fix autotrack issues.

tweak gameclock to work properly with demos.
tried to fix stealth chat messages.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4896 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-06-14 01:28:01 +00:00
parent cb5bbfee2a
commit bdc8ae1281
22 changed files with 425 additions and 214 deletions

View file

@ -45,8 +45,6 @@ enum
TM_MODHINTS, //using the mod's //at hints
TM_STATS //parsing mvd stats and making our own choices
} autotrackmode;
int autotrack_hint; //the latest hint from the mod, might be negative for invalid.
int autotrack_killer; //if someone kills the guy we're tracking, this is the guy we should switch to.
char *autotrack_statsrule;
static void QDECL CL_AutoTrackChanged(cvar_t *v, char *oldval)
{
@ -148,10 +146,13 @@ static int CL_FindHighTrack(int seat, char *rule)
//set a default to the currently tracked player, to reuse the current player we're tracking if someone lower equalises.
j = cl.playerview[seat].cam_spec_track;
if (j >= 0)
if (j >= 0 && cl.players[j].name[0] && !cl.players[j].spectator)
max = CL_TrackScore(&cl.players[j], rule);
else
{
max = -9999;
j = -1;
}
for (i = 0; i < cl.allocated_client_slots; i++)
{
@ -183,15 +184,15 @@ static int CL_AutoTrack_Choose(int seat)
{
int best = -1;
if (autotrackmode == TM_KILLER)
best = autotrack_killer;
if (autotrackmode == TM_MODHINTS && seat == 0 && autotrack_hint >= 0)
best = autotrack_hint;
best = cl.autotrack_killer;
if (autotrackmode == TM_MODHINTS && seat == 0 && cl.autotrack_hint >= 0)
best = cl.autotrack_hint;
if (autotrackmode == TM_STATS && cls.demoplayback == DPB_MVD)
best = CL_FindHighTrack(seat, autotrack_statsrule);
if (autotrackmode == TM_HIGHTRACK || best == -1)
best = CL_FindHighTrack(seat, "f");
//TM_USER should generally avoid autotracking
autotrack_killer = best; //killer should continue to track whatever is currently tracked until its changed by frag message parsing
cl.autotrack_killer = best; //killer should continue to track whatever is currently tracked until its changed by frag message parsing
return best;
}
@ -402,8 +403,13 @@ static void Cam_CheckHighTarget(playerview_t *pv)
j = CL_AutoTrack_Choose(pv - cl.playerview);
if (j >= 0)
{
if (!pv->cam_locked || pv->cam_spec_track != j)
if (pv->cam_spec_track != j || !pv->cam_locked)
{
if (cl.teamplay)
Stats_Message("Now tracking:\n%s\n%s", cl.players[j].name, cl.players[j].team);
else
Stats_Message("Now tracking:\n%s", cl.players[j].name);
pv->cam_auto++;
Cam_Lock(pv, j);
//un-lock any higher seats watching our new target. this keeps things ordered.
for (spv = pv+1; spv >= cl.playerview && spv < &cl.playerview[cl.splitclients]; spv++)
@ -577,12 +583,12 @@ void Cam_SetAutoTrack(int userid)
{ //this is a hint from the server about who to track
int slot;
playerview_t *pv = &cl.playerview[0];
autotrack_hint = -1;
cl.autotrack_hint = -1;
for (slot = 0; slot < cl.allocated_client_slots; slot++)
{
if (cl.players[slot].userid == userid)
{
autotrack_hint = slot;
cl.autotrack_hint = slot;
return;
}
}
@ -719,6 +725,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
{
Cam_Unlock(pv);
VectorCopy(pv->viewangles, cmd->angles);
autotrackmode = TM_USER;
return;
}
}
@ -728,7 +735,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
else
{
pv->cam_oldbuttons &= ~BUTTON_ATTACK;
if (!pv->cam_auto)
if (!pv->cam_auto && autotrackmode == TM_USER)
{
if ((cmd->buttons & BUTTON_JUMP) && !(pv->cam_oldbuttons & BUTTON_JUMP))
Cam_TrackCrosshairedPlayer(pv);

View file

@ -322,6 +322,7 @@ void CL_MakeActive(char *gamename)
Con_DPrintf("%i additional FS searches\n", fs_finds);
fs_finds = 0;
}
cl.matchgametimestart = 0;
cls.state = ca_active;
S_Purge(true);
CL_UpdateWindowTitle();
@ -1408,6 +1409,8 @@ void CL_ClearState (void)
cl.gametime = 0;
cl.gametimemark = 0;
cl.splitclients = 1;
cl.autotrack_hint = -1;
cl.autotrack_killer = -1;
}
/*
@ -1932,7 +1935,7 @@ void CL_CheckServerInfo(void)
else
cl.matchstate = MATCH_DONTKNOW;
if (oldstate != cl.matchstate)
cl.matchgametime = 0;
cl.matchgametimestart = cl.gametime;
CL_CheckServerPacks();
@ -4688,10 +4691,6 @@ double Host_Frame (double time)
spare = 0;
host_frametime = (realtime - oldrealtime)*cl.gamespeed;
if (!cl.paused)
{
cl.matchgametime += host_frametime;
}
oldrealtime = realtime;
CL_ProgressDemoTime();

View file

@ -5384,13 +5384,31 @@ void CL_PrintChat(player_info_t *plr, char *msg, int plrflags)
*(msg - 2) = 0; // it's assumed that msg has 2 chars before it due to strstr
}*/
if (*msg == '\r')
{
name = msg;
msg = strstr(msg, ": ");
if (msg)
{
name++;
*msg = 0;
msg+=2;
plrflags &= ~TPM_TEAM|TPM_OBSERVEDTEAM;
}
else
{
msg = name;
name = NULL;
}
}
if (msg[0] == '/' && msg[1] == 'm' && msg[2] == 'e' && msg[3] == ' ')
{
msg += 4;
memessage = true; // special /me formatting
}
if (plr) // use special formatting with a real chat message
if (plr && !name) // use special formatting with a real chat message
name = plr->name; // use player's name
if (cl_standardchat.ival)
@ -5463,6 +5481,8 @@ void CL_PrintChat(player_info_t *plr, char *msg, int plrflags)
else
Q_strncatz(fullchatmessage, " ", sizeof(fullchatmessage));
}
else
Q_strncatz(fullchatmessage, "\1", sizeof(fullchatmessage));
// print message
if (cl_parsewhitetext.value && (cl_parsewhitetext.value == 1 || (plrflags & (TPM_TEAM|TPM_OBSERVEDTEAM))))
@ -6668,8 +6688,9 @@ void CLNQ_ParseProQuakeMessage (char *s)
break;
case pqc_match_time:
cl.matchgametime = MSG_ReadBytePQ(&s)*60;
cl.matchgametime += MSG_ReadBytePQ(&s);
cl.matchgametimestart = MSG_ReadBytePQ(&s)*60;
cl.matchgametimestart += MSG_ReadBytePQ(&s);
cl.matchgametimestart = cl.gametime - cl.matchgametimestart;
break;
case pqc_match_reset:

View file

@ -239,6 +239,7 @@ cvar_t show_speed = SCVAR("show_speed", "0");
cvar_t show_speed_x = SCVAR("show_speed_x", "-1");
cvar_t show_speed_y = SCVAR("show_speed_y", "-9");
cvar_t scr_loadingrefresh = SCVAR("scr_loadingrefresh", "0");
cvar_t scr_showobituaries = CVAR("scr_showobituaries", "0");
void *scr_curcursor;
@ -263,6 +264,7 @@ void CLSCR_Init(void)
Cvar_Register(&show_speed_x, cl_screengroup);
Cvar_Register(&show_speed_y, cl_screengroup);
Cvar_Register(&scr_neticontimeout, cl_screengroup);
Cvar_Register(&scr_showobituaries, cl_screengroup);
memset(&key_customcursor, 0, sizeof(key_customcursor));
@ -425,6 +427,8 @@ void VARGS Stats_Message(char *msg, ...)
va_list argptr;
char str[2048];
cprint_t *p = &scr_centerprint[0];
if (!scr_showobituaries.ival)
return;
if (p->time_off >= 0)
return;
@ -1433,23 +1437,18 @@ void SCR_DrawGameClock(void)
else
timelimit = 0;
if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME])
if (cl.matchstate == MATCH_STANDBY)
showtime = cl.servertime;
else if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME])
showtime = timelimit - (cl.servertime - cl.playerview[0].statsf[STAT_MATCHSTARTTIME]);
else
showtime = timelimit - cl.matchgametime;
else
showtime = timelimit - (cl.servertime - cl.matchgametimestart);
if (showtime < 0)
{
showtime *= -1;
minutes = showtime/60;
seconds = (int)showtime - (minutes*60);
}
else
{
minutes = showtime/60;
seconds = (int)showtime - (minutes*60);
}
minutes = showtime/60;
seconds = (int)showtime - (minutes*60);
sprintf(str, " %02i:%02i", minutes, seconds);
SCR_StringXY(str, show_gameclock_x.value, show_gameclock_y.value);

View file

@ -632,6 +632,7 @@ struct playerview_s
int cam_oldbuttons; //
vec3_t cam_viewangles; //
double cam_lastviewtime; //
float cam_reautotrack; // timer to throttle tracking changes.
int cam_spec_track; // player# of who we are tracking
enum
{
@ -682,6 +683,8 @@ typedef struct
int movesequence; // client->server frames
int spectator;
int autotrack_hint; //the latest hint from the mod, might be negative for invalid.
int autotrack_killer; //if someone kills the guy we're tracking, this is the guy we should switch to.
double last_ping_request; // while showing scoreboard
double last_servermessage;
@ -818,7 +821,7 @@ typedef struct
qboolean sendprespawn;
int contentstage;
double matchgametime;
double matchgametimestart;
enum {
MATCH_DONTKNOW,
MATCH_COUNTDOWN,

View file

@ -111,6 +111,11 @@ qboolean Stats_HaveKills(void)
void VARGS Stats_Message(char *msg, ...);
qboolean Stats_TrackerImageLoaded(char *in)
{
qboolean error;
return Font_TrackerValid(unicode_decode(&error, in, &in, true));
}
static char *Stats_GenTrackerImageString(char *in)
{ //images are of the form "foo \sg\ bar \q\"
//which should eg be remapped to: "foo ^Ue200 bar foo ^Ue201"
@ -237,7 +242,7 @@ void Stats_FragMessage(int p1, int wid, int p2, qboolean teamkill)
}
}
Q_snprintfz(message, sizeof(message), "%s%s ^7%s %s%s\n", p1c, p1n, w->image?w->image:w->abrev, p2c, p2n);
Q_snprintfz(message, sizeof(message), "%s%s ^7%s %s%s\n", p1c, p1n, Stats_TrackerImageLoaded(w->image)?w->image:w->abrev, p2c, p2n);
tracker = Con_FindConsole("tracker");
if (!tracker)

View file

@ -99,6 +99,7 @@ void SCR_SetLoadingFile(char *str);
void Font_Init(void);
void Font_Shutdown(void);
int Font_RegisterTrackerImage(const char *image); //returns a unicode char value that can be used to embed the char within a line of text.
qboolean Font_TrackerValid(unsigned int imid);
struct font_s *Font_LoadFont(float height, const char *fontfilename);
void Font_Free(struct font_s *f);
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);

View file

@ -1342,7 +1342,7 @@ void V_CalcRefdef (playerview_t *pv)
viewheight += pv->crouch;
if (pv->stats[STAT_HEALTH] < 0 && pv->cam_spec_track >= 0 && v_deathtilt.value) // PF_GIB will also set PF_DEAD
if (pv->stats[STAT_HEALTH] < 0 && (!cl.spectator || pv->cam_locked) && v_deathtilt.value) // PF_GIB will also set PF_DEAD
{
if (!cl.spectator || cl_chasecam.ival)
r_refdef.viewangles[ROLL] = 80*v_deathtilt.value; // dead view angle

View file

@ -2207,9 +2207,13 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
*plr = player;
}
}
}
if (!flags) // search for fake player
// if (i == cl.allocated_client_slots)
// return flags;
}
/*
if (!flags) // search for fake/non player
{
if ((name = strstr(s, ": "))) // use name as temp
{
@ -2220,6 +2224,7 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
flags |= TPM_TEAM;
}
}
*/
return flags;
}

View file

@ -2967,9 +2967,8 @@ void Cmd_WriteConfig_f(void)
#else
snprintf(fname, sizeof(fname), "fte.cfg");
#endif
FS_NativePath(fname, FS_GAMEONLY, sysname, sizeof(sysname));
FS_CreatePath(fname, FS_GAMEONLY);
f = FS_OpenVFS(fname, "wbp", FS_GAMEONLY);
f = FS_OpenWithFriends(fname, sysname, sizeof(sysname), 3, "quake.rc", "*.cfg", "configs/*.cfg");
all = cfg_save_all.ival;
}

View file

@ -2182,7 +2182,7 @@ unsigned int unicode_decode(int *error, const void *in, char **out, qboolean mar
if (markup && ((char*)in)[0] == '^' && ((char*)in)[1] == 'U' && ishexcode(((char*)in)[2]) && ishexcode(((char*)in)[3]) && ishexcode(((char*)in)[4]) && ishexcode(((char*)in)[5]))
{
*out = (char*)in + 6;
charcode = (dehex(((char*)in)[2]) << 12) | (dehex(((char*)in)[2]) << 8) | (dehex(((char*)in)[2]) << 4) | (dehex(((char*)in)[2]) << 0);
charcode = (dehex(((char*)in)[2]) << 12) | (dehex(((char*)in)[3]) << 8) | (dehex(((char*)in)[4]) << 4) | (dehex(((char*)in)[5]) << 0);
}
else if (markup && ((char*)in)[0] == '^' && ((char*)in)[1] == '{')
{
@ -4720,6 +4720,7 @@ static void Sys_ErrorThread(void *ctx, void *data, size_t a, size_t b)
}
void COM_WorkerAbort(char *message)
{
int us;
struct com_work_s work;
com_fatalerror = true;
if (Sys_IsMainThread())
@ -4728,6 +4729,7 @@ void COM_WorkerAbort(char *message)
if (!com_workercondition[0])
return; //Sys_IsMainThread was probably called too early...
memset(&work, 0, sizeof(work));
work.func = Sys_ErrorThread;
work.ctx = NULL;
work.data = message;
@ -4745,8 +4747,36 @@ void COM_WorkerAbort(char *message)
Sys_ConditionSignal(com_workercondition[0]);
Sys_UnlockConditional(com_workercondition[0]);
while(com_fatalerror)
Sys_Sleep(0.1);
//find out which worker we are
for (us = WORKERTHREADS-1; us > 0; us--)
if (Sys_IsThread(com_workerthread[us]))
break;
if (us)
{
//and post any pending work we have back over to the main thread, because we're going down as soon as we can.
while(!com_workerdone[us])
{
struct com_work_s *w;
Sys_LockConditional(com_workercondition[us]);
w = com_work_head[us];
if (w)
com_work_head[us] = w->next;
if (!com_work_head[us])
com_work_head[us] = com_work_tail[us] = NULL;
Sys_UnlockConditional(com_workercondition[us]);
if (w)
{
COM_AddWork(0, w->func, w->ctx, w->data, w->a, w->b);
Z_Free(w);
}
else
Sys_ConditionSignal(com_workercondition[0]);
Sys_Sleep(0.1);
}
com_workerdone[0] = true;
Sys_ConditionSignal(com_workercondition[0]);
}
Sys_ThreadAbort();
}
//return if there's *any* loading that needs to be done anywhere.
@ -4880,6 +4910,7 @@ void COM_AssertMainThread(const char *msg)
void COM_DestroyWorkerThread(void)
{
int i;
COM_WorkerFullSync();
com_fatalerror = false;
for (i = 0; i < WORKERTHREADS; i++)
{
@ -4917,6 +4948,7 @@ void COM_DestroyWorkerThread(void)
if (com_workercondition[i])
Sys_DestroyConditional(com_workercondition[i]);
com_workercondition[i] = NULL;
com_workerthread[i] = NULL;
}
if (com_resourcemutex)

View file

@ -459,6 +459,8 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r
vfsfile_t *FS_OpenTemp(void);
vfsfile_t *FS_OpenTCP(const char *name, int defaultport);
vfsfile_t *FS_OpenWithFriends(const char *fname, char *sysname, size_t sysnamesize, int numfriends, ...);
#define countof(array) (sizeof(array)/sizeof(array[0]))
#ifdef _WIN32
//windows doesn't support utf-8. Which is a shame really, because that's the charset we expect from everything.
@ -485,7 +487,6 @@ qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize, siz
qbyte *COM_LoadTempFile (const char *path, size_t *fsize);
qbyte *COM_LoadTempMoreFile (const char *path, size_t *fsize); //allocates a little bit more without freeing old temp
//qbyte *COM_LoadHunkFile (const char *path);
qbyte *COM_LoadMallocFile (const char *path, size_t *fsize);
searchpathfuncs_t *COM_IteratePaths (void **iterator, char *pathbuffer, int pathbuffersize, char *dirname, int dirnamesize);
void COM_FlushFSCache(qboolean purge, qboolean domutex); //a file was written using fopen

View file

@ -1480,7 +1480,66 @@ qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out
return true;
}
/*locates and opens a file*/
//returns false to stop the enumeration. check the return value of the fs enumerator to see if it was canceled by this return value.
static int QDECL FS_NullFSEnumerator(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath)
{
return FALSE;
}
//opens a file in the same (writable) path that contains an existing version of the file or one of the other patterns listed
vfsfile_t *FS_OpenWithFriends(const char *fname, char *sysname, size_t sysnamesize, int numfriends, ...)
{
searchpath_t *search;
searchpath_t *lastwritable = NULL;
flocation_t loc;
va_list ap;
int i;
char cleanname[MAX_QPATH];
fname = FS_GetCleanPath(fname, cleanname, sizeof(cleanname));
if (!fname)
return NULL;
for (search = com_searchpaths; search ; search = search->next)
{
if ((search->flags & SPF_EXPLICIT) && (search->flags & SPF_WRITABLE))
lastwritable = search;
if (search->handle->FindFile(search->handle, &loc, fname, NULL))
break;
va_start(ap, numfriends);
for (i = 0; i < numfriends; i++)
{
char *path = va_arg(ap, char*);
if (!search->handle->EnumerateFiles(search->handle, path, FS_NullFSEnumerator, NULL))
break;
}
va_end(ap);
if (i < numfriends)
break;
}
if (lastwritable)
{
//figure out the system path
Q_strncpyz(sysname, lastwritable->logicalpath, sysnamesize);
FS_CleanDir(sysname, sysnamesize);
Q_strncatz(sysname, fname, sysnamesize);
//create the dir if needed and open the file.
COM_CreatePath(sysname);
return VFSOS_Open(sysname, "wbp");
}
return NULL;
}
/*locates and opens a file
modes:
r = read
w = write
a = append
t = text mode (because windows sucks). binary is otherwise assumed.
p = persist (ie: saved games and configs, but not downloads or large content)
*/
vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto)
{
char cleanname[MAX_QPATH];
@ -2164,6 +2223,8 @@ static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purep
Q_strncpyz(search->purepath, purepath, sizeof(search->purepath));
Q_strncpyz(search->logicalpath, logicalpath, sizeof(search->logicalpath));
flags &= ~SPF_WRITABLE;
//temp packages also do not nest
if (!(flags & SPF_TEMPORARY))
{
@ -2908,21 +2969,21 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
{
//paths with a leading * are private, and not announced to clients that ask what the current gamedir is.
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, dir+1);
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE);
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE|(com_homepathenabled?0:SPF_WRITABLE));
if (com_homepathenabled)
{
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, dir+1);
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE);
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE|SPF_WRITABLE);
}
}
else
{
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, dir);
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT);
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT|(com_homepathenabled?0:SPF_WRITABLE));
if (com_homepathenabled)
{
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, dir);
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT);
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT|SPF_WRITABLE);
}
}
}

View file

@ -74,4 +74,5 @@ void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man),
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir.
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);

View file

@ -476,7 +476,7 @@ newsection:
if (!strcmp(filename, "p_start"))
{
section = 3;
sprintf (newfiles[i].name, "patches/%s", filename); //the map loader will find these.
sprintf (newfiles[i].name, "patches/%s.pat", filename); //the map loader will find these.
break;
}
if (!strcmp(filename, "f_start"))
@ -547,7 +547,7 @@ newsection:
section = 0;
goto newsection;
}
sprintf (newfiles[i].name, "patches/%s", filename);
sprintf (newfiles[i].name, "patches/%s.pat", filename);
break;
case 4: //flats section
if (!strcmp(filename, "f_end"))
@ -555,7 +555,7 @@ newsection:
section = 0;
goto newsection;
}
sprintf (newfiles[i].name, "flats/%s", filename);
sprintf (newfiles[i].name, "flats/%s.raw", filename);
break;
}
}
@ -572,6 +572,8 @@ newsection:
Con_TPrintf ("Added packfile %s (%i files)\n", desc, numpackfiles);
pack->mutex = Sys_CreateMutex();
pack->pub.fsver = FSVER;
pack->pub.GetPathDetails = FSPAK_GetPathDetails;
pack->pub.ClosePath = FSPAK_ClosePath;

View file

@ -102,6 +102,7 @@ void Sys_SetThreadName(unsigned int dwThreadID, char *threadName);
void Sys_ThreadsInit(void);
//qboolean Sys_IsThread(void *thread);
qboolean Sys_IsMainThread(void);
qboolean Sys_IsThread(void *thread);
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize);
void Sys_WaitOnThread(void *thread);
void Sys_DetachThread(void *thread);

View file

@ -157,12 +157,12 @@ qboolean Sys_IsMainThread(void)
{
return mainthread == GetCurrentThreadId();
}
/*
qboolean Sys_IsThread(void *thread)
{
return GetThreadId(thread) == GetCurrentThreadId();
}
*/
/* Mutex calls */
/*

View file

@ -300,6 +300,25 @@ static image_t *Font_GetTrackerImage(unsigned int imid)
return NULL;
return trackerimages[imid].image;
}
qboolean Font_TrackerValid(unsigned int imid)
{
imid -= TRACKERFIRST;
if (imid >= countof(trackerimages))
return false;
if (!trackerimages[imid].image)
{
if (!*trackerimages[imid].name)
return false;
trackerimages[imid].image = Image_GetTexture(trackerimages[imid].name, NULL, 0, NULL, NULL, 0, 0, TF_INVALID);
}
if (!trackerimages[imid].image)
return false;
if (trackerimages[imid].image->status == TEX_LOADING)
COM_WorkerPartialSync(trackerimages[imid].image, &trackerimages[imid].image->status, TEX_LOADING);
if (trackerimages[imid].image->status != TEX_LOADED)
return false;
return true;
}
//called at load time - initalises font buffers
void Font_Init(void)
@ -1121,13 +1140,14 @@ void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
if (col->length + col->topdelta > p->height)
break;
src = (unsigned char *)col + 3; /*why 3? why not, I suppose*/
src = (unsigned char *)col + 2; /*why 3? why not, I suppose*/
dst = b + stride*col->topdelta;
for (y = 0; y < col->length; y++)
{
*dst = *src++;
dst += stride;
}
src++;
col = (doomcolumn_t *)((unsigned char*)col + col->length + 4);
}
b++;
@ -1245,14 +1265,18 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
f->charheight = h;
}
FS_FreeFile(dp);
}
/*if all loaded okay, replicate the chars to the quake-compat range (both white+red chars)*/
if (i == '_'+1)
{
//doom doesn't have many chars, so make sure the lower case chars exist.
for (i = 'a'; i <= 'z'; i++)
f->chars[i] = f->chars[i-'a'+'A'];
//no space char either
f->chars[' '].advance = 8;
f->singletexture = R_LoadTexture8("doomfont", PLANEWIDTH, PLANEHEIGHT, buf, 0, true);
for (i = 0xe000; i <= 0xe0ff; i++)
{

View file

@ -62,7 +62,7 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose);
static void Mod_PrintFormats_f(void);
#ifdef MAP_DOOM
qboolean Mod_LoadDoomLevel(model_t *mod);
qboolean QDECL Mod_LoadDoomLevel(model_t *mod, void *buffer, size_t fsize);
#endif
#ifdef DSPMODELS
@ -1392,7 +1392,7 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
if (!*mt->name) //I HATE MAPPERS!
{
sprintf(mt->name, "unnamed%i", i);
Con_Printf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name);
Con_DPrintf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name);
}
mt->width = LittleLong (mt->width);

View file

@ -1520,7 +1520,7 @@ static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2)
{
int i, m;
if (!v2 || !v1)
return false;
return true;
m = (cl.worldmodel->numclusters+7)>>3;
for (i=(m&~3) ; i<m ; i++)

View file

@ -3,6 +3,20 @@
#include "glquake.h"
#include "shader.h"
char *va2(char *buffer, size_t buffersize, const char *format, ...)
{
va_list argptr;
va_start (argptr, format);
buffer[--buffersize] = 0;
vsnprintf (buffer, buffersize, format, argptr);
va_end (argptr);
return buffer;
}
int SignbitsForPlane (mplane_t *out);
int PlaneTypeForNormal ( vec3_t normal );
@ -208,7 +222,7 @@ unsigned int vertexsglbase;
typedef struct
{
char name[8];
char name[16];
shader_t *shader;
unsigned short width;
unsigned short height;
@ -272,7 +286,12 @@ int Doom_PointContents(model_t *model, vec3_t axis[3], vec3_t p)
return FTECONTENTS_EMPTY;
}
qboolean Doom_Trace(model_t *model, int hulloverride, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int contentstype, trace_t *trace)
/*
fixme:
use q2-style bsp collision using the trisoup for flats collisions.
use blockmap for walls
*/
qboolean Doom_Trace(model_t *model, int hulloverride, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean iscapsule, unsigned int contentstype, trace_t *trace)
{
#if 0
#define TRACESTEP 16
@ -657,8 +676,8 @@ qboolean Doom_Trace(model_t *model, int hulloverride, int frame, vec3_t axis[3],
trace->allsolid = trace->startsolid = false;
//Con_Printf("total = %f\n", trace->fraction);
return trace->fraction==1;
#endif
return trace->fraction==1;
}
@ -688,7 +707,7 @@ void Doom_LoadPalette(void)
if (!paletteloaded)
{
paletteloaded = true;
file = FS_LoadMallocFile("wad/playpal");
file = FS_LoadMallocFile("wad/playpal", NULL);
if (file)
{
memcpy(doompalette, file, 768);
@ -706,10 +725,9 @@ void Doom_LoadPalette(void)
}
}
#endif
int Doom_LoadFlat(char *flatname)
int Doom_LoadFlat(model_t *mod, char *flatname)
{
#ifndef SERVERONLY
char *file;
char texname[64];
int texnum;
@ -725,23 +743,10 @@ int Doom_LoadFlat(char *flatname)
memset(gldoomtextures + numgldoomtextures, 0, sizeof(gldoomtextures[numgldoomtextures]));
numgldoomtextures++;
strncpy(gldoomtextures[texnum].name, texname, 8);
gldoomtextures[texnum].shader = R_RegisterShader(texname, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\n}\n}\n");
Q_strncpyz(gldoomtextures[texnum].name, texname, sizeof(gldoomtextures[texnum].name));
gldoomtextures[texnum].width = 64;
gldoomtextures[texnum].height = 64;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
file = FS_LoadMallocFile(texname);
if (file)
{
gldoomtextures[texnum].shader->defaulttextures.base = R_LoadTexture8Pal24(texname, 64, 64, file, doompalette, 0);
Z_Free(file);
}
return texnum;
#else
@ -814,7 +819,8 @@ static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float z1,
mesh->numvertexes += 4;
mesh->numindexes += 6;
BE_DrawMesh_Single(tex->shader, mesh, NULL, &tex->shader->defaulttextures, 0);
if (tex->shader)
BE_DrawMesh_Single(tex->shader, mesh, NULL, 0);
}
static void GLR_DrawFlats(int floortexnum, int floorheight, int ceiltexnum, int ceilheight, int numverts, unsigned short *verts, unsigned int colour4b)
@ -859,7 +865,8 @@ static void GLR_DrawFlats(int floortexnum, int floorheight, int ceiltexnum, int
mesh->numvertexes += numverts;
mesh->numindexes += numverts;
BE_DrawMesh_Single(floortex->shader, mesh, NULL, &floortex->shader->defaulttextures, 0);
if (floortex->shader)
BE_DrawMesh_Single(floortex->shader, mesh, NULL, 0);
}
//ceiling
@ -898,7 +905,8 @@ static void GLR_DrawFlats(int floortexnum, int floorheight, int ceiltexnum, int
mesh->numvertexes += numverts;
mesh->numindexes += numverts;
BE_DrawMesh_Single(ceiltex->shader, mesh, NULL, &ceiltex->shader->defaulttextures, 0);
if (ceiltex->shader)
BE_DrawMesh_Single(ceiltex->shader, mesh, NULL, 0);
}
}
@ -1125,7 +1133,7 @@ void GLR_DoomWorld(void)
for (texnum = 0; texnum < numgldoomtextures; texnum++) //a hash table might be a good plan.
{
t = &gldoomtextures[texnum];
if (t->mesh.numindexes)
if (t->mesh.numindexes && t->shader)
{
t->batch.next = cl.worldmodel->batches[t->shader->sort];
cl.worldmodel->batches[t->shader->sort] = &t->batch;
@ -1375,7 +1383,7 @@ static unsigned short *Triangulate_Finish(int *numtris, unsigned short *old, int
return out;
}
static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
static void Triangulate_Sectors(model_t *mod, dsector_t *sectorl, qboolean glbspinuse)
{
int seg, nsec;
int i, sec=-1;
@ -1448,8 +1456,8 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
for (i = 0; i < sectorc; i++)
{
sectorm[i].ceilingtex = Doom_LoadFlat(sectorl[i].ceilingtexture);
sectorm[i].floortex = Doom_LoadFlat(sectorl[i].floortexture);
sectorm[i].ceilingtex = Doom_LoadFlat(mod, sectorl[i].ceilingtexture);
sectorm[i].floortex = Doom_LoadFlat(mod, sectorl[i].floortexture);
sectorm[i].lightlev = sectorl[i].lightlevel;
sectorm[i].specialtype = sectorl[i].specialtype;
sectorm[i].tag = sectorl[i].tag;
@ -1464,9 +1472,9 @@ static void *textures2;
static char *pnames;
static void Doom_LoadTextureInfos(void)
{
textures1 = FS_LoadMallocFile("wad/texture1");
textures2 = FS_LoadMallocFile("wad/texture2");
pnames = FS_LoadMallocFile("wad/pnames");
textures1 = FS_LoadMallocFile("wad/texture1", NULL);
textures2 = FS_LoadMallocFile("wad/texture2", NULL);
pnames = FS_LoadMallocFile("wad/pnames", NULL);
}
typedef struct {
@ -1494,7 +1502,7 @@ typedef struct {
short ypos;
} doomimage_t;
static void Doom_ExtractPName(unsigned int *out, doomimage_t *di, int outwidth, int outheight, int x, int y)
static void Doom_ExtractPName(unsigned int *out, doomimage_t *di, size_t imgsize, int outwidth, int outheight, int x, int y)
{
unsigned int *colpointers;
int c, fr, rc, extra;
@ -1518,7 +1526,7 @@ static void Doom_ExtractPName(unsigned int *out, doomimage_t *di, int outwidth,
if (c+x >= outwidth)
break;
if (colpointers[c] >= com_filesize)
if (colpointers[c] >= imgsize)
break;
coldata = data + colpointers[c];
while(1)
@ -1535,7 +1543,8 @@ static void Doom_ExtractPName(unsigned int *out, doomimage_t *di, int outwidth,
if (fr<0)
{
coldata -= fr; //plus
coldata += -fr; //plus
rc -= -fr;
fr = 0;
}
@ -1587,11 +1596,16 @@ static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned shor
tc = (ddoomtexturecomponant_t*)(tx+1);
for (i = 0; i < tx->componantcount; i++, tc++)
{
doomimage_t *img;
size_t imgsize;
strncpy(patch+8, pnames+4+8*tc->patchnum, 8);
Q_strlwr(patch+8);
patch[16] = '\0';
Q_strncatz(patch, ".pat", sizeof(patch));
Doom_ExtractPName(tex, (doomimage_t *)COM_LoadTempFile(patch), tx->width, tx->height, tc->xoffset, tc->yoffset);
img = (doomimage_t *)FS_LoadMallocFile(patch, &imgsize);
Doom_ExtractPName(tex, img, imgsize, tx->width, tx->height, tc->xoffset, tc->yoffset);
BZ_Free(img);
}
*hasalpha = false;
@ -1614,15 +1628,15 @@ static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned shor
return r_nulltex;
}
static int Doom_LoadPatch(char *name)
static int Doom_LoadPatch(model_t *mod, char *name)
{
texid_t tex;
qboolean hasalpha = false;
int texnum;
size_t nlen = strnlen(name, 8);
for (texnum = 0; texnum < numgldoomtextures; texnum++) //a hash table might be a good plan.
{
if(!strncmp(name, gldoomtextures[texnum].name, 8))
if(!memcmp(name, gldoomtextures[texnum].name, nlen) && !gldoomtextures[texnum].name[nlen])
{
return texnum;
}
@ -1634,32 +1648,59 @@ static int Doom_LoadPatch(char *name)
memset(gldoomtextures + numgldoomtextures, 0, sizeof(gldoomtextures[numgldoomtextures]));
numgldoomtextures++;
strncpy(gldoomtextures[texnum].name, name, 8);
tex = r_nulltex;
if (textures1 && !TEXVALID(tex))
tex = Doom_LoadPatchFromTexWad(name, textures1, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
if (textures2 && !TEXVALID(tex))
tex = Doom_LoadPatchFromTexWad(name, textures2, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
if (!TEXVALID(tex))
{
//all else failed.
gldoomtextures[texnum].width = image_width;
gldoomtextures[texnum].height = image_height;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
}
if (hasalpha)
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\nalphafunc ge128\n}\n}\n");
else
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\n}\n}\n");
gldoomtextures[texnum].shader->defaulttextures.base = tex;
memcpy(gldoomtextures[texnum].name, name, nlen);
gldoomtextures[texnum].name[nlen] = 0;
return texnum;
}
static void Doom_LoadShaders(void *ctx, void *data, size_t a, size_t b)
{
model_t *mod = ctx;
texnums_t tn;
qboolean hasalpha = false;
qboolean isflat;
int texnum;
char tmp[MAX_QPATH];
for (texnum = 0; texnum < numgldoomtextures; texnum++) //a hash table might be a good plan.
{
isflat = !strncmp(gldoomtextures[texnum].name, "flats/", 6);
memset(&tn, 0, sizeof(tn));
if (isflat)
{
void *file = FS_LoadMallocFile(va2(tmp, sizeof(tmp), "%s.raw", gldoomtextures[texnum].name), NULL);
if (file)
{
tn.base = Image_GetTexture(gldoomtextures[texnum].name, NULL, 0, file, doompalette, 64, 64, TF_8PAL24);
Z_Free(file);
}
gldoomtextures[texnum].width = 64;
gldoomtextures[texnum].height = 64;
}
else
{
if (textures1 && !TEXVALID(tn.base))
tn.base = Doom_LoadPatchFromTexWad(gldoomtextures[texnum].name, textures1, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
if (textures2 && !TEXVALID(tn.base))
tn.base = Doom_LoadPatchFromTexWad(gldoomtextures[texnum].name, textures2, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
}
if (!TEXVALID(tn.base))
{
gldoomtextures[texnum].width = 64;
gldoomtextures[texnum].height = 64;
hasalpha = false;
}
if (hasalpha)
gldoomtextures[texnum].shader = R_RegisterShader(gldoomtextures[texnum].name, SUF_NONE, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\nalphafunc ge128\n}\n}\n");
else
gldoomtextures[texnum].shader = R_RegisterShader(gldoomtextures[texnum].name, SUF_NONE, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\n}\n}\n");
R_BuildDefaultTexnums(&tn, gldoomtextures[texnum].shader);
}
};
static void Doom_Purge (struct model_s *mod)
{
int texnum;
@ -1674,7 +1715,7 @@ static void Doom_Purge (struct model_s *mod)
gldoomtextures = NULL;
}
#endif
static void CleanWalls(dsidedef_t *sidedefsl)
static void CleanWalls(model_t *mod, dsidedef_t *sidedefsl)
{
int i;
char texname[64];
@ -1697,7 +1738,7 @@ static void CleanWalls(dsidedef_t *sidedefsl)
else
{
strncpy(lastmiddle, texname, 8);
sidedefsm[i].middletex = lastmidtex = Doom_LoadPatch(texname);//Mod_LoadHiResTexture(texname, true, false);
sidedefsm[i].middletex = lastmidtex = Doom_LoadPatch(mod, texname);
}
}
@ -1712,7 +1753,7 @@ static void CleanWalls(dsidedef_t *sidedefsl)
else
{
strncpy(lastlower, texname, 8);
sidedefsm[i].lowertex = lastlowtex = Doom_LoadPatch(texname);//Mod_LoadHiResTexture(texname, true, true);
sidedefsm[i].lowertex = lastlowtex = Doom_LoadPatch(mod, texname);
}
}
@ -1727,7 +1768,7 @@ static void CleanWalls(dsidedef_t *sidedefsl)
else
{
strncpy(lastupper, texname, 8);
sidedefsm[i].uppertex = lastuptex = Doom_LoadPatch(texname);//Mod_LoadHiResTexture(texname, true, false);
sidedefsm[i].uppertex = lastuptex = Doom_LoadPatch(mod, texname);
}
}
#endif
@ -1737,14 +1778,16 @@ static void CleanWalls(dsidedef_t *sidedefsl)
}
}
void QuakifyThings(dthing_t *thingsl)
void QuakifyThings(model_t *mod, dthing_t *thingsl)
{
int sector;
int spawnflags;
char *name;
int i;
int zpos;
static char newlump[1024*1024];
static char newlump[1024*1024]; //FIXME
char thingname[MAX_QPATH];
char *ptr = newlump;
vec3_t point;
@ -1793,7 +1836,7 @@ void QuakifyThings(dthing_t *thingsl)
break;
default:
name = va("thing_%i", thingsl[i].type);
name = va2(thingname, sizeof(thingname), "thing_%i", thingsl[i].type);
break;
}
@ -1815,7 +1858,7 @@ void QuakifyThings(dthing_t *thingsl)
if (thingsl[i].flags & THING_DEAF)
spawnflags |= 1;
sprintf(ptr, "{\n"
Q_snprintfz(ptr, newlump+sizeof(newlump)-ptr, "{\n"
"\"classname\" \"%s\"\n"
"\"origin\" \"%i %i %i\"\n"
"\"spawnflags\" \"%i\"\n"
@ -1829,8 +1872,8 @@ void QuakifyThings(dthing_t *thingsl)
ptr += strlen(ptr);
}
loadmodel->entities = BZ_Malloc(ptr-newlump+1);
memcpy(loadmodel->entities, newlump, ptr-newlump+1);
mod->entities = BZ_Malloc(ptr-newlump+1);
memcpy(mod->entities, newlump, ptr-newlump+1);
}
void Doom_GeneratePlanes(ddoomnode_t *nodel)
@ -1949,11 +1992,13 @@ static void Doom_LoadVerticies(char *name)
int stdc, glc;
int *gl2;
int i;
size_t fsize;
char tmp[MAX_QPATH];
std = (void *)COM_LoadTempFile (va("%s.vertexes", name));
stdc = com_filesize/sizeof(*std);
std = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.vertexes", name), &fsize);
stdc = fsize/sizeof(*std);
gl2 = (void *)COM_LoadTempMoreFile (va("%s.gl_vert", name));
gl2 = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.gl_vert", name), &fsize);
if (!gl2)
{
glc = 0;
@ -1962,53 +2007,57 @@ static void Doom_LoadVerticies(char *name)
else if (gl2[0] == *(int*)"gNd2")
{
gl2++;
glc = (com_filesize-4)/sizeof(int)/2;
glc = (fsize-4)/sizeof(int)/2;
gl1 = NULL;
}
else
{
glc = com_filesize/sizeof(*gl1);
glc = fsize/sizeof(*gl1);
gl1 = (ddoomvertex_t*)gl2;
}
if (!stdc)
return;
vertexesc = stdc + glc;
vertexesl = BZ_Malloc(vertexesc*sizeof(*vertexesl));
vertexsglbase = stdc;
for (i = 0; i < stdc; i++)
if (stdc)
{
vertexesl[i].xpos = std[i].xpos;
vertexesl[i].ypos = std[i].ypos;
}
if (gl1)
{
for (i = 0; i < glc; i++)
vertexesc = stdc + glc;
vertexesl = BZ_Malloc(vertexesc*sizeof(*vertexesl));
vertexsglbase = stdc;
for (i = 0; i < stdc; i++)
{
vertexesl[stdc+i].xpos = gl1[i].xpos;
vertexesl[stdc+i].ypos = gl1[i].ypos;
}
}
else
{
for (i = 0; i < glc; i++)
{
vertexesl[stdc+i].xpos = (float)gl2[i*2] / 0x10000;
vertexesl[stdc+i].ypos = (float)gl2[i*2+1] / 0x10000;
vertexesl[i].xpos = std[i].xpos;
vertexesl[i].ypos = std[i].ypos;
}
if (gl1)
{
for (i = 0; i < glc; i++)
{
vertexesl[stdc+i].xpos = gl1[i].xpos;
vertexesl[stdc+i].ypos = gl1[i].ypos;
}
}
else
{
for (i = 0; i < glc; i++)
{
vertexesl[stdc+i].xpos = (float)gl2[i*2] / 0x10000;
vertexesl[stdc+i].ypos = (float)gl2[i*2+1] / 0x10000;
}
}
}
Z_Free(std);
Z_Free(gl2);
}
static void Doom_LoadSSectors(char *name)
{
ssectorsl = (void *)FS_LoadMallocFile (va("%s.gl_ssect", name));
size_t fsize;
char tmp[MAX_QPATH];
ssectorsl = (void *)FS_LoadMallocFile (va2(tmp, sizeof(tmp), "%s.gl_ssect", name), &fsize);
if (!ssectorsl)
ssectorsl = (void *)FS_LoadMallocFile (va("%s.ssectors", name));
ssectorsl = (void *)FS_LoadMallocFile (va2(tmp, sizeof(tmp), "%s.ssectors", name), &fsize);
//FIXME: "gNd3" means that it's glbsp version 3.
ssectorsc = com_filesize/sizeof(*ssectorsl);
ssectorsc = fsize/sizeof(*ssectorsl);
}
static void Doom_LoadSSegs(char *name)
@ -2019,12 +2068,14 @@ static void Doom_LoadSSegs(char *name)
dgl_seg1_t *s1;
dseg_t *s0;
int i;
size_t fsize;
char tmp[MAX_QPATH];
file = (void *)FS_LoadMallocFile (va("%s.gl_segs", name));
file = (void *)FS_LoadMallocFile (va2(tmp, sizeof(tmp), "%s.gl_segs", name), &fsize);
if (!file)
{
s0 = (void *)FS_LoadMallocFile (va("%s.segs", name));
segsc = com_filesize/sizeof(*s0);
s0 = (void *)FS_LoadMallocFile (va2(tmp, sizeof(tmp), "%s.segs", name), &fsize);
segsc = fsize/sizeof(*s0);
segsl = BZ_Malloc(segsc * sizeof(*segsl));
for (i = 0; i < segsc; i++)
@ -2039,7 +2090,7 @@ static void Doom_LoadSSegs(char *name)
else if (*(int *)file == *(int *)"gNd3")
{
s3 = file;
segsc = com_filesize/sizeof(*s3);
segsc = fsize/sizeof(*s3);
segsl = s3;
}
@ -2048,7 +2099,7 @@ static void Doom_LoadSSegs(char *name)
else
{
s1 = file;
segsc = com_filesize/sizeof(*s1);
segsc = fsize/sizeof(*s1);
segsl = BZ_Malloc(segsc * sizeof(*segsl));
for (i = 0; i < segsc; i++)
@ -2071,37 +2122,38 @@ static void Doom_LoadSSegs(char *name)
}
}
qboolean Mod_LoadDoomLevel(model_t *mod)
qboolean QDECL Mod_LoadDoomLevel(model_t *mod, void *buffer, size_t fsize)
{
int h;
dsector_t *sectorl;
dsidedef_t *sidedefsl;
char name[MAX_QPATH];
char tmp[MAX_QPATH];
int *gl_nodes;
COM_StripExtension(mod->name, name, sizeof(name));
if (!COM_LoadTempFile(va("%s", mod->name)))
if (fsize != 4)
{
Con_Printf("Wad map %s does not exist\n", mod->name);
Con_Printf("Wad map %s does actually exist... weird.\n", mod->name);
return false;
}
gl_nodes = (void *)FS_LoadMallocFile (va("%s.gl_nodes", name));
if (gl_nodes && com_filesize>0)
COM_StripExtension(mod->name, name, sizeof(name));
gl_nodes = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.gl_nodes", name), &fsize);
if (gl_nodes && fsize>0)
{
nodel = (void *)gl_nodes;
nodec = com_filesize/sizeof(*nodel);
nodec = fsize/sizeof(*nodel);
}
else
{
gl_nodes=NULL;
nodel = (void *)FS_LoadMallocFile (va("%s.nodes", name));
nodec = com_filesize/sizeof(*nodel);
nodel = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.nodes", name), &fsize);
nodec = fsize/sizeof(*nodel);
}
sectorl = (void *)FS_LoadMallocFile (va("%s.sectors", name));
sectorc = com_filesize/sizeof(*sectorl);
sectorl = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.sectors", name), &fsize);
sectorc = fsize/sizeof(*sectorl);
#ifndef SERVERONLY
numgldoomtextures=0;
@ -2114,14 +2166,14 @@ qboolean Mod_LoadDoomLevel(model_t *mod)
Doom_LoadSSegs(name);
Doom_LoadSSectors(name);
thingsl = (void *)FS_LoadMallocFile (va("%s.things", name));
thingsc = com_filesize/sizeof(*thingsl);
linedefsl = (void *)FS_LoadMallocFile (va("%s.linedefs", name));
linedefsc = com_filesize/sizeof(*linedefsl);
sidedefsl = (void *)FS_LoadMallocFile (va("%s.sidedefs", name));
sidedefsc = com_filesize/sizeof(*sidedefsl);
blockmapl = (void *)FS_LoadMallocFile (va("%s.blockmap", name));
// blockmaps = com_filesize;
thingsl = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.things", name), &fsize);
thingsc = fsize/sizeof(*thingsl);
linedefsl = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.linedefs", name), &fsize);
linedefsc = fsize/sizeof(*linedefsl);
sidedefsl = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.sidedefs", name), &fsize);
sidedefsc = fsize/sizeof(*sidedefsl);
blockmapl = (void *)FS_LoadMallocFile (va2(tmp,sizeof(tmp),"%s.blockmap", name), &fsize);
// blockmaps = fsize;
#ifndef SERVERONLY
Doom_LoadTextureInfos();
#endif
@ -2151,17 +2203,17 @@ qboolean Mod_LoadDoomLevel(model_t *mod)
Doom_SetModelFunc(mod);
mod->needload = false;
mod->fromgame = fg_doom;
mod->type = mod_brush;
mod->nodes = (void*)0x1;
CleanWalls(sidedefsl);
CleanWalls(mod, sidedefsl);
Triangulate_Sectors(sectorl, !!gl_nodes);
Triangulate_Sectors(mod, sectorl, !!gl_nodes);
QuakifyThings(thingsl);
QuakifyThings(mod, thingsl);
COM_AddWork(0, Doom_LoadShaders, mod, NULL, 0, 0);
return true;
}

View file

@ -466,7 +466,7 @@ static edict_t *QDECL Q1QVMPF_EntAlloc(pubprogfuncs_t *pf)
static int QDECL Q1QVMPF_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, float spawnflags)
{
q1qvmentstring = mapstring;
VM_Call(q1qvm, GAME_LOADENTS);
VM_Call(q1qvm, GAME_LOADENTS, 0, 0, 0);
q1qvmentstring = NULL;
return sv.world.edict_size;
}
@ -1310,6 +1310,7 @@ void Q1QVM_Shutdown(void)
Q_strncpyz(svs.clients[i].namebuf, svs.clients[i].name, sizeof(svs.clients[i].namebuf));
svs.clients[i].name = svs.clients[i].namebuf;
}
VM_Call(q1qvm, GAME_SHUTDOWN, 0, 0, 0);
VM_Destroy(q1qvm);
q1qvm = NULL;
VM_fcloseall(VMFSID_Q1QVM);
@ -1332,7 +1333,7 @@ void Q1QVM_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, o);
pr_global_struct->time = w->physicstime;
VM_Call(q1qvm, GAME_EDICT_TOUCH);
VM_Call(q1qvm, GAME_EDICT_TOUCH, 0, 0, 0);
pr_global_struct->self = oself;
pr_global_struct->other = oother;
@ -1342,7 +1343,7 @@ void Q1QVM_Event_Think(world_t *w, wedict_t *s)
{
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, w->edicts);
VM_Call(q1qvm, GAME_EDICT_THINK);
VM_Call(q1qvm, GAME_EDICT_THINK, 0, 0, 0);
}
qboolean Q1QVM_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
@ -1424,7 +1425,7 @@ qboolean PR_LoadQ1QVM(void)
q1qvmprogfuncs.stringtable = VM_MemoryBase(q1qvm);
ret = VM_Call(q1qvm, GAME_INIT, (qintptr_t)(sv.time*1000), rand());
ret = VM_Call(q1qvm, GAME_INIT, (qintptr_t)(sv.time*1000), rand(), 0, 0, 0);
if (!ret)
{
Q1QVM_Shutdown();
@ -1466,9 +1467,6 @@ qboolean PR_LoadQ1QVM(void)
sv.world.edict_size = gd->sizeofent;
vevars = (qintptr_t)gd->ents;
evars = ((char*)VM_MemoryBase(q1qvm) + vevars);
//FIXME: range check this pointer
//FIXME: range check the globals pointer
//WARNING: global is not remapped yet...
//This code is written evilly, but works well enough
@ -1527,7 +1525,7 @@ qboolean PR_LoadQ1QVM(void)
pr_global_ptrs->dimension_send = &dimensionsend;
pr_global_ptrs->physics_mode = &physics_mode;
dimensionsend = 255;
dimensionsend = dimensiondefault = 255;
for (i = 0; i < 16; i++)
pr_global_ptrs->spawnparamglobals[i] = (float*)((char*)VM_MemoryBase(q1qvm)+(qintptr_t)(&gd->global->parm1 + i));
for (; i < NUM_SPAWN_PARMS; i++)
@ -1571,12 +1569,12 @@ void Q1QVM_ClientConnect(client_t *cl)
// call the spawn function
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator);
VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator, 0, 0, 0);
// actually spawn the player
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_PUT_CLIENT_IN_SERVER, cl->spectator);
VM_Call(q1qvm, GAME_PUT_CLIENT_IN_SERVER, cl->spectator, 0, 0, 0);
}
qboolean Q1QVM_GameConsoleCommand(void)
@ -1595,7 +1593,7 @@ qboolean Q1QVM_GameConsoleCommand(void)
pr_global_struct->self = 0;
pr_global_struct->other = 0;
VM_Call(q1qvm, GAME_CONSOLE_COMMAND); //mod uses Cmd_Argv+co to get args
VM_Call(q1qvm, GAME_CONSOLE_COMMAND, 0, 0, 0); //mod uses Cmd_Argv+co to get args
pr_global_struct->self = oldself;
pr_global_struct->other = oldother;
@ -1610,7 +1608,7 @@ qboolean Q1QVM_ClientSay(edict_t *player, qboolean team)
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team);
washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team, 0, 0, 0);
return washandled;
}
@ -1622,53 +1620,53 @@ qboolean Q1QVM_UserInfoChanged(edict_t *player)
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player);
return VM_Call(q1qvm, GAME_CLIENT_USERINFO_CHANGED);
return VM_Call(q1qvm, GAME_CLIENT_USERINFO_CHANGED, 0, 0, 0);
}
void Q1QVM_PlayerPreThink(void)
{
VM_Call(q1qvm, GAME_CLIENT_PRETHINK, host_client->spectator);
VM_Call(q1qvm, GAME_CLIENT_PRETHINK, host_client->spectator, 0, 0, 0);
}
void Q1QVM_RunPlayerThink(void)
{
VM_Call(q1qvm, GAME_EDICT_THINK);
VM_Call(q1qvm, GAME_CLIENT_THINK, host_client->spectator);
VM_Call(q1qvm, GAME_EDICT_THINK, 0, 0, 0);
VM_Call(q1qvm, GAME_CLIENT_THINK, host_client->spectator, 0, 0, 0);
}
void Q1QVM_PostThink(void)
{
VM_Call(q1qvm, GAME_CLIENT_POSTTHINK, host_client->spectator);
VM_Call(q1qvm, GAME_CLIENT_POSTTHINK, host_client->spectator, 0, 0, 0);
}
void Q1QVM_StartFrame(void)
{
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000));
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), 0, 0, 0);
}
void Q1QVM_Blocked(void)
{
VM_Call(q1qvm, GAME_EDICT_BLOCKED);
VM_Call(q1qvm, GAME_EDICT_BLOCKED, 0, 0, 0);
}
void Q1QVM_SetNewParms(void)
{
VM_Call(q1qvm, GAME_SETNEWPARMS);
VM_Call(q1qvm, GAME_SETNEWPARMS, 0, 0, 0);
}
void Q1QVM_SetChangeParms(void)
{
VM_Call(q1qvm, GAME_SETCHANGEPARMS);
VM_Call(q1qvm, GAME_SETCHANGEPARMS, 0, 0, 0);
}
void Q1QVM_ClientCommand(void)
{
VM_Call(q1qvm, GAME_CLIENT_COMMAND);
VM_Call(q1qvm, GAME_CLIENT_COMMAND, 0, 0, 0);
}
void Q1QVM_GameCodePausedTic(float pausedduration)
{
VM_Call(q1qvm, GAME_PAUSED_TIC, (qintptr_t)(pausedduration*1000));
VM_Call(q1qvm, GAME_PAUSED_TIC, (qintptr_t)(pausedduration*1000), 0, 0, 0);
}
void Q1QVM_DropClient(client_t *cl)
@ -1677,7 +1675,7 @@ void Q1QVM_DropClient(client_t *cl)
Q_strncpyz(cl->namebuf, cl->name, sizeof(cl->namebuf));
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
VM_Call(q1qvm, GAME_CLIENT_DISCONNECT);
VM_Call(q1qvm, GAME_CLIENT_DISCONNECT, 0, 0, 0);
cl->name = cl->namebuf;
}