chore: decompose TestAllCommands
This commit is contained in:
164
src/app/rom.cc
164
src/app/rom.cc
@@ -245,80 +245,86 @@ Bytes CreateCompressionString(std::shared_ptr<CompressionPiece>& start,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test every command to see the gain with current position
|
void CheckByteRepeat(const uchar* rom_data, DataSizeArray& data_size_taken,
|
||||||
void TestAllCommands(const uchar* rom_data, DataSizeArray& data_size_taken,
|
|
||||||
CommandArgumentArray& cmd_args, uint& src_data_pos,
|
CommandArgumentArray& cmd_args, uint& src_data_pos,
|
||||||
const uint last_pos, uint start) {
|
const uint last_pos) {
|
||||||
{ // BYTE REPEAT
|
uint pos = src_data_pos;
|
||||||
uint pos = src_data_pos;
|
char byte_to_repeat = rom_data[pos];
|
||||||
char byte_to_repeat = rom_data[pos];
|
while (pos <= last_pos && rom_data[pos] == byte_to_repeat) {
|
||||||
while (pos <= last_pos && rom_data[pos] == byte_to_repeat) {
|
data_size_taken[kCommandByteFill]++;
|
||||||
data_size_taken[kCommandByteFill]++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
cmd_args[kCommandByteFill][0] = byte_to_repeat;
|
|
||||||
}
|
|
||||||
{ // WORD REPEAT
|
|
||||||
if (src_data_pos + 2 <= last_pos &&
|
|
||||||
rom_data[src_data_pos] != rom_data[src_data_pos + 1]) {
|
|
||||||
uint pos = src_data_pos;
|
|
||||||
char byte1 = rom_data[pos];
|
|
||||||
char byte2 = rom_data[pos + 1];
|
|
||||||
pos += 2;
|
|
||||||
data_size_taken[kCommandWordFill] = 2;
|
|
||||||
while (pos + 1 <= last_pos) {
|
|
||||||
if (rom_data[pos] == byte1 && rom_data[pos + 1] == byte2)
|
|
||||||
data_size_taken[kCommandWordFill] += 2;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
pos += 2;
|
|
||||||
}
|
|
||||||
cmd_args[kCommandWordFill][0] = byte1;
|
|
||||||
cmd_args[kCommandWordFill][1] = byte2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{ // INC BYTE
|
|
||||||
uint pos = src_data_pos;
|
|
||||||
char byte = rom_data[pos];
|
|
||||||
pos++;
|
pos++;
|
||||||
data_size_taken[kCommandIncreasingFill] = 1;
|
|
||||||
byte++;
|
|
||||||
while (pos <= last_pos && byte == rom_data[pos]) {
|
|
||||||
data_size_taken[kCommandIncreasingFill]++;
|
|
||||||
byte++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
cmd_args[kCommandIncreasingFill][0] = rom_data[src_data_pos];
|
|
||||||
}
|
}
|
||||||
{ // INTRA CPY
|
cmd_args[kCommandByteFill][0] = byte_to_repeat;
|
||||||
if (src_data_pos != start) {
|
}
|
||||||
uint searching_pos = start;
|
|
||||||
uint current_pos_u = src_data_pos;
|
|
||||||
uint copied_size = 0;
|
|
||||||
uint search_start = start;
|
|
||||||
|
|
||||||
while (searching_pos < src_data_pos && current_pos_u <= last_pos) {
|
void CheckWordRepeat(const uchar* rom_data, DataSizeArray& data_size_taken,
|
||||||
while (rom_data[current_pos_u] != rom_data[searching_pos] &&
|
CommandArgumentArray& cmd_args, uint& src_data_pos,
|
||||||
searching_pos < src_data_pos)
|
const uint last_pos) {
|
||||||
searching_pos++;
|
if (src_data_pos + 2 <= last_pos &&
|
||||||
search_start = searching_pos;
|
rom_data[src_data_pos] != rom_data[src_data_pos + 1]) {
|
||||||
while (current_pos_u <= last_pos &&
|
uint pos = src_data_pos;
|
||||||
rom_data[current_pos_u] == rom_data[searching_pos] &&
|
char byte1 = rom_data[pos];
|
||||||
searching_pos < src_data_pos) {
|
char byte2 = rom_data[pos + 1];
|
||||||
copied_size++;
|
pos += 2;
|
||||||
current_pos_u++;
|
data_size_taken[kCommandWordFill] = 2;
|
||||||
searching_pos++;
|
while (pos + 1 <= last_pos) {
|
||||||
}
|
if (rom_data[pos] == byte1 && rom_data[pos + 1] == byte2)
|
||||||
if (copied_size > data_size_taken[kCommandRepeatingBytes]) {
|
data_size_taken[kCommandWordFill] += 2;
|
||||||
search_start -= start;
|
else
|
||||||
printf("- Found repeat of %d at %d\n", copied_size, search_start);
|
break;
|
||||||
data_size_taken[kCommandRepeatingBytes] = copied_size;
|
pos += 2;
|
||||||
cmd_args[kCommandRepeatingBytes][0] = search_start & SNES_BYTE_MAX;
|
}
|
||||||
cmd_args[kCommandRepeatingBytes][1] = search_start >> 8;
|
cmd_args[kCommandWordFill][0] = byte1;
|
||||||
}
|
cmd_args[kCommandWordFill][1] = byte2;
|
||||||
current_pos_u = src_data_pos;
|
}
|
||||||
copied_size = 0;
|
}
|
||||||
|
|
||||||
|
void CheckIncByte(const uchar* rom_data, DataSizeArray& data_size_taken,
|
||||||
|
CommandArgumentArray& cmd_args, uint& src_data_pos,
|
||||||
|
const uint last_pos) {
|
||||||
|
uint pos = src_data_pos;
|
||||||
|
char byte = rom_data[pos];
|
||||||
|
pos++;
|
||||||
|
data_size_taken[kCommandIncreasingFill] = 1;
|
||||||
|
byte++;
|
||||||
|
while (pos <= last_pos && byte == rom_data[pos]) {
|
||||||
|
data_size_taken[kCommandIncreasingFill]++;
|
||||||
|
byte++;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
cmd_args[kCommandIncreasingFill][0] = rom_data[src_data_pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckIntraCopy(const uchar* rom_data, DataSizeArray& data_size_taken,
|
||||||
|
CommandArgumentArray& cmd_args, uint& src_data_pos,
|
||||||
|
const uint last_pos, uint start) {
|
||||||
|
if (src_data_pos != start) {
|
||||||
|
uint searching_pos = start;
|
||||||
|
uint current_pos_u = src_data_pos;
|
||||||
|
uint copied_size = 0;
|
||||||
|
uint search_start = start;
|
||||||
|
|
||||||
|
while (searching_pos < src_data_pos && current_pos_u <= last_pos) {
|
||||||
|
while (rom_data[current_pos_u] != rom_data[searching_pos] &&
|
||||||
|
searching_pos < src_data_pos)
|
||||||
|
searching_pos++;
|
||||||
|
search_start = searching_pos;
|
||||||
|
while (current_pos_u <= last_pos &&
|
||||||
|
rom_data[current_pos_u] == rom_data[searching_pos] &&
|
||||||
|
searching_pos < src_data_pos) {
|
||||||
|
copied_size++;
|
||||||
|
current_pos_u++;
|
||||||
|
searching_pos++;
|
||||||
}
|
}
|
||||||
|
if (copied_size > data_size_taken[kCommandRepeatingBytes]) {
|
||||||
|
search_start -= start;
|
||||||
|
printf("- Found repeat of %d at %d\n", copied_size, search_start);
|
||||||
|
data_size_taken[kCommandRepeatingBytes] = copied_size;
|
||||||
|
cmd_args[kCommandRepeatingBytes][0] = search_start & SNES_BYTE_MAX;
|
||||||
|
cmd_args[kCommandRepeatingBytes][1] = search_start >> 8;
|
||||||
|
}
|
||||||
|
current_pos_u = src_data_pos;
|
||||||
|
copied_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,8 +430,14 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
|
|||||||
data_size_taken.fill({});
|
data_size_taken.fill({});
|
||||||
cmd_args.fill({{}});
|
cmd_args.fill({{}});
|
||||||
|
|
||||||
TestAllCommands(rom_data_.data(), data_size_taken, cmd_args, src_data_pos,
|
CheckByteRepeat(rom_data_.data(), data_size_taken, cmd_args, src_data_pos,
|
||||||
last_pos, start);
|
last_pos);
|
||||||
|
CheckWordRepeat(rom_data_.data(), data_size_taken, cmd_args, src_data_pos,
|
||||||
|
last_pos);
|
||||||
|
CheckIncByte(rom_data_.data(), data_size_taken, cmd_args, src_data_pos,
|
||||||
|
last_pos);
|
||||||
|
CheckIntraCopy(rom_data_.data(), data_size_taken, cmd_args, src_data_pos,
|
||||||
|
last_pos, start);
|
||||||
|
|
||||||
uint max_win = 2;
|
uint max_win = 2;
|
||||||
uint cmd_with_max = kCommandDirectCopy;
|
uint cmd_with_max = kCommandDirectCopy;
|
||||||
@@ -512,19 +524,19 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, bool reversed) {
|
|||||||
buffer_pos += length;
|
buffer_pos += length;
|
||||||
offset += length;
|
offset += length;
|
||||||
break;
|
break;
|
||||||
case kCommandByteFill: // Advances 1 byte in the ROM
|
case kCommandByteFill:
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
buffer[buffer_pos++] = rom_data_[offset];
|
buffer[buffer_pos++] = rom_data_[offset];
|
||||||
offset += 1;
|
offset += 1; // Advances 1 byte in the ROM
|
||||||
break;
|
break;
|
||||||
case kCommandWordFill: // Advance 2 byte in the ROM
|
case kCommandWordFill:
|
||||||
for (int i = 0; i < length; i += 2) {
|
for (int i = 0; i < length; i += 2) {
|
||||||
buffer[buffer_pos] = rom_data_[offset];
|
buffer[buffer_pos] = rom_data_[offset];
|
||||||
buffer_pos++;
|
buffer_pos++;
|
||||||
buffer[buffer_pos] = rom_data_[offset + 1];
|
buffer[buffer_pos] = rom_data_[offset + 1];
|
||||||
buffer_pos++;
|
buffer_pos++;
|
||||||
}
|
}
|
||||||
offset += 2;
|
offset += 2; // Advance 2 byte in the ROM
|
||||||
break;
|
break;
|
||||||
case kCommandIncreasingFill: {
|
case kCommandIncreasingFill: {
|
||||||
uchar inc_byte = rom_data_[offset];
|
uchar inc_byte = rom_data_[offset];
|
||||||
@@ -541,7 +553,7 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, bool reversed) {
|
|||||||
auto addr = (rom_data_[offset + 2]) | ((rom_data_[offset + 1]) << 8);
|
auto addr = (rom_data_[offset + 2]) | ((rom_data_[offset + 1]) << 8);
|
||||||
if (addr > offset) {
|
if (addr > offset) {
|
||||||
return absl::InternalError(absl::StrFormat(
|
return absl::InternalError(absl::StrFormat(
|
||||||
"DecompressOverworldV2: Offset for command copy exceeds "
|
"DecompressOverworld: Offset for command copy exceeds "
|
||||||
"current position (Offset : %#04x | Pos : %#06x)\n",
|
"current position (Offset : %#04x | Pos : %#06x)\n",
|
||||||
addr, offset));
|
addr, offset));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user