Inside3D!
     

Built in functions

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
goblinoid



Joined: 21 Mar 2008
Posts: 22

PostPosted: Mon Dec 14, 2009 2:15 pm    Post subject: Built in functions Reply with quote

Greetings,

At the end of defs.qc there is a bunch of built in functions, can someone explain me how they work? I mean in a generic way, not what each of them does, like where they come from, how the engine handle them, things like that.

Thanks
Back to top
View user's profile Send private message
KrimZon



Joined: 05 Nov 2004
Posts: 10

PostPosted: Tue Dec 15, 2009 12:04 pm    Post subject: Re: Built in functions Reply with quote

All the actual compiled QuakeC code is compiled into one array of instructions. There's also a bunch of indexes for things like global variables, fields and functions.

Each entry in the function list contains, among other things, the index into the instruction list of the first instruction of that function.

Builtins however have a negative index, and instead point to an index in an engine-side list of C function pointers. The engine checks the sign and if it's negative it looks in the builtin list and calls the C function rather than interpreting any instructions from the progs. The # number in the declaration/definition of a builtin is its actual position in the builtins list.

So the engine has to define every single builtin function that gets made available to the QC. They're generally for something that QC can't do on its own, or which would be much slower to do in QC. To QC they behave exactly like QC functions - they take parameters, they return a value and they can affect other globals or entities while running.

I don't know if that fully explains it. I have further notes on QuakeC here but they're incomplete and aimed for developing a QC interpreter. There's also a somewhat human-readable dump of the stock progs.dat, which I used when making those notes.

(While posting this I noticed slight errors in my notes, but they still demonstrate the general structure of a compiled progs.dat)
Back to top
View user's profile Send private message
goblinoid



Joined: 21 Mar 2008
Posts: 22

PostPosted: Tue Dec 15, 2009 1:49 pm    Post subject: Reply with quote

Thank you KrimZon, it's more clear now. I'll take a look in those links later.

I have another question, how they should be delcared on defs.qc? Does their names mater or if they're in the right order they'll work anyway?
Back to top
View user's profile Send private message
KrimZon



Joined: 05 Nov 2004
Posts: 10

PostPosted: Tue Dec 15, 2009 8:04 pm    Post subject: Reply with quote

That's actually a pretty useful point - the only thing that matters when declaring a particular builtin is the number. (Also the parameters have to match so that they make sense to the function and don't cause an error, but they don't have to be exact).

You can change the name of a builtin and write your own wrapper for it - Frikbot does this to make it so easy to add to any mod - it does stuff like:
Code:
void(entity e, string s) sprint_real = #24;
void(entity e, string s) sprint =
{
  if (!e.is_bot)
    sprint_real(e, s);
};

This means that the rest of any mod can keep calling sprintf but the builtin only gets called for real players.

You can also have multiple names for the same builtin, a common example being:
Code:
void(entity e, string s) centerprint = #73;
void(entity e, string s1, string s2) centerprint2 = #73;
void(entity e, string s1, string s2, string s3) centerprint3 = #73;
// etc.

You'll then get multiple functions in the function list that point to the same builtin.

All the # part does is say that instead of having a body, this function is performed by the built in function pointer #73 or whichever number it is.

They're actually defined the same as a normal function (at least in the original QuakeC syntax) except where the body goes, you put # followed by a number:
Code:
*return_value* ( *parameter_list* ) *name* = { *code* }; // qc
*return_value* ( *parameter_list* ) *name* = #*number* ; // builtin

It's replacing the body "{ .. }" with builtin number "#...".


So:

They can be in any order. (Just have to be defined before use.)

They can have any name.

There can be duplicates with different names.

They can have any parameters so long as the builtin code knows what to do with them. (But for most of the stock quake builtins the parameters in defs.qc are pretty much the only right ones.)

Also you don't even have to define builtins you don't use - they can just be left out entirely. (This is how extensions work - the engine has the builtins but there's no problem for mods to not define them or call them. You can also define a builtin that isn't present in a particular engine, and everything will be fine so long as you don't actually call that function.)
Back to top
View user's profile Send private message
goblinoid



Joined: 21 Mar 2008
Posts: 22

PostPosted: Tue Dec 15, 2009 9:38 pm    Post subject: Reply with quote

Thanks again KrimZon.

I have a problem with a mod and mvdsv, it's not recognising some built in function. Perhaps they're out of order or something, I'll check that.

Anything else I should know about builtins?
Back to top
View user's profile Send private message
Lardarse



Joined: 05 Nov 2005
Posts: 243
Location: Bristol, UK

PostPosted: Fri Dec 25, 2009 9:23 am    Post subject: Reply with quote

There is a hard limit of 8 function paramaters that can be passed to a function. Modern QuakeC compilers allow you to extend that, but it's not possible to send more than 8 parameters to a builtin function.
_________________
<ekiM> Son, you're writing data structures your CPU can't cache.
Back to top
View user's profile Send private message
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Fri Dec 25, 2009 2:11 pm    Post subject: Reply with quote

if your mvdsv problem is with mvdsv-specific builtins then you probably need to set a cvar so they actually exist and the 'standard' ones do not.
you could instead add some string that makes it think its ktpro.
sadly I don't remember the string or cvar name
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group