126 lines
3.0 KiB
C++
126 lines
3.0 KiB
C++
#include "MveDecoder.hh"
|
|
|
|
#include "GSMvePlay.hh"
|
|
#include "render/Overlay.hh"
|
|
#include "render/Renderer.hh"
|
|
#include "render/AudioStream.hh"
|
|
|
|
namespace game {
|
|
GSMvePlay::GSMvePlay(render::Renderer& renderer, MveDecoder::Movie& movie)
|
|
: GameState(renderer), movie_(movie),
|
|
overlay_(nullptr), delta_(0),
|
|
nextFT_(1000/15.0f), frameRGBA_(), decoded_(false), firstFrame_(true)
|
|
{
|
|
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);
|
|
|
|
audio_ = std::make_unique<render::AudioStream>();
|
|
|
|
frameRGBA_.resize(mveWidth*mveHeight*4);
|
|
|
|
decode_();
|
|
overlay_->setContentBGRA8(frameRGBA_.data());
|
|
decode_();
|
|
}
|
|
|
|
GSMvePlay::~GSMvePlay()
|
|
{
|
|
}
|
|
|
|
void GSMvePlay::decode_()
|
|
{
|
|
if (movie_.hasAudio()) {
|
|
auto samples = movie_.getNextAudio();
|
|
audio_->queueSamples(1, 22050, samples.data(), samples.size()*2);
|
|
}
|
|
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];
|
|
|
|
frameRGBA_[i] = palette[idx*3+2];
|
|
frameRGBA_[i+1] = palette[idx*3+1];
|
|
frameRGBA_[i+2] = palette[idx*3];
|
|
frameRGBA_[i+3] = 255u;
|
|
|
|
i += 4;
|
|
}
|
|
}
|
|
} else
|
|
frameRGBA_.resize(0);
|
|
}
|
|
|
|
bool GSMvePlay::handleEvent(SDL_Event& event)
|
|
{
|
|
switch (event.type) {
|
|
case SDL_KEYDOWN:
|
|
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
|
renderer_.popGS();
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void GSMvePlay::draw(unsigned delta_ms)
|
|
{
|
|
const float frameTime = 1000/15.0f;
|
|
if (firstFrame_) {
|
|
firstFrame_ = false;
|
|
audio_->play();
|
|
}
|
|
|
|
delta_ += delta_ms;
|
|
if (delta_ >= nextFT_) {
|
|
if (!decoded_)
|
|
decode_();
|
|
if (!frameRGBA_.size()) {
|
|
renderer_.popGS();
|
|
return;
|
|
}
|
|
|
|
if (delta_-nextFT_ <= frameTime)
|
|
nextFT_ = frameTime-(delta_-nextFT_);
|
|
else
|
|
nextFT_ = frameTime;
|
|
|
|
delta_ = 0;
|
|
|
|
overlay_->setContentBGRA8(frameRGBA_.data());
|
|
|
|
decoded_ = false;
|
|
} else if (!decoded_) {
|
|
decode_();
|
|
decoded_ = true;
|
|
}
|
|
|
|
overlay_->draw();
|
|
}
|
|
}
|