Use fast types instead. Add DistortionEffect class. Fix up BackgroundLayer class to not include PGE layer arguments anymore.
This commit is contained in:
parent
d1837503e0
commit
41ab66d4c9
7
.vs/VSWorkspaceState.json
Normal file
7
.vs/VSWorkspaceState.json
Normal file
@ -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…
x
Reference in New Issue
Block a user