there were no pointers in those examples
Code: Select all
void(entity *ent) zomgwtf =
{
*ent = spawn();
ent->foo = 5;
otherstuff(*ent);
};
entity foo;
zomgwtf(&foo);
there's your pointer example. obviously __out is a bit simpler and works in more engines, so that's why I didn't bother describing pointers.
regarding optional arguments, you should generally not use these in your own code.
specifically, unlike the engine, the qc normally has no way to tell exactly how many arguments were passed, and any arguments which were not passed will have undefined values. if you then pass those undefined values on to the engine, the engine will see those arguments as present, and will then also trip up because their values are undefined.
You can justify using them in the prior arguments indicate whether the later arguments are valid, but the qcc cannot help validate that. As such, its probably better to just remove the optionals and explicitly pass 0s or something.
When I wrote about tables, I was trying to be generic.
I can try and be specific in the case of function tables instead if that would help...
In QC, function references are just references - they are an index into a table of functions defined within the progs.dat
this function table is essentially just an array of structs. one of those fields is the qc instruction index that the function starts at.
so, when you pass a function, you're actually passing an index into that table. and the engine goes and reads that first_instruction field of that table and jumps to that instruction. There's some other stuff in there too, of course, like arguments, but meh.
strings on the other hand, are a byte index into a bit block of chars inside the progs. change the index into the table and you change the string, but you can also cast them to pointers and memcpy data over them, changing the data that those strings refer to without actually changing the string references themselves.
entities work the same way. the entity type is actually just an index. in some engines its a simple index, in others its a byte offset from world. either way you can change the data that's stored at that index by writing all of its fields, which will also affect any other references with the same index, and all without changing the index itself.
so yeah, references/pointers are separate and distinct from the data that they refer to. one is an index, one is a block of memory. you can change the index itself, or you can change the data that the index refers to without changing the index which will of course be visible through all other references/indexes to the same block of memory. in the case of functions that block of memory isn't directly visible, in the case of entities its readable and writable, in the case of strings its normally read-only. either way, the separation between the reference and the data itself is the same.