Temporary files and save game data are now placed in seperate dirs.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@433 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
meep-eep
2002-12-18 04:30:50 +00:00
parent 173a9a9403
commit 1c2f030f2d
23 changed files with 703 additions and 83 deletions
+11
View File
@@ -88,6 +88,17 @@ The bugs reported but not yet verified:
together with the ships in the player's fleet, the modules that are drawn together with the ships in the player's fleet, the modules that are drawn
inside the flagship are off by one pixel to the left. inside the flagship are off by one pixel to the left.
- First, I had saved my game while at the planet/scan menu (I do not know
which planet or moon I was on). I loaded it the next day and tried to get
minerals while avoiding various hazards. I managed to get the minerals, but
was hit heavily by the hazards. The moment I pressed Escape, I noticed I
had THIRTEEN empty crew slot circles for the Lander at the time (as opposed
to twelve like it should have) - an extra empty circle appeared to the left
of the bottom row of crew circles. My Lander was not destroyed, and the
minerals I had gathered were still intact and added to my cargo total.
Moreover, the crew of the Vindicator was refilled to my maximum of 50 -- I
had 40 when I saved and loaded at the beginning of this point. "
- < badalex> ok, im in hyper space right? and lets say one of those - < badalex> ok, im in hyper space right? and lets say one of those
probes comes to me... so we start the melee and i select a probes comes to me... so we start the melee and i select a
ship, that all works, but after a select a ship the select a ship, that all works, but after a select a ship the select a
+1
View File
@@ -1,4 +1,5 @@
0.2: 0.2:
- Put save data and temporary files in a seperate dir - SvdB
- Fix OpenGL colors on big-endian CPUs, from Bryce McKinlay - Fix OpenGL colors on big-endian CPUs, from Bryce McKinlay
- MikMod now loops modules correctly (OpenAL), from Nic - MikMod now loops modules correctly (OpenAL), from Nic
- player.fon/42.png corrected, from Parker - player.fon/42.png corrected, from Parker
+2
View File
@@ -88,6 +88,8 @@ Glitches (don't crash the game, medium priority):
when compared to 3DO when compared to 3DO
- When there are more than one page of saved supermelee teams, the last - When there are more than one page of saved supermelee teams, the last
entries will be wrong. entries will be wrong.
- Temp files don't get deleted if the game is exited in full game mode.
(and the temp dir doesn't get deleted if it's not empty)
Implementation bugs (low priority): Implementation bugs (low priority):
- Scaling code problems: - Scaling code problems:
+29
View File
@@ -1,6 +1,33 @@
/* This file contains some compile-time configuration options for *nix
* systems.
* src/config.h is generated from src/config.h.in by build.sh
* For windows, you'll have to edit src/msvc++/config.h manually
* if you want anything else than the defaults.
*/
#ifdef WIN32
/* If we're compiling in windows, we want the other config.h */
# include "msvc++/config.h"
#endif
#ifndef _CONFIG_H
#define _CONFIG_H
/* Directory where the UQM game data is located */ /* Directory where the UQM game data is located */
#define CONTENTDIR "@CONTENTDIR@" #define CONTENTDIR "@CONTENTDIR@"
/* Directory where game data will be stored */
#define USERDIR "~/.uqm/"
/* Directory where supermelee teams will be stored */
#define MELEEDIR USERDIR "teams/"
/* Directory where save games will be stored */
#define SAVEDIR USERDIR "save/"
/* Directory where config files will be stored */
#define CONFIGDIR USERDIR
/* Defined if words are stored with the most significant byte first */ /* Defined if words are stored with the most significant byte first */
@WORDS_BIGENDIAN@ @WORDS_BIGENDIAN@
@@ -13,3 +40,5 @@
/* Defined if your system has getopt.h */ /* Defined if your system has getopt.h */
@HAVE_GETOPT_H@ @HAVE_GETOPT_H@
#endif /* _CONFIG_H */
+22 -2
View File
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_CONFIG_H" /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /FR /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_CONFIG_H" /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "SOUNDMODULE_OPENAL" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -128,6 +128,22 @@ SOURCE=..\sc2code\libs\decomp\lzh.h
SOURCE=..\sc2code\libs\decomp\update.c SOURCE=..\sc2code\libs\decomp\update.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "file"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\sc2code\libs\file\dirs.c
# End Source File
# Begin Source File
SOURCE=..\sc2code\libs\file\filintrn.h
# End Source File
# Begin Source File
SOURCE=..\sc2code\libs\file\temp.c
# End Source File
# End Group
# Begin Group "graphics" # Begin Group "graphics"
# PROP Default_Filter "" # PROP Default_Filter ""
@@ -682,6 +698,10 @@ SOURCE=..\sc2code\libs\declib.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\sc2code\libs\file.h
# End Source File
# Begin Source File
SOURCE=..\sc2code\libs\gfxlib.h SOURCE=..\sc2code\libs\gfxlib.h
# End Source File # End Source File
# Begin Source File # Begin Source File
+39
View File
@@ -0,0 +1,39 @@
/* This file contains some compile-time configuration options for MS Windows
* systems.
* Change the values below if you want anything other than the defaults.
* For *nix systems, src/config.h is used, which is generated by
* build.sh from src/config.h.in.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
/* Directory where the UQM game data is located */
#define CONTENTDIR "../content"
/* Directory where game data will be stored */
#define USERDIR "../userdata"
/* Directory where supermelee teams will be stored */
#define MELEEDIR USERDIR "teams/"
/* Directory where save games will be stored */
#define SAVEDIR USERDIR "save/"
/* Directory where config files will be stored */
#define CONFIGDIR USERDIR
/* Define if words are stored with the most significant byte first */
#undef WORDS_BIGENDIAN
/* Defined if your system has strupr of its own */
#define HAVE_STRUPR
/* Defined if your system has stricmp of its own */
#define HAVE_STRICMP
/* Defined if your system has getopt.h */
#undef HAVE_GETOPT_H
#endif /* _CONFIG_H */
+54 -1
View File
@@ -20,14 +20,18 @@
* By Mika Kolehmainen. * By Mika Kolehmainen.
*/ */
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "compiler.h" #include "compiler.h"
#include "options.h" #include "options.h"
#include "file.h"
int optWhichMusic = MUSIC_3DO; int optWhichMusic = MUSIC_3DO;
char *configDir, *saveDir, *meleeDir;
BOOLEAN optSubtitles = TRUE; BOOLEAN optSubtitles = TRUE;
BOOLEAN FileExists (char *filename) BOOLEAN FileExists (const char *filename)
{ {
FILE *fp; FILE *fp;
if ((fp = fopen (filename, "rb")) == NULL) if ((fp = fopen (filename, "rb")) == NULL)
@@ -36,3 +40,52 @@ BOOLEAN FileExists (char *filename)
fclose (fp); fclose (fp);
return TRUE; return TRUE;
} }
void
prepareConfigDir (void) {
configDir = malloc (PATH_MAX - 13);
if (expandPath (configDir, PATH_MAX - 13, CONFIGDIR) == -1)
{
// Doesn't have to be fatal, but might mess up things when saving
// config files.
fprintf (stderr, "Fatal error: Invalid path to config files.\n");
exit (EXIT_FAILURE);
}
configDir = realloc (configDir, strlen (configDir) + 1);
// Create the path upto the config dir, if not already existing.
mkdirhier (configDir);
}
void
prepareSaveDir (void) {
saveDir = malloc (PATH_MAX - 13);
if (expandPath (saveDir, PATH_MAX - 13, SAVEDIR) == -1)
{
// Doesn't have to be fatal, but might mess up things when saving
// config files.
fprintf (stderr, "Fatal error: Invalid path to config files.\n");
exit (EXIT_FAILURE);
}
saveDir = realloc (saveDir, strlen (saveDir) + 1);
// Create the path upto the save dir, if not already existing.
mkdirhier (saveDir);
}
void
prepareMeleeDir (void) {
meleeDir = malloc (PATH_MAX - 13);
if (expandPath (meleeDir, PATH_MAX - 13, MELEEDIR) == -1)
{
// Doesn't have to be fatal, but might mess up things when saving
// config files.
fprintf (stderr, "Fatal error: Invalid path to config files.\n");
exit (EXIT_FAILURE);
}
meleeDir = realloc (meleeDir, strlen (meleeDir) + 1);
// Create the path upto the save dir, if not already existing.
mkdirhier (meleeDir);
}
+10 -1
View File
@@ -35,6 +35,15 @@ extern int optWhichMusic;
extern BOOLEAN optSubtitles; extern BOOLEAN optSubtitles;
BOOLEAN FileExists (char *filename); BOOLEAN FileExists (const char *filename);
extern char *configDir;
extern char *meleeDir;
extern char *saveDir;
void prepareConfigDir(void);
void prepareMeleeDir(void);
void prepareSaveDir(void);
#endif #endif
+9 -2
View File
@@ -1,6 +1,11 @@
#ifndef _PORT_H
#define _PORT_H
#include "config.h"
#ifdef WIN32 #ifdef WIN32
#define HAVE_STRICMP #define alloca _alloca
#define HAVE_STRUPR #define snprintf _snprintf
#endif #endif
#ifndef HAVE_STRICMP #ifndef HAVE_STRICMP
@@ -11,3 +16,5 @@
char *strupr (char *str); char *strupr (char *str);
#endif #endif
#endif /* _PORT_H */
+2 -2
View File
@@ -7,6 +7,6 @@ uqm_CFILES="battle.c border.c build.c cleanup.c clock.c collide.c comm.c
master.c melee.c misc.c oscill.c outfit.c pickmele.c master.c melee.c misc.c oscill.c outfit.c pickmele.c
pickship.c plandata.c process.c restart.c save.c settings.c pickship.c plandata.c process.c restart.c save.c settings.c
setup.c ship.c shipstat.c shipyard.c sis.c starbase.c setup.c ship.c shipstat.c shipyard.c sis.c starbase.c
starcon.c starmap.c state.c status.c tactrans.c trans.c starcon.c starmap.c state.c status.c tactrans.c
utils.c velocity.c weapon.c" trans.c utils.c velocity.c weapon.c"
+13 -13
View File
@@ -20,6 +20,7 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#include "file.h"
//#define DEBUG //#define DEBUG
@@ -35,7 +36,7 @@ InitGroupInfo (BOOLEAN FirstTime)
{ {
PVOID fp; PVOID fp;
fp = OpenResFile (RANDGRPINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (RANDGRPINFO_FILE), "wb");
if (fp) if (fp)
{ {
GROUP_HEADER GH; GROUP_HEADER GH;
@@ -48,7 +49,8 @@ InitGroupInfo (BOOLEAN FirstTime)
CloseResFile (fp); CloseResFile (fp);
} }
if (FirstTime && (fp = OpenResFile (DEFGRPINFO_FILE, "wb"))) if (FirstTime && (fp = OpenResFile (tempFilePath (DEFGRPINFO_FILE),
"wb")))
{ {
PutResFileChar (0, fp); PutResFileChar (0, fp);
@@ -59,8 +61,8 @@ InitGroupInfo (BOOLEAN FirstTime)
void void
UninitGroupInfo (void) UninitGroupInfo (void)
{ {
unlink (DEFGRPINFO_FILE); unlink (tempFilePath (DEFGRPINFO_FILE));
unlink (RANDGRPINFO_FILE); unlink (tempFilePath (RANDGRPINFO_FILE));
} }
void void
@@ -347,10 +349,9 @@ GetGroupInfo (DWORD offset, BYTE which_group)
{ {
PVOID fp; PVOID fp;
fp = OpenResFile ( fp = OpenResFile (tempFilePath (
offset && which_group ? DEFGRPINFO_FILE : RANDGRPINFO_FILE, offset && which_group ? DEFGRPINFO_FILE : RANDGRPINFO_FILE),
"r+b" "r+b");
);
if (fp) if (fp)
{ {
BYTE RaceType, NumShips; BYTE RaceType, NumShips;
@@ -386,7 +387,7 @@ GetGroupInfo (DWORD offset, BYTE which_group)
fprintf (stderr, "GetGroupInfo: battle groups out of date %u/%u/%u!\n", fprintf (stderr, "GetGroupInfo: battle groups out of date %u/%u/%u!\n",
month_index, day_index, year_index); month_index, day_index, year_index);
#endif /* DEBUG */ #endif /* DEBUG */
fp = OpenResFile (RANDGRPINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (RANDGRPINFO_FILE), "wb");
GH.NumGroups = 0; GH.NumGroups = 0;
GH.star_index = (COUNT)~0; GH.star_index = (COUNT)~0;
GH.GroupOffset[0] = 0; GH.GroupOffset[0] = 0;
@@ -615,10 +616,9 @@ PutGroupInfo (DWORD offset, BYTE which_group)
{ {
PVOID fp; PVOID fp;
fp = OpenResFile ( fp = OpenResFile (tempFilePath (
offset && which_group ? DEFGRPINFO_FILE : RANDGRPINFO_FILE, offset && which_group ? DEFGRPINFO_FILE : RANDGRPINFO_FILE),
"r+b" "r+b");
);
if (fp) if (fp)
{ {
GROUP_HEADER GH; GROUP_HEADER GH;
+2 -2
View File
@@ -1,2 +1,2 @@
uqm_SUBDIRS="decomp graphics input math memory resource sound strings task uqm_SUBDIRS="decomp file graphics input math memory resource sound strings
threads time video" task threads time video"
+50
View File
@@ -0,0 +1,50 @@
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Contains file handling code
#ifndef _FILE_H
/* Make sure we have PATH_MAX */
#ifdef WIN32
# include <stdlib.h>
# define PATH_MAX _MAX_PATH
#else
/* PATH_MAX is per POSIX defined in <limits.h> */
# include <limits.h>
#endif
#ifdef WIN32
# include <direct.h>
# define access _access
# define F_OK 0
# define W_OK 2
# define R_OK 4
# define mkdir _mkdir
# define rmdir _rmdir
#else
# include <unistd.h>
#endif
void initTempDir (void);
void unInitTempDir (void);
char *tempFilePath (const char *filename);
int mkdirhier (const char *path);
const char *getHomeDir (void);
int createDirectory(const char *dir, int mode);
int expandPath(char *dest, size_t len, const char *src);
#endif /* _FILE_H */
+1
View File
@@ -0,0 +1 @@
uqm_CFILES="dirs.c temp.c"
+199
View File
@@ -0,0 +1,199 @@
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Contains code handling directories
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#include <direct.h>
#endif
#include "port.h"
#include "config.h"
#include "filintrn.h"
int
createDirectory(const char *dir, int mode) {
#ifdef WIN32
return mkdir (dir);
#else
return mkdir (dir, (mode_t) mode);
#endif
}
// make all components of the path if they don't exist already
// returns 0 on success, -1 on failure.
// on failure, some parts may still have been created.
int
mkdirhier (const char *path) {
char *buf; // buffer
char *ptr; // end of the string in buf
const char *pathstart; // start of a component of path
const char *pathend; // first char past the end of a component of path
size_t len;
struct stat statbuf;
len = strlen (path);
buf = alloca (len + 2); // one extra for possibly added '/'
ptr = buf;
pathstart = path;
if (*pathstart == '/') {
*ptr = '/';
ptr++;
pathstart++;
}
if (*pathstart == '\0') {
// path exists completely, nothing more to do
return 0;
}
// walk through the path as long as the components exist
while (1) {
pathend = strchr (pathstart, '/');
if (pathend == NULL)
pathend = path + len;
memcpy(ptr, pathstart, pathend - pathstart);
ptr += pathend - pathstart;
*ptr = '\0';
if (stat (buf, &statbuf) == -1) {
if (errno != ENOENT) {
fprintf (stderr, "Can't stat %s: %s\n", buf,
strerror (errno));
return -1;
}
break;
}
if (*pathend == '\0')
return 0;
*ptr = '/';
ptr++;
pathstart = pathend + 1;
while (*pathstart == '/')
pathstart++;
// pathstart is the next non-slash character
if (*pathstart == '\0')
return 0;
}
// create all components left
while (1) {
if (createDirectory (buf, 0777) == -1) {
fprintf (stderr, "Error: Can't create %s: %s\n", buf,
strerror (errno));
return -1;
}
if (*pathend == '\0')
break;
*ptr = '/';
ptr++;
pathstart = pathend + 1;
while (*pathstart == '/')
pathstart++;
// pathstart is the next non-slash character
if (*pathstart == '\0')
break;
pathend = strchr (pathstart, '/');
if (pathend == NULL)
pathend = path + len;
memcpy (ptr, pathstart, pathend - pathstart);
ptr += pathend - pathstart;
*ptr = '\0';
}
return 0;
}
// Get the user's home dir
// returns a pointer to a static buffer
const char *
getHomeDir(void) {
return getenv ("HOME");
}
int
expandPath(char *dest, size_t len, const char *src) {
size_t srclen;
srclen = strlen (src);
if (src[0] == '~')
{
const char *home;
size_t homelen;
if (src[1] != '/')
{
errno = EINVAL;
return -1;
}
home = getHomeDir ();
if (home == NULL)
{
errno = ENOENT;
return -1;
}
homelen = strlen (home);
if (homelen + srclen > len)
{
errno = ENAMETOOLONG;
return -1;
}
memcpy(dest, home, homelen);
dest += homelen;
src++; /* skip the ~ */
} else {
if (strlen (src) >= len)
{
errno = ENAMETOOLONG;
return -1;
}
}
#ifdef WIN32
/* Replaces backslashes in path by slashes. */
while (*src != '\0')
{
if (*src == '\\')
{
*(dest++) = '/';
src++;
}
else
*(dest++) = *(src++);
}
*dest = '\0';
#else
strcpy(dest, src);
#endif
return 0;
}
+27
View File
@@ -0,0 +1,27 @@
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Contains code handling temporary files and dirs
#ifndef _FILEINTRN_H
#include "../file.h"
void CreateDirectory (const char *dir, int mode);
void RemoveTempDir (void);
#endif /* _FILEINTRN_H */
+145
View File
@@ -0,0 +1,145 @@
/*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Contains code handling temporary files and dirs
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#ifdef WIN32
# include <io.h>
#endif
#include <string.h>
#include <time.h>
#include "filintrn.h"
#include "timelib.h"
#include "port.h"
#include "libs/compiler.h"
static char *tempDir;
static void
removeTempDir (void)
{
rmdir (tempDir);
}
// Try if the null-terminated path 'dir' to a directory is valid
// as temp path.
// On success, 'buf' will be filled with the path, with a trailing /,
// null-terminated, and 0 is returned.
// On failure, EINVAL, ENAMETOOLONG, or one of the errors access() can return
// is returned, and the contents of buf is unspecified.
static int
tryTempDir (char *buf, size_t buflen, const char *dir)
{
size_t len;
int haveSlash;
if (dir == NULL)
return EINVAL;
len = strlen (dir);
haveSlash = (dir[len - 1] == '/'
#ifdef WIN32
|| dir[len - 1] == '\\'
#endif
);
if ((haveSlash ? len : len + 1) >= buflen)
return ENAMETOOLONG;
strcpy (buf, dir);
if (!haveSlash)
{
buf[len] = '/';
len++;
buf[len] = '\0';
}
if (access (buf, R_OK | W_OK) == -1)
return errno;
return 0;
}
static void
getTempDir (char *buf, size_t buflen) {
if (tryTempDir (buf, buflen, getenv("TMP")) &&
tryTempDir (buf, buflen, getenv("TEMP")) &&
tryTempDir (buf, buflen, "/tmp/") &&
tryTempDir (buf, buflen, "./"))
{
fprintf (stderr, "Fatal Error: Cannot find a suitable location "
"to store temporary files.\n");
exit(EXIT_FAILURE);
}
}
#define NUM_TEMP_RETRIES 16
// Number of files to try to open before giving up.
void
initTempDir (void) {
size_t len;
DWORD num;
int i;
char *tempPtr;
// Pointer to the location in the tempDir string where the
// path to the temp dir ends and the dir starts.
tempDir = malloc (PATH_MAX);
getTempDir (tempDir, PATH_MAX - 21);
// reserve 8 chars for dirname, 1 for slash, and 12 for filename
len = strlen(tempDir);
num = ((DWORD) time (NULL));
// num = GetTimeCounter () % 0xffffffff;
tempPtr = tempDir + len;
i = NUM_TEMP_RETRIES;
while (i--)
{
sprintf (tempPtr, "%08lx", num + i);
if (createDirectory (tempDir, 0700) == -1)
continue;
// Success, we've got a temp dir.
tempDir = realloc (tempDir, len + 9);
atexit (removeTempDir);
return;
}
// Failure, could not make a temporary directory.
fprintf(stderr, "Fatal error: Cannot get a name for a temporary "
"directory.\n");
exit(EXIT_FAILURE);
}
void
unInitTempDir (void) {
// nothing at the moment.
// the removing of the dir is handled via atexit
}
// return the path to a file in the temp dir with the specified filename.
// returns a pointer to a static buffer.
char *
tempFilePath (const char *filename) {
static char file[PATH_MAX];
if (snprintf(file, PATH_MAX, "%s/%s", tempDir, filename) == -1) {
fprintf(stderr, "Path to temp file too long.\n");
exit(EXIT_FAILURE);
}
return file;
}
+2 -2
View File
@@ -145,7 +145,7 @@ LoadDirEntryTable (PSTR pattern, PCOUNT pnum_entries)
#include <unistd.h> #include <unistd.h>
#include <fnmatch.h> #include <fnmatch.h>
#include <ctype.h> #include <ctype.h>
#include <sys/param.h> #include <limits.h>
DIRENTRY_REF DIRENTRY_REF
LoadDirEntryTable (PSTR pattern, PCOUNT pnum_entries) LoadDirEntryTable (PSTR pattern, PCOUNT pnum_entries)
@@ -155,7 +155,7 @@ LoadDirEntryTable (PSTR pattern, PCOUNT pnum_entries)
STRING_TABLEPTR lpST; STRING_TABLEPTR lpST;
PDWORD lpLastOffs; PDWORD lpLastOffs;
PSTR slash; // Pointer inside pattern to the last / PSTR slash; // Pointer inside pattern to the last /
SBYTE path[MAXPATHLEN + 1]; // buffer for a filename with path SBYTE path[PATH_MAX]; // buffer for a filename with path
PSTR file; // Pointer inside path to the filename PSTR file; // Pointer inside path to the filename
size_t pathlen; // length of path, excluding last / and filename size_t pathlen; // length of path, excluding last / and filename
+8 -6
View File
@@ -19,6 +19,8 @@
#include "starcon.h" #include "starcon.h"
#include "declib.h" #include "declib.h"
#include "libs/tasklib.h" #include "libs/tasklib.h"
#include "options.h"
#include "file.h"
ACTIVITY NextActivity; ACTIVITY NextActivity;
@@ -85,10 +87,10 @@ BOOLEAN
LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc) LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc)
{ {
FILE *in_fp; FILE *in_fp;
char buf[256]; char buf[256], file[PATH_MAX];
sprintf (buf, "starcon2.%02u", which_game); sprintf (file, "%sstarcon2.%02u", saveDir, which_game);
in_fp = OpenResFile (buf, "rb"); in_fp = OpenResFile (file, "rb");
if (in_fp) if (in_fp)
{ {
FILE *fp; FILE *fp;
@@ -221,7 +223,7 @@ LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc)
} }
} }
fp = OpenResFile (STARINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (STARINFO_FILE), "wb");
if (fp) if (fp)
{ {
DWORD flen; DWORD flen;
@@ -240,7 +242,7 @@ LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc)
CloseResFile (fp); CloseResFile (fp);
} }
fp = OpenResFile (DEFGRPINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (DEFGRPINFO_FILE), "wb");
if (fp) if (fp)
{ {
DWORD flen; DWORD flen;
@@ -259,7 +261,7 @@ LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc)
CloseResFile (fp); CloseResFile (fp);
} }
fp = OpenResFile (RANDGRPINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (RANDGRPINFO_FILE), "wb");
if (fp) if (fp)
{ {
DWORD flen; DWORD flen;
+19 -7
View File
@@ -19,6 +19,8 @@
#include <ctype.h> #include <ctype.h>
#include "starcon.h" #include "starcon.h"
#include "melee.h" #include "melee.h"
#include "options.h"
#include "file.h"
//Added by Chris //Added by Chris
@@ -1014,11 +1016,18 @@ static void
LoadTeamList (PMELEE_STATE pMS, UNICODE *pbuf) LoadTeamList (PMELEE_STATE pMS, UNICODE *pbuf)
{ {
COUNT num_entries; COUNT num_entries;
char dir[PATH_MAX];
char file[PATH_MAX];
char *loc_buf;
sprintf (dir, "%s*.mle", meleeDir);
strcpy (file, meleeDir);
loc_buf = file + strlen (file);
GetNewList: GetNewList:
DestroyDirEntryTable (ReleaseDirEntryTable (pMS->TeamDE)); DestroyDirEntryTable (ReleaseDirEntryTable (pMS->TeamDE));
pMS->TeamDE = CaptureDirEntryTable ( pMS->TeamDE = CaptureDirEntryTable (
LoadDirEntryTable ("*.mle", &num_entries) LoadDirEntryTable (dir, &num_entries)
); );
pMS->CurIndex = 0; pMS->CurIndex = 0;
@@ -1027,10 +1036,9 @@ GetNewList:
int status; int status;
FILE *load_fp; FILE *load_fp;
TEAM_IMAGE TI; TEAM_IMAGE TI;
UNICODE loc_buf[60];
GetDirEntryContents (pMS->TeamDE, (STRINGPTR)loc_buf, FALSE); GetDirEntryContents (pMS->TeamDE, (STRINGPTR)loc_buf, FALSE);
if ((load_fp = OpenResFile (loc_buf, "rb")) == 0) if ((load_fp = OpenResFile (file, "rb")) == 0)
status = -1; status = -1;
else else
{ {
@@ -1042,7 +1050,7 @@ GetNewList:
} }
if (status == -1) if (status == -1)
{ {
DeleteResFile (loc_buf); DeleteResFile (file);
goto GetNewList; goto GetNewList;
} }
@@ -1060,15 +1068,19 @@ static BOOLEAN
DoSaveTeam (PMELEE_STATE pMS) DoSaveTeam (PMELEE_STATE pMS)
{ {
STAMP MsgStamp; STAMP MsgStamp;
UNICODE buf[60]; char buf[PATH_MAX];
char *file;
FILE *save_fp; FILE *save_fp;
CONTEXT OldContext; CONTEXT OldContext;
strcpy(buf, meleeDir);
file = buf + strlen (buf);
sprintf (file, "%s.mle", pMS->TeamImage[pMS->side].TeamName);
RetrySave: RetrySave:
SetSemaphore (GraphicsSem); SetSemaphore (GraphicsSem);
OldContext = SetContext (ScreenContext); OldContext = SetContext (ScreenContext);
ConfirmSaveLoad (&MsgStamp); ConfirmSaveLoad (&MsgStamp);
wsprintf (buf, "%s.mle", pMS->TeamImage[pMS->side].TeamName);
save_fp = OpenResFile (buf, "wb"); save_fp = OpenResFile (buf, "wb");
if (save_fp) if (save_fp)
{ {
@@ -1094,7 +1106,7 @@ RetrySave:
goto RetrySave; goto RetrySave;
} }
LoadTeamList (pMS, buf); LoadTeamList (pMS, file);
if (save_fp) if (save_fp)
{ {
+11 -8
View File
@@ -18,11 +18,14 @@
#include "starcon.h" #include "starcon.h"
#include "declib.h" #include "declib.h"
#include "file.h"
#include "options.h"
void FreeSC2Data (void); void FreeSC2Data (void);
BOOLEAN LoadSC2Data (void); BOOLEAN LoadSC2Data (void);
static void static void
SaveShipQueue (DECODE_REF fh, PQUEUE pQueue) SaveShipQueue (DECODE_REF fh, PQUEUE pQueue)
{ {
@@ -306,7 +309,7 @@ RetrySave:
FRAME frame; FRAME frame;
POINT pt; POINT pt;
STAR_DESC SD; STAR_DESC SD;
char buf[256]; char buf[256], file[PATH_MAX];
extern void SaveFlagshipState (void); extern void SaveFlagshipState (void);
success = TRUE; success = TRUE;
@@ -378,7 +381,7 @@ RetrySave:
} }
} }
fp = OpenResFile (STARINFO_FILE, "rb"); fp = OpenResFile (tempFilePath (STARINFO_FILE), "rb");
if (fp) if (fp)
{ {
flen = LengthResFile (fp); flen = LengthResFile (fp);
@@ -396,7 +399,7 @@ RetrySave:
CloseResFile (fp); CloseResFile (fp);
} }
fp = OpenResFile (DEFGRPINFO_FILE, "rb"); fp = OpenResFile (tempFilePath (DEFGRPINFO_FILE), "rb");
if (fp) if (fp)
{ {
flen = LengthResFile (fp); flen = LengthResFile (fp);
@@ -414,7 +417,7 @@ RetrySave:
CloseResFile (fp); CloseResFile (fp);
} }
fp = OpenResFile (RANDGRPINFO_FILE, "rb"); fp = OpenResFile (tempFilePath (RANDGRPINFO_FILE), "rb");
if (fp) if (fp)
{ {
flen = LengthResFile (fp); flen = LengthResFile (fp);
@@ -436,9 +439,9 @@ RetrySave:
flen = cclose (fh); flen = cclose (fh);
sprintf (buf, "starcon2.%02u", which_game); sprintf (file, "%sstarcon2.%02u", saveDir, which_game);
// fprintf (stderr, "'%s' is %lu bytes long\n", buf, flen + sizeof (*summary_desc)); // fprintf (stderr, "'%s' is %lu bytes long\n", file, flen + sizeof (*summary_desc));
if (flen && (out_fp = (PVOID)OpenResFile (buf, "wb"))) if (flen && (out_fp = (PVOID)OpenResFile (file, "wb")))
{ {
PrepareSummary (summary_desc); PrepareSummary (summary_desc);
@@ -457,7 +460,7 @@ RetrySave:
success = FALSE; success = FALSE;
if (!success) if (!success)
DeleteResFile (buf); DeleteResFile (file);
} }
mem_unlock (h); mem_unlock (h);
+5 -4
View File
@@ -20,13 +20,14 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#include "file.h"
void void
InitPlanetInfo (void) InitPlanetInfo (void)
{ {
PVOID fp; PVOID fp;
fp = OpenResFile (STARINFO_FILE, "wb"); fp = OpenResFile (tempFilePath (STARINFO_FILE), "wb");
if (fp) if (fp)
{ {
DWORD offset; DWORD offset;
@@ -48,7 +49,7 @@ InitPlanetInfo (void)
void void
UninitPlanetInfo (void) UninitPlanetInfo (void)
{ {
unlink (STARINFO_FILE); unlink (tempFilePath (STARINFO_FILE));
} }
void void
@@ -59,7 +60,7 @@ GetPlanetInfo (void)
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[BIOLOGICAL_SCAN] = pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[BIOLOGICAL_SCAN] =
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[MINERAL_SCAN] = pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[MINERAL_SCAN] =
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN] = 0; pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN] = 0;
fp = OpenResFile (STARINFO_FILE, "rb"); fp = OpenResFile (tempFilePath (STARINFO_FILE), "rb");
if (fp) if (fp)
{ {
COUNT star_index, planet_index, moon_index; COUNT star_index, planet_index, moon_index;
@@ -106,7 +107,7 @@ PutPlanetInfo (void)
{ {
PVOID fp; PVOID fp;
fp = OpenResFile (STARINFO_FILE, "r+b"); fp = OpenResFile (tempFilePath (STARINFO_FILE), "r+b");
if (fp) if (fp)
{ {
COUNT i; COUNT i;
+25 -16
View File
@@ -16,12 +16,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#ifndef WIN32 #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#include "config.h" #endif
#else #ifdef WIN32
# include <direct.h> # include <direct.h>
#endif #endif
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_GETOPT_H #ifdef HAVE_GETOPT_H
#include <getopt.h> #include <getopt.h>
@@ -33,16 +36,19 @@
#include "libs/sound/sound_common.h" #include "libs/sound/sound_common.h"
#include "libs/input/input_common.h" #include "libs/input/input_common.h"
#include "libs/tasklib.h" #include "libs/tasklib.h"
#include "file.h"
#include "port.h"
#include "options.h" #include "options.h"
#if defined(GFXMODULE_SDL) || defined(SOUNDMODULE_SDL) #if defined(GFXMODULE_SDL) || defined(SOUNDMODULE_SDL)
# include <SDL.h> # include <SDL.h>
// Including this is actually necessary on OSX. // Including this is actually necessary on OSX.
#endif #endif
void static void
CDToContentDir (char *contentdir) CDToContentDir (char *contentdir)
{ {
char *testfile = "starcon.txt"; const char *testfile = "starcon.txt";
if (!FileExists (testfile)) if (!FileExists (testfile))
{ {
@@ -50,7 +56,7 @@ CDToContentDir (char *contentdir)
(chdir ("content") || !FileExists (testfile)) && (chdir ("content") || !FileExists (testfile)) &&
(chdir ("../../content") || !FileExists (testfile))) { (chdir ("../../content") || !FileExists (testfile))) {
fprintf(stderr, "Fatal error: content not available, running from wrong dir?\n"); fprintf(stderr, "Fatal error: content not available, running from wrong dir?\n");
exit(-1); exit(EXIT_FAILURE);
} }
} }
} }
@@ -64,7 +70,6 @@ main (int argc, char *argv[])
int width = 640, height = 480, bpp = 16; int width = 640, height = 480, bpp = 16;
int vol; int vol;
char contentdir[1000]; char contentdir[1000];
char str[1000];
int option_index = 0, c; int option_index = 0, c;
static struct option long_options[] = static struct option long_options[] =
@@ -114,16 +119,15 @@ main (int argc, char *argv[])
gfxdriver = TFB_GFXDRIVER_SDL_OPENGL; gfxdriver = TFB_GFXDRIVER_SDL_OPENGL;
break; break;
case 'c': case 'c':
sscanf(optarg, "%s", str); if (!strcmp (optarg, "bilinear"))
if (!strcmp (str, "bilinear"))
{ {
gfxflags |= TFB_GFXFLAGS_SCALE_BILINEAR; gfxflags |= TFB_GFXFLAGS_SCALE_BILINEAR;
} }
else if (!strcmp (str, "sai")) else if (!strcmp (optarg, "sai"))
{ {
gfxflags |= TFB_GFXFLAGS_SCALE_SAI; gfxflags |= TFB_GFXFLAGS_SCALE_SAI;
} }
else if (!strcmp (str, "supersai")) else if (!strcmp (optarg, "supersai"))
{ {
gfxflags |= TFB_GFXFLAGS_SCALE_SUPERSAI; gfxflags |= TFB_GFXFLAGS_SCALE_SUPERSAI;
} }
@@ -168,18 +172,17 @@ main (int argc, char *argv[])
optWhichMusic = MUSIC_PC; optWhichMusic = MUSIC_PC;
break; break;
case 'q': case 'q':
sscanf(optarg, "%s", str); if (!strcmp (optarg, "high"))
if (!strcmp (str, "high"))
{ {
soundflags &= ~(TFB_SOUNDFLAGS_MQAUDIO|TFB_SOUNDFLAGS_LQAUDIO); soundflags &= ~(TFB_SOUNDFLAGS_MQAUDIO|TFB_SOUNDFLAGS_LQAUDIO);
soundflags |= TFB_SOUNDFLAGS_HQAUDIO; soundflags |= TFB_SOUNDFLAGS_HQAUDIO;
} }
else if (!strcmp (str, "medium")) else if (!strcmp (optarg, "medium"))
{ {
soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_LQAUDIO); soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_LQAUDIO);
soundflags |= TFB_SOUNDFLAGS_MQAUDIO; soundflags |= TFB_SOUNDFLAGS_MQAUDIO;
} }
else if (!strcmp (str, "low")) else if (!strcmp (optarg, "low"))
{ {
soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_MQAUDIO); soundflags &= ~(TFB_SOUNDFLAGS_HQAUDIO|TFB_SOUNDFLAGS_MQAUDIO);
soundflags |= TFB_SOUNDFLAGS_LQAUDIO; soundflags |= TFB_SOUNDFLAGS_LQAUDIO;
@@ -213,7 +216,11 @@ main (int argc, char *argv[])
} }
} }
initTempDir();
CDToContentDir (contentdir); CDToContentDir (contentdir);
prepareConfigDir();
prepareMeleeDir();
prepareSaveDir();
InitThreadSystem (); InitThreadSystem ();
InitTimeSystem (); InitTimeSystem ();
@@ -236,5 +243,7 @@ main (int argc, char *argv[])
TFB_FlushGraphics (); TFB_FlushGraphics ();
} }
exit(0); unInitTempDir();
exit(EXIT_SUCCESS);
} }