Command line option parsing complete.

This commit is contained in:
Scott Duensing 2019-12-01 19:12:12 -06:00
parent a68e114c1e
commit 90a24f67d4
10 changed files with 594 additions and 26 deletions

2
.gitignore vendored
View file

@ -29,3 +29,5 @@ singe/thirdparty/SDL2_image/external/libpng-1.6.37/autom4te.cache/
singe/thirdparty/SDL2_image/external/libwebp-1.0.3/autom4te.cache/ singe/thirdparty/SDL2_image/external/libwebp-1.0.3/autom4te.cache/
singe/thirdparty/SDL2_image/external/tiff-4.1.0/autom4te.cache/ singe/thirdparty/SDL2_image/external/tiff-4.1.0/autom4te.cache/
thirdparty-build/ thirdparty-build/
singe/extensions.h
videotest/*.singe

View file

@ -20,6 +20,9 @@
*/ */
#include <stdio.h>
#include <getopt.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h> #include <SDL2/SDL_mixer.h>
@ -31,31 +34,372 @@
#include "util.h" #include "util.h"
#include "videoPlayer.h" #include "videoPlayer.h"
#include "singe.h" #include "singe.h"
#include "extensions.h"
// /home/scott/code/singe2/videotest/Stargate.m4v #define VERSION_STRING "v2.00"
#define COPYRIGHT_END_YEAR "2020"
typedef struct RatioS {
int aspectNum;
int aspectDom;
} RatioT;
typedef struct ResolutionS {
int width;
int height;
} ResolutionT;
typedef struct ModeS {
RatioT ratio;
ResolutionT resolution;
} ModeT;
void showUsage(char *name, char *message);
// /home/scott/code/singe2/videotest/Stargate.singe
// /home/scott/code/singe2/videotest/TestClip_720x480_29.97fps_2000_frames.avi // /home/scott/code/singe2/videotest/TestClip_720x480_29.97fps_2000_frames.avi
__attribute__((noreturn))
void showUsage(char *name, char *message) {
utilSay(" ___ ___ _ _ ___ ___");
utilSay("/ __|_ _| \\| |/ __| __| Somewhat Interactive Nostalgic Game Emulator %s", VERSION_STRING);
utilSay("\\__ \\| || .` | (_ | _| Copyright (c) 2006-%s Scott C. Duensing", COPYRIGHT_END_YEAR);
utilSay("|___/___|_|\\_|\\___|___| https://kangaroopunch.com");
utilSay("");
utilSay("Usage: %s [OPTIONS] scriptName{.singe}", utilGetLastPathComponent(name));
utilSay("");
utilSay(" -v, --framefile=FILENAME use an alternate video file");
utilSay(" -d, --datadir=PATHNAME alternate location for written files");
utilSay(" -m, --nomouse disable mouse");
utilSay(" -n, --noserversend do not send usage statistics");
utilSay(" -s, --nosound, --mutesound mutes all sound");
utilSay(" -f, --fullscreen run in full screen mode");
utilSay(" -w, --fullscreen_window run in windowed full screen mode");
utilSay(" -l, --volume_vldp=PERCENT specify laserdisc volume in percent");
utilSay(" -e, --volume_nonvldp=PERCENT specify sound effects volume in percent");
// 00000000011111111112222222222333333333344444444445555555555666666666677777777778
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
utilSay(" -z, --scalefactor=PERCENT reduce screen size for overscan compensation");
utilSay(" -x, --xresolution=VALUE specify horizontal resolution");
utilSay(" -y, --yresolution=VALUE specify vertical resolution");
utilSay(" -h, --help this display");
utilSay("");
if (message) {
utilSay("Error: %s", message);
utilSay("");
exit(1);
}
exit(0);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int x = 0;
int err = 0; int err = 0;
int flags = 0; int flags = 0;
int thisFrame = -1; int thisFrame = -1;
int lastFrame = -1; int lastFrame = -1;
int videoHandle = -1; int videoHandle = -1;
char *filename = argv[1]; int optionIndex = 0;
int bestResIndex = -1;
int bestRatioIndex = -1;
char *temp = NULL;
float thisRatio = 0;
float bestRatio = 9999;
bool running = true; bool running = true;
SDL_Window *window = NULL; SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL; SDL_Renderer *renderer = NULL;
SDL_Texture *texture = NULL; SDL_Texture *texture = NULL;
SDL_DisplayMode mode;
static struct option options[] = {
{ "nomouse", no_argument, NULL, 'm' },
{ "noserversend", no_argument, NULL, 'n' },
{ "nosound", no_argument, NULL, 's' },
{ "mutesound", no_argument, NULL, 's' },
{ "fullscreen", no_argument, NULL, 'f' },
{ "fullscreen_window", no_argument, NULL, 'w' },
{ "datadir", optional_argument, NULL, 'd' },
{ "framefile", optional_argument, NULL, 'v' },
{ "volume_vldp", optional_argument, NULL, 'l' },
{ "volume_nonlvdp", optional_argument, NULL, 'e' },
{ "scalefactor", optional_argument, NULL, 'z' },
{ "xresolution", optional_argument, NULL, 'x' },
{ "yresolution", optional_argument, NULL, 'y' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
static ModeT modes[] = {
{ { 4, 3 }, { 640, 480 } },
{ { 4, 3 }, { 800, 600 } },
{ { 4, 3 }, { 960, 720 } },
{ { 4, 3 }, { 1024, 768 } },
{ { 4, 3 }, { 1280, 960 } },
{ { 4, 3 }, { 1400, 1050 } },
{ { 4, 3 }, { 1440, 1080 } },
{ { 4, 3 }, { 1600, 1200 } },
{ { 4, 3 }, { 1856, 1392 } },
{ { 4, 3 }, { 1920, 1440 } },
{ { 4, 3 }, { 2048, 1536 } },
{ { 16, 9 }, { 1024, 576 } },
{ { 16, 9 }, { 1152, 648 } },
{ { 16, 9 }, { 1280, 720 } },
{ { 16, 9 }, { 1366, 768 } },
{ { 16, 9 }, { 1600, 900 } },
{ { 16, 9 }, { 1920, 1080 } },
{ { 16, 9 }, { 2560, 1440 } },
{ { 16, 9 }, { 3840, 2160 } },
{ { 16, 9 }, { 7680, 4320 } },
{ { 16, 10 }, { 1280, 800 } },
{ { 16, 10 }, { 1440, 900 } },
{ { 16, 10 }, { 1680, 1050 } },
{ { 16, 10 }, { 1920, 1200 } },
{ { 16, 10 }, { 2560, 1600 } },
{ { 0, 0 }, { 0, 0 } }
};
// Did we get a filename to open? // Parse command line
if (argc != 2) utilDie("Usage: %s <filename>\n", argv[0]); while (true) {
optionIndex = 0;
opterr = 0;
x = getopt_long(argc, argv, "mnsfwhd:v:l:e:z:x:y:", options, &optionIndex);
// Out of options?
if (x == -1) break;
// Handle options
switch (x) {
// No Mouse
case 'm':
_confNoMouse = true;
break;
// No Server Statss
case 'n':
_confNoStats = true;
break;
// No Sound
case 's':
_confNoSound = true;
break;
// Full Screen
case 'f':
_confFullScreen = true;
break;
// Full Screen Windowed
case 'w':
_confFullScreenWindow = true;
break;
// Video File
case 'v':
if (_confVideoFile) free(_confVideoFile);
_confVideoFile = strdup(optarg);
break;
// Data Dir
case 'd':
if (_confDataDir) free(_confDataDir);
_confDataDir = strdup(optarg);
break;
// Video Volume
case 'l':
_confVolumeVldp = atoi(optarg);
break;
// Effects Volume
case 'e':
_confVolumeNonVldp = atoi(optarg);
break;
// Zoom
case 'z':
_confScaleFactor = atoi(optarg);
break;
// X Resolution
case 'x':
_confXResolution = atoi(optarg);
break;
// Y Resolution
case 'y':
_confYResolution = atoi(optarg);
break;
// Help
case 'h':
showUsage(argv[0], NULL);
break;
case '?':
showUsage(argv[0], "Unknown option.");
break;
default:
abort(); // Something bad happened
break;
}
}
// Did we get a filename or path to open?
if (optind != (argc - 1)) showUsage(argv[0], "No script file specified.");
_confScriptFile = strdup(argv[optind]);
// Exists?
if (!utilFileExists(_confScriptFile)) {
// Missing. Is a path?
if (utilPathExists(_confScriptFile)) {
// See if the script exists in the path.
temp = utilCreateString("%s%c%s.singe", _confScriptFile, utilGetPathSeparator(), utilGetLastPathComponent(_confScriptFile));
if (utilFileExists(temp)) {
// Found script named for path inside path.
free(_confScriptFile);
_confScriptFile = temp;
temp = NULL;
} else {
// Not in the path either.
free(_confScriptFile);
_confScriptFile = NULL;
}
} else {
// Not a path either.
free(_confScriptFile);
_confScriptFile = NULL;
}
}
if (!_confScriptFile) showUsage(argv[0], "Unable to locate script.");
// Do we need to generate a video name?
if (_confVideoFile) {
if (!utilFileExists(_confVideoFile)) {
free(_confVideoFile);
_confVideoFile = NULL;
}
} else {
x = (int)(strlen(_confScriptFile) - strlen(utilGetFileExtension(_confScriptFile))) - 1;
if (x < 0) {
x = 0;
}
temp = strdup(_confScriptFile);
temp[x] = 0;
// Check all known extensions - lower case only, Windows users!
x = 0;
while (ffmpegExtensions[x]) {
_confVideoFile = utilCreateString("%s.%s", temp, ffmpegExtensions[x]);
if (utilFileExists(_confVideoFile)) {
break;
}
free(_confVideoFile);
_confVideoFile = NULL;
x++;
}
free(temp);
}
if (!_confVideoFile) showUsage(argv[0], "Unable to locate video.");
// Do we need to generate a data directory name?
if (_confDataDir) {
if (!utilPathExists(_confDataDir)) {
free(_confDataDir);
_confDataDir = NULL;
}
} else {
// Put it in the game folder.
x = (int)(strlen(_confScriptFile) - strlen(utilGetLastPathComponent(_confScriptFile))) - 1;
if (x < 0) {
x = 0;
}
_confDataDir = strdup(_confScriptFile);
_confDataDir[x] = 0;
}
if (!_confDataDir) showUsage(argv[0], "Unable to locate data directory.");
// Do the full screen options make sense?
if (_confFullScreen && _confFullScreenWindow) showUsage(argv[0], "Full Screen or Full Screen Windowed. Pick one.");
// Sane volume values?
if ((_confVolumeVldp < 0) || (_confVolumeVldp > 100)) showUsage(argv[0], "Laserdisc volume must be between 0 and 100 percent.");
if ((_confVolumeNonVldp < 0) || (_confVolumeNonVldp > 100)) showUsage(argv[0], "Effects volume must be between 0 and 100 percent.");
// Sane scale factor?
if ((_confScaleFactor < 50) || (_confScaleFactor > 100)) showUsage(argv[0], "Display scale must be between 50 and 100 percent.");
// Init SDL // Init SDL
err = SDL_Init(SDL_INIT_EVERYTHING); if (SDL_Init(SDL_INIT_EVERYTHING) != 0) utilDie("%s", SDL_GetError());
if (err != 0) utilDie("%s", SDL_GetError()); if (SDL_GetCurrentDisplayMode(0, &mode) < 0) utilDie("%s", SDL_GetError());
// Determine resolution if not specified
if ((_confXResolution <= 0) || (_confYResolution <= 0)) {
// Find our current aspect ratio
x = 0;
while (modes[x].ratio.aspectNum != 0) {
thisRatio = fabsf(((float)modes[x].ratio.aspectNum / (float)modes[x].ratio.aspectDom) - ((float)mode.w / (float)mode.h));
if (thisRatio < bestRatio) {
bestRatio = thisRatio;
bestRatioIndex = x;
}
x++;
}
x = 0;
// Were both resolutions not specified?
if ((_confXResolution <= 0) && (_confYResolution <= 0)) {
// Are we full screen?
if (_confFullScreen || _confFullScreenWindow) {
// Use desktop resolution
_confXResolution = mode.w;
_confYResolution = mode.h;
} else {
// Find largest window that will fit on the screen but not fill it
while (modes[x].ratio.aspectNum != 0) {
if ((modes[x].ratio.aspectNum == modes[bestRatioIndex].ratio.aspectNum) && (modes[x].ratio.aspectDom == modes[bestRatioIndex].ratio.aspectDom)) {
if ((modes[x].resolution.width < mode.w) && (modes[x].resolution.height < mode.h)) {
bestResIndex = x;
}
}
x++;
}
_confXResolution = modes[bestResIndex].resolution.width;
_confYResolution = modes[bestResIndex].resolution.height;
}
} else {
// Find unprovided width/height using provided value
while (modes[x].ratio.aspectNum != 0) {
// Is this the aspect ratio we're using?
if ((modes[bestRatioIndex].ratio.aspectNum == modes[x].ratio.aspectNum) && (modes[bestRatioIndex].ratio.aspectDom == modes[x].ratio.aspectDom)) {
// Do we have the width or height?
if (_confXResolution > 0) {
// We have the width. Is this the matching entry?
if (modes[x].resolution.width == _confXResolution) {
bestResIndex = x;
_confYResolution = modes[x].resolution.height;
break;
}
} else {
// We have the height. Is this the matching entry?
if (modes[x].resolution.height == _confYResolution) {
bestResIndex = x;
_confXResolution = modes[x].resolution.width;
break;
}
}
}
x++;
}
}
}
// Did we end up with a valid resolution?
if (_confXResolution <= 0) showUsage(argv[0], "Unable to determine X resolution. (Is the Y value sane?)");
if (_confYResolution <= 0) showUsage(argv[0], "Unable to determine Y resolution. (Is the X value sane?)");
if ((_confXResolution > mode.w) || (_confYResolution > mode.h)) showUsage(argv[0], "Specified resolution is larger than the display.");
// Init SDL_mixer ***FIX*** // Init SDL_mixer ***FIX***
flags = /* MIX_INIT_FLAC | */ MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG | MIX_INIT_MID | MIX_INIT_OPUS; flags = /* MIX_INIT_FLAC | */ MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG | MIX_INIT_MID | MIX_INIT_OPUS;
@ -71,9 +415,15 @@ int main(int argc, char *argv[]) {
if (TTF_Init() < 0) utilDie("%s", TTF_GetError()); if (TTF_Init() < 0) utilDie("%s", TTF_GetError());
// Create Resizable Window // Create Resizable Window
window = SDL_CreateWindow(filename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE); window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _confXResolution, _confYResolution, SDL_WINDOW_RESIZABLE);
if (window == NULL) utilDie("%s", SDL_GetError()); if (window == NULL) utilDie("%s", SDL_GetError());
// Do we want full screen of some kind?
if (_confFullScreen || _confFullScreenWindow) {
flags = _confFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
SDL_SetWindowFullscreen(window, (Uint32)flags);
}
// Create an accelerated renderer. // Create an accelerated renderer.
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) utilDie("%s", SDL_GetError()); if (renderer == NULL) utilDie("%s", SDL_GetError());
@ -86,10 +436,13 @@ int main(int argc, char *argv[]) {
err = Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 44100 /* freq */ * 16 /* bits */ * 2 /* channels */ * 2 /* seconds */); err = Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 44100 /* freq */ * 16 /* bits */ * 2 /* channels */ * 2 /* seconds */);
if (err != 0) utilDie("%s", Mix_GetError()); if (err != 0) utilDie("%s", Mix_GetError());
// Finish our setup
SDL_DisableScreenSaver();
if (videoInit()) utilDie("Unable to initialize video player."); if (videoInit()) utilDie("Unable to initialize video player.");
videoHandle = videoLoad(filename, renderer); videoHandle = videoLoad(_confVideoFile, _confDataDir, renderer);
if (videoHandle < 0) utilDie("Unable to load video file: %s", filename); if (videoHandle < 0) utilDie("Unable to load video file: %s", _confVideoFile);
videoPlay(videoHandle); videoPlay(videoHandle);
@ -148,10 +501,14 @@ int main(int argc, char *argv[]) {
Mix_CloseAudio(); Mix_CloseAudio();
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_EnableScreenSaver();
TTF_Quit(); TTF_Quit();
IMG_Quit(); IMG_Quit();
Mix_Quit(); Mix_Quit();
SDL_Quit(); SDL_Quit();
if (_confDataDir) free(_confDataDir);
if (_confVideoFile) free(_confVideoFile);
if (_confScriptFile) free(_confScriptFile);
return 0; return 0;
} }

View file

@ -73,6 +73,76 @@ function autoBuild() {
} }
function createExtensionHeader() {
local FFMPEG=$1
local a=
local c=0
outputLicense
printf "\n\n#ifndef FFMPEG_EXTENSIONS_H\n#define FFMPEG_EXTENSIONS_H\n\n\n"
printf "// ===== THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT =====\n\n\n"
printf "#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-variable\"\n"
printf "static char *ffmpegExtensions[] = {\n"
printf "\t"
getExtensions "${FFMPEG}" | sort | uniq -u | while read a; do
printf "\"${a}\", "
c=$((c+1))
if [[ ${c} -ge 10 ]]; then
printf "\n\t"
c=0
fi
done
printf "0\n};\n#pragma GCC diagnostic pop\n\n\n#endif // FFMPEG_EXTENSIONS_H\n"
}
function getExtensions() {
local FFMPEG=$1
local a=
local b=
local c=
local d=
local e=
local f=
local g=
"${FFMPEG}" -demuxers 2> /dev/null | while read a b c; do
if [[ "${a}x" == "Dx" ]]; then
"${FFMPEG}" -h demuxer=${b} 2> /dev/null | grep "Common extensions" | while read d e f; do
g=${f/./}
echo -e "${g//,/\\n}"
done
fi
done
}
function outputLicense() {
cat <<-LICENSE
/*
*
* Singe 2
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
LICENSE
}
# === zlib === # === zlib ===
if [[ ! -e "${G_INSTALLED}/lib/libz.a" ]]; then if [[ ! -e "${G_INSTALLED}/lib/libz.a" ]]; then
echo ${G_L} echo ${G_L}
@ -164,7 +234,10 @@ DEPS_CFLAGS="-I${G_INSTALLED}/include -I${G_INSTALLED}/include/opus" \
autoBuild libopusfile.a SDL2_mixer/external/opusfile-0.11 --disable-http autoBuild libopusfile.a SDL2_mixer/external/opusfile-0.11 --disable-http
# === FFMPEG === # === FFMPEG ===
autoBuild libavcodec.a ffmpeg "--disable-debug --disable-muxers --disable-encoders --disable-filters --disable-hwaccels --disable-network --disable-devices --disable-programs --enable-gpl" autoBuild libavcodec.a ffmpeg "--disable-debug --disable-muxers --disable-encoders --disable-filters --disable-hwaccels --disable-network --disable-devices --enable-gpl"
if [[ ! -e extensions.h ]]; then
createExtensionHeader "${G_DEST}/installed/bin/ffmpeg" > extensions.h
fi
# === FFMS2 === # === FFMS2 ===
FFMPEG_LIBS="-L${G_INSTALLED}/lib -l:libavformat.a -l:libavcodec.a -l:libswscale.a -l:libavutil.a -l:libswresample.a -l:libz.a -l:liblzma.a -l:libbz2.a -lpthread -lXv -lX11 -lXext -lm" \ FFMPEG_LIBS="-L${G_INSTALLED}/lib -l:libavformat.a -l:libavcodec.a -l:libswscale.a -l:libavutil.a -l:libswresample.a -l:libz.a -l:liblzma.a -l:libbz2.a -lpthread -lXv -lX11 -lXext -lm" \

View file

@ -23,3 +23,25 @@
#include <lua.h> #include <lua.h>
#include <lualib.h> #include <lualib.h>
#include <lauxlib.h> #include <lauxlib.h>
#include "thirdparty/uthash.h"
#include "common.h"
#include "util.h"
#include "singe.h"
// Command line options
char *_confVideoFile = NULL;
char *_confScriptFile = NULL;
char *_confDataDir = NULL;
int _confNoMouse = false;
int _confNoStats = false;
int _confNoSound = false;
int _confFullScreen = false;
int _confFullScreenWindow = false;
int _confVolumeVldp = 100;
int _confVolumeNonVldp = 100;
int _confScaleFactor = 100;
int _confXResolution = -1;
int _confYResolution = -1;

View file

@ -23,4 +23,21 @@
#ifndef SINGE_H #ifndef SINGE_H
#define SINGE_H #define SINGE_H
// Command line options
extern char *_confVideoFile;
extern char *_confScriptFile;
extern char *_confDataDir;
extern int _confNoMouse;
extern int _confNoStats;
extern int _confNoSound;
extern int _confFullScreen;
extern int _confFullScreenWindow;
extern int _confVolumeVldp;
extern int _confVolumeNonVldp;
extern int _confScaleFactor;
extern int _confXResolution;
extern int _confYResolution;
#endif // SINGE_H #endif // SINGE_H

View file

@ -101,7 +101,8 @@ HEADERS += \
common.h \ common.h \
util.h \ util.h \
videoPlayer.h \ videoPlayer.h \
singe.h singe.h \
extensions.h
SOURCES += \ SOURCES += \
$$MANYMOUSE_SOURCES \ $$MANYMOUSE_SOURCES \

View file

@ -22,12 +22,34 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include "common.h"
#include "util.h" #include "util.h"
__attribute__((__format__(__printf__, 1, 0)))
char *utilCreateString(char *format, ...) {
va_list args;
va_list argsCopy;
int size = 0;
char *buffer = NULL;
va_start(args, format);
va_copy(argsCopy, args);
size = vsnprintf(NULL, 0, format, argsCopy) + 1;
va_end(argsCopy);
buffer = calloc(1, (size_t)size);
if (buffer) {
vsnprintf(buffer, (size_t)size, format, args);
}
va_end(args);
return buffer;
}
__attribute__((__format__(__printf__, 1, 0))) __attribute__((__format__(__printf__, 1, 0)))
__attribute__((noreturn)) __attribute__((noreturn))
void utilDie(char *fmt, ...) { void utilDie(char *fmt, ...) {
@ -41,6 +63,69 @@ void utilDie(char *fmt, ...) {
} }
bool utilFileExists(char *filename) {
FILE *file;
if ((file = fopen(filename, "r+"))) {
fclose(file);
return true;
}
return false;
}
char *utilGetFileExtension(char *filename) {
char *start = filename + strlen(filename);
int x;
// Scan through name and find the last '.'
for (x=0; x<(int)strlen(filename); x++) {
if (filename[x] == '.') {
start = &filename[x + 1];
}
// Reset if we find a path separator
if (filename[x] == utilGetPathSeparator()) {
start = filename + strlen(filename);
}
}
return start;
}
char *utilGetLastPathComponent(char *pathname) {
char *start = pathname;
int x;
// Scan through name and find the last path separator
for (x=0; x<(int)strlen(pathname); x++) {
if (pathname[x] == utilGetPathSeparator()) {
start = &pathname[x + 1];
}
}
return start;
}
char utilGetPathSeparator(void) {
#ifdef _WIN32
return '\\';
#else
return '/';
#endif
}
bool utilPathExists(char *pathname) {
DIR *dir = opendir(pathname);
if (dir) {
closedir(dir);
return true;
}
return false;
}
__attribute__((__format__(__printf__, 1, 0))) __attribute__((__format__(__printf__, 1, 0)))
void utilSay(char *fmt, ...) { void utilSay(char *fmt, ...) {
va_list args; va_list args;

View file

@ -23,7 +23,18 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
#include "common.h"
char *utilCreateString(char *format, ...);
void utilDie(char *fmt, ...); void utilDie(char *fmt, ...);
bool utilFileExists(char *filename);
char *utilGetFileExtension(char *filename);
char *utilGetLastPathComponent(char *pathname);
char utilGetPathSeparator(void);
bool utilPathExists(char *pathname);
void utilSay(char *fmt, ...); void utilSay(char *fmt, ...);
#endif // UTIL_H #endif // UTIL_H

View file

@ -154,7 +154,7 @@ int videoIsPlaying(int playerIndex) {
} }
int videoLoad(char *filename, SDL_Renderer *renderer) { int videoLoad(char *filename, char *indexPath, SDL_Renderer *renderer) {
char indexName[1024]; char indexName[1024];
int pixelFormats[2]; int pixelFormats[2];
int result = -1; int result = -1;
@ -177,7 +177,7 @@ int videoLoad(char *filename, SDL_Renderer *renderer) {
v->errInfo.SubType = FFMS_ERROR_SUCCESS; v->errInfo.SubType = FFMS_ERROR_SUCCESS;
// Index file // Index file
snprintf(indexName, 1024, "%s.index", filename); snprintf(indexName, 1024, "%s%c%s.index", indexPath, utilGetPathSeparator(), utilGetLastPathComponent(filename));
index = FFMS_ReadIndex(indexName, &v->errInfo); index = FFMS_ReadIndex(indexName, &v->errInfo);
if (index) { if (index) {
if (FFMS_IndexBelongsToFile(index, filename, &v->errInfo)) { if (FFMS_IndexBelongsToFile(index, filename, &v->errInfo)) {

View file

@ -29,7 +29,7 @@
int videoInit(void); int videoInit(void);
int videoIsPlaying(int playerIndex); int videoIsPlaying(int playerIndex);
int videoLoad(char *filename, SDL_Renderer *renderer); int videoLoad(char *filename, char *indexPath, SDL_Renderer *renderer);
int videoPause(int playerIndex); int videoPause(int playerIndex);
int videoPlay(int playerIndex); int videoPlay(int playerIndex);
int videoQuit(void); int videoQuit(void);