Reorganized internals to allow executing multiple Singe scripts.

This commit is contained in:
Scott Duensing 2020-03-15 17:47:47 -05:00
parent 9e943584aa
commit a6b6a11846
8 changed files with 751 additions and 725 deletions

View file

@ -101,7 +101,7 @@ int32_t frameFileInit(void) {
}
int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer) {
int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer, bool showCalculated) {
int32_t result = 0;
int32_t count = 0;
int64_t frame = 0;
@ -203,7 +203,7 @@ int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Re
result = _nextId++;
// Show debug output?
if (_confShowCalculated) {
if (showCalculated) {
// 00000000011111111112222222222333333333344444444445555555555666666666677777777778
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
utilSay("Existing Framefile:\n");

View file

@ -31,7 +31,7 @@
int64_t frameFileGetFrame(int32_t frameFileHandle, int32_t videoHandle);
int32_t frameFileInit(void);
int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer);
int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer, bool showCalculated);
int32_t frameFileSeek(int32_t frameFileHandle, int64_t seekFrame, int32_t *videoHandle, int64_t *actualFrame);
int32_t frameFileQuit(void);
int32_t frameFileUnload(int32_t frameFileHandle);

View file

@ -252,25 +252,25 @@ int main(int argc, char *argv[]) {
// Show Calculated Frame File Values
case 'c':
_confShowCalculated = true;
_conf.showCalculated = true;
break;
// Data Dir
case 'd':
if (_confDataDir) free(_confDataDir);
_confDataDir = strdup(arg);
if (_conf.dataDir) free(_conf.dataDir);
_conf.dataDir = strdup(arg);
argCount++;
break;
// Effects Volume
case 'e':
_confVolumeNonVldp = atoi(arg);
_conf.volumeNonVldp = atoi(arg);
argCount++;
break;
// Full Screen
case 'f':
_confFullScreen = true;
_conf.fullScreen = true;
break;
// Sinden Light Gun
@ -287,29 +287,29 @@ int main(int argc, char *argv[]) {
// No Logos
case 'k':
_confNoLogos = true;
_conf.noLogos = true;
break;
// Video Volume
case 'l':
_confVolumeVldp = atoi(arg);
_conf.volumeVldp = atoi(arg);
argCount++;
break;
// No Mouse
case 'm':
_confNoMouse = true;
_conf.noMouse = true;
break;
// Overscan Zoom
case 'o':
_confScaleFactor = atoi(arg);
_conf.scaleFactor = atoi(arg);
argCount++;
break;
// No Sound
case 's':
_confNoSound = true;
_conf.noSound = true;
break;
// Trace
@ -319,36 +319,36 @@ int main(int argc, char *argv[]) {
// Ugly Stretched Video
case 'u':
_confStretchVideo = true;
_conf.stretchVideo = true;
break;
// Video File
case 'v':
if (_confVideoFile) free(_confVideoFile);
_confVideoFile = strdup(arg);
if (_conf.videoFile) free(_conf.videoFile);
_conf.videoFile = strdup(arg);
argCount++;
break;
// Full Screen Windowed
case 'w':
_confFullScreenWindow = true;
_conf.fullScreenWindow = true;
break;
// X Resolution
case 'x':
_confXResolution = atoi(arg);
_conf.xResolution = atoi(arg);
argCount++;
break;
// Y Resolution
case 'y':
_confYResolution = atoi(arg);
_conf.yResolution = atoi(arg);
argCount++;
break;
// No console output or splash screens
case 'z':
_confNoConsole = true;
_conf.noConsole = true;
break;
default:
@ -358,123 +358,123 @@ int main(int argc, char *argv[]) {
}
// For that dumb OS
if (!_confNoConsole) utilRedirectConsole();
if (!_conf.noConsole) utilRedirectConsole();
// Did we get a filename or path to open?
if ((argc - argCount) != 1) showUsage(exeName, "No script file specified.");
_confScriptFile = strdup(argv[argCount]);
utilFixPathSeparators(&_confScriptFile, false);
_conf.scriptFile = strdup(argv[argCount]);
utilFixPathSeparators(&_conf.scriptFile, false);
// Exists?
if (!utilFileExists(_confScriptFile)) {
if (!utilFileExists(_conf.scriptFile)) {
// Missing. Is a path?
if (utilPathExists(_confScriptFile)) {
if (utilPathExists(_conf.scriptFile)) {
// See if the script exists in the path.
temp = utilCreateString("%s%c%s.singe", _confScriptFile, utilGetPathSeparator(), utilGetLastPathComponent(_confScriptFile));
temp = utilCreateString("%s%c%s.singe", _conf.scriptFile, utilGetPathSeparator(), utilGetLastPathComponent(_conf.scriptFile));
if (utilFileExists(temp)) {
// Found script named for path inside path.
free(_confScriptFile);
_confScriptFile = temp;
free(_conf.scriptFile);
_conf.scriptFile = temp;
temp = NULL;
} else {
// Not in the path either.
free(_confScriptFile);
_confScriptFile = NULL;
free(_conf.scriptFile);
_conf.scriptFile = NULL;
}
} else {
// Not a path either.
free(_confScriptFile);
_confScriptFile = NULL;
free(_conf.scriptFile);
_conf.scriptFile = NULL;
}
}
if (!_confScriptFile) showUsage(exeName, "Unable to locate script.");
if (!_conf.scriptFile) showUsage(exeName, "Unable to locate script.");
// Do we need to generate a video name?
if (_confVideoFile) {
utilFixPathSeparators(&_confVideoFile, false);
if (!utilFileExists(_confVideoFile)) {
free(_confVideoFile);
_confVideoFile = NULL;
if (_conf.videoFile) {
utilFixPathSeparators(&_conf.videoFile, false);
if (!utilFileExists(_conf.videoFile)) {
free(_conf.videoFile);
_conf.videoFile = NULL;
}
} else {
x = (int32_t)(strlen(_confScriptFile) - strlen(utilGetFileExtension(_confScriptFile))) - 1;
x = (int32_t)(strlen(_conf.scriptFile) - strlen(utilGetFileExtension(_conf.scriptFile))) - 1;
if (x < 0) {
x = 0;
}
temp = strdup(_confScriptFile);
temp = strdup(_conf.scriptFile);
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)) {
_conf.videoFile = utilCreateString("%s.%s", temp, ffmpegExtensions[x]);
if (utilFileExists(_conf.videoFile)) {
break;
}
free(_confVideoFile);
_confVideoFile = NULL;
free(_conf.videoFile);
_conf.videoFile = NULL;
x++;
}
free(temp);
// If we still don't have one, try a framefile
if (!_confVideoFile) {
_confVideoFile = utilCreateString("%s.txt", temp);
if (!utilFileExists(_confVideoFile)) {
free(_confVideoFile);
_confVideoFile = NULL;
if (!_conf.videoFile) {
_conf.videoFile = utilCreateString("%s.txt", temp);
if (!utilFileExists(_conf.videoFile)) {
free(_conf.videoFile);
_conf.videoFile = NULL;
}
}
}
if (!_confVideoFile) showUsage(exeName, "Unable to locate video.");
if (!_conf.videoFile) showUsage(exeName, "Unable to locate video.");
// Is it a framefile?
if (strncmp(utilGetFileExtension(_confVideoFile), "txt", 3) == 0) {
_confIsFrameFile = true;
if (strncmp(utilGetFileExtension(_conf.videoFile), "txt", 3) == 0) {
_conf.isFrameFile = true;
}
// Do we need to generate a data directory name?
if (_confDataDir) {
utilFixPathSeparators(&_confDataDir, false);
if (_conf.dataDir) {
utilFixPathSeparators(&_conf.dataDir, false);
// Try to create data directory to ensure it exists.
utilMkDirP(_confDataDir, 0777);
utilMkDirP(_conf.dataDir, 0777);
// Does it exist?
if (!utilPathExists(_confDataDir)) {
free(_confDataDir);
_confDataDir = NULL;
if (!utilPathExists(_conf.dataDir)) {
free(_conf.dataDir);
_conf.dataDir = NULL;
}
} else {
// Put it in the game folder.
x = (int32_t)(strlen(_confScriptFile) - strlen(utilGetLastPathComponent(_confScriptFile))) - 1;
x = (int32_t)(strlen(_conf.scriptFile) - strlen(utilGetLastPathComponent(_conf.scriptFile))) - 1;
if (x < 0) {
x = 0;
}
temp = strdup(_confScriptFile);
temp = strdup(_conf.scriptFile);
temp[x] = 0;
_confDataDir = strdup(temp);
_conf.dataDir = strdup(temp);
free(temp);
temp = NULL;
}
if (!_confDataDir) showUsage(exeName, "Unable to locate data directory.");
utilFixPathSeparators(&_confDataDir, true);
if (!_conf.dataDir) showUsage(exeName, "Unable to locate data directory.");
utilFixPathSeparators(&_conf.dataDir, true);
// Do they want tracing?
if (tracing) {
temp = utilCreateString("%strace.txt", _confDataDir);
temp = utilCreateString("%strace.txt", _conf.dataDir);
utilTraceStart(temp);
free(temp);
temp = NULL;
}
// Do the full screen options make sense?
if (_confFullScreen && _confFullScreenWindow) showUsage(exeName, "Full Screen or Full Screen Windowed. Pick one.");
if (_conf.fullScreen && _conf.fullScreenWindow) showUsage(exeName, "Full Screen or Full Screen Windowed. Pick one.");
// Sane volume values?
if ((_confVolumeVldp < 0) || (_confVolumeVldp > 100)) showUsage(exeName, "Laserdisc volume must be between 0 and 100 percent.");
if ((_confVolumeNonVldp < 0) || (_confVolumeNonVldp > 100)) showUsage(exeName, "Effects volume must be between 0 and 100 percent.");
if ((_conf.volumeVldp < 0) || (_conf.volumeVldp > 100)) showUsage(exeName, "Laserdisc volume must be between 0 and 100 percent.");
if ((_conf.volumeNonVldp < 0) || (_conf.volumeNonVldp > 100)) showUsage(exeName, "Effects volume must be between 0 and 100 percent.");
// Sane scale factor?
if ((_confScaleFactor < 50) || (_confScaleFactor > 100)) showUsage(exeName, "Display scale must be between 50 and 100 percent.");
if ((_conf.scaleFactor < 50) || (_conf.scaleFactor > 100)) showUsage(exeName, "Display scale must be between 50 and 100 percent.");
// Sinden light gun?
if (sindenString) {
if (_confScaleFactor != 100) showUsage(exeName, "Cannot use --sindengun and --scalefactor together.");
if (_conf.scaleFactor != 100) showUsage(exeName, "Cannot use --sindengun and --scalefactor together.");
// Was it wrapped in quotes?
if ((sindenString[0] == '"') || (sindenString[0] == '\'')) {
sindenString[0] = ' ';
@ -487,12 +487,12 @@ int main(int argc, char *argv[]) {
// RW GW BW WW RB GB BB WB - Custom color "white" border and width then custom color "black" border and width
temp = strtok(sindenString, " ");
while (temp != NULL) {
_confSindenArgv[_confSindenArgc++] = atoi(temp);
_conf.sindenArgv[_conf.sindenArgc++] = atoi(temp);
temp = strtok(NULL, " ");
if ((temp != NULL) && (_confSindenArgc > SINDEN_OPTION_COUNT)) showUsage(exeName, "Too many arguments to --sindengun.");
if ((temp != NULL) && (_conf.sindenArgc > SINDEN_OPTION_COUNT)) showUsage(exeName, "Too many arguments to --sindengun.");
}
// Did we get a sane number of arguments?
if ((_confSindenArgc != SINDEN_WHITE) && (_confSindenArgc != SINDEN_WHITE_BLACK) && (_confSindenArgc != SINDEN_CUSTOM_WHITE) && (_confSindenArgc != SINDEN_CUSTOM_WHITE_BLACK) && (_confSindenArgc != SINDEN_CUSTOM_WHITE_CUSTOM_BLACK)) showUsage(exeName, "Bad argument count to --sindengun.");
if ((_conf.sindenArgc != SINDEN_WHITE) && (_conf.sindenArgc != SINDEN_WHITE_BLACK) && (_conf.sindenArgc != SINDEN_CUSTOM_WHITE) && (_conf.sindenArgc != SINDEN_CUSTOM_WHITE_BLACK) && (_conf.sindenArgc != SINDEN_CUSTOM_WHITE_CUSTOM_BLACK)) showUsage(exeName, "Bad argument count to --sindengun.");
free(sindenString);
}
@ -501,7 +501,7 @@ int main(int argc, char *argv[]) {
if (SDL_GetCurrentDisplayMode(0, &mode) < 0) utilDie("%s", SDL_GetError());
// Determine resolution if not specified
if ((_confXResolution <= 0) || (_confYResolution <= 0)) {
if ((_conf.xResolution <= 0) || (_conf.yResolution <= 0)) {
// Did they specify an aspect ratio?
if (aspectString) {
aspectNum = atoi(aspectString);
@ -538,12 +538,12 @@ int main(int argc, char *argv[]) {
if (bestRatioIndex < 0) showUsage(exeName, "Unknown aspect ratio.");
x = 0;
// Were both resolutions not specified?
if ((_confXResolution <= 0) && (_confYResolution <= 0)) {
if ((_conf.xResolution <= 0) && (_conf.yResolution <= 0)) {
// Are we full screen?
if (_confFullScreen || _confFullScreenWindow) {
if (_conf.fullScreen || _conf.fullScreenWindow) {
// Use desktop resolution
_confXResolution = mode.w;
_confYResolution = mode.h;
_conf.xResolution = mode.w;
_conf.yResolution = mode.h;
} else {
// Find largest window that will fit on the screen but not fill it
while (modes[x].ratio.aspectNum != 0) {
@ -554,8 +554,8 @@ int main(int argc, char *argv[]) {
}
x++;
}
_confXResolution = modes[bestResIndex].resolution.width;
_confYResolution = modes[bestResIndex].resolution.height;
_conf.xResolution = modes[bestResIndex].resolution.width;
_conf.yResolution = modes[bestResIndex].resolution.height;
}
} else {
// Find unprovided width/height using provided value
@ -563,18 +563,18 @@ int main(int argc, char *argv[]) {
// 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) {
if (_conf.xResolution > 0) {
// We have the width. Is this the matching entry?
if (modes[x].resolution.width == _confXResolution) {
if (modes[x].resolution.width == _conf.xResolution) {
bestResIndex = x;
_confYResolution = modes[x].resolution.height;
_conf.yResolution = modes[x].resolution.height;
break;
}
} else {
// We have the height. Is this the matching entry?
if (modes[x].resolution.height == _confYResolution) {
if (modes[x].resolution.height == _conf.yResolution) {
bestResIndex = x;
_confXResolution = modes[x].resolution.width;
_conf.xResolution = modes[x].resolution.width;
break;
}
}
@ -584,9 +584,9 @@ int main(int argc, char *argv[]) {
}
}
// Did we end up with a valid resolution?
if (_confXResolution <= 0) showUsage(exeName, "Unable to determine X resolution. (Is the Y value sane?)");
if (_confYResolution <= 0) showUsage(exeName, "Unable to determine Y resolution. (Is the X value sane?)");
if ((_confXResolution > mode.w) || (_confYResolution > mode.h)) showUsage(exeName, "Specified resolution is larger than the display.");
if (_conf.xResolution <= 0) showUsage(exeName, "Unable to determine X resolution. (Is the Y value sane?)");
if (_conf.yResolution <= 0) showUsage(exeName, "Unable to determine Y resolution. (Is the X value sane?)");
if ((_conf.xResolution > mode.w) || (_conf.yResolution > mode.h)) showUsage(exeName, "Specified resolution is larger than the display.");
// Init SDL_mixer ***FIX***
flags = /* MIX_INIT_FLAC | */ MIX_INIT_MOD | /* MIX_INIT_MP3 | */ MIX_INIT_OGG | MIX_INIT_MID | MIX_INIT_OPUS;
@ -602,7 +602,7 @@ int main(int argc, char *argv[]) {
if (TTF_Init() < 0) utilDie("%s", TTF_GetError());
// Create Resizable Window
window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _confXResolution, _confYResolution, SDL_WINDOW_RESIZABLE);
window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _conf.xResolution, _conf.yResolution, SDL_WINDOW_RESIZABLE);
if (window == NULL) utilDie("%s", SDL_GetError());
// Window Icon
@ -613,8 +613,8 @@ int main(int argc, char *argv[]) {
icon = NULL;
// Do we want full screen of some kind?
if (_confFullScreen || _confFullScreenWindow) {
flags = _confFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
if (_conf.fullScreen || _conf.fullScreenWindow) {
flags = _conf.fullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
SDL_SetWindowFullscreen(window, (Uint32)flags);
}
@ -652,14 +652,14 @@ int main(int argc, char *argv[]) {
IMG_Quit();
Mix_Quit();
SDL_Quit();
if (_confDataDir) free(_confDataDir);
if (_confVideoFile) free(_confVideoFile);
if (_confScriptFile) free(_confScriptFile);
if (_conf.dataDir) free(_conf.dataDir);
if (_conf.videoFile) free(_conf.videoFile);
if (_conf.scriptFile) free(_conf.scriptFile);
utilTraceEnd();
ap_free(&parser);
#ifdef _WIN32
if (!_confNoConsole) getchar();
if (!_conf.noConsole) getchar();
#endif
return 0;

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@
// Don't forget to update singe.rc!
#define SINGE_VERSION 2.00
#define VERSION_STRING "v2.00b11"
#define VERSION_STRING "v2.00b12"
#define COPYRIGHT_END_YEAR "2020"
@ -45,26 +45,31 @@ enum {
};
typedef struct ConfigS {
char *videoFile;
char *scriptFile;
char *dataDir;
bool isFrameFile;
bool stretchVideo;
bool noMouse;
bool noSound;
bool fullScreen;
bool fullScreenWindow;
bool showCalculated;
bool noConsole;
bool noLogos;
int32_t volumeVldp;
int32_t volumeNonVldp;
int32_t scaleFactor;
int32_t xResolution;
int32_t yResolution;
int32_t sindenArgc;
int32_t sindenArgv[SINDEN_OPTION_COUNT];
} ConfigT;
// Command line options
extern char *_confVideoFile;
extern char *_confScriptFile;
extern char *_confDataDir;
extern bool _confIsFrameFile;
extern bool _confStretchVideo;
extern bool _confNoMouse;
extern bool _confNoSound;
extern bool _confFullScreen;
extern bool _confFullScreenWindow;
extern bool _confShowCalculated;
extern bool _confNoConsole;
extern bool _confNoLogos;
extern int32_t _confVolumeVldp;
extern int32_t _confVolumeNonVldp;
extern int32_t _confScaleFactor;
extern int32_t _confXResolution;
extern int32_t _confYResolution;
extern int32_t _confSindenArgc;
extern int32_t _confSindenArgv[SINDEN_OPTION_COUNT];
extern ConfigT _conf;
void singe(SDL_Window *window, SDL_Renderer *renderer);

View file

@ -1,7 +1,7 @@
101 ICON "/tmp/icon.ico"
1 VERSIONINFO
FILEVERSION 2,0,0,11
PRODUCTVERSION 2,0,0,11
FILEVERSION 2,0,0,12
PRODUCTVERSION 2,0,0,12
BEGIN
BLOCK "StringFileInfo"
BEGIN
@ -9,12 +9,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Kangaroo Punch Studios"
VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine"
VALUE "FileVersion", "2.00b11"
VALUE "FileVersion", "2.00b12"
VALUE "InternalName", "Singe"
VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing"
VALUE "OriginalFilename", "singe.exe"
VALUE "ProductName", "Singe"
VALUE "ProductVersion", "2.00b11"
VALUE "ProductVersion", "2.00b12"
END
END
BLOCK "VarFileInfo"

View file

@ -42,10 +42,8 @@ static const int CONSOLE_LINES = 1000;
#include "util.h"
extern bool _confNoConsole;
FILE *utilTraceFile = NULL;
static bool _consoleEnabled = true;
static FILE *_utilTraceFile = NULL;
char *utilCreateString(char *format, ...) {
@ -82,7 +80,7 @@ __attribute__((__format__(__printf__, 1, 0)))
__attribute__((noreturn))
void utilDie(char *fmt, ...) {
va_list args;
if (!_confNoConsole) {
if (_consoleEnabled) {
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
@ -96,6 +94,11 @@ void utilDie(char *fmt, ...) {
}
void utilEnableConsole(bool enable) {
_consoleEnabled = enable;
}
bool utilFileExists(char *filename) {
FILE *file;
if ((file = fopen(filename, "r+"))) {
@ -372,7 +375,7 @@ void utilRedirectConsole(void) {
__attribute__((__format__(__printf__, 1, 0)))
void utilSay(char *fmt, ...) {
va_list args;
if (!_confNoConsole) {
if (_consoleEnabled) {
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
@ -404,7 +407,7 @@ char *utilStrndup( const char *s1, size_t n) {
void utilTrace(char *fmt, ...) {
va_list args;
if (utilTraceFile) {
if (_utilTraceFile) {
va_start(args, fmt);
utilTraceVArgs(fmt, args);
va_end(args);
@ -413,21 +416,26 @@ void utilTrace(char *fmt, ...) {
void utilTraceEnd(void) {
if (utilTraceFile) fclose(utilTraceFile);
if (_utilTraceFile) fclose(_utilTraceFile);
}
FILE *utilTraceGetFile(void) {
return _utilTraceFile;
}
void utilTraceStart(char *filename) {
utilTraceFile = fopen(filename, "wt");
if (!utilTraceFile) utilDie("Unable to create trace file: %s", filename);
_utilTraceFile = fopen(filename, "wt");
if (!_utilTraceFile) utilDie("Unable to create trace file: %s", filename);
}
__attribute__((__format__(__printf__, 1, 0)))
void utilTraceVArgs(char *fmt, va_list args) {
if (utilTraceFile) {
vfprintf(utilTraceFile, fmt, args);
fprintf(utilTraceFile, "\n");
fflush(utilTraceFile);
if (_utilTraceFile) {
vfprintf(_utilTraceFile, fmt, args);
fprintf(_utilTraceFile, "\n");
fflush(_utilTraceFile);
}
}

View file

@ -35,12 +35,10 @@
#define UTIL_PATH_MAX 1024
extern FILE *utilTraceFile;
char *utilCreateString(char *format, ...);
char *utilCreateStringVArgs(char *format, va_list args);
void utilDie(char *fmt, ...);
void utilEnableConsole(bool enable);
bool utilFileExists(char *filename);
void utilFixPathSeparators(char **path, bool slash);
char *utilGetFileExtension(char *filename);
@ -56,6 +54,7 @@ int utilStricmp(char *a, char *b);
char *utilStrndup( const char *s1, size_t n);
void utilTrace(char *fmt, ...);
void utilTraceEnd(void);
FILE *utilTraceGetFile(void);
void utilTraceStart(char *filename);
void utilTraceVArgs(char *fmt, va_list args);