Use fast types instead. Add DistortionEffect class. Fix up BackgroundLayer class to not include PGE layer arguments anymore.

master
sigonasr2 5 months ago
parent d1837503e0
commit 41ab66d4c9
  1. 7
      .vs/VSWorkspaceState.json
  2. 107
      EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp

@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\EarthboundBattleBackgrounds.sln",
"PreviewInSolutionExplorer": false
}

@ -8,10 +8,10 @@
using namespace olc; using namespace olc;
struct Rom{ struct Rom{
const static uint16_t MIN_INDEX{}; const static uint_fast16_t MIN_INDEX{};
const static uint16_t MAX_INDEX{326U}; const static uint_fast16_t MAX_INDEX{326U};
std::array<uint32_t,114>paletteBits; std::array<uint_fast32_t,114>paletteBits;
std::array<uint32_t,103>graphicsBits; std::array<uint_fast32_t,103>graphicsBits;
enum Command{ enum Command{
UNCOMPRESSED_BLOCK, UNCOMPRESSED_BLOCK,
RUN_LENGTH_ENCODED_BYTE, RUN_LENGTH_ENCODED_BYTE,
@ -23,8 +23,8 @@ struct Rom{
UNKNOWN_2, UNKNOWN_2,
}; };
static uint32_t snesToHex(uint32_t addr,bool header=true){ static uint_fast32_t snesToHex(uint_fast32_t addr,bool header=true){
uint32_t newAddr{addr}; uint_fast32_t newAddr{addr};
if(newAddr>=0x400000&&newAddr<0x600000);//NO-OP if(newAddr>=0x400000&&newAddr<0x600000);//NO-OP
else if(newAddr>=0xC00000&&newAddr<0x1000000)newAddr-=0xC00000; else if(newAddr>=0xC00000&&newAddr<0x1000000)newAddr-=0xC00000;
else throw std::out_of_range{std::format("SNES address out of range: {}",newAddr)}; else throw std::out_of_range{std::format("SNES address out of range: {}",newAddr)};
@ -32,8 +32,8 @@ struct Rom{
if(header)newAddr+=0x200; if(header)newAddr+=0x200;
return newAddr-0xA0200; return newAddr-0xA0200;
} }
static uint32_t hexToSnes(uint32_t addr,bool header=true){ static uint_fast32_t hexToSnes(uint_fast32_t addr,bool header=true){
uint32_t newAddr{addr}; uint_fast32_t newAddr{addr};
if(header)newAddr-=0x200; if(header)newAddr-=0x200;
if(newAddr>=0&&newAddr<0x400000)return newAddr+0xC00000; if(newAddr>=0&&newAddr<0x400000)return newAddr+0xC00000;
else if(newAddr>=0x400000&&newAddr<0x600000)return newAddr; else if(newAddr>=0x400000&&newAddr<0x600000)return newAddr;
@ -41,22 +41,22 @@ struct Rom{
} }
struct DataBlock{ struct DataBlock{
uint32_t addr,ptr; uint_fast32_t addr,ptr;
std::u8string_view data; std::u8string_view data;
DataBlock(std::u8string_view data,uint32_t loc) DataBlock(std::u8string_view data,uint_fast32_t loc)
:data(data){ :data(data){
addr=ptr=loc; addr=ptr=loc;
} }
uint8_t readInt8(){ uint_fast8_t readInt8(){
return data[ptr++]; return data[ptr++];
} }
uint16_t readShort(){ uint_fast16_t readShort(){
return readInt8()|(readInt8()<<8); return readInt8()|(readInt8()<<8);
} }
uint32_t readInt32(){ uint_fast32_t readInt32(){
return readInt8()|(readInt8()<<8)|(readInt8()<<16)|(readInt8()<<24); return readInt8()|(readInt8()<<8)|(readInt8()<<16)|(readInt8()<<24);
} }
uint32_t getCompressedSize(uint32_t pointer){ uint_fast32_t getCompressedSize(uint_fast32_t pointer){
int32_t bpos{}; int32_t bpos{};
int32_t pos{int32_t(pointer)}; int32_t pos{int32_t(pointer)};
int32_t bpos2{}; int32_t bpos2{};
@ -111,16 +111,16 @@ struct Rom{
} }
return bpos; return bpos;
} }
std::vector<uint16_t>decompress(){ std::vector<uint_fast16_t>decompress(){
uint32_t size{getCompressedSize(ptr)}; uint_fast32_t size{getCompressedSize(ptr)};
if(size<1)throw std::runtime_error(std::format("Got an invalid data size of {}",size)); if(size<1)throw std::runtime_error(std::format("Got an invalid data size of {}",size));
std::vector<uint16_t>blockOutput; std::vector<uint_fast16_t>blockOutput;
blockOutput.resize(size); blockOutput.resize(size);
decompressBlock(ptr,blockOutput); decompressBlock(ptr,blockOutput);
return blockOutput; return blockOutput;
} }
private: private:
void decompressBlock(uint32_t ptrStart,std::vector<uint16_t>&block){ void decompressBlock(uint_fast32_t ptrStart,std::vector<uint_fast16_t>&block){
size_t maxLength{block.size()}; size_t maxLength{block.size()};
int32_t pos{int32_t(ptrStart)}; int32_t pos{int32_t(ptrStart)};
int32_t bpos{}; int32_t bpos{};
@ -184,8 +184,8 @@ struct Rom{
}; };
struct BattleBackground{ struct BattleBackground{
BattleBackground(std::u8string_view data,uint32_t index){ BattleBackground(std::u8string_view data,uint_fast32_t index){
DataBlock readData{data,0xDCA1+index*uint32_t(this->data.size())}; DataBlock readData{data,0xDCA1+index*uint_fast32_t(this->data.size())};
for(int i=0;i<this->data.size();i++){ for(int i=0;i<this->data.size();i++){
this->data[i]=readData.readInt8(); this->data[i]=readData.readInt8();
} }
@ -206,37 +206,37 @@ struct Rom{
byte verticalMovement; byte verticalMovement;
byte horizontalAcceleration; byte horizontalAcceleration;
byte verticalAcceleration; byte verticalAcceleration;
uint32_t animationEffectsData; uint_fast32_t animationEffectsData;
}; };
}; };
uint32_t GetAnimation(){ uint_fast32_t GetAnimation(){
return (data[13]<<24)+(data[14]<<16)+(data[15]<<8)+data[16]; return (data[13]<<24)+(data[14]<<16)+(data[15]<<8)+data[16];
} }
}; };
struct BackgroundPalette{ struct BackgroundPalette{
std::vector<Pixel>colors; std::vector<Pixel>colors;
byte bpp; byte bpp;
uint32_t addr; uint_fast32_t addr;
BackgroundPalette(std::u8string_view data,uint16_t index,byte bpp) BackgroundPalette(std::u8string_view data,uint_fast16_t index,byte bpp)
:bpp(bpp){ :bpp(bpp){
DataBlock pointer{data,0xDAD9U+index*4U}; DataBlock pointer{data,0xDAD9U+index*4U};
uint32_t addr=snesToHex(pointer.readInt32()); uint_fast32_t addr=snesToHex(pointer.readInt32());
DataBlock dataBlock{data,addr}; DataBlock dataBlock{data,addr};
this->addr=addr; this->addr=addr;
if(bpp!=2&&bpp!=4)throw std::invalid_argument{std::format("Palette Error: Incorrect color depth specified. Must be 2 or 4, provided {}",bpp)}; if(bpp!=2&&bpp!=4)throw std::invalid_argument{std::format("Palette Error: Incorrect color depth specified. Must be 2 or 4, provided {}",bpp)};
for(uint8_t i:std::views::iota(0,pow(2,bpp))){ for(uint_fast8_t i:std::views::iota(0,pow(2,bpp))){
uint16_t clr16{dataBlock.readShort()}; uint_fast16_t clr16{dataBlock.readShort()};
uint8_t b{((clr16>>10)&31)*8U}; uint_fast8_t b{((clr16>>10)&31)*8U};
uint8_t g{((clr16>>5)&31)*8U}; uint_fast8_t g{((clr16>>5)&31)*8U};
uint8_t r{(clr16&31)*8U}; uint_fast8_t r{(clr16&31)*8U};
colors.emplace_back(r,g,b); colors.emplace_back(r,g,b);
} }
} }
}; };
using Tile=std::array<std::array<int,8>,8>; using Tile=std::array<std::array<int,8>,8>;
struct BackgroundGraphics{ struct BackgroundGraphics{
std::vector<uint16_t>graphicsData; std::vector<uint_fast16_t>graphicsData;
std::vector<uint16_t>arrayGraphicsData; std::vector<uint_fast16_t>arrayGraphicsData;
std::vector<Tile>tiles; std::vector<Tile>tiles;
byte bpp; byte bpp;
private: private:
@ -259,14 +259,14 @@ struct Rom{
} }
} }
public: public:
BackgroundGraphics(std::u8string_view data,uint16_t index,byte bpp) BackgroundGraphics(std::u8string_view data,uint_fast16_t index,byte bpp)
:bpp(bpp){ :bpp(bpp){
DataBlock graphicsPtr{data,0xD7A1U+index*4U}; DataBlock graphicsPtr{data,0xD7A1U+index*4U};
DataBlock loadGraphicsPtr{data,snesToHex(graphicsPtr.readInt32())}; DataBlock loadGraphicsPtr{data,snesToHex(graphicsPtr.readInt32())};
graphicsData=loadGraphicsPtr.decompress(); graphicsData=loadGraphicsPtr.decompress();
buildTiles(); buildTiles();
DataBlock arrayPtrBlock{data,0xD93DU+index*4}; DataBlock arrayPtrBlock{data,0xD93DU+index*4};
uint32_t arrayPtr{snesToHex(arrayPtrBlock.readInt32())}; uint_fast32_t arrayPtr{snesToHex(arrayPtrBlock.readInt32())};
DataBlock arrayBlock{data,arrayPtr}; DataBlock arrayBlock{data,arrayPtr};
arrayGraphicsData=arrayBlock.decompress(); arrayGraphicsData=arrayBlock.decompress();
} }
@ -283,6 +283,19 @@ struct Rom{
:bitmap(bitmap){} :bitmap(bitmap){}
}; };
struct DistortionEffect{
enum{
HORIZONTAL=1,
HORIZONTAL_INTERLACED=2,
VERTICAL=3
};
uint_fast16_t type(){
return std::clamp(data[2],uint_fast8_t(1),uint_fast8_t(3U));
}
private:
std::array<uint_fast8_t,17>data;
};
struct PaletteCycle{ struct PaletteCycle{
std::vector<Pixel>originalCols; std::vector<Pixel>originalCols;
std::vector<Pixel>currentCols; std::vector<Pixel>currentCols;
@ -301,7 +314,7 @@ struct Rom{
PaletteCycle cycle; PaletteCycle cycle;
BattleBackground&background; BattleBackground&background;
BackgroundGraphics&graphics; BackgroundGraphics&graphics;
BackgroundLayer(PixelGameEngine*pge,uint8_t pgeLayer,uint16_t backgroundInd,std::vector<BattleBackground>&backgrounds,std::vector<BackgroundPalette>&palettes,std::vector<BackgroundGraphics>&graphics) BackgroundLayer(PixelGameEngine*pge,uint_fast16_t backgroundInd,std::vector<BattleBackground>&backgrounds,std::vector<BackgroundPalette>&palettes,std::vector<BackgroundGraphics>&graphics)
:pge(pge),spr(new Sprite(256,256)),distorter(*spr),background(backgrounds[backgroundInd]),graphics(graphics[background.graphicsInd]),cycle(background,palettes[background.paletteInd]){} :pge(pge),spr(new Sprite(256,256)),distorter(*spr),background(backgrounds[backgroundInd]),graphics(graphics[background.graphicsInd]),cycle(background,palettes[background.paletteInd]){}
}; };
std::u8string data; std::u8string data;
@ -309,14 +322,14 @@ struct Rom{
std::vector<BattleBackground>backgrounds; std::vector<BattleBackground>backgrounds;
std::vector<BackgroundPalette>palettes; std::vector<BackgroundPalette>palettes;
std::vector<BackgroundGraphics>graphics; std::vector<BackgroundGraphics>graphics;
BackgroundLayer layer1{nullptr,0U,0U,backgrounds},layer2{nullptr,1U,0U,backgrounds}; BackgroundLayer layer1{nullptr,0U,backgrounds,palettes,graphics},layer2{nullptr,0U,backgrounds,palettes,graphics};
Rom(){ Rom(){
#pragma region Setup Reversed Bytes #pragma region Setup Reversed Bytes
reversedBytes.resize(256); reversedBytes.resize(256);
for(int i:std::views::iota(0U,reversedBytes.size())){ for(int i:std::views::iota(0U,reversedBytes.size())){
uint8_t newNumb{}; uint_fast8_t newNumb{};
for(int digit=0;digit<8;digit++){ for(int digit=0;digit<8;digit++){
uint8_t digitVal{1U<<digit}; uint_fast8_t digitVal{1U<<digit};
if(i&digitVal)newNumb|=1<<(7-digit); if(i&digitVal)newNumb|=1<<(7-digit);
} }
reversedBytes[i]=newNumb; reversedBytes[i]=newNumb;
@ -327,15 +340,15 @@ struct 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();
for(uint16_t i:std::views::iota(0U,MAX_INDEX+1U)){ for(uint_fast16_t i:std::views::iota(0U,MAX_INDEX+1U)){
backgrounds.emplace_back(data,i); backgrounds.emplace_back(data,i);
paletteBits[backgrounds.back().paletteInd]=backgrounds.back().bbp; paletteBits[backgrounds.back().paletteInd]=backgrounds.back().bbp;
graphicsBits[backgrounds.back().graphicsInd]=backgrounds.back().bbp; graphicsBits[backgrounds.back().graphicsInd]=backgrounds.back().bbp;
} }
for(uint16_t i:std::views::iota(0U,paletteBits.size())){ for(uint_fast16_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())){ for(uint_fast16_t i:std::views::iota(0U,graphicsBits.size())){
graphics.emplace_back(data,i,graphicsBits[i]); graphics.emplace_back(data,i,graphicsBits[i]);
} }
} }
@ -363,8 +376,8 @@ public:
if(GetMouseWheel()<0)yOffset-=32; if(GetMouseWheel()<0)yOffset-=32;
if(GetMouseWheel()>0)yOffset+=32; if(GetMouseWheel()>0)yOffset+=32;
for(uint8_t row=0;Rom::BackgroundPalette&palette:rom.palettes){ for(uint_fast8_t row=0;Rom::BackgroundPalette&palette:rom.palettes){
for(uint8_t index=0;Pixel&col:palette.colors){ for(uint_fast8_t index=0;Pixel&col:palette.colors){
FillRectDecal(vf2d{index*8.f+8,row*8.f+yOffset},{8,8},col); FillRectDecal(vf2d{index*8.f+8,row*8.f+yOffset},{8,8},col);
index++; index++;
} }
@ -372,7 +385,7 @@ public:
} }
} }
uint8_t selectedPalette{}; uint_fast8_t selectedPalette{};
void GraphicsDisplayTest(){ void GraphicsDisplayTest(){
if(GetMouseWheel()<0)yOffset-=32; if(GetMouseWheel()<0)yOffset-=32;
@ -386,14 +399,14 @@ public:
if(GetKey(PGDN).bPressed)selectedPalette=std::clamp(int(selectedPalette)+1,0,int(rom.palettes.size()-1));; if(GetKey(PGDN).bPressed)selectedPalette=std::clamp(int(selectedPalette)+1,0,int(rom.palettes.size()-1));;
Rom::BackgroundPalette&palette{rom.palettes[selectedPalette]}; Rom::BackgroundPalette&palette{rom.palettes[selectedPalette]};
for(uint8_t index=0;Pixel&col:palette.colors){ for(uint_fast8_t index=0;Pixel&col:palette.colors){
FillRectDecal(vf2d{index*8.f,8.f},{8,8},col); FillRectDecal(vf2d{index*8.f,8.f},{8,8},col);
index++; index++;
} }
DrawRectDecal(vf2d{8.f,8.f},{8*16,8}); DrawRectDecal(vf2d{8.f,8.f},{8*16,8});
for(uint8_t row=0;Rom::BackgroundGraphics&graphics:rom.graphics){ for(uint_fast8_t row=0;Rom::BackgroundGraphics&graphics:rom.graphics){
for(uint8_t col=0;Rom::Tile&tile:graphics.tiles){ for(uint_fast8_t col=0;Rom::Tile&tile:graphics.tiles){
for(int x{};x<tile.size();x++){ for(int x{};x<tile.size();x++){
for(int y{};y<tile[x].size();y++){ for(int y{};y<tile[x].size();y++){
int paletteInd{tile[x][y]}; int paletteInd{tile[x][y]};

Loading…
Cancel
Save