bug: fix decompress word fill issue
* decompression on vanilla 1mb ROMs was having issues
This commit is contained in:
@@ -499,43 +499,47 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, bool reversed) {
|
|||||||
Bytes buffer(size, 0);
|
Bytes buffer(size, 0);
|
||||||
uint length = 0;
|
uint length = 0;
|
||||||
uint buffer_pos = 0;
|
uint buffer_pos = 0;
|
||||||
uchar cmd = 0;
|
uchar command = 0;
|
||||||
uchar databyte = rom_data_[offset];
|
uchar header = rom_data_[offset];
|
||||||
while (databyte != SNES_BYTE_MAX) { // End of decompression
|
|
||||||
if ((databyte & CMD_EXPANDED_MOD) == CMD_EXPANDED_MOD) {
|
while (header != SNES_BYTE_MAX) {
|
||||||
|
if ((header & CMD_EXPANDED_MOD) == CMD_EXPANDED_MOD) {
|
||||||
// Expanded Command
|
// Expanded Command
|
||||||
cmd = ((databyte >> 2) & CMD_MOD);
|
command = ((header >> 2) & CMD_MOD);
|
||||||
length =
|
length =
|
||||||
(((databyte << 8) | rom_data_[offset + 1]) & CMD_EXPANDED_LENGTH_MOD);
|
(((header << 8) | rom_data_[offset + 1]) & CMD_EXPANDED_LENGTH_MOD);
|
||||||
offset += 2; // Advance 2 bytes in ROM
|
offset += 2; // Advance 2 bytes in ROM
|
||||||
} else {
|
} else {
|
||||||
// Normal Command
|
// Normal Command
|
||||||
cmd = ((databyte >> 5) & CMD_MOD);
|
command = ((header >> 5) & CMD_MOD);
|
||||||
length = (databyte & CMD_NORMAL_LENGTH_MOD);
|
length = (header & CMD_NORMAL_LENGTH_MOD);
|
||||||
offset += 1; // Advance 1 byte in ROM
|
offset += 1; // Advance 1 byte in ROM
|
||||||
}
|
}
|
||||||
length += 1; // each commands is at least of size 1 even if index 00
|
length += 1; // each commands is at least of size 1 even if index 00
|
||||||
|
|
||||||
switch (cmd) {
|
switch (command) {
|
||||||
case kCommandDirectCopy: // Does not advance in the ROM
|
case kCommandDirectCopy: // Does not advance in the ROM
|
||||||
memcpy(buffer.data() + buffer_pos, rom_data_.data() + offset, length);
|
memcpy(buffer.data() + buffer_pos, rom_data_.data() + offset, length);
|
||||||
buffer_pos += length;
|
buffer_pos += length;
|
||||||
offset += length;
|
offset += length;
|
||||||
break;
|
break;
|
||||||
case kCommandByteFill:
|
case kCommandByteFill:
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++) {
|
||||||
buffer[buffer_pos++] = rom_data_[offset];
|
|
||||||
offset += 1; // Advances 1 byte in the ROM
|
|
||||||
break;
|
|
||||||
case kCommandWordFill:
|
|
||||||
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_pos++;
|
|
||||||
}
|
}
|
||||||
offset += 2; // Advance 2 byte in the ROM
|
offset += 1; // Advances 1 byte in the ROM
|
||||||
break;
|
break;
|
||||||
|
case kCommandWordFill: {
|
||||||
|
auto a = rom_data_[offset + 1];
|
||||||
|
auto b = rom_data_[offset + 2];
|
||||||
|
for (int i = 0; i < length; i = i + 2) {
|
||||||
|
buffer[buffer_pos + i] = a;
|
||||||
|
if ((i + 1) < length) buffer[buffer_pos + i + 1] = b;
|
||||||
|
}
|
||||||
|
buffer_pos += length;
|
||||||
|
offset += 2; // Advance 2 byte in the ROM
|
||||||
|
} break;
|
||||||
case kCommandIncreasingFill: {
|
case kCommandIncreasingFill: {
|
||||||
uchar inc_byte = rom_data_[offset];
|
uchar inc_byte = rom_data_[offset];
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
@@ -574,11 +578,11 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, bool reversed) {
|
|||||||
std::cout << absl::StrFormat(
|
std::cout << absl::StrFormat(
|
||||||
"DecompressOverworld: Invalid command in header for "
|
"DecompressOverworld: Invalid command in header for "
|
||||||
"decompression (Offset : %#06x, Command: %#04x)\n",
|
"decompression (Offset : %#06x, Command: %#04x)\n",
|
||||||
offset, cmd);
|
offset, command);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
// check next byte
|
// check next byte
|
||||||
databyte = rom_data_[offset];
|
header = rom_data_[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user