Updated the file loading to C++ standard as well as adding zarby's decompress function
This commit is contained in:
@@ -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
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user