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