Notes on the Source of the Impulse Commands Patch 
by Peter "Czar" Williams

Those of you who read the tutorial on QDevelS (http://www.planetquake.com/
qdevels). This source is not exactly what is on the site; I'm very sure 
all of the code is identical. Read the tutorial for a REALLY complete
explanation of what's going on.

WHO
	Me, dammit.

WHAT
	Only the source files that have been modified. For the two
impulse DLL's, this means complete source; for the gamex86, this means
g_cmds.c, g_main.c, p_client.c, and impulse.h

WHERE
	This patch was tested exclusively on the quality level FACT3,
with deathmatch set to one for your protection.

WHEN
	January, 1998

HOW
To make a new project:
	-The game. Copy the complete source to your dest directory.
Copy the files in the subdir "game" over the ones in your dest dir.
Create a project as normal.
	-Impulse patch. Copy the complete source from, say, the subdir
"echo" to your dest directory. Create the project the same way you would
a gamex86.dll, except with only i_main.c and its headers. Modify
the ImpulseXXXX functions, add new functions, leave GetImpulseAPI 
alone. See the source in the subdir "qcmds" to see a more interesting
DLL (barely).

The damn thing works:
	-In gamex86.dll. When the level first loads, ClientConnect
gets called. It in turn calls the new function InitImpulseLib. The
source in that is very self-explanatory: it puts the filename 
together, tries to load the DLL, and calls GetImpulseAPI in the DLL.
I decided to model the communication architecture like that between
the EXE and the gamex86.dll, using two new structs, impulse_import_t
and impulse_export_t. The gamex86.dll gives the impx86.dll the 
game import, what the game exports, the level struct, the game struct,
and the FindItem function because it's very useful. The impx86.dll 
gives the game DLL the functions ImpulseInit, ImpulseCommand, and
ImpulseShutdown. Finally, InitImpulseLib calls the function 
ImpulseInit in impx86.dll.
	That's the initialization. When a "cmd impulse" is issued,
ClientCommand calls the function ImpulseCommand in impx86.dll if it
exists. There, strange and mysterious things occur. Then it returns.
	Finally, when ShutdownGame is called when the level exits or
the user quits, CLoseImpulseLib is called. If everything's in order
ImpulseShutdown in the impulse DLL is called, then the DLL is 
unloaded.
	-In impx86.dll. There are only four necessary functions:
GetImpulseAPI, ImpulseInit, ImpulseCommand, and ImpulseShutdown.
GetImpulseAPI should be the same for nearly every impulse library:
it copies the impulse_import_t data to a local version and returns
the impulse_export_t. ImpulseInit is called when the DLL is first
loaded. Obviously, do your initialization code there. ImpulseCommand
is the workhorse: its responsibility is to do something with an 
impulse. It is passed the entity that issued the impulse and the
number of the impulse. Usually there's a switch statement that 
decides what to do. Finally, ImpulseShutdown should do you shutdown
code.

WHY
	...I used impulse_xxport_t's instead of normal 
GetProcAddress: that's the way John Cash did it and I think he 
knwos what he's doing.