121 lines
2.7 KiB
C++
121 lines
2.7 KiB
C++
#include <cstdio>
|
|
#include <cstring>
|
|
#include <cerrno>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <limits>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "common.hh"
|
|
#include "util.hh"
|
|
#include "TreFile.hh"
|
|
#include "IffFile.hh"
|
|
#include "MveDecoder.hh"
|
|
#include "render/Renderer.hh"
|
|
#include "game/GSMvePlay.hh"
|
|
|
|
using render::Renderer;
|
|
|
|
void usage(char *argv0) {
|
|
fprintf(stderr, "Usage: %s [-h] (tre-file name/crc)/iff-file\n", argv0);
|
|
fprintf(stderr, "\tAttempt to decode the movie stored in iff-file, or in the\n\tiff-object \"name\"/\"crc\" contained in tre-file\n");
|
|
fprintf(stderr, "\t-p [id]\tPlay branch id, or all branches if no id given\n");
|
|
fprintf(stderr, "\t-h\tPrint this help\n");
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
std::string inFile, objectSpec;
|
|
int branch = -1;
|
|
bool useTre = false, play = false;
|
|
{
|
|
int opt;
|
|
while ((opt = getopt(argc, argv, "hp::")) != -1) {
|
|
switch (opt) {
|
|
case 'h':
|
|
usage(argv[0]);
|
|
return 0;
|
|
case 'p':
|
|
play = true;
|
|
if (optarg) {
|
|
try {
|
|
branch = std::stoi(optarg, nullptr, 10);
|
|
} catch (std::invalid_argument &ex) {
|
|
} catch (std::out_of_range &ex) {
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (optind >= argc) {
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
inFile = argv[optind++];
|
|
|
|
if (optind < argc) {
|
|
useTre = true;
|
|
objectSpec = argv[optind];
|
|
}
|
|
}
|
|
|
|
try {
|
|
MmapFile mmap{inFile};
|
|
|
|
std::unique_ptr<TreFile> tre;
|
|
TreFile::Object object;
|
|
std::unique_ptr<MveDecoder> mve;
|
|
if (useTre) {
|
|
tre = std::make_unique<TreFile>(mmap.data(), mmap.size());
|
|
|
|
// Try to parse objectSpec as CRC
|
|
try {
|
|
unsigned long CRC = std::stoul(objectSpec, nullptr, 16);
|
|
if (CRC <= std::numeric_limits<uint32_t>::max()) {
|
|
object = tre->openCRC(CRC);
|
|
}
|
|
} catch (std::invalid_argument &ex) {
|
|
} catch (std::out_of_range &ex) {
|
|
}
|
|
|
|
|
|
if (!object) // Wasn't a CRC, try as name
|
|
object = tre->openName(objectSpec);
|
|
|
|
mve = std::make_unique<MveDecoder>(object);
|
|
} else
|
|
mve = std::make_unique<MveDecoder>(mmap);
|
|
|
|
if (play) {
|
|
Renderer renderer;
|
|
|
|
if (branch >= 0) {
|
|
auto movie = mve->open(branch);
|
|
renderer.pushGS(std::make_unique<game::GSMvePlay>(renderer, movie));
|
|
renderer.run();
|
|
} else {
|
|
for(unsigned i = 0;i < mve->numBranches();++i) {
|
|
auto movie = mve->open(i);
|
|
renderer.pushGS(std::make_unique<game::GSMvePlay>(renderer, movie));
|
|
renderer.run();
|
|
}
|
|
}
|
|
}
|
|
} catch (POSIXException &ex) {
|
|
fflush(stdout);
|
|
fprintf(stderr, "%s\n", ex.toString().c_str());
|
|
return 2;
|
|
} catch (Exception &ex) {
|
|
fflush(stdout);
|
|
fprintf(stderr, "%s\n", ex.toString().c_str());
|
|
return 3;
|
|
}
|
|
|
|
return 0;
|
|
}
|