mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 09:34:18 +02:00
play logo FMV; loading screen skipping; fix click at start playing of PSX FMVs
This commit is contained in:
@@ -26,7 +26,7 @@ namespace Game {
|
||||
if (level->level.isTitle() && id != TR::LVL_MAX)
|
||||
playVideo = false;
|
||||
|
||||
level->init(playVideo);
|
||||
level->init(id == TR::LVL_MAX, playVideo);
|
||||
|
||||
UI::game = level;
|
||||
#if !defined(_OS_PSP) && !defined(_OS_CLOVER)
|
||||
|
@@ -868,6 +868,31 @@ namespace TR {
|
||||
}
|
||||
}
|
||||
|
||||
const char* getGameLogo(Version version) {
|
||||
if (version & VER_TR1) {
|
||||
CHECK_FILE("FMV/CORELOGO.FMV");
|
||||
CHECK_FILE("FMV/CORE.RPL");
|
||||
CHECK_FILE("video/1/CORELOGO.FMV");
|
||||
return "video/1/CORE.RPL";
|
||||
}
|
||||
|
||||
if (version & VER_TR2) {
|
||||
CHECK_FILE("FMV/LOGO.FMV");
|
||||
CHECK_FILE("FMV/LOGO.RPL");
|
||||
CHECK_FILE("video/2/LOGO.FMV");
|
||||
return "video/2/LOGO.RPL";
|
||||
}
|
||||
|
||||
if (version & VER_TR3) {
|
||||
CHECK_FILE("FMV/LOGO.FMV");
|
||||
CHECK_FILE("fmv/logo.rpl");
|
||||
CHECK_FILE("video/3/LOGO.FMV");
|
||||
return "video/3/logo.rpl";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* getGameVideo(LevelID id) {
|
||||
switch (id) {
|
||||
// TR1
|
||||
|
@@ -33,7 +33,7 @@ struct OptionItem {
|
||||
uint32 icon;
|
||||
uint8 maxValue;
|
||||
bool bar;
|
||||
|
||||
|
||||
OptionItem(Type type = TYPE_EMPTY, int title = STR_NOT_IMPLEMENTED, intptr_t offset = 0, uint32 color = 0xFFFFFFFF, int icon = 0, uint8 maxValue = 0, bool bar = false) : type(type), title(StringID(title)), offset(offset), color(color), icon(icon), maxValue(maxValue), bar(bar) {}
|
||||
|
||||
void setValue(uint8 value, Core::Settings *settings) const {
|
||||
@@ -214,6 +214,9 @@ struct Inventory {
|
||||
Texture *background[2];
|
||||
Video *video;
|
||||
|
||||
bool playLogo;
|
||||
bool playVideo;
|
||||
|
||||
bool active;
|
||||
bool chosen;
|
||||
float phaseRing, phasePage, phaseChoose, phaseSelect;
|
||||
@@ -478,6 +481,14 @@ struct Inventory {
|
||||
new Stream(TR::getGameScreen(inv->game->getLevel()->id), loadTitleBG, inv);
|
||||
}
|
||||
|
||||
static void loadLogo(Stream *stream, void *userData) {
|
||||
Inventory *inv = (Inventory*)userData;
|
||||
if (stream)
|
||||
inv->video = new Video(stream);
|
||||
else
|
||||
inv->skipVideo();
|
||||
}
|
||||
|
||||
Inventory(IGame *game) : game(game), active(false), chosen(false), index(0), targetIndex(0), page(PAGE_OPTION), targetPage(PAGE_OPTION), itemsCount(0), playerIndex(0), changeTimer(0.0f), nextLevel(TR::LVL_MAX), lastKey(cMAX) {
|
||||
TR::LevelID id = game->getLevel()->id;
|
||||
|
||||
@@ -545,10 +556,21 @@ struct Inventory {
|
||||
delete background[i];
|
||||
}
|
||||
|
||||
void init(bool playVideo) {
|
||||
void startVideo() {
|
||||
new Stream(playVideo ? TR::getGameVideo(game->getLevel()->id) : NULL, loadVideo, this);
|
||||
}
|
||||
|
||||
void init(bool playLogo, bool playVideo) {
|
||||
this->playLogo = playLogo;
|
||||
this->playVideo = playVideo;
|
||||
|
||||
if (playLogo) {
|
||||
new Stream(TR::getGameLogo(game->getLevel()->version), loadLogo, this);
|
||||
return;
|
||||
}
|
||||
startVideo();
|
||||
}
|
||||
|
||||
bool isActive() {
|
||||
return active || phaseRing > 0.0f;
|
||||
}
|
||||
@@ -919,6 +941,16 @@ struct Inventory {
|
||||
void skipVideo() {
|
||||
delete video;
|
||||
video = NULL;
|
||||
|
||||
if (playLogo) {
|
||||
playLogo = false;
|
||||
if (playVideo) {
|
||||
startVideo();
|
||||
return;
|
||||
}
|
||||
}
|
||||
playVideo = false;
|
||||
|
||||
game->playTrack(0);
|
||||
if (game->getLevel()->isTitle()) {
|
||||
titleTimer = 0.0f;
|
||||
@@ -928,10 +960,17 @@ struct Inventory {
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (video && (Input::state[0][cInventory] || Input::state[0][cAction] || Input::state[0][cJump] ||
|
||||
Input::state[1][cInventory] || Input::state[1][cAction] || Input::state[1][cJump] ||
|
||||
Input::down[ikCtrl] || Input::down[ikEnter] || Input::down[ikAlt]))
|
||||
skipVideo();
|
||||
if (titleTimer > 1.0f && (
|
||||
Input::state[0][cInventory] || Input::state[0][cAction] || Input::state[0][cJump] ||
|
||||
Input::state[1][cInventory] || Input::state[1][cAction] || Input::state[1][cJump] ||
|
||||
Input::down[ikCtrl] || Input::down[ikEnter] || Input::down[ikAlt]))
|
||||
{
|
||||
if (video) {
|
||||
if (video->time > 0.5f)
|
||||
skipVideo();
|
||||
} else if (titleTimer > 1.0f && titleTimer < 2.5f)
|
||||
titleTimer = 1.0f;
|
||||
}
|
||||
|
||||
if (video) {
|
||||
video->update();
|
||||
@@ -1555,14 +1594,14 @@ struct Inventory {
|
||||
Texture *tmp = background[0];
|
||||
|
||||
float sy = 1.0f;
|
||||
if (game->getLevel()->version & TR::VER_TR1)
|
||||
if ((game->getLevel()->version & TR::VER_TR1) && !playLogo)
|
||||
sy = 1.2f;
|
||||
|
||||
background[0] = video->frameTex[0];
|
||||
renderTitleBG(1.0f, sy, 255);
|
||||
|
||||
background[0] = video->frameTex[1];
|
||||
renderTitleBG(1.0f, sy, clamp(int((video->time / video->step) * 255), 0, 255));
|
||||
renderTitleBG(1.0f, sy, clamp(int((video->stepTimer / video->step) * 255), 0, 255));
|
||||
|
||||
background[0] = tmp;
|
||||
|
||||
|
@@ -759,8 +759,8 @@ struct Level : IGame {
|
||||
Sound::stopAll();
|
||||
}
|
||||
|
||||
void init(bool playVideo) {
|
||||
inventory->init(playVideo);
|
||||
void init(bool playLogo, bool playVideo) {
|
||||
inventory->init(playLogo, playVideo);
|
||||
}
|
||||
|
||||
void addPlayer(int index) {
|
||||
|
39
src/video.h
39
src/video.h
@@ -1099,14 +1099,27 @@ struct Video {
|
||||
int i = 0;
|
||||
while (i < count) {
|
||||
if (xa->pos >= COUNT(xa->buffer)) {
|
||||
if (aFrames[curAudioFrame].size == 0)
|
||||
if (aFrames[curAudioFrame].size == 0) {
|
||||
curAudioFrame = (curAudioFrame + 1) % AUDIO_MAX_FRAMES;
|
||||
|
||||
if (aFrames[curAudioFrame].size == 0) {
|
||||
stream->setPos(oldPos);
|
||||
nextFrame();
|
||||
oldPos = stream->pos;
|
||||
curAudioFrame = aFrameIndex;
|
||||
if (aFrames[curAudioFrame].size == 0) {
|
||||
// check next 3 frames for audio frame
|
||||
stream->setPos(oldPos);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
nextFrame();
|
||||
curAudioFrame = aFrameIndex;
|
||||
if (curAudioFrame != -1 && aFrames[curAudioFrame].size != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (curAudioFrame == -1) { // no audio frames found!
|
||||
ASSERT(false);
|
||||
memset(frames, 0, count * sizeof(Sound::Frame));
|
||||
return count;
|
||||
}
|
||||
|
||||
oldPos = stream->pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
stream->setPos(aFrames[curAudioFrame].pos);
|
||||
@@ -1126,12 +1139,12 @@ struct Video {
|
||||
Decoder *decoder;
|
||||
Texture *frameTex[2];
|
||||
Color32 *frameData;
|
||||
float time, step;
|
||||
float step, stepTimer, time;
|
||||
bool isPlaying;
|
||||
bool needUpdate;
|
||||
Sound::Sample *sample;
|
||||
|
||||
Video(Stream *stream) : decoder(NULL), time(0.0f), isPlaying(false) {
|
||||
Video(Stream *stream) : decoder(NULL), time(0.0f), stepTimer(0.0f), isPlaying(false) {
|
||||
frameTex[0] = frameTex[1] = NULL;
|
||||
|
||||
if (!stream) return;
|
||||
@@ -1154,7 +1167,8 @@ struct Video {
|
||||
sample = Sound::play(decoder);
|
||||
|
||||
step = 1.0f / decoder->fps;
|
||||
time = step;
|
||||
stepTimer = step;
|
||||
time = 0.0f;
|
||||
isPlaying = true;
|
||||
}
|
||||
|
||||
@@ -1171,10 +1185,11 @@ struct Video {
|
||||
void update() {
|
||||
if (!isPlaying) return;
|
||||
|
||||
time += Core::deltaTime;
|
||||
if (time < step)
|
||||
stepTimer += Core::deltaTime;
|
||||
if (stepTimer < step)
|
||||
return;
|
||||
time -= step;
|
||||
stepTimer -= step;
|
||||
time += step;
|
||||
#ifdef VIDEO_TEST
|
||||
int t = Core::getTime();
|
||||
while (decoder->decodeVideo(frameData)) {}
|
||||
|
Reference in New Issue
Block a user