Hard Light Productions Forums
Off-Topic Discussion => Programming => Topic started by: blackhole on July 06, 2008, 04:14:33 am
-
Because every now and then, we write them. Sure, they'll get chopped up into safer versions, but they're still fun to look at.
_events[i].first.second->getEvent(_events[i].first.first)->setFireID(RetrieveFromPointer<UNRELATEDDEF>(_events,refs[counter++])->first);
-
huh? why do you have objects and namespaces named like that? that is bound to be confusing.
-
...there are no namespaces in that line of code :wtf:
If your referring to .first and .second, those are pairs and therefore I have no control over the naming.
-
never mind.
miss read the code. thought you where using First::getEvent.first.first
-
Thought I'd share one of the more difficult to debug ones I've seen (simplified for expository purposes, and to hide the guilty parties):
struct FunctionThreadData { };
RESULT function( )
{
FunctionThreadData thread_data;
...
afxBeginThread( thread_function, &thread_data );
return SUCCESS;
}
If you're not sure what's going on above, it's passing a pointer to a stack allocated variable to a thread function and then returning.
If you're lucky, your threaded function gets half a chance to access data in the passed variable before it goes out of scope.
Took quite a while to track this one down.
-
if( ((wip->arm_time) && ((Missiontime - wp->creation_time) < wip->arm_time))
|| ((wip->arm_dist) && (pobj != NULL && pobj->type != OBJ_NONE && (vm_vec_dist(&wobj->pos, &pobj->pos) < wip->arm_dist)))
|| ((wip->arm_radius) && (wp->homing_object == NULL
|| (wp->homing_subsys == NULL && vm_vec_dist(&wobj->pos, &wp->homing_object->pos) > wip->arm_radius)
|| (wp->homing_subsys != NULL && get_subsystem_pos(&spos, wp->homing_object, wp->homing_subsys) && vm_vec_dist(&wobj->pos, &spos) > wip->arm_radius))))
{
return false;
}
Just imagine that without newlines or indentation.
Here's another fun piece of code.
1) You start with two functions, add_collision_pairs and remove_collision_pairs.
2) You need to add collision pairs when a ship becomes collideable and was not collideable before, and remove collision pairs when a ship becomes non-collideable but was collideable before
3) A ship is collideable when it is not in limbo and has the collision flag set.
4) obj->flags contains the old bitflags, new_flags contains the new bitflags
-
After horsing around in the ATL and MFC headers trying to track down a compile error, I'd like to nominate the ATL/MFC macros. :eek:
-
Not sure what I am going to do with this one.. (note the sole "delete"...)
void MapGraphics::ExecuteDelayedBlit()
{
for (std::list<DelayedBlitInformation>::iterator i = delayedBlitInfo_.begin(); i != delayedBlitInfo_.end(); ++i)
{
//SDL_SetAlpha((*i).sourceImage, SDL_SRCALPHA, 0);
if (*((*i).targetSurface) == mapBackground_) {
SDL_SetAlpha((*i).sourceImage, SDL_SRCALPHA, 0);
SDL_BlitSurface((*i).sourceImage, (*i).blitRect, *((*i).targetSurface), &(*i).destination);
}
else {
GfxEngine::BlitWithAlpha((*i).sourceImage, (*i).blitRect, *((*i).targetSurface), &(*i).destination);
}
UpdateRect((*i).destination);
delete (*i).blitRect; //delete the in MoveAndReplace with "new" created SDL_Rect
SDL_SetAlpha((*i).sourceImage, 0, 0);
}
delayedBlitInfo_.clear();
}
I also love the way to write the type of iterators..
-
Ever read the Source Code for some of the Java functions? Some of them won't even compile in later versions of Java...
-
Int3();
-
I vote for the Fortran one.
Sometimes I feel lucky I was never taught any kind of structural programming. Otherwise, I could, like, get involved with this kind of stuff. Life is simple as long as the only thing to do is computationally efficient algorithms.
As far as I remember, they said never to use multiple threads unless it is absolutely necessary. I, for one, have, of course, no idea what they were talking about but it sounded good enough to warrant writing it down here.
Mika
-
I'd like to nominate __if_exists and __if_not_exists C++ extensions... you can see them in the ATL headers.
-
I'd lke to nominate Microsoft for making this legal in MSVC6
for (int i=0; whatever) {
}
x = i;
Every other compiler on the planet will beat you around the head and yell "SCOPE!" at you if you tried that nonsense.
-
That's pretty blatantly unfair to Microsoft. C++ as a standard wasn't even ratified until the year that C++ 6.0 was released, meaning that there were at least 5 versions of the program released while C++ was in development. If this were something GNU/Linux related, I doubt you'd be just as quick to slap them around for not conforming to a standard during development that didn't even exist. I'm not saying that you, personally, are a Linux-lover, just that it's a lot more trendy to be quick to blame Microsoft for all the problems in their software.
Once somebody made the decision that "for loops are shorthand for while loops, so the declared variables should be accessible outside the loop" or something else happened, and it was released, and thousands and then millions of people started using Visual C++, Microsoft faces a conundrum. They can fix the language and piss off everybody who doesn't feel like they need to spend the time, and therefore money, to fix their code. Those people will hold it against Microsoft, possibly not buy the new version of their software, and go on holding Microsoft accountable for bugs in the old version of their software. Meaning Microsoft either has to support multiple versions of software, or they have to stick with the old behavior. Since sticking with the old behavior is less risky, it makes more sense while Microsoft is still competing with other companies. Nowadays, Microsoft doesn't really have to care and part of their business strategy is demonstrating that they're willing to go the extra mile to get "standards compliance".
As an example, look at all the crap I got for seriously revising the syntax for the scripting system once. I had experienced developers acting like I was incompetent just because I changed it, regardless of whether it actually made things better or not, when my changes affected all of a dozen people directly and maybe some hundred thousand people. Microsoft makes changes to the compiler, it affects millions of people directly, and billions of people indirectly. What kind of ****storm could they expect to hit the fan if there wasn't so much pressure to conform to standards as there is nowadays?
All that being said, MSVC2008 does give you
main.cpp(35) : error C2065: 'i' : undeclared identifier
So when I read your comment it comes across as a symptom of the problem that would cause Microsoft to say that they should keep things the way they are, because presumably if they left COFF support in and didn't change anything, you'd be upgrading to 2008 and using that instead. Granted, I don't see any good reason for them to take COFF out except to force people to use their proprietary debug files, but I doubt that's something that couldn't be fixed given time, effort, and some well-place #defines.
-
That's pretty blatantly unfair to Microsoft. C++ as a standard wasn't even ratified until the year that C++ 6.0 was released, meaning that there were at least 5 versions of the program released while C++ was in development. If this were something GNU/Linux related, I doubt you'd be just as quick to slap them around for not conforming to a standard during development that didn't even exist. I'm not saying that you, personally, are a Linux-lover, just that it's a lot more trendy to be quick to blame Microsoft for all the problems in their software.
If I encountered anything as stupid on Linux I'd be just as quick to blame them. :p
I don't encounter stupidity on Linux cause I don't use it. You can bet I'd complain more if I ever took leave of my senses long enough to install it. :p
-
wrt the for loop, there's been a compiler switch since VS2005 that will change VCs behaviour on this one /Zc:forScope
It's on by default.
-
That's pretty blatantly unfair to Microsoft. C++ as a standard wasn't even ratified until the year that C++ 6.0 was released, meaning that there were at least 5 versions of the program released while C++ was in development. If this were something GNU/Linux related, I doubt you'd be just as quick to slap them around for not conforming to a standard during development that didn't even exist. I'm not saying that you, personally, are a Linux-lover, just that it's a lot more trendy to be quick to blame Microsoft for all the problems in their software.
Once somebody made the decision that "for loops are shorthand for while loops, so the declared variables should be accessible outside the loop" or something else happened, and it was released, and thousands and then millions of people started using Visual C++, Microsoft faces a conundrum. They can fix the language and piss off everybody who doesn't feel like they need to spend the time, and therefore money, to fix their code. Those people will hold it against Microsoft, possibly not buy the new version of their software, and go on holding Microsoft accountable for bugs in the old version of their software. Meaning Microsoft either has to support multiple versions of software, or they have to stick with the old behavior. Since sticking with the old behavior is less risky, it makes more sense while Microsoft is still competing with other companies. Nowadays, Microsoft doesn't really have to care and part of their business strategy is demonstrating that they're willing to go the extra mile to get "standards compliance".
As an example, look at all the crap I got for seriously revising the syntax for the scripting system once. I had experienced developers acting like I was incompetent just because I changed it, regardless of whether it actually made things better or not, when my changes affected all of a dozen people directly and maybe some hundred thousand people. Microsoft makes changes to the compiler, it affects millions of people directly, and billions of people indirectly. What kind of ****storm could they expect to hit the fan if there wasn't so much pressure to conform to standards as there is nowadays?
All that being said, MSVC2008 does give you
main.cpp(35) : error C2065: 'i' : undeclared identifier
So when I read your comment it comes across as a symptom of the problem that would cause Microsoft to say that they should keep things the way they are, because presumably if they left COFF support in and didn't change anything, you'd be upgrading to 2008 and using that instead. Granted, I don't see any good reason for them to take COFF out except to force people to use their proprietary debug files, but I doubt that's something that couldn't be fixed given time, effort, and some well-place #defines.
I nominate this as an absurdly over-the-top totally-unnecessary response from a clearly disgruntled programmer.
:p
-
I've never been happy about watching other people squander my hard work and, more importantly, my time.
I'm just glad it's all in the past now. :)
-
Does that mean you're working on FSOpen again? Or that you are forever done?
-
It means I'm around to provide support, but I don't plan on coding on FS2Open for the foreseeable future.
-
Does that mean I've got permission to start adding the stuff from the patch in the Diaspora internal to trunk then?
-
Check your PMs. :)
-
This was a rather interesting approach to checking four points surrounding a position on a grid as part of an A* Pathfinding setup...
for (yPos = -1; yPos >1; yPos = yPos + 2)
{
for (xPos = -1; xPos >1; xPos = xPos = xPos+2)
{
xPosB = (xPos + (path[pointer].getXValue()));
yPosB = (yPos + (path[pointer].getXValue()));
current = new XYValue(xPosB, 0);
if (roads.getByLocation(current) != 0)
{
options.add(current);
}
current = new XYValue(0,yPosB);
if (roads.getByLocation(current) != 0)
{
options.add(current);
}
}
}
From that point onwards, I decided to do it the old-fashioned way ;)
-
Never, ever, ever convert an unsigned long to a double and then back again if you have 4294967295 assigned to it.
-
a few years ago i tried to write a class which simulates an integer, except that this integer could handle much larger values than a normal 4-byte integer.
naturally i had to implement all the basic arithmetic functions (+,-,*,/)....
a few months ago i found my code again and wanted to see how i solved this stuff... and i could figure out everything except my division function (which works correct and surprisingly(!) fast)... but i have no f*king clue how it works and what i did there *g*
also it seems that at that time i thought it's obvious how it works and just refused to comment it .... d'oh.
maybe it was a result of the Ballmer Peak (http://xkcd.com/323/).. i don't know
so, here it is, that ugly beast ... :
BigInt& BigInt::operator/=(BigInt divisor)
{
const BigInt biNull("0");
if (divisor==biNull)
throw exception("division through zero");
if (/*this*/isLess/*than*/(divisor)) {
// result would be 0.xxxxx
num_.clear();
num_.push_back('0');
return *this;
}
cVec result;
vsize div_len = divisor.length();
while (divisor<=*this)
divisor << 1; // fast divisor*10
divisor >> 1;
unsigned i=1, k=0, l=0;
while (true) {
while (divisor>*this) {
if (*this==biNull || (i>=2 && l==k)) {
result.insert(result.begin(), '0');
i=1;
}
divisor >> 1; // fast divisor/10
++i;
l=k;
}
++k;
if (divisor.length() < div_len)
break;
unsigned j=0;
for (; divisor<=*this; ++j)
*this -= divisor;
result.insert(result.begin(), j+'0');
}
if (result.size()>1 && *result.begin() == '0')
result.erase(result.begin());
num_.swap(result);
return *this;
}
maybe i will give it a second look now.. with a pen and a paper ;)
-
Browsing through the source files of my current project I found this brilliant piece code.
Converting a number to a string, the easy way:
string ObjectManager::CreateStringFromNumber(unsigned int value, unsigned int digit)
{
#if (!((('9' - 9) == '0') && (('8' - 8)8) == '0') && (('7' - 7) == '0') && (('6' - 6) == '0') && (('5' - 5) == '0') && (('4' - 4) == '0') && (('3' - 3) == '0') && (('2' - 2) == '0') && (('1' - 1) == '0')))
Logger log("CreateStringFromNumber");
log.WriteLine(RootLogger::ERROR, "Failed to convert from int to char");
throw "Error";
#endif
string result(digits, '0');
int tmp = 1;
for (unsigned int i = 1; i < digits; ++i)
{
tmp *= 10;
}
for (string::iterator iter = result.begin(); iter != result.end(); ++iter)
{
(*iter) = static_cast<char>((value/tmp)+'0');
value %= tmp;
tmp /= 10;
}
return result;
}
i guess sprintf just doesn't cut it any more, right uchuujin ;)
-
get lost :>
-
void cUsable::Use();
Now my code really is on drugs.
-
Thought I'd post one from within the SCP itself.
/analyse gives the rather tame
3>c:\users\james\documents\visual studio 2008\projects\freespace2\code\graphics\generic.cpp(36) : warning C6054: String 'argument 1' might not be zero-terminated: Lines: 32, 35, 36
The code that caused this warning?
ga->filename[strlen(ga->filename)] = '\0';
-
portej05:
That line makes no sense... strlen(ga->filename) won't work right if it isn't null-terminated, but assuming it doesn't crash from an access violation, the return value will have '\0' there already...
:wtf:
-
Aardwolf: I know :P Hence why it is here :D
-
That is just beyond wrong. And it has gotten much worse after seeing it since it appears that was part of one of my commits. :shaking:
-
Just found a pile of these:
orienteditor.cpp Line 220:
m_spin1.SetRange((short)99999, (short)-99999);
For those who aren't sure what's going on, the maximum value of a signed short is 32767
-
Some exercises in unintentional obfuscation from my game dev library.
if (o.x < cx - allow) {
safePush(c - 1, r, o);
}
if (o.x > cx+allow) {
safePush(c + 1, r, o);
}
if (o.y < cy - allow) {
if (o.x < cx - allow) {
safePush(c - 1, r - 1, o);
}
if (o.x > cx+allow) {
safePush(c + 1, r - 1, o);
}
safePush(c, r - 1, o);
}
if (o.y > cy + allow) {
if (o.x < cx - allow) {
safePush(c - 1, r + 1, o);
}
if (o.x > cx+allow) {
safePush(c + 1, r + 1, o);
}
safePush(c, r + 1, o);
}
safePush(c, r, o);
for (var c:int = 0; c < density; c++) {
for (var r:int = 0; r < density; r++) {
for (i = 0; i < grid[c][r].length; i++) {
var a:Entity = grid[c][r][i];
for (var j:int = i + 1; j < grid[c][r].length; j++) {
if (!a.checkDupeColl(grid[c][r][j]) && !grid[c][r][j].checkDupeColl(a)) {
a.collided.push(grid[c][r][j]);
grid[c][r][j].collided.push(a);
if (a.collisions.willHit(grid[c][r][j].collisions.type)) {
a.entityCollisionSolve(grid[c][r][j], true);
}
}
}
}
}
}
-
That is some fantastic use of whitespace and descriptive variable names.
-
It made sense at the time.
Actually, and sadly, it still makes sense now.
The whitespace is because flashdevelop indents in tabs, and this was already tabbed in a great deal due to class/package/other functions.
-
It made sense at the time.
Actually, and sadly, it still makes sense now.
The whitespace is because flashdevelop indents in tabs, and this was already tabbed in a great deal due to class/package/other functions.
The problem isn't the tabs: the problem is having a tab spacing of 8. :) Cut that to 4 (or 2, if you prefer) and you'll be a much happier chipmunk.
-
But... I like it like this ):
-
if (o.x < cx - allow) {
safePush(c - 1, r, o);
}
if (o.x > cx+allow) {
safePush(c + 1, r, o);
}
Doh! quite generous spacing there. Well, at least it motivates you to keep the actual code lines short.
-
It made sense at the time.
Actually, and sadly, it still makes sense now.
The whitespace is because flashdevelop indents in tabs, and this was already tabbed in a great deal due to class/package/other functions.
The problem isn't the tabs: the problem is having a tab spacing of 8. :) Cut that to 4 (or 2, if you prefer) and you'll be a much happier chipmunk.
The whole point in using tabs (I personally don't, but ...) is that you, the programmer, can choose where your tab stops are. You want a tab spacing of 4? (setq tab-width 4) :)
So I say, let him use tabs if he wants. It's not like it's hard to "fix" it
-
char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);--E;J[E]=T[E]=E)printf("._");for(;(A-=Z=!Z)||(printf("\n|"),A=39,C--);Z||printf(M))M[Z]=Z[A-(E=A
[J-Z])&&!C&A==T[A]|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
This is probably the best I have seen for a while. It is a winning entry to Obfuscated C Code competition in 1985. It is still short enough to look like it could be understood, but confusing enough that you really don't want to try.
The whole thing is explained here:
http://homepages.cwi.nl/~tromp/maze.html
It's amazing what you can come up with when searching how to do object oriented kind of stuff with ANSI C. Object Oriented programming in ANSI C doesn't seem that difficult yet, I'm actually surprised how easily it can be done.
-
After horsing around in the ATL and MFC headers trying to track down a compile error, I'd like to nominate the ATL/MFC macros. :eek:
I'd say some of the ATL developers inside Microsoft also feel that way, as they managed to get confused within the ATL library (http://addxorrol.blogspot.com/2009/07/poking-around-msvidctldll.html).
-
After horsing around in the ATL and MFC headers trying to track down a compile error, I'd like to nominate the ATL/MFC macros. :eek:
I'd say some of the ATL developers inside Microsoft also feel that way, as they managed to get confused within the ATL library (http://addxorrol.blogspot.com/2009/07/poking-around-msvidctldll.html).
That was the funniest article I've read in a while. :lol:
-
I'd like to nominate memset(this, 0, sizeof(ade_table_entry)); for provoking the following comment from WMCoolmon:
//std::vector<ade_table_entry> Subentries;
//std::vector<uint> Subentries;
//WMC - I have HAD it with these motherfriendly vectors
//on this motherfriendly class.
-
I just discovered that in C# I can do this and it can be something that isn't bad:
public object this[int i]
{
get
{
return something[i];
}
set
{
something[i] = value;
}
}
and then:
this[i] = something;
-
Found this gem inside missionbriefcommon.cpp:
strcat(errormsg, "\0");
-
WOAH.
Just found this function:
void lcl_translate_brief_icon_name(char *name)
It's about as in-efficient as it gets, and there're lots of examples in localize.cpp.
Worse, if this is called per-frame (not established yet), I wouldn't want to be French, German or Polish.
This one's good as well (from missiondebrief.cpp):
strcpy(voice_dest, "9_");
strcpy(voice_dest + 2, voice_base);
-
Almost as good as Mikas above:
From aicode.cpp line 5875:
int t = ((Missiontime /(65536*10)) ^ target_objnum ^ 0x01) % (NUM_SKILL_LEVELS+2);
-
Not horrifying, as such, but certainly made my (FSO) day:
// Stuffs a boolean value pointed at by Mp.
// YES/NO (supporting 1/0 now as well)
// Now supports localization :) -WMC
void stuff_boolean(bool *b, bool a_to_eol)
{
char token[32];
stuff_string_white(token, sizeof(token)/sizeof(char));
if(a_to_eol)
advance_to_eoln(NULL);
if( isdigit(token[0]))
{
if(token[0] != '0')
*b = true;
else
*b = false;
}
else
{
if(!stricmp(token, "yes")
|| !stricmp(token, "true")
|| !stricmp(token, "ja") //German
|| !stricmp(token, "Oui") //French
|| !stricmp(token, "si") //Spanish
|| !stricmp(token, "ita vero") //Latin
|| !stricmp(token, "HIja'") || !stricmp(token, "HISlaH")) //Klingon
{
*b = true;
}
else if(!stricmp(token, "no")
|| !stricmp(token, "false")
|| !stricmp(token, "nein") //German
|| !stricmp(token, "Non") //French
//I don't know spanish for "no"
//But according to altavista, spanish for "No" is "no"
//Go figure.
|| !stricmp(token, "minime") //Latin
|| !stricmp(token, "ghobe'")) //Klingon
{
*b = false;
}
else
{
*b = false;
Warning(LOCATION, "Boolean '%s' type unknown; assuming 'no/false'",token);
}
}
diag_printf("Stuffed bool: %s\n", (b) ? NOX("true") : NOX("false"));
}
Note: This is not an endorsement to use anything other than YES or NO - these may be removed in the future for performance or security reasons.
-
wouldn't it have been better to run it through the localization functions?
though I guess that's why it's here.
-
The localisation functions would be better implemented as maps - they're one VERY expensive function call.
Probably because the localisation functions were so damn slow.
-
unsigned int epicfail = 0/0;
'nuff said.
-
if(_wrappedtext[end-1] == ' ') //DirectX ignores spaces because microsoft likes hiring retards, so we have to improvise
{
_wrappedtext.insert(end,1,L'X');
_driver->calcTexcRect(_wrappedtext.String()+linepos,_fontID,&strdim,_drawflags,count+1);
_wrappedtext.erase(end,1);
count = strdim.right;
memset(&strdim,0,sizeof(tagRECT));
_driver->calcTexcRect(L"X",_fontID,&strdim,_drawflags,1);
strdim.right=count-strdim.right;
}
This code is even more horrifying when you realize that there isn't a way around this. I hate DirectX.
-
bool __fastcall SetUVCoords(unsigned char index, float u, float v)
{
float* uvcoords=(float*)(((char*)this)+sizeof(cVertexMulti)); uvcoords[(index*=2)] = u; uvcoords[++index] = v;
}
Try and guess why I had to do this.
-
This has something to do with parametric U and V coordinates? Otherwise, I don't know, I'm C++ illiterate (and will remain so). Algorithm wise, that index*=2 and later
++index results in a nice, confusing effect...
-
int t = ((Missiontime /(65536*10)) ^ target_objnum ^ 0x01) % (NUM_SKILL_LEVELS+2);
Whoa! There surely isn't an easier way to do this? Or is it because of performance?
-
bool __fastcall SetUVCoords(unsigned char index, float u, float v)
{
float* uvcoords=(float*)(((char*)this)+sizeof(cVertexMulti)); uvcoords[(index*=2)] = u; uvcoords[++index] = v;
}
Try and guess why I had to do this.
struct UVCoord { float u, float v};
class MyClass {
std::vector<UVCoord> uvcoords;
//...
public:
//...
bool __fastcall SetUVCoords(Uint8 index, float u, float v)
{
UVCoord tmp = {u,v};
uvcoords[index] = tmp;
}
};
Why wouldn't it work this way? Or am I misunderstanding what your code is supposed to do..?
-
Sadly, no. The reason i had to do it this crazy way is because its for graphics card data. The data inside the struct must be packed in a very specific manner, so I cannot use anything like vectors or virtual functions or *anything* that might introduce hidden data within the struct. Normally only 1 set of UV coordinates is required, so you just make a struct with that, but in this case i needed to allow for any number of UV coordinate pairs, and thus this monstrosity was born.
In reality, I never actually create the struct in the first place, (its pointed to a block of memory within a vertex buffer) so its slightly less insane then it appears to be... slightly.
-
Truly horrifying.
-
Someone at some point had a very late night:
From neblightning.cpp (674)
// add some flavor to the bolt. mmmmmmmm, lightning
if(!IS_VEC_NULL_SQ_SAFE(&Storm->flavor)){
// start with your basic hot sauce. measure how much you have
vec3d your_basic_hot_sauce;
vm_vec_sub(&your_basic_hot_sauce, &strike, &start);
float how_much_hot_sauce = vm_vec_normalize(&your_basic_hot_sauce);
// now figure out how much of that good wing sauce to add
vec3d wing_sauce = Storm->flavor;
if(frand_range(0.0, 1.0f) < 0.5f){
vm_vec_scale(&wing_sauce, -1.0f);
}
float how_much_of_that_good_wing_sauce_to_add = vm_vec_normalize(&wing_sauce);
// mix the two together, taking care not to add too much
vec3d the_mixture;
if(how_much_of_that_good_wing_sauce_to_add > 1000.0f){
how_much_of_that_good_wing_sauce_to_add = 1000.0f;
}
vm_vec_interp_constant(&the_mixture, &your_basic_hot_sauce, &wing_sauce, how_much_of_that_good_wing_sauce_to_add / 1000.0f);
// take the final sauce and store it in the proper container
vm_vec_scale(&the_mixture, how_much_hot_sauce);
// make sure to put it on everything! whee!
vm_vec_add(&strike, &start, &the_mixture);
}
-
That's amazing. :lol:
-
The horrifying part is that the sauce is required for the clients in multiplayer but never defined if a standalone is running. That = crash for any nebula mission.
-
Yeah I'd seen that one before but decided it was too spicy for me to touch. :p
-
I nominate this for the 2 hours of confusion it caused me (my dumb assumption too :P )
//WMC - pilot files don't support different numbers of medals
Assert(Num_medals == MAX_MEDALS);
for (i=0; i<Num_medals; i++){
cfwrite_int(stats->medals[i], file);
}
for(;i<MAX_MEDALS;i++){
cfwrite_int(0, file);
}
It only writes MAX_MEDALS*4 bytes, not MAX_MEDALS*2*4 as I initially read it.
-
// Copyright ©2010 Erik McClure
#ifndef __FUNCTOR_H__
#define __FUNCTOR_H__
namespace bss_util {
#define __EMPTY
#define __FUNCTOR(name, treturn, rt, argsdef, args, argsval) struct name##_base \
{ \
virtual ~##name##_base() {} \
virtual treturn __fastcall Call(args)const =0; \
inline virtual name##_base* __fastcall Clone() const=0; \
treturn operator()(args) const { rt Call(argsval); } \
}; \
template<class T> \
struct name : name##_base \
{ \
name(T* source, treturn (__fastcall T::*funcptr)(argsdef)) : _funcptr(funcptr), _source(source) {} \
virtual treturn __fastcall Call(args) const { rt (_source->*_funcptr)(argsval); } \
inline virtual name##<T>* __fastcall Clone() const { return new name##<T>(*this); } \
protected: \
T* _source; \
treturn (__fastcall T::*_funcptr)(argsdef); \
}
#define __FUNCTOR0(name,treturn, rt) __FUNCTOR(name,treturn, rt, void, void, __EMPTY)
#define FUNCTOR0(name,treturn) __FUNCTOR0(name, treturn, return)
#define FUNCTOR0V(name) __FUNCTOR0(name, void, __EMPTY)
#define __FUNCTOR_COMBINE(p1,p2) p1##,##p2
#define __FUNCTOR1(name,treturn, rt, arg1type, arg1name) __FUNCTOR(name,treturn, rt, arg1type, arg1type arg1name, arg1name)
#define FUNCTOR1(name,treturn, arg1type) __FUNCTOR1(name, treturn, return, arg1type, arg1)
#define FUNCTOR1V(name,arg1type) __FUNCTOR1(name, void, __EMPTY, arg1type, arg1)
#define __FUNCTOR2(name,treturn, rt, arg1type, arg1name, arg2type, arg2name) __FUNCTOR(name,treturn, rt, __FUNCTOR_COMBINE(arg1type,arg2type), __FUNCTOR_COMBINE(arg1type arg1name,arg2type arg2name), __FUNCTOR_COMBINE(arg1name,arg2name))
#define FUNCTOR2(name,treturn, arg1type, arg2type) __FUNCTOR2(name, treturn, return, arg1type, arg1, arg2type, arg2)
#define FUNCTOR2V(name,arg1type,arg2type) __FUNCTOR2(name, void, __EMPTY, arg1type, arg1, arg2type, arg2)
#define __FUNCTOR3(name,treturn, rt, arg1type, arg1name, arg2type, arg2name, arg3type, arg3name) __FUNCTOR(name,treturn, rt, __FUNCTOR_COMBINE(__FUNCTOR_COMBINE(arg1type,arg2type),arg3type), __FUNCTOR_COMBINE(__FUNCTOR_COMBINE(arg1type arg1name,arg2type arg2name), arg3type arg3name), __FUNCTOR_COMBINE(__FUNCTOR_COMBINE(arg1name,arg2name),arg3name))
#define FUNCTOR3(name,treturn, arg1type, arg2type, arg3type) __FUNCTOR3(name, treturn, return, arg1type, arg1, arg2type, arg2, arg3type, arg3)
#define FUNCTOR3V(name,arg1type,arg2type,arg3type) __FUNCTOR3(name, void, __EMPTY, arg1type, arg1, arg2type, arg2, arg3type, arg3)
//If you go up to 4 the compiler starts having issues with all the defines
}
#endif
I have an unhealthy obsession with metaprogramming
-
*snip*
I have an unhealthy obsession with metaprogramming
What. The frak.