Updated the file loading to C++ standard as well as adding zarby's decompress function

This commit is contained in:
Justin Scofield
2022-06-12 22:13:50 -04:00
parent 41643a7fd4
commit 8b466d4646
2 changed files with 110 additions and 34 deletions

View File

@@ -1,27 +1,30 @@
#include "ROM.h"
#include <filesystem>
namespace yaze {
namespace Application {
namespace Data {
void ROM::LoadFromFile(const std::string &path) {
FILE *file = fopen(path.c_str(), "r+");
if (file == NULL) return;
fseek(file, 0, SEEK_END);
size = ftell(file);
fclose(file);
type_ = LoROM;
size_ = std::filesystem::file_size(path.c_str());
std::ifstream file(path.c_str(), std::ios::binary);
if (!file.is_open()) {
std::cout << "Error: Could not open ROM file " << path << std::endl;
}
current_rom_ = new unsigned char[size_];
data_ = new char[size_];
// Reading data to array of unsigned chars
file = fopen(path.c_str(), "r+");
current_rom_ = (unsigned char *)malloc(size);
rom_data_ = (char *)malloc(size);
fread(rom_data_, sizeof(char), size, file);
int bytes_read = fread(current_rom_, sizeof(unsigned char), size, file);
fclose(file);
for (unsigned int i = 0; i < size_; i++) {
char byte_read_ = ' ';
file.read(&byte_read_, sizeof(char));
current_rom_[i] = byte_read_;
data_[i] = byte_read_;
}
memcpy(title, rom_data_ + 32704, 21);
type = LoROM;
version = current_rom_[27];
memcpy(title, data_ + 32704, 21);
version_ = current_rom_[27];
loaded = true;
}
@@ -35,17 +38,19 @@ std::vector<tile8> ROM::ExtractTiles(TilePreset &preset) {
filePos = getRomPosition(preset, tilePos, preset.SNESTilesLocation);
std::cout << "ROM Position: " << filePos << " from "
<< preset.SNESTilesLocation << std::endl;
// decompress the graphics
char *data = (char *)malloc(sizeof(char) * size);
memcpy(data, (rom_data_ + filePos), size);
data = alttp_decompress_gfx(data, 0, size, &size_out, &lastCompressedSize);
std::cout << "size: " << size << std::endl;
std::cout << "lastCompressedSize: " << lastCompressedSize << std::endl;
memcpy(data, (data_ + filePos), size);
//data = alttp_decompress_gfx(data, 0, size, &size_out, &compressed_size_);
// std::cout << "size: " << size << std::endl;
// std::cout << "lastCompressedSize: " << compressed_size_ << std::endl;
data = Decompress(filePos);
if (data == NULL) {
std::cout << alttp_decompression_error << std::endl;
return rawTiles;
}
// unpack the tiles based on their depth
unsigned tileCpt = 0;
std::cout << "Unpacking tiles..." << std::endl;
@@ -67,7 +72,7 @@ SNESPalette ROM::ExtractPalette(TilePreset &preset) {
std::cout << "Palette pos : " << filePos << std::endl; // TODO: make this hex
unsigned int palette_size = pow(2, preset.bpp); // - 1;
char *ab = (char *)malloc(sizeof(char) * (palette_size * 2));
memcpy(ab, rom_data_ + filePos, palette_size * 2);
memcpy(ab, data_ + filePos, palette_size * 2);
for (int i = 0; i < palette_size; i++) {
std::cout << ab[i];
@@ -90,7 +95,6 @@ SNESPalette ROM::ExtractPalette(TilePreset &preset) {
unsigned int ROM::getRomPosition(const TilePreset &preset, int directAddr,
unsigned int snesAddr) {
bool romHasHeader = false; // romInfo.hasHeader
if (overrideHeaderInfo) romHasHeader = overridenHeaderInfo;
unsigned int filePos = -1;
enum rom_type rType = LoROM;
std::cout << "ROM::getRomPosition: directAddr:" << directAddr << std::endl;
@@ -112,6 +116,79 @@ short ROM::AddressFromBytes(byte addr1, byte addr2) {
return (short)((addr1 << 8) | (addr2));
}
char *ROM::Decompress(int pos, bool reversed) {
char *buffer = new char[0x600];
for (int i = 0; i < 0x600; i++) {
buffer[i] = 0;
}
unsigned int bufferPos = 0;
unsigned char cmd = 0;
unsigned int length = 0;
unsigned char databyte = (unsigned char)data_[pos];
while (true) {
databyte = (unsigned char)data_[pos];
if (databyte == 0xFF) // End of decompression
{
break;
}
if ((databyte & 0xE0) == 0xE0) // Expanded Command
{
cmd = (unsigned char)((databyte >> 2) & 0x07);
length = (unsigned short)(((data_[pos] << 8) | data_[pos + 1]) & 0x3FF);
pos += 2; // Advance 2 bytes in ROM
} else // Normal Command
{
cmd = (unsigned char)((databyte >> 5) & 0x07);
length = (unsigned char)(databyte & 0x1F);
pos += 1; // Advance 1 byte in ROM
}
length += 1; // Every commands are at least 1 size even if 00
switch (cmd) {
case 00: // Direct Copy (Could be replaced with a MEMCPY)
for (int i = 0; i < length; i++) {
buffer[bufferPos++] = (unsigned char)data_[pos++];
}
// Do not advance in the ROM
break;
case 01: // Byte Fill
for (int i = 0; i < length; i++) {
buffer[bufferPos++] = (unsigned char)data_[pos];
}
pos += 1; // Advance 1 byte in the ROM
break;
case 02: // Word Fill
for (int i = 0; i < length; i++) {
buffer[bufferPos++] = (unsigned char)data_[pos];
buffer[bufferPos++] = (unsigned char)data_[pos + 1];
}
pos += 2; // Advance 2 byte in the ROM
break;
case 03: // Increasing Fill
{
unsigned char incByte = (unsigned char)data_[pos];
for (int i = 0; i < (unsigned int)length; i++) {
buffer[bufferPos++] = (unsigned char)incByte++;
}
pos += 1; // Advance 1 byte in the ROM
} break;
case 04: // Repeat (Reversed byte order for maps)
{
unsigned short s1 = ((data_[pos + 1] & 0xFF) << 8);
unsigned short s2 = ((data_[pos] & 0xFF));
unsigned short Addr = (unsigned short)(s1 | s2);
printf("Repeat Address : %4X", Addr);
for (int i = 0; i < length; i++) {
buffer[bufferPos] = (unsigned char)buffer[Addr + i];
bufferPos++;
}
pos += 2; // Advance 2 bytes in the ROM
} break;
}
}
return buffer;
}
} // namespace Data
} // namespace Application
} // namespace yaze

View File

@@ -35,28 +35,27 @@ class ROM {
unsigned int getRomPosition(const TilePreset& preset, int directAddr,
unsigned int snesAddr);
short AddressFromBytes(byte addr1, byte addr2);
char* Decompress(int pos, bool reversed = false);
inline byte* GetRawData() { return current_rom_; }
const unsigned char* getTitle() const { return title; }
unsigned int getSize() const { return size; }
char getVersion() const { return version; }
unsigned int getSize() const { return size_; }
char getVersion() const { return version_; }
bool isLoaded() const { return loaded; }
private:
bool loaded = false;
byte* current_rom_;
char* rom_data_;
char* data_;
bool fastrom;
long int size;
enum rom_type type;
long int size_;
enum rom_type type_;
bool overrideHeaderInfo;
bool overridenHeaderInfo;
unsigned int lastUnCompressSize;
unsigned int lastCompressedSize;
unsigned int lastCompressSize;
unsigned char version;
unsigned int uncompressed_size_;
unsigned int compressed_size_;
unsigned int compress_size_;
unsigned char version_;
unsigned char title[21] = "ROM Not Loaded";
};