mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 22:51:57 +00:00
Tweeked the filesystem some more, now prompts if a game directory could not be found.
Fixed up clipped decals slightly. They should now be usable. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3169 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
43d97c3e31
commit
b8bd024a1d
5 changed files with 129 additions and 48 deletions
|
@ -1682,8 +1682,11 @@ void CLDP_ParseDownloadData(void)
|
||||||
|
|
||||||
MSG_ReadData(buffer, size);
|
MSG_ReadData(buffer, size);
|
||||||
|
|
||||||
VFS_SEEK(cls.downloadqw, start);
|
if (cls.downloadqw)
|
||||||
VFS_WRITE(cls.downloadqw, buffer, size);
|
{
|
||||||
|
VFS_SEEK(cls.downloadqw, start);
|
||||||
|
VFS_WRITE(cls.downloadqw, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
//this is only reliable because I'm lazy
|
//this is only reliable because I'm lazy
|
||||||
MSG_WriteByte(&cls.netchan.message, clcdp_ackdownloaddata);
|
MSG_WriteByte(&cls.netchan.message, clcdp_ackdownloaddata);
|
||||||
|
@ -1717,15 +1720,20 @@ void CLDP_ParseDownloadBegin(char *s)
|
||||||
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "wb", FS_GAME);
|
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "wb", FS_GAME);
|
||||||
cls.downloadmethod = DL_DARKPLACES;
|
cls.downloadmethod = DL_DARKPLACES;
|
||||||
|
|
||||||
//fill the file with 0 bytes
|
if (cls.downloadqw)
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
for (pos = 0, chunk = 1; chunk; pos += chunk)
|
|
||||||
{
|
{
|
||||||
chunk = size - pos;
|
//fill the file with 0 bytes
|
||||||
if (chunk > sizeof(buffer))
|
memset(buffer, 0, sizeof(buffer));
|
||||||
chunk = sizeof(buffer);
|
for (pos = 0, chunk = 1; chunk; pos += chunk)
|
||||||
VFS_WRITE(cls.downloadqw, buffer, chunk);
|
{
|
||||||
|
chunk = size - pos;
|
||||||
|
if (chunk > sizeof(buffer))
|
||||||
|
chunk = sizeof(buffer);
|
||||||
|
VFS_WRITE(cls.downloadqw, buffer, chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
CL_DownloadFailed(cls.downloadname);
|
||||||
|
|
||||||
downloadstarttime = Sys_DoubleTime();
|
downloadstarttime = Sys_DoubleTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1949,6 +1949,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
|
||||||
dir = bestdir;
|
dir = bestdir;
|
||||||
}
|
}
|
||||||
VectorInverse(dir);
|
VectorInverse(dir);
|
||||||
|
VectorNormalize(dir);
|
||||||
|
|
||||||
VectorNormalize(vec);
|
VectorNormalize(vec);
|
||||||
CrossProduct(dir, vec, tangent);
|
CrossProduct(dir, vec, tangent);
|
||||||
|
@ -2010,6 +2011,15 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
|
||||||
|
|
||||||
decverts += 3*3;
|
decverts += 3*3;
|
||||||
decalcount--;
|
decalcount--;
|
||||||
|
|
||||||
|
|
||||||
|
// maintain run list
|
||||||
|
if (!(ptype->state & PS_INRUNLIST))
|
||||||
|
{
|
||||||
|
ptype->nexttorun = part_run_list;
|
||||||
|
part_run_list = ptype;
|
||||||
|
ptype->state |= PS_INRUNLIST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3707,7 +3717,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t
|
||||||
vec3_t stop, normal;
|
vec3_t stop, normal;
|
||||||
part_type_t *type, *lastvalidtype;
|
part_type_t *type, *lastvalidtype;
|
||||||
particle_t *p, *kill;
|
particle_t *p, *kill;
|
||||||
clippeddecal_t *d;
|
clippeddecal_t *d, *dkill;
|
||||||
ramp_t *ramp;
|
ramp_t *ramp;
|
||||||
float grav;
|
float grav;
|
||||||
vec3_t friction;
|
vec3_t friction;
|
||||||
|
@ -3778,39 +3788,32 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t
|
||||||
{
|
{
|
||||||
if (type->clippeddecals)
|
if (type->clippeddecals)
|
||||||
{
|
{
|
||||||
/* for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
dkill = type->clippeddecals;
|
dkill = type->clippeddecals;
|
||||||
if (dkill && dkill->die < particletime)
|
if (dkill && dkill->die < particletime)
|
||||||
{
|
{
|
||||||
type->clippeddecals = dkill->next;
|
type->clippeddecals = dkill->next;
|
||||||
free_decals =
|
dkill->next = free_decals;
|
||||||
|
free_decals = dkill;
|
||||||
|
|
||||||
dkill->next = (clippeddecal_t *)kill_list;
|
|
||||||
kill_list = (particle_t*)dkill;
|
|
||||||
if (!kill_first)
|
|
||||||
kill_first = kill_list;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/ for (d=type->clippeddecals ; d ; d=d->next)
|
for (d=type->clippeddecals ; d ; d=d->next)
|
||||||
{
|
{
|
||||||
/* for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
dkill = d->next;
|
dkill = d->next;
|
||||||
if (dkill && dkill->die < particletime)
|
if (dkill && dkill->die < particletime)
|
||||||
{
|
{
|
||||||
d->next = dkill->next;
|
d->next = dkill->next;
|
||||||
dkill->next = (clippeddecal_t *)kill_list;
|
dkill->next = free_decals;
|
||||||
kill_list = (particle_t*)dkill;
|
free_decals = dkill;
|
||||||
if (!kill_first)
|
|
||||||
kill_first = kill_list;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -429,7 +429,11 @@ char *cleanarg(char *arg)
|
||||||
//no hacking us, please.
|
//no hacking us, please.
|
||||||
while (*arg == '-' || *arg == '+')
|
while (*arg == '-' || *arg == '+')
|
||||||
arg++;
|
arg++;
|
||||||
return arg;
|
while (*arg && *arg <= ' ')
|
||||||
|
arg++;
|
||||||
|
if (*arg)
|
||||||
|
return arg;
|
||||||
|
return "badarg";
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
|
@ -1775,7 +1775,7 @@ potentialgamepath_t pgp[] = {
|
||||||
#define NEXCFG "set sv_maxairspeed \"400\"\nset sv_mintic \"0.01\"\ncl_nolerp 0\n"
|
#define NEXCFG "set sv_maxairspeed \"400\"\nset sv_mintic \"0.01\"\ncl_nolerp 0\n"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *gamename; //sent to the master server when this is the current gamemode.
|
const char *protocolname; //sent to the master server when this is the current gamemode.
|
||||||
const char *exename; //used if the exe name contains this
|
const char *exename; //used if the exe name contains this
|
||||||
const char *argname; //used if this was used as a parameter.
|
const char *argname; //used if this was used as a parameter.
|
||||||
const char *auniquefile; //used if this file is relative from the gamedir
|
const char *auniquefile; //used if this file is relative from the gamedir
|
||||||
|
@ -1783,25 +1783,26 @@ typedef struct {
|
||||||
const char *customexec;
|
const char *customexec;
|
||||||
|
|
||||||
const char *dir[4];
|
const char *dir[4];
|
||||||
|
const char *poshname; //Full name for the game.
|
||||||
} gamemode_info_t;
|
} gamemode_info_t;
|
||||||
const gamemode_info_t gamemode_info[] = {
|
const gamemode_info_t gamemode_info[] = {
|
||||||
//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get.
|
//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get.
|
||||||
//this is to avoid having too many gamemodes anyway.
|
//this is to avoid having too many gamemodes anyway.
|
||||||
|
|
||||||
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
|
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
|
||||||
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", NULL, "id1", "qw", "fte"},
|
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", NULL, {"id1", "qw", "fte"}, "Quake"},
|
||||||
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL, NULL, "id1", "qw", "hipnotic", "fte"},
|
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"},
|
||||||
{"Darkplaces-Rogue", "rogue", "-rogue", NULL, NULL, "id1", "qw", "rogue", "fte"},
|
{"Darkplaces-Rogue", "rogue", "-rogue", NULL, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"},
|
||||||
{"Nexuiz", "nexuiz", "-nexuiz", "nexuiz.exe", NEXCFG, "data", "ftedata"},
|
{"Nexuiz", "nexuiz", "-nexuiz", "nexuiz.exe", NEXCFG, {"data", "ftedata"}, "Nexuiz"},
|
||||||
|
|
||||||
//supported commercial mods (some are currently only partially supported)
|
//supported commercial mods (some are currently only partially supported)
|
||||||
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", NULL, "data1", "fte"},
|
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", NULL, {"data1", "fte"}, "Hexen II"},
|
||||||
{"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", NULL, "baseq2", "fteq2"},
|
{"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", NULL, {"baseq2", "fteq2"}, "Quake II"},
|
||||||
{"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", NULL, "baseq3", "fteq3"},
|
{"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", NULL, {"baseq3", "fteq3"}, "Quake III Arena"},
|
||||||
|
|
||||||
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, "base", "fte"},
|
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"},
|
||||||
|
|
||||||
{"FTE-HalfLife", "hl", "-halflife", "valve/liblist.gam",NULL, "valve", "ftehl"},
|
{"FTE-HalfLife", "hl", "-halflife", "valve/liblist.gam",NULL, {"valve", "ftehl"}, "Half-Life"},
|
||||||
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
@ -1999,8 +2000,33 @@ void FS_ReloadPackFiles_f(void)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
qboolean Sys_FindGameData(const char *gamename, char *basepath, int basepathlen)
|
#include <shlobj.h>
|
||||||
|
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen)
|
||||||
{
|
{
|
||||||
|
DWORD resultlen;
|
||||||
|
HKEY key = NULL;
|
||||||
|
|
||||||
|
#ifndef INVALID_FILE_ATTRIBUTES
|
||||||
|
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//first, try and find it in our game paths location
|
||||||
|
if (!FAILED(RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
|
||||||
|
{
|
||||||
|
resultlen = basepathlen;
|
||||||
|
if (!RegQueryValueEx(key, gamename, NULL, NULL, basepath, &resultlen))
|
||||||
|
{
|
||||||
|
if (GetFileAttributes(basepath) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
RegCloseKey(key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!strcmp(gamename, "q1"))
|
if (!strcmp(gamename, "q1"))
|
||||||
{
|
{
|
||||||
//try and find it via steam
|
//try and find it via steam
|
||||||
|
@ -2008,8 +2034,6 @@ qboolean Sys_FindGameData(const char *gamename, char *basepath, int basepathlen)
|
||||||
//append SteamApps\common\quake
|
//append SteamApps\common\quake
|
||||||
//use it if we find winquake.exe there
|
//use it if we find winquake.exe there
|
||||||
FILE *f;
|
FILE *f;
|
||||||
DWORD resultlen;
|
|
||||||
HKEY key = NULL;
|
|
||||||
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
|
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
|
||||||
{
|
{
|
||||||
resultlen = basepathlen;
|
resultlen = basepathlen;
|
||||||
|
@ -2107,6 +2131,49 @@ qboolean Sys_FindGameData(const char *gamename, char *basepath, int basepathlen)
|
||||||
//append SteamApps\common\hexen 2
|
//append SteamApps\common\hexen 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (poshname)
|
||||||
|
{
|
||||||
|
char resultpath[MAX_PATH];
|
||||||
|
BROWSEINFO bi;
|
||||||
|
LPITEMIDLIST il;
|
||||||
|
memset(&bi, 0, sizeof(bi));
|
||||||
|
if (sys_parentwindow)
|
||||||
|
bi.hwndOwner = sys_parentwindow; //note that this is usually still null
|
||||||
|
else
|
||||||
|
bi.hwndOwner = mainwindow; //note that this is usually still null
|
||||||
|
bi.pidlRoot = NULL;
|
||||||
|
bi.pszDisplayName = resultpath;
|
||||||
|
bi.lpszTitle = va("Please locate your existing %s installation", poshname);
|
||||||
|
bi.ulFlags = BIF_RETURNONLYFSDIRS;
|
||||||
|
bi.lpfn = NULL;
|
||||||
|
bi.lParam = 0;
|
||||||
|
bi.iImage = 0;
|
||||||
|
|
||||||
|
il = SHBrowseForFolder(&bi);
|
||||||
|
if (il)
|
||||||
|
{
|
||||||
|
SHGetPathFromIDList(il, resultpath);
|
||||||
|
CoTaskMemFree(il);
|
||||||
|
Q_strncpyz(basepath, resultpath, basepathlen-1);
|
||||||
|
|
||||||
|
//and save it into the windows registry
|
||||||
|
if (!FAILED(RegCreateKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths",
|
||||||
|
0, NULL,
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
KEY_WRITE,
|
||||||
|
NULL,
|
||||||
|
&key,
|
||||||
|
NULL)))
|
||||||
|
{
|
||||||
|
RegSetValueEx(key, gamename, 0, REG_SZ, basepath, strlen(basepath));
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -2181,7 +2248,7 @@ void COM_InitFilesystem (void)
|
||||||
Cvar_Register(&com_gamename, "evil hacks");
|
Cvar_Register(&com_gamename, "evil hacks");
|
||||||
Cvar_Register(&com_modname, "evil hacks");
|
Cvar_Register(&com_modname, "evil hacks");
|
||||||
//identify the game from a telling file
|
//identify the game from a telling file
|
||||||
for (i = 0; gamemode_info[i].gamename; i++)
|
for (i = 0; gamemode_info[i].argname; i++)
|
||||||
{
|
{
|
||||||
if (!gamemode_info[i].auniquefile)
|
if (!gamemode_info[i].auniquefile)
|
||||||
continue; //no more
|
continue; //no more
|
||||||
|
@ -2194,13 +2261,13 @@ void COM_InitFilesystem (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//use the game based on an exe name over the filesystem one (could easily have multiple fs path matches).
|
//use the game based on an exe name over the filesystem one (could easily have multiple fs path matches).
|
||||||
for (i = 0; gamemode_info[i].gamename; i++)
|
for (i = 0; gamemode_info[i].argname; i++)
|
||||||
{
|
{
|
||||||
if (strstr(com_argv[0], gamemode_info[i].exename))
|
if (strstr(com_argv[0], gamemode_info[i].exename))
|
||||||
gamenum = i;
|
gamenum = i;
|
||||||
}
|
}
|
||||||
//use the game based on an parameter over all else.
|
//use the game based on an parameter over all else.
|
||||||
for (i = 0; gamemode_info[i].gamename; i++)
|
for (i = 0; gamemode_info[i].argname; i++)
|
||||||
{
|
{
|
||||||
if (COM_CheckParm(gamemode_info[i].argname))
|
if (COM_CheckParm(gamemode_info[i].argname))
|
||||||
{
|
{
|
||||||
|
@ -2216,7 +2283,7 @@ void COM_InitFilesystem (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (Sys_FindGameData(gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
|
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
|
||||||
{
|
{
|
||||||
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
|
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
|
||||||
com_quakedir[strlen(com_quakedir)-1] = '/';
|
com_quakedir[strlen(com_quakedir)-1] = '/';
|
||||||
|
@ -2239,14 +2306,14 @@ void COM_InitFilesystem (void)
|
||||||
//still failed? find quake and use that one by default
|
//still failed? find quake and use that one by default
|
||||||
if (gamenum<0)
|
if (gamenum<0)
|
||||||
{
|
{
|
||||||
for (i = 0; gamemode_info[i].gamename; i++)
|
for (i = 0; gamemode_info[i].argname; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(gamemode_info[i].argname, "-quake"))
|
if (!strcmp(gamemode_info[i].argname, "-quake"))
|
||||||
gamenum = i;
|
gamenum = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename);
|
Cvar_Set(&com_gamename, gamemode_info[gamenum].protocolname);
|
||||||
|
|
||||||
if (gamemode_info[gamenum].customexec)
|
if (gamemode_info[gamenum].customexec)
|
||||||
Cbuf_AddText(gamemode_info[gamenum].customexec, RESTRICT_LOCAL);
|
Cbuf_AddText(gamemode_info[gamenum].customexec, RESTRICT_LOCAL);
|
||||||
|
@ -2390,7 +2457,7 @@ void COM_InitFilesystem (void)
|
||||||
|
|
||||||
|
|
||||||
i = COM_CheckParm ("-addbasegame");
|
i = COM_CheckParm ("-addbasegame");
|
||||||
do //use multiple -addbasegames (this is so the basic dirs don't die)
|
while (i && i < com_argc-1) //use multiple -addbasegames (this is so the basic dirs don't die)
|
||||||
{
|
{
|
||||||
FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_quakedir, com_argv[i+1]), ~0);
|
FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_quakedir, com_argv[i+1]), ~0);
|
||||||
if (*com_homedir)
|
if (*com_homedir)
|
||||||
|
@ -2398,7 +2465,6 @@ void COM_InitFilesystem (void)
|
||||||
|
|
||||||
i = COM_CheckNextParm ("-addbasegame", i);
|
i = COM_CheckNextParm ("-addbasegame", i);
|
||||||
}
|
}
|
||||||
while (i && i < com_argc-1);
|
|
||||||
|
|
||||||
|
|
||||||
// any set gamedirs will be freed up to here
|
// any set gamedirs will be freed up to here
|
||||||
|
|
|
@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
//
|
//
|
||||||
void Sys_mkdir (char *path); //not all pre-unix systems have directories (including dos 1)
|
void Sys_mkdir (char *path); //not all pre-unix systems have directories (including dos 1)
|
||||||
qboolean Sys_remove (char *path);
|
qboolean Sys_remove (char *path);
|
||||||
qboolean Sys_FindGameData(const char *gamename, char *basepath, int basepathlen);
|
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen);
|
||||||
|
|
||||||
//
|
//
|
||||||
// memory protection
|
// memory protection
|
||||||
|
|
Loading…
Reference in a new issue