1003 lines
36 KiB
C++
1003 lines
36 KiB
C++
/*********************************************************************
|
||
* 64‑Core Mask Editor – actual source code available in Matrix
|
||
* #russianantispyware:xmr.se
|
||
* You can download this software here:
|
||
* archive.org/details/b_20260327
|
||
* forums.servethehome.com/index.php?threads/es-xeon-discussion.5031/page-250
|
||
* git.skylar.tech/anon47/b
|
||
*
|
||
* Build (GNU/Linux; macOS; Windows, mingw (more hard than in GNU/Linux))
|
||
* g++ -std=c++17 `wx-config --cxxflags --libs` -o BitEditor BitEditor.cpp
|
||
*
|
||
* Build (Windows, MSVC (untested))
|
||
* cl /EHsc /std=c++17 BitEditor.cpp wxmsw31u_core.lib wxbase31u.lib
|
||
*********************************************************************/
|
||
|
||
#include <wx/wx.h>
|
||
#include <wx/checkbox.h>
|
||
#include <wx/sizer.h>
|
||
#include <wx/textctrl.h>
|
||
#include <wx/clipbrd.h> // for clipboard copy
|
||
#include <wx/dialog.h>
|
||
#include <array>
|
||
#include <cstdint>
|
||
#include <iomanip>
|
||
#include <sstream>
|
||
#include <string> // <-- std::string
|
||
|
||
class MaskEditorFrame : public wxFrame
|
||
{
|
||
public:
|
||
explicit MaskEditorFrame(const wxString& title);
|
||
|
||
private:
|
||
// -----------------------------------------------------------------
|
||
// UI controls
|
||
// -----------------------------------------------------------------
|
||
wxTextCtrl* m_hexCtrl{ nullptr };
|
||
wxTextCtrl* m_binCtrl{ nullptr };
|
||
wxTextCtrl* m_availCtrl1{ nullptr };
|
||
wxCheckBox* m_availChk1{ nullptr };
|
||
wxTextCtrl* m_availCtrl2{ nullptr };
|
||
wxCheckBox* m_availChk2{ nullptr };
|
||
wxButton* m_invertBtn{ nullptr };
|
||
wxStaticText* m_sourceLabel{ nullptr };
|
||
wxButton* m_copyBtn{ nullptr }; // copy → clipboard
|
||
wxButton* m_showBtn{ nullptr }; // show → dialog
|
||
std::array<wxCheckBox*, 64> m_checkBoxes;
|
||
std::array<wxTextCtrl*, 64> m_extraEdits;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Data & state
|
||
// -----------------------------------------------------------------
|
||
uint64_t m_mask = 0ULL;
|
||
uint64_t m_availMask1 = 0xFFFFFFFFFFFFFFFFULL;
|
||
uint64_t m_availMask2 = 0xFFFFFFFFFFFFFFFFULL;
|
||
bool m_updating = false;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Helper conversion functions
|
||
// -----------------------------------------------------------------
|
||
static uint64_t HexStringToU64(const wxString& s);
|
||
static wxString U64ToHexString(uint64_t v);
|
||
static wxString U64ToBinString(uint64_t v);
|
||
static uint64_t BinStringToU64(const wxString& s);
|
||
static wxString StripSpaces(const wxString& s);
|
||
|
||
// -----------------------------------------------------------------
|
||
// UI update helpers
|
||
// -----------------------------------------------------------------
|
||
void UpdateAllFromMask(bool skipHex = false, bool skipBin = false);
|
||
void UpdateMaskFromCheckBoxes();
|
||
void ApplyAvailability();
|
||
uint64_t EffectiveAvailMask() const;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Event handlers
|
||
// -----------------------------------------------------------------
|
||
void OnHexChanged (wxCommandEvent&);
|
||
void OnBinChanged (wxCommandEvent&);
|
||
void OnAvail1Changed (wxCommandEvent&);
|
||
void OnAvail2Changed (wxCommandEvent&);
|
||
void OnAvailMapToggled(wxCommandEvent&);
|
||
void OnCheckBoxChanged(wxCommandEvent&);
|
||
void OnInvertClicked (wxCommandEvent&);
|
||
void OnCopyClicked (wxCommandEvent&); // copy → clipboard
|
||
void OnShowClicked (wxCommandEvent&); // show → dialog
|
||
void OnClose (wxCloseEvent&); // unused‑parameter warning silenced
|
||
|
||
wxDECLARE_EVENT_TABLE();
|
||
};
|
||
|
||
/* -----------------------------------------------------------------
|
||
The source code is kept in a plain std::string.
|
||
It is a *single* constant – no wxString involved at this point.
|
||
----------------------------------------------------------------- */
|
||
static const std::string kProgramSource = R"src(
|
||
/*********************************************************************
|
||
* 64‑Core Mask Editor – actual source code available in Matrix
|
||
* #russianantispyware:xmr.se
|
||
* You can download this software here:
|
||
* archive.org/details/b_20260327
|
||
* forums.servethehome.com/index.php?threads/es-xeon-discussion.5031/page-250
|
||
* git.skylar.tech/anon47/b
|
||
*
|
||
* Build (GNU/Linux; macOS; Windows, mingw (more hard than in GNU/Linux))
|
||
* g++ -std=c++17 `wx-config --cxxflags --libs` -o BitEditor BitEditor.cpp
|
||
*
|
||
* Build (Windows, MSVC (untested))
|
||
* cl /EHsc /std=c++17 BitEditor.cpp wxmsw31u_core.lib wxbase31u.lib
|
||
*********************************************************************/
|
||
|
||
#include <wx/wx.h>
|
||
#include <wx/checkbox.h>
|
||
#include <wx/sizer.h>
|
||
#include <wx/textctrl.h>
|
||
#include <wx/clipbrd.h> // for clipboard copy
|
||
#include <wx/dialog.h>
|
||
#include <array>
|
||
#include <cstdint>
|
||
#include <iomanip>
|
||
#include <sstream>
|
||
#include <string> // <-- std::string
|
||
|
||
class MaskEditorFrame : public wxFrame
|
||
{
|
||
public:
|
||
explicit MaskEditorFrame(const wxString& title);
|
||
|
||
private:
|
||
// -----------------------------------------------------------------
|
||
// UI controls
|
||
// -----------------------------------------------------------------
|
||
wxTextCtrl* m_hexCtrl{ nullptr };
|
||
wxTextCtrl* m_binCtrl{ nullptr };
|
||
wxTextCtrl* m_availCtrl1{ nullptr };
|
||
wxCheckBox* m_availChk1{ nullptr };
|
||
wxTextCtrl* m_availCtrl2{ nullptr };
|
||
wxCheckBox* m_availChk2{ nullptr };
|
||
wxButton* m_invertBtn{ nullptr };
|
||
wxStaticText* m_sourceLabel{ nullptr };
|
||
wxButton* m_copyBtn{ nullptr }; // copy → clipboard
|
||
wxButton* m_showBtn{ nullptr }; // show → dialog
|
||
std::array<wxCheckBox*, 64> m_checkBoxes;
|
||
std::array<wxTextCtrl*, 64> m_extraEdits;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Data & state
|
||
// -----------------------------------------------------------------
|
||
uint64_t m_mask = 0ULL;
|
||
uint64_t m_availMask1 = 0xFFFFFFFFFFFFFFFFULL;
|
||
uint64_t m_availMask2 = 0xFFFFFFFFFFFFFFFFULL;
|
||
bool m_updating = false;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Helper conversion functions
|
||
// -----------------------------------------------------------------
|
||
static uint64_t HexStringToU64(const wxString& s);
|
||
static wxString U64ToHexString(uint64_t v);
|
||
static wxString U64ToBinString(uint64_t v);
|
||
static uint64_t BinStringToU64(const wxString& s);
|
||
static wxString StripSpaces(const wxString& s);
|
||
|
||
// -----------------------------------------------------------------
|
||
// UI update helpers
|
||
// -----------------------------------------------------------------
|
||
void UpdateAllFromMask(bool skipHex = false, bool skipBin = false);
|
||
void UpdateMaskFromCheckBoxes();
|
||
void ApplyAvailability();
|
||
uint64_t EffectiveAvailMask() const;
|
||
|
||
// -----------------------------------------------------------------
|
||
// Event handlers
|
||
// -----------------------------------------------------------------
|
||
void OnHexChanged (wxCommandEvent&);
|
||
void OnBinChanged (wxCommandEvent&);
|
||
void OnAvail1Changed (wxCommandEvent&);
|
||
void OnAvail2Changed (wxCommandEvent&);
|
||
void OnAvailMapToggled(wxCommandEvent&);
|
||
void OnCheckBoxChanged(wxCommandEvent&);
|
||
void OnInvertClicked (wxCommandEvent&);
|
||
void OnCopyClicked (wxCommandEvent&); // copy → clipboard
|
||
void OnShowClicked (wxCommandEvent&); // show → dialog
|
||
void OnClose (wxCloseEvent&); // unused‑parameter warning silenced
|
||
|
||
wxDECLARE_EVENT_TABLE();
|
||
};
|
||
|
||
/* -----------------------------------------------------------------
|
||
The source code is kept in a plain std::string.
|
||
It is a *single* constant – no wxString involved at this point.
|
||
----------------------------------------------------------------- */
|
||
please paste the source code just as it is into block down bellow
|
||
static const std::string kProgramSource = R"src(
|
||
|
||
)src\";
|
||
|
||
wxBEGIN_EVENT_TABLE(MaskEditorFrame, wxFrame)
|
||
EVT_CHECKBOX (wxID_ANY, MaskEditorFrame::OnCheckBoxChanged)
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnInvertClicked)
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnCopyClicked) // clipboard
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnShowClicked) // dialog
|
||
EVT_CLOSE (MaskEditorFrame::OnClose)
|
||
wxEND_EVENT_TABLE()
|
||
|
||
//===================================================================
|
||
// IMPLEMENTATION
|
||
//===================================================================
|
||
|
||
MaskEditorFrame::MaskEditorFrame(const wxString& title)
|
||
: wxFrame(nullptr, wxID_ANY, title,
|
||
wxDefaultPosition, wxSize(720, 640))
|
||
{
|
||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||
|
||
// ------------------------------------------------------------
|
||
// HEX mask
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* hexSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
hexSizer->Add(new wxStaticText(this, wxID_ANY, "HEX mask:"), 0,
|
||
wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_hexCtrl = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
hexSizer->Add(m_hexCtrl, 0, wxRIGHT, 10);
|
||
topSizer->Add(hexSizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// BIN mask
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* binSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
binSizer->Add(new wxStaticText(this, wxID_ANY, "BIN mask:"), 0,
|
||
wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_binCtrl = new wxTextCtrl(this, wxID_ANY,
|
||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||
wxDefaultPosition, wxSize(540, -1));
|
||
binSizer->Add(m_binCtrl, 0, wxRIGHT, 10);
|
||
topSizer->Add(binSizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Availability map #1 + enable checkbox
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* avail1Sizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_availChk1 = new wxCheckBox(this, wxID_ANY, "Enable map 1");
|
||
m_availChk1->SetValue(true);
|
||
avail1Sizer->Add(m_availChk1, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
|
||
avail1Sizer->Add(new wxStaticText(this, wxID_ANY,
|
||
"Availability map #1 (hex):"),
|
||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_availCtrl1 = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
avail1Sizer->Add(m_availCtrl1, 0, wxRIGHT, 10);
|
||
topSizer->Add(avail1Sizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Availability map #2 + enable checkbox
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* avail2Sizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_availChk2 = new wxCheckBox(this, wxID_ANY, "Enable map 2");
|
||
m_availChk2->SetValue(true);
|
||
avail2Sizer->Add(m_availChk2, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
|
||
avail2Sizer->Add(new wxStaticText(this, wxID_ANY,
|
||
"Availability map #2 (hex):"),
|
||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_availCtrl2 = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
avail2Sizer->Add(m_availCtrl2, 0, wxRIGHT, 10);
|
||
topSizer->Add(avail2Sizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// 64 cores – 8 × 8 grid, each cell = checkbox + tiny edit
|
||
// ------------------------------------------------------------
|
||
wxGridSizer* grid = new wxGridSizer(8, 8, 4, 4);
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
wxBoxSizer* cell = new wxBoxSizer(wxHORIZONTAL);
|
||
wxString lbl = wxString::Format("C%02d", i);
|
||
m_checkBoxes[i] = new wxCheckBox(this, wxID_ANY, lbl);
|
||
cell->Add(m_checkBoxes[i], 0, wxALIGN_CENTER_VERTICAL);
|
||
m_extraEdits[i] = new wxTextCtrl(this, wxID_ANY, "",
|
||
wxDefaultPosition, wxSize(35, -1));
|
||
m_extraEdits[i]->SetMaxLength(3);
|
||
cell->Add(m_extraEdits[i], 0,
|
||
wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
|
||
grid->Add(cell, 0, wxALL, 2);
|
||
}
|
||
topSizer->Add(grid, 1, wxALL | wxEXPAND, 8);
|
||
|
||
// ------------------------------------------------------------
|
||
// Invert button
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_invertBtn = new wxButton(this, wxID_ANY, "Invert Mask");
|
||
btnSizer->AddStretchSpacer(1);
|
||
btnSizer->Add(m_invertBtn, 0, wxRIGHT, 10);
|
||
btnSizer->AddStretchSpacer(1);
|
||
topSizer->Add(btnSizer, 0, wxEXPAND | wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Bottom area – label + two buttons (copy & show)
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* bottomSizer = new wxBoxSizer(wxVERTICAL);
|
||
|
||
// 1) label
|
||
m_sourceLabel = new wxStaticText(this, wxID_ANY,
|
||
"This is version 1. Actual release is available in "
|
||
"https://matrix.org chat room: #russianantispyware:xmr.se"
|
||
);
|
||
wxFont f = m_sourceLabel->GetFont();
|
||
f.SetPointSize(f.GetPointSize() - 1);
|
||
m_sourceLabel->SetFont(f);
|
||
bottomSizer->Add(m_sourceLabel, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxALL, 8);
|
||
|
||
// 2) copy‑to‑clipboard button
|
||
m_copyBtn = new wxButton(this, wxID_ANY,
|
||
"Copy source code to clipboard");
|
||
bottomSizer->Add(m_copyBtn, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 6);
|
||
|
||
// 3) show‑source button
|
||
m_showBtn = new wxButton(this, wxID_ANY,
|
||
"Show source code");
|
||
bottomSizer->Add(m_showBtn, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 12);
|
||
|
||
topSizer->Add(bottomSizer, 0, wxEXPAND | wxALL, 5);
|
||
|
||
SetSizer(topSizer);
|
||
Centre();
|
||
|
||
// ------------------------------------------------------------
|
||
// Bind events
|
||
// ------------------------------------------------------------
|
||
m_hexCtrl->Bind(wxEVT_TEXT, &MaskEditorFrame::OnHexChanged, this);
|
||
m_binCtrl->Bind(wxEVT_TEXT, &MaskEditorFrame::OnBinChanged, this);
|
||
m_availCtrl1->Bind(wxEVT_TEXT, &MaskEditorFrame::OnAvail1Changed, this);
|
||
m_availCtrl2->Bind(wxEVT_TEXT, &MaskEditorFrame::OnAvail2Changed, this);
|
||
m_availChk1->Bind(wxEVT_CHECKBOX, &MaskEditorFrame::OnAvailMapToggled, this);
|
||
m_availChk2->Bind(wxEVT_CHECKBOX, &MaskEditorFrame::OnAvailMapToggled, this);
|
||
m_copyBtn->Bind(wxEVT_BUTTON, &MaskEditorFrame::OnCopyClicked, this);
|
||
m_showBtn->Bind(wxEVT_BUTTON, &MaskEditorFrame::OnShowClicked, this);
|
||
|
||
// ------------------------------------------------------------
|
||
// Initialise internal data from the default UI contents
|
||
// ------------------------------------------------------------
|
||
m_mask = HexStringToU64(m_hexCtrl->GetValue());
|
||
m_availMask1 = HexStringToU64(m_availCtrl1->GetValue());
|
||
m_availMask2 = HexStringToU64(m_availCtrl2->GetValue());
|
||
|
||
UpdateAllFromMask(); // fill binary field & check‑boxes
|
||
ApplyAvailability(); // disable cores that are not present
|
||
}
|
||
|
||
//===================================================================
|
||
// Conversion helpers (portable – no wxString::RemoveAll)
|
||
//===================================================================
|
||
wxString MaskEditorFrame::StripSpaces(const wxString& s)
|
||
{
|
||
wxString t = s;
|
||
t.Replace(" ", "");
|
||
t.Replace("\t", "");
|
||
return t;
|
||
}
|
||
|
||
uint64_t MaskEditorFrame::HexStringToU64(const wxString& s)
|
||
{
|
||
wxString str = StripSpaces(s);
|
||
str.MakeUpper();
|
||
if (str.StartsWith("0X"))
|
||
str = str.Mid(2);
|
||
uint64_t v = 0;
|
||
std::wistringstream iss(str.wc_str());
|
||
iss >> std::hex >> v;
|
||
if (iss.fail())
|
||
return 0ULL;
|
||
return v;
|
||
}
|
||
|
||
wxString MaskEditorFrame::U64ToHexString(uint64_t v)
|
||
{
|
||
std::wstringstream ss;
|
||
ss << std::uppercase << std::hex << std::setw(16) << std::setfill(L'0') << v;
|
||
return wxString(ss.str());
|
||
}
|
||
|
||
wxString MaskEditorFrame::U64ToBinString(uint64_t v)
|
||
{
|
||
wxString s;
|
||
for (int i = 63; i >= 0; --i)
|
||
s << ((v >> i) & 1ULL ? '1' : '0');
|
||
return s;
|
||
}
|
||
|
||
uint64_t MaskEditorFrame::BinStringToU64(const wxString& s)
|
||
{
|
||
wxString str = StripSpaces(s);
|
||
if (str.Length() > 64)
|
||
str = str.Left(64);
|
||
uint64_t v = 0;
|
||
for (size_t i = 0; i < str.Length(); ++i)
|
||
{
|
||
v <<= 1;
|
||
if (str[i] == '1')
|
||
v |= 1ULL;
|
||
}
|
||
return v;
|
||
}
|
||
|
||
//===================================================================
|
||
// UI update helpers
|
||
//===================================================================
|
||
void MaskEditorFrame::UpdateAllFromMask(bool skipHex, bool skipBin)
|
||
{
|
||
m_updating = true;
|
||
|
||
if (!skipHex)
|
||
m_hexCtrl->SetValue(U64ToHexString(m_mask));
|
||
if (!skipBin)
|
||
m_binCtrl->SetValue(U64ToBinString(m_mask));
|
||
|
||
uint64_t effectiveAvail = EffectiveAvailMask();
|
||
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
bool corePresent = (effectiveAvail >> i) & 1ULL;
|
||
m_checkBoxes[i]->Enable(corePresent);
|
||
if (corePresent)
|
||
m_checkBoxes[i]->SetValue(((m_mask >> i) & 1ULL) != 0);
|
||
else
|
||
m_checkBoxes[i]->SetValue(false);
|
||
}
|
||
|
||
m_updating = false;
|
||
}
|
||
|
||
void MaskEditorFrame::UpdateMaskFromCheckBoxes()
|
||
{
|
||
uint64_t newMask = 0ULL;
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
if (m_checkBoxes[i]->IsEnabled() && m_checkBoxes[i]->GetValue())
|
||
newMask |= (1ULL << i);
|
||
}
|
||
m_mask = newMask;
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
/* Compute the *effective* availability mask (AND semantics). */
|
||
uint64_t MaskEditorFrame::EffectiveAvailMask() const
|
||
{
|
||
uint64_t mask = 0xFFFFFFFFFFFFFFFFULL;
|
||
if (m_availChk1->GetValue())
|
||
mask &= m_availMask1;
|
||
if (m_availChk2->GetValue())
|
||
mask &= m_availMask2;
|
||
return mask;
|
||
}
|
||
|
||
/* Apply the effective availability to UI and to the current mask. */
|
||
void MaskEditorFrame::ApplyAvailability()
|
||
{
|
||
uint64_t effective = EffectiveAvailMask();
|
||
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
bool present = (effective >> i) & 1ULL;
|
||
m_checkBoxes[i]->Enable(present);
|
||
if (!present)
|
||
m_checkBoxes[i]->SetValue(false);
|
||
}
|
||
m_mask &= effective;
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
//===================================================================
|
||
// Event handlers
|
||
//===================================================================
|
||
void MaskEditorFrame::OnHexChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_mask = HexStringToU64(m_hexCtrl->GetValue()) & EffectiveAvailMask();
|
||
UpdateAllFromMask(/*skipHex=*/true, /*skipBin=*/false);
|
||
}
|
||
|
||
void MaskEditorFrame::OnBinChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_mask = BinStringToU64(m_binCtrl->GetValue()) & EffectiveAvailMask();
|
||
UpdateAllFromMask(/*skipHex=*/false, /*skipBin=*/true);
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvail1Changed(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_availMask1 = HexStringToU64(m_availCtrl1->GetValue());
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvail2Changed(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_availMask2 = HexStringToU64(m_availCtrl2->GetValue());
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvailMapToggled(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnCheckBoxChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
UpdateMaskFromCheckBoxes();
|
||
}
|
||
|
||
void MaskEditorFrame::OnInvertClicked(wxCommandEvent&)
|
||
{
|
||
m_mask = (~m_mask) & EffectiveAvailMask();
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
/* ---------------------------------------------------------------
|
||
Copy the source code to the clipboard (exactly as the original)
|
||
--------------------------------------------------------------- */
|
||
void MaskEditorFrame::OnCopyClicked(wxCommandEvent&)
|
||
{
|
||
// Convert std::string → wxString (UTF‑8 aware)
|
||
wxString wxSrc = wxString::FromUTF8(kProgramSource.c_str());
|
||
|
||
if (!wxTheClipboard->Open())
|
||
{
|
||
wxMessageBox("Could not open the clipboard.", "Error",
|
||
wxOK | wxICON_ERROR);
|
||
return;
|
||
}
|
||
|
||
bool ok = wxTheClipboard->SetData(new wxTextDataObject(wxSrc));
|
||
wxTheClipboard->Close();
|
||
|
||
if (!ok)
|
||
wxMessageBox("Failed to set clipboard data.", "Error",
|
||
wxOK | wxICON_ERROR);
|
||
else
|
||
wxMessageBox("Source code copied to clipboard.", "Info",
|
||
wxOK | wxICON_INFORMATION);
|
||
}
|
||
|
||
/* ---------------------------------------------------------------
|
||
Show the same source code in a modal dialog (read‑only)
|
||
--------------------------------------------------------------- */
|
||
void MaskEditorFrame::OnShowClicked(wxCommandEvent&)
|
||
{
|
||
// Convert once more to wxString – the dialog needs it.
|
||
wxString wxSrc = wxString::FromUTF8(kProgramSource.c_str());
|
||
|
||
wxDialog dlg(this, wxID_ANY, "Source code of BitEditor",
|
||
wxDefaultPosition, wxSize(720, 480),
|
||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
|
||
|
||
wxTextCtrl* txt = new wxTextCtrl(&dlg, wxID_ANY, wxSrc,
|
||
wxDefaultPosition, wxDefaultSize,
|
||
wxTE_MULTILINE | wxTE_READONLY |
|
||
wxTE_RICH2 | wxHSCROLL | wxVSCROLL);
|
||
|
||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||
sizer->Add(txt, 1, wxEXPAND | wxALL, 5);
|
||
dlg.SetSizerAndFit(sizer);
|
||
|
||
dlg.ShowModal(); // dialog is destroyed automatically on return
|
||
}
|
||
|
||
/* Silencing the unused‑parameter warning */
|
||
void MaskEditorFrame::OnClose(wxCloseEvent& /*evt*/)
|
||
{
|
||
Destroy();
|
||
}
|
||
|
||
//===================================================================
|
||
// Application class
|
||
//===================================================================
|
||
class MaskEditorApp : public wxApp
|
||
{
|
||
public:
|
||
bool OnInit() override
|
||
{
|
||
if (!wxApp::OnInit())
|
||
return false;
|
||
|
||
const wxString title = wxString::FromUTF8(u8"64‑Core Mask Editor – source code also available in Matrix #russianantispyware:xmr.se");
|
||
|
||
MaskEditorFrame* frame = new MaskEditorFrame(title);
|
||
frame->Show(true);
|
||
return true;
|
||
}
|
||
};
|
||
|
||
wxIMPLEMENT_APP(MaskEditorApp);
|
||
)src";
|
||
|
||
wxBEGIN_EVENT_TABLE(MaskEditorFrame, wxFrame)
|
||
EVT_CHECKBOX (wxID_ANY, MaskEditorFrame::OnCheckBoxChanged)
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnInvertClicked)
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnCopyClicked) // clipboard
|
||
EVT_BUTTON (wxID_ANY, MaskEditorFrame::OnShowClicked) // dialog
|
||
EVT_CLOSE (MaskEditorFrame::OnClose)
|
||
wxEND_EVENT_TABLE()
|
||
|
||
//===================================================================
|
||
// IMPLEMENTATION
|
||
//===================================================================
|
||
|
||
MaskEditorFrame::MaskEditorFrame(const wxString& title)
|
||
: wxFrame(nullptr, wxID_ANY, title,
|
||
wxDefaultPosition, wxSize(720, 640))
|
||
{
|
||
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
|
||
|
||
// ------------------------------------------------------------
|
||
// HEX mask
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* hexSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
hexSizer->Add(new wxStaticText(this, wxID_ANY, "HEX mask:"), 0,
|
||
wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_hexCtrl = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
hexSizer->Add(m_hexCtrl, 0, wxRIGHT, 10);
|
||
topSizer->Add(hexSizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// BIN mask
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* binSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
binSizer->Add(new wxStaticText(this, wxID_ANY, "BIN mask:"), 0,
|
||
wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_binCtrl = new wxTextCtrl(this, wxID_ANY,
|
||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||
wxDefaultPosition, wxSize(540, -1));
|
||
binSizer->Add(m_binCtrl, 0, wxRIGHT, 10);
|
||
topSizer->Add(binSizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Availability map #1 + enable checkbox
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* avail1Sizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_availChk1 = new wxCheckBox(this, wxID_ANY, "Enable map 1");
|
||
m_availChk1->SetValue(true);
|
||
avail1Sizer->Add(m_availChk1, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
|
||
avail1Sizer->Add(new wxStaticText(this, wxID_ANY,
|
||
"Availability map #1 (hex):"),
|
||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_availCtrl1 = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
avail1Sizer->Add(m_availCtrl1, 0, wxRIGHT, 10);
|
||
topSizer->Add(avail1Sizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Availability map #2 + enable checkbox
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* avail2Sizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_availChk2 = new wxCheckBox(this, wxID_ANY, "Enable map 2");
|
||
m_availChk2->SetValue(true);
|
||
avail2Sizer->Add(m_availChk2, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
|
||
avail2Sizer->Add(new wxStaticText(this, wxID_ANY,
|
||
"Availability map #2 (hex):"),
|
||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||
m_availCtrl2 = new wxTextCtrl(this, wxID_ANY, "FFFFFFFFFFFFFFFF",
|
||
wxDefaultPosition, wxSize(300, -1));
|
||
avail2Sizer->Add(m_availCtrl2, 0, wxRIGHT, 10);
|
||
topSizer->Add(avail2Sizer, 0, wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// 64 cores – 8 × 8 grid, each cell = checkbox + tiny edit
|
||
// ------------------------------------------------------------
|
||
wxGridSizer* grid = new wxGridSizer(8, 8, 4, 4);
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
wxBoxSizer* cell = new wxBoxSizer(wxHORIZONTAL);
|
||
wxString lbl = wxString::Format("C%02d", i);
|
||
m_checkBoxes[i] = new wxCheckBox(this, wxID_ANY, lbl);
|
||
cell->Add(m_checkBoxes[i], 0, wxALIGN_CENTER_VERTICAL);
|
||
m_extraEdits[i] = new wxTextCtrl(this, wxID_ANY, "",
|
||
wxDefaultPosition, wxSize(35, -1));
|
||
m_extraEdits[i]->SetMaxLength(3);
|
||
cell->Add(m_extraEdits[i], 0,
|
||
wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
|
||
grid->Add(cell, 0, wxALL, 2);
|
||
}
|
||
topSizer->Add(grid, 1, wxALL | wxEXPAND, 8);
|
||
|
||
// ------------------------------------------------------------
|
||
// Invert button
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
|
||
m_invertBtn = new wxButton(this, wxID_ANY, "Invert Mask");
|
||
btnSizer->AddStretchSpacer(1);
|
||
btnSizer->Add(m_invertBtn, 0, wxRIGHT, 10);
|
||
btnSizer->AddStretchSpacer(1);
|
||
topSizer->Add(btnSizer, 0, wxEXPAND | wxALL, 5);
|
||
|
||
// ------------------------------------------------------------
|
||
// Bottom area – label + two buttons (copy & show)
|
||
// ------------------------------------------------------------
|
||
wxBoxSizer* bottomSizer = new wxBoxSizer(wxVERTICAL);
|
||
|
||
// 1) label
|
||
m_sourceLabel = new wxStaticText(this, wxID_ANY,
|
||
"This is version 1. Actual release is available in "
|
||
"https://matrix.org chat room: #russianantispyware:xmr.se"
|
||
);
|
||
wxFont f = m_sourceLabel->GetFont();
|
||
f.SetPointSize(f.GetPointSize() - 1);
|
||
m_sourceLabel->SetFont(f);
|
||
bottomSizer->Add(m_sourceLabel, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxALL, 8);
|
||
|
||
// 2) copy‑to‑clipboard button
|
||
m_copyBtn = new wxButton(this, wxID_ANY,
|
||
"Copy source code to clipboard");
|
||
bottomSizer->Add(m_copyBtn, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 6);
|
||
|
||
// 3) show‑source button
|
||
m_showBtn = new wxButton(this, wxID_ANY,
|
||
"Show source code");
|
||
bottomSizer->Add(m_showBtn, 0,
|
||
wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 12);
|
||
|
||
topSizer->Add(bottomSizer, 0, wxEXPAND | wxALL, 5);
|
||
|
||
SetSizer(topSizer);
|
||
Centre();
|
||
|
||
// ------------------------------------------------------------
|
||
// Bind events
|
||
// ------------------------------------------------------------
|
||
m_hexCtrl->Bind(wxEVT_TEXT, &MaskEditorFrame::OnHexChanged, this);
|
||
m_binCtrl->Bind(wxEVT_TEXT, &MaskEditorFrame::OnBinChanged, this);
|
||
m_availCtrl1->Bind(wxEVT_TEXT, &MaskEditorFrame::OnAvail1Changed, this);
|
||
m_availCtrl2->Bind(wxEVT_TEXT, &MaskEditorFrame::OnAvail2Changed, this);
|
||
m_availChk1->Bind(wxEVT_CHECKBOX, &MaskEditorFrame::OnAvailMapToggled, this);
|
||
m_availChk2->Bind(wxEVT_CHECKBOX, &MaskEditorFrame::OnAvailMapToggled, this);
|
||
m_copyBtn->Bind(wxEVT_BUTTON, &MaskEditorFrame::OnCopyClicked, this);
|
||
m_showBtn->Bind(wxEVT_BUTTON, &MaskEditorFrame::OnShowClicked, this);
|
||
|
||
// ------------------------------------------------------------
|
||
// Initialise internal data from the default UI contents
|
||
// ------------------------------------------------------------
|
||
m_mask = HexStringToU64(m_hexCtrl->GetValue());
|
||
m_availMask1 = HexStringToU64(m_availCtrl1->GetValue());
|
||
m_availMask2 = HexStringToU64(m_availCtrl2->GetValue());
|
||
|
||
UpdateAllFromMask(); // fill binary field & check‑boxes
|
||
ApplyAvailability(); // disable cores that are not present
|
||
}
|
||
|
||
//===================================================================
|
||
// Conversion helpers (portable – no wxString::RemoveAll)
|
||
//===================================================================
|
||
wxString MaskEditorFrame::StripSpaces(const wxString& s)
|
||
{
|
||
wxString t = s;
|
||
t.Replace(" ", "");
|
||
t.Replace("\t", "");
|
||
return t;
|
||
}
|
||
|
||
uint64_t MaskEditorFrame::HexStringToU64(const wxString& s)
|
||
{
|
||
wxString str = StripSpaces(s);
|
||
str.MakeUpper();
|
||
if (str.StartsWith("0X"))
|
||
str = str.Mid(2);
|
||
uint64_t v = 0;
|
||
std::wistringstream iss(str.wc_str());
|
||
iss >> std::hex >> v;
|
||
if (iss.fail())
|
||
return 0ULL;
|
||
return v;
|
||
}
|
||
|
||
wxString MaskEditorFrame::U64ToHexString(uint64_t v)
|
||
{
|
||
std::wstringstream ss;
|
||
ss << std::uppercase << std::hex << std::setw(16) << std::setfill(L'0') << v;
|
||
return wxString(ss.str());
|
||
}
|
||
|
||
wxString MaskEditorFrame::U64ToBinString(uint64_t v)
|
||
{
|
||
wxString s;
|
||
for (int i = 63; i >= 0; --i)
|
||
s << ((v >> i) & 1ULL ? '1' : '0');
|
||
return s;
|
||
}
|
||
|
||
uint64_t MaskEditorFrame::BinStringToU64(const wxString& s)
|
||
{
|
||
wxString str = StripSpaces(s);
|
||
if (str.Length() > 64)
|
||
str = str.Left(64);
|
||
uint64_t v = 0;
|
||
for (size_t i = 0; i < str.Length(); ++i)
|
||
{
|
||
v <<= 1;
|
||
if (str[i] == '1')
|
||
v |= 1ULL;
|
||
}
|
||
return v;
|
||
}
|
||
|
||
//===================================================================
|
||
// UI update helpers
|
||
//===================================================================
|
||
void MaskEditorFrame::UpdateAllFromMask(bool skipHex, bool skipBin)
|
||
{
|
||
m_updating = true;
|
||
|
||
if (!skipHex)
|
||
m_hexCtrl->SetValue(U64ToHexString(m_mask));
|
||
if (!skipBin)
|
||
m_binCtrl->SetValue(U64ToBinString(m_mask));
|
||
|
||
uint64_t effectiveAvail = EffectiveAvailMask();
|
||
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
bool corePresent = (effectiveAvail >> i) & 1ULL;
|
||
m_checkBoxes[i]->Enable(corePresent);
|
||
if (corePresent)
|
||
m_checkBoxes[i]->SetValue(((m_mask >> i) & 1ULL) != 0);
|
||
else
|
||
m_checkBoxes[i]->SetValue(false);
|
||
}
|
||
|
||
m_updating = false;
|
||
}
|
||
|
||
void MaskEditorFrame::UpdateMaskFromCheckBoxes()
|
||
{
|
||
uint64_t newMask = 0ULL;
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
if (m_checkBoxes[i]->IsEnabled() && m_checkBoxes[i]->GetValue())
|
||
newMask |= (1ULL << i);
|
||
}
|
||
m_mask = newMask;
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
/* Compute the *effective* availability mask (AND semantics). */
|
||
uint64_t MaskEditorFrame::EffectiveAvailMask() const
|
||
{
|
||
uint64_t mask = 0xFFFFFFFFFFFFFFFFULL;
|
||
if (m_availChk1->GetValue())
|
||
mask &= m_availMask1;
|
||
if (m_availChk2->GetValue())
|
||
mask &= m_availMask2;
|
||
return mask;
|
||
}
|
||
|
||
/* Apply the effective availability to UI and to the current mask. */
|
||
void MaskEditorFrame::ApplyAvailability()
|
||
{
|
||
uint64_t effective = EffectiveAvailMask();
|
||
|
||
for (int i = 0; i < 64; ++i)
|
||
{
|
||
bool present = (effective >> i) & 1ULL;
|
||
m_checkBoxes[i]->Enable(present);
|
||
if (!present)
|
||
m_checkBoxes[i]->SetValue(false);
|
||
}
|
||
m_mask &= effective;
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
//===================================================================
|
||
// Event handlers
|
||
//===================================================================
|
||
void MaskEditorFrame::OnHexChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_mask = HexStringToU64(m_hexCtrl->GetValue()) & EffectiveAvailMask();
|
||
UpdateAllFromMask(/*skipHex=*/true, /*skipBin=*/false);
|
||
}
|
||
|
||
void MaskEditorFrame::OnBinChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_mask = BinStringToU64(m_binCtrl->GetValue()) & EffectiveAvailMask();
|
||
UpdateAllFromMask(/*skipHex=*/false, /*skipBin=*/true);
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvail1Changed(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_availMask1 = HexStringToU64(m_availCtrl1->GetValue());
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvail2Changed(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
m_availMask2 = HexStringToU64(m_availCtrl2->GetValue());
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnAvailMapToggled(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
ApplyAvailability();
|
||
}
|
||
|
||
void MaskEditorFrame::OnCheckBoxChanged(wxCommandEvent&)
|
||
{
|
||
if (m_updating) return;
|
||
UpdateMaskFromCheckBoxes();
|
||
}
|
||
|
||
void MaskEditorFrame::OnInvertClicked(wxCommandEvent&)
|
||
{
|
||
m_mask = (~m_mask) & EffectiveAvailMask();
|
||
UpdateAllFromMask();
|
||
}
|
||
|
||
/* ---------------------------------------------------------------
|
||
Copy the source code to the clipboard (exactly as the original)
|
||
--------------------------------------------------------------- */
|
||
void MaskEditorFrame::OnCopyClicked(wxCommandEvent&)
|
||
{
|
||
// Convert std::string → wxString (UTF‑8 aware)
|
||
wxString wxSrc = wxString::FromUTF8(kProgramSource.c_str());
|
||
|
||
if (!wxTheClipboard->Open())
|
||
{
|
||
wxMessageBox("Could not open the clipboard.", "Error",
|
||
wxOK | wxICON_ERROR);
|
||
return;
|
||
}
|
||
|
||
bool ok = wxTheClipboard->SetData(new wxTextDataObject(wxSrc));
|
||
wxTheClipboard->Close();
|
||
|
||
if (!ok)
|
||
wxMessageBox("Failed to set clipboard data.", "Error",
|
||
wxOK | wxICON_ERROR);
|
||
else
|
||
wxMessageBox("Source code copied to clipboard.", "Info",
|
||
wxOK | wxICON_INFORMATION);
|
||
}
|
||
|
||
/* ---------------------------------------------------------------
|
||
Show the same source code in a modal dialog (read‑only)
|
||
--------------------------------------------------------------- */
|
||
void MaskEditorFrame::OnShowClicked(wxCommandEvent&)
|
||
{
|
||
// Convert once more to wxString – the dialog needs it.
|
||
wxString wxSrc = wxString::FromUTF8(kProgramSource.c_str());
|
||
|
||
wxDialog dlg(this, wxID_ANY, "Source code of BitEditor",
|
||
wxDefaultPosition, wxSize(720, 480),
|
||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
|
||
|
||
wxTextCtrl* txt = new wxTextCtrl(&dlg, wxID_ANY, wxSrc,
|
||
wxDefaultPosition, wxDefaultSize,
|
||
wxTE_MULTILINE | wxTE_READONLY |
|
||
wxTE_RICH2 | wxHSCROLL | wxVSCROLL);
|
||
|
||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||
sizer->Add(txt, 1, wxEXPAND | wxALL, 5);
|
||
dlg.SetSizerAndFit(sizer);
|
||
|
||
dlg.ShowModal(); // dialog is destroyed automatically on return
|
||
}
|
||
|
||
/* Silencing the unused‑parameter warning */
|
||
void MaskEditorFrame::OnClose(wxCloseEvent& /*evt*/)
|
||
{
|
||
Destroy();
|
||
}
|
||
|
||
//===================================================================
|
||
// Application class
|
||
//===================================================================
|
||
class MaskEditorApp : public wxApp
|
||
{
|
||
public:
|
||
bool OnInit() override
|
||
{
|
||
if (!wxApp::OnInit())
|
||
return false;
|
||
|
||
const wxString title = wxString::FromUTF8(u8"64‑Core Mask Editor – source code also available in Matrix #russianantispyware:xmr.se");
|
||
|
||
MaskEditorFrame* frame = new MaskEditorFrame(title);
|
||
frame->Show(true);
|
||
return true;
|
||
}
|
||
};
|
||
|
||
wxIMPLEMENT_APP(MaskEditorApp);
|