#include "image.h"
-/* ------------------------------------------------------------------------- */
+/* ========================================================================= */
/* some generic helper functions */
+/* ========================================================================= */
+
+/* ------------------------------------------------------------------------- */
+/* platform independent wrappers for printf() et al. (newline aware) */
/* ------------------------------------------------------------------------- */
-void fprintf_line(FILE *stream, char *line_string, int line_length)
+static void vfprintf_newline(FILE *stream, char *format, va_list ap)
+{
+ char *newline = STRING_NEWLINE;
+
+ vfprintf(stream, format, ap);
+
+ fprintf(stream, "%s", newline);
+}
+
+static void fprintf_newline(FILE *stream, char *format, ...)
+{
+ if (format)
+ {
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf_newline(stream, format, ap);
+ va_end(ap);
+ }
+}
+
+void fprintf_line(FILE *stream, char *line_chars, int line_length)
{
int i;
for (i = 0; i < line_length; i++)
- fprintf(stream, "%s", line_string);
+ fprintf(stream, "%s", line_chars);
- fprintf(stream, "\n");
+ fprintf_newline(stream, "");
}
-void printf_line(char *line_string, int line_length)
+void printf_line(char *line_chars, int line_length)
{
- fprintf_line(stdout, line_string, line_length);
+ fprintf_line(stdout, line_chars, line_length);
}
-void printf_line_with_prefix(char *prefix, char *line_string, int line_length)
+void printf_line_with_prefix(char *prefix, char *line_chars, int line_length)
{
fprintf(stdout, "%s", prefix);
- fprintf_line(stdout, line_string, line_length);
+ fprintf_line(stdout, line_chars, line_length);
}
+/* ------------------------------------------------------------------------- */
+/* string functions */
+/* ------------------------------------------------------------------------- */
+
/* int2str() returns a number converted to a string;
the used memory is static, but will be overwritten by later calls,
so if you want to save the result, copy it to a private string buffer;
return real_name;
}
-char *getHomeDir()
-{
- static char *dir = NULL;
-
-#if defined(PLATFORM_WIN32)
- if (dir == NULL)
- {
- dir = checked_malloc(MAX_PATH + 1);
-
- if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir)))
- strcpy(dir, ".");
- }
-#elif defined(PLATFORM_UNIX)
- if (dir == NULL)
- {
- if ((dir = getenv("HOME")) == NULL)
- {
- struct passwd *pwd;
-
- if ((pwd = getpwuid(getuid())) != NULL)
- dir = getStringCopy(pwd->pw_dir);
- else
- dir = ".";
- }
- }
-#else
- dir = ".";
-#endif
-
- return dir;
-}
-
/* ------------------------------------------------------------------------- */
/* path manipulation functions */
static char *getLastPathSeparatorPtr(char *filename)
{
- char *last_separator = strrchr(filename, '/');
+ char *last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_UNIX);
-#if !defined(PLATFORM_UNIX)
if (last_separator == NULL) /* also try DOS/Windows variant */
- last_separator = strrchr(filename, '\\');
-#endif
+ last_separator = strrchr(filename, CHAR_PATH_SEPARATOR_DOS);
return last_separator;
}
-static char *getBaseNamePtr(char *filename)
+char *getBaseNamePtr(char *filename)
{
char *last_separator = getLastPathSeparatorPtr(filename);
char *getPath2(char *path1, char *path2)
{
+ char *sep = STRING_PATH_SEPARATOR;
char *complete_path = checked_malloc(strlen(path1) + 1 +
strlen(path2) + 1);
- sprintf(complete_path, "%s/%s", path1, path2);
+ sprintf(complete_path, "%s%s%s", path1, sep, path2);
return complete_path;
}
char *getPath3(char *path1, char *path2, char *path3)
{
+ char *sep = STRING_PATH_SEPARATOR;
char *complete_path = checked_malloc(strlen(path1) + 1 +
strlen(path2) + 1 +
strlen(path3) + 1);
- sprintf(complete_path, "%s/%s/%s", path1, path2, path3);
+ sprintf(complete_path, "%s%s%s%s%s", path1, sep, path2, sep, path3);
return complete_path;
}
return internal_error;
}
+#if 1
+
+void Error(int mode, char *format, ...)
+{
+ static boolean last_line_was_separator = FALSE;
+ char *process_name = "";
+
+ /* display warnings only when running in verbose mode */
+ if (mode & ERR_WARN && !options.verbose)
+ return;
+
+ if (mode == ERR_RETURN_LINE)
+ {
+ if (!last_line_was_separator)
+ fprintf_line(program.error_file, format, 79);
+
+ last_line_was_separator = TRUE;
+
+ return;
+ }
+
+ last_line_was_separator = FALSE;
+
+ if (mode & ERR_SOUND_SERVER)
+ process_name = " sound server";
+ else if (mode & ERR_NETWORK_SERVER)
+ process_name = " network server";
+ else if (mode & ERR_NETWORK_CLIENT)
+ process_name = " network client **";
+
+ if (format)
+ {
+ va_list ap;
+
+ fprintf(program.error_file, "%s%s: ", program.command_basename,
+ process_name);
+
+ if (mode & ERR_WARN)
+ fprintf(program.error_file, "warning: ");
+
+ va_start(ap, format);
+ vfprintf_newline(program.error_file, format, ap);
+ va_end(ap);
+ }
+
+ if (mode & ERR_HELP)
+ fprintf_newline(program.error_file,
+ "%s: Try option '--help' for more information.",
+ program.command_basename);
+
+ if (mode & ERR_EXIT)
+ fprintf_newline(program.error_file, "%s%s: aborting",
+ program.command_basename, process_name);
+
+ if (mode & ERR_EXIT)
+ {
+ if (mode & ERR_FROM_SERVER)
+ exit(1); /* child process: normal exit */
+ else
+ program.exit_function(1); /* main process: clean up stuff */
+ }
+}
+
+#else
+
void Error(int mode, char *format, ...)
{
static boolean last_line_was_separator = FALSE;
last_line_was_separator = FALSE;
-#if defined(PLATFORM_MSDOS)
+#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
newline = "\r\n";
if ((error = openErrorFile()) == NULL)
{
printf("Cannot write to error output file!%s", newline);
+
program.exit_function(1);
}
#endif
}
}
+#endif
+
/* ------------------------------------------------------------------------- */
/* checked memory allocation and freeing functions */
return (feof(file) || ferror(file) ? FALSE : TRUE);
}
-void putFileChunk(FILE *file, char *chunk_name, int chunk_size,
- int byte_order)
+int putFileChunk(FILE *file, char *chunk_name, int chunk_size,
+ int byte_order)
{
+ int num_bytes = 0;
+
/* write chunk name */
- fputs(chunk_name, file);
+ if (file != NULL)
+ fputs(chunk_name, file);
+
+ num_bytes += strlen(chunk_name);
if (chunk_size >= 0)
{
/* write chunk size */
- putFile32BitInteger(file, chunk_size, byte_order);
+ if (file != NULL)
+ putFile32BitInteger(file, chunk_size, byte_order);
+
+ num_bytes += 4;
}
+
+ return num_bytes;
}
int getFileVersion(FILE *file)
version_build);
}
-void putFileVersion(FILE *file, int version)
+int putFileVersion(FILE *file, int version)
{
- int version_major = VERSION_MAJOR(version);
- int version_minor = VERSION_MINOR(version);
- int version_patch = VERSION_PATCH(version);
- int version_build = VERSION_BUILD(version);
+ if (file != NULL)
+ {
+ int version_major = VERSION_MAJOR(version);
+ int version_minor = VERSION_MINOR(version);
+ int version_patch = VERSION_PATCH(version);
+ int version_build = VERSION_BUILD(version);
+
+ fputc(version_major, file);
+ fputc(version_minor, file);
+ fputc(version_patch, file);
+ fputc(version_build, file);
+ }
- fputc(version_major, file);
- fputc(version_minor, file);
- fputc(version_patch, file);
- fputc(version_build, file);
+ return 4;
}
void ReadBytesFromFile(FILE *file, byte *buffer, unsigned long bytes)
string_has_parameter(value, "random") ? ANIM_RANDOM :
string_has_parameter(value, "ce_value") ? ANIM_CE_VALUE :
string_has_parameter(value, "ce_score") ? ANIM_CE_SCORE :
+ string_has_parameter(value, "ce_delay") ? ANIM_CE_DELAY :
string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL :
string_has_parameter(value, "vertical") ? ANIM_VERTICAL :
ANIM_DEFAULT);
return get_parameter_value(value_raw, suffix, TYPE_INTEGER);
}
+struct ScreenModeInfo *get_screen_mode_from_string(char *screen_mode_string)
+{
+ static struct ScreenModeInfo screen_mode;
+ char *screen_mode_string_x = strchr(screen_mode_string, 'x');
+ char *screen_mode_string_copy;
+ char *screen_mode_string_pos_w;
+ char *screen_mode_string_pos_h;
+
+ if (screen_mode_string_x == NULL) /* invalid screen mode format */
+ return NULL;
+
+ screen_mode_string_copy = getStringCopy(screen_mode_string);
+
+ screen_mode_string_pos_w = screen_mode_string_copy;
+ screen_mode_string_pos_h = strchr(screen_mode_string_copy, 'x');
+ *screen_mode_string_pos_h++ = '\0';
+
+ screen_mode.width = atoi(screen_mode_string_pos_w);
+ screen_mode.height = atoi(screen_mode_string_pos_h);
+
+ return &screen_mode;
+}
+
+void get_aspect_ratio_from_screen_mode(struct ScreenModeInfo *screen_mode,
+ int *x, int *y)
+{
+ float aspect_ratio = (float)screen_mode->width / (float)screen_mode->height;
+ float aspect_ratio_new;
+ int i = 1;
+
+ do
+ {
+ *x = i * aspect_ratio + 0.000001;
+ *y = i;
+
+ aspect_ratio_new = (float)*x / (float)*y;
+
+ i++;
+ }
+ while (aspect_ratio_new != aspect_ratio && *y < screen_mode->height);
+}
+
static void FreeCustomArtworkList(struct ArtworkListInfo *,
struct ListNodeInfo ***, int *);
if (filename == NULL)
return;
+#if 0
+ printf("LoadArtworkConfigFromFilename '%s' ...\n", filename);
+#endif
+
if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
return;
char *filename_base = UNDEFINED_FILENAME, *filename_local;
int i, j;
-#if 0
- printf("GOT CUSTOM ARTWORK CONFIG FILE '%s'\n", filename);
-#endif
-
DrawInitText("Loading artwork config:", 120, FC_GREEN);
DrawInitText(ARTWORKINFO_FILENAME(artwork_info->type), 150, FC_YELLOW);
/* ------------------------------------------------------------------------- */
/* functions only needed for non-Unix (non-command-line) systems */
/* (MS-DOS only; SDL/Windows creates files "stdout.txt" and "stderr.txt") */
+/* (now also added for Windows, to create files in user data directory) */
/* ------------------------------------------------------------------------- */
-#if defined(PLATFORM_MSDOS)
-
-#define ERROR_FILENAME "stderr.txt"
+char *getErrorFilename(char *basename)
+{
+ return getPath2(getUserGameDataDir(), basename);
+}
-void initErrorFile()
+void openErrorFile()
{
- unlink(ERROR_FILENAME);
+ /* always start with reliable default values */
+ program.error_file = stderr;
+
+#if defined(PLATFORM_WIN32) || defined(PLATFORM_MSDOS)
+ if ((program.error_file = fopen(program.error_filename, MODE_WRITE)) == NULL)
+ fprintf_newline(stderr, "ERROR: cannot open file '%s' for writing!",
+ program.error_filename);
+#endif
}
-FILE *openErrorFile()
+void closeErrorFile()
{
- return fopen(ERROR_FILENAME, MODE_APPEND);
+ if (program.error_file != stderr) /* do not close stream 'stderr' */
+ fclose(program.error_file);
}
void dumpErrorFile()
{
- FILE *error_file = fopen(ERROR_FILENAME, MODE_READ);
+ FILE *error_file = fopen(program.error_filename, MODE_READ);
if (error_file != NULL)
{
fclose(error_file);
}
}
+
+void NotifyUserAboutErrorFile()
+{
+#if defined(PLATFORM_WIN32)
+ char *title_text = getStringCat2(program.program_title, " Error Message");
+ char *error_text = getStringCat2("The program was aborted due to an error; "
+ "for details, see the following error file:"
+ STRING_NEWLINE, program.error_filename);
+
+ MessageBox(NULL, error_text, title_text, MB_OK);
#endif
+}
/* ------------------------------------------------------------------------- */