Rendering!! It sorta works.
This commit is contained in:
parent
bbeac33ad6
commit
1f20f0c837
@ -320,8 +320,52 @@ struct Rom{
|
|||||||
const float c3{PI/60.f};
|
const float c3{PI/60.f};
|
||||||
Sprite&bitmap;
|
Sprite&bitmap;
|
||||||
std::unique_ptr<DistortionEffect>effect;
|
std::unique_ptr<DistortionEffect>effect;
|
||||||
|
float amplitude,frequency,compression,speed;
|
||||||
Distorter(Sprite&bitmap)
|
Distorter(Sprite&bitmap)
|
||||||
:bitmap(bitmap){}
|
:bitmap(bitmap){}
|
||||||
|
void setup(int ticks){
|
||||||
|
int t2{ticks*2};
|
||||||
|
amplitude=c1*(effect->amplitude()+effect->amplitudeAcceleration()*t2);
|
||||||
|
frequency=c2*(effect->frequency()+(effect->frequencyAcceleration()*t2));
|
||||||
|
compression=1+(effect->compression()+(effect->compressionAcceleration()*t2))/256.f;
|
||||||
|
speed=c3*speed*ticks;
|
||||||
|
}
|
||||||
|
float getAppliedOffset(int y){
|
||||||
|
float s=std::round(amplitude*sin(frequency*y+speed));
|
||||||
|
switch(effect->type()){
|
||||||
|
case DistortionEffect::HORIZONTAL:return s;
|
||||||
|
case DistortionEffect::HORIZONTAL_INTERLACED:return y%2?s:-s;
|
||||||
|
case DistortionEffect::VERTICAL:return fmod(floor(s+y*effect->compression()),256.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void computeFrame(PixelGameEngine*pge,int ticks,float alpha,bool erase){
|
||||||
|
setup(ticks);
|
||||||
|
for(int y:std::views::iota(0,pge->ScreenHeight())){
|
||||||
|
float offset{getAppliedOffset(y)};
|
||||||
|
int L=effect->type()==DistortionEffect::VERTICAL?offset:y;
|
||||||
|
for(int x:std::views::iota(0,pge->ScreenWidth())){
|
||||||
|
int dx=x;
|
||||||
|
if(effect->type()==DistortionEffect::HORIZONTAL||effect->type()==DistortionEffect::HORIZONTAL_INTERLACED)dx=fmod(x+offset,pge->ScreenWidth());
|
||||||
|
if(erase){
|
||||||
|
Pixel newCol{bitmap.GetPixel(dx,L)};
|
||||||
|
newCol.r*=alpha;
|
||||||
|
newCol.g*=alpha;
|
||||||
|
newCol.b*=alpha;
|
||||||
|
pge->Draw(dx,L,newCol);
|
||||||
|
}else{
|
||||||
|
Pixel newCol{bitmap.GetPixel(dx,L)};
|
||||||
|
newCol.r*=alpha;
|
||||||
|
newCol.g*=alpha;
|
||||||
|
newCol.b*=alpha;
|
||||||
|
Pixel mixedCol{pge->GetDrawTarget()->GetPixel(dx,L)};
|
||||||
|
mixedCol.r+=newCol.r;
|
||||||
|
mixedCol.g+=newCol.g;
|
||||||
|
mixedCol.b+=newCol.b;
|
||||||
|
pge->Draw(dx,L,mixedCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PaletteCycle{
|
struct PaletteCycle{
|
||||||
@ -334,6 +378,51 @@ struct Rom{
|
|||||||
originalCols.emplace_back(originalCols[i]);
|
originalCols.emplace_back(originalCols[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void cycle(){
|
||||||
|
if(speed==0)return;
|
||||||
|
cycleCountdown=std::clamp(cycleCountdown-1,0,int(std::numeric_limits<byte>::max()));
|
||||||
|
if(cycleCountdown<=0){
|
||||||
|
cycleColors();
|
||||||
|
cycleCount++;
|
||||||
|
cycleCountdown=speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void cycleColors(){
|
||||||
|
if(type==1||type==2){
|
||||||
|
int cycleLength{end1-start1+1};
|
||||||
|
int cycle1Position{cycleCount%cycleLength};
|
||||||
|
for(int i:std::views::iota(int(start1),end1+1)){
|
||||||
|
int newColor=i-cycle1Position;
|
||||||
|
if(newColor<start1)newColor+=cycleLength;
|
||||||
|
currentCols[i]=originalCols[newColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(type==2){
|
||||||
|
int cycleLength{end2-start2+1};
|
||||||
|
int cycle2Position{cycleCount%cycleLength};
|
||||||
|
for(int i:std::views::iota(int(start2),end2+1)){
|
||||||
|
int newColor=i-cycle2Position;
|
||||||
|
if(newColor<start2)newColor+=cycleLength;
|
||||||
|
currentCols[i]=originalCols[newColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(type==3){
|
||||||
|
int cycleLength{end1-start1+1};
|
||||||
|
int cycle1Position{cycleCount%(cycleLength*2)};
|
||||||
|
for(int i:std::views::iota(int(start1),end1+1)){
|
||||||
|
int newColor=i+cycle1Position;
|
||||||
|
if(newColor>end1){
|
||||||
|
int difference{newColor-end1-1};
|
||||||
|
newColor=end1-difference;
|
||||||
|
if(newColor<start1){
|
||||||
|
difference=start1-newColor-1;
|
||||||
|
newColor=start1+difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentCols[i]=originalCols[newColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelGameEngine*pge;
|
PixelGameEngine*pge;
|
||||||
@ -343,6 +432,43 @@ struct Rom{
|
|||||||
BackgroundGraphics&graphics;
|
BackgroundGraphics&graphics;
|
||||||
PaletteCycle cycle;
|
PaletteCycle cycle;
|
||||||
uint_fast16_t backgroundInd;
|
uint_fast16_t backgroundInd;
|
||||||
|
|
||||||
|
void drawTile(const int x,const int y,const int tile,const int subPalette,const bool verticalFlip,const bool horizontalFlip){
|
||||||
|
int px{},py{};
|
||||||
|
for(int i:std::views::iota(0,8)){
|
||||||
|
if(horizontalFlip)px=x+7-i;
|
||||||
|
else px=x+i;
|
||||||
|
for(int j:std::views::iota(0,8)){
|
||||||
|
if(verticalFlip)py=y+7-j;
|
||||||
|
else py=y+j;
|
||||||
|
spr->SetPixel(px,py,cycle.currentCols[graphics.tiles[tile][i][j]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(){
|
||||||
|
int block{};
|
||||||
|
int tile{};
|
||||||
|
int subPalette{}; //Subpalette should always be zero....I don't understand?
|
||||||
|
int n{};
|
||||||
|
int b1{};
|
||||||
|
int b2{};
|
||||||
|
bool verticalFlip{false};
|
||||||
|
bool horizontalFlip{false};
|
||||||
|
for(int i:std::views::iota(0,32)){
|
||||||
|
for(int j:std::views::iota(0,32)){
|
||||||
|
n=j*32+i;
|
||||||
|
b1=graphics.arrayGraphicsData[n*2];
|
||||||
|
b2=graphics.arrayGraphicsData[n*2+1]<<8;
|
||||||
|
block=b1+b2;
|
||||||
|
tile=block&0x3FF;
|
||||||
|
verticalFlip=block&0x8000;
|
||||||
|
horizontalFlip=block&0x4000;
|
||||||
|
//subPalette=(block>>10)&7; //THIS SHOULD NOT BE NECESSARY!!!
|
||||||
|
drawTile(i*8,j*8,tile,0,verticalFlip,horizontalFlip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BackgroundLayer(PixelGameEngine*pge,uint_fast16_t backgroundInd,std::vector<BattleBackground>&backgrounds,std::vector<BackgroundPalette>&palettes,std::vector<BackgroundGraphics>&graphics,std::u8string_view data)
|
BackgroundLayer(PixelGameEngine*pge,uint_fast16_t backgroundInd,std::vector<BattleBackground>&backgrounds,std::vector<BackgroundPalette>&palettes,std::vector<BackgroundGraphics>&graphics,std::u8string_view data)
|
||||||
:pge(pge),spr(new Sprite(256,256)),distorter(*spr),backgroundInd(backgroundInd),background(backgrounds[backgroundInd]),graphics(graphics[background.graphicsInd]),cycle(background,palettes[background.paletteInd]){
|
:pge(pge),spr(new Sprite(256,256)),distorter(*spr),backgroundInd(backgroundInd),background(backgrounds[backgroundInd]),graphics(graphics[background.graphicsInd]),cycle(background,palettes[background.paletteInd]){
|
||||||
uint_fast32_t effectVal{((background.GetAnimation()>>16)&0xFF)};
|
uint_fast32_t effectVal{((background.GetAnimation()>>16)&0xFF)};
|
||||||
@ -366,10 +492,20 @@ struct Rom{
|
|||||||
backgroundInd=std::clamp(backgroundInd,0U,uint_fast16_t(backgrounds.size()));
|
backgroundInd=std::clamp(backgroundInd,0U,uint_fast16_t(backgrounds.size()));
|
||||||
layer2=std::make_unique<BackgroundLayer>(nullptr,backgroundInd,backgrounds,palettes,graphics,data);
|
layer2=std::make_unique<BackgroundLayer>(nullptr,backgroundInd,backgrounds,palettes,graphics,data);
|
||||||
}
|
}
|
||||||
|
void AdvanceLayers(int tick,float alpha1,float alpha2){
|
||||||
|
layer1->cycle.cycle();
|
||||||
|
layer1->draw();
|
||||||
|
layer1->distorter.computeFrame(pge,tick,alpha1,true);
|
||||||
|
layer2->cycle.cycle();
|
||||||
|
layer2->draw();
|
||||||
|
layer2->distorter.computeFrame(pge,tick,alpha2,false);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<BackgroundLayer>layer1,layer2;
|
std::unique_ptr<BackgroundLayer>layer1,layer2;
|
||||||
|
PixelGameEngine*pge;
|
||||||
public:
|
public:
|
||||||
Rom(){
|
Rom(PixelGameEngine*pge)
|
||||||
|
:pge(pge){
|
||||||
#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())){
|
||||||
@ -398,8 +534,8 @@ public:
|
|||||||
graphics.emplace_back(data,i,graphicsBits[i]);
|
graphics.emplace_back(data,i,graphicsBits[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
layer1=std::make_unique<BackgroundLayer>(nullptr,0U,backgrounds,palettes,graphics,data);
|
layer1=std::make_unique<BackgroundLayer>(pge,0U,backgrounds,palettes,graphics,data);
|
||||||
layer2=std::make_unique<BackgroundLayer>(nullptr,0U,backgrounds,palettes,graphics,data);
|
layer2=std::make_unique<BackgroundLayer>(pge,0U,backgrounds,palettes,graphics,data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -413,11 +549,12 @@ public:
|
|||||||
sAppName = "Earthbound Battle Backgrounds";
|
sAppName = "Earthbound Battle Backgrounds";
|
||||||
}
|
}
|
||||||
|
|
||||||
Rom rom;
|
Rom*rom;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool OnUserCreate() override
|
bool OnUserCreate() override
|
||||||
{
|
{
|
||||||
|
rom=new Rom(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +562,7 @@ public:
|
|||||||
if(GetMouseWheel()<0)yOffset-=32;
|
if(GetMouseWheel()<0)yOffset-=32;
|
||||||
if(GetMouseWheel()>0)yOffset+=32;
|
if(GetMouseWheel()>0)yOffset+=32;
|
||||||
|
|
||||||
for(uint_fast8_t row=0;Rom::BackgroundPalette&palette:rom.palettes){
|
for(uint_fast8_t row=0;Rom::BackgroundPalette&palette:rom->palettes){
|
||||||
for(uint_fast8_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++;
|
||||||
@ -444,17 +581,17 @@ public:
|
|||||||
|
|
||||||
DrawStringDecal({},std::format("Selected Palette: {}",selectedPalette));
|
DrawStringDecal({},std::format("Selected Palette: {}",selectedPalette));
|
||||||
|
|
||||||
if(GetKey(PGUP).bPressed)selectedPalette=std::clamp(int(selectedPalette)-1,0,int(rom.palettes.size()-1));
|
if(GetKey(PGUP).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));;
|
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(uint_fast8_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(uint_fast8_t row=0;Rom::BackgroundGraphics&graphics:rom.graphics){
|
for(uint_fast8_t row=0;Rom::BackgroundGraphics&graphics:rom->graphics){
|
||||||
for(uint_fast8_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++){
|
||||||
@ -473,26 +610,51 @@ public:
|
|||||||
|
|
||||||
int yOffset{0};
|
int yOffset{0};
|
||||||
float accumulatedTime{};
|
float accumulatedTime{};
|
||||||
|
int tick{};
|
||||||
|
|
||||||
|
uint16_t selectedLayer1{};
|
||||||
|
uint16_t selectedLayer2{};
|
||||||
|
|
||||||
void runTick(){
|
void runTick(){
|
||||||
float alpha1{1.f},alpha2{1.f};
|
float alpha1{1.f},alpha2{1.f};
|
||||||
if(rom.GetLayer1()->backgroundInd&&!rom.GetLayer2()->backgroundInd){
|
if(rom->GetLayer1()->backgroundInd&&!rom->GetLayer2()->backgroundInd){
|
||||||
alpha1=1.f;
|
alpha1=1.f;
|
||||||
alpha2=0.f;
|
alpha2=0.f;
|
||||||
}
|
}
|
||||||
if(!rom.GetLayer1()->backgroundInd&&rom.GetLayer2()->backgroundInd){
|
if(!rom->GetLayer1()->backgroundInd&&rom->GetLayer2()->backgroundInd){
|
||||||
alpha1=0.f;
|
alpha1=0.f;
|
||||||
alpha2=1.f;
|
alpha2=1.f;
|
||||||
}
|
}
|
||||||
|
rom->AdvanceLayers(tick,alpha1,alpha2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnUserUpdate(float fElapsedTime) override
|
bool OnUserUpdate(float fElapsedTime) override
|
||||||
{
|
{
|
||||||
|
if(GetKey(RIGHT).bPressed){
|
||||||
|
selectedLayer1=std::clamp(selectedLayer1+1,0,int(rom->backgrounds.size()));
|
||||||
|
rom->SetLayer1(selectedLayer1);
|
||||||
|
}
|
||||||
|
if(GetKey(LEFT).bPressed){
|
||||||
|
selectedLayer1=std::clamp(selectedLayer1-1,0,int(rom->backgrounds.size()));
|
||||||
|
rom->SetLayer1(selectedLayer1);
|
||||||
|
}
|
||||||
|
if(GetKey(UP).bPressed){
|
||||||
|
selectedLayer2=std::clamp(selectedLayer2+1,0,int(rom->backgrounds.size()));
|
||||||
|
rom->SetLayer2(selectedLayer2);
|
||||||
|
}
|
||||||
|
if(GetKey(DOWN).bPressed){
|
||||||
|
selectedLayer2=std::clamp(selectedLayer2-1,0,int(rom->backgrounds.size()));
|
||||||
|
rom->SetLayer2(selectedLayer2);
|
||||||
|
}
|
||||||
|
|
||||||
accumulatedTime+=fElapsedTime;
|
accumulatedTime+=fElapsedTime;
|
||||||
while(accumulatedTime>=1/60.f){
|
while(accumulatedTime>=1/60.f){
|
||||||
runTick();
|
runTick();
|
||||||
accumulatedTime-=1/60.f
|
accumulatedTime-=1/60.f;
|
||||||
|
tick++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawStringDecal({},std::format("Layer 1: {} Layer 2: {}",selectedLayer1,selectedLayer2));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user