Begin writing decompression block.

master
sigonasr2 5 months ago
parent 759fcd26e1
commit 29f1ac7777
  1. 98
      EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp

@ -54,6 +54,79 @@ struct Rom{
uint32_t readInt32(){ uint32_t readInt32(){
return readInt8()|(readInt8()<<8)|(readInt8()<<16)|(readInt8()<<24); return readInt8()|(readInt8()<<8)|(readInt8()<<16)|(readInt8()<<24);
} }
uint32_t getCompressedSize(uint32_t pointer){
uint32_t bpos{};
uint32_t pos{pointer};
uint32_t bpos2{};
while(data[pos]!=0xFF){
if(pos>=data.length())throw std::runtime_error{"Unexpected end of data."};
char commandType{data[pos]>>5};
char length{(data[pos]&0x1F)+1};
if(commandType==7){
commandType=(data[pos]&0x1C)>>2;
length=((data[pos]&3)<<8)+(data[pos+1])+1;
++pos;
}
if(bpos+length<0)throw std::runtime_error("Length ended up negative.");
pos++;
if(commandType>=4){
bpos2=(data[pos]<<8)+data[pos+1];
if(bpos2<0)throw std::runtime_error("Reading negative data.");
pos+=2;
}
switch(commandType){
case UNCOMPRESSED_BLOCK:{
bpos+=length;
pos+=length;
}break;
case RUN_LENGTH_ENCODED_BYTE:{
bpos+=length;
++pos;
}break;
case RUN_LENGTH_ENCODED_SHORT:{
if(bpos<0)throw std::runtime_error("Reading negative data while reading RLE short.");
bpos+=2*length;
pos+=2;
}break;
case INCREMENTAL_SEQUENCE:{
bpos+=length;
++pos;
}break;
case REPEAT_PREVIOUS_DATA:{
if(bpos2<0)throw std::runtime_error("Reading negative data while repeating previous data.");
bpos+=length;
}break;
case REVERSE_BITS:{
if(bpos2<0)throw std::runtime_error("Reading negative data while reversing bits.");
bpos+=length;
}break;
case UNKNOWN_1:{
if(bpos2-length+1<0)throw std::runtime_error("Unexpected error in Unkonwn 1.");
bpos+=length;
}break;
case UNKNOWN_2:{throw std::runtime_error("Reached unexpected command.");}break;
}
}
return bpos;
}
std::vector<uint16_t>decompress(){
uint32_t size{getCompressedSize(ptr)};
if(size<1)throw std::runtime_error(std::format("Got an invalid data size of {}",size));
std::vector<uint16_t>blockOutput;
blockOutput.resize(size);
decompressBlock(ptr,blockOutput);
}
private:
void decompressBlock(uint32_t ptrStart,std::vector<uint16_t>&block){
size_t maxLength{block.size()};
uint32_t pos{ptrStart};
uint32_t bpos{};
uint32_t bpos2{};
int read{};
while(data[pos]!=0xFF){
}
}
}; };
struct BattleBackground{ struct BattleBackground{
@ -106,9 +179,19 @@ struct Rom{
} }
} }
}; };
using Tile=std::array<std::array<int,8>,8>;
struct BackgroundGraphics{
std::vector<uint16_t>graphicsData;
std::vector<Tile>tiles;
BackgroundGraphics(std::string_view data,uint16_t index,byte bpp){
DataBlock graphicsPointer{data,0xD7A1U+index*4U};
graphicsPointer.decompress();
}
};
std::string data; std::string data;
std::vector<BattleBackground>backgrounds; std::vector<BattleBackground>backgrounds;
std::vector<BackgroundPalette>palettes; std::vector<BackgroundPalette>palettes;
std::vector<BackgroundGraphics>graphics;
Rom(){ Rom(){
std::ifstream dataStream{"truncated_backgrounds.dat",std::ios_base::binary}; std::ifstream dataStream{"truncated_backgrounds.dat",std::ios_base::binary};
while(dataStream.good())data+=dataStream.get(); while(dataStream.good())data+=dataStream.get();
@ -121,6 +204,9 @@ struct Rom{
for(uint16_t i:std::views::iota(0U,paletteBits.size())){ for(uint16_t i:std::views::iota(0U,paletteBits.size())){
palettes.emplace_back(data,i,paletteBits[i]); palettes.emplace_back(data,i,paletteBits[i]);
} }
for(uint16_t i:std::views::iota(0U,graphicsBits.size())){
}
} }
}; };
@ -144,10 +230,7 @@ public:
return true; return true;
} }
int yOffset{0}; void PaletteDisplayTest(){
bool OnUserUpdate(float fElapsedTime) override
{
if(GetMouseWheel()<0)yOffset-=32; if(GetMouseWheel()<0)yOffset-=32;
if(GetMouseWheel()>0)yOffset+=32; if(GetMouseWheel()>0)yOffset+=32;
@ -158,6 +241,13 @@ public:
} }
row++; row++;
} }
}
int yOffset{0};
bool OnUserUpdate(float fElapsedTime) override
{
PaletteDisplayTest();
return true; return true;
} }
}; };

Loading…
Cancel
Save