#1760 posted by aDaya on 2015/10/15 01:27:42
OK, so the Gatling Gun i've been coding this past few days now works flawlessly, it's great. I can't thank Preach enough for his help.
I've been testing it in Darkplaces (like I did with the InfantryGun), but once I switched to Quakespasm the weapon doesn't appear at all. In fact he gives this error in the console:
http://image.noelshack.com/fichiers/2015/42/1444865216-spasm0005.png
So what gives? I don't think that's linked to the bit field I gave to it (it being "8388608" so it doesn't conflict with other items).
#1761 posted by metlslime on 2015/10/15 02:09:38
is it case sensitive and you have inconsist case between the map file and the quakec?
#1762 posted by aDaya on 2015/10/15 02:30:17
I checked if it was a case of hitboxes changing between clients, like how powerups need to be lifted up to 16 units from the ground to appear properly. I tried that, but the error's still there.
Looks Like Your Progs.day Isnt Loaded
#1763 posted by ericw on 2015/10/15 02:45:46
That Error
#1764 posted by ijed on 2015/10/15 02:49:26
Means the qc being called doesn't exist.
So yeah, check that you haven't got an upper/lower case problem somewhere that Dark places was automatically correcting.
#1765 posted by metlslime on 2015/10/15 06:23:02
the error literally means the classname in the map file doesn't match any spawn functions found in the progs.dat, which is why i suggested the upper/lower case issue. It could also be a spelling issue (though can't explain why it would work in darkplaces then) or maybe the progs.dat isn't even being loaded (perhaps darkplaces has different rules about folder searchpaths or valid filenames for it?)
#1766 posted by aDaya on 2015/10/15 10:04:23
That was it, when I transferred the files from darkplaces to quakespasm I forgot to transfer the progs.dat file.
Thanks again for your support!
Mdl Winding Sanity Check
#1767 posted by Kinn on 2015/10/18 00:02:26
Can anyone tell me what the correct winding order is for quake .mdl triangles? (CW or CCW?). It's not a big issue because I can reorder my vertices to switch the winding, but the fact that my tris are coming out flipped is baffling me a little bit.
Pretty Sure It's CW
Resetting Think Fields
#1769 posted by Preach on 2015/10/27 23:32:26
Imagine you would like to reset an entity which has already had a .think function set; this lets you use the same check for a entity which currently has no thoughts as one which has never had any. Then imagine that you were overly paranoid about how airtight your solution was, and you wrote in an incredibly pretentious manner. The result might be something like https://tomeofpreach.wordpress.com/2015/10/27/eternal-sunshine-of-the-spotless-think/
@Preach
#1770 posted by Spike on 2015/10/28 00:37:34
Or, if you're using FTEQCC there's a handy c++ism.
self.think = 0;
you can also use __NULL__ if you want to make it look a little less bugged.
__NULL__
#1771 posted by Preach on 2015/10/28 00:42:58
Is the 0 thing a new feature? I get a pointer/integer type mismatch with my current version. Just tried __NULL__ and that works well.
#1772 posted by Spike on 2015/10/28 01:33:51
newer than __NULL__ anyway (aka: 0i).
Integer Constants?
#1773 posted by Preach on 2015/10/28 08:04:34
Is that a way of getting actual integer constants then? Might be an interesting trick I can get out of them if so...
#1774 posted by Spike on 2015/10/28 16:01:34
denorm = (__variant)5i;
denorm20 = 4*denorm;
float4 = denorm20 / denorm;
if you omit the __variant cast then it does an implicit int->float conversion. if its not a known constant then it'll attempt to use extended opcodes / builtins.
with the cast, it'll use a direct store, resulting in a denormalised float (ie: a really really small float, that has the same bitpattern as a positive int of up to 23 bits, just much smaller).
I'm sure you're aware of this, but for other readers, multiplying a float by denormalised 1i 'converts' that float into a denormalised pseudo-int. you can then add two such pseudo-ints together using standard fpu operations and then convert back into floats with division.
you can use this for evil hacks like field indexing or function indexing.
I would caution against doing this for a few reasons.
1) fte's field remapping (as part of its nq+qw hybrid support) tends to break any assumptions about known offsets, so be sure to not hardcode any specific offsets nor expect them to work correctly over 'recognised' (aka: remappable) fields.
2) there's no way to directly reference globals other than to hack some entity to index its fields into quake's hunk memory. this will be caught by fte,dp,qf, and will need inconsistent offsets in various other engines.
3) its basically unreadable.
4) denormalised floats are often not supported or are emulated and thus incredibly slow. x86 cpus do support them in hardware, but intel chips are known to have significant performance slowdowns with them. itanium does NOT support them, even when running x86 code, while amd chips don't have any issues, yay amd.
I'm unsure about hardfpu arm chips.
fteqcc does support int operations, if you try using them with vanilla opcodes, it will promote mixed-type operations to using floats, and generate function calls for pure-int operations and casts. supposedly, at least versions that support func=0 anyway.
-fassume-int causes fteqcc to assume that ALL non-floating immediates are int types rather than floats. This is supposed to be useful to JIT type qc execution, but also makes quakec more c-like, if anyone wants that. 5.0 is still interpretted as a float.
Something Like That
#1775 posted by Preach on 2015/10/30 00:30:38
The old fastqcc stuff with indexing fields and pretending to get dynamic arrays seemed a bit desperate and risky, particularly today with all the different and complex custom engines about.
What I really wanted was some way to do a static vtable in Quake, without needing an entity to store all the functions in. I thought I might be able to make some kind of jump table with a bunch of return statements, and use an integer parameter to select of many of them to skip over.
It doesn't seem to work though, even though the stumbling point appears to be confusing the variable holding the jump distance with a label name to goto. Is there a better way of doing that which I'm missing? Can you index a block of consecutive functions if you define them all in succession?
�omg
#1776 posted by necros on 2015/10/30 02:10:49
you are totally crazy, you know. any sane man would just use entities and be done with it!!!
�wait
#1777 posted by necros on 2015/10/30 02:20:04
i assumed you were trying to fake OO?
Preach
#1778 posted by Spike on 2015/10/30 13:46:48
void() foo = {code;};
is really this:
var void() foo;
foo = numfunctions;
functions[numfunctions] = {code;};
numfunctions++;
or in other words, for functions to be consecutive, it is the function bodys that need to be consecutive, not their prototypes.
this makes assumptions about function ordering quite annoying in practise.
QC has no variable-distance jumps. If you want static vtables you're probably best just making an array and indexing in to that. I'm unsure how you would cope with assigning offsets though. And of couse, touch and think functions wouldn't work very well with it.
Which is why fteqcc's class stuff just uses fields for its virtual functions, and in doing so it can cope with thinks, touches, etc with ease (including engine-specific extensions, so long as they've an appropriate .void() or whatever def outside of a class for them to inherit from). nonvirtual calls are still direct calls of course. however fteqcc does only provide single inheritance, and constructors are designed to mirror spawn functions rather than traditional constructors.
class foo : entity
{
string myname;
virtual void() think =
{
dprint("I'm thinking here\n");
};
void() foo =
{
if (!myname) myname = "unnamed";
dprint(myname, "'s spawn function\n");
nextthink = time + 1;
};
};
void() calledfromsomewhereelse = {foo bar = spawn(foo, myname:"TheTest");};
class members use some weird name mangling (unless inherited from the basic entity type), which can make them problematic in maps.
there's only one extension used, and that's that it uses 'spawnfunc_foo' to fill in the stuff and call the constructor. this is used so that you can just call spawnfunc_player() inside ClientConnect without any issues about any player classes (you shouldn't really use this trick unless its known to be a non-class entity, as it doesn't reset any class fields, and aliasing between classes would leave unpredictable values).
dammit, another essay.
Cheers
#1779 posted by Preach on 2015/10/31 01:21:24
for functions to be consecutive, it is the function bodys that need to be consecutive, not their prototypes.
This sounds helpful rather than harmful, you don't need to worry that someone ahead of you in the compilation list prototypes one of your functions and mucks up the order. I hear what you say about entities being much more sensible for things with actual state, but I think there's a niche here which it could fill. Thanks for the post!
Binary Saves And Dealing With New Versions
#1780 posted by necros on 2015/11/11 05:22:08
non-quake question... say you are saving some data into a binary file. let's say preferences. somewhere along the line you may add in some new feature with accompanying preferences.
how do you deal with this when you need to read the old binary data and do a one time upgrade? do you just keep your old loading method and use the first byte to identify which loading method to use? is there a better way?
#1781 posted by metlslime on 2015/11/11 05:55:54
you can create an extensible format... preferences are a list of key + value, so in theory you just want to add new key/value pairs over time. You either want a directory at the beginning of the file that first has "number of entries" and then an array of offsets to each entry, and then each entry can have a standard format, or you can have fixed size entries and just keep reading until you hit EOF, then you don't need a directory.
Either way, when reading the file, if it doesn't have all of the entries you expect you can just use the default value for the missing preferences.
Question: why do you want it to be binary?
Sound
#1782 posted by madfox on 2015/11/11 07:10:24
What can I do to prevent a new model,
that is jumping up and down to cause the
client.qc line : 849
void() PlayerJump =
sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
sound?
#1783 posted by necros on 2015/11/11 07:15:39
Question: why do you want it to be binary?
I want it to be portable (eg: no registry keys) but I don't want the user messing with things.
Sound()
#1784 posted by madfox on 2015/11/11 07:26:27
Actually I ment,
how do I stop the sounds h2ojump.wav / dland2.wav
for a new model playing in game?
|