mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-27 11:34:17 +01:00
262 lines
6.1 KiB
C++
262 lines
6.1 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <atomic>
|
|
|
|
#include "Cafe/HW/MMU/MMU.h"
|
|
#include "util/helpers/helpers.h"
|
|
#include "gui/helpers/wxCustomEvents.h"
|
|
|
|
enum SearchDataType
|
|
{
|
|
SearchDataType_None,
|
|
SearchDataType_String,
|
|
SearchDataType_Float,
|
|
SearchDataType_Double,
|
|
SearchDataType_Int8,
|
|
SearchDataType_Int16,
|
|
SearchDataType_Int32,
|
|
SearchDataType_Int64,
|
|
};
|
|
|
|
struct TableEntry_t
|
|
{
|
|
uint32 address;
|
|
const char description[32];
|
|
SearchDataType type;
|
|
bool freeze;
|
|
uint16 dataLen;
|
|
uint8* data;
|
|
};
|
|
|
|
class MemorySearcherTool : public wxFrame
|
|
{
|
|
public:
|
|
MemorySearcherTool(wxFrame* parent);
|
|
virtual ~MemorySearcherTool();
|
|
|
|
void OnTimerTick(wxTimerEvent& event);
|
|
void OnClose(wxCloseEvent&);
|
|
void OnSearch(wxCommandEvent&);
|
|
void OnSearchFinished(wxCommandEvent& event);
|
|
void OnUpdateGauge(wxSetGaugeValue& event);
|
|
void OnFilter(wxCommandEvent& event);
|
|
void OnResultListClick(wxMouseEvent& event);
|
|
void OnEntryListRightClick(wxDataViewEvent& event);
|
|
//void OnEntryListRightClick2(wxContextMenuEvent& event);
|
|
void OnPopupClick(wxCommandEvent& event);
|
|
|
|
void OnItemEdited(wxDataViewEvent& event);
|
|
|
|
private:
|
|
void Reset();
|
|
bool VerifySearchValue() const;
|
|
void FillResultList();
|
|
void RefreshResultList();
|
|
void RefreshStashList();
|
|
void SetSearchDataType();
|
|
std::string GetSearchTypeName() const;
|
|
void CreateRightClickPopupMenu();
|
|
|
|
void Load();
|
|
void Save();
|
|
|
|
static bool IsAddressValid(uint32 addr);
|
|
|
|
template <typename T>
|
|
bool ConvertStringToType(const char* inValue, T& outValue) const
|
|
{
|
|
std::istringstream iss(inValue);
|
|
iss >> std::noskipws >> outValue;
|
|
return iss && iss.eof();
|
|
}
|
|
|
|
using ListType_t = std::vector<MEMPTR<void>>;
|
|
ListType_t SearchValues(SearchDataType type, void* ptr, uint32 size)
|
|
{
|
|
/*if (type == SearchDataType_String)
|
|
return SearchValues((const char* )ptr, size);
|
|
else */if (type == SearchDataType_Float)
|
|
return SearchValues((float*)ptr, size);
|
|
else if (type == SearchDataType_Double)
|
|
return SearchValues((double*)ptr, size);
|
|
else if (type == SearchDataType_Int8)
|
|
return SearchValues((sint8*)ptr, size);
|
|
else if (type == SearchDataType_Int16)
|
|
return SearchValues((sint16*)ptr, size);
|
|
else if (type == SearchDataType_Int32)
|
|
return SearchValues((sint32*)ptr, size);
|
|
else if (type == SearchDataType_Int64)
|
|
return SearchValues((sint64*)ptr, size);
|
|
return {};
|
|
}
|
|
|
|
ListType_t FilterValues(SearchDataType type)
|
|
{
|
|
/*if (type == SearchDataType_String)
|
|
return FilterValues<const char*>();
|
|
else */if (type == SearchDataType_Float)
|
|
return FilterValues<float>();
|
|
else if (type == SearchDataType_Double)
|
|
return FilterValues<double>();
|
|
else if (type == SearchDataType_Int8)
|
|
return FilterValues<sint8>();
|
|
else if (type == SearchDataType_Int16)
|
|
return FilterValues<sint16>();
|
|
else if (type == SearchDataType_Int32)
|
|
return FilterValues<sint32>();
|
|
else if (type == SearchDataType_Int64)
|
|
return FilterValues<sint64>();
|
|
return {};
|
|
}
|
|
|
|
constexpr static int kGaugeStep = 0x10000;
|
|
|
|
template <typename T>
|
|
ListType_t SearchValues(T* ptr, uint32 size)
|
|
{
|
|
const auto value = m_textValue->GetValue();
|
|
const auto* string_value = value.c_str().AsChar();
|
|
const auto search_value = ConvertString<T>(string_value);
|
|
|
|
const auto* end = (T*)((uint8*)ptr + size - sizeof(T));
|
|
|
|
uint32 counter = 0;
|
|
std::vector<MEMPTR<void>> result;
|
|
for (; ptr < end; ++ptr)
|
|
{
|
|
if (!m_running)
|
|
return result;
|
|
|
|
const auto tmp = (betype<T>*)ptr;
|
|
if (equals(search_value, tmp->value()))
|
|
result.emplace_back(ptr);
|
|
|
|
counter += sizeof(T);
|
|
if(counter >= kGaugeStep)
|
|
{
|
|
wxQueueEvent(this, new wxSetGaugeValue(1, m_gauge));
|
|
counter -= kGaugeStep;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename T>
|
|
ListType_t FilterValues()
|
|
{
|
|
const auto value = m_textValue->GetValue();
|
|
const auto* string_value = value.c_str().AsChar();
|
|
const auto search_value = ConvertString<T>(string_value);
|
|
|
|
ListType_t newSearchBuffer;
|
|
newSearchBuffer.reserve(m_searchBuffer.size());
|
|
|
|
for (const auto& it : m_searchBuffer)
|
|
{
|
|
if (!m_running)
|
|
return newSearchBuffer;
|
|
|
|
const auto tmp = (betype<T>*)it.GetPtr();
|
|
if (equals(search_value , tmp->value()))
|
|
newSearchBuffer.emplace_back(it);
|
|
|
|
wxQueueEvent(this, new wxSetGaugeValue(1, m_gauge));
|
|
}
|
|
|
|
return newSearchBuffer;
|
|
}
|
|
|
|
wxDECLARE_EVENT_TABLE();
|
|
|
|
SearchDataType m_searchDataType = SearchDataType_None;
|
|
wxComboBox* m_cbDataType;
|
|
wxTextCtrl* m_textValue;
|
|
wxButton *m_buttonStart, *m_buttonFilter;
|
|
wxListCtrl* m_listResults;
|
|
wxDataViewListCtrl* m_listEntryTable;
|
|
wxStaticText* m_textEntryTable;
|
|
wxGauge* m_gauge;
|
|
wxTimer* m_refresh_timer;
|
|
|
|
ListType_t m_searchBuffer;
|
|
std::vector<TableEntry_t> m_tableEntries;
|
|
|
|
std::mutex m_mutex;
|
|
std::thread m_worker;
|
|
|
|
std::atomic_bool m_running = true;
|
|
std::atomic_bool m_search_running = false;
|
|
std::vector<std::future<ListType_t>> m_search_jobs;
|
|
|
|
bool m_clear_state = false;
|
|
};
|
|
|
|
template <>
|
|
bool MemorySearcherTool::ConvertStringToType(const char* inValue, sint8& outValue) const;
|
|
|
|
|
|
|
|
//
|
|
//template <typename T>
|
|
//void MemorySearcherTool::FilterValues()
|
|
//{
|
|
// auto s1 = m_textValue->GetValue();
|
|
// auto s2 = s1.c_str();
|
|
// auto stringValue = s2.AsChar();
|
|
//
|
|
// T filterValue;
|
|
// ConvertStringToType(stringValue, filterValue);
|
|
//
|
|
// std::vector<uint32> newSearchBuffer;
|
|
// newSearchBuffer.reserve(m_searchBuffer.size());
|
|
//
|
|
// uint32 gaugeValue = 0;
|
|
// uint32 count = m_searchBuffer.size();
|
|
// uint32 counter = 0;
|
|
//
|
|
// for (auto it = m_searchBuffer.begin(); it != m_searchBuffer.end(); ++it)
|
|
// {
|
|
// if (m_running)
|
|
// return;
|
|
//
|
|
// T value = memory_read<T>(*it);
|
|
// if constexpr (std::is_same<T, float>::value)
|
|
// {
|
|
// //float value1 = filterValue * 0.95f;
|
|
// float diff = filterValue - value;
|
|
// diff = fabs(diff);
|
|
// if(diff < value*0.05f)
|
|
// {
|
|
// newSearchBuffer.push_back(*it);
|
|
// }
|
|
//
|
|
// }
|
|
// else
|
|
// {
|
|
// if (value == filterValue)
|
|
// {
|
|
// newSearchBuffer.push_back(*it);
|
|
// }
|
|
// }
|
|
//
|
|
// ++counter;
|
|
// uint32 newValue = counter * 100 / count;
|
|
// if (newValue > gaugeValue + GAUGE_STEP_SIZE)
|
|
// {
|
|
// gaugeValue = newValue;
|
|
// m_gaugeValue = newValue;
|
|
// }
|
|
// }
|
|
//
|
|
// m_mutex.lock();
|
|
// m_searchBuffer = newSearchBuffer;
|
|
// m_gaugeValue = 100;
|
|
// m_mutex.unlock();
|
|
// m_isSearchFinished = true;
|
|
//}
|
|
//
|
|
|