mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-04 14:05:32 +02:00
Clean up videos some more, make them skippable
Also, revert a change I made to the button names internally a long time ago, when the intent behind mkxp-z was possibly going to be different.
This commit is contained in:
parent
45c5553619
commit
84f95966ea
7 changed files with 66 additions and 56 deletions
|
@ -264,14 +264,17 @@ RB_METHOD(graphicsPlayMovie)
|
|||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
VALUE filename, volumeArg;
|
||||
rb_scan_args(argc, argv, "11", &filename, &volumeArg);
|
||||
VALUE filename, volumeArg, skippable;
|
||||
rb_scan_args(argc, argv, "12", &filename, &volumeArg, &skippable);
|
||||
SafeStringValue(filename);
|
||||
|
||||
bool skip;
|
||||
rb_bool_arg(skippable, &skip);
|
||||
int volume = (volumeArg == Qnil) ? 100 : NUM2INT(volumeArg);
|
||||
|
||||
// TODO: Video control inputs (e.g. skip, pause)
|
||||
|
||||
GFX_GUARD_EXC(shState->graphics().playMovie(RSTRING_PTR(filename), volume););
|
||||
GFX_GUARD_EXC(shState->graphics().playMovie(RSTRING_PTR(filename), volume, skip););
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
|
|
@ -367,8 +367,8 @@ struct {
|
|||
{"LEFT", Input::Left},
|
||||
{"RIGHT", Input::Right},
|
||||
{"UP", Input::Up},
|
||||
{"C", Input::ZL},
|
||||
{"Z", Input::ZR},
|
||||
{"C", Input::C},
|
||||
{"Z", Input::Z},
|
||||
{"A", Input::A},
|
||||
{"B", Input::B},
|
||||
{"X", Input::X},
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
static const int inputMapRowToCode[] {
|
||||
Input::Down, Input::Left, Input::Right, Input::Up,
|
||||
Input::A, Input:: B, Input::ZL, Input::X, Input::Y, Input::ZR,
|
||||
Input::A, Input:: B, Input::C, Input::X, Input::Y, Input::Z,
|
||||
Input::L, Input::R
|
||||
};
|
||||
|
||||
|
@ -280,10 +280,10 @@ s.d.ja.dir = (axis.value >= 0) ? AxisDir::Positive : AxisDir::Negative;
|
|||
SET_BINDING(Up);
|
||||
SET_BINDING(A);
|
||||
SET_BINDING(B);
|
||||
SET_BINDING_CUSTOM(ZL, "C");
|
||||
SET_BINDING(C);
|
||||
SET_BINDING(X);
|
||||
SET_BINDING(Y);
|
||||
SET_BINDING_CUSTOM(ZR, "Z");
|
||||
SET_BINDING(Z);
|
||||
SET_BINDING(L);
|
||||
SET_BINDING(R);
|
||||
|
||||
|
@ -292,10 +292,10 @@ if (!data.config.kbActionNames.value.empty()) bindingNames[@(Input::code)] = \
|
|||
@(data.config.kbActionNames.value.c_str())
|
||||
SET_BINDING_CONF(A,a);
|
||||
SET_BINDING_CONF(B,b);
|
||||
SET_BINDING_CONF(ZL,c);
|
||||
SET_BINDING_CONF(C,c);
|
||||
SET_BINDING_CONF(X,x);
|
||||
SET_BINDING_CONF(Y,y);
|
||||
SET_BINDING_CONF(ZR,z);
|
||||
SET_BINDING_CONF(Z,z);
|
||||
SET_BINDING_CONF(L,l);
|
||||
SET_BINDING_CONF(R,r);
|
||||
|
||||
|
|
|
@ -104,12 +104,13 @@ struct Movie
|
|||
const THEORAPLAY_VideoFrame *video;
|
||||
bool hasVideo;
|
||||
bool hasAudio;
|
||||
bool skippable;
|
||||
Bitmap *videoBitmap;
|
||||
SDL_RWops srcOps;
|
||||
static float volume;
|
||||
|
||||
Movie(int volume_)
|
||||
: decoder(0), audio(0), video(0)
|
||||
Movie(int volume_, bool skippable_)
|
||||
: decoder(0), audio(0), video(0), skippable(skippable_), videoBitmap(0)
|
||||
{
|
||||
volume = volume_ * 0.01f;
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ struct Movie
|
|||
SDL_Delay(VIDEO_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
videoBitmap = new Bitmap(video->width, video->height);
|
||||
movieAudioQueue = NULL;
|
||||
movieAudioQueueTail = NULL;
|
||||
|
||||
|
@ -284,12 +285,18 @@ struct Movie
|
|||
void play()
|
||||
{
|
||||
// Assuming every frame has the same duration.
|
||||
Uint32 frameMs = (video->fps == 0.0) ? 0 : ((Uint32) (1000.0 / video->fps));
|
||||
// Uint32 frameMs = (video->fps == 0.0) ? 0 : ((Uint32) (1000.0 / video->fps));
|
||||
Uint32 baseTicks = SDL_GetTicks();
|
||||
bool openedAudio = false;
|
||||
while (THEORAPLAY_isDecoding(decoder)) {
|
||||
// Check for reset/shutdown input
|
||||
if(shState->graphics().updateMovieInput(this)) break;
|
||||
|
||||
// Check for attempted skip
|
||||
if (skippable) {
|
||||
shState->input().update();
|
||||
if (shState->input().isTriggered(Input::C) || shState->input().isTriggered(Input::B)) break;
|
||||
}
|
||||
|
||||
const Uint32 now = SDL_GetTicks() - baseTicks;
|
||||
|
||||
|
@ -312,25 +319,12 @@ struct Movie
|
|||
|
||||
}
|
||||
|
||||
if (video && (video->playms <= now)) {
|
||||
|
||||
// Application is too far behind
|
||||
if (!video) {
|
||||
Debug() << "WARNING: Video playback cannot keep up!";
|
||||
break;
|
||||
}
|
||||
|
||||
// Got a video frame, now draw it
|
||||
videoBitmap->replaceRaw(video->pixels, video->width * video->height * 4);
|
||||
shState->graphics().update();
|
||||
THEORAPLAY_freeVideo(video);
|
||||
video = NULL;
|
||||
|
||||
} else {
|
||||
// Next video frame not yet ready, let the CPU breathe
|
||||
SDL_Delay(VIDEO_DELAY);
|
||||
}
|
||||
|
||||
// Got a video frame, now draw it
|
||||
videoBitmap->replaceRaw(video->pixels, video->width * video->height * 4);
|
||||
shState->graphics().update(false);
|
||||
THEORAPLAY_freeVideo(video);
|
||||
video = NULL;
|
||||
|
||||
if (openedAudio) {
|
||||
queueMoreMovieAudio(decoder, now);
|
||||
}
|
||||
|
@ -954,10 +948,13 @@ unsigned long long Graphics::lastUpdate() {
|
|||
return p->last_update;
|
||||
}
|
||||
|
||||
void Graphics::update() {
|
||||
void Graphics::update(bool checkForShutdown) {
|
||||
p->threadData->rqWindowAdjust.wait();
|
||||
p->last_update = shState->runTime();
|
||||
p->checkShutDownReset();
|
||||
|
||||
if (checkForShutdown)
|
||||
p->checkShutDownReset();
|
||||
|
||||
p->checkSyncLock();
|
||||
|
||||
|
||||
|
@ -1227,31 +1224,41 @@ bool Graphics::updateMovieInput(Movie *movie) {
|
|||
return p->threadData->rqTerm || p->threadData->rqReset;
|
||||
}
|
||||
|
||||
void Graphics::playMovie(const char *filename, int volume) {
|
||||
Movie *movie = new Movie(volume);
|
||||
void Graphics::playMovie(const char *filename, int volume, bool skippable) {
|
||||
Movie *movie = new Movie(volume, skippable);
|
||||
MovieOpenHandler handler(movie->srcOps);
|
||||
shState->fileSystem().openRead(handler, filename);
|
||||
|
||||
if (movie->preparePlayback()) {
|
||||
int limiterDisabled = p->fpsLimiter.disabled;
|
||||
p->fpsLimiter.disabled = false;
|
||||
p->fpsLimiter.setDesiredFPS(movie->video->fps);
|
||||
int oldFPS = getFrameRate();
|
||||
setFrameRate(movie->video->fps);
|
||||
bool oldframeskip = p->useFrameSkip;
|
||||
p->useFrameSkip = true;
|
||||
p->useFrameSkip = false;
|
||||
update();
|
||||
|
||||
Sprite movieSprite;
|
||||
movie->videoBitmap = new Bitmap(movie->video->width, movie->video->height);
|
||||
|
||||
// Currently this stretches to fit the screen. VX Ace behavior is to center it and let the edges run off
|
||||
movieSprite.setBitmap(movie->videoBitmap);
|
||||
movieSprite.setZoomX((double)width() / movie->video->width);
|
||||
movieSprite.setZoomY((double)height() / movie->video->height);
|
||||
double ratio = (double)width() / movie->video->width;
|
||||
movieSprite.setZoomX(ratio);
|
||||
movieSprite.setZoomY(ratio);
|
||||
movieSprite.setY((height() / 2) - (movie->video->height * ratio / 2));
|
||||
|
||||
Sprite letterboxSprite;
|
||||
Bitmap letterbox(width(), height());
|
||||
letterbox.fillRect(0, 0, width(), height(), Vec4(0,0,0,255));
|
||||
letterboxSprite.setBitmap(&letterbox);
|
||||
|
||||
letterboxSprite.setZ(-1001);
|
||||
movieSprite.setZ(-1000);
|
||||
|
||||
movie->play();
|
||||
|
||||
p->fpsLimiter.disabled = limiterDisabled;
|
||||
p->fpsLimiter.setDesiredFPS(p->frameRate);
|
||||
setFrameRate(oldFPS);
|
||||
p->useFrameSkip = oldframeskip;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
unsigned long long getDelta();
|
||||
unsigned long long lastUpdate();
|
||||
|
||||
void update();
|
||||
void update(bool checkForShutdown = true);
|
||||
void freeze();
|
||||
void transition(int duration = 8,
|
||||
const char *filename = "",
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
void resizeScreen(int width, int height);
|
||||
void drawMovieFrame(const THEORAPLAY_VideoFrame* video, Bitmap *videoBitmap);
|
||||
bool updateMovieInput(Movie *movie);
|
||||
void playMovie(const char *filename, int volume);
|
||||
void playMovie(const char *filename, int volume, bool skippable);
|
||||
void screenshot(const char *filename);
|
||||
|
||||
void reset();
|
||||
|
|
|
@ -41,8 +41,8 @@ public:
|
|||
|
||||
Down = 2, Left = 4, Right = 6, Up = 8,
|
||||
|
||||
A = 11, B = 12, ZL = 13,
|
||||
X = 14, Y = 15, ZR = 16,
|
||||
A = 11, B = 12, C = 13,
|
||||
X = 14, Y = 15, Z = 16,
|
||||
L = 17, R = 18,
|
||||
|
||||
Shift = 21, Ctrl = 22, Alt = 23,
|
||||
|
|
|
@ -72,13 +72,13 @@ static const KbBindingData defaultKbBindings[] =
|
|||
{ SDL_SCANCODE_UP, Input::Up },
|
||||
{ SDL_SCANCODE_DOWN, Input::Down },
|
||||
|
||||
{ SDL_SCANCODE_SPACE, Input::ZL },
|
||||
{ SDL_SCANCODE_RETURN, Input::ZL },
|
||||
{ SDL_SCANCODE_SPACE, Input::C },
|
||||
{ SDL_SCANCODE_RETURN, Input::C },
|
||||
{ SDL_SCANCODE_ESCAPE, Input::B },
|
||||
{ SDL_SCANCODE_KP_0, Input::B },
|
||||
{ SDL_SCANCODE_LSHIFT, Input::A },
|
||||
{ SDL_SCANCODE_X, Input::B },
|
||||
{ SDL_SCANCODE_D, Input::ZR },
|
||||
{ SDL_SCANCODE_D, Input::Z },
|
||||
{ SDL_SCANCODE_Q, Input::L },
|
||||
{ SDL_SCANCODE_W, Input::R },
|
||||
{ SDL_SCANCODE_A, Input::X },
|
||||
|
@ -89,13 +89,13 @@ static const KbBindingData defaultKbBindings[] =
|
|||
static const KbBindingData defaultKbBindings1[] =
|
||||
{
|
||||
{ SDL_SCANCODE_Z, Input::A },
|
||||
{ SDL_SCANCODE_C, Input::ZL },
|
||||
{ SDL_SCANCODE_C, Input::C },
|
||||
};
|
||||
|
||||
/* RGSS2 and higher */
|
||||
static const KbBindingData defaultKbBindings2[] =
|
||||
{
|
||||
{ SDL_SCANCODE_Z, Input::ZL }
|
||||
{ SDL_SCANCODE_Z, Input::C }
|
||||
};
|
||||
|
||||
static elementsN(defaultKbBindings);
|
||||
|
@ -106,10 +106,10 @@ static const JsBindingData defaultJsBindings[] =
|
|||
{
|
||||
{ 3, Input::A },
|
||||
{ 0, Input::B },
|
||||
{ 1, Input::ZL },
|
||||
{ 1, Input::C },
|
||||
{ 2, Input::X },
|
||||
{ 4, Input::Y },
|
||||
{ 5, Input::ZR },
|
||||
{ 5, Input::Z },
|
||||
{ 9, Input::L },
|
||||
{ 10, Input::R }
|
||||
};
|
||||
|
@ -240,8 +240,8 @@ static bool verifyDesc(const BindingDesc &desc)
|
|||
{
|
||||
Input::None,
|
||||
Input::Down, Input::Left, Input::Right, Input::Up,
|
||||
Input::A, Input::B, Input::ZL,
|
||||
Input::X, Input::Y, Input::ZR,
|
||||
Input::A, Input::B, Input::C,
|
||||
Input::X, Input::Y, Input::Z,
|
||||
Input::L, Input::R,
|
||||
Input::Shift, Input::Ctrl, Input::Alt,
|
||||
Input::F5, Input::F6, Input::F7, Input::F8, Input::F9
|
||||
|
|
Loading…
Add table
Reference in a new issue