Boston, MA 02111-1307, USA
*/
+#ifdef WIN32
+# include <direct.h>
+# include <io.h>
+# include <shlobj.h>
+#endif
+
+// on *x, we MUST include "quakedef.h" before anything that may include IO
+// functions to get _FILE_OFFSET_BITS
#include "quakedef.h"
+#ifdef __APPLE__
+// include SDL for IPHONEOS code
+# include <TargetConditionals.h>
+# if TARGET_OS_IPHONE
+# include <SDL.h>
+# endif
+#endif
+
#include <limits.h>
#include <fcntl.h>
-#ifdef WIN32
-# include <direct.h>
-# include <io.h>
-# include <shlobj.h>
-#else
+#ifndef WIN32
# include <pwd.h>
# include <sys/stat.h>
# include <unistd.h>
#define QFILE_FLAG_DEFLATED (1 << 1)
/// file is actually already loaded data
#define QFILE_FLAG_DATA (1 << 2)
+/// real file will be removed on close
+#define QFILE_FLAG_REMOVE (1 << 3)
#define FILE_BUFF_SIZE 2048
typedef struct
ztoolkit_t* ztk; ///< For zipped files.
const unsigned char *data; ///< For data files.
+
+ const char *filename; ///< Kept around for QFILE_FLAG_REMOVE, unused otherwise
};
flags = PACKFILE_FLAG_DEFLATED;
else
flags = 0;
- offset = BuffLittleLong (&ptr[42]) + eocd->prepended_garbage;
- packsize = BuffLittleLong (&ptr[20]);
- realsize = BuffLittleLong (&ptr[24]);
+ offset = (unsigned int)(BuffLittleLong (&ptr[42]) + eocd->prepended_garbage);
+ packsize = (unsigned int)BuffLittleLong (&ptr[20]);
+ realsize = (unsigned int)BuffLittleLong (&ptr[24]);
switch(ptr[5]) // C_VERSION_MADE_BY_1
{
Create a package entry associated with a PK3 file
====================
*/
-pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle)
+pack_t *FS_LoadPackPK3FromFD (const char *packfile, int packhandle, qboolean silent)
{
pk3_endOfCentralDir_t eocd;
pack_t *pack;
if (! PK3_GetEndOfCentralDir (packfile, packhandle, &eocd))
{
- Con_Printf ("%s is not a PK3 file\n", packfile);
+ if(!silent)
+ Con_Printf ("%s is not a PK3 file\n", packfile);
close(packhandle);
return NULL;
}
#endif
if (packhandle < 0)
return NULL;
- return FS_LoadPackPK3FromFD(packfile, packhandle);
+ return FS_LoadPackPK3FromFD(packfile, packhandle, false);
}
// parse the directory
for (i = 0;i < numpackfiles;i++)
{
- fs_offset_t offset = LittleLong (info[i].filepos);
- fs_offset_t size = LittleLong (info[i].filelen);
+ fs_offset_t offset = (unsigned int)LittleLong (info[i].filepos);
+ fs_offset_t size = (unsigned int)LittleLong (info[i].filelen);
FS_AddFileToPack (info[i].name, pack, offset, size, size, PACKFILE_FLAG_TRUEOFFS);
}
if(fs_selfpack)
{
searchpath_t *search;
- search = Mem_Alloc(fs_mempool, sizeof(searchpath_t));
+ search = (searchpath_t *)Mem_Alloc(fs_mempool, sizeof(searchpath_t));
search->next = fs_searchpaths;
search->pack = fs_selfpack;
fs_searchpaths = search;
{
int i;
qboolean fs_modified = false;
+ qboolean reset = false;
char gamedirbuf[MAX_INPUTLINE];
+ if (fs_searchpaths)
+ reset = true;
FS_ClearSearchPath();
+ // automatically activate gamemode for the gamedirs specified
+ if (reset)
+ COM_ChangeGameTypeForGameDirs();
+
// add the game-specific paths
// gamedirname1 (typically id1)
FS_AddGameHierarchy (gamedirname1);
unlink (va("%s/qconsole.log", fs_gamedir));
// look for the pop.lmp file and set registered to true if it is found
- if ((gamemode == GAME_NORMAL || gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE) && !FS_FileExists("gfx/pop.lmp"))
+ if (FS_FileExists("gfx/pop.lmp"))
+ Cvar_Set ("registered", "1");
+ switch(gamemode)
{
- if (fs_modified)
- Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
+ case GAME_NORMAL:
+ case GAME_HIPNOTIC:
+ case GAME_ROGUE:
+ if (!registered.integer)
+ {
+ if (fs_modified)
+ Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
+ else
+ Con_Print("Playing shareware version.\n");
+ }
else
- Con_Print("Playing shareware version.\n");
- }
- else
- {
- Cvar_Set ("registered", "1");
- if (gamemode == GAME_NORMAL || gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
Con_Print("Playing registered version.\n");
+ break;
+ case GAME_STEELSTORM:
+ if (registered.integer)
+ Con_Print("Playing registered version.\n");
+ else
+ Con_Print("Playing shareware version.\n");
+ break;
+ default:
+ break;
}
// unload all wads so that future queries will return the new data
*/
extern void Host_SaveConfig (void);
extern void Host_LoadConfig_f (void);
+extern qboolean vid_opened;
+extern void VID_Stop(void);
qboolean FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qboolean complain, qboolean failmissing)
{
int i;
// reinitialize filesystem to detect the new paks
FS_Rescan();
- // exec the new config
- Host_LoadConfig_f();
+ if (cls.demoplayback)
+ {
+ CL_Disconnect_f();
+ cls.demonum = 0;
+ }
// unload all sounds so they will be reloaded from the new files as needed
S_UnloadAllSounds_f();
- // reinitialize renderer (this reloads hud/console background/etc)
- R_Modules_Restart();
+ // close down the video subsystem, it will start up again when the config finishes...
+ VID_Stop();
+ vid_opened = false;
+
+ // restart the video subsystem after the config is executed
+ Cbuf_InsertText("\nloadconfig\nvid_restart\n\n");
return true;
}
FS_ChangeGameDirs(numgamedirs, gamedirs, true, true);
}
-static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblocking);
static const char *FS_SysCheckGameDir(const char *gamedir)
{
static char buf[8192];
fs_mempool = Mem_AllocPool("file management", 0, NULL);
if(com_selffd >= 0)
{
- fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd);
+ fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true);
if(fs_selfpack)
{
char *buf, *q;
size_t homedirlen;
#endif
#endif
+#ifndef __IPHONEOS__
char *homedir;
+#endif
#ifdef WIN32
const char* dllnames [] =
// don't care for the result; if it fails, %USERPROFILE% will be used instead
#endif
+ *fs_basedir = 0;
+ *fs_userdir = 0;
+ *fs_gamedir = 0;
+
+#ifdef __IPHONEOS__
+ // fs_basedir is "" by default, to utilize this you can simply add your gamedir to the Resources in xcode
+ // fs_userdir stores configurations to the Documents folder of the app
+ strlcpy(fs_userdir, "../Documents/", sizeof(fs_userdir));
+#else
// Add the personal game directory
if((i = COM_CheckParm("-userdir")) && i < com_argc - 1)
{
fs_basedir[split - com_argv[0]] = 0;
}
#endif
+#endif
#endif
// -basedir <path>
Internal function used to create a qfile_t and open the relevant non-packed file on disk
====================
*/
-static qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblocking)
+qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblocking)
{
qfile_t* file;
return NULL;
}
+ file->filename = Mem_strdup(fs_mempool, filepath);
+
file->real_length = lseek (file->handle, 0, SEEK_END);
// For files opened in append mode, we start at the end of the file
// the dup() call to avoid having to close the dup_handle on error here
if (lseek (pack->handle, pfile->offset, SEEK_SET) == -1)
{
- Con_Printf ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %d)\n",
- pfile->name, pack->filename, (int) pfile->offset);
+ Con_Printf ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %08x%08x)\n",
+ pfile->name, pack->filename, (unsigned int)(pfile->offset >> 32), (unsigned int)(pfile->offset));
return NULL;
}
if (close (file->handle))
return EOF;
+ if (file->filename)
+ {
+ if (file->flags & QFILE_FLAG_REMOVE)
+ remove(file->filename);
+
+ Mem_Free((void *) file->filename);
+ }
+
if (file->ztk)
{
qz_inflateEnd (&file->ztk->zstream);
return 0;
}
+void FS_RemoveOnClose(qfile_t* file)
+{
+ file->flags |= QFILE_FLAG_REMOVE;
+}
/*
====================
The filename will be prefixed by the current game directory
============
*/
-qboolean FS_WriteFile (const char *filename, void *data, fs_offset_t len)
+qboolean FS_WriteFileInBlocks (const char *filename, const void *const *data, const fs_offset_t *len, size_t count)
{
qfile_t *file;
+ size_t i;
+ fs_offset_t lentotal;
file = FS_OpenRealFile(filename, "wb", false);
if (!file)
return false;
}
- Con_DPrintf("FS_WriteFile: %s (%u bytes)\n", filename, (unsigned int)len);
- FS_Write (file, data, len);
+ lentotal = 0;
+ for(i = 0; i < count; ++i)
+ lentotal += len[i];
+ Con_DPrintf("FS_WriteFile: %s (%u bytes)\n", filename, (unsigned int)lentotal);
+ for(i = 0; i < count; ++i)
+ FS_Write (file, data[i], len[i]);
FS_Close (file);
return true;
}
+qboolean FS_WriteFile (const char *filename, const void *data, fs_offset_t len)
+{
+ return FS_WriteFileInBlocks(filename, &data, &len, 1);
+}
+
/*
=============================================================================