Core: Start improving memory search

This commit is contained in:
Vicki Pfau 2017-10-14 15:36:51 -07:00
parent 264f238ec3
commit 591ab468e9
3 changed files with 151 additions and 141 deletions

View File

@ -13,9 +13,7 @@ CXX_GUARD_START
#include <mgba-util/vector.h> #include <mgba-util/vector.h>
enum mCoreMemorySearchType { enum mCoreMemorySearchType {
mCORE_MEMORY_SEARCH_32, mCORE_MEMORY_SEARCH_INT,
mCORE_MEMORY_SEARCH_16,
mCORE_MEMORY_SEARCH_8,
mCORE_MEMORY_SEARCH_STRING, mCORE_MEMORY_SEARCH_STRING,
mCORE_MEMORY_SEARCH_GUESS, mCORE_MEMORY_SEARCH_GUESS,
}; };
@ -23,11 +21,11 @@ enum mCoreMemorySearchType {
struct mCoreMemorySearchParams { struct mCoreMemorySearchParams {
int memoryFlags; int memoryFlags;
enum mCoreMemorySearchType type; enum mCoreMemorySearchType type;
int align;
int width;
union { union {
const char* valueStr; const char* valueStr;
uint32_t value32; uint32_t valueInt;
uint32_t value16;
uint32_t value8;
}; };
}; };
@ -35,7 +33,9 @@ struct mCoreMemorySearchResult {
uint32_t address; uint32_t address;
int segment; int segment;
uint64_t guessDivisor; uint64_t guessDivisor;
uint64_t guessMultiplier;
enum mCoreMemorySearchType type; enum mCoreMemorySearchType type;
int width;
}; };
DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult); DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult);

View File

@ -29,33 +29,41 @@ static size_t _search32(const void* mem, size_t size, const struct mCoreMemoryBl
if ((mask & 1) && (!limit || found < limit)) { if ((mask & 1) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i; res->address = start + i;
res->type = mCORE_MEMORY_SEARCH_32; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 4;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 2) && (!limit || found < limit)) { if ((mask & 2) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 4; res->address = start + i + 4;
res->type = mCORE_MEMORY_SEARCH_32; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 4;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 4) && (!limit || found < limit)) { if ((mask & 4) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 8; res->address = start + i + 8;
res->type = mCORE_MEMORY_SEARCH_32; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 4;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 8) && (!limit || found < limit)) { if ((mask & 8) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 12; res->address = start + i + 12;
res->type = mCORE_MEMORY_SEARCH_32; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 4;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
} }
@ -86,65 +94,81 @@ static size_t _search16(const void* mem, size_t size, const struct mCoreMemoryBl
if ((mask & 1) && (!limit || found < limit)) { if ((mask & 1) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i; res->address = start + i;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 2) && (!limit || found < limit)) { if ((mask & 2) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 2; res->address = start + i + 2;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 4) && (!limit || found < limit)) { if ((mask & 4) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 4; res->address = start + i + 4;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 8) && (!limit || found < limit)) { if ((mask & 8) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 6; res->address = start + i + 6;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 16) && (!limit || found < limit)) { if ((mask & 16) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 8; res->address = start + i + 8;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 32) && (!limit || found < limit)) { if ((mask & 32) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 10; res->address = start + i + 10;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 64) && (!limit || found < limit)) { if ((mask & 64) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 12; res->address = start + i + 12;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 128) && (!limit || found < limit)) { if ((mask & 128) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 14; res->address = start + i + 14;
res->type = mCORE_MEMORY_SEARCH_16; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 2;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
} }
@ -174,65 +198,81 @@ static size_t _search8(const void* mem, size_t size, const struct mCoreMemoryBlo
if ((mask & 1) && (!limit || found < limit)) { if ((mask & 1) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i; res->address = start + i;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 2) && (!limit || found < limit)) { if ((mask & 2) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 1; res->address = start + i + 1;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 4) && (!limit || found < limit)) { if ((mask & 4) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 2; res->address = start + i + 2;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 8) && (!limit || found < limit)) { if ((mask & 8) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 3; res->address = start + i + 3;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 16) && (!limit || found < limit)) { if ((mask & 16) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 4; res->address = start + i + 4;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 32) && (!limit || found < limit)) { if ((mask & 32) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 5; res->address = start + i + 5;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 64) && (!limit || found < limit)) { if ((mask & 64) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 6; res->address = start + i + 6;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
if ((mask & 128) && (!limit || found < limit)) { if ((mask & 128) && (!limit || found < limit)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i + 7; res->address = start + i + 7;
res->type = mCORE_MEMORY_SEARCH_8; res->type = mCORE_MEMORY_SEARCH_INT;
res->width = 1;
res->segment = -1; // TODO res->segment = -1; // TODO
res->guessDivisor = 1; res->guessDivisor = 1;
res->guessMultiplier = 1;
++found; ++found;
} }
} }
@ -240,18 +280,32 @@ static size_t _search8(const void* mem, size_t size, const struct mCoreMemoryBlo
return found; return found;
} }
static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, struct mCoreMemorySearchResults* out, size_t limit) { static size_t _searchInt(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) {
if (params->align == params->width || params->align == -1) {
switch (params->width) {
case 4:
return _search32(mem, size, block, params->valueInt, out, limit);
case 2:
return _search16(mem, size, block, params->valueInt, out, limit);
case 1:
return _search8(mem, size, block, params->valueInt, out, limit);
}
}
return 0;
}
static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, int len, struct mCoreMemorySearchResults* out, size_t limit) {
const char* memStr = mem; const char* memStr = mem;
size_t found = 0; size_t found = 0;
size_t len = strlen(valueStr);
uint32_t start = block->start; uint32_t start = block->start;
uint32_t end = size; // TODO: Segments uint32_t end = size; // TODO: Segments
size_t i; size_t i;
for (i = 0; (!limit || found < limit) && i < end - len; ++i) { for (i = 0; (!limit || found < limit) && i < end - len; ++i) {
if (!strncmp(valueStr, &memStr[i], len)) { if (!memcmp(valueStr, &memStr[i], len)) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out);
res->address = start + i; res->address = start + i;
res->type = mCORE_MEMORY_SEARCH_STRING; res->type = mCORE_MEMORY_SEARCH_STRING;
res->width = len;
res->segment = -1; // TODO res->segment = -1; // TODO
++found; ++found;
} }
@ -342,14 +396,10 @@ static size_t _searchGuess(const void* mem, size_t size, const struct mCoreMemor
static size_t _search(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) { static size_t _search(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) {
switch (params->type) { switch (params->type) {
case mCORE_MEMORY_SEARCH_32: case mCORE_MEMORY_SEARCH_INT:
return _search32(mem, size, block, params->value32, out, limit); return _searchInt(mem, size, block, params, out, limit);
case mCORE_MEMORY_SEARCH_16:
return _search16(mem, size, block, params->value16, out, limit);
case mCORE_MEMORY_SEARCH_8:
return _search8(mem, size, block, params->value8, out, limit);
case mCORE_MEMORY_SEARCH_STRING: case mCORE_MEMORY_SEARCH_STRING:
return _searchStr(mem, size, block, params->valueStr, out, limit); return _searchStr(mem, size, block, params->valueStr, params->width, out, limit);
case mCORE_MEMORY_SEARCH_GUESS: case mCORE_MEMORY_SEARCH_GUESS:
return _searchGuess(mem, size, block, params->valueStr, out, limit); return _searchGuess(mem, size, block, params->valueStr, out, limit);
} }
@ -384,26 +434,26 @@ bool _testGuess(struct mCore* core, const struct mCoreMemorySearchResult* res, c
value = strtoull(params->valueStr, &end, 10); value = strtoull(params->valueStr, &end, 10);
if (end) { if (end) {
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) { if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) { if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) { if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
} }
value = strtoull(params->valueStr, &end, 16); value = strtoull(params->valueStr, &end, 16);
if (end) { if (end) {
if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) { if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) { if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) { if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) {
return true; return true;
} }
} }
@ -415,69 +465,27 @@ void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchP
for (i = 0; i < mCoreMemorySearchResultsSize(inout); ++i) { for (i = 0; i < mCoreMemorySearchResultsSize(inout); ++i) {
struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsGetPointer(inout, i); struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsGetPointer(inout, i);
switch (res->type) { switch (res->type) {
case mCORE_MEMORY_SEARCH_8: case mCORE_MEMORY_SEARCH_INT:
switch (params->type) { switch (params->width) {
case mCORE_MEMORY_SEARCH_8: case 1:
if (core->rawRead8(core, res->address, res->segment) != params->value8) { if (core->rawRead8(core, res->address, res->segment) != params->valueInt) {
mCoreMemorySearchResultsShift(inout, i, 1); mCoreMemorySearchResultsShift(inout, i, 1);
--i; --i;
} }
break; break;
case mCORE_MEMORY_SEARCH_16: case 2:
if (core->rawRead8(core, res->address, res->segment) != params->value16) { if (core->rawRead8(core, res->address, res->segment) != params->valueInt) {
mCoreMemorySearchResultsShift(inout, i, 1); mCoreMemorySearchResultsShift(inout, i, 1);
--i; --i;
} }
break; break;
case mCORE_MEMORY_SEARCH_32: case 4:
if (core->rawRead32(core, res->address, res->segment) != params->value32) { if (core->rawRead32(core, res->address, res->segment) != params->valueInt) {
mCoreMemorySearchResultsShift(inout, i, 1); mCoreMemorySearchResultsShift(inout, i, 1);
--i; --i;
} }
break; break;
case mCORE_MEMORY_SEARCH_GUESS: case -1:
if (!_testGuess(core, res, params)) {
mCoreMemorySearchResultsShift(inout, i, 1);
--i;
}
break;
default:
break;
}
break;
case mCORE_MEMORY_SEARCH_16:
switch (params->type) {
case mCORE_MEMORY_SEARCH_16:
if (core->rawRead16(core, res->address, res->segment) != params->value16) {
mCoreMemorySearchResultsShift(inout, i, 1);
--i;
}
break;
case mCORE_MEMORY_SEARCH_32:
if (core->rawRead32(core, res->address, res->segment) != params->value32) {
mCoreMemorySearchResultsShift(inout, i, 1);
--i;
}
break;
case mCORE_MEMORY_SEARCH_GUESS:
if (!_testGuess(core, res, params)) {
mCoreMemorySearchResultsShift(inout, i, 1);
--i;
}
break;
default:
break;
}
break;
case mCORE_MEMORY_SEARCH_32:
switch (params->type) {
case mCORE_MEMORY_SEARCH_32:
if (core->rawRead32(core, res->address, res->segment) != params->value32) {
mCoreMemorySearchResultsShift(inout, i, 1);
--i;
}
break;
case mCORE_MEMORY_SEARCH_GUESS:
if (!_testGuess(core, res, params)) { if (!_testGuess(core, res, params)) {
mCoreMemorySearchResultsShift(inout, i, 1); mCoreMemorySearchResultsShift(inout, i, 1);
--i; --i;

View File

@ -41,49 +41,48 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
QByteArray string; QByteArray string;
bool ok = false; bool ok = false;
if (m_ui.typeNum->isChecked()) { if (m_ui.typeNum->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_INT;
params->align = -1;
if (m_ui.bits8->isChecked()) { if (m_ui.bits8->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_8; params->width = 1;
} }
if (m_ui.bits16->isChecked()) { if (m_ui.bits16->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_16; params->width = 2;
} }
if (m_ui.bits32->isChecked()) { if (m_ui.bits32->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_32; params->width = 4;
} }
if (m_ui.numHex->isChecked()) { if (m_ui.numHex->isChecked()) {
uint32_t v = m_ui.value->text().toUInt(&ok, 16); uint32_t v = m_ui.value->text().toUInt(&ok, 16);
if (ok) { if (ok) {
switch (params->type) { params->valueInt = v;
case mCORE_MEMORY_SEARCH_8: switch (params->width) {
case 1:
ok = v < 0x100; ok = v < 0x100;
params->value8 = v;
break; break;
case mCORE_MEMORY_SEARCH_16: case 2:
ok = v < 0x10000; ok = v < 0x10000;
params->value16 = v;
break; break;
case mCORE_MEMORY_SEARCH_32: case 4:
params->value32 = v;
break; break;
default: default:
ok = false; ok = false;
break;
} }
} }
} }
if (m_ui.numDec->isChecked()) { if (m_ui.numDec->isChecked()) {
uint32_t v = m_ui.value->text().toUInt(&ok, 10); uint32_t v = m_ui.value->text().toUInt(&ok, 10);
if (ok) { if (ok) {
switch (params->type) { params->valueInt = v;
case mCORE_MEMORY_SEARCH_8: switch (params->width) {
case 1:
ok = v < 0x100; ok = v < 0x100;
params->value8 = v;
break; break;
case mCORE_MEMORY_SEARCH_16: case 2:
ok = v < 0x10000; ok = v < 0x10000;
params->value16 = v;
break; break;
case mCORE_MEMORY_SEARCH_32: case 4:
params->value32 = v;
break; break;
default: default:
ok = false; ok = false;
@ -101,6 +100,7 @@ bool MemorySearch::createParams(mCoreMemorySearchParams* params) {
params->type = mCORE_MEMORY_SEARCH_STRING; params->type = mCORE_MEMORY_SEARCH_STRING;
m_string = m_ui.value->text().toLocal8Bit(); m_string = m_ui.value->text().toLocal8Bit();
params->valueStr = m_string.constData(); params->valueStr = m_string.constData();
params->width = m_ui.value->text().size();
ok = true; ok = true;
} }
return ok; return ok;
@ -145,61 +145,63 @@ void MemorySearch::refresh() {
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0'))); QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0')));
m_ui.results->setItem(i, 0, item); m_ui.results->setItem(i, 0, item);
QTableWidgetItem* type; QTableWidgetItem* type;
if (m_ui.numHex->isChecked()) { QByteArray string;
switch (result->type) { if (result->type == mCORE_MEMORY_SEARCH_INT && m_ui.numHex->isChecked()) {
case mCORE_MEMORY_SEARCH_8: switch (result->width) {
case 1:
item = new QTableWidgetItem(QString("%1").arg(core->rawRead8(core, result->address, result->segment), 2, 16, QChar('0'))); item = new QTableWidgetItem(QString("%1").arg(core->rawRead8(core, result->address, result->segment), 2, 16, QChar('0')));
break; break;
case mCORE_MEMORY_SEARCH_16: case 2:
item = new QTableWidgetItem(QString("%1").arg(core->rawRead16(core, result->address, result->segment), 4, 16, QChar('0'))); item = new QTableWidgetItem(QString("%1").arg(core->rawRead16(core, result->address, result->segment), 4, 16, QChar('0')));
break; break;
case mCORE_MEMORY_SEARCH_GUESS: case 4:
case mCORE_MEMORY_SEARCH_32:
item = new QTableWidgetItem(QString("%1").arg(core->rawRead32(core, result->address, result->segment), 8, 16, QChar('0'))); item = new QTableWidgetItem(QString("%1").arg(core->rawRead32(core, result->address, result->segment), 8, 16, QChar('0')));
break; break;
case mCORE_MEMORY_SEARCH_STRING:
item = new QTableWidgetItem("?"); // TODO
} }
} else { } else {
switch (result->type) { switch (result->type) {
case mCORE_MEMORY_SEARCH_8: case mCORE_MEMORY_SEARCH_INT:
switch (result->width) {
case 1:
item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment))); item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment)));
break; break;
case mCORE_MEMORY_SEARCH_16: case 2:
item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment))); item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment)));
break; break;
case mCORE_MEMORY_SEARCH_GUESS: case 4:
case mCORE_MEMORY_SEARCH_32:
item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment))); item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment)));
break; break;
}
break;
case mCORE_MEMORY_SEARCH_STRING: case mCORE_MEMORY_SEARCH_STRING:
item = new QTableWidgetItem("?"); // TODO string.reserve(result->width);
for (int i = 0; i < result->width; ++i) {
string.append(core->rawRead8(core, result->address + i, result->segment));
}
item = new QTableWidgetItem(QLatin1String(string)); // TODO
} }
} }
QString divisor; QString divisor;
if (result->guessDivisor > 1) { if (result->guessDivisor > 1) {
if (result->guessMultiplier > 1) {
divisor = tr(" (%0/%1×)").arg(result->guessMultiplier).arg(result->guessMultiplier);
} else {
divisor = tr(" (⅟%0×)").arg(result->guessDivisor); divisor = tr(" (⅟%0×)").arg(result->guessDivisor);
} }
} else if (result->guessMultiplier > 1) {
divisor = tr(" (%0×)").arg(result->guessMultiplier);
}
switch (result->type) { switch (result->type) {
case mCORE_MEMORY_SEARCH_8: case mCORE_MEMORY_SEARCH_INT:
type = new QTableWidgetItem(tr("1 byte%0").arg(divisor)); type = new QTableWidgetItem(tr("%1 byte%2").arg(result->width).arg(divisor));
break;
case mCORE_MEMORY_SEARCH_16:
type = new QTableWidgetItem(tr("2 bytes%0").arg(divisor));
break;
case mCORE_MEMORY_SEARCH_GUESS:
case mCORE_MEMORY_SEARCH_32:
type = new QTableWidgetItem(tr("4 bytes%0").arg(divisor));
break; break;
case mCORE_MEMORY_SEARCH_STRING: case mCORE_MEMORY_SEARCH_STRING:
item = new QTableWidgetItem("?"); // TODO type = new QTableWidgetItem("string");
} }
m_ui.results->setItem(i, 1, item); m_ui.results->setItem(i, 1, item);
m_ui.results->setItem(i, 2, type); m_ui.results->setItem(i, 2, type);
} }
m_ui.results->sortItems(0); m_ui.results->sortItems(0);
m_ui.results->resizeColumnsToContents();
m_ui.results->resizeRowsToContents();
} }
void MemorySearch::openMemory() { void MemorySearch::openMemory() {