ULTIMA8: Refactor so all Crusader movies get subtitles

Previously there was a bit of duplication, and Weasel and the intro movies
didn't get subtitles.  Cleaned up the code a bit and now all are treated
consistently.
This commit is contained in:
Matthew Duggan 2021-05-08 13:58:54 +09:00
parent 531ed6865b
commit f5c4374888
4 changed files with 80 additions and 96 deletions

View File

@ -28,6 +28,7 @@
#include "ultima/ultima8/filesys/file_system.h"
#include "ultima/ultima8/graphics/palette_manager.h"
#include "ultima/ultima8/gumps/movie_gump.h"
#include "ultima/ultima8/gumps/gump_notify_process.h"
#include "ultima/ultima8/kernel/object_manager.h"
#include "ultima/ultima8/kernel/kernel.h"
#include "ultima/ultima8/world/world.h"
@ -149,15 +150,13 @@ bool RemorseGame::startInitialUsecode(int saveSlot) {
static ProcId playMovie(const char *movieID, bool fade, bool noScale) {
const Std::string filename = Std::string::format("flics/%s.avi", movieID);
FileSystem *filesys = FileSystem::get_instance();
Common::SeekableReadStream *rs = filesys->ReadFile(filename);
if (!rs) {
pout << "RemorseGame::playIntro: movie not found." << Std::endl;
MovieGump *gump = MovieGump::CruMovieViewer(movieID, 640, 480, nullptr, nullptr);
if (!gump) {
pout << "RemorseGame::playIntro: movie " << movieID << " not found." << Std::endl;
return 0;
}
// TODO: Add support for subtitles (.txt file). The format is very simple.
return MovieGump::U8MovieViewer(rs, fade, false, noScale);
gump->CreateNotifier();
return gump->GetNotifyProcess()->getPid();
}
ProcId RemorseGame::playIntroMovie(bool fade) {

View File

@ -40,6 +40,60 @@
namespace Ultima {
namespace Ultima8 {
static Std::string _fixCrusaderMovieName(const Std::string &s) {
/*
HACK! The game comes with movies MVA01.AVI etc, but the usecode mentions both
MVA01 and MVA1. We do a translation here. These are the strings we need to fix:
008E: 0D push string "mva1"
036D: 0D push string "mva3a"
04E3: 0D push string "mva4"
0656: 0D push string "mva5a"
07BD: 0D push string "mva6"
0944: 0D push string "mva7"
0A68: 0D push string "mva8"
0B52: 0D push string "mva9"
*/
if (s.size() == 4)
return Std::string::format("mva0%c", s[3]);
else if (s.equals("mva3a"))
return "mva03a";
else if (s.equals("mva5a"))
return "mva05a";
return s;
}
static Common::SeekableReadStream *_tryLoadCruMovieFile(const Std::string &filename, const char *extn) {
const Std::string path = Std::string::format("flics/%s.%s", filename.c_str(), extn);
FileSystem *filesys = FileSystem::get_instance();
Common::SeekableReadStream *rs = filesys->ReadFile(path);
if (!rs) {
// Try with a "0" in the name
const Std::string adjustedfn = Std::string::format("flics/0%s.%s", filename.c_str(), extn);
rs = filesys->ReadFile(adjustedfn);
if (!rs)
return nullptr;
}
return rs;
}
static Common::SeekableReadStream *_tryLoadCruAVI(const Std::string &filename) {
Common::SeekableReadStream *rs = _tryLoadCruMovieFile(filename, "avi");
if (!rs)
warning("movie %s not found", filename.c_str());
return rs;
}
// Convenience function that tries to open both TXT (No Remorse)
// and IFF (No Regret) subtitle formats.
static Common::SeekableReadStream *_tryLoadCruSubtitle(const Std::string &filename) {
Common::SeekableReadStream *txtfile = _tryLoadCruMovieFile(filename, "txt");
if (txtfile)
return txtfile;
return _tryLoadCruMovieFile(filename, "iff");
}
DEFINE_RUNTIME_CLASSTYPE_CODE(MovieGump)
MovieGump::MovieGump() : ModalGump(), _player(nullptr) {
@ -134,7 +188,7 @@ bool MovieGump::OnKeyDown(int key, int mod) {
return true;
}
//static
/*static*/
ProcId MovieGump::U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool introMusicHack, bool noScale) {
ModalGump *gump;
if (GAME_IS_U8)
@ -156,6 +210,18 @@ ProcId MovieGump::U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool
}
}
/*static*/ MovieGump *MovieGump::CruMovieViewer(const Std::string fname, int x, int y, const byte *pal, Gump *parent) {
Common::SeekableReadStream *rs = _tryLoadCruAVI(fname);
if (!rs)
return nullptr;
MovieGump *gump = new MovieGump(x, y, rs, false, false, pal);
gump->InitGump(parent, true);
gump->setRelativePosition(CENTER);
gump->loadSubtitles(_tryLoadCruSubtitle(fname));
return gump;
}
void MovieGump::loadSubtitles(Common::SeekableReadStream *rs) {
if (!rs)
return;
@ -197,59 +263,6 @@ void MovieGump::saveData(Common::WriteStream *ws) {
}
static Std::string _fixCrusaderMovieName(const Std::string &s) {
/*
HACK! The game comes with movies MVA01.AVI etc, but the usecode mentions both
MVA01 and MVA1. We do a translation here. These are the strings we need to fix:
008E: 0D push string "mva1"
036D: 0D push string "mva3a"
04E3: 0D push string "mva4"
0656: 0D push string "mva5a"
07BD: 0D push string "mva6"
0944: 0D push string "mva7"
0A68: 0D push string "mva8"
0B52: 0D push string "mva9"
*/
if (s.size() == 4)
return Std::string::format("mva0%c", s[3]);
else if (s.equals("mva3a"))
return "mva03a";
else if (s.equals("mva5a"))
return "mva05a";
return s;
}
static Common::SeekableReadStream *_tryLoadCruMovieFile(const Std::string &filename, const char *extn) {
const Std::string path = Std::string::format("flics/%s.%s", filename.c_str(), extn);
FileSystem *filesys = FileSystem::get_instance();
Common::SeekableReadStream *rs = filesys->ReadFile(path);
if (!rs) {
// Try with a "0" in the name
const Std::string adjustedfn = Std::string::format("flics/0%s.%s", filename.c_str(), extn);
rs = filesys->ReadFile(adjustedfn);
if (!rs)
return nullptr;
}
return rs;
}
static Common::SeekableReadStream *_tryLoadCruAVI(const Std::string &filename) {
Common::SeekableReadStream *rs = _tryLoadCruMovieFile(filename, "avi");
if (!rs)
warning("movie %s not found", filename.c_str());
return rs;
}
// Convenience function that tries to open both TXT (No Remorse)
// and IFF (No Regret) subtitle formats.
static Common::SeekableReadStream *_tryLoadCruSubtitle(const Std::string &filename) {
Common::SeekableReadStream *txtfile = _tryLoadCruMovieFile(filename, "txt");
if (txtfile)
return txtfile;
return _tryLoadCruMovieFile(filename, "iff");
}
uint32 MovieGump::I_playMovieOverlay(const uint8 *args,
unsigned int /*argsize*/) {
ARG_ITEM_FROM_PTR(item);
@ -267,13 +280,7 @@ uint32 MovieGump::I_playMovieOverlay(const uint8 *args,
const Palette *pal = palman->getPalette(PaletteManager::Pal_Game);
assert(pal);
Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
if (rs) {
MovieGump *gump = new MovieGump(x, y, rs, false, false, pal->_palette);
gump->InitGump(nullptr, true);
gump->setRelativePosition(CENTER);
gump->loadSubtitles(_tryLoadCruSubtitle(name));
}
CruMovieViewer(name, x, y, pal->_palette, nullptr);
}
return 0;
@ -286,13 +293,7 @@ uint32 MovieGump::I_playMovieCutscene(const uint8 *args, unsigned int /*argsize*
ARG_UINT16(y);
if (item) {
Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
if (rs) {
MovieGump *gump = new MovieGump(x * 3, y * 3, rs, false, false);
gump->InitGump(nullptr, true);
gump->setRelativePosition(CENTER);
gump->loadSubtitles(_tryLoadCruSubtitle(name));
}
CruMovieViewer(name, x * 3, y * 3, nullptr, nullptr);
}
return 0;
@ -312,13 +313,7 @@ uint32 MovieGump::I_playMovieCutsceneAlt(const uint8 *args, unsigned int /*argsi
warning("MovieGump::I_playMovieCutsceneAlt: TODO: This intrinsic should pause and fade the background to grey");
if (item) {
Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
if (rs) {
MovieGump *gump = new MovieGump(x * 3, y * 3, rs, false, false);
gump->InitGump(nullptr, true);
gump->setRelativePosition(CENTER);
gump->loadSubtitles(_tryLoadCruSubtitle(name));
}
CruMovieViewer(name, x * 3, y * 3, nullptr, nullptr);
}
return 0;
@ -330,13 +325,7 @@ uint32 MovieGump::I_playMovieCutsceneRegret(const uint8 *args, unsigned int /*ar
warning("MovieGump::I_playMovieCutsceneRegret: TODO: use fade argument %d", fade);
Common::SeekableReadStream *rs = _tryLoadCruAVI(name);
if (rs) {
MovieGump *gump = new MovieGump(640, 480, rs, false, false);
gump->InitGump(nullptr, true);
gump->setRelativePosition(CENTER);
gump->loadSubtitles(_tryLoadCruSubtitle(name));
}
CruMovieViewer(name, 640, 480, nullptr, nullptr);
return 0;
}

View File

@ -56,6 +56,7 @@ public:
bool OnKeyDown(int key, int mod) override;
static ProcId U8MovieViewer(Common::SeekableReadStream *rs, bool fade, bool introMusicHack, bool noScale);
static MovieGump *CruMovieViewer(const Std::string fname, int x, int y, const byte *pal, Gump *parent);
bool loadData(Common::ReadStream *rs);
void saveData(Common::WriteStream *ws) override;

View File

@ -196,16 +196,11 @@ void WeaselGump::InitGump(Gump *newparent, bool take_focus) {
}
Gump *WeaselGump::playMovie(const Std::string &filename) {
const Std::string path = Std::string::format("flics/%s.avi", filename.c_str());
FileSystem *filesys = FileSystem::get_instance();
Common::SeekableReadStream *rs = filesys->ReadFile(path);
if (!rs) {
MovieGump *gump = MovieGump::CruMovieViewer(filename, 600, 450, nullptr, this);
if (!gump) {
warning("Couldn't load flic %s", filename.c_str());
return nullptr;
}
Gump *gump = new MovieGump(600, 450, rs, false, false);
gump->InitGump(this, true);
gump->setRelativePosition(CENTER);
gump->CreateNotifier();
return gump;
}