diff --git a/EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp b/EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp index 707b9ed..faa80c4 100644 --- a/EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp +++ b/EarthboundBattleBackgrounds/EarthboundBattleBackgrounds/main.cpp @@ -1,6 +1,9 @@ #define OLC_PGE_APPLICATION #include "olcPixelGameEngine.h" +#include + +using namespace olc; struct Rom{ const static uint16_t MIN_INDEX{}; @@ -18,6 +21,23 @@ struct Rom{ UNKNOWN_2, }; + static uint32_t snesToHex(uint32_t addr,bool header=true){ + uint32_t newAddr{addr}; + if(newAddr>=0x400000&&newAddr<0x600000);//NO-OP + else if(newAddr>=0xC00000&&newAddr<0x1000000)newAddr-=0xC00000; + else throw std::out_of_range{std::format("SNES address out of range: {}",newAddr)}; + + if(header)newAddr+=0x200; + return newAddr-0xA0200; + } + static uint32_t hexToSnes(uint32_t addr,bool header=true){ + uint32_t newAddr{addr}; + if(header)newAddr-=0x200; + if(newAddr>=0&&newAddr<0x400000)return newAddr+0xC00000; + else if(newAddr>=0x400000&&newAddr<0x600000)return newAddr; + else throw std::out_of_range{std::format("File offset out of range: {}",newAddr)}; + } + struct DataBlock{ uint32_t addr,ptr; std::string_view data; @@ -66,17 +86,41 @@ struct Rom{ return (data[13]<<24)+(data[14]<<16)+(data[15]<<8)+data[16]; } }; + struct BackgroundPalette{ + std::vectorcolors; + byte bpp; + uint32_t addr; + BackgroundPalette(std::string_view data,uint16_t index,byte bpp) + :bpp(bpp){ + DataBlock pointer{data,0xDAD9U+index*4U}; + uint32_t addr=snesToHex(pointer.readInt32()); + DataBlock dataBlock{data,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)}; + for(uint8_t i:std::views::iota(0,pow(2,bpp))){ + uint16_t clr16{dataBlock.readShort()}; + uint8_t b{((clr16>>10)&31)*8U}; + uint8_t g{((clr16>>5)&31)*8U}; + uint8_t r{(clr16&31)*8U}; + colors.emplace_back(r,g,b); + } + } + }; std::string data; std::vectorbackgrounds; + std::vectorpalettes; Rom(){ std::ifstream dataStream{"truncated_backgrounds.dat",std::ios_base::binary}; while(dataStream.good())data+=dataStream.get(); - for(uint16_t i=0;i<=MAX_INDEX;i++){ + for(uint16_t i:std::views::iota(0U,MAX_INDEX+1U)){ backgrounds.emplace_back(data,i); paletteBits[backgrounds.back().paletteInd]=backgrounds.back().bbp; graphicsBits[backgrounds.back().graphicsInd]=backgrounds.back().bbp; } + for(uint16_t i:std::views::iota(0U,paletteBits.size())){ + palettes.emplace_back(data,i,paletteBits[i]); + } } }; @@ -100,9 +144,20 @@ public: return true; } + int yOffset{0}; + bool OnUserUpdate(float fElapsedTime) override { - + if(GetMouseWheel()<0)yOffset-=32; + if(GetMouseWheel()>0)yOffset+=32; + + for(uint8_t row=0;Rom::BackgroundPalette&palette:rom.palettes){ + for(uint8_t index=0;Pixel&col:palette.colors){ + FillRectDecal(vf2d{index*8.f+8,row*8.f+yOffset},{8,8},col); + index++; + } + row++; + } return true; } }; diff --git a/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.exe b/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.exe index f70a807..736f29c 100644 Binary files a/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.exe and b/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.exe differ diff --git a/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.pdb b/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.pdb index 8cdcce7..c4d840e 100644 Binary files a/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.pdb and b/EarthboundBattleBackgrounds/x64/Debug/EarthboundBattleBackgrounds.pdb differ