chore: decompose TestAllCommands

This commit is contained in:
Justin Scofield
2022-08-17 10:13:13 -04:00
parent 1f50a6a61a
commit 1bcbd9e1f3

View File

@@ -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));
} }