96 lines
2.4 KiB
C++
96 lines
2.4 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;
|
|
auto height = movie_.getHeight(), width = movie_.getWidth();
|
|
for (unsigned y = 0;y < height;++y) {
|
|
for (unsigned x = 0;x < width;++x) {
|
|
auto idx = frame[y*width+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();
|
|
}
|
|
}
|