while (1)
{
// skip whitespace up to a /n
- while (*text && *text <= ' ' && *text != '\n')
+ while (*text && *text <= ' ' && *text != '\r' && *text != '\n')
text++;
- if (*text == '\n')
+ // line endings:
+ // UNIX: \n
+ // Mac: \r
+ // Windows: \r\n
+ if (*text == '\n' || *text == '\r')
{
// a newline seperates commands in the buffer
+ if (*text == '\r' && text[1] == '\n')
+ text++;
text++;
break;
}
// skip whitespace
skipwhite:
- for (;*data <= ' ' && (*data != '\n' || !returnnewline);data++)
+ // line endings:
+ // UNIX: \n
+ // Mac: \r
+ // Windows: \r\n
+ for (;*data <= ' ' && ((*data != '\n' && *data != '\r') || !returnnewline);data++)
{
if (*data == 0)
{
}
}
+ // handle Windows line ending
+ if (data[0] == '\r' && data[1] == '\n')
+ data++;
+
if (data[0] == '/' && data[1] == '/')
{
// comment
- while (*data && *data != '\n')
+ while (*data && *data != '\n' && *data != '\r')
data++;
goto skipwhite;
}
com_token[len] = 0;
*datapointer = data+1;
return true;
- }
+ }
else if (*data == '\'')
{
// quoted string
com_token[len] = 0;
*datapointer = data+1;
return true;
- }
+ }
+ else if (*data == '\r')
+ {
+ // translate Mac line ending to UNIX
+ com_token[len++] = '\n';
+ com_token[len] = 0;
+ *datapointer = data;
+ return true;
+ }
else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
{
// single character
if (*data == '/' && data[1] == '/')
{
// comment
- while (*data && *data != '\n')
+ while (*data && *data != '\n' && *data != '\r')
data++;
goto skipwhite;
}
// COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
{ "teu", "-teu", "TheEvilUnleashed", "baseteu", NULL, "teu", "teu" },
// GAME_BATTLEMECH
-// COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
+// COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
{ "battlemech", "-battlemech", "Battlemech", "base", NULL, "battlemech", "battlemech" },
// GAME_ZYMOTIC
// COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
{ "zymotic", "-zymotic", "Zymotic", "data", NULL, "zymotic", "zymotic" },
// GAME_FNIGGIUM
-// COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium
+// COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium
{ "fniggium", "-fniggium", "Fniggium", "data", NULL, "fniggium", "fniggium" },
// GAME_SETHERAL
-// COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
+// COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
{ "setheral", "-setheral", "Setheral", "data", NULL, "setheral", "setheral" },
// GAME_SOM
-// COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man
+// COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man
{ "som", "-som", "Son of Man", "id1", "sonofman", "som", "darkplaces" },
// GAME_TENEBRAE
// COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
commentprefixlength = 0;
if (commentprefix)
commentprefixlength = strlen(commentprefix);
- while (*l && *l != '\n')
+ while (*l && *l != '\n' && *l != '\r')
{
if (*l > ' ')
{
if (commentprefixlength && !strncmp(l, commentprefix, commentprefixlength))
{
- while (*l && *l != '\n')
+ while (*l && *l != '\n' && *l != '\r')
l++;
break;
}
else
l++;
}
+ // line endings:
+ // UNIX: \n
+ // Mac: \r
+ // Windows: \r\n
+ if (*l == '\r')
+ l++;
if (*l == '\n')
l++;
*text = l;
if (logfile != NULL || log_file.string[0] == '\0')
return;
- logfile = FS_Open (log_file.string, "a", false);
+ logfile = FS_Open (log_file.string, "ab", false);
if (logfile != NULL)
{
strlcpy (crt_log_file, log_file.string, sizeof (crt_log_file));
{
qfile_t *file;
- file = FS_Open (logfilename, "a", true);
+ file = FS_Open (logfilename, "ab", true);
if (file != NULL)
{
va_list argptr;
for (linewidth = con_linewidth; linewidth && text[linewidth-1] == ' '; linewidth--);
x = (vid.conwidth - linewidth * 8) / 2;
- } else
+ } else
x = 0;
DrawQ_String(x, v, text, con_linewidth, 8, 8, 1, 1, 1, 1, 0);
size_t real_length; // uncompressed file size (for files opened in "read" mode)
size_t position; // current position in the file
size_t offset; // offset into the package (0 if external file)
+ int ungetc; // single stored character from ungetc, cleared to EOF when read
// Contents buffer
size_t buff_ind, buff_len; // buffer current index and length
file = Mem_Alloc (fs_mempool, sizeof (*file));
memset (file, 0, sizeof (*file));
+ file->ungetc = EOF;
file->handle = open (filepath, mod | opt, 0666);
if (file->handle < 0)
file->real_length = pfile->realsize;
file->offset = pfile->offset;
file->position = 0;
+ file->ungetc = EOF;
if (lseek (file->handle, file->offset, SEEK_SET) == -1)
Sys_Error ("FS_OpenPackedFile: can't lseek to %s in %s (offset: %d)",
====================
FS_Getc
-Get the next character of a file
+Get stored ungetc character or the next character of a file
====================
*/
int FS_Getc (qfile_t* file)
{
char c;
- if (FS_Read (file, &c, 1) != 1)
+ if (file->ungetc != EOF)
+ {
+ c = file->ungetc;
+ file->ungetc = EOF;
+ }
+ else if (FS_Read (file, &c, 1) != 1)
return EOF;
return c;
}
+/*
+====================
+FS_UnGetc
+
+Put a character back into the Getc buffer (only supports one character!)
+====================
+*/
+void FS_UnGetc (qfile_t* file, unsigned char c)
+{
+ file->ungetc = c;
+}
+
+
/*
====================
FS_Seek
}
-/*
-====================
-FS_Gets
-
-Extract a line from a file
-====================
-*/
-char* FS_Gets (qfile_t* file, char* buffer, size_t buffersize)
-{
- size_t ind;
-
- for (ind = 0; ind < (size_t) buffersize - 1; ind++)
- {
- int c = FS_Getc (file);
- switch (c)
- {
- // End of file
- case EOF:
- if (!ind)
- return NULL;
-
- buffer[ind] = '\0';
- return buffer;
-
- // End of line
- case '\r':
- case '\n':
- buffer[ind] = '\n';
- buffer[ind + 1] = '\0';
- return buffer;
-
- default:
- buffer[ind] = c;
- }
-
- }
-
- buffer[buffersize - 1] = '\0';
- return buffer;
-}
-
-
-/*
-==========
-FS_Getline
-
-Dynamic length version of fgets. DO NOT free the buffer.
-==========
-*/
-char *FS_Getline (qfile_t *file)
-{
- static int size = 256;
- static char *buf = 0;
- char *t;
- int len;
-
- if (!buf)
- buf = Mem_Alloc (fs_mempool, size);
-
- if (!FS_Gets (file, buf, size))
- return 0;
-
- len = strlen (buf);
- while (buf[len - 1] != '\n' && buf[len - 1] != '\r')
- {
- t = Mem_Alloc (fs_mempool, size + 256);
- memcpy(t, buf, size);
- Mem_Free(buf);
- size += 256;
- buf = t;
- if (!FS_Gets (file, buf + len, size - len))
- break;
- len = strlen (buf);
- }
- while ((len = strlen(buf)) && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
- buf[len - 1] = 0;
- return buf;
-}
-
-
/*
============
FS_LoadFile
int FS_Printf(qfile_t* file, const char* format, ...);
int FS_VPrintf(qfile_t* file, const char* format, va_list ap);
int FS_Getc (qfile_t* file);
+void FS_UnGetc (qfile_t* file, unsigned char c);
int FS_Seek (qfile_t* file, long offset, int whence);
long FS_Tell (qfile_t* file);
-char *FS_Gets (qfile_t* file, char* buffer, size_t buffersize);
-char *FS_Getline (qfile_t *file); // DO NOT FREE the returned buffer
typedef struct fssearch_s
{
void Host_InitLocal (void)
{
Host_InitCommands ();
-
+
Cmd_AddCommand("saveconfig", Host_SaveConfig_f);
Cvar_RegisterVariable (&host_framerate);
// config.cfg cvars
if (host_initialized && cls.state != ca_dedicated)
{
- f = FS_Open ("config.cfg", "w", false);
+ f = FS_Open ("config.cfg", "wb", false);
if (!f)
{
Con_Print("Couldn't write config.cfg.\n");
EntityFrame4_FreeDatabase(host_client->entitydatabase4);
if (host_client->entitydatabase5)
EntityFrame5_FreeDatabase(host_client->entitydatabase5);
-
+
if (sv.active)
{
// clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
ED_ClearEdict(host_client->edict);
}
-
+
// clear the client struct (this sets active to false)
memset(host_client, 0, sizeof(*host_client));
void Host_Changelevel_f (void)
{
char level[MAX_QPATH];
-
+
if (Cmd_Argc() != 2)
{
Con_Print("changelevel <levelname> : continue game on a new level\n");
void Host_Restart_f (void)
{
char mapname[MAX_QPATH];
-
+
if (Cmd_Argc() != 1)
{
Con_Print("restart : restart current level\n");
FS_DefaultExtension (name, ".sav", sizeof (name));
Con_Printf("Saving game to %s...\n", name);
- f = FS_Open (name, "w", false);
+ f = FS_Open (name, "wb", false);
if (!f)
{
Con_Print("ERROR: couldn't open.\n");
qfile_t *f;
char filename[MAX_QPATH];
char mapname[MAX_QPATH];
- float time, tfloat;
- char buf[32768];
+ float time;
const char *start;
- char *str;
- int i, r;
+ const char *t;
+ char *text;
edict_t *ent;
+ int i;
int entnum;
int version;
float spawn_parms[NUM_SPAWN_PARMS];
cls.demonum = -1; // stop demo loop in case this fails
- f = FS_Open (filename, "r", false);
- if (!f)
+ t = text = FS_LoadFile (filename, tempmempool, false);
+ if (!text)
{
Con_Print("ERROR: couldn't open.\n");
return;
}
- str = FS_Getline (f);
- sscanf (str, "%i\n", &version);
+ // version
+ COM_ParseToken(&t, false);
+ version = atoi(com_token);
if (version != SAVEGAME_VERSION)
{
- FS_Close (f);
+ Mem_Free(text);
Con_Printf("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
return;
}
- str = FS_Getline (f);
+ // description
+ // this is a little hard to parse, as : is a separator in COM_ParseToken,
+ // so use the console parser instead
+ COM_ParseTokenConsole(&t);
+
for (i = 0;i < NUM_SPAWN_PARMS;i++)
{
- str = FS_Getline (f);
- sscanf (str, "%f\n", &spawn_parms[i]);
+ COM_ParseToken(&t, false);
+ spawn_parms[i] = atof(com_token);
}
+ // skill
+ COM_ParseToken(&t, false);
// this silliness is so we can load 1.06 save files, which have float skill values
- str = FS_Getline (f);
- sscanf (str, "%f\n", &tfloat);
- current_skill = (int)(tfloat + 0.1);
+ current_skill = (int)(atof(com_token) + 0.5);
Cvar_SetValue ("skill", (float)current_skill);
- strcpy (mapname, FS_Getline (f));
+ // mapname
+ COM_ParseToken(&t, false);
+ strcpy (mapname, com_token);
- str = FS_Getline (f);
- sscanf (str, "%f\n",&time);
+ // time
+ COM_ParseToken(&t, false);
+ time = atof(com_token);
allowcheats = sv_cheats.integer != 0;
+
SV_SpawnServer (mapname);
if (!sv.active)
{
+ Mem_Free(text);
Con_Print("Couldn't load map\n");
return;
}
for (i = 0;i < MAX_LIGHTSTYLES;i++)
{
- str = FS_Getline (f);
- sv.lightstyles[i] = Mem_Alloc(edictstring_mempool, strlen(str)+1);
- strcpy (sv.lightstyles[i], str);
+ // light style
+ COM_ParseToken(&t, false);
+ sv.lightstyles[i] = Mem_Alloc(edictstring_mempool, strlen(com_token)+1);
+ strcpy (sv.lightstyles[i], com_token);
}
// load the edicts out of the savegame file
entnum = -1;
for (;;)
{
- r = EOF;
- for (i = 0;i < (int)sizeof(buf) - 1;i++)
- {
- r = FS_Getc (f);
- if (r == EOF || !r)
- break;
- buf[i] = r;
- if (r == '}')
- {
- i++;
+ start = t;
+ while (COM_ParseToken(&t, false))
+ if (!strcmp(com_token, "}"))
break;
- }
- }
- if (r == EOF)
- break;
- if (i == sizeof(buf)-1)
- Host_Error ("Loadgame buffer overflow");
- buf[i] = 0;
- start = buf;
if (!COM_ParseToken(&start, false))
{
// end of file
break;
}
if (strcmp(com_token,"{"))
+ {
+ Mem_Free(text);
Host_Error ("First token isn't a brace");
+ }
if (entnum == -1)
{
{
// parse an edict
if (entnum >= MAX_EDICTS)
+ {
+ Mem_Free(text);
Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)\n", MAX_EDICTS);
+ }
while (entnum >= sv.max_edicts)
SV_IncreaseEdicts();
ent = EDICT_NUM(entnum);
SV_ClientPrintf("You can't change name more than once every 5 seconds!\n");
return;
}
-
+
host_client->nametime = sv.time + 5;
// point the string back at updateclient->name to keep it safe
Host_Playermodel_f
======================
*/
-cvar_t cl_playermodel = {CVAR_SAVE, "_cl_playermodel", ""};
+cvar_t cl_playermodel = {CVAR_SAVE, "_cl_playermodel", ""};
// the old cl_playermodel in cl_main has been renamed to __cl_playermodel
void Host_Playermodel_f (void)
{
SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n");
return;
}
-
+
host_client->nametime = sv.time + 5;
*/
SV_ClientPrintf("You can't change playermodel more than once every 5 seconds!\n");
return;
}
-
+
host_client->nametime = sv.time + 5;
*/
void M_ScanSaves (void)
{
- int i, j;
+ int i, j, len;
char name[MAX_OSPATH];
- char *str;
+ char buf[SAVEGAME_COMMENT_LENGTH + 256];
+ const char *t;
qfile_t *f;
int version;
strcpy (m_filenames[i], "--- UNUSED SLOT ---");
loadable[i] = false;
sprintf (name, "s%i.sav", i);
- f = FS_Open (name, "r", false);
+ f = FS_Open (name, "rb", false);
if (!f)
continue;
- str = FS_Getline (f);
- sscanf (str, "%i\n", &version);
- str = FS_Getline (f);
- strlcpy (m_filenames[i], str, sizeof (m_filenames[i]));
+ // read enough to get the comment
+ len = FS_Read(f, buf, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = 0;
+ t = buf;
+ // version
+ COM_ParseToken(&t, false);
+ version = atoi(com_token);
+ // description
+ COM_ParseToken(&t, false);
+ strlcpy (m_filenames[i], com_token, sizeof (m_filenames[i]));
// change _ back to space
for (j=0 ; j<SAVEGAME_COMMENT_LENGTH ; j++)
{
int optnum;
S_LocalSound ("sound/misc/menu3.wav");
-
+
optnum = 0;
if (options_graphics_cursor == optnum++) Cvar_SetValueQuick (&r_shadow_gloss, bound(0, r_shadow_gloss.integer + dir, 2));
// COMMANDLINEOPTION: Client: -useqmenu causes the first time you open the menu to use the quake menu, then reverts to menu.dat (if forceqmenu is 0)
if(COM_CheckParm("-useqmenu"))
MR_SetRouting (TRUE);
- else
+ else
MR_SetRouting (FALSE);
}
static void Mod_Q1BSP_LoadLightList(void)
{
int a, n, numlights;
- char lightsfilename[1024], *s, *t, *lightsstring;
+ char tempchar, *s, *t, *lightsstring, lightsfilename[1024];
mlight_t *e;
strlcpy (lightsfilename, loadmodel->name, sizeof (lightsfilename));
numlights = 0;
while (*s)
{
- while (*s && *s != '\n')
+ while (*s && *s != '\n' && *s != '\r')
s++;
if (!*s)
{
Mem_Free(lightsstring);
- Host_Error("lights file must end with a newline\n");
+ Con_Printf("lights file must end with a newline\n");
+ return;
}
s++;
numlights++;
while (*s && n < numlights)
{
t = s;
- while (*s && *s != '\n')
+ while (*s && *s != '\n' && *s != '\r')
s++;
if (!*s)
{
- Mem_Free(lightsstring);
- Host_Error("misparsed lights file!\n");
+ Con_Printf("misparsed lights file!\n");
+ break;
}
e = loadmodel->brushq1.lights + n;
+ tempchar = *s;
*s = 0;
a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->distbias, &e->style);
- *s = '\n';
+ *s = tempchar;
if (a != 14)
{
- Mem_Free(lightsstring);
- Host_Error("invalid lights file, found %d parameters on line %i, should be 14 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone distancebias style)\n", a, n + 1);
+ Con_Printf("invalid lights file, found %d parameters on line %i, should be 14 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone distancebias style)\n", a, n + 1);
+ break;
}
- s++;
+ if (*s == '\r')
+ s++;
+ if (*s == '\n')
+ s++;
n++;
}
if (*s)
- {
- Mem_Free(lightsstring);
- Host_Error("misparsed lights file!\n");
- }
+ Con_Printf("misparsed lights file!\n");
loadmodel->brushq1.numlights = numlights;
Mem_Free(lightsstring);
}
RemovePortalFromNodes(portal);
// cut the portal into two portals, one on each side of the node plane
- PolygonD_Divide(portal->numpoints, portal->points, plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, 1.0/32.0, MAX_PORTALPOINTS, frontpoints, &numfrontpoints, MAX_PORTALPOINTS, backpoints, &numbackpoints);
+ PolygonD_Divide(portal->numpoints, portal->points, plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, 1.0/32.0, MAX_PORTALPOINTS, frontpoints, &numfrontpoints, MAX_PORTALPOINTS, backpoints, &numbackpoints);
if (!numfrontpoints)
{
if (dist1near >= 0 && dist2near >= 0 && dist1far < 0 && dist2far >= 0){node = node->children[0];continue;}
if (dist1near >= 0 && dist2near >= 0 && dist1far >= 0 && dist2far < 0){node = node->children[0];continue;}
if (dist1near >= 0 && dist2near >= 0 && dist1far >= 0 && dist2far >= 0){node = node->children[0];continue;}
- {
+ {
if (dist2near < 0) // d1n<0 && d2n<0
{
if (dist2near < 0) // d1n<0 && d2n<0
// assume failure if it returns early
G_FLOAT(OFS_RETURN) = 0;
-
+
ent = PROG_TO_EDICT(pr_global_struct->self);
if (ent == sv.edicts)
PF_WARNING("walkmove: can not modify world entity\n");
string[end] = 0;
// remove \n following \r
if (c == '\r')
+ {
c = FS_Getc(pr_files[filenum]);
+ if (c != '\n')
+ FS_UnGetc(pr_files[filenum], c);
+ }
if (developer.integer)
Con_Printf("fgets: %s\n", string);
if (c >= 0 || end)
else
Matrix4x4_CreateIdentity(&tagmatrix);
- if ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
+ if ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
{ // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
attachloop = 0;
do
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+ out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
Matrix4x4_Copy(&tagmatrix, out);
// finally transformate by matrix of tag on parent entity
Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
out->m[0][3] = attachmatrix.m[0][3] + attachmatrix.m[0][0]*tagmatrix.m[0][3] + attachmatrix.m[0][1]*tagmatrix.m[1][3] + attachmatrix.m[0][2]*tagmatrix.m[2][3];
out->m[1][3] = attachmatrix.m[1][3] + attachmatrix.m[1][0]*tagmatrix.m[0][3] + attachmatrix.m[1][1]*tagmatrix.m[1][3] + attachmatrix.m[1][2]*tagmatrix.m[2][3];
- out->m[2][3] = attachmatrix.m[2][3] + attachmatrix.m[2][0]*tagmatrix.m[0][3] + attachmatrix.m[2][1]*tagmatrix.m[1][3] + attachmatrix.m[2][2]*tagmatrix.m[2][3];
+ out->m[2][3] = attachmatrix.m[2][3] + attachmatrix.m[2][0]*tagmatrix.m[0][3] + attachmatrix.m[2][1]*tagmatrix.m[1][3] + attachmatrix.m[2][2]*tagmatrix.m[2][3];
Matrix4x4_Copy(&tagmatrix, out);
ent = attachent;
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+ out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
{// RENDER_VIEWMODEL magic
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
- out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+ out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
/*
// Cl_bob, ported from rendering code
caseinsens = G_FLOAT(OFS_PARM1);
quiet = G_FLOAT(OFS_PARM2);
-
+
for(handle = 0; handle < MAX_SEARCHES; handle++)
if(!pr_fssearchlist[handle])
break;
int handle;
handle = G_FLOAT(OFS_PARM0);
-
+
if(handle < 0 || handle >= MAX_SEARCHES)
{
Con_Printf("PF_search_end: invalid handle %i\n", handle);
Con_Printf("PF_search_getsize: no such handle %i\n", handle);
return;
}
-
+
G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames;
}
Con_Printf("PF_search_getfilename: invalid filenum %i\n", filenum);
return;
}
-
+
tmp = PR_GetTempString();
strcpy(tmp, pr_fssearchlist[handle]->filenames[filenum]);
i++;
if (string[i] == 'n')
*new_p++ = '\n';
+ else if (string[i] == 'r')
+ *new_p++ = '\r';
else
*new_p++ = '\\';
}
ddef_t *infielddefs;
dfunction_t *dfunctions;
- if (!progsname || !*progsname)
+ if (!progsname || !*progsname)
Host_Error("PR_LoadProgs: passed empty progsname");
// flush the non-C variable lookup cache
entity findchainfloat(.string field, float match)
entity findchainentity(.string field, entity match)
-
+
string precache_file(string)
string precache_sound (string sample)
coredump()
const string str_cvar (string)
crash()
stackdump()
-
+
float search_begin(string pattern, float caseinsensitive, float quiet)
void search_end(float handle)
float search_getsize(float handle)
string altstr_prepare(string)
string altstr_get(string,float)
string altstr_set(string altstr, float num, string set)
-
-perhaps only : Menu : WriteMsg
+
+perhaps only : Menu : WriteMsg
===============================
WriteByte(float data, float dest, float desto)
WriteCoord(float data, float dest, float desto)
WriteString(string data, float dest, float desto)
WriteEntity(entity data, float dest, float desto)
-
+
Client & Menu : draw functions & video functions
===================================================
float iscachedpic(string pic)
-string precache_pic(string pic)
+string precache_pic(string pic)
freepic(string s)
float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
float cin_open(string file, string name)
void cin_close(string name)
void cin_setstate(string name, float type)
-float cin_getstate(string name)
+float cin_getstate(string name)
void cin_restart(string name)
==============================================================================
Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
return;
}
-
+
client = svs.clients + clientnum;
VM_VarString(1, string, sizeof(string));
MSG_WriteChar(&client->message,svc_print);
void VM_localsound(void)
{
char *s;
-
+
VM_SAFEPARMCOUNT(1,VM_localsound);
s = PRVM_G_STRING(OFS_PARM0);
Con_Printf("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME);
PRVM_G_FLOAT(OFS_RETURN) = -4;
return;
- }
+ }
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
const string str_cvar (string)
=================
*/
-void VM_str_cvar(void)
+void VM_str_cvar(void)
{
char *out, *name;
const char *cvar_string;
VM_CheckEmptyString(name);
- out = VM_GetTempString();
+ out = VM_GetTempString();
cvar_string = Cvar_VariableString(name);
-
+
strcpy(out, cvar_string);
PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out);
ent = PRVM_G_FLOAT(OFS_PARM0);
if(PRVM_PROG_TO_EDICT(ent)->p.e->free)
PRVM_ERROR ("VM_ftoe: %s tried to access a freed entity (entity %i)!\n", PRVM_NAME, ent);
-
+
PRVM_G_INT(OFS_RETURN) = ent;
}
=========
*/
-void VM_crash(void)
+void VM_crash(void)
{
VM_SAFEPARMCOUNT(0, VM_crash);
if(!sv.active)
{
- Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
+ Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
return;
}
string[end] = 0;
// remove \n following \r
if (c == '\r')
+ {
c = FS_Getc(VM_FILES[filenum]);
+ if (c != '\n')
+ FS_UnGetc(VM_FILES[filenum], c);
+ }
if (developer.integer >= 3)
Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
if (c >= 0 || end)
{
char *s;
- if(prog->argc < 1)
+ if(prog->argc < 1)
PRVM_ERROR("VM_strcat wrong parameter count (min. 1 expected ) !\n");
-
+
s = VM_GetTempString();
VM_VarString(0, s, VM_STRINGTEMP_LENGTH);
PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
{
VM_SAFEPARMCOUNT(0,VM_getmousepos);
-
+
PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
const char *data;
VM_SAFEPARMCOUNT(2, VM_parseentitydata);
-
+
// get edict and test it
ent = PRVM_G_EDICT(OFS_PARM0);
if (ent->p.e->free)
{
char *filename;
qbyte *data;
-
+
VM_SAFEPARMCOUNT(1,VM_loadfromfile);
-
+
filename = PRVM_G_STRING(OFS_PARM0);
// .. is parent directory on many platforms
// / is parent directory on Amiga
data = FS_LoadFile(filename, tempmempool, false);
if (data == NULL)
PRVM_G_FLOAT(OFS_RETURN) = -1;
-
+
PRVM_ED_LoadFromFile(data);
if(data)
caseinsens = PRVM_G_FLOAT(OFS_PARM1);
quiet = PRVM_G_FLOAT(OFS_PARM2);
-
+
for(handle = 0; handle < MAX_VMSEARCHES; handle++)
if(!VM_SEARCHLIST[handle])
break;
VM_SAFEPARMCOUNT(1, VM_search_end);
handle = PRVM_G_FLOAT(OFS_PARM0);
-
+
if(handle < 0 || handle >= MAX_VMSEARCHES)
{
Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME);
Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME);
return;
}
-
+
PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames;
}
Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME);
return;
}
-
+
tmp = VM_GetTempString();
strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]);
{
VM_SAFEPARMCOUNT(1,VM_iscachedpic);
- // drawq hasnt such a function, thus always return true
+ // drawq hasnt such a function, thus always return true
PRVM_G_FLOAT(OFS_RETURN) = false;
}
=========
VM_precache_pic
-string precache_pic(string pic)
+string precache_pic(string pic)
=========
*/
void VM_precache_pic(void)
{
char *s;
-
+
VM_SAFEPARMCOUNT(1, VM_precache_pic);
-
+
s = PRVM_G_STRING(OFS_PARM0);
PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-
+
if(!s)
PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME);
VM_CheckEmptyString (s);
-
+
if(!Draw_CachePic(s))
- PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
}
/*
VM_SAFEPARMCOUNT(1,VM_freepic);
s = PRVM_G_STRING(OFS_PARM0);
-
+
if(!s)
PRVM_ERROR ("VM_freepic: %s: NULL\n");
-
+
VM_CheckEmptyString (s);
-
+
Draw_FreePic(s);
}
PRVM_G_FLOAT(OFS_RETURN) = -1;
return;
}
-
+
pos = PRVM_G_VECTOR(OFS_PARM0);
scale = PRVM_G_VECTOR(OFS_PARM2);
rgb = PRVM_G_VECTOR(OFS_PARM3);
flag = (int)PRVM_G_FLOAT(OFS_PARM5);
-
+
if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
{
Con_Printf("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
PRVM_G_FLOAT(OFS_RETURN) = -2;
return;
}
-
+
if(pos[2] || scale[2])
- Con_Printf("VM_drawcharacter: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
+ Con_Printf("VM_drawcharacter: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
if(!scale[0] || !scale[1])
{
DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
+}
/*
=========
char *string;
int flag;
VM_SAFEPARMCOUNT(6,VM_drawstring);
-
+
string = PRVM_G_STRING(OFS_PARM1);
if(!string)
{
PRVM_G_FLOAT(OFS_RETURN) = -1;
return;
}
-
+
//VM_CheckEmptyString(string); Why should it be checked - perhaps the menu wants to support the precolored letters, too?
-
+
pos = PRVM_G_VECTOR(OFS_PARM0);
scale = PRVM_G_VECTOR(OFS_PARM2);
rgb = PRVM_G_VECTOR(OFS_PARM3);
flag = (int)PRVM_G_FLOAT(OFS_PARM5);
-
+
if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
{
Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
PRVM_G_FLOAT(OFS_RETURN) = -2;
return;
}
-
+
if(!scale[0] || !scale[1])
{
Con_Printf("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
}
if(pos[2] || scale[2])
- Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
-
+ Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
+
DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
if(!pic)
{
Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
- PRVM_G_FLOAT(OFS_RETURN) = -1;
+ PRVM_G_FLOAT(OFS_RETURN) = -1;
return;
}
PRVM_G_FLOAT(OFS_RETURN) = -4;
return;
}
-
+
pos = PRVM_G_VECTOR(OFS_PARM0);
size = PRVM_G_VECTOR(OFS_PARM2);
rgb = PRVM_G_VECTOR(OFS_PARM3);
}
if(pos[2] || size[2])
- Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
-
+ Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
+
DrawQ_Pic(pos[0], pos[1], pic, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
{
float *size, *pos, *rgb;
int flag;
-
+
VM_SAFEPARMCOUNT(5,VM_drawfill);
-
-
+
+
pos = PRVM_G_VECTOR(OFS_PARM0);
size = PRVM_G_VECTOR(OFS_PARM1);
rgb = PRVM_G_VECTOR(OFS_PARM2);
flag = (int) PRVM_G_FLOAT(OFS_PARM4);
-
+
if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
{
Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
PRVM_G_FLOAT(OFS_RETURN) = -2;
return;
}
-
+
if(pos[2] || size[2])
- Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
-
+ Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
+
DrawQ_Pic(pos[0], pos[1], 0, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag);
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid.conwidth);
y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid.conheight);
w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid.conwidth - x));
- h = bound(0, PRVM_G_FLOAT(OFS_PARM3) + PRVM_G_FLOAT(OFS_PARM1) - y, (vid.conheight - y));
+ h = bound(0, PRVM_G_FLOAT(OFS_PARM3) + PRVM_G_FLOAT(OFS_PARM1) - y, (vid.conheight - y));
DrawQ_SetClipArea(x, y, w, h);
}
cachepic_t *pic;
VM_SAFEPARMCOUNT(1,VM_getimagesize);
-
+
p = PRVM_G_STRING(OFS_PARM0);
if(!p)
PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
-
+
VM_CheckEmptyString (p);
pic = Draw_CachePic (p);
{
char *file;
char *name;
-
+
VM_SAFEPARMCOUNT( 2, VM_cin_open );
-
+
file = PRVM_G_STRING( OFS_PARM0 );
name = PRVM_G_STRING( OFS_PARM1 );
name = PRVM_G_STRING( OFS_PARM0 );
VM_CheckEmptyString( name );
- CL_CloseVideo( CL_GetVideo( name ) );
+ CL_CloseVideo( CL_GetVideo( name ) );
}
/*
video = CL_GetVideo( name );
if( video && state > CLVIDEO_UNUSED && state < CLVIDEO_STATECOUNT )
- CL_SetVideoState( video, state );
+ CL_SetVideoState( video, state );
}
/*
for( pos = altstr ; *pos && count ; pos++ )
if( *pos == '\\' && !*++pos )
- break;
+ break;
else if( *pos == '\'' )
count--;
for( ; *in ; in++ )
if( *in == '\'' || (*in == '\\' && !*++in) )
break;
-
+
if( !in ) {
PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( "" );
return;
else
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
-
+
/*
VM_M_callfunction
callfunction(...,string function_name)
-Extension: pass
+Extension: pass
=========
*/
mfunction_t *PRVM_ED_FindFunction (const char *name);
if(!s)
PRVM_ERROR("VM_M_callfunction: null string !\n");
- VM_CheckEmptyString(s);
+ VM_CheckEmptyString(s);
func = PRVM_ED_FindFunction(s);
PRVM_ExecuteProgram(func - prog->functions,"");
prog->argc++;
}
-}
+}
/*
=========
{
mfunction_t *func;
char *s;
-
+
VM_SAFEPARMCOUNT(1, VM_M_isfunction);
-
+
s = PRVM_G_STRING(OFS_PARM0);
-
+
if(!s)
PRVM_ERROR("VM_M_isfunction: null string !\n");
-
- VM_CheckEmptyString(s);
-
+
+ VM_CheckEmptyString(s);
+
func = PRVM_ED_FindFunction(s);
if(!func)
return;
}
- ent = PRVM_G_EDICT(OFS_PARM1);
+ ent = PRVM_G_EDICT(OFS_PARM1);
if(ent->p.e->free)
{
Con_Printf("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1));
PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
- PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
+ PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
}
/*
keynum = PRVM_G_FLOAT(OFS_PARM0);
tmp = VM_GetTempString();
-
+
strcpy(tmp, Key_KeynumToString(keynum));
PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
cmd = PRVM_G_STRING(OFS_PARM0);
-
+
VM_CheckEmptyString(cmd);
(ret = VM_GetTempString())[0] = 0;
-
+
M_FindKeysForCommand(cmd, keys);
for(i = 0; i < NUMKEYS; i++)
PRVM_G_FLOAT ( OFS_RETURN ) = hostcache_viewcount;
return;
case 1:
- PRVM_G_FLOAT ( OFS_RETURN ) = hostcache_cachecount;
+ PRVM_G_FLOAT ( OFS_RETURN ) = hostcache_cachecount;
case 2:
PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
return;
}
field = (int) PRVM_G_FLOAT( OFS_PARM1 );
-
+
switch( field ) {
case HCIF_CNAME:
strncpy( mask->info.cname, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.cname) );
mask->active = true;
mask->tests[field] = (int) PRVM_G_FLOAT( OFS_PARM3 );
-}
+}
/*
========================
key = PRVM_G_STRING( OFS_PARM0 );
VM_CheckEmptyString( key );
-
+
if( !strcmp( key, "cname" ) )
PRVM_G_FLOAT( OFS_RETURN ) = HCIF_CNAME;
else if( !strcmp( key, "ping" ) )
VM_tokenize,
VM_argv,
VM_isserver, // 60
- VM_clientcount,
- VM_clientstate,
+ VM_clientcount,
+ VM_clientstate,
VM_clcommand,
VM_changelevel,
- VM_localsound,
+ VM_localsound,
VM_getmousepos,
VM_gettime,
VM_loadfromdata,
VM_loadfromfile,
VM_modulo, // 70
- VM_str_cvar,
+ VM_str_cvar,
VM_crash,
VM_stackdump, // 73
VM_search_begin,
VM_search_end,
VM_search_getsize,
VM_search_getfilename, // 77
- VM_chr,
+ VM_chr,
VM_itof,
VM_ftoi, // 80
VM_itof, // isString
VM_drawcharacter,
VM_drawstring,
VM_drawpic,
- VM_drawfill,
+ VM_drawfill,
VM_drawsetcliparea,
VM_drawresetcliparea,
VM_getimagesize,// 460
VM_cin_open,
VM_cin_close,
- VM_cin_setstate,
+ VM_cin_setstate,
VM_cin_getstate,
VM_cin_restart, // 465
0,0,0,0,0, // 470
VM_M_sethostcachesort,
VM_M_refreshhostcache,
VM_M_gethostcachenumber,
- VM_M_gethostcacheindexforkey,
+ VM_M_gethostcacheindexforkey,
VM_M_addwantedhostcachekey // 623
};
void R_Shadow_LoadWorldLights(void)
{
int n, a, style, shadow, flags;
- char name[MAX_QPATH], cubemapname[MAX_QPATH], *lightsstring, *s, *t;
+ char tempchar, *lightsstring, *s, *t, name[MAX_QPATH], cubemapname[MAX_QPATH];
float origin[3], radius, color[3], angles[3], corona, coronasizescale, ambientscale, diffusescale, specularscale;
if (r_refdef.worldmodel == NULL)
{
}
*/
t = s;
- while (*s && *s != '\n')
+ while (*s && *s != '\n' && *s != '\r')
s++;
if (!*s)
break;
- *s = 0;
+ tempchar = *s;
shadow = true;
// check for modifier flags
if (*t == '!')
shadow = false;
t++;
}
+ *s = 0;
a = sscanf(t, "%f %f %f %f %f %f %f %d %s %f %f %f %f %f %f %f %f %i", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname, &corona, &angles[0], &angles[1], &angles[2], &coronasizescale, &ambientscale, &diffusescale, &specularscale, &flags);
+ *s = tempchar;
if (a < 18)
flags = LIGHTFLAG_REALTIMEMODE;
if (a < 17)
cubemapname[strlen(cubemapname)-1] = 0;
strcpy(cubemapname, cubemapname + 1);
}
- *s = '\n';
if (a < 8)
{
Con_Printf("found %d parameters on line %i, should be 8 or more parameters (origin[0] origin[1] origin[2] radius color[0] color[1] color[2] style \"cubemapname\" corona angles[0] angles[1] angles[2] coronasizescale ambientscale diffusescale specularscale flags)\n", a, n + 1);
VectorScale(color, r_editlights_rtlightscolorscale.value, color);
radius *= r_editlights_rtlightssizescale.value;
R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, corona, style, shadow, cubemapname, coronasizescale, ambientscale, diffusescale, specularscale, flags);
- s++;
+ if (*s == '\r')
+ s++;
+ if (*s == '\n')
+ s++;
n++;
}
if (*s)
void R_Shadow_LoadLightsFile(void)
{
int n, a, style;
- char name[MAX_QPATH], *lightsstring, *s, *t;
+ char tempchar, *lightsstring, *s, *t, name[MAX_QPATH];
float origin[3], radius, color[3], subtract, spotdir[3], spotcone, falloff, distbias;
if (r_refdef.worldmodel == NULL)
{
while (*s)
{
t = s;
- while (*s && *s != '\n')
+ while (*s && *s != '\n' && *s != '\r')
s++;
if (!*s)
break;
+ tempchar = *s;
*s = 0;
a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d", &origin[0], &origin[1], &origin[2], &falloff, &color[0], &color[1], &color[2], &subtract, &spotdir[0], &spotdir[1], &spotdir[2], &spotcone, &distbias, &style);
- *s = '\n';
+ *s = tempchar;
if (a < 14)
{
Con_Printf("invalid lights file, found %d parameters on line %i, should be 14 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone distancebias style)\n", a, n + 1);
radius = bound(15, radius, 4096);
VectorScale(color, (2.0f / (8388608.0f)), color);
R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, vec3_origin, color, radius, 0, style, true, NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE);
- s++;
+ if (*s == '\r')
+ s++;
+ if (*s == '\n')
+ s++;
n++;
}
if (*s)