⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extension_system.txt

📁 quake1 dos源代码最新版本
💻 TXT
字号:
================================================================
Title         : Tutorial: Implementing Lord Havoc's Extension System into the Quake engine
Date          : 2000-10-23
Filename      : EXTENSION_SYSTEM.TXT
Authors       : Matthias "Maddes" Buecher
                Forest "Lord Havoc" Hale
Email Address : maddes@go.to
                havoc@gamevisions.com
Homepage      : Quake Info Pool
                http://www.quake-info-pool.net/
                DarkPlaces
                http://darkplaces.gamevisions.com/
                Quake Standards Group (short QSG)
                http://www.quakesrc.org/
Complexity    : Moderate
================================================================



Index
=====
Part I   - Purpose and system explanation
Part II  - Implementing the Extension System into the Quake engine
Part III - How to use the Extension System in QuakeC



Part I - Purpose and system explanation
=======================================
Many engines provide new functionalities for QuakeC coders to use in their
addons. But the problem for QuakeC coders is how to determine during run-time if
the engine supports all the needed new functionalities?
That is where Lord Havoc came in. He added a builtin function which states if an
extension is available in the engine or not.

Lord Havoc's function was added to the QSG standard by using the Enhanced BuiltIn
Function System (EBFS) with the name "extension_find" and the number #99.
If you want to add Lord Havoc's "extension_find" to your own engine, you should add
the EBFS before (tutorial here: EBFS.TXT).



Part II  - Implementing the Extension System into the Quake engine
==================================================================
Adding the Extension System to your engine is very easy, even if you did lots of
changes to your own engine.

The new builtin function needs some new data, the names of the supported engine
extensions. The main function loops through the array and compares the strings
with the requested extension name. The builtin function "extension_find" uses
the above function and passes the result to the PROGS.DAT.

At the top of PR_CMDS.C add the following code...

// 2001-10-20 Extension System by Lord Havoc  start
char *pr_extensions[] =
{
// add the extension names here, syntax: "extensionname",
};

int pr_numextensions = sizeof(pr_extensions)/sizeof(pr_extensions[0]);

qboolean extension_find(char *name)
{
	int	i;

	for (i=0; i < pr_numextensions; i++)
	{
		if (!Q_strcasecmp(pr_extensions[i], name))
			return true;
	}
	return false;
}

/*
=================
PF_extension_find

returns true if the extension is supported by the server

float extension_find(string name)
=================
*/
void PF_extension_find (void)
{
	G_FLOAT(OFS_RETURN) = extension_find(G_STRING(OFS_PARM0));
}
// 2001-10-20 Extension System by Lord Havoc  end

   ... and add this to the pr_builtin[] array (EBFS!) ...

	{  99, "extension_find", PF_extension_find },	// 2001-10-20 Extension System by Lord Havoc


The Extension System is now ready to run, but a nice addition is the new command
"extensionlist", which lists all available extensions.

First we have to globally declare the new data in PROGS.H with these lines ...

// 2001-10-20 Extension System by Lord Havoc  start
extern char *pr_extensions[];
extern int	pr_numextensions;
// 2001-10-20 Extension System by Lord Havoc  end

Then put the command function at top of PR_EDICT.C...

// 2001-10-20 Extension System by Lord Havoc  start
void PR_Extension_List_f (void)
{
	int		i;
	char	*partial;
	int		len;
	int		count;

	if (Cmd_Argc() > 1)
	{
		partial = Cmd_Argv (1);
		len = strlen(partial);
	}
	else
	{
		partial = NULL;
		len = 0;
	}

	count=0;
	for (i=0; i < pr_numextensions; i++)
	{
		if (partial && Q_strncasecmp (partial, pr_extensions[i], len))
		{
			continue;
		}
		count++;
		Con_Printf ("%s\n", pr_extensions[i]);
	}

	Con_Printf ("------------\n");
	if (partial)
	{
		Con_Printf ("%i beginning with \"%s\" out of ", count, partial);
	}
	Con_Printf ("%i extensions\n", i);
}
// 2001-10-20 Extension System by Lord Havoc  end

    ... and at last add this function as a command in PR_Init() with the following line...

	Cmd_AddCommand ("extensionlist", PR_Extension_List_f);	// 2001-10-20 Extension System by Lord Havoc

Now recompile the engine.


Last but not least, do not forget to mention the Extension System in your readme
and add the next chapter to your engine documentation. This way QuakeC coders
will know how to use EBFS with your engine.



Part III - How to use the Extension System in QuakeC
====================================================
The Extension System is implemented by using the Enhanced BuiltIn Function
System (EBFS) of the Quake Standards Group (QSG). Check out their homepage for
more details on EBFS and other additional builtin functions.

Using the Extension System and EBFS in your addons is very easy. You only have
to make changes to DEFS.QC and WORLD.QC plus all occurences where you use
extensions or additional builtin functions.

Here is an example for a fictional extension called "tutorial_sample".

Step #1 - DEFS.QC:

You add the declaration of the new builtin function "extension_find" just like
normal plus a corresponding variable for it. For each extension you should also
add a corresponding variable. The declaration of the EBFS function
"builtin_find" is obligatory.

// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes  start
float(string s) builtin_find = #100;
float	qc_builtin_find;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes  end

// 2001-10-20 Extension System by Lord Havoc  start
float(string s) extension_find = #99;
float	qc_extension_find;
// 2001-10-20 Extension System by Lord Havoc  end

float	ext_tut_sample;	// 2001-10-20 New Extension: tutorial_sample by Maddes


Step #2 - WORLD.QC:

At the beginning of the function "worldspawn" (this is when a map is loaded) you
have to check for the needed additional functions and extensions.

You check for additional builtin functions with the EBFS function "builtin_find".
It returns the function number of a given function name. The result is zero when
the function does not exist. If the function exists, the QuakeC code has to
check if the returned function number is the same as defined in DEFS.QC, this is
for avoiding problems with non-compliant engines.

If a really necessary function is not available, you should dump the game with
the regular builtin function "error", pointing the user to the QSG homepage for
a compliant engine.

As the EBFS function "builtin_find" is an additional builtin function too, the
above system doesn't work for it. Hence there is also a new cvar called
"pr_builtin_find" which contains the function number of "builtin_find".

After checking all the builtin functions you can check for the extensions.

// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes  start
	qc_builtin_find = cvar("pr_builtin_find");
	if (qc_builtin_find)
	{
		if (qc_builtin_find != 100)
		{
			dprint("Builtin function \"builtin_find\" is #");
			dprint(ftos(qc_builtin_find));
			dprint(" and not #100 - IGNORED!!!\n");
			qc_builtin_find = 0;
		}
	}

	// check for additional builtin functions
	qc_extension_find = 0;	// 2001-10-20 Extension System by Lord Havoc

	if (qc_builtin_find)
	{
// 2001-10-20 Extension System by Lord Havoc  start
		qc_extension_find = builtin_find("extension_find");
		if (qc_extension_find)
		{
			if (qc_extension_find != 99)
			{
				dprint("Builtin function \"extension_find\" is #");
				dprint(ftos(qc_extension_find));
				dprint(" and not #99 - IGNORED!!!\n");
				qc_extension_find = 0;
			}
		}
// 2001-10-20 Extension System by Lord Havoc  end
	}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes  end

// 2001-10-20 Extension System by Lord Havoc  start
	if (qc_extension_find)
	{
		ext_tut_sample = extension_find("tutorial_sample");	// 2001-10-20 New Extension: tutorial_sample by Maddes
	}
// 2001-10-20 Extension System by Lord Havoc  end


Step #3 - Using extensions anywhere

Everytime you want to use one of the extensions you have determine if it is
available by checking its corresponding variable.

	if (ext_tut_sample)
	{
		// Do here what is necessary for this extension
	}

Instead of using a separate variable for each extension, you could also use
variables with bit flags (Note: 24 bit flags are the maximum of a float).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -