1
0
Fork 0
forked from fte/fteqw

Redesigned sound code for greater modularity.

Added support for dp6/dp7 protocols (ents are still broken).
md3 tags should work properly (still suffer from origin-of-parent interpolation bugs)


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1089 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-06-14 04:52:10 +00:00
parent ec2d01d6bf
commit dfd8e1aaed
65 changed files with 2511 additions and 3048 deletions

View file

@ -132,6 +132,7 @@ void Cam_Unlock(int pnum)
void Cam_Lock(int pnum, int playernum)
{
int i;
cam_lastviewtime[pnum] = -1000;
@ -148,6 +149,9 @@ void Cam_Lock(int pnum, int playernum)
}
Sbar_Changed();
for (i = 0; i < MAX_CLIENTS; i++)
CL_NewTranslation(i);
}
trace_t Cam_DoTrace(vec3_t vec1, vec3_t vec2)

View file

@ -1233,19 +1233,32 @@ float CL_LerpEntityFrac(float lerprate, float lerptime)
return f;
}
float CL_EntLerpFactor(int entnum)
{
float f;
if (cl.lerpents[entnum].lerprate<=0)
return 0;
else
f = 1-(cl.time-cl.lerpents[entnum].lerptime)/cl.lerpents[entnum].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
return f;
}
void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
{
entity_state_t *ps;
float *org=NULL, *ang=NULL;
vec3_t axis[3];
vec3_t temp[3];
vec3_t destorg;
float transform[12], parent[12], result[12], old[12], temp[12];
int model = 0; //these two are only initialised because msvc sucks at detecting usage.
int frame = 0;
float *tagorg=NULL;
float *tagaxis;
int frame2 = cl.lerpents[tagent].frame;
float frame2ness;
// ent->keynum = tagent;
@ -1288,12 +1301,51 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
AngleVectors(ang, axis[0], axis[1], axis[2]);
VectorInverse(axis[1]);
if (Mod_GetTag)
Mod_GetTag(cl.model_precache[model], tagnum, frame, &tagorg, &tagaxis);
else
tagaxis = NULL;
if (tagaxis)
frame2ness = CL_EntLerpFactor(tagent);
if (Mod_GetTag && Mod_GetTag(cl.model_precache[model], tagnum, frame, frame2, frame2ness, cl.time - cl.lerpents[tagent].framechange, cl.time - cl.lerpents[tagent].framechange, transform))
{
old[0] = ent->axis[0][0];
old[1] = ent->axis[1][0];
old[2] = ent->axis[2][0];
old[3] = ent->origin[0];
old[4] = ent->axis[0][1];
old[5] = ent->axis[1][1];
old[6] = ent->axis[2][1];
old[7] = ent->origin[1];
old[8] = ent->axis[0][2];
old[9] = ent->axis[1][2];
old[10] = ent->axis[2][2];
old[11] = ent->origin[2];
parent[0] = axis[0][0];
parent[1] = axis[1][0];
parent[2] = axis[2][0];
parent[3] = org[0];
parent[4] = axis[0][1];
parent[5] = axis[1][1];
parent[6] = axis[2][1];
parent[7] = org[1];
parent[8] = axis[0][2];
parent[9] = axis[1][2];
parent[10] = axis[2][2];
parent[11] = org[2];
R_ConcatTransforms((void*)old, (void*)parent, (void*)temp);
R_ConcatTransforms((void*)temp, (void*)transform, (void*)result);
ent->axis[0][0] = result[0];
ent->axis[1][0] = result[1];
ent->axis[2][0] = result[2];
ent->origin[0] = result[3];
ent->axis[0][1] = result[4];
ent->axis[1][1] = result[5];
ent->axis[2][1] = result[6];
ent->origin[1] = result[7];
ent->axis[0][2] = result[8];
ent->axis[1][2] = result[9];
ent->axis[2][2] = result[10];
ent->origin[2] = result[11];
/*
VectorAdd(org, ent->origin, destorg);
VectorMA(destorg, tagorg[0], ent->axis[0], destorg);
VectorMA(destorg, tagorg[1], ent->axis[1], destorg);
@ -1303,14 +1355,13 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
// Con_Printf("Found tag %i\n", cl.lerpents[tagent].tagindex);
Matrix3_Multiply(axis, ent->axis, temp); //the ent->axis here is the result of the parent's transforms
Matrix3_Multiply((void*)tagaxis, temp, ent->axis);
*/
}
else //hrm.
{
memcpy(ent->axis, axis, sizeof(temp));
VectorCopy(org, ent->origin);
}
}
// if (org)
// VectorAdd(ent->origin, org, ent->origin);
@ -1615,6 +1666,7 @@ void CL_LinkPacketEntities (void)
{ //hmm. hexen spider gibs...
dl = CL_AllocDlight (s1->number);
VectorCopy (ent->origin, dl->origin);
dl->origin[2] += 1;
dl->radius = 200;
dl->die = (float)cl.time;
dl->color[0] = 0.20;
@ -2223,15 +2275,15 @@ void CL_LinkPlayers (void)
if ((!r_flashblend.value || j != cl.playernum[0]) && r_powerupglow.value)
{
if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 3)->noppl = (j != cl.playernum[0]);
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (r_lightflicker.value?(rand()&31):0), 0.1, 3)->noppl = (j != cl.playernum[0]);
else if (state->effects & EF_BLUE)
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 1)->noppl = (j != cl.playernum[0]);
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (r_lightflicker.value?(rand()&31):0), 0.1, 1)->noppl = (j != cl.playernum[0]);
else if (state->effects & EF_RED)
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 2)->noppl = (j != cl.playernum[0]);
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (r_lightflicker.value?(rand()&31):0), 0.1, 2)->noppl = (j != cl.playernum[0]);
else if (state->effects & EF_BRIGHTLIGHT)
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2] + 16, 400 + (rand()&31), 0.1, 0)->noppl = (j != cl.playernum[0]);
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2] + 16, 400 + (r_lightflicker.value?(rand()&31):0), 0.1, 0)->noppl = (j != cl.playernum[0]);
else if (state->effects & EF_DIMLIGHT)
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 0)->noppl = (j != cl.playernum[0]);
CL_NewDlight (j+1, state->origin[0], state->origin[1], state->origin[2], 200 + (r_lightflicker.value?(rand()&31):0), 0.1, 0)->noppl = (j != cl.playernum[0]);
}
if (state->modelindex < 1)
@ -2297,12 +2349,12 @@ void CL_LinkPlayers (void)
{
if (j == cl.playernum[pnum])
{
if (cl.spectator)
/* if (cl.spectator)
{
cl_numvisedicts--;
continue;
}
angles[0] = -1*cl.viewangles[pnum][0] / 3;
*/ angles[0] = -1*cl.viewangles[pnum][0] / 3;
angles[1] = cl.viewangles[pnum][1];
angles[2] = cl.viewangles[pnum][2];
ent->origin[0] = cl.simorg[pnum][0];

View file

@ -543,7 +543,7 @@ CL_FinishMove
*/
void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum)
{
int ms, i;
int i;
int bits;
//
@ -793,15 +793,10 @@ float CL_FilterTime (double time, float wantfps) //now returns the extra time no
{
fpscap = cls.maxfps ? max (30.0, cls.maxfps) : 0x7fff;
if (wantfps>0)
fps = bound (10.0, wantfps, fpscap);
if (wantfps < 1)
fps = fpscap;
else
{
// if (com_serveractive)
// fps = fpscap;
// else
fps = bound (30.0, rate.value/80.0, fpscap);
}
fps = bound (10.0, wantfps, fpscap);
}
if (time < 1000 / fps)
@ -882,6 +877,7 @@ int CL_RemoveClientCommands(char *command)
if (!clientcmdlist)
return removed;
}
first = clientcmdlist;
while(first->next)
{
if (!strcmp(first->next->command, command))
@ -1011,8 +1007,6 @@ void CL_SendCmd (float frametime)
int lost;
int seq_hash;
int firstsize;
int extramsec;
vec3_t v;
float wantfps;
qbyte lightlev;

View file

@ -1005,7 +1005,7 @@ void CL_User_f (void)
int i;
#ifndef CLIENTONLY
if (isDedicated)
if (sv.state)
{
SV_User_f();
return;
@ -1964,7 +1964,7 @@ void CLNQ_ConnectionlessPacket(void)
Con_TPrintf (TLC_DUPCONNECTION);
return;
}
net_from.port = htons(MSG_ReadLong());
net_from.port = htons((short)MSG_ReadLong());
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.qport);
cls.netchan.isnqprotocol = true;
cls.netchan.compress = 0;
@ -2941,7 +2941,7 @@ void Host_Init (quakeparms_t *parms)
Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
host_hunklevel = Hunk_LowMark ();
R_SetRenderer(0);//set the renderer stuff to 'none'...
R_SetRenderer(-1);//set the renderer stuff to unset...
host_initialized = true;
@ -2977,15 +2977,17 @@ void Host_Init (quakeparms_t *parms)
if ((i = COM_CheckParm ("-bpp")))
Cvar_Set(Cvar_FindVar("vid_bpp"), com_argv[i+1]);
if (!qrenderer && *vid_renderer.string)
if (qrenderer<=0 && *vid_renderer.string)
{
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
}
if (qrenderer<=0)
{
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
}
if (!qrenderer)
{
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
}
if (qrenderer == QR_NONE)
Con_Printf("Use the setrenderer command to use a gui\n");
UI_Init();

View file

@ -147,3 +147,5 @@ qboolean Master_GetSortDescending(void);
int Master_NumSorted(void);
void Master_ClearMasks(void);
serverinfo_t *Master_SortedServer(int idx);
void Master_SetMaskString(qboolean or, hostcachekey_t field, char *param, slist_test_t testop);
void Master_SetMaskInteger(qboolean or, hostcachekey_t field, int param, slist_test_t testop);

View file

@ -1222,7 +1222,7 @@ void CL_ParseServerData (void)
if (cls.fteprotocolextensions & PEXT_FLOATCOORDS)
{
sizeofcoord = 4;
sizeofangle = 1;
sizeofangle = 2;
}
else
{
@ -2386,6 +2386,7 @@ void CL_NewTranslation (int slot)
char *s;
player_info_t *player;
int local;
if (slot >= MAX_CLIENTS)
Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS");
@ -2411,7 +2412,15 @@ void CL_NewTranslation (int slot)
bottom = player->bottomcolor;
if (!cl.splitclients && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(player->team, cl.players[cl.playernum[0]].team))
if (cl.teamplay && cl.spectator)
{
local = Cam_TrackNum(0);
if (local < 0)
local = cl.playernum[0];
}
else
local = cl.playernum[0];
if (cl.teamplay && !strcmp(player->team, cl.players[local].team))
{
if (cl_teamtopcolor>=0)
top = cl_teamtopcolor;

View file

@ -106,7 +106,7 @@ extern cvar_t scr_printspeed;
extern cvar_t scr_allowsnap;
extern cvar_t scr_sshot_type;
extern cvar_t crosshair;
extern cvar_t con_height;
extern cvar_t scr_consize;
qboolean scr_initialized; // ready to draw
@ -1259,7 +1259,7 @@ void SCR_SetUpToDrawConsole (void)
}
else if (key_dest == key_console || scr_chatmode)
{
scr_conlines = vid.height*con_height.value/100; // half screen
scr_conlines = vid.height*scr_consize.value; // half screen
if (scr_conlines < 32)
scr_conlines = 32; //prevent total loss of console.
else if (scr_conlines>vid.height)

View file

@ -344,6 +344,7 @@ void CL_ParseBeam (int tent)
{
m = Mod_ForName("progs/beam.mdl", false); //remember to precache!
btype = P_FindParticleType("te_beam");
etype = P_FindParticleType("te_beam_end");
}
else
{

View file

@ -368,50 +368,37 @@ int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagnam
float *ang;
float *org;
float *org1;
float *ang1;
float *org2;
float *ang2;
float l1;
float tr[12];
qboolean found;
org = (float*)out;
ang = ((float*)out+3);
l1 = 1-l2;
if (Mod_GetTag)
{
if (Mod_TagNumForName)
tagnum = Mod_TagNumForName(model, tagname);
else
tagnum = 0;
Mod_GetTag(model, tagnum, f1, &org1, &ang1);
Mod_GetTag(model, tagnum, f2, &org2, &ang2);
found = Mod_GetTag(model, tagnum, f1, f2, l2, 0, 0, tr);
}
else
found = false;
if (found)
{
ang1=ang2=NULL;
org1=org2=NULL; //msvc was warning about this not being present.
}
if (ang1 && ang2)
{
org[0] = org1[0]*l1 + org2[0]*l2;
org[1] = org1[1]*l1 + org2[1]*l2;
org[2] = org1[2]*l1 + org2[2]*l2;
ang[0] = ang1[0]*l1 + ang2[0]*l2;
ang[1] = ang1[1]*l1 + ang2[1]*l2;
ang[2] = ang1[2]*l1 + ang2[2]*l2;
ang[3] = ang1[3]*l1 + ang2[3]*l2;
ang[4] = ang1[4]*l1 + ang2[4]*l2;
ang[5] = ang1[5]*l1 + ang2[5]*l2;
ang[6] = ang1[6]*l1 + ang2[6]*l2;
ang[7] = ang1[7]*l1 + ang2[7]*l2;
ang[8] = ang1[8]*l1 + ang2[8]*l2;
ang[0] = tr[0];
ang[1] = tr[1];
ang[2] = tr[2];
org[0] = tr[3];
ang[3] = tr[4];
ang[4] = tr[5];
ang[5] = tr[6];
org[1] = tr[7];
ang[6] = tr[8];
ang[7] = tr[9];
ang[8] = tr[10];
org[2] = tr[11];
return true;
}

View file

@ -384,9 +384,8 @@ typedef struct downloadlist_s {
typedef struct {
float lerptime;
#ifdef HALFLIFEMODELS
float framechange; //marks time of last frame change - for halflife model sequencing.
#endif
float oldframechange;
float lerprate; //inverse rate...
vec3_t origin;
vec3_t angles;
@ -787,6 +786,8 @@ qboolean CSQC_DrawView(void);
void CSQC_Shutdown(void);
qboolean CSQC_StuffCmd(char *cmd);
qboolean CSQC_CenterPrint(char *cmd);
qboolean CSQC_ConsoleCommand(char *cmd);
qboolean CSQC_KeyPress(int key, qboolean down);
#endif
//

View file

@ -68,6 +68,7 @@ cvar_t con_numnotifylines = {"con_notifylines","4"}; //max lines to show
cvar_t con_notifytime = {"con_notifytime","3"}; //seconds
cvar_t con_centernotify = {"con_centernotify", "0"};
cvar_t con_displaypossabilities = {"con_displaypossabilities", "1"};
cvar_t cl_chatmode = {"cl_chatmode", "2"};
#define NUM_CON_TIMES 24
float con_times[NUM_CON_TIMES]; // realtime time the line was generated
@ -511,6 +512,7 @@ void Con_Init (void)
Cvar_Register (&con_centernotify, "Console controls");
Cvar_Register (&con_numnotifylines, "Console controls");
Cvar_Register (&con_displaypossabilities, "Console controls");
Cvar_Register (&cl_chatmode, "Console controls");
Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
Cmd_AddCommand ("togglechat", Con_ToggleChat_f);

View file

@ -212,6 +212,11 @@ int mouse_x, mouse_y;
void ResetFrameBuffers(void);
#endif
#ifdef RGLQUAKE
extern int glwidth;
extern int glheight;
#endif
void Sys_SendKeyEvents(void)
{
SDL_Event event;

View file

@ -53,6 +53,7 @@ qboolean keydown[256];
qboolean deltaused[256][KEY_MODIFIERSTATES];
extern cvar_t con_displaypossabilities;
extern cvar_t cl_chatmode;
static int KeyModifier (qboolean shift, qboolean alt, qboolean ctrl)
{
@ -354,7 +355,7 @@ void Con_ExecuteLine(console_t *con, char *line)
con_commandmatch=1;
if (line[0] == '\\' || line[0] == '/')
Cbuf_AddText (line+1, RESTRICT_LOCAL); // skip the >
else if (Cmd_IsCommand(line))
else if (cl_chatmode.value && Cmd_IsCommand(line))
Cbuf_AddText (line, RESTRICT_LOCAL); // valid command
#ifdef Q2CLIENT
else if (cls.protocol == CP_QUAKE2)
@ -362,7 +363,7 @@ void Con_ExecuteLine(console_t *con, char *line)
#endif
else
{ // convert to a chat message
if (cls.state >= ca_connected && (strncmp(line, "say ", 4)))
if (cl_chatmode.value == 1 || ((cls.state >= ca_connected && cl_chatmode.value == 2) && (strncmp(line, "say ", 4))))
{
if (keydown[K_CTRL])
Cbuf_AddText ("say_team ", RESTRICT_LOCAL);

View file

@ -148,50 +148,59 @@ void M_DrawTextBox (int x, int y, int width, int lines)
// draw left side
cx = x;
cy = y;
p = Draw_CachePic ("gfx/box_tl.lmp");
M_DrawTransPic (cx, cy, p);
p = Draw_CachePic ("gfx/box_ml.lmp");
for (n = 0; n < lines; n++)
{
cy += 8;
p = Draw_SafeCachePic ("gfx/box_tl.lmp");
if (p)
M_DrawTransPic (cx, cy, p);
}
p = Draw_CachePic ("gfx/box_bl.lmp");
M_DrawTransPic (cx, cy+8, p);
p = Draw_SafeCachePic ("gfx/box_ml.lmp");
if (p)
for (n = 0; n < lines; n++)
{
cy += 8;
M_DrawTransPic (cx, cy, p);
}
p = Draw_SafeCachePic ("gfx/box_bl.lmp");
if (p)
M_DrawTransPic (cx, cy+8, p);
// draw middle
cx += 8;
while (width > 0)
{
cy = y;
p = Draw_CachePic ("gfx/box_tm.lmp");
M_DrawTransPic (cx, cy, p);
p = Draw_CachePic ("gfx/box_mm.lmp");
for (n = 0; n < lines; n++)
{
cy += 8;
if (n == 1)
p = Draw_CachePic ("gfx/box_mm2.lmp");
p = Draw_SafeCachePic ("gfx/box_tm.lmp");
if (p)
M_DrawTransPic (cx, cy, p);
}
p = Draw_CachePic ("gfx/box_bm.lmp");
M_DrawTransPic (cx, cy+8, p);
p = Draw_SafeCachePic ("gfx/box_mm.lmp");
if (p)
for (n = 0; n < lines; n++)
{
cy += 8;
if (n == 1)
p = Draw_CachePic ("gfx/box_mm2.lmp");
M_DrawTransPic (cx, cy, p);
}
p = Draw_SafeCachePic ("gfx/box_bm.lmp");
if (p)
M_DrawTransPic (cx, cy+8, p);
width -= 2;
cx += 16;
}
// draw right side
cy = y;
p = Draw_CachePic ("gfx/box_tr.lmp");
M_DrawTransPic (cx, cy, p);
p = Draw_CachePic ("gfx/box_mr.lmp");
for (n = 0; n < lines; n++)
{
cy += 8;
p = Draw_SafeCachePic ("gfx/box_tr.lmp");
if (p)
M_DrawTransPic (cx, cy, p);
}
p = Draw_CachePic ("gfx/box_br.lmp");
M_DrawTransPic (cx, cy+8, p);
p = Draw_SafeCachePic ("gfx/box_mr.lmp");
if (p)
for (n = 0; n < lines; n++)
{
cy += 8;
M_DrawTransPic (cx, cy, p);
}
p = Draw_SafeCachePic ("gfx/box_br.lmp");
if (p)
M_DrawTransPic (cx, cy+8, p);
}
//=============================================================================

View file

@ -103,7 +103,7 @@ extern qbyte *FNC(Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *mode
extern void FNC(Mod_NowLoadExternal) (void);
extern void FNC(Mod_Think) (void);
extern void (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, float **org, float **axis);
extern qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
extern int (*Mod_TagNumForName) (struct model_s *model, char *name);
#undef FNC

View file

@ -1266,7 +1266,7 @@ void PF_cs_sound(progfuncs_t *prinst, struct globalvars_s *pr_globals)
sfx_t *sfx;
entity = G_EDICT(prinst, OFS_PARM0);
entity = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
channel = G_FLOAT(OFS_PARM1);
sample = PR_GetStringOfs(prinst, OFS_PARM2);
volume = G_FLOAT(OFS_PARM3) * 255;
@ -1912,6 +1912,11 @@ void CSQC_ParseEntities(void)
packetsize = MSG_ReadShort();
packetstart = msg_readcount;
}
else
{
packetsize = 0;
packetstart = 0;
}
ent = csqcent[entnum];
if (!ent)

View file

@ -1283,7 +1283,8 @@ void P_NewServer(void)
Con_Printf("Couldn't find particle description, using spikeset\n");
Cbuf_AddText(particle_set_spikeset, RESTRICT_SERVER);
}
#if defined(_DEBUG) && defined(WIN32) //expand the particles cfg into a C style quoted string, and copy to clipboard so I can paste it in.
/*
#if defined(_DEBUG) && defined(_WIN32) //expand the particles cfg into a C style quoted string, and copy to clipboard so I can paste it in.
{
char *TL_ExpandToCString(char *in);
extern HWND mainwindow;
@ -1321,6 +1322,7 @@ void P_NewServer(void)
CloseClipboard();
}
#endif
*/
}
}

View file

@ -223,7 +223,7 @@ void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj);
#if defined(RGLQUAKE)
void GLMod_Init (void);
void GLMod_GetTag(struct model_s *model, int tagnum, int frame, float **org, float **axis);
qboolean GLMod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result);
int GLMod_TagNumForName(struct model_s *model, char *name);
void GLMod_ClearAll (void);
struct model_s *GLMod_ForName (char *name, qboolean crash);

View file

@ -162,7 +162,7 @@ cvar_t gl_lateswap = {"gl_lateswap", "0"};
cvar_t scr_sshot_type = {"scr_sshot_type", "jpg"};
cvar_t con_height = {"con_height", "50"};
cvar_t scr_consize = {"scr_consize", "0.5"};
cvar_t scr_viewsize = {"viewsize","100", NULL, CVAR_ARCHIVE};
cvar_t scr_fov = {"fov","90", NULL, CVAR_ARCHIVE}; // 10 - 170
cvar_t scr_conspeed = {"scr_conspeed","300"};
@ -491,7 +491,7 @@ void Renderer_Init(void)
Cvar_Register (&scr_centertime, SCREENOPTIONS);
Cvar_Register (&scr_printspeed, SCREENOPTIONS);
Cvar_Register (&scr_allowsnap, SCREENOPTIONS);
Cvar_Register (&con_height, SCREENOPTIONS);
Cvar_Register (&scr_consize, SCREENOPTIONS);
Cvar_Register(&r_bloodstains, GRAPHICALNICETIES);
@ -605,7 +605,7 @@ struct mleaf_s *(*Mod_PointInLeaf) (float *p, struct model_s *model);
qbyte *(*Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void);
void (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, float **org, float **axis);
qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
int (*Mod_TagNumForName) (struct model_s *model, char *name);
@ -626,7 +626,7 @@ void (*VID_SetWindowCaption) (char *msg);
void (*SCR_UpdateScreen) (void);
r_qrenderer_t qrenderer=QR_NONE;
r_qrenderer_t qrenderer=-1;
char *q_renderername = "Non-Selected renderer";
@ -695,7 +695,7 @@ struct {
qbyte *(*Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void);
void (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, float **org, float **axis);
qboolean(*Mod_GetTag) (model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result);
int (*Mod_TagNumForName) (struct model_s *model, char *name);
@ -1254,6 +1254,9 @@ void M_Menu_Video_f (void)
void R_SetRenderer(int wanted)
{
qrenderer = wanted;
if (wanted<0)
wanted=QR_NONE;
q_renderername = rendererinfo[wanted].name[0];
Draw_PicFromWad = rendererinfo[wanted].Draw_PicFromWad;
@ -1333,8 +1336,6 @@ void R_SetRenderer(int wanted)
SCR_UpdateScreen = rendererinfo[wanted].SCR_UpdateScreen;
qrenderer = wanted;
}
static qbyte default_quakepal[768] =
@ -1845,7 +1846,7 @@ void R_SetRenderer_f (void)
}
else if (!stricmp(Cmd_Argv(1), "dedicated"))
{
Cvar_Set(&vid_renderer, "sv");
Cvar_Set(&vid_renderer, "dedicated");
R_RestartRenderer_f();
}
else if (!stricmp(Cmd_Argv(1), "SW") || !stricmp(Cmd_Argv(1), "Software"))

View file

@ -32,18 +32,82 @@
#include "quakedef.h"
static int snd_inited;
static snd_pcm_uframes_t buffer_size;
static const char *pcmname = NULL;
static snd_pcm_t *pcm;
soundcardinfo_t *sndcardinfo;
qboolean snd_firsttime;
int SNDDMA_Init (soundcardinfo_t *sc)
static unsigned int ALSA_GetDMAPos (soundcardinfo_t *sc)
{
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset;
snd_pcm_uframes_t nframes = sc->sn.samples / sc->sn.numchannels;
snd_pcm_avail_update (sc->handle);
snd_pcm_mmap_begin (sc->handle, &areas, &offset, &nframes);
offset *= sc->sn.numchannels;
nframes *= sc->sn.numchannels;
sc->sn.samplepos = offset;
sc->sn.buffer = areas->addr;
return sc->sn.samplepos;
}
static void ALSA_Shutdown (soundcardinfo_t *sc)
{
snd_pcm_close (sc->handle);
}
static void ALSA_Submit (soundcardinfo_t *sc)
{
extern int soundtime;
int state;
int count = sc->paintedtime - soundtime;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t nframes;
snd_pcm_uframes_t offset;
nframes = count / sc->sn.numchannels;
snd_pcm_avail_update (sc->handle);
snd_pcm_mmap_begin (sc->handle, &areas, &offset, &nframes);
state = snd_pcm_state (sc->handle);
switch (state) {
case SND_PCM_STATE_PREPARED:
snd_pcm_mmap_commit (sc->handle, offset, nframes);
snd_pcm_start (sc->handle);
break;
case SND_PCM_STATE_RUNNING:
snd_pcm_mmap_commit (sc->handle, offset, nframes);
break;
default:
break;
}
}
static void *ALSA_LockBuffer(soundcardinfo_t *sc)
{
return sc->sn.buffer;
}
static void ALSA_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
{
}
static void ALSA_SetUnderWater(soundcardinfo_t *sc, qboolean underwater)
{
}
void S_UpdateCapture(void)
{
}
static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum)
{
snd_pcm_t *pcm;
snd_pcm_uframes_t buffer_size;
soundcardinfo_t *ec; //existing card
char *pcmname;
cvar_t *devname;
int err, i;
int bps = -1, stereo = -1;
unsigned int rate = 0;
@ -54,11 +118,19 @@ int SNDDMA_Init (soundcardinfo_t *sc)
snd_pcm_hw_params_alloca (&hw);
snd_pcm_sw_params_alloca (&sw);
// COMMANDLINEOPTION: Linux ALSA Sound: -sndpcm <devicename> selects which pcm device to us, default is "default"
if ((i=COM_CheckParm("-sndpcm"))!=0)
pcmname=com_argv[i+1];
if (!pcmname)
pcmname = "default";
devname = Cvar_Get(va("snd_alsadevice%i", cardnum+1), cardnum==0?"default":"", 0, "Sound controls");
pcmname = devname->string;
if (!*pcmname)
return 2;
for (ec = sndcardinfo; ec; ec = ec->next)
if (!strcmp(ec->name, pcmname))
break;
if (ec)
return 2; //no more
sc->inactive_sound = true; //linux sound devices always play sound, even when we're not the active app...
// COMMANDLINEOPTION: Linux ALSA Sound: -sndbits <number> sets sound precision to 8 or 16 bit (email me if you want others added)
if ((i=COM_CheckParm("-sndbits")) != 0)
@ -104,8 +176,7 @@ int SNDDMA_Init (soundcardinfo_t *sc)
goto error;
}
err = snd_pcm_hw_params_set_access (pcm, hw,
SND_PCM_ACCESS_MMAP_INTERLEAVED);
err = snd_pcm_hw_params_set_access (pcm, hw, SND_PCM_ACCESS_MMAP_INTERLEAVED);
if (0 > err) {
Con_Printf ("ALSA: Failure to set noninterleaved PCM access. %s\n"
"Note: Interleaved is not supported\n",
@ -115,12 +186,10 @@ int SNDDMA_Init (soundcardinfo_t *sc)
switch (bps) {
case -1:
err = snd_pcm_hw_params_set_format (pcm, hw,
SND_PCM_FORMAT_S16);
err = snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_S16);
if (0 <= err) {
bps = 16;
} else if (0 <= (err = snd_pcm_hw_params_set_format (pcm, hw,
SND_PCM_FORMAT_U8))) {
} else if (0 <= (err = snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_U8))) {
bps = 8;
} else {
Con_Printf ("ALSA: no useable formats. %s\n",
@ -149,8 +218,7 @@ int SNDDMA_Init (soundcardinfo_t *sc)
err = snd_pcm_hw_params_set_channels (pcm, hw, 2);
if (0 <= err) {
stereo = 1;
} else if (0 <= (err = snd_pcm_hw_params_set_channels (pcm, hw,
1))) {
} else if (0 <= (err = snd_pcm_hw_params_set_channels (pcm, hw, 1))) {
stereo = 0;
} else {
Con_Printf ("ALSA: no usable channels. %s\n",
@ -261,11 +329,18 @@ int SNDDMA_Init (soundcardinfo_t *sc)
goto error;
}
sc->Lock = ALSA_LockBuffer;
sc->Unlock = ALSA_UnlockBuffer;
sc->SetWaterDistortion = ALSA_SetUnderWater;
sc->Submit = ALSA_Submit;
sc->Shutdown = ALSA_Shutdown;
sc->GetDMAPos = ALSA_GetDMAPos;
sc->sn.samples = buffer_size * sc->sn.numchannels; // mono samples in buffer
sc->sn.speed = rate;
SNDDMA_GetDMAPos (sc); // sets shm->buffer
sc->handle = pcm;
ALSA_GetDMAPos (sc); // sets shm->buffer
snd_inited = 1;
return true;
error:
@ -273,80 +348,6 @@ error:
return false;
}
int SNDDMA_GetDMAPos (soundcardinfo_t *sc)
{
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset;
snd_pcm_uframes_t nframes = sc->sn.samples / sc->sn.numchannels;
int (*pALSA_InitCard) (soundcardinfo_t *sc, int cardnum) = &ALSA_InitCard;
if (!snd_inited)
return 0;
snd_pcm_avail_update (pcm);
snd_pcm_mmap_begin (pcm, &areas, &offset, &nframes);
offset *= sc->sn.numchannels;
nframes *= sc->sn.numchannels;
sc->sn.samplepos = offset;
sc->sn.buffer = areas->addr;
return sc->sn.samplepos;
}
void SNDDMA_Shutdown (soundcardinfo_t *sc)
{
if (snd_inited) {
snd_pcm_close (pcm);
snd_inited = 0;
}
}
/*
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
*/
void SNDDMA_Submit (soundcardinfo_t *sc)
{
extern int soundtime;
int state;
int count = sc->paintedtime - soundtime;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t nframes;
snd_pcm_uframes_t offset;
nframes = count / sc->sn.numchannels;
snd_pcm_avail_update (pcm);
snd_pcm_mmap_begin (pcm, &areas, &offset, &nframes);
state = snd_pcm_state (pcm);
switch (state) {
case SND_PCM_STATE_PREPARED:
snd_pcm_mmap_commit (pcm, offset, nframes);
snd_pcm_start (pcm);
break;
case SND_PCM_STATE_RUNNING:
snd_pcm_mmap_commit (pcm, offset, nframes);
break;
default:
break;
}
}
void *S_LockBuffer(soundcardinfo_t *sc)
{
return sc->sn.buffer;
}
void S_UnlockBuffer(soundcardinfo_t *sc)
{
}
void SNDDMA_SetUnderWater(qboolean underwater)
{
}
void S_UpdateCapture(void)
{
}

View file

@ -8,7 +8,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -21,12 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#ifndef __CYGWIN__
#ifdef _WIN32
#include "winquake.h"
#endif
void S_Play(void);
void S_PlayVol(void);
void S_SoundList(void);
@ -40,14 +34,13 @@ void S_UpdateCard(soundcardinfo_t *sc);
// Internal sound data & structures
// =======================================================================
soundcardinfo_t *sndcardinfo; //the master card.
int snd_blocked = 0;
static qboolean snd_ambient = 1;
qboolean snd_initialized = false;
int snd_speed;
qboolean snd_multipledevices = false;
vec3_t listener_origin;
vec3_t listener_forward;
vec3_t listener_right;
@ -89,6 +82,8 @@ cvar_t snd_playersoundvolume = {"snd_localvolume", "1"}; //sugested by crunch
cvar_t snd_capture = {"snd_capture", "0"};
cvar_t snd_usemultipledevices = {"snd_multipledevices", "0"};
// ====================================================================
// User-setable variables
@ -145,6 +140,61 @@ void S_SoundInfo_f(void)
}
sounddriver pDSOUND_InitCard;
sounddriver pALSA_InitCard;
sounddriver pOSS_InitCard;
sounddriver pSDL_InitCard;
sounddriver pWAV_InitCard;
sounddriver *drivers[] = {
&pDSOUND_InitCard,
&pALSA_InitCard,
&pOSS_InitCard,
&pSDL_InitCard,
&pWAV_InitCard,
NULL
};
static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum)
{
sounddriver *sd;
int st = 0;
memset(sc, 0, sizeof(*sc));
if (snd_khz.value >= 45)
sc->sn.speed = 48000;
else if (snd_khz.value >= 30) //set by a slider
sc->sn.speed = 44100;
else if (snd_khz.value >= 20)
sc->sn.speed = 22050;
else
sc->sn.speed = 11025;
sd = drivers[*drivernum];
if (!sd)
return 2; //no more cards.
if (!*sd) //driver not loaded
st = 2;
else
st = (**sd)(sc, *cardnum);
if (st == 1) //worked
{
*cardnum += 1; //use the next card next time
return st;
}
else if (st == 0) //failed, try the next card with this driver.
{
*cardnum += 1;
return SNDDMA_Init(sc, cardnum, drivernum);
}
else //card number wasn't valid, try the first card of the next driver
{
*cardnum = 0;
*drivernum += 1;
return SNDDMA_Init(sc, cardnum, drivernum);
}
}
/*
================
S_Startup
@ -153,6 +203,7 @@ S_Startup
void S_Startup (void)
{
int cardnum, drivernum;
int warningmessage=0;
int rc;
soundcardinfo_t *sc;
@ -167,28 +218,14 @@ void S_Startup (void)
if (!fakedma)
{
#if defined(_WIN32) && !defined(NODIRECTX)
extern int aimedforguid; //restart directsound guid aims.
aimedforguid=0;
#endif
for(;;)
for(cardnum = 0, drivernum = 0;;)
{
sc = Z_Malloc(sizeof(soundcardinfo_t));
if (snd_khz.value >= 45)
sc->sn.speed = 48000;
else if (snd_khz.value >= 30) //set by a slider
sc->sn.speed = 44100;
else if (snd_khz.value >= 20)
sc->sn.speed = 22050;
else
sc->sn.speed = 11025;
rc = SNDDMA_Init(sc);
rc = SNDDMA_Init(sc, &cardnum, &drivernum);
if (!rc) //error stop
{
#ifndef _WIN32
Con_Printf("S_Startup: SNDDMA_Init failed.\n");
#endif
Z_Free(sc);
break;
}
@ -255,7 +292,7 @@ void S_Startup (void)
warningmessage = true;
}
Z_Free(sc);
Z_Free(sc);
continue;
}
}
@ -264,35 +301,44 @@ void S_Startup (void)
sc->next = sndcardinfo;
sndcardinfo = sc;
if (!snd_usemultipledevices.value)
break;
}
}
sound_started = 1;
}
void SNDDMA_SetUnderWater(qboolean underwater)
{
soundcardinfo_t *sc;
for (sc = sndcardinfo; sc; sc=sc->next)
sc->SetWaterDistortion(sc, underwater);
}
void S_Restart_f (void)
{
extern qboolean snd_firsttime;
{
Cache_Flush();//forget the old sounds.
if (COM_CheckParm("-nosound"))
return;
S_StopAllSounds (true);
S_StopAllSounds (true);
S_Shutdown();
sound_started = 0;
snd_firsttime = true;
S_Startup();
ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav");
ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
S_StopAllSounds (true);
}
void S_Control_f (void)
{
{
int i;
char *command;
if (Cmd_Argc() < 2)
@ -304,7 +350,7 @@ void S_Control_f (void)
{
Cache_Flush();//forget the old sounds.
S_StopAllSounds (true);
S_StopAllSounds (true);
S_Shutdown();
sound_started = 0;
@ -313,29 +359,29 @@ void S_Control_f (void)
{
if (!Q_strcasecmp(Cmd_Argv (2), "off"))
{
if (snd_multipledevices)
if (snd_usemultipledevices.value)
{
snd_multipledevices = false;
S_Restart_f();
}
Cvar_SetValue(&snd_usemultipledevices, 0);
S_Restart_f();
}
}
else if (!snd_multipledevices)
else if (!snd_usemultipledevices.value)
{
snd_multipledevices = true;
Cvar_SetValue(&snd_usemultipledevices, 1);
S_Restart_f();
}
return;
}
if (!Q_strcasecmp(command, "single"))
{
snd_multipledevices = false;
Cvar_SetValue(&snd_usemultipledevices, 0);
S_Restart_f();
return;
}
if (!Q_strcasecmp(command, "rate") || !Q_strcasecmp(command, "speed"))
{
Cvar_SetValue(&snd_khz, atof(Cmd_Argv (2))/1000);
Cvar_SetValue(&snd_khz, atof(Cmd_Argv (2))/1000);
S_Restart_f();
return;
}
@ -449,12 +495,6 @@ void S_Init (void)
// if (COM_CheckParm("-simsound"))
// fakedma = true;
if (COM_CheckParm ("-nomultipledevices") || COM_CheckParm ("-singlesound"))
snd_multipledevices = false;
if (COM_CheckParm ("-multisound"))
snd_multipledevices = true;
p = COM_CheckParm ("-soundspeed");
if (p)
{
@ -462,7 +502,7 @@ void S_Init (void)
Cvar_SetValue(&snd_khz, atof(com_argv[p+1])/1000);
else
Sys_Error ("S_Init: you must specify a speed in KB after -soundspeed");
}
}
Cmd_AddCommand("play", S_Play);
@ -496,6 +536,15 @@ void S_Init (void)
Cvar_Register(&snd_inactive, "Sound controls");
Cvar_Register(&snd_playersoundvolume, "Sound controls");
Cvar_Register(&snd_usemultipledevices, "Sound controls");
if (COM_CheckParm ("-nomultipledevices") || COM_CheckParm ("-singlesound"))
Cvar_SetValue(&snd_usemultipledevices, 0);
if (COM_CheckParm ("-multisound"))
Cvar_SetValue(&snd_usemultipledevices, 1);
if (host_parms.memsize < 0x800000)
{
@ -559,12 +608,12 @@ void S_ShutdownCard(soundcardinfo_t *sc)
aimedforguid = 0;
#endif
if (!fakedma)
{
SNDDMA_Shutdown(sc);
}
{
sc->Shutdown(sc);
}
}
void S_Shutdown(void)
{
{
soundcardinfo_t *sc, *next;
for (sc = sndcardinfo; sc; sc=next)
{
@ -608,12 +657,12 @@ sfx_t *S_FindName (char *name)
if (num_sfx == MAX_SFX)
Sys_Error ("S_FindName: out of sfx_t");
sfx = &known_sfx[i];
strcpy (sfx->name, name);
num_sfx++;
return sfx;
}
@ -627,7 +676,7 @@ S_TouchSound
void S_TouchSound (char *name)
{
sfx_t *sfx;
if (!sound_started)
return;
@ -649,11 +698,11 @@ sfx_t *S_PrecacheSound (char *name)
return NULL;
sfx = S_FindName (name);
// cache it in
if (precache.value &&sndcardinfo)
S_LoadSound (sfx);
return sfx;
}
@ -701,8 +750,8 @@ channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel)
if (sc->channel[first_to_die].sfx)
sc->channel[first_to_die].sfx = NULL;
return &sc->channel[first_to_die];
}
return &sc->channel[first_to_die];
}
/*
=================
@ -732,9 +781,9 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
// calculate stereo seperation and distance attenuation
snd = ch->sfx;
VectorSubtract(ch->origin, listener_origin, source_vec);
dist = VectorNormalize(source_vec) * ch->dist_mult;
dotright = DotProduct(listener_right, source_vec);
dotforward = DotProduct(listener_forward, source_vec);
dotup = DotProduct(listener_up, source_vec);
@ -778,7 +827,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
target_chan = SND_PickChannel(sc, entnum, entchannel);
if (!target_chan)
return;
// spatialize
memset (target_chan, 0, sizeof(*target_chan));
if (!origin)
@ -809,7 +858,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
target_chan->pos = startpos;
target_chan->end = sc->paintedtime + scache->length;
target_chan->looping = false;
// if an identical sound has also been started this frame, offset the pos
// a bit to keep it from just making the first one louder
check = &sc->channel[NUM_AMBIENTS];
@ -917,12 +966,14 @@ void S_StopAllSoundsC (void)
void S_ClearBuffer (soundcardinfo_t *sc)
{
void *buffer;
int clear;
#if defined(_WIN32) && !defined(NODIRECTX)
if (!sound_started || (!sc->sn.buffer && !sc->pDSBuf))
#else
//#if defined(_WIN32) && !defined(NODIRECTX)
// if (!sound_started || (!sc->sn.buffer && !sc->pDSBuf))
//#else
if (!sound_started || !sc->sn.buffer)
#endif
//#endif
return;
if (sc->sn.samplebits == 8)
@ -930,6 +981,13 @@ void S_ClearBuffer (soundcardinfo_t *sc)
else
clear = 0;
buffer = sc->Lock(sc);
if (buffer)
{
Q_memset(sc->sn.buffer, clear, sc->sn.samples * sc->sn.samplebits/8);
sc->Unlock(sc, buffer);
}
/*
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
{
@ -960,13 +1018,14 @@ void S_ClearBuffer (soundcardinfo_t *sc)
Q_memset(pData, clear, sc->sn.samples * sc->sn.samplebits/8);
sc->pDSBuf->lpVtbl->Unlock(sc->pDSBuf, pData, dwSize, NULL, 0);
}
else
#endif
{
Q_memset(sc->sn.buffer, clear, sc->sn.samples * sc->sn.samplebits/8);
}
*/
}
/*
@ -1010,7 +1069,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
ss->end = scard->paintedtime + scache->length;
ss->looping = true;
SND_Spatialize (scard, ss);
}
}
@ -1051,7 +1110,7 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
scache = S_LoadSound (newmusic);
if (scache)
{
{
chan->sfx = newmusic;
chan->pos = 0;
chan->end = sc->paintedtime + scache->length+1000;
@ -1078,11 +1137,11 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{
chan = &sc->channel[ambient_channel];
chan = &sc->channel[ambient_channel];
chan->sfx = ambient_sfx[ambient_channel];
VectorCopy(listener_origin, chan->origin);
vol = ambient_level.value * l->ambient_sound_level[ambient_channel];
if (vol < 8)
vol = 0;
@ -1100,7 +1159,7 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
if (chan->master_vol < vol)
chan->master_vol = vol;
}
chan->vol[0] = chan->vol[1] = chan->vol[2] = chan->vol[3] = chan->vol[4] = chan->vol[5] = chan->master_vol;
}
}
@ -1141,13 +1200,13 @@ void S_UpdateCard(soundcardinfo_t *sc)
if (!sc->inactive_sound)
return;
}
// update general area ambient sound sources
S_UpdateAmbientSounds (sc);
combine = NULL;
// update spatialization for static and dynamic sounds
// update spatialization for static and dynamic sounds
ch = sc->channel+NUM_AMBIENTS+NUM_MUSICS;
for (i=NUM_AMBIENTS+ NUM_MUSICS ; i<sc->total_chans; i++, ch++)
{
@ -1160,7 +1219,7 @@ void S_UpdateCard(soundcardinfo_t *sc)
// try to combine static sounds with a previous channel of the same
// sound effect so we don't mix five torches every frame
if (i > MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS + NUM_MUSICS)
{
// see if it can just use the last one
@ -1180,7 +1239,7 @@ void S_UpdateCard(soundcardinfo_t *sc)
for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS+ NUM_MUSICS ; j<i; j++, combine++)
if (combine->sfx == ch->sfx)
break;
if (j == sc->total_chans)
{
combine = NULL;
@ -1200,8 +1259,8 @@ void S_UpdateCard(soundcardinfo_t *sc)
continue;
}
}
}
//
@ -1217,29 +1276,29 @@ void S_UpdateCard(soundcardinfo_t *sc)
// Con_Printf ("%i, %i %i %i %i %i %i %s\n", i, ch->vol[0], ch->vol[1], ch->vol[2], ch->vol[3], ch->vol[4], ch->vol[5], ch->sfx->name);
total++;
}
Con_Printf ("----(%i)----\n", total);
}
// mix some sound
// mix some sound
S_Update_(sc);
}
void GetSoundtime(soundcardinfo_t *sc)
{
int samplepos;
int samplepos;
int fullsamples;
fullsamples = sc->sn.samples / sc->sn.numchannels;
// it is possible to miscount buffers if it has wrapped twice between
// calls to S_Update. Oh well.
samplepos = SNDDMA_GetDMAPos(sc);
samplepos = sc->GetDMAPos(sc);
if (samplepos < sc->oldsamplepos)
{
sc->buffers++; // buffer wrapped
if (sc->paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
sc->buffers = 0;
@ -1310,28 +1369,12 @@ void S_Update_(soundcardinfo_t *sc)
if (endtime - soundtime > samps)
endtime = soundtime + samps;
#if defined(_WIN32) && !defined(NODIRECTX)
// if the buffer was lost or stopped, restore it and/or restart it
{
DWORD dwStatus;
if (sc->pDSBuf)
{
if (sc->pDSBuf->lpVtbl->GetStatus (sc->pDSBuf, &dwStatus) != DD_OK)
Con_Printf ("Couldn't get sound buffer status\n");
if (dwStatus & DSBSTATUS_BUFFERLOST)
sc->pDSBuf->lpVtbl->Restore (sc->pDSBuf);
if (!(dwStatus & DSBSTATUS_PLAYING))
sc->pDSBuf->lpVtbl->Play(sc->pDSBuf, 0, 0, DSBPLAY_LOOPING);
}
}
#endif
if (sc->Restore)
sc->Restore(sc);
S_PaintChannels (sc, endtime);
SNDDMA_Submit (sc);
sc->Submit(sc);
}
/*
@ -1348,7 +1391,7 @@ void S_Play(void)
int i;
char name[256];
sfx_t *sfx;
i = 1;
while (i<Cmd_Argc())
{
@ -1373,7 +1416,7 @@ void S_PlayVol(void)
float vol;
char name[256];
sfx_t *sfx;
i = 1;
while (i<Cmd_Argc())
{
@ -1604,7 +1647,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
else
{
int src=0;
int pos=0;
int pos=0;
while (pos++ < samples)
{
@ -1630,7 +1673,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
else
{
int src=0;
int pos=0;
int pos=0;
while (pos++ < samples)
{
@ -1664,7 +1707,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
else
{
int src=0;
int pos=0;
int pos=0;
while (pos++ < samples)
{
@ -1695,5 +1738,3 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
S_StartSoundCard(si, -1, 0, &s->sfx, r_origin, 1, 32767, 0);
}
}
#endif //cygwin

View file

@ -1,44 +1,3 @@
#ifdef __CYGWIN__
#include "quakedef.h"
int SNDDMA_Init(soundcardinfo_t *sc)
{
Con_Printf("Cygwin targets do not have sound. Sorry.\n");
return 0;
}
void S_Init(void)
{
Con_Printf("Cygwin targets do not have sound. Sorry.\n");
}
void S_Startup (void){}
void S_Restart_f (void){}
void SNDDMA_SetUnderWater(qboolean underwater) {}
void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, int width){}
void S_Shutdown (void){}
void S_ShutdownCur (void){}
void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation){}
void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation){}
void S_StopSound (int entnum, int entchannel){}
void S_StopAllSounds(qboolean clear){}
void S_ClearBuffer (soundcardinfo_t *sc){}
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up){}
void S_ExtraUpdate (void){}
sfx_t *S_PrecacheSound (char *sample)
{
return NULL;
}
void S_TouchSound (char *sample){}
void S_LocalSound (char *s){}
void S_ClearPrecache (void){}
void S_BeginPrecaching (void){}
void S_EndPrecaching (void){}
cvar_t bgmvolume;
cvar_t volume;
cvar_t precache;
int snd_speed;
#else
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
@ -51,20 +10,54 @@ int snd_speed;
#include <stdio.h>
#include "quakedef.h"
qboolean snd_firsttime = true;
static int tryrates[] = { 11025, 22051, 44100, 8000 };
soundcardinfo_t *sndcardinfo;
void SNDDMA_SetUnderWater(qboolean underwater) //simply a stub. Any ideas how to actually implement this properly?
static void OSS_SetUnderWater(qboolean underwater) //simply a stub. Any ideas how to actually implement this properly?
{
}
void S_UpdateCapture(void) //any ideas how to get microphone input?
static int OSS_GetDMAPos(soundcardinfo_t *sc)
{
struct count_info count;
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
{
perror("/dev/dsp");
Con_Printf("Uh, sound dead.\n");
close(sc->audio_fd);
return 0;
}
// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1);
// fprintf(stderr, "%d \r", count.ptr);
sc->sn.samplepos = count.ptr / (sc->sn.samplebits / 8);
return sc->sn.samplepos;
}
static void OSS_Shutdown(soundcardinfo_t *sc)
{
if (sc->sn.buffer) //close it properly, so we can go and restart it later.
munmap(sc->sn.buffer, sc->sn.samples * (sc->sn.samplebits/8));
if (sc->audio_fd)
close(sc->audio_fd);
*sc->name = '\0';
}
static void OSS_Submit(soundcardinfo_t *sc)
{
}
int SNDDMA_Init(soundcardinfo_t *sc)
static void *OSS_Lock(soundcardinfo_t *sc)
{
return sc->sn.buffer;
}
static void OSS_Unlock(soundcardinfo_t *sc, void *buffer)
{
}
static int OSS_InitCard(soundcardinfo_t *sc, int cardnum)
{ //FIXME: implement snd_multipledevices somehow.
int rc;
int fmt;
@ -96,22 +89,22 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not open %s\n", snddev);
devname = Cvar_Get("snd_devicename2", "", 0, "Sound controls");
snddev = devname->string;
if (*snddev) //try a secondary if they named one
{
printf("Initing sound device %s\n", snddev);
sc->audio_fd = open(snddev, O_RDWR | O_NONBLOCK);
if (sc->audio_fd < 0)
Con_Printf("Could not open %s\n", snddev);
}
if (sc->audio_fd < 0)
{
Con_Printf("Running without sound\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
}
@ -122,7 +115,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not reset %s\n", snddev);
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
@ -130,25 +123,25 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Sound driver too old\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
{
Con_Printf("Sorry but your soundcard can't do this\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
{
{
perror("GETOSPACE");
Con_Printf("Um, can't do GETOSPACE?\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
sc->sn.splitbuffer = 0;
// set sample bits & speed
@ -195,12 +188,12 @@ int SNDDMA_Init(soundcardinfo_t *sc)
// memory map the dma buffer
sc->sn.buffer = (unsigned char *) mmap(NULL, info.fragstotal
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0);
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0);
if (!sc->sn.buffer)
{
perror(snddev);
Con_Printf("Could not mmap %s\n", snddev);
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
@ -212,7 +205,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not set %s to stereo=%d", snddev, sc->sn.numchannels);
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
if (tmp)
@ -225,19 +218,19 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not set %s speed to %d", snddev, sc->sn.speed);
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
if (sc->sn.samplebits == 16)
{
{
rc = AFMT_S16_LE;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not support 16-bit data. Try 8-bit.\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
}
@ -249,7 +242,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not support 8-bit data.\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
}
@ -257,7 +250,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("%d-bit sound not supported.", sc->sn.samplebits);
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
@ -269,7 +262,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not toggle.\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
tmp = PCM_ENABLE_OUTPUT;
@ -278,52 +271,26 @@ int SNDDMA_Init(soundcardinfo_t *sc)
{
perror(snddev);
Con_Printf("Could not toggle.\n");
SNDDMA_Shutdown(sc);
OSS_Shutdown(sc);
return 0;
}
sc->sn.samplepos = 0;
sc->Lock = OSS_Lock;
sc->Unlock = OSS_Unlock;
sc->SetWaterDistortion = OSS_SetUnderWater;
sc->Submit = OSS_Submit;
sc->Shutdown = OSS_Shutdown;
sc->GetDMAPos = OSS_GetDMAPos;
return 1;
}
int SNDDMA_GetDMAPos(soundcardinfo_t *sc)
{
struct count_info count;
int (*pOSS_InitCard) (soundcardinfo_t *sc, int cardnum) = &OSS_InitCard;
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
{
perror("/dev/dsp");
Con_Printf("Uh, sound dead.\n");
close(sc->audio_fd);
return 0;
}
// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1);
// fprintf(stderr, "%d \r", count.ptr);
sc->sn.samplepos = count.ptr / (sc->sn.samplebits / 8);
return sc->sn.samplepos;
}
void SNDDMA_Shutdown(soundcardinfo_t *sc)
{
if (sc->sn.buffer) //close it properly, so we can go and restart it later.
munmap(sc->sn.buffer, sc->sn.samples * (sc->sn.samplebits/8));
if (sc->audio_fd)
close(sc->audio_fd);
*sc->name = '\0';
}
/*
==============
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
===============
*/
void SNDDMA_Submit(soundcardinfo_t *sc)
void S_UpdateCapture(void)
{
}
#endif

View file

@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#ifndef __CYGWIN__
#include "winquake.h"
int cache_full_cycle;
@ -428,5 +426,3 @@ wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
return info;
}
#endif

View file

@ -21,18 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#ifndef __CYGWIN__
#ifndef NOSOUNDASM
#define NOSOUNDASM //since channels per sound card went to 6 (portable_samplegroup_t was changed)
#endif
#ifdef _WIN32
#include "winquake.h"
#else
#define DWORD unsigned long
#endif
#define PAINTBUFFER_SIZE 2048
portable_samplegroup_t paintbuffer[PAINTBUFFER_SIZE];
int snd_scaletable[32][256];
@ -72,49 +64,16 @@ void S_TransferStereo16 (soundcardinfo_t *sc, int endtime)
{
int lpos;
int lpaintedtime;
DWORD *pbuf;
#if defined(_WIN32) && !defined(NODIRECTX)
int reps;
DWORD dwSize=0,dwSize2=0;
DWORD *pbuf2;
HRESULT hresult;
#endif
short *pbuf;
snd_vol = volume.value*256;
snd_p = (int *) paintbuffer;
lpaintedtime = sc->paintedtime;
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
{
reps = 0;
while ((hresult = sc->pDSBuf->lpVtbl->Lock(sc->pDSBuf, 0, sc->gSndBufSize, (void**)&pbuf, &dwSize,
(void**)&pbuf2, &dwSize2, 0)) != DS_OK)
{
if (hresult != DSERR_BUFFERLOST)
{
Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
if (++reps > 10000)
{
Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
}
}
else
#endif
{
pbuf = (DWORD *)sc->sn.buffer;
}
pbuf = sc->Lock(sc);
if (!pbuf)
return;
while (lpaintedtime < endtime)
{
@ -139,10 +98,7 @@ void S_TransferStereo16 (soundcardinfo_t *sc, int endtime)
lpaintedtime += (sc->snd_linear_count>>1);
}
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
sc->pDSBuf->lpVtbl->Unlock(sc->pDSBuf, pbuf, dwSize, NULL, 0);
#endif
sc->Unlock(sc, pbuf);
}
void Snd_WriteLinearBlastStereo16_4Speaker (soundcardinfo_t *sc)
@ -195,49 +151,16 @@ void S_Transfer4Speaker16 (soundcardinfo_t *sc, int endtime)
{
int lpos;
int lpaintedtime;
DWORD *pbuf;
#if defined(_WIN32) && !defined(NODIRECTX)
int reps;
DWORD dwSize=0,dwSize2=0;
DWORD *pbuf2;
HRESULT hresult;
#endif
short *pbuf;
snd_vol = volume.value*256;
snd_p = (int *) paintbuffer;
lpaintedtime = sc->paintedtime;
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
{
reps = 0;
while ((hresult = sc->pDSBuf->lpVtbl->Lock(sc->pDSBuf, 0, sc->gSndBufSize, (void**)&pbuf, &dwSize,
(void**)&pbuf2, &dwSize2, 0)) != DS_OK)
{
if (hresult != DSERR_BUFFERLOST)
{
Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
if (++reps > 10000)
{
Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
}
}
else
#endif
{
pbuf = (DWORD *)sc->sn.buffer;
}
pbuf = sc->Lock(sc);
if (!pbuf)
return;
while (lpaintedtime < endtime)
{
@ -262,10 +185,7 @@ void S_Transfer4Speaker16 (soundcardinfo_t *sc, int endtime)
lpaintedtime += (sc->snd_linear_count>>2);
}
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
sc->pDSBuf->lpVtbl->Unlock(sc->pDSBuf, pbuf, dwSize, NULL, 0);
#endif
sc->Unlock(sc, pbuf);
}
void Snd_WriteLinearBlast6Speaker16 (soundcardinfo_t *sc)
@ -339,49 +259,16 @@ void S_Transfer6Speaker16 (soundcardinfo_t *sc, int endtime)
{
int lpos;
int lpaintedtime;
DWORD *pbuf;
#if defined(_WIN32) && !defined(NODIRECTX)
int reps;
DWORD dwSize=0,dwSize2=0;
DWORD *pbuf2;
HRESULT hresult;
#endif
short *pbuf;
snd_vol = volume.value*256;
snd_p = (int *) paintbuffer;
lpaintedtime = sc->paintedtime;
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
{
reps = 0;
while ((hresult = sc->pDSBuf->lpVtbl->Lock(sc->pDSBuf, 0, sc->gSndBufSize, (void**)&pbuf, &dwSize,
(void**)&pbuf2, &dwSize2, 0)) != DS_OK)
{
if (hresult != DSERR_BUFFERLOST)
{
Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
if (++reps > 10000)
{
Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
}
}
else
#endif
{
pbuf = (DWORD *)sc->sn.buffer;
}
pbuf = sc->Lock(sc);
if (!pbuf)
return;
while (lpaintedtime < endtime)
{
@ -406,10 +293,7 @@ void S_Transfer6Speaker16 (soundcardinfo_t *sc, int endtime)
lpaintedtime += (sc->snd_linear_count/6);
}
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
sc->pDSBuf->lpVtbl->Unlock(sc->pDSBuf, pbuf, dwSize, NULL, 0);
#endif
sc->Unlock(sc, pbuf);
}
void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
@ -421,13 +305,7 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
int step;
int val;
int snd_vol;
DWORD *pbuf;
#if defined(_WIN32) && !defined(NODIRECTX)
int reps;
DWORD dwSize=0,dwSize2=0;
DWORD *pbuf2;
HRESULT hresult;
#endif
short *pbuf;
if (sc->sn.samplebits == 16 && sc->sn.numchannels == 2)
{
@ -456,38 +334,9 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
step = 3 - sc->sn.numchannels;
snd_vol = volume.value*256;
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf)
{
reps = 0;
while ((hresult = sc->pDSBuf->lpVtbl->Lock(sc->pDSBuf, 0, sc->gSndBufSize, (void**)&pbuf, &dwSize,
(void**)&pbuf2,&dwSize2, 0)) != DS_OK)
{
if (hresult != DSERR_BUFFERLOST)
{
Con_Printf ("S_TransferPaintBuffer: DS::Lock Sound Buffer Failed\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
if (++reps > 10000)
{
Con_Printf ("S_TransferPaintBuffer: DS: couldn't restore buffer\n");
S_ShutdownCard (sc);
SNDDMA_Init (sc);
return;
}
}
}
else
#endif
{
pbuf = (DWORD *)sc->sn.buffer;
}
pbuf = sc->Lock(sc);
if (!pbuf)
return;
if (sc->sn.samplebits == 16)
{
@ -520,22 +369,7 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
}
}
#if defined(_WIN32) && !defined(NODIRECTX)
if (sc->pDSBuf) {
DWORD dwNewpos, dwWrite;
int il = sc->paintedtime;
int ir = endtime - sc->paintedtime;
ir += il;
sc->pDSBuf->lpVtbl->Unlock(sc->pDSBuf, pbuf, dwSize, NULL, 0);
sc->pDSBuf->lpVtbl->GetCurrentPosition(sc->pDSBuf, &dwNewpos, &dwWrite);
// if ((dwNewpos >= il) && (dwNewpos <= ir))
// Con_Printf("%d-%d p %d c\n", il, ir, dwNewpos);
}
#endif
sc->Unlock(sc, pbuf);
}
@ -995,5 +829,3 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
ch->pos += count;
}
#endif

View file

@ -3,53 +3,61 @@
#include <SDL.h>
extern cvar_t snd_khz;
#define SOUND_BUFFER_SIZE 0x0400
int snd_inited;
soundcardinfo_t *sndcardinfo;
int snd_firsttime = 0;
int aimedforguid;
//lamocodec.
static char buffer[SOUND_BUFFER_SIZE];
int sndpos;
void SNDDMA_Submit(soundcardinfo_t *sc)
{ //We already wrote it into the 'dma' buffer (heh, the closest we can get to it at least)
//so we now wait for sdl to request it.
//yes, this can result in slow sound.
}
void SNDDMA_Shutdown(soundcardinfo_t *sc)
static void SSDL_Shutdown(soundcardinfo_t *sc)
{
if (snd_inited)
{
snd_inited = false;
SDL_CloseAudio();
}
Con_Printf("Shutdown SDL sound\n");
SDL_CloseAudio();
Con_Printf("buffer\n");
if (sc->sn.buffer)
free(sc->sn.buffer);
sc->sn.buffer = NULL;
Con_Printf("down\n");
}
int SNDDMA_GetDMAPos(soundcardinfo_t *sc)
static unsigned int SSDL_GetDMAPos(soundcardinfo_t *sc)
{
sc->sn.samplepos = (sndpos / (sc->sn.samplebits/8)) % sc->sn.samples;
sc->sn.samplepos = (sc->snd_sent / (sc->sn.samplebits/8)) % sc->sn.samples;
return sc->sn.samplepos;
}
void SNDDMA_Paint(void *userdata, qbyte *stream, int len)
//this function is called from inside SDL.
//transfer the 'dma' buffer into the buffer it requests.
static void SSDL_Paint(void *userdata, qbyte *stream, int len)
{
soundcardinfo_t *sc = userdata;
if (len > SOUND_BUFFER_SIZE)
len = SOUND_BUFFER_SIZE; //whoa nellie!
if (len > SOUND_BUFFER_SIZE - sndpos)
if (len > SOUND_BUFFER_SIZE - sc->snd_sent)
{ //buffer will wrap, fill in the rest
memcpy(stream, buffer + sndpos, SOUND_BUFFER_SIZE - sndpos);
len -= SOUND_BUFFER_SIZE - sndpos;
sndpos = 0;
memcpy(stream, sc->sn.buffer + sc->snd_sent, SOUND_BUFFER_SIZE - sc->snd_sent);
len -= SOUND_BUFFER_SIZE - sc->snd_sent;
sc->snd_sent = 0;
} //and finish from the start
memcpy(stream, buffer + sndpos, len);
sndpos += len;
memcpy(stream, sc->sn.buffer + sc->snd_sent, len);
sc->snd_sent += len;
}
static void *SSDL_LockBuffer(soundcardinfo_t *sc)
{
SDL_LockAudio();
return sc->sn.buffer;
}
static void SSDL_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
{
SDL_UnlockAudio();
}
static void SSDL_SetUnderWater(soundcardinfo_t *sc, qboolean uw)
{
}
static void SSDL_Submit(soundcardinfo_t *sc)
{
//SDL will call SSDL_Paint to paint when it's time, and the sound buffer is always there...
}
@ -57,16 +65,15 @@ void S_UpdateCapture(void) //any ideas how to get microphone input?
{
}
int SNDDMA_Init(soundcardinfo_t *sc)
static int SDL_InitCard(soundcardinfo_t *sc, int cardnum)
{
SDL_AudioSpec desired, obtained;
if (snd_inited)
if (cardnum)
{ //our init code actually calls this function multiple times, in the case that the user has multiple sound cards
// Con_Printf("Sound was already inited\n");
return 2; //erm. SDL won't allow multiple sound cards anyway.
}
Con_Printf("SDL AUDIO INITING\n");
if(SDL_InitSubSystem(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE))
{
@ -76,24 +83,12 @@ Con_Printf("SDL AUDIO INITING\n");
memset(&desired, 0, sizeof(desired));
if (!sc->sn.speed)
{
if (snd_khz.value >= 45)
sc->sn.speed = 48000;
else if (snd_khz.value >= 30) //set by a slider
sc->sn.speed = 44100;
else if (snd_khz.value >= 20)
sc->sn.speed = 22050;
else
sc->sn.speed = 11025;
}
desired.freq = sc->sn.speed;
desired.channels = 2;
desired.samples = SOUND_BUFFER_SIZE;
desired.format = AUDIO_S16;
desired.callback = SNDDMA_Paint;
desired.userdata = sc;
desired.callback = SSDL_Paint;
desired.userdata = sc;
if ( SDL_OpenAudio(&desired, &obtained) < 0 )
@ -105,14 +100,18 @@ Con_Printf("SDL AUDIO INITING\n");
sc->sn.speed = desired.freq;
sc->sn.samplebits = 16;
sc->sn.samples = SOUND_BUFFER_SIZE;
sc->sn.buffer = buffer;
sc->sn.buffer = malloc(SOUND_BUFFER_SIZE*sc->sn.samplebits/8);
Con_Printf("Got sound %i-%i\n", obtained.freq, obtained.format);
snd_inited = true;
SDL_PauseAudio(0);
sc->Lock = SSDL_LockBuffer;
sc->Unlock = SSDL_UnlockBuffer;
sc->SetWaterDistortion = SSDL_SetUnderWater;
sc->Submit = SSDL_Submit;
sc->Shutdown = SSDL_Shutdown;
sc->GetDMAPos = SSDL_GetDMAPos;
return true;
}
void SNDDMA_SetUnderWater(qboolean underwater)
{
}
sounddriver pSDL_InitCard = &SDL_InitCard;

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@ 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -59,7 +59,7 @@ typedef struct sfxcache_s
int loopstart;
int speed;
int width;
int stereo;
int stereo;
qbyte data[1]; // variable sized
} sfxcache_t;
@ -81,7 +81,7 @@ typedef struct
typedef struct
{
sfx_t *sfx; // sfx number
int vol[MAXSOUNDCHANNELS]; // 0-255 volume
int vol[MAXSOUNDCHANNELS]; // 0-255 volume
int delay[MAXSOUNDCHANNELS];
int end; // end time in global paintsamples
int pos; // sample position in sfx
@ -139,15 +139,6 @@ channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel);
// spatializes a channel
void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch);
// initializes cycling through a DMA buffer and returns information on it
int SNDDMA_Init(soundcardinfo_t *sc);
// gets the current DMA position
int SNDDMA_GetDMAPos(soundcardinfo_t *sc);
// shutdown the DMA xfer.
void SNDDMA_Shutdown(soundcardinfo_t *sc);
// restart entire sound subsystem
void S_Restart_f (void);
@ -190,7 +181,7 @@ extern cvar_t volume;
extern cvar_t snd_capture;
extern qboolean snd_initialized;
extern qboolean snd_multipledevices;
extern cvar_t snd_usemultipledevices;
extern int snd_blocked;
@ -200,59 +191,60 @@ sfxcache_t *S_LoadSound (sfx_t *s);
wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength);
void SND_InitScaletable (void);
void SNDDMA_Submit(soundcardinfo_t *sc);
void S_AmbientOff (void);
void S_AmbientOn (void);
#ifndef _WIN32
//inititalisation functions.
typedef int (*sounddriver) (soundcardinfo_t *sc, int cardnum);
extern sounddriver pDSOUND_InitCard;
extern sounddriver pALSA_InitCard;
extern sounddriver pOSS_InitCard;
extern sounddriver pSDL_InitCard;
extern sounddriver pWAV_InitCard;
struct soundcardinfo_s { //windows has one defined AFTER directsound
char name[256]; //a description of the card.
struct soundcardinfo_s *next;
//speaker orientations for spacialisation.
float dist[MAX_CHANNELS];
float pitch[MAX_CHANNELS];
float yaw[MAX_CHANNELS];
char name[256];
//info on which sound effects are playing
channel_t channel[MAX_CHANNELS];
int total_chans;
//mixer
volatile dma_t sn; //why is this volatile?
qboolean inactive_sound; //continue mixing for this card even when the window isn't active.
qboolean selfpainting; //allow the sound code to call the right functions when it feels the need (not properly supported).
qboolean selfpainting; //allow the sound code to call the right functions when it feels the need.
//sdl uses this and runs multithreaded.
int paintedtime; //used in the mixer
int oldsamplepos; //fixme: is this still needed?
int snd_linear_count; //used by the mixer.
int buffers; //used to keep track of buffer wraps for consistant sound
qboolean inactive_sound;
int rawend; //streaming audio (avi/cin/roq)
int rawstart;
qboolean snd_isdirect;
qboolean snd_iswave;
int paintedtime;
int oldsamplepos;
int buffers;
qboolean dsound_init;
qboolean wav_init;
volatile dma_t sn;
int snd_linear_count;
//callbacks
void *(*Lock) (soundcardinfo_t *sc);
void (*Unlock) (soundcardinfo_t *sc, void *buffer);
void (*Submit) (soundcardinfo_t *sc);
void (*Shutdown) (soundcardinfo_t *sc);
unsigned int (*GetDMAPos) (soundcardinfo_t *sc);
void (*SetWaterDistortion) (soundcardinfo_t *sc, qboolean underwater);
void (*Restore) (soundcardinfo_t *sc);
//driver -specific
void *handle;
int snd_sent;
int snd_completed;
int audio_fd;
channel_t channel[MAX_CHANNELS];
int total_chans;
int rawend;
int rawstart;
struct soundcardinfo_s *next;
};
#endif
extern soundcardinfo_t *sndcardinfo;

View file

@ -1135,7 +1135,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
#ifndef CLIENTONLY
if (isDedicated)
{
NET_Sleep(100, false);
NET_Sleep(50, false);
// find time passed since last cycle
newtime = Sys_DoubleTime ();

View file

@ -454,6 +454,13 @@ void V_cshift_f (void)
{
if (Cmd_Argc() != 5 && Cmd_Argc() != 1) //this is actually to warn of a malice bug (and prevent a totally black screen) more than it is to help the user. :/
{ //The 1 is so teamfortress can use it to clear.
if (Cmd_FromGamecode()) //nehahra does nasty things and becomes unplayable.
{
cl.cshifts[CSHIFT_SERVER].destcolor[0] = 0;
cl.cshifts[CSHIFT_SERVER].destcolor[1] = 0;
cl.cshifts[CSHIFT_SERVER].destcolor[2] = 0;
cl.cshifts[CSHIFT_SERVER].percent = 0;
}
Con_Printf("v_cshift: v_cshift <r> <g> <b> <alpha>\n");
return;
}
@ -1274,6 +1281,42 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
r_refdef.fov_y = CalcFov(r_refdef.fov_x, vrect->width, vrect->height);
}
void ML_Project(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void R_DrawNameTags(void)
{
int i;
vec3_t center;
vec3_t tagcenter;
vec3_t waste, waste2;
frame_t *frame;
player_state_t *state;
if (!cl.spectator && !cls.demoplayback)
return;
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
GL_Set2D();
#endif
frame = &cl.frames[cl.parsecount&UPDATE_MASK];
state = frame->playerstate;
for (i = 0; i < MAX_CLIENTS; i++, state++)
{
if (state->messagenum != cl.parsecount)
continue; // not present this frame
if (!TraceLineN(r_refdef.vieworg, state->origin, waste, waste2))
{
VectorCopy(state->origin, tagcenter);
tagcenter[2] += 32;
ML_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, (float)r_refdef.vrect.width/r_refdef.vrect.height, r_refdef.fov_y);
if (center[2] > 1)
return;
Draw_FunString(center[0]*r_refdef.vrect.width+r_refdef.vrect.x, (1-center[1])*r_refdef.vrect.height+r_refdef.vrect.y, cl.players[i].name);
}
}
}
void V_RenderPlayerViews(int plnum)
{
int viewnum;
@ -1306,7 +1349,10 @@ void V_RenderPlayerViews(int plnum)
R_RenderView_fisheye();
else
#endif
{
R_RenderView ();
R_DrawNameTags();
}
if (scr_chatmode == 2)
{

View file

@ -78,7 +78,7 @@ extern LPDIRECTDRAWSURFACE lpFrontBuffer;
extern LPDIRECTDRAWSURFACE lpBackBuffer;
extern LPDIRECTDRAWPALETTE lpDDPal;
#endif
/*
struct soundcardinfo_s {
int snd_linear_count; //change in asm_i386.h. MUST be first
@ -86,6 +86,14 @@ struct soundcardinfo_s {
float yaw[MAXSOUNDCHANNELS];
float dist[MAXSOUNDCHANNELS];
void *handle;
void *(*Lock) (soundcardinfo_t *sc);
void (*Unlock) (soundcardinfo_t *sc, void *buffer);
void (*Submit) (soundcardinfo_t *sc);
void (*Shutdown) (soundcardinfo_t *sc);
unsigned int (*GetDMAPos) (soundcardinfo_t *sc);
void (*SetWaterDistortion) (soundcardinfo_t *sc, qboolean underwater);
#ifndef NODIRECTX
LPDIRECTSOUND pDS;
LPDIRECTSOUNDBUFFER pDSBuf;
@ -102,21 +110,13 @@ struct soundcardinfo_s {
qboolean selfpainting;
qboolean inactive_sound;
#ifndef NODIRECTX
qboolean snd_isdirect;
#endif
qboolean snd_iswave;
int paintedtime;
int oldpaintedtime;
int oldsamplepos;
int buffers;
#ifndef NODIRECTX
qboolean dsound_init;
#endif
qboolean wav_init;
dma_t sn;
@ -139,7 +139,7 @@ int total_chans;
struct soundcardinfo_s *next;
};
*/
//void VID_LockBuffer (void);

View file

@ -1801,7 +1801,7 @@ static void TP_TeamColor_f (void)
{
cl_teamtopcolor = -1;
cl_teambottomcolor = -1;
if (qrenderer) //make sure we have the renderer initialised...
if (qrenderer>QR_NONE) //make sure we have the renderer initialised...
for (i = 0; i < MAX_CLIENTS; i++)
CL_NewTranslation(i);
return;
@ -1826,7 +1826,7 @@ static void TP_TeamColor_f (void)
cl_teamtopcolor = top;
cl_teambottomcolor = bottom;
if (qrenderer) //make sure we have the renderer initialised...
if (qrenderer>QR_NONE) //make sure we have the renderer initialised...
for (i = 0; i < MAX_CLIENTS; i++)
CL_NewTranslation(i);
}
@ -1852,7 +1852,7 @@ static void TP_EnemyColor_f (void)
{
cl_enemytopcolor = -1;
cl_enemybottomcolor = -1;
if (qrenderer) //make sure we have the renderer initialised...
if (qrenderer>QR_NONE) //make sure we have the renderer initialised...
for (i = 0; i < MAX_CLIENTS; i++)
CL_NewTranslation(i);
return;
@ -1877,7 +1877,7 @@ static void TP_EnemyColor_f (void)
cl_enemytopcolor = top;
cl_enemybottomcolor = bottom;
if (qrenderer) //make sure we have the renderer initialised...
if (qrenderer>QR_NONE) //make sure we have the renderer initialised...
for (i = 0; i < MAX_CLIENTS; i++)
CL_NewTranslation(i);
}

View file

@ -731,13 +731,17 @@ void MSG_WriteAngle16 (sizebuf_t *sb, float f)
{
MSG_WriteShort (sb, (int)(f*65536/360) & 65535);
}
void MSG_WriteAngle8 (sizebuf_t *sb, float f)
{
MSG_WriteByte (sb, (int)(f*256/360) & 255);
}
void MSG_WriteAngle (sizebuf_t *sb, float f)
{
if (sizeofangle==2)
MSG_WriteAngle16(sb, f);
else
MSG_WriteByte (sb, (int)(f*256/360) & 255);
MSG_WriteAngle8 (sb, f);
}
void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
@ -4223,8 +4227,8 @@ 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.
//this is to avoid having too many gamemodes anyway.
{"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", "id1", "qw", "fte"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", "hipnotic/pak0.pak","id1", "qw", "hipnotic", "fte"},
{"Darkplaces-Rogue", "rogue", "-rogue", "rogue/pak0.pak", "id1", "qw", "rogue", "fte"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", NULL/*"hipnotic/pak0.pak"*/,"id1", "qw", "hipnotic", "fte"},
{"Darkplaces-Rogue", "rogue", "-rogue", NULL/*"rogue/pak0.pak", "id1"*/, "qw", "rogue", "fte"},
{"Nexuiz", "nexuiz", "-nexuiz", "data/data.pk3", "id1", "qw", "data", "fte"},
//supported commercial mods (some are currently only partially supported)
@ -4252,7 +4256,6 @@ void COM_InitFilesystem (void)
int gamenum=-1;
char *check;
//
// -basedir <path>
@ -4270,6 +4273,8 @@ void COM_InitFilesystem (void)
//identify the game from a telling file
for (i = 0; gamemode_info[i].gamename; i++)
{
if (!gamemode_info[i].auniquefile)
return;
f = fopen(va("%s/%s", com_quakedir, gamemode_info[i].auniquefile), "rb");
if (f)
{

View file

@ -135,6 +135,7 @@ void MSG_WriteString (sizebuf_t *sb, const char *s);
void MSG_WriteCoord (sizebuf_t *sb, float f);
void MSG_WriteBigCoord (sizebuf_t *sb, float f);
void MSG_WriteAngle (sizebuf_t *sb, float f);
void MSG_WriteAngle8 (sizebuf_t *sb, float f);
void MSG_WriteAngle16 (sizebuf_t *sb, float f);
void MSG_WriteDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd);
void MSG_WriteDir (sizebuf_t *sb, float *dir);

View file

@ -2394,11 +2394,11 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
void CModQ3_SortShaders(void)
{
texture_t *textemp;
/* texture_t *textemp;
int i, j;
//sort loadmodel->textures
//correct pointers in loadmodel->texinfo
/*
for (i = 0; i < numtexinfo; i++)
{
for (j = i+1; j < numtexinfo; j++)

View file

@ -156,6 +156,9 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport);
qboolean Netchan_CanPacket (netchan_t *chan, int rate);
qboolean Netchan_CanReliable (netchan_t *chan, int rate);
#ifdef NQPROT
qboolean NQNetChan_Process(netchan_t *chan);
#endif
#ifdef HUFFNETWORK
int Huff_PreferedCompressionCRC (void);

View file

@ -352,26 +352,6 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
send.maxsize = MAX_NQMSGLEN + PACKET_HEADER;
send.cursize = 0;
//send out the unreliable
if (length)
{
MSG_WriteLong(&send, 0);
MSG_WriteLong(&send, BigLong(chan->outgoing_unreliable));
chan->outgoing_unreliable++;
SZ_Write (&send, data, length);
*(int*)send_buf = BigLong(NETFLAG_UNRELIABLE | send.cursize);
NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address);
if (chan->cleartime < realtime)
chan->cleartime = realtime + send.cursize/(float)rate;
else
chan->cleartime += send.cursize/(float)rate;
send.cursize = 0;
}
if (!chan->reliable_length && chan->message.cursize)
{
memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
@ -389,6 +369,11 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
i = MAX_NQDATAGRAM;
SZ_Write (&send, chan->reliable_buf+chan->reliable_start, i);
if (send.cursize + length < send.maxsize)
{ //throw the unreliable packet into the same one as the reliable (but not sent reliably)
SZ_Write (&send, data, length);
length = 0;
}
if (chan->reliable_start+i == chan->reliable_length)
@ -402,6 +387,26 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
else
chan->cleartime += send.cursize/(float)rate;
}
//send out the unreliable (if still unsent)
if (length)
{
MSG_WriteLong(&send, 0);
MSG_WriteLong(&send, BigLong(chan->outgoing_unreliable));
chan->outgoing_unreliable++;
SZ_Write (&send, data, length);
*(int*)send_buf = BigLong(NETFLAG_UNRELIABLE | send.cursize);
NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address);
if (chan->cleartime < realtime)
chan->cleartime = realtime + send.cursize/(float)rate;
else
chan->cleartime += send.cursize/(float)rate;
send.cursize = 0;
}
return;
}
#endif

View file

@ -430,7 +430,7 @@ qboolean NET_StringToSockaddr (char *s, struct sockaddr_qstorage *sadr)
int len;
memset(&udp6hint, 0, sizeof(udp6hint));
udp6hint.ai_family = 0;//Any... AF_INET6;
udp6hint.ai_family = 0;//Any... we check for AF_INET6 or 4
udp6hint.ai_socktype = SOCK_DGRAM;
udp6hint.ai_protocol = IPPROTO_UDP;

View file

@ -198,7 +198,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svcdp_precache 54 // [short] precacheindex [string] filename, precacheindex is + 0 for modelindex and +32768 for soundindex
#define svc_nails2 54 //qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
#define svcdp_spawnbaseline2 55
#ifdef PEXT_VIEW2
#define svc_view2 56
#endif
@ -206,6 +206,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_lightstylecol 57
#endif
#define svcdp_entities 57
#ifdef PEXT_BULLETENS
#define svc_bulletentext 58
#endif
@ -660,6 +662,7 @@ enum {
typedef struct entity_state_s
{
int number; // edict index
int bitmask; // for dp ents, so lost state can be repeated in replacement packets.
int flags; // nolerp, etc
vec3_t origin;

View file

@ -459,8 +459,8 @@ int Fragment_ClipPolyToPlane(float *inverts, float *outverts, int incount, float
int clippedcount = 0;
vec3_t impact;
float *lastvalid; //the reason these arn't just an index is because it'd need to be a special case for the first vert.
float lastvaliddot;
float *lastvalid = NULL; //the reason these arn't just an index is because it'd need to be a special case for the first vert.
float lastvaliddot = 0;
for (i = 0; i < incount; i++)
{
@ -539,7 +539,6 @@ int Fragment_ClipPolyToPlane(float *inverts, float *outverts, int incount, float
void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
{
//emit the triangle, and clip it's fragments.
int start, i;
int p;
float verts[MAXFRAGMENTVERTS*3];
float verts2[MAXFRAGMENTVERTS*3];

View file

@ -947,6 +947,9 @@ Hunk_AllocName
*/
void *Hunk_AllocName (int size, char *name)
{
#ifdef NOHIGH
int roundup;
#endif
hunk_t *h;
#ifdef PARANOID
@ -971,7 +974,10 @@ void *Hunk_AllocName (int size, char *name)
h = (hunk_t *)(hunk_base + hunk_low_used);
#ifdef NOHIGH
if (!VirtualAlloc (hunk_base, hunk_low_used+size+sizeof(hunk_t), MEM_COMMIT, PAGE_READWRITE))
roundup = hunk_low_used+size+sizeof(hunk_t);
roundup += 1024*64;
roundup &= ~(1024*64 - 1);
if (!VirtualAlloc (hunk_base, roundup, MEM_COMMIT, PAGE_READWRITE))
{
char *buf;
Hunk_Print(true);

View file

@ -2098,6 +2098,10 @@ SOURCE=..\client\skin.c
# End Source File
# Begin Source File
SOURCE=..\client\snd_directx.c
# End Source File
# Begin Source File
SOURCE=..\client\snd_dma.c
!IF "$(CFG)" == "ftequake - Win32 Release"
@ -5002,70 +5006,728 @@ SOURCE=..\common\zone.c
# Begin Source File
SOURCE=..\QCLIB\Comprout.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\qclib\execloop.h
!IF "$(CFG)" == "ftequake - Win32 Release"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\hash.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\initlib.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\pr_edict.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\Pr_exec.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /WX /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\pr_multi.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\progtype.h
!IF "$(CFG)" == "ftequake - Win32 Release"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\qcc_cmdlib.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\qcc_pr_comp.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# PROP Exclude_From_Build 1
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\qcc_pr_lex.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# PROP Exclude_From_Build 1
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\QccMain.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# PROP Exclude_From_Build 1
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\qcd_main.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\QCLIB\qcdecomp.c
!IF "$(CFG)" == "ftequake - Win32 Release"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# PROP Exclude_From_Build 1
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# End Group
# Begin Group "asm"

View file

@ -8,6 +8,8 @@
#define SKELETALMODELS
#endif
#define MAX_BONES 256
//FIXME
typedef struct
{
@ -119,6 +121,7 @@ typedef struct {
#ifdef SKELETALMODELS
typedef struct {
char name[32];
int parent;
} galiasbone_t;
@ -289,7 +292,7 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
#ifdef SKELETALMODELS
static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, galisskeletaltransforms_t *weights, int numweights)
{
float bonepose[256][12];
float bonepose[MAX_BONES][12];
float *outhead;
galisskeletaltransforms_t *v;
@ -594,6 +597,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, entity_
int frame;
int tc, bc;
int local;
if (!gl_nocolors.value)
{
@ -607,7 +611,15 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, entity_
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[cl.playernum[0]].team))
if (cl.teamplay && cl.spectator)
{
local = Cam_TrackNum(0);
if (local < 0)
local = cl.playernum[0];
}
else
local = cl.playernum[0];
if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[local].team))
{
if (cl_teamtopcolor>=0)
tc = cl_teamtopcolor;
@ -2814,28 +2826,157 @@ typedef struct {
void GLMod_GetTag(model_t *model, int tagnum, int frame, float **org, float **axis)
qboolean GLMod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result)
{
galiasinfo_t *inf;
md3tag_t *t;
*org = NULL;
*axis = NULL;
if (!model || model->type != mod_alias)
return;
return false;
inf = Mod_Extradata(model);
t = (md3tag_t*)((char*)inf + inf->ofstags);
if (tagnum <= 0 || tagnum > inf->numtags)
return;
if (frame < 0 || frame >= inf->numtagframes)
return;
tagnum--; //tagnum 0 is 'use my angles/org'
#ifdef SKELETALMODELS
if (inf->numbones)
{
galiasbone_t *bone;
galiasgroup_t *g1, *g2;
t += tagnum;
t += inf->numtags*frame;
*org = t->org;
*axis = (float*)t->ang;
float tempmatrix[12]; //flipped between this and bonematrix
float *matrix; //the matrix for a single bone in a single pose.
float m[12]; //combined interpolated version of 'matrix'.
int b, k; //counters
float *pose[4]; //the per-bone matricies (one for each pose)
float plerp[4]; //the ammount of that pose to use (must combine to 1)
int numposes = 0;
if (tagnum <= 0 || tagnum > inf->numbones)
return false;
tagnum--; //tagnum 0 is 'use my angles/org'
if (frame1 < 0 || frame1 >= inf->groups)
return false;
if (frame2 < 0 || frame2 >= inf->groups)
{
f2ness = 0;
frame2 = frame1;
}
bone = (galiasbone_t*)((char*)inf + inf->ofsbones);
//the higher level merges old/new anims, but we still need to blend between automated frame-groups.
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
frame1 = (int)f1time%g1->numposes;
frame2 = ((int)f1time+1)%g1->numposes;
f1time = f1time - (int)f1time;
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f1time) * (1-f2ness);
numposes++;
if (frame1 != frame2)
{
pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f1time * (1-f2ness);
numposes++;
}
if (f2ness)
{
frame1 = (int)f2time%g2->numposes;
frame2 = ((int)f2time+1)%g2->numposes;
f2time = f2time - (int)f2time;
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame1);
plerp[numposes] = (1-f2time) * f2ness;
numposes++;
if (frame1 != frame2)
{
pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame2);
plerp[numposes] = f2time * f2ness;
numposes++;
}
}
//set up the identity matrix
for (k = 0;k < 12;k++)
result[k] = 0;
result[0] = 1;
result[5] = 1;
result[10] = 1;
while(tagnum >= 0)
{
//set up the per-bone transform matrix
for (k = 0;k < 12;k++)
m[k] = 0;
for (b = 0;b < numposes;b++)
{
matrix = pose[b] + tagnum*12;
for (k = 0;k < 12;k++)
m[k] += matrix[k] * plerp[b];
}
memcpy(tempmatrix, result, sizeof(tempmatrix));
R_ConcatTransforms((void*)m, (void*)tempmatrix, (void*)result);
tagnum = bone[tagnum].parent;
}
return true;
}
#endif
if (inf->numtags)
{
md3tag_t *t1, *t2;
if (tagnum <= 0 || tagnum > inf->numtags)
return false;
if (frame1 < 0 || frame1 >= inf->numtagframes)
return false;
if (frame2 < 0 || frame2 >= inf->numtagframes)
frame2 = frame1;
tagnum--; //tagnum 0 is 'use my angles/org'
t1 = (md3tag_t*)((char*)inf + inf->ofstags);
t1 += tagnum;
t1 += inf->numtags*frame1;
t2 = (md3tag_t*)((char*)inf + inf->ofstags);
t2 += tagnum;
t2 += inf->numtags*frame2;
if (t1 == t2)
{
result[0] = t1->ang[0][0];
result[1] = t1->ang[1][0];
result[2] = t1->ang[2][0];
result[3] = t1->org[0];
result[4] = t1->ang[0][1];
result[5] = t1->ang[1][1];
result[6] = t1->ang[2][1];
result[7] = t1->org[1];
result[8] = t1->ang[0][2];
result[9] = t1->ang[1][2];
result[10] = t1->ang[2][2];
result[11] = t1->org[2];
}
else
{
float f1ness = 1-f2ness;
result[0] = t1->ang[0][0]*f1ness + t2->ang[0][0]*f2ness;
result[1] = t1->ang[1][0]*f1ness + t2->ang[1][0]*f2ness;
result[2] = t1->ang[2][0]*f1ness + t2->ang[2][0]*f2ness;
result[3] = t1->org[0]*f1ness + t2->org[0]*f2ness;
result[4] = t1->ang[0][1]*f1ness + t2->ang[0][1]*f2ness;
result[5] = t1->ang[1][1]*f1ness + t2->ang[1][1]*f2ness;
result[6] = t1->ang[2][1]*f1ness + t2->ang[2][1]*f2ness;
result[7] = t1->org[1]*f1ness + t2->org[1]*f2ness;
result[8] = t1->ang[0][2]*f1ness + t2->ang[0][2]*f2ness;
result[9] = t1->ang[1][2]*f1ness + t2->ang[1][2]*f2ness;
result[10] = t1->ang[2][2]*f1ness + t2->ang[2][2]*f2ness;
result[11] = t1->org[2]*f1ness + t2->org[2]*f2ness;
}
return true;
}
return false;
}
int GLMod_TagNumForName(model_t *model, char *name)
@ -2846,14 +2987,27 @@ int GLMod_TagNumForName(model_t *model, char *name)
if (!model || model->type != mod_alias)
return 0;
inf = Mod_Extradata(model);
#ifdef SKELETALMODELS
if (inf->numbones)
{
galiasbone_t *b;
b = (galiasbone_t*)((char*)inf + inf->ofsbones);
for (i = 0; i < inf->numbones; i++)
{
if (!strcmp(b[i].name, name))
return i+1;
}
}
#endif
t = (md3tag_t*)((char*)inf + inf->ofstags);
for (i = 0; i < inf->numtags; i++)
{
if (!strcmp(t[i].name, name))
return i+1;
}
return 0;
}
@ -3361,7 +3515,10 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
bone = Hunk_Alloc(root->numtransforms*sizeof(*transforms));
inbone = (zymbone_t*)((char*)header + header->lump_bones.start);
for (i = 0; i < root->numbones; i++)
{
Q_strncpyz(bone[i].name, inbone[i].name, sizeof(bone[i].name));
bone[i].parent = BigLong(inbone[i].parent);
}
root->ofsbones = (char *)bone - (char *)root;
renderlist = (int*)((char*)header + header->lump_render.start);

View file

@ -676,6 +676,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex)
qglDisable(GL_TEXTURE_2D);
GL_SelectTexture(GL_TEXTURE1_ARB);
GL_TexEnv(GL_MODULATE);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglDisable(GL_TEXTURE_2D);
@ -2250,7 +2251,6 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour)
VectorSubtract(r_refdef.vieworg, e->origin, relativeeyeorigin);
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
qglBlendFunc(GL_ONE, GL_ONE);
if (qglGetError())

View file

@ -1501,6 +1501,10 @@ r_refdef must be set before the first call
void R_RenderScene (void)
{
qboolean GLR_DoomWorld(void);
if (!cl.worldmodel)
r_refdef.flags |= Q2RDF_NOWORLDMODEL;
if (!mirror)
GLR_SetupFrame ();

View file

@ -3767,7 +3767,6 @@ void GL_BuildLightmaps (void)
{
int i, j;
model_t *m;
msurface_t *fa;
r_framecount = 1; // no dlightcache

View file

@ -395,7 +395,7 @@ reeval:
if (ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", pr_xfunction->s_name);
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;

View file

@ -1,914 +0,0 @@
//qc execution code.
//we have two conditions.
//one allows us to debug and trace through our code, the other doesn't.
//hopefully, the compiler will do a great job at optimising this code for us, where required.
//if it dosn't, then bum.
//the general overhead should be reduced significantly, and I would be supprised if it did run slower.
//run away loops are checked for ONLY on gotos and function calls. This might give a poorer check, but it will run faster overall.
//Appears to work fine.
#if INTSIZE == 16
#define cont cont16
#define reeval reeval16
#define st st16
#define pr_statements pr_statements16
#define fakeop fakeop16
#define dstatement_t dstatement16_t
#define sofs signed short
#define uofs unsigned short
#elif INTSIZE == 32
#define cont cont32
#define reeval reeval32
#define st st32
#define pr_statements pr_statements32
#define fakeop fakeop32
#define dstatement_t dstatement32_t
#define sofs signed int
#define uofs unsigned int
#elif INTSIZE == 24
#error INTSIZE should be set to 32.
#else
#error Bad cont size
#endif
//rely upon just st
{
#ifdef DEBUGABLE
cont: //last statement may have been a breakpoint
s = st-pr_statements;
s+=1;
s=ShowStep(progfuncs, s);
st = pr_statements + s;
reeval:
#else
st++;
#endif
switch (st->op)
{
case OP_ADD_F:
OPC->_float = OPA->_float + OPB->_float;
break;
case OP_ADD_V:
OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
break;
case OP_SUB_F:
OPC->_float = OPA->_float - OPB->_float;
break;
case OP_SUB_V:
OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
break;
case OP_MUL_F:
OPC->_float = OPA->_float * OPB->_float;
break;
case OP_MUL_V:
OPC->_float = OPA->vector[0]*OPB->vector[0]
+ OPA->vector[1]*OPB->vector[1]
+ OPA->vector[2]*OPB->vector[2];
break;
case OP_MUL_FV:
OPC->vector[0] = OPA->_float * OPB->vector[0];
OPC->vector[1] = OPA->_float * OPB->vector[1];
OPC->vector[2] = OPA->_float * OPB->vector[2];
break;
case OP_MUL_VF:
OPC->vector[0] = OPB->_float * OPA->vector[0];
OPC->vector[1] = OPB->_float * OPA->vector[1];
OPC->vector[2] = OPB->_float * OPA->vector[2];
break;
case OP_DIV_F:
OPC->_float = OPA->_float / OPB->_float;
break;
case OP_DIV_VF:
OPC->vector[0] = OPB->_float / OPA->vector[0];
OPC->vector[1] = OPB->_float / OPA->vector[1];
OPC->vector[2] = OPB->_float / OPA->vector[2];
break;
case OP_BITAND:
OPC->_float = (float)((int)OPA->_float & (int)OPB->_float);
break;
case OP_BITOR:
OPC->_float = (float)((int)OPA->_float | (int)OPB->_float);
break;
case OP_GE:
OPC->_float = (float)(OPA->_float >= OPB->_float);
break;
case OP_GE_I:
OPC->_int = (int)(OPA->_int >= OPB->_int);
break;
case OP_GE_IF:
OPC->_float = (float)(OPA->_int >= OPB->_float);
break;
case OP_GE_FI:
OPC->_float = (float)(OPA->_float >= OPB->_int);
break;
case OP_LE:
OPC->_float = (float)(OPA->_float <= OPB->_float);
break;
case OP_LE_I:
OPC->_int = (int)(OPA->_int <= OPB->_int);
break;
case OP_LE_IF:
OPC->_float = (float)(OPA->_int <= OPB->_float);
break;
case OP_LE_FI:
OPC->_float = (float)(OPA->_float <= OPB->_int);
break;
case OP_GT:
OPC->_float = (float)(OPA->_float > OPB->_float);
break;
case OP_GT_I:
OPC->_int = (int)(OPA->_int > OPB->_int);
break;
case OP_GT_IF:
OPC->_float = (float)(OPA->_int > OPB->_float);
break;
case OP_GT_FI:
OPC->_float = (float)(OPA->_float > OPB->_int);
break;
case OP_LT:
OPC->_float = (float)(OPA->_float < OPB->_float);
break;
case OP_LT_I:
OPC->_int = (int)(OPA->_int < OPB->_int);
break;
case OP_LT_IF:
OPC->_float = (float)(OPA->_int < OPB->_float);
break;
case OP_LT_FI:
OPC->_float = (float)(OPA->_float < OPB->_int);
break;
case OP_AND:
OPC->_float = (float)(OPA->_float && OPB->_float);
break;
case OP_OR:
OPC->_float = (float)(OPA->_float || OPB->_float);
break;
case OP_NOT_F:
OPC->_float = (float)(!OPA->_float);
break;
case OP_NOT_V:
OPC->_float = (float)(!OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2]);
break;
case OP_NOT_S:
OPC->_float = (float)(!(OPA->string) || !*(OPA->string+progfuncs->stringtable));
break;
case OP_NOT_FNC:
OPC->_float = (float)(!(OPA->function & ~0xff000000));
break;
case OP_NOT_ENT:
OPC->_float = (float)(PROG_TO_EDICT(OPA->edict) == (edictrun_t *)sv_edicts);
break;
case OP_EQ_F:
OPC->_float = (float)(OPA->_float == OPB->_float);
break;
case OP_EQ_IF:
OPC->_float = (float)(OPA->_int == OPB->_float);
break;
case OP_EQ_FI:
OPC->_float = (float)(OPA->_float == OPB->_int);
break;
case OP_EQ_V:
OPC->_float = (float)((OPA->vector[0] == OPB->vector[0]) &&
(OPA->vector[1] == OPB->vector[1]) &&
(OPA->vector[2] == OPB->vector[2]));
break;
case OP_EQ_S:
if (OPA->string==OPB->string)
OPC->_float = true;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
OPC->_float = true;
else
OPC->_float = false;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
OPC->_float = true;
else
OPC->_float = false;
}
else
OPC->_float = (float)(!strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
break;
case OP_EQ_E:
OPC->_float = (float)(OPA->_int == OPB->_int);
break;
case OP_EQ_FNC:
OPC->_float = (float)(OPA->function == OPB->function);
break;
case OP_NE_F:
OPC->_float = (float)(OPA->_float != OPB->_float);
break;
case OP_NE_V:
OPC->_float = (float)((OPA->vector[0] != OPB->vector[0]) ||
(OPA->vector[1] != OPB->vector[1]) ||
(OPA->vector[2] != OPB->vector[2]));
break;
case OP_NE_S:
if (OPA->string==OPB->string)
OPC->_float = false;
else if (!OPA->string)
{
if (!OPB->string || !*(OPB->string+progfuncs->stringtable))
OPC->_float = false;
else
OPC->_float = true;
}
else if (!OPB->string)
{
if (!OPA->string || !*(OPA->string+progfuncs->stringtable))
OPC->_float = false;
else
OPC->_float = true;
}
else
OPC->_float = (float)(strcmp(OPA->string+progfuncs->stringtable,OPB->string+progfuncs->stringtable));
break;
case OP_NE_E:
OPC->_float = (float)(OPA->_int != OPB->_int);
break;
case OP_NE_FNC:
OPC->_float = (float)(OPA->function != OPB->function);
break;
//==================
case OP_STORE_IF:
OPB->_float = (float)OPA->_int;
break;
case OP_STORE_FI:
OPB->_int = (int)OPA->_float;
break;
case OP_STORE_I:
OPB->_int = OPA->_int;
break;
case OP_STORE_F:
case OP_STORE_ENT:
case OP_STORE_FLD: // integers
case OP_STORE_S:
case OP_STORE_FNC: // pointers
OPB->_int = OPA->_int;
break;
case OP_STORE_V:
OPB->vector[0] = OPA->vector[0];
OPB->vector[1] = OPA->vector[1];
OPB->vector[2] = OPA->vector[2];
break;
//store a value to a pointer
case OP_STOREP_IF:
ptr = (eval_t *)(OPB->_int);
ptr->_float = (float)OPA->_int;
break;
case OP_STOREP_FI:
ptr = (eval_t *)(OPB->_int);
ptr->_int = (int)OPA->_float;
break;
case OP_STOREP_I:
ptr = (eval_t *)(OPB->_int);
ptr->_int = OPA->_int;
break;
case OP_STOREP_F:
case OP_STOREP_ENT:
case OP_STOREP_FLD: // integers
case OP_STOREP_S:
case OP_STOREP_FNC: // pointers
ptr = (eval_t *)(OPB->_int);
ptr->_int = OPA->_int;
break;
case OP_STOREP_V:
ptr = (eval_t *)(OPB->_int);
ptr->vector[0] = OPA->vector[0];
ptr->vector[1] = OPA->vector[1];
ptr->vector[2] = OPA->vector[2];
break;
case OP_STOREP_C: //store character in a string
ptr = (eval_t *)(OPB->_int);
*(unsigned char *)ptr = (char)OPA->_float;
break;
case OP_MULSTORE_F: // f *= f
OPB->_float *= OPA->_float;
break;
case OP_MULSTORE_V: // v *= f
OPB->vector[0] *= OPA->_float;
OPB->vector[1] *= OPA->_float;
OPB->vector[2] *= OPA->_float;
break;
case OP_MULSTOREP_F: // e.f *= f
ptr = (eval_t *)(OPB->_int);
OPC->_float = (ptr->_float *= OPA->_float);
break;
case OP_MULSTOREP_V: // e.v *= f
ptr = (eval_t *)(OPB->_int);
OPC->vector[0] = (ptr->vector[0] *= OPA->_float);
OPC->vector[0] = (ptr->vector[1] *= OPA->_float);
OPC->vector[0] = (ptr->vector[2] *= OPA->_float);
break;
case OP_DIVSTORE_F: // f /= f
OPB->_float /= OPA->_float;
break;
case OP_DIVSTOREP_F: // e.f /= f
ptr = (eval_t *)(OPB->_int);
OPC->_float = (ptr->_float /= OPA->_float);
break;
case OP_ADDSTORE_F: // f += f
OPB->_float += OPA->_float;
break;
case OP_ADDSTORE_V: // v += v
OPB->vector[0] += OPA->vector[0];
OPB->vector[1] += OPA->vector[1];
OPB->vector[2] += OPA->vector[2];
break;
case OP_ADDSTOREP_F: // e.f += f
ptr = (eval_t *)(OPB->_int);
OPC->_float = (ptr->_float += OPA->_float);
break;
case OP_ADDSTOREP_V: // e.v += v
ptr = (eval_t *)(OPB->_int);
OPC->vector[0] = (ptr->vector[0] += OPA->vector[0]);
OPC->vector[1] = (ptr->vector[1] += OPA->vector[1]);
OPC->vector[2] = (ptr->vector[2] += OPA->vector[2]);
break;
case OP_SUBSTORE_F: // f -= f
OPB->_float -= OPA->_float;
break;
case OP_SUBSTORE_V: // v -= v
OPB->vector[0] -= OPA->vector[0];
OPB->vector[1] -= OPA->vector[1];
OPB->vector[2] -= OPA->vector[2];
break;
case OP_SUBSTOREP_F: // e.f -= f
ptr = (eval_t *)(OPB->_int);
OPC->_float = (ptr->_float -= OPA->_float);
break;
case OP_SUBSTOREP_V: // e.v -= v
ptr = (eval_t *)(OPB->_int);
OPC->vector[0] = (ptr->vector[0] -= OPA->vector[0]);
OPC->vector[1] = (ptr->vector[1] -= OPA->vector[1]);
OPC->vector[2] = (ptr->vector[2] -= OPA->vector[2]);
break;
//get a pointer to a field var
case OP_ADDRESS:
ed = PROG_TO_EDICT(OPA->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
if (ed->readonly)
PR_RunError (progfuncs, "assignment to read-only entity");
OPC->_int = (int)(((int *)edvars(ed)) + OPB->_int);
break;
//load a field to a value
case OP_LOAD_I:
case OP_LOAD_F:
case OP_LOAD_FLD:
case OP_LOAD_ENT:
case OP_LOAD_S:
case OP_LOAD_FNC:
ed = PROG_TO_EDICT(OPA->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int);
OPC->_int = ptr->_int;
break;
case OP_LOAD_V:
ed = PROG_TO_EDICT(OPA->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int);
OPC->vector[0] = ptr->vector[0];
OPC->vector[1] = ptr->vector[1];
OPC->vector[2] = ptr->vector[2];
break;
//==================
case OP_IFNOTS:
RUNAWAYCHECK();
if (!OPA->string || !*OPA->string)
st += (sofs)st->b - 1; // offset the s++
break;
case OP_IFNOT:
RUNAWAYCHECK();
if (!OPA->_int)
st += (sofs)st->b - 1; // offset the s++
break;
case OP_IFS:
RUNAWAYCHECK();
if (OPA->string && *OPA->string)
st += (sofs)st->b - 1; // offset the s++
break;
case OP_IF:
RUNAWAYCHECK();
if (OPA->_int)
st += (sofs)st->b - 1; // offset the s++
break;
case OP_GOTO:
RUNAWAYCHECK();
st += (sofs)st->a - 1; // offset the s++
break;
case OP_CALL8H:
case OP_CALL7H:
case OP_CALL6H:
case OP_CALL5H:
case OP_CALL4H:
case OP_CALL3H:
case OP_CALL2H:
G_VECTOR(OFS_PARM1)[0] = OPC->vector[0];
G_VECTOR(OFS_PARM1)[1] = OPC->vector[1];
G_VECTOR(OFS_PARM1)[2] = OPC->vector[2];
case OP_CALL1H:
G_VECTOR(OFS_PARM0)[0] = OPB->vector[0];
G_VECTOR(OFS_PARM0)[1] = OPB->vector[1];
G_VECTOR(OFS_PARM0)[2] = OPB->vector[2];
case OP_CALL8:
case OP_CALL7:
case OP_CALL6:
case OP_CALL5:
case OP_CALL4:
case OP_CALL3:
case OP_CALL2:
case OP_CALL1:
case OP_CALL0:
RUNAWAYCHECK();
pr_xstatement = st-pr_statements;
if (st->op > OP_CALL8)
pr_argc = st->op - (OP_CALL1H-1);
else
pr_argc = st->op - OP_CALL0;
fnum = OPA->function;
if ((fnum & ~0xff000000)<=0)
{
pr_trace++;
printf("NULL function from qc.\n");
#ifndef DEBUGABLE
goto cont;
#endif
break;
}
p=pr_typecurrent;
//about to switch. needs caching.
//if it's an external call, switch now (before any function pointers are used)
PR_MoveParms(progfuncs, (fnum & 0xff000000)>>24, p);
PR_SwitchProgs(progfuncs, (fnum & 0xff000000)>>24);
newf = &pr_functions[fnum & ~0xff000000];
if (newf->first_statement < 0)
{ // negative statements are built in functions
i = -newf->first_statement;
// p = pr_typecurrent;
if (i < externs->numglobalbuiltins)
{
(*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
if (prinst->continuestatement!=-1)
{
st=&pr_statements[prinst->continuestatement];
prinst->continuestatement=-1;
break;
}
}
else
{
i -= externs->numglobalbuiltins;
if (i > current_progstate->numbuiltins)
{
if (newf->first_statement == -0x7fffffff)
((builtin_t)newf->profile) (progfuncs, (struct globalvars_s *)current_progstate->globals);
else
PR_RunError (progfuncs, "Bad builtin call number");
}
else
current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
}
PR_MoveParms(progfuncs, p, pr_typecurrent);
// memcpy(&pr_progstate[p].globals[OFS_RETURN], &current_progstate->globals[OFS_RETURN], sizeof(vec3_t));
PR_SwitchProgs(progfuncs, (progsnum_t)p);
//#ifndef DEBUGABLE //decide weather non debugger wants to start debugging.
s = st-pr_statements;
goto restart;
//#endif
// break;
}
// PR_MoveParms((OPA->function & 0xff000000)>>24, pr_typecurrent);
// PR_SwitchProgs((OPA->function & 0xff000000)>>24);
s = PR_EnterFunction (progfuncs, newf, p);
st = &pr_statements[s];
goto restart;
// break;
case OP_DONE:
case OP_RETURN:
RUNAWAYCHECK();
pr_globals[OFS_RETURN] = pr_globals[st->a];
pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
s = PR_LeaveFunction (progfuncs);
st = &pr_statements[s];
if (pr_depth == exitdepth)
{
PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
PR_SwitchProgs(progfuncs, initial_progs);
return; // all done
}
goto restart;
// break;
case OP_STATE:
externs->stateop(progfuncs, OPA->_float, OPB->function);
break;
case OP_ADD_I:
OPC->_int = OPA->_int + OPB->_int;
break;
case OP_ADD_FI:
OPC->_float = OPA->_float + (float)OPB->_int;
break;
case OP_ADD_IF:
OPC->_float = (float)OPA->_int + OPB->_float;
break;
case OP_SUB_I:
OPC->_int = OPA->_int - OPB->_int;
break;
case OP_SUB_FI:
OPC->_float = OPA->_float - (float)OPB->_int;
break;
case OP_SUB_IF:
OPC->_float = (float)OPA->_int - OPB->_float;
break;
case OP_C_ITOF:
OPC->_float = (float)OPA->_int;
break;
case OP_C_FTOI:
OPC->_int = (int)OPA->_float;
break;
case OP_CP_ITOF:
ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
OPC->_float = (float)ptr->_int;
break;
case OP_CP_FTOI:
ptr = (eval_t *)(((qbyte *)sv_edicts) + OPA->_int);
OPC->_int = (int)ptr->_float;
break;
case OP_BITAND_I:
OPC->_int = (OPA->_int & OPB->_int);
break;
case OP_BITOR_I:
OPC->_int = (OPA->_int | OPB->_int);
break;
case OP_MUL_I:
OPC->_int = OPA->_int * OPB->_int;
break;
case OP_DIV_I:
if (OPB->_int == 0) //no division by zero allowed...
OPC->_int = 0;
else
OPC->_int = OPA->_int / OPB->_int;
break;
case OP_EQ_I:
OPC->_int = (OPA->_int == OPB->_int);
break;
case OP_NE_I:
OPC->_int = (OPA->_int != OPB->_int);
break;
//array/structure reading/riting.
case OP_GLOBALADDRESS:
OPC->_int = (int)(&((int)(OPA->_int)) + OPB->_int);
break;
case OP_POINTER_ADD: //pointer to 32 bit (remember to *3 for vectors)
OPC->_int = OPA->_int + OPB->_int*4;
break;
case OP_LOADA_I:
case OP_LOADA_F:
case OP_LOADA_FLD:
case OP_LOADA_ENT:
case OP_LOADA_S:
case OP_LOADA_FNC:
ptr = (eval_t *)(&((int)(OPA->_int)) + OPB->_int);
OPC->_int = ptr->_int;
break;
case OP_LOADA_V:
ptr = (eval_t *)(&((int)(OPA->_int)) + OPB->_int);
OPC->vector[0] = ptr->vector[0];
OPC->vector[1] = ptr->vector[1];
OPC->vector[2] = ptr->vector[2];
break;
case OP_ADD_SF: //(char*)c = (char*)a + (float)b
OPC->_int = OPA->_int + (int)OPB->_float;
break;
case OP_SUB_S: //(float)c = (char*)a - (char*)b
OPC->_int = OPA->_int - OPB->_int;
break;
case OP_LOADP_C: //load character from a string
ptr = (eval_t *)(((int)(OPA->_int)) + (int)OPB->_float);
OPC->_float = *(unsigned char *)ptr;
break;
case OP_LOADP_I:
case OP_LOADP_F:
case OP_LOADP_FLD:
case OP_LOADP_ENT:
case OP_LOADP_S:
case OP_LOADP_FNC:
#ifdef PRBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int >= pr_edict_size/4)
{
Host_Error("Progs attempted to read an invalid field in an edict (%i)\n", OPB->_int);
return;
}
#endif
ptr = (eval_t *)(((int)(OPA->_int)) + OPB->_int);
OPC->_int = ptr->_int;
break;
case OP_LOADP_V:
#ifdef PRBOUNDSCHECK
if (OPB->_int < 0 || OPB->_int + 2 >= pr_edict_size/4)
{
Host_Error("Progs attempted to read an invalid field in an edict (%i)\n", OPB->_int);
return;
}
#endif
ptr = (eval_t *)(((int)(OPA->_int)) + OPB->_int);
OPC->vector[0] = ptr->vector[0];
OPC->vector[1] = ptr->vector[1];
OPC->vector[2] = ptr->vector[2];
break;
case OP_POWER_I:
OPC->_int = OPA->_int ^ OPB->_int;
break;
case OP_RSHIFT_I:
OPC->_int = OPA->_int >> OPB->_int;
break;
case OP_LSHIFT_I:
OPC->_int = OPA->_int << OPB->_int;
break;
case OP_FETCH_GBL_F:
case OP_FETCH_GBL_S:
case OP_FETCH_GBL_E:
case OP_FETCH_GBL_FNC:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
t = (eval_t *)&pr_globals[(uofs)st->a + i];
OPC->_int = t->_int;
break;
case OP_FETCH_GBL_V:
i = (int)OPB->_float;
if(i < 0 || i > G_INT((uofs)st->a - 1))
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
}
t = (eval_t *)&pr_globals[(uofs)st->a
+((int)OPB->_float)*3];
OPC->vector[0] = t->vector[0];
OPC->vector[1] = t->vector[1];
OPC->vector[2] = t->vector[2];
break;
case OP_CSTATE:
externs->cstateop(progfuncs, OPA->_float, OPB->_float, fnum);
break;
case OP_CWSTATE:
externs->cwstateop(progfuncs, OPA->_float, OPB->_float, fnum);
break;
case OP_THINKTIME:
externs->thinktimeop(progfuncs, (struct edict_s *)PROG_TO_EDICT(OPA->edict), OPB->_float);
break;
case OP_BITSET: // b (+) a
OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
break;
case OP_BITSETP: // .b (+) a
ptr = (eval_t *)(OPB->_int);
ptr->_float = (float)((int)ptr->_float | (int)OPA->_float);
break;
case OP_BITCLR: // b (-) a
OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
break;
case OP_BITCLRP: // .b (-) a
ptr = (eval_t *)(OPB->_int);
ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float));
break;
case OP_RAND0:
G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff);
break;
case OP_RAND1:
G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
break;
case OP_RAND2:
if(OPA->_float < OPB->_float)
{
G_FLOAT(OFS_RETURN) = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
*(OPB->_float-OPA->_float));
}
else
{
G_FLOAT(OFS_RETURN) = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
*(OPA->_float-OPB->_float));
}
break;
case OP_RANDV0:
G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff);
G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff);
G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff);
break;
case OP_RANDV1:
G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff)*OPA->vector[0];
G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff)*OPA->vector[1];
G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff)*OPA->vector[2];
break;
case OP_RANDV2:
for(i = 0; i < 3; i++)
{
if(OPA->vector[i] < OPB->vector[i])
{
G_FLOAT(OFS_RETURN+i) = OPA->vector[i]+((rand()&0x7fff)/((float)0x7fff)
*(OPB->vector[i]-OPA->vector[i]));
}
else
{
G_FLOAT(OFS_RETURN+i) = OPB->vector[i]+(rand()*(1.0f/RAND_MAX)
*(OPA->vector[i]-OPB->vector[i]));
}
}
break;
case OP_SWITCH_F:
case OP_SWITCH_V:
case OP_SWITCH_S:
case OP_SWITCH_E:
case OP_SWITCH_FNC:
swtch = OPA;
swtchtype = st->op;
RUNAWAYCHECK();
st += (sofs)st->b - 1; // offset the st++
break;
case OP_CASE:
switch(swtchtype)
{
case OP_SWITCH_F:
if (swtch->_float == OPA->_float)
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
break;
case OP_SWITCH_E:
case OP_SWITCH_FNC:
if (swtch->_int == OPA->_int)
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
break;
case OP_SWITCH_S:
if (swtch->_int == OPA->_int)
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
if ((!swtch->_int && progfuncs->stringtable[OPA->string]) || (!OPA->_int && progfuncs->stringtable[swtch->string])) //one is null (cannot be not both).
break;
if (!strcmp(progfuncs->stringtable+swtch->string, progfuncs->stringtable+OPA->string))
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
break;
case OP_SWITCH_V:
if (swtch->vector[0] == OPA->vector[0] && swtch->vector[1] == OPA->vector[1] && swtch->vector[2] == OPA->vector[2])
{
RUNAWAYCHECK();
st += (sofs)st->b-1; // -1 to offset the s++
}
break;
default:
PR_RunError (progfuncs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype);
break;
}
break;
case OP_CASERANGE:
switch(swtchtype)
{
case OP_SWITCH_F:
if (swtch->_float >= OPA->_float && swtch->_float <= OPB->_float)
{
RUNAWAYCHECK();
st += (sofs)st->c-1; // -1 to offset the s++
}
break;
default:
PR_RunError (progfuncs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype);
}
break;
default:
if (st->op & 0x8000) //break point!
{
pr_xstatement = s = st-pr_statements;
printf("Break point hit.\n");
if (pr_trace<1)
pr_trace=1; //this is what it's for
s = ShowStep(progfuncs, s);
st = &pr_statements[s]; //let the user move execution
pr_xstatement = s = st-pr_statements;
memcpy(&fakeop, st, sizeof(dstatement_t)); //don't hit the new statement as a break point, cos it's probably the same one.
fakeop.op &= ~0x8000;
st = &fakeop; //a little remapping...
goto reeval; //reexecute
}
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "Bad opcode %i", st->op);
}
}
#undef cont
#undef reeval
#undef st
#undef pr_statements
#undef fakeop
#undef dstatement_t
#undef sofs
#undef uofs

View file

@ -395,7 +395,7 @@ reeval:
if (ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", pr_xfunction->s_name);
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;

View file

@ -395,7 +395,7 @@ reeval:
if (ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", pr_xfunction->s_name);
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;

View file

@ -395,7 +395,7 @@ reeval:
if (ed->readonly)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "assignment to read-only entity in %s", pr_xfunction->s_name);
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
}
OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust));
break;

View file

@ -98,7 +98,9 @@ int PR_InitEnts(progfuncs_t *progfuncs, int max_ents)
return max_fields_size;
}
char tempedicts[2048]; //used as a safty buffer
edictrun_t tempedict; //used as a safty buffer
float tempedictfields[2048];
void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) //can be used to wipe all memory
{
int i;
@ -139,9 +141,12 @@ void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs)
prinst->reorganisefields = false;
maxedicts = 1;
prinst->edicttable = &sv_edicts;
sv_num_edicts = 1; //set up a safty buffer so things won't go horribly wrong too often
sv_edicts=(struct edict_s *)tempedicts;
((edictrun_t*)sv_edicts)->readonly = true;
sv_edicts=(struct edict_s *)&tempedict;
tempedict.readonly = true;
tempedict.fields = tempedictfields;
tempedict.isfree = false;
}

View file

@ -1620,7 +1620,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
ddef32_t *d32;
func_t CheckSpawn=0;
extern char tempedicts[];
extern edictrun_t tempedict;
int crc = 1;
int entsize = 0;
@ -1885,8 +1885,9 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
pr_typecurrent=0;
sv_num_edicts = 1; //set up a safty buffer so things won't go horribly wrong too often
sv_edicts=(struct edict_s *)tempedicts;
((edictrun_t*)sv_edicts)->readonly = true;
sv_edicts=(struct edict_s *)&tempedict;
prinst->edicttable = &sv_edicts;
sv_num_edicts = numents; //should be fine

View file

@ -209,8 +209,8 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
//editbadfile(pr_strings + pr_xfunction->s_file, -1);
pr_depth = 0; // dump the stack so host_error can shutdown functions
prinst->exitdepth = 0;
// pr_depth = 0; // dump the stack so host_error can shutdown functions
// prinst->exitdepth = 0;
Abort (string);
}
@ -259,7 +259,11 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
// save off any locals that the new function steps on (to a side place, fromwhere they are restored on exit)
c = f->locals;
if (localstack_used + c > LOCALSTACK_SIZE)
{
localstack_used -= pr_spushed;
pr_depth--;
PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack overflow\n");
}
for (i=0 ; i < c ; i++)
localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];

View file

@ -314,10 +314,10 @@ QCC_opcode_t pr_opcodes[] =
{7, "<THINKTIME>", "THINKTIME", -1, ASSOC_LEFT, &type_entity, &type_float, &type_void},
{7, "(+)", "BITSET", 6, ASSOC_RIGHT, &type_float, &type_float, &type_float},
{7, "(+)", "BITSETP", 6, ASSOC_RIGHT, &type_pointer, &type_float, &type_float},
{7, "(-)", "BITCLR", 6, ASSOC_RIGHT, &type_float, &type_float, &type_float},
{7, "(-)", "BITCLRP", 6, ASSOC_RIGHT, &type_pointer, &type_float, &type_float},
{7, "|=", "BITSET_F", 6, ASSOC_RIGHT, &type_float, &type_float, &type_float},
{7, "|=", "BITSETP_F", 6, ASSOC_RIGHT, &type_pointer, &type_float, &type_float},
{7, "(-)", "BITCLR_F", 6, ASSOC_RIGHT, &type_float, &type_float, &type_float},
{7, "(-)", "BITCLRP_F", 6, ASSOC_RIGHT, &type_pointer, &type_float, &type_float},
{7, "<RAND0>", "RAND0", -1, ASSOC_LEFT, &type_void, &type_void, &type_float},
{7, "<RAND1>", "RAND1", -1, ASSOC_LEFT, &type_float, &type_void, &type_float},
@ -477,18 +477,29 @@ QCC_opcode_t pr_opcodes[] =
{7, "<>", "GADDRESS", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_I", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_F", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FLD", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_ENT", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_S", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "GLOAD_FNC", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "<>", "BOUNDCHECK", -1, ASSOC_LEFT, &type_float, &type_float, &type_float},
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_void},
{7, "<PUSH>", "PUSH", -1, ASSOC_RIGHT, &type_float, &type_void, &type_pointer},
{7, "<POP>", "POP", -1, ASSOC_RIGHT, &type_float, &type_void, &type_void},
{7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_void},
{7, "<PUSH>", "PUSH", -1, ASSOC_RIGHT, &type_float, &type_void, &type_pointer},
{7, "<POP>", "POP", -1, ASSOC_RIGHT, &type_float, &type_void, &type_void},
{7, "|=", "BITSET_I", 6, ASSOC_RIGHT, &type_integer, &type_integer, &type_integer},
{7, "|=", "BITSETP_I", 6, ASSOC_RIGHT, &type_pointer, &type_integer, &type_integer},
{7, "*=", "MULSTORE_I", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_integer, &type_integer},
{7, "*=", "MULSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_vector},
{7, "/=", "DIVSTORE_I", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_integer, &type_integer},
{7, "/=", "DIVSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_vector},
{7, "+=", "ADDSTORE_I", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_integer, &type_integer},
{7, "+=", "ADDSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_integer},
{7, "-=", "SUBSTORE_I", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_integer, &type_integer},
{7, "-=", "SUBSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_vector, &type_vector},
{0, NULL}
};
@ -842,13 +853,14 @@ void QCC_FreeOffset(gofs_t ofs, unsigned int size)
{
freeoffset_t *fofs;
if (ofs+size == numpr_globals)
{
{ //fixme: is this a bug?
numpr_globals -= size;
return;
}
for (fofs = freeofs; fofs; fofs=fofs->next)
{
//fixme: if this means the last block becomes free, free them all.
if (fofs->ofs == ofs + size)
{
fofs->ofs -= size;
@ -1328,10 +1340,13 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
QCC_PR_ParseWarning(0, "Result of comparison is constant");
break;
case OP_EQ_F:
case OP_EQ_V:
case OP_EQ_S:
case OP_EQ_E:
case OP_EQ_FNC:
// if (opt_shortenifnots)
// if (var_b->constant && ((int*)qcc_pr_globals)[var_b->ofs]==0) // (a == 0) becomes (!a)
// op = &pr_opcodes[(op - pr_opcodes) - OP_EQ_F + OP_NOT_F];
case OP_EQ_V:
case OP_NE_F:
case OP_NE_V:
@ -7297,25 +7312,27 @@ void QCC_PR_ParseDefs (char *classname)
v = pr_immediate._float;
QCC_PR_Lex();
}
bits = 0;
i = (int)v;
if (i != v)
QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTINTEGER, "enumflags - %f not an integer", v);
else
{
while(i)
{
if (((i>>1)<<1) != i)
bits++;
i>>=1;
}
if (bits != 1)
QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)v);
}
}
bits = 0;
i = (int)v;
if (i != v)
QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTINTEGER, "enumflags - %f not an integer", v);
else
{
while(i)
{
if (((i>>1)<<1) != i)
bits++;
i>>=1;
}
if (bits != 1)
QCC_PR_ParseWarning(WARN_ENUMFLAGS_NOTBINARY, "enumflags - value %i not a single bit", (int)v);
}
def = QCC_MakeFloatDef(v);
pHash_Add(&globalstable, name, def, qccHunkAlloc(sizeof(bucket_t)));
v*=2;
if (QCC_PR_CheckToken("}"))

View file

@ -43,12 +43,12 @@ int numCompilerConstants;
char *pr_punctuation[] =
// longer symbols must be before a shorter partial match
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "(+)", "(-)", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL};
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "|=", "(-)", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL};
char *pr_punctuationremap[] = //a nice bit of evilness.
//|= -> (+)
//-> -> .
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)","(+)", "(-)", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL};
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "|=", "(-)", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL};
// simple types. function types are dynamically allocated
QCC_type_t *type_void;// = {ev_void/*, &def_void*/};

View file

@ -135,10 +135,21 @@ void NPP_Flush(void)
}
bufferlen = 0;
break;
case svcdp_showlmp:
case svcdp_hidelmp:
ignoreprotocol = true;
Con_Printf ("Ignoring svc_showlmp\n");
requireextension = PEXT_SHOWPIC;
buffer[0] = svc_hidepic;
break;
case svcdp_showlmp:
requireextension = PEXT_SHOWPIC;
memmove(buffer+2, buffer+1, bufferlen-1);
bufferlen++;
buffer[0] = svc_showpic;
buffer[1] = 0; //top left
//pad the bytes to shorts.
buffer[bufferlen] = buffer[bufferlen-1];
buffer[bufferlen-1] = 0;
buffer[bufferlen+1] = 0;
bufferlen+=2;
break;
case svc_temp_entity:
@ -455,13 +466,15 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
if (!data)
protocollen = bufferlen;
break;
case svcdp_showlmp: // [string] slotname [string] lmpfilename [short] x [short] y
case svcdp_showlmp: // [string] slotname [string] lmpfilename [byte] x [byte] y
//note: nehara uses bytes!
//and the rest of dp uses shorts. how nasty is that?
if (!data)
{ //second string, plus 4 bytes.
{ //second string, plus 2 bytes.
int i;
for (i = 0; i < bufferlen; i++)
if (!buffer[i])
protocollen = bufferlen+4;
protocollen = bufferlen+2;
}
break;
}

View file

@ -3022,6 +3022,53 @@ void PF_dropclient (progfuncs_t *prinst, struct globalvars_s *pr_globals)
cl->drop = true;
return;
}
//DP_QC_BOTCLIENT
//entity() spawnclient = #454;
void PF_spawnclient (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
for (i = 0; i < sv.allocated_client_slots; i++)
{
if (!*svs.clients[i].name)
{
svs.clients[i].protocol = SCP_BAD;
svs.clients[i].state = cs_spawned;
svs.clients[i].netchan.message.allowoverflow = true;
svs.clients[i].netchan.message.maxsize = 0;
svs.clients[i].datagram.allowoverflow = true;
svs.clients[i].datagram.maxsize = 0;
RETURN_EDICT(prinst, svs.clients[i].edict);
return;
}
}
RETURN_EDICT(prinst, sv.edicts);
}
//DP_QC_BOTCLIENT
//float(entity client) clienttype = #455;
void PF_clienttype (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int entnum = G_EDICTNUM(prinst, OFS_PARM0);
if (entnum < 1 || entnum > sv.allocated_client_slots)
{
G_FLOAT(OFS_RETURN) = 3; //not a client slot
return;
}
entnum--;
if (svs.clients[entnum].state < cs_connected)
{
G_FLOAT(OFS_RETURN) = 0; //disconnected
return;
}
if (svs.clients[entnum].protocol == SCP_BAD)
G_FLOAT(OFS_RETURN) = 2; //an active, not-bot client.
else
G_FLOAT(OFS_RETURN) = 1; //an active, not-bot client.
}
/*
=================
PF_localcmd
@ -5992,6 +6039,8 @@ lh_extension_t QSG_Extensions[] = {
{"DP_EF_FULLBRIGHT"}, //Rerouted to hexen2 support.
{"DP_EF_NODRAW"}, //implemented by sending it with no modelindex
{"DP_EF_RED"},
{"DP_ENT_EXTERIORMODELTOCLIENT"},
{"DP_GFX_SKINFILES"},
{"DP_HALFLIFE_MAP_CVAR"},
{"DP_MONSTERWALK"},
{"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code for hexen2 support.
@ -8288,22 +8337,87 @@ typedef struct {
float ang[3][3];
} md3tag_t;
md3tag_t *SV_GetTags(int modelindex, int *tagcount)
typedef struct zymlump_s
{
md3Header_t *file;
file = (md3Header_t*)COM_LoadTempFile(sv.model_precache[modelindex]);
int start;
int length;
} zymlump_t;
typedef struct zymtype1header_s
{
char id[12]; // "ZYMOTICMODEL", length 12, no termination
int type; // 0 (vertex morph) 1 (skeletal pose) or 2 (skeletal scripted)
int filesize; // size of entire model file
float mins[3], maxs[3], radius; // for clipping uses
int numverts;
int numtris;
int numsurfaces;
int numbones; // this may be zero in the vertex morph format (undecided)
int numscenes; // 0 in skeletal scripted models
// skeletal pose header
// lump offsets are relative to the file
zymlump_t lump_scenes; // zymscene_t scene[numscenes]; // name and other information for each scene (see zymscene struct)
zymlump_t lump_poses; // float pose[numposes][numbones][6]; // animation data
zymlump_t lump_bones; // zymbone_t bone[numbones];
zymlump_t lump_vertbonecounts; // int vertbonecounts[numvertices]; // how many bones influence each vertex (separate mainly to make this compress better)
zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct
zymlump_t lump_texcoords; // float texcoords[numvertices][2];
zymlump_t lump_render; // int renderlist[rendersize]; // sorted by shader with run lengths (int count), shaders are sequentially used, each run can be used with glDrawElements (each triangle is 3 int indices)
zymlump_t lump_surfnames; // char shadername[numsurfaces][32]; // shaders used on this model
zymlump_t lump_trizone; // byte trizone[numtris]; // see trizone explanation
} zymtype1header_t;
typedef struct zymbone_s
{
char name[32];
int flags;
int parent; // parent bone number
} zymbone_t;
int SV_TagForName(int modelindex, char *tagname)
{
int i;
unsigned int *file;
file = (void*)COM_LoadTempFile(sv.model_precache[modelindex]);
if (!file)
{
Con_Printf("setattachment: \"%s\" is missing\n", sv.model_precache[modelindex]);
return NULL;
return 0;
}
if (file->ident != MD3_IDENT)
if (*file == MD3_IDENT)
{
Con_DPrintf("setattachment: not an md3 (%s)\n", sv.model_precache[modelindex]);
return NULL;
md3Header_t *md3 = (md3Header_t*)file;
md3tag_t *tag;
tag = (md3tag_t*)((char*)md3 + md3->ofsTags);
for (i = 0;i < md3->numTags;i++)
{
if (!strcmp(tagname, tag[i].name))
{
return i + 1;
}
}
}
*tagcount = file->numTags;
return (md3tag_t*)((char*)file + file->ofsTags);
else if (!strncmp((char*)file, "ZYMOTICMODEL", 12) && BigLong(file[3]) == 1)
{
zymtype1header_t *zym = (zymtype1header_t*)file;
zymbone_t *tag;
tag = (zymbone_t*)((char*)zym + BigLong(zym->lump_bones.start));
for (i = BigLong(zym->numbones)-1;i >=0;i--)
{
if (!strcmp(tagname, tag[i].name))
{
return i + 1;
}
}
}
else
Con_DPrintf("setattachment: %s not supported\n", sv.model_precache[modelindex]);
return 0;
}
void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -8315,9 +8429,7 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
eval_t *te;
eval_t *ti;
int i, modelindex;
md3tag_t *model;
int tagcount;
int modelindex;
te = prinst->GetEdictFieldValue(prinst, e, "tag_entity", NULL);
ti = prinst->GetEdictFieldValue(prinst, e, "tag_index", NULL);
@ -8328,18 +8440,11 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (tagentity != sv.edicts && tagname && tagname[0])
{
modelindex = (int)tagentity->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS && (model = SV_GetTags(modelindex, &tagcount)))
if (modelindex > 0 && modelindex < MAX_MODELS && sv.model_precache[modelindex])
{
for (i = 0;i < tagcount;i++)
{
if (!strcmp(tagname, model[i].name))
{
e->tagindex = i + 1;
break;
}
}
e->tagindex = SV_TagForName(modelindex, tagname);
if (e->tagindex == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), model->name);
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.models[modelindex]->name);
}
else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity));
@ -8351,7 +8456,7 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
MSG_WriteShort(&sv.multicast, e->entnum);
MSG_WriteShort(&sv.multicast, e->tagent);
MSG_WriteShort(&sv.multicast, e->tagindex);
SV_MulticastProtExt(vec3_origin, MULTICAST_ALL_R, 0xffffffff, PEXT_SETATTACHMENT, 0);
if (te)
@ -8749,6 +8854,9 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"dropclient", PF_dropclient, 0, 0, 0, 453},// #453 void(entity player) dropclient
{"spawnclient", PF_spawnclient, 0, 0, 0, 454}, //entity() spawnclient = #454;
{"clienttype", PF_clienttype, 0, 0, 0, 455}, //float(entity client) clienttype = #455;
//end other peoples extras
{"writestring2", PF_WriteString2, 0, 0, 0, 700}, //writestring but without the null terminator. makes things a little nicer.

View file

@ -489,7 +489,7 @@ typedef struct client_s
unsigned long zquake_extensions;
enum {
SCP_BAD,
SCP_BAD, //don't send (a bot)
SCP_QUAKEWORLD,
SCP_QUAKE2,
SCP_NETQUAKE,
@ -967,6 +967,10 @@ void SV_FindModelNumbers (void);
//
// sv_user.c
//
#ifdef NQPROT
void SVNQ_New_f (void);
void SVNQ_ExecuteClientMessage (client_t *cl);
#endif
void SV_ExecuteClientMessage (client_t *cl);
void SVQ2_ExecuteClientMessage (client_t *cl);
int SV_PMTypeForClient (client_t *cl);

View file

@ -695,6 +695,323 @@ void SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *
MSG_WriteShort (msg, 0); // end of packetentities
}
#ifdef NQPROT
// reset all entity fields (typically used if status changed)
#define E5_FULLUPDATE (1<<0)
// E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8
// E5_ORIGIN32=1: float[3] = s->origin[0], s->origin[1], s->origin[2]
#define E5_ORIGIN (1<<1)
// E5_ANGLES16=0: byte[3] = s->angle[0] * 256 / 360, s->angle[1] * 256 / 360, s->angle[2] * 256 / 360
// E5_ANGLES16=1: short[3] = s->angle[0] * 65536 / 360, s->angle[1] * 65536 / 360, s->angle[2] * 65536 / 360
#define E5_ANGLES (1<<2)
// E5_MODEL16=0: byte = s->modelindex
// E5_MODEL16=1: short = s->modelindex
#define E5_MODEL (1<<3)
// E5_FRAME16=0: byte = s->frame
// E5_FRAME16=1: short = s->frame
#define E5_FRAME (1<<4)
// byte = s->skin
#define E5_SKIN (1<<5)
// E5_EFFECTS16=0 && E5_EFFECTS32=0: byte = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=0: short = s->effects
// E5_EFFECTS16=0 && E5_EFFECTS32=1: int = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=1: int = s->effects
#define E5_EFFECTS (1<<6)
// bits >= (1<<8)
#define E5_EXTEND1 (1<<7)
// byte = s->renderflags
#define E5_FLAGS (1<<8)
// byte = bound(0, s->alpha * 255, 255)
#define E5_ALPHA (1<<9)
// byte = bound(0, s->scale * 16, 255)
#define E5_SCALE (1<<10)
// flag
#define E5_ORIGIN32 (1<<11)
// flag
#define E5_ANGLES16 (1<<12)
// flag
#define E5_MODEL16 (1<<13)
// byte = s->colormap
#define E5_COLORMAP (1<<14)
// bits >= (1<<16)
#define E5_EXTEND2 (1<<15)
// short = s->tagentity
// byte = s->tagindex
#define E5_ATTACHMENT (1<<16)
// short[4] = s->light[0], s->light[1], s->light[2], s->light[3]
// byte = s->lightstyle
// byte = s->lightpflags
#define E5_LIGHT (1<<17)
// byte = s->glowsize
// byte = s->glowcolor
#define E5_GLOW (1<<18)
// short = s->effects
#define E5_EFFECTS16 (1<<19)
// int = s->effects
#define E5_EFFECTS32 (1<<20)
// flag
#define E5_FRAME16 (1<<21)
// unused
#define E5_UNUSED22 (1<<22)
// bits >= (1<<24)
#define E5_EXTEND3 (1<<23)
// unused
#define E5_UNUSED24 (1<<24)
// unused
#define E5_UNUSED25 (1<<25)
// unused
#define E5_UNUSED26 (1<<26)
// unused
#define E5_UNUSED27 (1<<27)
// unused
#define E5_UNUSED28 (1<<28)
// unused
#define E5_UNUSED29 (1<<29)
// unused
#define E5_UNUSED30 (1<<30)
// bits2 > 0
#define E5_EXTEND4 (1<<31)
void SVDP_EmitEntity(entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean isnew)
{
int bits;
if (!memcmp(from, to, sizeof(entity_state_t)))
return; //didn't change
bits = 0;
if (isnew)
bits |= E5_FULLUPDATE;
if (!VectorCompare(from->origin, to->origin))
bits |= E5_ORIGIN;
if (!VectorCompare(from->angles, to->angles))
bits |= E5_ANGLES;
if (from->modelindex != to->modelindex)
bits |= E5_MODEL;
if (from->frame != to->frame)
bits |= E5_FRAME;
if (from->skinnum != to->skinnum)
bits |= E5_SKIN;
if (from->effects != to->effects)
bits |= E5_EFFECTS;
if (from->flags != to->flags)
bits |= E5_FLAGS;
if (from->trans != to->trans)
bits |= E5_ALPHA;
// if (from->scale != to->scale)
// bits |= E5_SCALE;
if (from->colormap != to->colormap)
bits |= E5_COLORMAP;
// if (from->tagentity != to->tagentity || o->tagindex != to->tagindex)
// bits |= E5_ATTACHMENT;
// if (from->light[0] != to->light[0] || o->light[1] != to->light[1] || o->light[2] != to->light[2] || o->light[3] != to->light[3] || o->lightstyle != to->lightstyle || o->lightpflags != to->lightpflags)
// bits |= E5_LIGHT;
// if (from->glowsize != to->glowsize || o->glowcolor != to->glowcolor)
// bits |= E5_GLOW;
// if (from->colormod[0] != to->colormod[0] || o->colormod[1] != to->colormod[1] || o->colormod[2] != to->colormod[2])
// bits |= E5_COLORMOD;
if ((bits & E5_ORIGIN) && (/*!(to->flags & RENDER_LOWPRECISION) ||*/ to->origin[0] < -4096 || to->origin[0] >= 4096 || to->origin[1] < -4096 || to->origin[1] >= 4096 || to->origin[2] < -4096 || to->origin[2] >= 4096))
bits |= E5_ORIGIN32;
if ((bits & E5_ANGLES)/* && !(to->flags & RENDER_LOWPRECISION)*/)
bits |= E5_ANGLES16;
if ((bits & E5_MODEL) && to->modelindex >= 256)
bits |= E5_MODEL16;
if ((bits & E5_FRAME) && to->frame >= 256)
bits |= E5_FRAME16;
if (bits & E5_EFFECTS)
{
if (to->effects >= 65536)
bits |= E5_EFFECTS32;
else if (to->effects >= 256)
bits |= E5_EFFECTS16;
}
if (bits >= 256)
bits |= E5_EXTEND1;
if (bits >= 65536)
bits |= E5_EXTEND2;
if (bits >= 16777216)
bits |= E5_EXTEND3;
to->bitmask |= bits;
if (!bits)
return;
MSG_WriteShort(msg, to->number);
MSG_WriteByte(msg, bits & 0xFF);
if (bits & E5_EXTEND1)
MSG_WriteByte(msg, (bits >> 8) & 0xFF);
if (bits & E5_EXTEND2)
MSG_WriteByte(msg, (bits >> 16) & 0xFF);
if (bits & E5_EXTEND3)
MSG_WriteByte(msg, (bits >> 24) & 0xFF);
if (bits & E5_FLAGS)
MSG_WriteByte(msg, to->flags);
if (bits & E5_ORIGIN)
{
if (bits & E5_ORIGIN32)
{
MSG_WriteFloat(msg, to->origin[0]);
MSG_WriteFloat(msg, to->origin[1]);
MSG_WriteFloat(msg, to->origin[2]);
}
else
{
MSG_WriteShort(msg, to->origin[0]*8);
MSG_WriteShort(msg, to->origin[1]*8);
MSG_WriteShort(msg, to->origin[2]*8);
}
}
if (bits & E5_ANGLES)
{
if (bits & E5_ANGLES16)
{
MSG_WriteAngle16(msg, to->angles[0]);
MSG_WriteAngle16(msg, to->angles[1]);
MSG_WriteAngle16(msg, to->angles[2]);
}
else
{
MSG_WriteAngle8(msg, to->angles[0]);
MSG_WriteAngle8(msg, to->angles[1]);
MSG_WriteAngle8(msg, to->angles[2]);
}
}
if (bits & E5_MODEL)
{
if (bits & E5_MODEL16)
MSG_WriteShort(msg, to->modelindex);
else
MSG_WriteByte(msg, to->modelindex);
}
if (bits & E5_FRAME)
{
if (bits & E5_FRAME16)
MSG_WriteShort(msg, to->frame);
else
MSG_WriteByte(msg, to->frame);
}
if (bits & E5_SKIN)
MSG_WriteByte(msg, to->skinnum);
if (bits & E5_EFFECTS)
{
if (bits & E5_EFFECTS32)
MSG_WriteLong(msg, to->effects);
else if (bits & E5_EFFECTS16)
MSG_WriteShort(msg, to->effects);
else
MSG_WriteByte(msg, to->effects);
}
if (bits & E5_ALPHA)
MSG_WriteByte(msg, to->trans*255);
if (bits & E5_SCALE)
MSG_WriteByte(msg, to->scale);
if (bits & E5_COLORMAP)
MSG_WriteByte(msg, to->colormap);
// if (bits & E5_ATTACHMENT)
// {
// MSG_WriteShort(msg, to->tagentity);
// MSG_WriteByte(msg, to->tagindex);
// }
// if (bits & E5_LIGHT)
// {
// MSG_WriteShort(msg, to->light[0]);
// MSG_WriteShort(msg, to->light[1]);
// MSG_WriteShort(msg, to->light[2]);
// MSG_WriteShort(msg, to->light[3]);
// MSG_WriteByte(msg, to->lightstyle);
// MSG_WriteByte(msg, to->lightpflags);
// }
// if (bits & E5_GLOW)
// {
// MSG_WriteByte(msg, to->glowsize);
// MSG_WriteByte(msg, to->glowcolor);
// }
// if (bits & E5_COLORMOD)
// {
// MSG_WriteByte(msg, to->colormod[0]);
// MSG_WriteByte(msg, to->colormod[1]);
// MSG_WriteByte(msg, to->colormod[2]);
// }
}
void SVDP_EmitEntitiesUpdate (client_t *client, packet_entities_t *to, sizebuf_t *msg)
{
edict_t *ent;
client_frame_t *fromframe;
packet_entities_t *from;
int oldindex, newindex;
int oldnum, newnum;
int oldmax;
// this is the frame that we are going to delta update from
if (client->delta_sequence != -1)
{
fromframe = &client->frames[client->delta_sequence & UPDATE_MASK];
from = &fromframe->entities;
oldmax = from->num_entities;
}
else
{
oldmax = 0; // no delta update
from = NULL;
}
client->delta_sequence++;
MSG_WriteByte(msg, svcdp_entities);
MSG_WriteLong(msg, 0);
if (client->protocol == SCP_DARKPLACES7)
MSG_WriteLong(msg, 0);
for (newindex = 0; newindex < to->num_entities; newindex++)
to->entities[newindex].bitmask = 0;
newindex = 0;
oldindex = 0;
//Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK
// , client->netchan.outgoing_sequence & UPDATE_MASK);
while (newindex < to->num_entities || oldindex < oldmax)
{
newnum = newindex >= to->num_entities ? 0x7fff : to->entities[newindex].number;
oldnum = oldindex >= oldmax ? 0x7fff : from->entities[oldindex].number;
if (newnum == oldnum)
{ // delta update from old position
//Con_Printf ("delta %i\n", newnum);
SVDP_EmitEntity (&from->entities[oldindex], &to->entities[newindex], msg, false);
oldindex++;
newindex++;
continue;
}
if (newnum < oldnum)
{ // this is a new entity, send it from the baseline
ent = EDICT_NUM(svprogfuncs, newnum);
//Con_Printf ("baseline %i\n", newnum);
SVDP_EmitEntity (&ent->baseline, &to->entities[newindex], msg, true);
newindex++;
continue;
}
if (newnum > oldnum)
{ // the old entity isn't present in the new message
//Con_Printf ("remove %i\n", oldnum);
MSG_WriteShort(msg, oldnum | 0x8000);
oldindex++;
continue;
}
}
MSG_WriteShort(msg, 0x8000);
}
#endif
int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs)
@ -1940,9 +2257,6 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
edict_t *clent;
client_frame_t *frame;
entity_state_t *state;
#ifdef NQPROT
int nqprot = !ISQWCLIENT(client);
#endif
client_t *split;
@ -2077,7 +2391,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (client->viewent
#ifdef NQPROT
&& !nqprot
&& ISQWCLIENT(client)
#endif
) //this entity is watching from outside themselves. The client is tricked into thinking that they themselves are in the view ent, and a new dummy ent (the old them) must be spawned.
{
@ -2132,7 +2446,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
}
#ifdef NQPROT
for (e=(nqprot?1:sv.allocated_client_slots+1) ; e<sv.num_edicts ; e++)
for (e=(ISQWCLIENT(client)?sv.allocated_client_slots+1:1) ; e<sv.num_edicts ; e++)
#else
for (e=sv.allocated_client_slots+1 ; e<sv.num_edicts ; e++)
#endif
@ -2218,7 +2532,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
continue;
#ifdef NQPROT
if (nqprot)
if (client->protocol == SCP_NETQUAKE)
{
if (msg->cursize + 32 > msg->maxsize)
break;
@ -2226,8 +2540,9 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
continue;
}
#endif
if (SV_AddNailUpdate (ent))
continue; // added to the special update list
if (ISQWCLIENT(client))
if (SV_AddNailUpdate (ent))
continue; // added to the special update list
#ifdef PEXT_LIGHTUPDATES
if (client->fteprotocolextensions & PEXT_LIGHTUPDATES)
if (SV_AddLightUpdate (ent))
@ -2397,8 +2712,15 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
#endif
}
#ifdef NQPROT
if (nqprot)
if (client->protocol == SCP_NETQUAKE)
return;
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
{
SVDP_EmitEntitiesUpdate(client, pack, msg);
SV_EmitCSQCUpdate(client, msg);
return;
}
#endif
if (!sv.demostatevalid)

View file

@ -544,11 +544,15 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
if (sv_bigcoords.value)
{
sizeofcoord = 4;
sizeofangle = 2;
}
else
{
sizeofcoord = 2;
sizeofangle = 1;
sizeofangle = 1;
}
VoteFlushAll();
#ifndef SERVERONLY

View file

@ -242,6 +242,16 @@ void VARGS SV_Error (char *error, ...)
_vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
if (svprogfuncs)
{
int size = 1024*1024*8;
char *buffer = BZ_Malloc(size);
svprogfuncs->save_ents(svprogfuncs, buffer, &size, 3);
COM_WriteFile("ssqccore.txt", buffer, size);
BZ_Free(buffer);
}
SV_EndRedirect();
Con_Printf ("SV_Error: %s\n",string);
@ -299,8 +309,9 @@ void SV_FinalMessage (char *message)
for (i=0, cl = svs.clients ; i<MAX_CLIENTS ; i++, cl++)
if (cl->state >= cs_spawned)
Netchan_Transmit (&cl->netchan, sv.datagram.cursize
, sv.datagram.data, 10000);
if (ISNQCLIENT(cl) || ISQWCLIENT(cl))
Netchan_Transmit (&cl->netchan, sv.datagram.cursize
, sv.datagram.data, 10000);
}
@ -997,9 +1008,12 @@ void SVC_GetChallenge (void)
}
Netchan_OutOfBand(NS_SERVER, net_from, over-buf, buf);
// buf = va("challenge FTE%i", svs.challenges[i].challenge);
// Netchan_OutOfBand(NS_SERVER, net_from, strlen(buf)+1, buf);
if (sv_listen.value >= 2)
{
//dp can respond to this (and fte won't get confused because the challenge will be wrong)
buf = va("challenge FTE%i", svs.challenges[i].challenge);
Netchan_OutOfBand(NS_SERVER, net_from, strlen(buf)+1, buf);
}
}
// Netchan_OutOfBandPrint (net_from, "%c%i", S2C_CHALLENGE,
@ -1209,6 +1223,8 @@ client_t *SVC_DirectConnect(void)
if (*(Cmd_Argv(0)+7) == '\\')
{
if (sv_listen.value < 2)
return NULL;
Q_strncpyz (userinfo[0], net_message.data + 11, sizeof(userinfo[0])-1);
if (strcmp(Info_ValueForKey(userinfo[0], "protocol"), "darkplaces 3"))
@ -1225,7 +1241,15 @@ client_t *SVC_DirectConnect(void)
else
protocol = SCP_DARKPLACES6;
challenge = atoi(Info_ValueForKey(userinfo[0], "challenge"));
s = Info_ValueForKey(userinfo[0], "challenge");
if (!strncmp(s, "FTE", 3))
challenge = atoi(s+3);
else
challenge = atoi(s);
s = Info_ValueForKey(userinfo[0], "name");
if (!*s)
Info_SetValueForKey(userinfo[0], "name", "CONNECTING", sizeof(userinfo[0]));
qport = 0;
}
@ -1434,7 +1458,9 @@ client_t *SVC_DirectConnect(void)
SV_FixupName(name, name);
if (!*name)
{
name = "Hidden";
}
else if (!stricmp(name, "console"))
name = "Not Console"; //have fun dudes.
@ -2022,12 +2048,12 @@ qboolean SV_ConnectionlessPacket (void)
return false;
}
#ifdef NQPROT
void SVNQ_ConnectionlessPacket(void)
{
sizebuf_t sb;
int header;
int length;
client_t *client;
char *str;
char buffer[256];
if (net_from.type == NA_LOOPBACK)
@ -2077,6 +2103,7 @@ void SVNQ_ConnectionlessPacket(void)
break;
}
}
#endif
/*
==============================================================================
@ -2458,7 +2485,7 @@ void SV_CheckTimeouts (void)
if (cl->state == cs_connected || cl->state == cs_spawned) {
if (!cl->spectator)
nclients++;
if (cl->netchan.last_received < droptime && cl->netchan.remote_address.type != NA_LOOPBACK) {
if (cl->netchan.last_received < droptime && cl->netchan.remote_address.type != NA_LOOPBACK && cl->protocol != SCP_BAD) {
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTTIMEDOUT, cl->name);
SV_DropClient (cl);
cl->state = cs_free; // don't bother with zombie state
@ -3056,7 +3083,7 @@ void Master_Heartbeat (void)
{
char string[2048];
int active;
int i;
int i, j;
qboolean madeqwstring = false;
char data[2];
@ -3112,9 +3139,9 @@ void Master_Heartbeat (void)
{
// count active users
active = 0;
for (i=0 ; i<MAX_CLIENTS ; i++)
if (svs.clients[i].state == cs_connected ||
svs.clients[i].state == cs_spawned )
for (j=0 ; j<MAX_CLIENTS ; j++)
if (svs.clients[j].state == cs_connected ||
svs.clients[j].state == cs_spawned )
active++;
sprintf (string, "%c\n%i\n%i\n", S2M_HEARTBEAT,

View file

@ -1506,7 +1506,8 @@ void SV_WalkMove (edict_t *ent)
}
#else
// 1/32 epsilon to keep floating point happy
#define DIST_EPSILON (0.03125)
int SV_SetOnGround (edict_t *ent)
{
vec3_t end;
@ -1517,7 +1518,7 @@ int SV_SetOnGround (edict_t *ent)
end[1] = ent->v->origin[1];
end[2] = ent->v->origin[2] - 1;
trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
if (trace.fraction < 1 && trace.plane.normal[2] >= 0.7)
if (trace.fraction <= DIST_EPSILON && trace.plane.normal[2] >= 0.7)
{
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent);

View file

@ -223,17 +223,33 @@ EVENT MESSAGES
static void SV_PrintToClient(client_t *cl, int level, char *string)
{
ClientReliableWrite_Begin (cl, cl->protocol==SCP_QUAKE2?svcq2_print:svc_print, strlen(string)+3);
#ifdef NQPROT
if (!ISQWCLIENT(cl))
switch (cl->protocol)
{
case SCP_BAD: //bot
break;
#ifdef Q2SERVER
case SCP_QUAKE2:
ClientReliableWrite_Begin (cl, svcq2_print, strlen(string)+3);
ClientReliableWrite_Byte (cl, level);
ClientReliableWrite_String (cl, string);
break;
#endif
#ifdef NQPROT
case SCP_NETQUAKE:
case SCP_DARKPLACES6:
case SCP_DARKPLACES7:
ClientReliableWrite_Begin (cl, svc_print, strlen(string)+3);
if (level == PRINT_CHAT)
ClientReliableWrite_Byte (cl, 1);
}
else
ClientReliableWrite_String (cl, string);
break;
#endif
case SCP_QUAKEWORLD:
ClientReliableWrite_Begin (cl, svc_print, strlen(string)+3);
ClientReliableWrite_Byte (cl, level);
ClientReliableWrite_String (cl, string);
ClientReliableWrite_String (cl, string);
break;
}
}
@ -329,6 +345,8 @@ void VARGS SV_BroadcastPrintf (int level, char *fmt, ...)
continue;
if (!cl->state)
continue;
if (cl->protocol == SCP_BAD)
continue;
if (cl->controller)
continue;
@ -526,9 +544,14 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
continue;
}
#ifdef NQPROT
if (!ISQWCLIENT(client))
switch (client->protocol)
{
case SCP_BAD:
break;
#ifdef NQPROT
case SCP_NETQUAKE:
case SCP_DARKPLACES6:
case SCP_DARKPLACES7:
if (reliable)
{
ClientReliableCheckBlock(client, sv.nqmulticast.cursize);
@ -536,16 +559,18 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
else
SZ_Write (&client->datagram, sv.nqmulticast.data, sv.nqmulticast.cursize);
}
else
break;
#endif
if (reliable)
{
ClientReliableCheckBlock(client, sv.multicast.cursize);
ClientReliableWrite_SZ(client, sv.multicast.data, sv.multicast.cursize);
case SCP_QUAKEWORLD:
if (reliable)
{
ClientReliableCheckBlock(client, sv.multicast.cursize);
ClientReliableWrite_SZ(client, sv.multicast.data, sv.multicast.cursize);
}
else
SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
break;
}
else
SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
}
}
else
@ -914,11 +939,11 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
for (split = client; split; split=split->controlled, pnum++)
SV_WriteEntityDataToMessage(split, msg, pnum);
/*
MSG_WriteByte (msg, svc_time);
MSG_WriteFloat(msg, sv.physicstime);
client->nextservertimeupdate = sv.physicstime;
*/
// Z_EXT_TIME protocol extension
// every now and then, send an update so that extrapolation
// on client side doesn't stray too far off
@ -942,6 +967,7 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
MSG_WriteByte (msg, svc_time);
MSG_WriteFloat(msg, sv.physicstime);
client->nextservertimeupdate = sv.physicstime;
Con_Printf("%f\n", sv.physicstime);
bits = 0;
@ -960,6 +986,7 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
#define SU_WEAPONFRAME (1<<12)
#define SU_ARMOR (1<<13)
#define SU_WEAPON (1<<14)
#define SU_EXTEND1 (1<<15)
if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT)
bits |= SU_VIEWHEIGHT;
@ -1002,6 +1029,9 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
// if (ent->v->weapon)
bits |= SU_WEAPON;
if (bits >= 65536)
bits |= SU_EXTEND1;
// send the data
MSG_WriteByte (msg, svc_clientdata);
@ -1018,11 +1048,19 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
// if (bits & (SU_PUNCH1<<i))
// MSG_WriteChar (msg, ent->v->punchangle[i]);
if (bits & (SU_VELOCITY1<<i))
MSG_WriteChar (msg, ent->v->velocity[i]/16);
{
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
MSG_WriteCoord(msg, ent->v->velocity[i]);
else
MSG_WriteChar (msg, ent->v->velocity[i]/16);
}
}
// [always sent] if (bits & SU_ITEMS)
MSG_WriteLong (msg, items);
if (bits & SU_ITEMS)
MSG_WriteLong (msg, items);
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
return;
if (bits & SU_WEAPONFRAME)
MSG_WriteByte (msg, ent->v->weaponframe);
@ -1184,6 +1222,8 @@ void SV_UpdateClientStats (client_t *client, int pnum)
stats[STAT_VIEW2] = 0;
#endif
stats[STAT_VIEWZOOM] = 255;
SV_UpdateQCStats(ent, stats);
//dmw tweek for stats
@ -1526,6 +1566,9 @@ void SV_UpdateToReliableMessages (void)
if (client->controller)
continue; //splitscreen
if (client->protocol == SCP_BAD)
continue; //botclient
#ifdef Q2SERVER
if (ISQ2CLIENT(client))
{
@ -1681,6 +1724,13 @@ void SV_SendClientMessages (void)
}
}
if (c->protocol == SCP_BAD)
{
SZ_Clear (&c->netchan.message);
SZ_Clear (&c->datagram);
continue;
}
// if the reliable message overflowed,
// drop the client
if (c->netchan.message.overflowed)

View file

@ -3238,13 +3238,25 @@ void SVNQ_PreSpawn_f (void)
}
else
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
if (host_client->protocol != SCP_NETQUAKE && (state->modelindex > 255 || state->frame > 255))
{
MSG_WriteByte(&host_client->netchan.message, svcdp_spawnbaseline2);
MSG_WriteShort (&host_client->netchan.message, e);
MSG_WriteShort (&host_client->netchan.message, e);
MSG_WriteByte (&host_client->netchan.message, state->modelindex&255);
MSG_WriteShort (&host_client->netchan.message, state->modelindex);
MSG_WriteShort (&host_client->netchan.message, state->frame);
}
else
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, e);
MSG_WriteByte (&host_client->netchan.message, state->modelindex&255);
MSG_WriteByte (&host_client->netchan.message, state->frame&255);
}
MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
for (i=0 ; i<3 ; i++)
@ -4597,14 +4609,38 @@ void SVNQ_ReadClientMove (usercmd_t *move)
move->msec=100;
// read buttons
bits = MSG_ReadByte ();
if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7)
bits = MSG_ReadLong();
else
bits = MSG_ReadByte ();
move->buttons = bits;
i = MSG_ReadByte ();
if (i)
move->impulse = i;
if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7)
{
/*move->cursor_screen[0] = */MSG_ReadShort() * (1.0f / 32767.0f);
/*move->cursor_screen[1] = */MSG_ReadShort() * (1.0f / 32767.0f);
/*move->cursor_start[0] = */MSG_ReadFloat();
/*move->cursor_start[1] = */MSG_ReadFloat();
/*move->cursor_start[2] = */MSG_ReadFloat();
/*move->cursor_impact[0] = */MSG_ReadFloat();
/*move->cursor_impact[1] = */MSG_ReadFloat();
/*move->cursor_impact[2] = */MSG_ReadFloat();
/*move->cursor_entitynumber = */(unsigned short)MSG_ReadShort();
/* if (move->cursor_entitynumber >= prog->max_edicts)
{
Con_DPrintf("SV_ReadClientMessage: client send bad cursor_entitynumber\n");
move->cursor_entitynumber = 0;
}
// as requested by FrikaC, cursor_trace_ent is reset to world if the
// entity is free at time of receipt
if (PRVM_EDICT_NUM(move->cursor_entitynumber)->priv.server->free)
move->cursor_entitynumber = 0;
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
*/ }
if (i && SV_FiltureImpulse(i, host_client->trustlevel))
@ -4656,7 +4692,6 @@ void SVNQ_ExecuteClientMessage (client_t *cl)
// mark time so clients will know how much to predict
// other players
cl->localtime = sv.time;
cl->delta_sequence = -1; // no delta unless requested
while (1)
{
if (msg_badread)

View file

@ -67,6 +67,7 @@ void SWSCR_UpdateScreen (void)
#ifdef _WIN32
{ // don't suck up any cpu if minimized
extern qboolean Minimized;
if (Minimized)
return;
}