Files
wc3re/game/GSMvePlay.cc

95 lines
2.3 KiB
C++

#include "MveDecoder.hh"
#include "GSMvePlay.hh"
#include "render/Overlay.hh"
#include "render/Renderer.hh"
namespace game {
GSMvePlay::GSMvePlay(render::Renderer& renderer, MveDecoder::Movie& movie)
: GameState(renderer), movie_(movie),
overlay_(nullptr), delta_(0),
nextFT_(1000/15.0f), frameRGB_()
{
int scrWidth = renderer_.getWidth(), scrHeight = renderer_.getHeight();
const float mvePAR = 1.2f;
int mveWidth = movie_.getWidth(), mveHeight = movie_.getHeight();
int top = 0, left = 0;
if ((static_cast<float>(mveWidth)/(mveHeight*mvePAR)) > (static_cast<float>(scrWidth)/scrHeight)) {
// letterbox
int newScrHeight = scrWidth/(static_cast<float>(mveWidth)/(mveHeight*mvePAR));
top = (scrHeight-newScrHeight)/2;
scrHeight = newScrHeight;
} else {
// pillarbox
int newScrWidth = scrHeight*(static_cast<float>(mveWidth)/(mveHeight*mvePAR));
left = (scrWidth-newScrWidth)/2;
scrWidth = newScrWidth;
}
overlay_ = std::make_unique<render::Overlay>(renderer_, scrWidth, scrHeight, left, top,
mveWidth, mveHeight);
auto align4Width = (mveWidth%4)?(mveWidth+(4-(mveWidth%4))):mveWidth;
frameRGB_.resize(align4Width*mveHeight*3);
decode_();
overlay_->setContentRGB8(frameRGB_.data());
decode_();
}
GSMvePlay::~GSMvePlay()
{
}
void GSMvePlay::decode_()
{
if (movie_.hasNext()) {
auto dec = movie_.decodeNext();
auto& frame = std::get<0>(dec);
auto& palette = std::get<1>(dec);
size_t i = 0;
for (unsigned y = 0;y < movie_.getHeight();++y) {
for (unsigned x = 0;x < movie_.getWidth();++x) {
auto idx = frame[y*movie_.getWidth()+x];
std::copy(&palette[idx*3], &palette[idx*3+3],
&frameRGB_[i]);
i += 3;
}
if ((i%4) != 0)
i += 4-(i%4);
}
} else
frameRGB_.resize(0);
}
void GSMvePlay::draw(unsigned delta_ms)
{
const float frameTime = 1000/15.0f;
delta_ += delta_ms;
if (delta_ >= nextFT_) {
if (!frameRGB_.size()) {
renderer_.popGS();
return;
}
if (delta_-nextFT_ <= frameTime)
nextFT_ = frameTime-(delta_-nextFT_);
else
nextFT_ = frameTime;
delta_ = 0;
overlay_->setContentRGB8(frameRGB_.data());
// Decode next frame
decode_();
}
overlay_->draw();
}
}