Skip to content

Commit

Permalink
Issue #78 Refactor TTM runner (#184)
Browse files Browse the repository at this point in the history
* Refactor ttm renderer from ttm player
  • Loading branch information
xavieran authored Mar 17, 2024
1 parent b59d97f commit d1f93f0
Show file tree
Hide file tree
Showing 8 changed files with 409 additions and 254 deletions.
2 changes: 2 additions & 0 deletions bak/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ add_library(bak
spells.hpp spells.cpp
tags.hpp tags.cpp
temple.hpp temple.cpp
ttmRenderer.hpp ttmRenderer.cpp
ttmRunner.hpp ttmRunner.cpp
textureFactory.hpp textureFactory.cpp
time.hpp time.cpp
timeExpiringState.hpp timeExpiringState.cpp
Expand Down
2 changes: 2 additions & 0 deletions bak/spriteRenderer.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include "bak/image.hpp"
#include "bak/palette.hpp"

Expand Down
168 changes: 168 additions & 0 deletions bak/ttmRenderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include "bak/ttmRenderer.hpp"

#include "bak/dialogSources.hpp"
#include "bak/imageStore.hpp"
#include "bak/screen.hpp"
#include "bak/textureFactory.hpp"

#include "com/assert.hpp"
#include "com/logger.hpp"

#include "graphics/types.hpp"

namespace BAK {

TTMRenderer::TTMRenderer(
std::string adsFile,
std::string ttmFile)
:
mRunner{adsFile, ttmFile},
mLogger{Logging::LogState::GetLogger("BAK::TTMRenderer")}
{
}

Graphics::TextureStore TTMRenderer::RenderTTM()
{
while (!AdvanceAction())
{
}
return mRenderedFrames;
}

bool TTMRenderer::AdvanceAction()
{
mLogger.Debug() << "AdvanceAction" << "\n";
auto actionOpt = mRunner.GetNextAction();
if (!actionOpt)
{
return true;
}
auto action = *actionOpt;
mLogger.Debug() << "Handle action: " << action << std::endl;
std::visit(
overloaded{
[&](const BAK::SlotPalette& sp){
mCurrentPaletteSlot = sp.mSlot;
},
[&](const BAK::LoadPalette& p){
mPaletteSlots.erase(mCurrentPaletteSlot);
mPaletteSlots.emplace(mCurrentPaletteSlot, BAK::Palette{p.mPalette});
},
[&](const BAK::SlotImage& sp){
mCurrentImageSlot = sp.mSlot;
},
[&](const BAK::LoadImage& p){
auto fb = BAK::FileBufferFactory::Get().CreateDataBuffer(p.mImage);
mImageSlots.erase(mCurrentImageSlot);
mImageSlots.emplace(mCurrentImageSlot, BAK::LoadImages(fb));
mLogger.Debug() << "Loaded image: " << p.mImage << " to slot: " << mCurrentImageSlot
<< " has " << mImageSlots.at(mCurrentImageSlot).mImages.size() << " images\n";
},
[&](const BAK::LoadScreen& p){
auto fb = BAK::FileBufferFactory::Get().CreateDataBuffer(p.mScreenName);
mScreen = BAK::LoadScreenResource(fb);
},
[&](const BAK::DrawScreen& sa){
if (sa.mArg1 == 3 || sa.mArg2 == 3)
{
mRenderer.GetSavedImagesLayer0() = {320, 200};
mRenderer.GetSavedImagesLayer1() = {320, 200};
mRenderer.GetSavedImagesLayerBG() = {320, 200};
}
if (mScreen && mPaletteSlots.contains(mCurrentPaletteSlot))
{
mRenderer.RenderSprite(
*mScreen,
mPaletteSlots.at(mCurrentPaletteSlot).mPaletteData,
glm::ivec2{0, 0},
false,
mRenderer.GetForegroundLayer());
}
},
[&](const BAK::DrawSprite& sa){
const auto imageSlot = sa.mImageSlot;
assert(mImageSlots.contains(sa.mImageSlot));
assert(static_cast<unsigned>(sa.mSpriteIndex)
< mImageSlots.at(sa.mImageSlot).mImages.size());

mRenderer.RenderSprite(
mImageSlots.at(sa.mImageSlot).mImages[sa.mSpriteIndex],
mPaletteSlots.at(mCurrentPaletteSlot).mPaletteData,
glm::ivec2{sa.mX, sa.mY},
sa.mFlippedInY,
mRenderer.GetForegroundLayer());
},
[&](const BAK::Update& sr){
if (mScreen)
{
mRenderer.RenderSprite(
*mScreen,
mPaletteSlots.at(mCurrentPaletteSlot).mPaletteData,
glm::ivec2{0, 0}, false, mRenderer.GetBackgroundLayer());
}

mRenderer.RenderTexture(
mRenderer.GetSavedImagesLayerBG(),
glm::ivec2{0},
mRenderer.GetBackgroundLayer());

mRenderer.RenderTexture(
mRenderer.GetSavedImagesLayer0(),
glm::ivec2{0},
mRenderer.GetBackgroundLayer());

mRenderer.RenderTexture(
mRenderer.GetSavedImagesLayer1(),
glm::ivec2{0},
mRenderer.GetBackgroundLayer());

mRenderer.RenderTexture(
mRenderer.GetForegroundLayer(),
glm::ivec2{0, 0},
mRenderer.GetBackgroundLayer());

auto bg = mRenderer.GetBackgroundLayer();
bg.Invert();
mRenderedFrames.AddTexture(bg);

mRenderer.GetForegroundLayer() = Graphics::Texture{320, 200};
mRenderer.GetBackgroundLayer() = Graphics::Texture{320, 200};
},
[&](const BAK::SaveImage& si){
mRenderer.SaveImage(si.pos, si.dims, mImageSaveLayer);
},
[&](const BAK::SetClearRegion& si){
mClearRegions.emplace(mImageSaveLayer, si);
},
[&](const BAK::ClearSaveLayer& si){
const auto& clearRegion = mClearRegions.at(mImageSaveLayer);
mRenderer.ClearSaveLayer(clearRegion.pos, clearRegion.dims, si.mLayer);
},
[&](const BAK::SaveBackground&){
mRenderer.GetSavedImagesLayer0() = {320, 200};
mRenderer.GetSavedImagesLayer1() = {320, 200};
mRenderer.SaveImage({0, 0}, {320, 200}, 2);
},
[&](const BAK::DrawRect& sr){
},
[&](const BAK::ClipRegion& a){
mRenderer.SetClipRegion(a);
},
[&](const BAK::DisableClipRegion&){
mRenderer.ClearClipRegion();
},
[&](const BAK::Purge&){
assert(false);
},
[&](const BAK::GotoTag& sa){
assert(false);
},
[&](const auto&){}
},
action
);

return false;
}

}
52 changes: 52 additions & 0 deletions bak/ttmRenderer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "bak/image.hpp"
#include "bak/palette.hpp"
#include "bak/scene.hpp"
#include "bak/spriteRenderer.hpp"
#include "bak/ttmRunner.hpp"

#include "com/logger.hpp"

namespace BAK {

class TTMRenderer
{

public:
TTMRenderer(
std::string adsFile,
std::string ttmFile);

Graphics::TextureStore RenderTTM();

private:
bool AdvanceAction();

TTMRunner mRunner;

struct PaletteSlot
{
BAK::Palette mPaletteData;
};
struct ImageSlot
{
std::vector<BAK::Image> mImages;
};
unsigned mCurrentPaletteSlot = 0;
unsigned mCurrentImageSlot = 0;
unsigned mImageSaveLayer = 0;
std::unordered_map<unsigned, BAK::SetClearRegion> mClearRegions;
std::unordered_map<unsigned, ImageSlot> mImageSlots;
std::unordered_map<unsigned, PaletteSlot> mPaletteSlots;
std::unordered_map<unsigned, Graphics::TextureStore> mTextures;

BAK::SpriteRenderer mRenderer;
std::optional<BAK::Image> mScreen;

Graphics::TextureStore mRenderedFrames;

const Logging::Logger& mLogger;
};

}
112 changes: 112 additions & 0 deletions bak/ttmRunner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "bak/ttmRunner.hpp"

#include "bak/dialogSources.hpp"
#include "bak/imageStore.hpp"
#include "bak/screen.hpp"
#include "bak/textureFactory.hpp"

#include "com/assert.hpp"
#include "com/logger.hpp"

#include "graphics/types.hpp"

namespace BAK {

TTMRunner::TTMRunner(
std::string adsFile,
std::string ttmFile)
:
mLogger{Logging::LogState::GetLogger("BAK::TTMRunner")}
{
mLogger.Debug() << "Loading ADS/TTM: " << adsFile << " " << ttmFile << "\n";
auto adsFb = BAK::FileBufferFactory::Get().CreateDataBuffer(adsFile);
mSceneSequences = BAK::LoadSceneSequences(adsFb);
auto ttmFb = BAK::FileBufferFactory::Get().CreateDataBuffer(ttmFile);
mActions = BAK::LoadDynamicScenes(ttmFb);

auto nextTag = mSceneSequences[1][mCurrentSequence].mScenes[mCurrentSequenceScene].mDrawScene;
mLogger.Debug() << "Next tag: " << nextTag << "\n";
mCurrentAction = FindActionMatchingTag(nextTag);
}

std::optional<BAK::SceneAction> TTMRunner::GetNextAction()
{
if (mCurrentAction == mActions.size())
{
return std::nullopt;
}

auto action = mActions[mCurrentAction];
bool nextActionChosen = false;
std::visit(
overloaded{
[&](const BAK::Purge&){
AdvanceToNextScene();
nextActionChosen = true;
},
[&](const BAK::GotoTag& sa){
mCurrentAction = FindActionMatchingTag(sa.mTag);
nextActionChosen = true;
},
[&](const auto&){}
},
action
);

if (nextActionChosen)
{
if (mCurrentAction == mActions.size())
{
return std::nullopt;
}

action = mActions[mCurrentAction];
}

mCurrentAction++;

return action;
}

void TTMRunner::AdvanceToNextScene()
{
auto& currentScenes = mSceneSequences[1][mCurrentSequence].mScenes;
mCurrentSequenceScene++;
if (mCurrentSequenceScene == currentScenes.size())
{
mCurrentSequenceScene = 0;
mCurrentSequence++;
}

if (mCurrentSequence == mSceneSequences[1].size())
{
mCurrentAction = mActions.size();
mCurrentSequence = 0;
return;
}

auto nextTag = mSceneSequences[1][mCurrentSequence].mScenes[mCurrentSequenceScene].mDrawScene;
mCurrentAction = FindActionMatchingTag(nextTag);
}

unsigned TTMRunner::FindActionMatchingTag(unsigned tag)
{
std::optional<unsigned> foundIndex{};
for (unsigned i = 0; i < mActions.size(); i++)
{
evaluate_if<BAK::SetScene>(mActions[i], [&](const auto& action) {
if (action.mSceneNumber == tag)
{
foundIndex = i;
}
});
if (foundIndex)
{
return *foundIndex;
}
}

return 0;
}

}
33 changes: 33 additions & 0 deletions bak/ttmRunner.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "bak/scene.hpp"

#include "com/logger.hpp"

namespace BAK {

class TTMRunner
{

public:
TTMRunner(
std::string adsFile,
std::string ttmFile);

std::optional<BAK::SceneAction> GetNextAction();

private:
void AdvanceToNextScene();
unsigned FindActionMatchingTag(unsigned tag);

std::unordered_map<unsigned, std::vector<BAK::SceneSequence>> mSceneSequences;
std::vector<BAK::SceneAction> mActions;

unsigned mCurrentAction = 0;
unsigned mCurrentSequence = 0;
unsigned mCurrentSequenceScene = 0;

const Logging::Logger& mLogger;
};

}
Loading

0 comments on commit d1f93f0

Please sign in to comment.