Beispiel #1
0
/*
====================
COM_BlockSequenceCRCByte

For proxy protecting
====================
*/
byte	COM_BlockSequenceCRCByte (byte *base, int length, int sequence)
{
	int			n, x;
	const byte	*p;
	byte		chkb[60 + 4];
	uint16		crc;
	byte		r;

	if (sequence < 0)
		Sys_Error("sequence < 0, this shouldn't happen\n");

	p = chktbl + (sequence % (sizeof(chktbl) - 4));

	if (length > 60)
		length = 60;
	memcpy (chkb, base, length);

	chkb[length] = p[0];
	chkb[length+1] = p[1];
	chkb[length+2] = p[2];
	chkb[length+3] = p[3];

	length += 4;

	crc = CRC_Block(chkb, length);

	for (x=0, n=0; n<length; n++)
		x += chkb[n];

	r = (crc ^ x) & 0xff;

	return r;
}
Beispiel #2
0
static cvar_t *Cvar_FindVarLink (const char *var_name, cvar_t **parent, cvar_t ***link, cvar_t **prev_alpha)
{
	int hashindex;
	cvar_t *var;

	// use hash lookup to minimize search time
	hashindex = CRC_Block((const unsigned char *)var_name, strlen(var_name));
	if(parent) *parent = NULL;
	if(prev_alpha) *prev_alpha = NULL;
	if(link) *link = &cvar_hashtable[hashindex];
	for (var = cvar_hashtable[hashindex];var;var = var->nextonhashchain)
	{
		if (!strcmp (var_name, var->name))
		{
			if(!prev_alpha || var == cvar_vars)
				return var;

			*prev_alpha = cvar_vars;
			// if prev_alpha happens to become NULL then there has been some inconsistency elsewhere
			// already - should I still insert '*prev_alpha &&' in the loop?
			while((*prev_alpha)->next != var)
				*prev_alpha = (*prev_alpha)->next;
			return var;
		}
		if(parent) *parent = var;
	}

	return NULL;
}
Beispiel #3
0
static unsigned SV_CheckModel(char *mdl)
{
	unsigned char *buf;
	unsigned short crc;
	int filesize;
	int mark;

	mark = Hunk_LowMark ();
	buf = (byte *) FS_LoadHunkFile (mdl, &filesize);
	if (!buf)
	{
		if (!strcmp (mdl, "progs/player.mdl"))
			return 33168;
		else if (!strcmp (mdl, "progs/newplayer.mdl"))
			return 62211;
		else if (!strcmp (mdl, "progs/eyes.mdl"))
			return 6967;
		else
			SV_Error ("SV_CheckModel: could not load %s\n", mdl);
	}

	crc = CRC_Block (buf, filesize);
	Hunk_FreeToLowMark (mark);

	return crc;
}
Beispiel #4
0
/*
============
Cvar_FindVar
============
*/
cvar_t *Cvar_FindVar (const char *var_name)
{
	int hashindex;
	cvar_t *var;

	// use hash lookup to minimize search time
	hashindex = CRC_Block((const unsigned char *)var_name, strlen(var_name)) % CVAR_HASHSIZE;
	for (var = cvar_hashtable[hashindex];var;var = var->nextonhashchain)
		if (!strcmp (var_name, var->name))
			return var;

	return NULL;
}
Beispiel #5
0
unsigned SV_CheckModel(char *mdl)
{
	byte	stackbuf[1024];		// avoid dirtying the cache heap
	byte *buf;
	unsigned short crc;

	buf = (byte *)FS_LoadStackFile (mdl, stackbuf, sizeof(stackbuf));
	if (!buf)
		Host_Error ("SV_CheckModel: could not load %s\n", mdl);
	crc = CRC_Block(buf, fs_filesize);

	return crc;
}
Beispiel #6
0
void PR_LoadProgs (void)
{
	int	i;
	char num[32];
	char name[MAX_OSPATH];
	int filesize;

	// flush the non-C variable lookup cache
	for (i = 0; i < GEFV_CACHESIZE; i++)
		gefvCache[i].field[0] = 0;

	// clear pr_newstrtbl
	PF_clear_strtbl();

	snprintf(name, sizeof(name), "%s.dat", sv_progsname.string);
	progs = (dprograms_t *)FS_LoadHunkFile (name, &filesize);
	if (!progs)
		progs = (dprograms_t *)FS_LoadHunkFile ("qwprogs.dat", &filesize);
	if (!progs)
		progs = (dprograms_t *)FS_LoadHunkFile ("spprogs.dat", &filesize);
#ifdef WITH_NQPROGS
	pr_nqprogs = false;
	if (!progs || Cvar_Value("sv_forcenqprogs")) {
		progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat", &filesize);
		if (progs)
			pr_nqprogs = true;
	}
#endif
	if (!progs)
		SV_Error ("PR_LoadProgs: couldn't load progs.dat");
	Con_DPrintf ("Programs occupy %iK.\n", filesize/1024);

	// add prog crc to the serverinfo
	snprintf (num, sizeof(num), "%i", CRC_Block ((byte *)progs, filesize));
#ifdef USE_PR2
	Info_SetStar( &_localinfo_, "*qvm", "DAT" );
	//	Info_SetValueForStarKey (svs.info, "*qvm", "DAT", MAX_SERVERINFO_STRING);
#endif
	Info_SetValueForStarKey (svs.info, "*progs", num, MAX_SERVERINFO_STRING);

	// byte swap the header
	for (i = 0; i < (int) sizeof(*progs) / 4 ; i++)
		((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );

	if (progs->version != PROG_VERSION)
		SV_Error ("qwprogs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
	if (progs->crc != (pr_nqprogs ? NQ_PROGHEADER_CRC : PROGHEADER_CRC))
		SV_Error ("You must have the qwprogs.dat from QuakeWorld installed");

	pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
	pr_strings = (char *)progs + progs->ofs_strings;
	pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
	pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
	pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);

	num_prstr = 0;

	pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
	pr_globals = (float *)pr_global_struct;

	pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);

	// byte swap the lumps
	for (i = 0; i < progs->numstatements; i++)
	{
		pr_statements[i].op = LittleShort(pr_statements[i].op);
		pr_statements[i].a = LittleShort(pr_statements[i].a);
		pr_statements[i].b = LittleShort(pr_statements[i].b);
		pr_statements[i].c = LittleShort(pr_statements[i].c);
	}

	for (i = 0; i < progs->numfunctions; i++)
	{
		pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
		pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
		pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
		pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
		pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
		pr_functions[i].locals = LittleLong (pr_functions[i].locals);
	}

	for (i = 0; i < progs->numglobaldefs; i++)
	{
		pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
		pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
		pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
	}

	for (i = 0; i < progs->numfielddefs; i++)
	{
		pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
		if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
			SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
		pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
		pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
	}

	for (i = 0; i < progs->numglobals; i++)
		((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);

#ifdef WITH_NQPROGS
	PR_InitPatchTables();
#endif

	// find optional QC-exported functions
	SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect");
	SpectatorThink = ED_FindFunctionOffset ("SpectatorThink");
	SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect");
	ChatMessage = ED_FindFunctionOffset ("ChatMessage");
	UserInfo_Changed = ED_FindFunctionOffset ("UserInfo_Changed");
	mod_ConsoleCmd = ED_FindFunctionOffset ("ConsoleCmd");
	mod_UserCmd = ED_FindFunctionOffset ("UserCmd");
	localinfoChanged = ED_FindFunctionOffset ("localinfoChanged");
	GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand");
	GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic");
	GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause");

	CheckKTPro ();
}
Beispiel #7
0
static uintptr_t
blend_get_hash (const void *e, void *unused)
{
	iqmblend_t *b = (iqmblend_t *) e;
	return CRC_Block ((byte *) b, sizeof (iqmblend_t));
}
Beispiel #8
0
/*
===============
PR_LoadProgs
===============
*/
void PR_LoadProgs (void)
{
	int	i;
	char	num[32];
	static int lumpsize[6] = { sizeof(dstatement_t), sizeof(ddef_t),
		sizeof(ddef_t), sizeof(dfunction_t), 4, 4 };
	int	filesize = 0;
	const char	*progsname;

	progs = NULL;

	// decide whether to load qwprogs.dat, progs.dat or spprogs.dat

#ifdef WITH_NQPROGS
	if (Cvar_Value("sv_forcenqprogs"))
		goto use_progs;
#endif

	if (!deathmatch.value)
	{
		if (Q_stricmp(com_gamedirfile, "qw") && 
			strcmp(com_gamedirfile, ""))
		{
			// if we're using a custom mod, anything
			// in gamedir is preferred to stock *progs.dat
			qbool check;
			check = FS_FindFile ("spprogs.dat");
			if (check && file_from_gamedir)
				goto use_spprogs;
#ifdef WITH_NQPROGS
			check = FS_FindFile ("progs.dat");
			if (check && file_from_gamedir)
				goto use_progs;
#endif
			check = FS_FindFile ("qwprogs.dat");
			if (check && file_from_gamedir)
				goto use_qwprogs;
		}

use_spprogs:
		progs = (dprograms_t *) FS_LoadHunkFile ("spprogs.dat");
		progsname = "spprogs.dat";
		pr_nqprogs = false;

		if (!progs) {
#ifdef WITH_NQPROGS
use_progs:
			progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat");
			progsname = "progs.dat";
			pr_nqprogs = true;
		}
#endif
		if (!progs) {
use_qwprogs:
			progs = (dprograms_t *)FS_LoadHunkFile ("qwprogs.dat");
			progsname = "qwprogs.dat";
			pr_nqprogs = false;
		}
	}
	else	// deathmatch
	{
		if (Q_stricmp(com_gamedirfile, "qw") && 
			strcmp(com_gamedirfile, ""))
		{
			qbool check;
			check = FS_FindFile ("qwprogs.dat");
			if (check && file_from_gamedir)
				goto dm_use_qwprogs;
#ifdef WITH_NQPROGS
			check = FS_FindFile ("progs.dat");
			if (check && file_from_gamedir)
				goto dm_use_progs;
#endif
		}

dm_use_qwprogs:
		progs = (dprograms_t *) FS_LoadHunkFile ("qwprogs.dat");
		progsname = "qwprogs.dat";
		pr_nqprogs = false;

		if (!progs) {
#ifdef WITH_NQPROGS
dm_use_progs:
			progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat");
			progsname = "progs.dat";
			pr_nqprogs = true;
		}
#endif
	}

	if (!progs)
		Host_Error ("PR_LoadProgs: couldn't load progs.dat");

	filesize = fs_filesize;

	if (filesize < (int)sizeof(*progs))
		Host_Error("%s is corrupt", progsname);

	Com_DPrintf ("Using %s (%i bytes).\n", progsname, filesize);

// add prog crc to the serverinfo
	sprintf (num, "%i", CRC_Block ((byte *)progs, filesize));
	svs.info.set("*progs", num);

// byte swap the header
	for (i = 0; i < sizeof(*progs)/4; i++)
		((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );		

	if (progs->version != PROG_VERSION)
		Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
	if (progs->crc != (pr_nqprogs ? NQ_PROGHEADER_CRC : PROGHEADER_CRC))
		Host_Error ("You must have the qwprogs.dat from QuakeWorld installed");

// check lump offsets and sizes
	for (i = 0; i < 6; i ++) {
		if (((int *)progs)[i*2 + 2] < sizeof(*progs)
			|| ((int *)progs)[i*2 + 2] + ((int *)progs)[i*2 + 3]*lumpsize[i] > filesize)
		Host_Error("progs.dat is corrupt");
	}

	pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
	pr_strings = (char *)progs + progs->ofs_strings;
	pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
	pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
	pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
	pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);

	pr_globals = (float *)pr_global_struct;

	PR_InitStrings ();

	pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
	
// byte swap the lumps
	for (i=0 ; i<progs->numstatements ; i++)
	{
		pr_statements[i].op = LittleShort(pr_statements[i].op);
		pr_statements[i].a = LittleShort(pr_statements[i].a);
		pr_statements[i].b = LittleShort(pr_statements[i].b);
		pr_statements[i].c = LittleShort(pr_statements[i].c);
	}

	for (i=0 ; i<progs->numfunctions; i++)
	{
	pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
	pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
	pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
	pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
	pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
	pr_functions[i].locals = LittleLong (pr_functions[i].locals);
	}	

	for (i=0 ; i<progs->numglobaldefs ; i++)
	{
		pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
		pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
		pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
	}

	for (i=0 ; i<progs->numfielddefs ; i++)
	{
		pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
		if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
			Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
		pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
		pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
	}


	for (i=0 ; i<progs->numglobals ; i++)
		((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);


#ifdef WITH_NQPROGS
	if (pr_nqprogs) {
		memcpy (pr_globaloffsetpatch, pr_globaloffsetpatch_nq, sizeof(pr_globaloffsetpatch));
		for (i = 0; i < 106; i++) {
			pr_fieldoffsetpatch[i] = (i < 8) ? i : (i < 25) ? i + 1 :
				(i < 28) ? i + (102 - 25) : (i < 73) ? i - 2 :
				(i < 74) ? i + (105 - 73) : (i < 105) ? i - 3 : /* (i == 105) */ 8;
		}

		for (i=0 ; i<progs->numfielddefs ; i++)
			pr_fielddefs[i].ofs = PR_FIELDOFS(pr_fielddefs[i].ofs);
	}
	else
	{
		memset (pr_globaloffsetpatch, 0, sizeof(pr_globaloffsetpatch));

		for (i = 0; i < 106; i++)
			pr_fieldoffsetpatch[i] = i;
	}
#endif

	// find optional QC-exported functions
	SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect");
	SpectatorThink = ED_FindFunctionOffset ("SpectatorThink");
	SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect");
	GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand");
	GE_ConsoleCommand = ED_FindFunctionOffset ("GE_ConsoleCommand");
	GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic");
	GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause");

	// find optional QC-exported fields
	fofs_maxspeed = ED_FindFieldOffset ("maxspeed");
	fofs_gravity = ED_FindFieldOffset ("gravity");
	fofs_items2 = ED_FindFieldOffset ("items2");
	fofs_movement = ED_FindFieldOffset ("movement");
	fofs_vw_index = ED_FindFieldOffset ("vw_index");
	for (i = 3; i < 8; i++)
		fofs_buttonX[i-3] = ED_FindFieldOffset(va("button%i", i));

	// reset stuff like ZQ_CLIENTCOMMAND, progs must enable it explicitly
	memset (&pr_ext_enabled, sizeof(pr_ext_enabled), 0);

	PR_Exec_Init ();
}
Beispiel #9
0
// Generate a chat message from a specified message type, and return
// the pointer of the generated message
char *CChatManager::GenerateChat(CBaseBot *pClient, const char *type)
{
   static char msg[256]; // for the chat message
   msg[0] = '\0'; // initialize the string

   unsigned short usCrc = CRC_Block((unsigned char *)type, strlen(type));

   // find if we already have this section
   int found;
   for (found = 0; found < m_ChatItem.size(); found++) {
      if (m_ChatItem[found].type == usCrc)
         break;
   }

   if (found < m_ChatItem.size()) {
      char sz[256];
      strncpy(sz, m_ChatItem[found].PickMessage(), 256);

      int length = strlen(sz);

      char *p = sz;
      while (p != NULL && *p) {
         if (*p == '%') {
            char type = *(++p); // skip to next character to get the type
            int hiscore = -9999, j, count;
            CClient *pPickedClient = NULL;
            char buffer[32];

            switch (type) {
            case '%':
               strncat(msg, "%", 256);
               break;

            case 'n': // bot name
               strncpy(buffer, pClient->GetNetName(), 32);
               HumanizeName(buffer);
               strncat(msg, buffer, 256); // append it to the message
               break;

            case 'r': // random opponent
               j = RandomLong(0, g_pServer->GetMaxClients());

               for (count = 0; count < g_pServer->GetMaxClients(); count++, j++) {
                  CClient *p = g_pServer->m_rgpClients[j];
                  if (p != pClient && p->IsValid()) {
                     strncpy(buffer, p->GetNetName(), 32);
                     HumanizeName(buffer);
                     strncat(msg, buffer, 256); // append it to the message
                     break;
                  }
               }

               if (count >= g_pServer->GetMaxClients())
                  return NULL; // can't find any player, don't say anything

               break;

            case 'f': // opponent in first place
               for (j = 0; j < g_pServer->GetMaxClients(); j++) {
                  CClient *p = g_pServer->m_rgpClients[j];
                  if (p == pClient || !p->IsValid())
                     continue;
                  if (p->GetFrags() >= hiscore) {
                     hiscore = p->GetFrags();
                     pPickedClient = p;
                  }
               }
               if (pPickedClient) {
                  strncpy(buffer, pPickedClient->GetNetName(), 32);
                  HumanizeName(buffer); // humanize the name
                  strncat(msg, buffer, 256); // append it to the message
               } else {
                  return NULL; // can't find such a player, don't say anything
               }
               break;

            case 'l': // opponent in last place
               hiscore = 9999;
               for (j = 0; j < g_pServer->GetMaxClients(); j++) {
                  CClient *p = g_pServer->m_rgpClients[j];
                  if (p == pClient || !p->IsValid())
                     continue;
                  if (p->GetFrags() <= hiscore) {
                     hiscore = p->GetFrags();
                     pPickedClient = p;
                  }
               }
               if (pPickedClient) {
                  strncpy(buffer, pPickedClient->GetNetName(), 32);
                  HumanizeName(buffer); // humanize the name
                  strncat(msg, buffer, 256); // append it to the message
               } else {
                  return NULL; // can't find such a player, don't say anything
               }
               break;

            case 'm': // map title
               strncat(msg, g_pServer->GetMapName(), 256); // get the map name
               break;

            case 'v': // last victim of this bot
               if (pClient->Chat()->m_strLastVictim.length() <= 0)
                  return NULL; // we don't have a victim yet, don't say anything
               strncat(msg, pClient->Chat()->m_strLastVictim.c_str(), 256);
               break;

            case 'k': // last player killed this bot
               if (pClient->Chat()->m_strLastKiller.length() <= 0)
                  return NULL; // this bot hasn't been killed yet, don't say anything
               strncat(msg, pClient->Chat()->m_strLastKiller.c_str(), 256);
               break;
            }

            p++; // skip to the next character
            continue;
         }

         char *prev = p;
         p = strchr(p, '%'); // search for the next "%" sign

         if (p) {
            *p = '\0'; // if found, terminate the string
         }

         strncat(msg, prev, 256); // append the remaining text

         if (p) {
            *p = '%'; // restore the '%'
         }
      }

      HumanizeChat(msg); // 'Humanize' the chat message
      return msg;
   }

   return NULL; // not found
}
Beispiel #10
0
// load the bot chat data file
void CChatManager::LoadBotChat()
{
   char str[256];

   FILE *fp = fopen(g_General.BuildFileName("botchat.txt"), "r");
   if (!fp) {
      printf("BOT: cannot load file botchat.txt !\n");
      return;
   }

   bool fIsReply = false, fLoadingKeywords = false;
   while (fgets(str, 256, fp)) {
      trim(str); // trim all the blanks or linefeeds

      // skip all comment lines or empty lines
      if (!str[0] || str[0] == ';' || str[0] == '/' || str[0] == '#')
         continue;

      // check if this is a section line (e.g., [SECTION])
      int length = strlen(str);

      if (str[0] == '[' && str[length - 1] == ']') {
         int i;

         char section[256];
         section[0] = '\0';

         strcpy(section, &str[1]);
         section[length - 2] = 0; // remove the ]

         trim(section);

         // convert the key name to upper case
         for (i = 0; i < length - 2; i++) {
            section[i] = toupper(section[i]);
         }

         if (strcmpi(section, "REPLIES") == 0) {
            fIsReply = true;
         } else {
            fIsReply = false;
            unsigned short usCrc = CRC_Block((unsigned char *)section, length - 2); // CRC the section name

            // add a session
            m_ChatItem.push_back(CChatItem(usCrc));
         }
      } else if (fIsReply) {
         if (strncmp(str, "@KEY ", 5) == 0) {
            // This is a keyword line. Add the keyword to our list
            if (!fLoadingKeywords) {
               m_ChatReply.push_back(CChatReply());
               fLoadingKeywords = true;
            }
            m_ChatReply[m_ChatReply.size() - 1].AddKeyword(&str[5]);
         } else if (m_ChatReply.size() > 0) {
            // This is a reply message line. Add it to our list
            m_ChatReply[m_ChatReply.size() - 1].AddMessage(str);
            fLoadingKeywords = false;
         }
      } else if (m_ChatItem.size() > 0) {
         // This is a chat message line. Add it to our list
         m_ChatItem[m_ChatItem.size() - 1].AddMessage(str);
      }
   }

   fclose(fp); // close the file
}
Beispiel #11
0
qbool VM_LoadBytecode( vm_t * vm, sys_callex_t syscall1 )
{
	char name[MAX_OSPATH];
	byte *buff;
	vmHeader_t *header;
	qvm_t *qvm;
	char num[32];
	int filesize;

	snprintf( name, sizeof( name ), "%s.qvm", vm->name );

	Con_DPrintf( "VM_LoadBytecode: load %s\n", name );
	buff = FS_LoadTempFile( name , &filesize );

	if ( !buff )
		return false;

	// add qvm crc to the serverinfo
	snprintf( num, sizeof(num), "%i", CRC_Block( ( byte * ) buff, filesize ) );
	Info_SetValueForStarKey( svs.info, "*progs", num, MAX_SERVERINFO_STRING );

	header = ( vmHeader_t * ) buff;

	header->vmMagic = LittleLong( header->vmMagic );
	header->instructionCount = LittleLong( header->instructionCount );
	header->codeOffset = LittleLong( header->codeOffset );
	header->codeLength = LittleLong( header->codeLength );
	header->dataOffset = LittleLong( header->dataOffset );
	header->dataLength = LittleLong( header->dataLength );
	header->litLength = LittleLong( header->litLength );
	header->bssLength = LittleLong( header->bssLength );

	// check file
	if ( header->vmMagic != VM_MAGIC || header->instructionCount <= 0 || header->codeLength <= 0 )
	{
		return false;
	}
	// create vitrual machine
	if(vm->hInst)
		qvm = (qvm_t *)vm->hInst;
	else
		qvm = (qvm_t *) Q_malloc (sizeof (qvm_t));

	qvm->len_cs = header->instructionCount + 1;	//bad opcode padding.
	qvm->len_ds = header->dataOffset + header->litLength + header->bssLength;
	//align ds
	qvm->ds_mask = 1;
	while( qvm->ds_mask < qvm->len_ds) qvm->ds_mask<<=1;
	qvm->len_ds = qvm->ds_mask;
	qvm->ds_mask--;

	qvm->len_ss = 0x10000;	// default by q3asm
	if ( qvm->len_ds < qvm->len_ss )
		Sys_Error( "VM_LoadBytecode: stacksize greater than data segment" );

	qvm->cs = ( qvm_instruction_t * ) Hunk_AllocName( qvm->len_cs * sizeof( qvm_instruction_t ), "qvmcode" );
	qvm->ds = (byte *) Hunk_AllocName( qvm->len_ds, "qvmdata" );
	qvm->ss = qvm->ds + qvm->len_ds - qvm->len_ss;

	// setup registers
	qvm->PC = 0;
	qvm->SP = 0;
	qvm->LP = qvm->len_ds - sizeof(int);
	qvm->cycles = 0;
	qvm->reenter = 0;
	qvm->syscall = syscall1;


	// load instructions
	{
		byte   *src = buff + header->codeOffset;
		qvm_instruction_t *dst = qvm->cs;
		opcode_t op;
		int     i;

		for ( i = 0; i < header->instructionCount; i++, dst++ )
		{
			op = (opcode_t) *src++;
			dst->opcode = op;
			switch ( op )
			{
			case OP_ARG:
				dst->parm._int = ( int ) *src++;
				break;

			case OP_ENTER:
			case OP_LEAVE:
			case OP_CONST:
			case OP_LOCAL:
			case OP_EQ:
			case OP_NE:
			case OP_LTI:
			case OP_LEI:
			case OP_GTI:
			case OP_GEI:
			case OP_LTU:
			case OP_LEU:
			case OP_GTU:
			case OP_GEU:
			case OP_EQF:
			case OP_NEF:
			case OP_LTF:
			case OP_LEF:
			case OP_GTF:
			case OP_GEF:
			case OP_BLOCK_COPY:

				dst->parm._int = LittleLong( *( int * ) src );
				src += 4;
				break;

			default:
				dst->parm._int = 0;
				break;
			}
		}
		dst->opcode = OP_BREAK;
		dst->parm._int = 0;
	}
	// load data segment
	{
		int   *src = ( int * ) ( buff + header->dataOffset );
		int   *dst = ( int * ) qvm->ds;
		int     i;

		for ( i = 0; i < header->dataLength / 4; i++ )
			*dst++ = LittleLong( *src++ );

		memcpy( dst, src, header->litLength );
	}

	LoadMapFile( qvm, vm->name );
	vm->type = VM_BYTECODE;
	vm->hInst = qvm;
	return true;
}
Beispiel #12
0
/*
=================
Mod_LoadAliasModel
=================
*/
void
Mod_LoadAliasModel(const model_loader_t *loader, model_t *mod, void *buffer,
		   const model_t *loadmodel, const char *loadname)
{
   byte *container;
   int i, j, pad;
   mdl_t *pinmodel;
   stvert_t *pinstverts;
   dtriangle_t *pintriangles;
   int version, numframes;
   int size;
   daliasframetype_t *pframetype;
   daliasframe_t *frame;
   daliasgroup_t *group;
   daliasskintype_t *pskintype;
   int start, end, total;
   float *intervals;

#ifdef QW_HACK
   const char *crcmodel = NULL;
   if (!strcmp(loadmodel->name, "progs/player.mdl"))
      crcmodel = "pmodel";
   if (!strcmp(loadmodel->name, "progs/eyes.mdl"))
      crcmodel = "emodel";

   if (crcmodel)
   {
      uint16_t crc = CRC_Block(buffer, com_filesize);
      Info_SetValueForKey(cls.userinfo, crcmodel, va("%d", (int)crc),
            MAX_INFO_STRING);

      if (cls.state >= ca_connected)
      {
         MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
         MSG_WriteStringf(&cls.netchan.message, "setinfo %s %d", crcmodel,
               (int)crc);
      }
   }
#endif

   start = Hunk_LowMark();

   pinmodel = (mdl_t *)buffer;

#ifdef MSB_FIRST
   version = LittleLong(pinmodel->version);
#else
   version = (pinmodel->version);
#endif
   if (version != ALIAS_VERSION)
      Sys_Error("%s has wrong version number (%i should be %i)",
            mod->name, version, ALIAS_VERSION);

   // allocate space for a working header, plus all the data except the frames,
   // skin and group info
   pad = loader->Aliashdr_Padding();
#ifdef MSB_FIRST
   size = pad + sizeof(aliashdr_t) +
      LittleLong(pinmodel->numframes) * sizeof(pheader->frames[0]);
#else
   size = pad + sizeof(aliashdr_t) +
      (pinmodel->numframes) * sizeof(pheader->frames[0]);
#endif

   container = (byte*)Hunk_AllocName(size, loadname);
   pheader = (aliashdr_t *)(container + pad);

#ifdef MSB_FIRST
   mod->flags = LittleLong(pinmodel->flags);

   // endian-adjust and copy the data, starting with the alias model header
   pheader->numskins = LittleLong(pinmodel->numskins);
   pheader->skinwidth = LittleLong(pinmodel->skinwidth);
   pheader->skinheight = LittleLong(pinmodel->skinheight);
#else
   mod->flags = (pinmodel->flags);

   pheader->numskins = (pinmodel->numskins);
   pheader->skinwidth = (pinmodel->skinwidth);
   pheader->skinheight = (pinmodel->skinheight);
#endif


   if (pheader->skinheight > MAX_LBM_HEIGHT)
      Sys_Error("model %s has a skin taller than %d", mod->name,
            MAX_LBM_HEIGHT);

#ifdef MSB_FIRST
   pheader->numverts = LittleLong(pinmodel->numverts);
#else
   pheader->numverts = (pinmodel->numverts);
#endif

   if (pheader->numverts <= 0)
      Sys_Error("model %s has no vertices", mod->name);

   if (pheader->numverts > MAXALIASVERTS)
      Sys_Error("model %s has too many vertices", mod->name);

#ifdef MSB_FIRST
   pheader->numtris = LittleLong(pinmodel->numtris);
#else
   pheader->numtris = (pinmodel->numtris);
#endif

   if (pheader->numtris <= 0)
      Sys_Error("model %s has no triangles", mod->name);

#ifdef MSB_FIRST
   pheader->numframes = LittleLong(pinmodel->numframes);
   pheader->size = LittleFloat(pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
   mod->synctype = (synctype_t)LittleLong(pinmodel->synctype);
#else
   pheader->numframes = (pinmodel->numframes);
   pheader->size = (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
   mod->synctype = (synctype_t)(pinmodel->synctype);
#endif
   mod->numframes = pheader->numframes;

   for (i = 0; i < 3; i++) {
#ifdef MSB_FIRST
      pheader->scale[i] = LittleFloat(pinmodel->scale[i]);
      pheader->scale_origin[i] = LittleFloat(pinmodel->scale_origin[i]);
#else
      pheader->scale[i] = (pinmodel->scale[i]);
      pheader->scale_origin[i] = (pinmodel->scale_origin[i]);
#endif
   }

   // load the skins
   pskintype = (daliasskintype_t *)&pinmodel[1];
   pskintype = (daliasskintype_t *)Mod_LoadAllSkins(loader, loadmodel, pheader->numskins,
         pskintype, loadname);

   // set base s and t vertices
   pinstverts = (stvert_t *)pskintype;
   for (i = 0; i < pheader->numverts; i++) {
#ifdef MSB_FIRST
      stverts[i].onseam = LittleLong(pinstverts[i].onseam);
      stverts[i].s = LittleLong(pinstverts[i].s);
      stverts[i].t = LittleLong(pinstverts[i].t);
#else
      stverts[i].onseam = (pinstverts[i].onseam);
      stverts[i].s = (pinstverts[i].s);
      stverts[i].t = (pinstverts[i].t);
#endif
   }

   // set up the triangles
   pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts];
   for (i = 0; i < pheader->numtris; i++)
   {
#ifdef MSB_FIRST
      triangles[i].facesfront = LittleLong(pintriangles[i].facesfront);
#else
      triangles[i].facesfront = (pintriangles[i].facesfront);
#endif
      for (j = 0; j < 3; j++)
      {
#ifdef MSB_FIRST
         triangles[i].vertindex[j] = LittleLong(pintriangles[i].vertindex[j]);
#else
         triangles[i].vertindex[j] = (pintriangles[i].vertindex[j]);
#endif
         if (triangles[i].vertindex[j] < 0 ||
               triangles[i].vertindex[j] >= pheader->numverts)
            Sys_Error("%s: invalid vertex index (%d of %d) in %s\n",
                  __func__, triangles[i].vertindex[j],
                  pheader->numverts, mod->name);
      }
   }

   /* load the frames */
   numframes = pheader->numframes;
   if (numframes < 1)
      Sys_Error("%s: Invalid # of frames: %d", __func__, numframes);

   posenum = 0;
   pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris];

   for (i = 0; i < numframes; i++)
   {
#ifdef MSB_FIRST
      if (LittleLong(pframetype->type) == ALIAS_SINGLE)
#else
         if ((pframetype->type) == ALIAS_SINGLE)
#endif
         {
            frame = (daliasframe_t *)(pframetype + 1);
            Mod_LoadAliasFrame(frame, &pheader->frames[i]);
            pframetype = (daliasframetype_t *)&frame->verts[pheader->numverts];
         } else {
            group = (daliasgroup_t *)(pframetype + 1);
            pframetype = Mod_LoadAliasGroup(group, &pheader->frames[i],
                  loadname);
         }
   }
   pheader->numposes = posenum;
   mod->type = mod_alias;

   // FIXME: do this right
   mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
   mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;

   /* Save the frame intervals */
   intervals = (float*)Hunk_Alloc(pheader->numposes * sizeof(float));
   pheader->poseintervals = (byte *)intervals - (byte *)pheader;
   for (i = 0; i < pheader->numposes; i++)
      intervals[i] = poseintervals[i];

   /* Save the mesh data (verts, stverts, triangles) */
   loader->LoadMeshData(loadmodel, pheader, triangles, stverts, poseverts);

   // move the complete, relocatable alias model to the cache
   end = Hunk_LowMark();
   total = end - start;

   Cache_AllocPadded(&mod->cache, pad, total - pad, loadname);
   if (!mod->cache.data)
      return;

   memcpy((byte *)mod->cache.data - pad, container, total);

   Hunk_FreeToLowMark(start);
}
Beispiel #13
0
/*
=================
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
	int					i;
	mdl_t				*pmodel, *pinmodel;
	stvert_t			*pstverts, *pinstverts;
	aliashdr_t			*pheader;
	mtriangle_t			*ptri;
	dtriangle_t			*pintriangles;
	int					version, numframes, numskins;
	int					size;
	daliasframetype_t	*pframetype;
	daliasskintype_t	*pskintype;
	maliasskindesc_t	*pskindesc;
	int					skinsize;
	int					start, end, total;
	
// some models are special
	if(!strcmp(mod->name, "progs/player.mdl"))
		mod->modhint = MOD_PLAYER;
	else if(!strcmp(mod->name, "progs/eyes.mdl"))
		mod->modhint = MOD_EYES;
	else if (!strcmp(mod->name, "progs/flame.mdl") ||
		!strcmp(mod->name, "progs/flame2.mdl"))
		mod->modhint = MOD_FLAME;
/*	else if (!strcmp(mod->name, "progs/bolt.mdl") ||
		!strcmp(mod->name, "progs/bolt2.mdl") ||
		!strcmp(mod->name, "progs/bolt3.mdl"))
		mod->modhint = MOD_THUNDERBOLT;	*/

	if (mod->modhint == MOD_PLAYER || mod->modhint == MOD_EYES)
		mod->crc = CRC_Block (buffer, fs_filesize);

	start = Hunk_LowMark ();

	pinmodel = (mdl_t *)buffer;

	version = LittleLong (pinmodel->version);
	if (version != ALIAS_VERSION)
		Host_Error ("%s has wrong version number (%i should be %i)",
						mod->name, version, ALIAS_VERSION);

//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
	size = 	sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) *
			 sizeof (pheader->frames[0]) +
			sizeof (mdl_t) +
			LittleLong (pinmodel->numverts) * sizeof (stvert_t) +
			LittleLong (pinmodel->numtris) * sizeof (mtriangle_t);

	pheader = Hunk_AllocName (size, loadname);
	pmodel = (mdl_t *) ((byte *)&pheader[1] +
			(LittleLong (pinmodel->numframes) - 1) *
			 sizeof (pheader->frames[0]));
	
//	mod->cache.data = pheader;
	mod->flags = LittleLong (pinmodel->flags);

//
// endian-adjust and copy the data, starting with the alias model header
//
	pmodel->boundingradius = LittleFloat (pinmodel->boundingradius);
	pmodel->numskins = LittleLong (pinmodel->numskins);
	pmodel->skinwidth = LittleLong (pinmodel->skinwidth);
	pmodel->skinheight = LittleLong (pinmodel->skinheight);

	if (pmodel->skinheight > MAX_LBM_HEIGHT)
		Host_Error ("model %s has a skin taller than %d", mod->name,
				   MAX_LBM_HEIGHT);

	pmodel->numverts = LittleLong (pinmodel->numverts);

	if (pmodel->numverts <= 0)
		Host_Error ("model %s has no vertices", mod->name);

	if (pmodel->numverts > MAXALIASVERTS)
		Host_Error ("model %s has too many vertices", mod->name);

	pmodel->numtris = LittleLong (pinmodel->numtris);

	if (pmodel->numtris <= 0)
		Host_Error ("model %s has no triangles", mod->name);

	pmodel->numframes = LittleLong (pinmodel->numframes);
	pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO;
	mod->synctype = LittleLong (pinmodel->synctype);
	mod->numframes = pmodel->numframes;

	for (i=0 ; i<3 ; i++)
	{
		pmodel->scale[i] = LittleFloat (pinmodel->scale[i]);
		pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]);
		pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]);
	}

	numskins = pmodel->numskins;
	numframes = pmodel->numframes;

	if (pmodel->skinwidth & 0x03)
		Host_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4");

	pheader->model = (byte *)pmodel - (byte *)pheader;

//
// load the skins
//
	skinsize = pmodel->skinheight * pmodel->skinwidth;

	if (numskins < 1)
		Host_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);

	pskintype = (daliasskintype_t *)&pinmodel[1];

	pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t),
								loadname);

	pheader->skindesc = (byte *)pskindesc - (byte *)pheader;

	for (i=0 ; i<numskins ; i++)
	{
		aliasskintype_t	skintype;

		skintype = LittleLong (pskintype->type);
		pskindesc[i].type = skintype;

		if (skintype == ALIAS_SKIN_SINGLE)
		{
			pskintype = (daliasskintype_t *)
					Mod_LoadAliasSkin (pskintype + 1,
									   &pskindesc[i].skin,
									   skinsize, pheader);
		}
		else
		{
			pskintype = (daliasskintype_t *)
					Mod_LoadAliasSkinGroup (pskintype + 1,
											&pskindesc[i].skin,
											skinsize, pheader);
		}
	}

//
// set base s and t vertices
//
	pstverts = (stvert_t *)&pmodel[1];
	pinstverts = (stvert_t *)pskintype;

	pheader->stverts = (byte *)pstverts - (byte *)pheader;

	for (i=0 ; i<pmodel->numverts ; i++)
	{
		pstverts[i].onseam = LittleLong (pinstverts[i].onseam);
	// put s and t in 16.16 format
		pstverts[i].s = LittleLong (pinstverts[i].s) << 16;
		pstverts[i].t = LittleLong (pinstverts[i].t) << 16;
	}

//
// set up the triangles
//
	ptri = (mtriangle_t *)&pstverts[pmodel->numverts];
	pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts];

	pheader->triangles = (byte *)ptri - (byte *)pheader;

	for (i=0 ; i<pmodel->numtris ; i++)
	{
		int		j;

		ptri[i].facesfront = LittleLong (pintriangles[i].facesfront);

		for (j=0 ; j<3 ; j++)
		{
			ptri[i].vertindex[j] =
					LittleLong (pintriangles[i].vertindex[j]);
		}
	}

//
// load the frames
//
	if (numframes < 1)
		Host_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes);

	pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris];

	for (i=0 ; i<numframes ; i++)
	{
		aliasframetype_t	frametype;

		frametype = LittleLong (pframetype->type);
		pheader->frames[i].type = frametype;


		if (frametype == ALIAS_SINGLE)
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasFrame (pframetype + 1,
										&pheader->frames[i].frame,
										pmodel->numverts,
										&pheader->frames[i].bboxmin,
										&pheader->frames[i].bboxmax,
										pheader, pheader->frames[i].name);
		}
		else
		{
			pframetype = (daliasframetype_t *)
					Mod_LoadAliasGroup (pframetype + 1,
										&pheader->frames[i].frame,
										pmodel->numverts,
										&pheader->frames[i].bboxmin,
										&pheader->frames[i].bboxmax,
										pheader, pheader->frames[i].name);
		}
	}

	mod->type = mod_alias;

// FIXME: do this right
	mod->mins[0] = mod->mins[1] = mod->mins[2] = -16;
	mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16;

//
// move the complete, relocatable alias model to the cache
//	
	end = Hunk_LowMark ();
	total = end - start;
	
	Cache_Alloc (&mod->cache, total, loadname);
	if (!mod->cache.data)
		return;
	memcpy (mod->cache.data, pheader, total);

	Hunk_FreeToLowMark (start);
}
Beispiel #14
0
/*
=================
Mod_LoadTextures
=================
*/
void Mod_LoadTextures (lump_t *l)
{
	int				i, j, num, max, altmax, texture_flag, brighten_flag;
	miptex_t		*mt;
	texture_t		*tx, *tx2, *txblock, *anims[10], *altanims[10];
	dmiptexlump_t	*m;
#ifndef RQM_SV_ONLY
	byte			*data;
#endif

	if (!l->filelen)
	{
		loadmodel->textures = NULL;
		return;
	}

	m = (dmiptexlump_t *)(mod_base + l->fileofs);
	m->nummiptex = LittleLong (m->nummiptex);
	loadmodel->numtextures = m->nummiptex;
	loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures), mod_loadname);

	txblock = Hunk_AllocName (m->nummiptex * sizeof(**loadmodel->textures), mod_loadname);

#ifndef RQM_SV_ONLY
#ifdef HEXEN2_SUPPORT
	if (hexen2)
		brighten_flag = 0;
	else
#endif
//	brighten_flag = (gl_lightmode.value == 1) ? TEX_BRIGHTEN : 0;
	brighten_flag = 0;

	texture_flag = (gl_picmip_all.value || loadmodel->isworldmodel) ? TEX_MIPMAP : 0;
#else
	brighten_flag = texture_flag = 0;
#endif

	for (i = 0 ; i < m->nummiptex ; i++)
	{
		m->dataofs[i] = LittleLong (m->dataofs[i]);
		if (m->dataofs[i] == -1)
			continue;

		mt = (miptex_t *)((byte *)m + m->dataofs[i]);
		loadmodel->textures[i] = tx = txblock + i;

		memcpy (tx->name, mt->name, sizeof(tx->name));
		if (!tx->name[0])
		{
			Q_snprintfz (tx->name, sizeof(tx->name), "unnamed%d", i);
			Con_DPrintf ("Warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
		}

		tx->width = mt->width = LittleLong (mt->width);
		tx->height = mt->height = LittleLong (mt->height);
//		if ((mt->width & 15) || (mt->height & 15))
//			Host_Error ("Mod_LoadTextures: Texture %s is not 16 aligned", mt->name);	// was Sys_Error

		for (j=0 ; j<MIPLEVELS ; j++)
			mt->offsets[j] = LittleLong (mt->offsets[j]);

		// HACK HACK HACK
		if (!strcmp(mt->name, "shot1sid") && mt->width == 32 && mt->height == 32
			&& CRC_Block((byte*)(mt+1), mt->width*mt->height) == 65393)
		{	// This texture in b_shell1.bsp has some of the first 32 pixels painted white.
			// They are invisible in software, but look really ugly in GL. So we just copy
			// 32 pixels from the bottom to make it look nice.
			memcpy (mt+1, (byte *)(mt+1) + 32*31, 32);
		}

#ifndef RQM_SV_ONLY
		if (loadmodel->isworldmodel && ISSKYTEX(tx->name))
		{
			R_InitSky (mt);
			continue;
		}

		if (Mod_LoadBrushModelTexture(tx, texture_flag))
			continue;

		if (mt->offsets[0])
		{
			data = (byte *)mt + mt->offsets[0];
			tx2 = tx;
		}
		else
		{
			data = (byte *)tx2 + tx2->offsets[0];		// JDH: what is tx2 equal to at this point ???
			tx2 = r_notexture_mip;
		}

#ifdef _DEBUG
//		for (j = tx2->width*tx2->height; j >= 0; j--)
//			if (data[j] == 255)
//				break;
#endif

//		tx->gl_texturenum = GL_LoadTexture (tx2->name, tx2->width, tx2->height, data, texture_flag | brighten_flag, 1);
		tx->gl_texturenum = GL_LoadTexture (tx2->name, tx2->width, tx2->height, data, texture_flag | TEX_BMODEL, 1);
		if (!ISTURBTEX(tx->name) && Img_HasFullbrights(data, tx2->width * tx2->height))
			tx->fb_texturenum = GL_LoadTexture (va("@fb_%s", tx2->name), tx2->width, tx2->height, data, texture_flag | TEX_FULLBRIGHT, 1);
	/************** JDH ***************/
		else tx->fb_texturenum = 0;
	/************** JDH ***************/
#endif
	}

// sequence the animations
	for (i=0 ; i<m->nummiptex ; i++)
	{
		tx = loadmodel->textures[i];
		if (!tx || tx->name[0] != '+')
			continue;
		if (tx->anim_next)
			continue;	// already sequenced

	// find the number of frames in the animation
		memset (anims, 0, sizeof(anims));
		memset (altanims, 0, sizeof(altanims));

		max = tx->name[1];
		altmax = 0;
		if (max >= 'a' && max <= 'z')
			max -= 'a' - 'A';
		if (max >= '0' && max <= '9')
		{
			max -= '0';
			altmax = 0;
			anims[max] = tx;
			max++;
		}
		else if (max >= 'A' && max <= 'J')
		{
			altmax = max - 'A';
			max = 0;
			altanims[altmax] = tx;
			altmax++;
		}
		else
		{
			Host_Error ("Bad animating texture %s", tx->name);	// was Sys_Error
		}

		for (j=i+1 ; j<m->nummiptex ; j++)
		{
			tx2 = loadmodel->textures[j];
			if (!tx2 || tx2->name[0] != '+')
				continue;
			if (strcmp(tx2->name+2, tx->name+2))
				continue;

			num = tx2->name[1];
			if (num >= 'a' && num <= 'z')
				num -= 'a' - 'A';
			if (num >= '0' && num <= '9')
			{
				num -= '0';
				anims[num] = tx2;
				if (num+1 > max)
					max = num + 1;
			}
			else if (num >= 'A' && num <= 'J')
			{
				num = num - 'A';
				altanims[num] = tx2;
				if (num+1 > altmax)
					altmax = num+1;
			}
			else
			{
				Host_Error ("Bad animating texture %s", tx->name);	// was Sys_Error
			}
		}

#define	ANIM_CYCLE	2
	// link them all together
		for (j=0 ; j<max ; j++)
		{
			tx2 = anims[j];
			if (!tx2)
				Host_Error ("Mod_LoadTextures: Missing frame %i of %s", j, tx->name);	// was Sys_Error
			tx2->anim_total = max * ANIM_CYCLE;
			tx2->anim_min = j * ANIM_CYCLE;
			tx2->anim_max = (j+1) * ANIM_CYCLE;
			tx2->anim_next = anims[(j+1)%max];
			if (altmax)
				tx2->alternate_anims = altanims[0];
		}
		for (j=0 ; j<altmax ; j++)
		{
			tx2 = altanims[j];
			if (!tx2)
				Host_Error ("Mod_LoadTextures: Missing frame %i of %s", j, tx->name);	// was Sys_Error
			tx2->anim_total = altmax * ANIM_CYCLE;
			tx2->anim_min = j * ANIM_CYCLE;
			tx2->anim_max = (j+1) * ANIM_CYCLE;
			tx2->anim_next = altanims[(j+1)%altmax];
			if (max)
				tx2->alternate_anims = anims[0];
		}
	}
}
Beispiel #15
0
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.

This is only called from the SV_Map_f() function.
================
*/
void SV_SpawnServer (char *mapname, qbool devmap)
{
	char *entitystring;
	edict_t *ent;
	int i;
	extern qbool sv_allow_cheats;
	extern cvar_t sv_cheats;

	Com_DPrintf ("SpawnServer: %s\n", mapname);

	NET_InitServer();

	SV_SaveSpawnparms ();

	svs.spawncount++; // any partially connected client will be restarted

	sv.state = ss_dead;
	com_serveractive = false;
	Cvar_ForceSet (&sv_paused, "0");

	Host_ClearMemory();

	if (deathmatch.value)
		Cvar_Set (&coop, "0");
	current_skill = (int)(skill.value + 0.5);
	if (current_skill < 0)
		current_skill = 0;
	if (current_skill > 3)
		current_skill = 3;
	Cvar_Set (&skill, va("%d", (int)current_skill));

	if ((sv_cheats.value || devmap) && !sv_allow_cheats) {
		sv_allow_cheats = true;
		Info_SetValueForStarKey (svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
	} else if ((!sv_cheats.value && !devmap) && sv_allow_cheats) {
		sv_allow_cheats = false;
		Info_SetValueForStarKey (svs.info, "*cheats", "", MAX_SERVERINFO_STRING);
	}

	// wipe the entire per-level structure
	memset (&sv, 0, sizeof(sv));

	SZ_Init (&sv.datagram, sv.datagram_buf, sizeof(sv.datagram_buf));
	sv.datagram.allowoverflow = true;

	SZ_Init (&sv.reliable_datagram, sv.reliable_datagram_buf, sizeof(sv.reliable_datagram_buf));

	SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));

	SZ_Init (&sv.signon, sv.signon_buffers[0], sizeof(sv.signon_buffers[0]));
	sv.num_signon_buffers = 1;

	// load progs to get entity field count
	// which determines how big each edict is
	PR_LoadProgs ();

	// allocate edicts
	sv.edicts = (edict_t *) Hunk_AllocName (SV_MAX_EDICTS*pr_edict_size, "edicts");

	// leave slots at start for clients only
	sv.num_edicts = MAX_CLIENTS+1;
	for (i = 0; i < MAX_CLIENTS; i++) {
		ent = EDICT_NUM(i+1);
		svs.clients[i].edict = ent;
		svs.clients[i].old_frags = 0; //ZOID - make sure we update frags right
	}

	sv.time = 1.0;

#ifndef SERVERONLY
	{
		void R_PreMapLoad (char *mapname);
		R_PreMapLoad (mapname);
	}
#endif

	strlcpy (sv.mapname, mapname, sizeof(sv.mapname));
	Cvar_ForceSet (&host_mapname, mapname);
	snprintf (sv.modelname, sizeof(sv.modelname), "maps/%s.bsp", mapname);

	sv.worldmodel = CM_LoadMap (sv.modelname, false, &sv.map_checksum, &sv.map_checksum2);

	// clear physics interaction links
	SV_ClearWorld ();

	sv.sound_precache[0] = pr_strings;

	sv.model_precache[0] = pr_strings;
	sv.model_precache[1] = sv.modelname;
	sv.models[1] = sv.worldmodel;
	for (i = 1; i < CM_NumInlineModels(); i++) {
		sv.model_precache[1+i] = localmodels[i];
		sv.models[i + 1] = CM_InlineModel (localmodels[i]);
	}

	//check player/eyes models for hacks
	sv.model_player_checksum = SV_CheckModel("progs/player.mdl");
	sv.eyes_player_checksum = SV_CheckModel("progs/eyes.mdl");

	// spawn the rest of the entities on the map

	// precache and static commands can be issued during map initialization
	sv.state = ss_loading;
	com_serveractive = true;

	ent = EDICT_NUM(0);
	ent->free = false;
	ent->v.model = PR_SetString(sv.modelname);
	ent->v.modelindex = 1;		// world model
	ent->v.solid = SOLID_BSP;
	ent->v.movetype = MOVETYPE_PUSH;

	pr_global_struct->mapname = PR_SetString(sv.mapname);
	// serverflags are for cross level information (sigils)
	pr_global_struct->serverflags = svs.serverflags;

	// run the frame start qc function to let progs check cvars
	SV_ProgStartFrame ();

	// load and spawn all other entities
	entitystring = NULL;
	if ((int) sv_loadentfiles.value) {
		int filesize;
		entitystring = (char *)FS_LoadHunkFile (va("maps/%s.ent", sv.mapname), &filesize);
		if (entitystring) {
			Com_DPrintf ("Using entfile maps/%s.ent\n", sv.mapname);
			Info_SetValueForStarKey (svs.info, "*entfile", va("%i",
				CRC_Block((byte *)entitystring, filesize)), MAX_SERVERINFO_STRING);
		}
	}

	if (!entitystring) {
		Info_SetValueForStarKey (svs.info,  "*entfile", "", MAX_SERVERINFO_STRING);
		entitystring = CM_EntityString();
	}
	ED_LoadFromFile (entitystring);

	// look up some model indexes for specialized message compression
	SV_FindModelNumbers ();

	// all spawning is completed, any further precache statements
	// or prog writes to the signon message are errors
	sv.state = ss_active;

	// run two frames to allow everything to settle
	SV_Physics ();
	sv.time += 0.1;
	SV_Physics ();
	sv.time += 0.1;
	sv.old_time = sv.time;

	// save movement vars
	SV_SetMoveVars();

	// create a baseline for more efficient communications
	SV_CreateBaseline ();
	sv.signon_buffer_size[sv.num_signon_buffers - 1] = sv.signon.cursize;

	Info_SetValueForKey (svs.info, "map", sv.mapname, MAX_SERVERINFO_STRING);
	Com_DPrintf ("Server spawned.\n");

#ifndef SERVERONLY
	if (!dedicated)
	{
		void CL_ClearState (void);
		CL_ClearState ();
	}
#endif
}