09 May 2018 Tagged: eulorac++

Having decided to fix a bug, I took a look at the Eulora wiki page for Windows.

This is not a guide to a correct Eulora build on Windows. It’s the story of how someone did it while knowing virtually nothing about the tools, language or project. For all I know, it’s the worst way to do it that ends up working.

I followed all of the wiki instructions, which are quite detailed, as closely as I could manage. I’ve never used Visual C++ before so it was difficult to know when I was making mistakes. Once I had done all the things, I ended up with about 800 compile errors that didn’t seem covered by any of the wiki page suggestions.

Visual C++ 2010 Build Output
src/common/paws/pawsmanager.h(657): error C2146: syntax error : missing ';' before identifier 'int64val'

There were hundreds of compile errors like the above. When I looked at the lines being flagged by the compiler, they looked like simple variable declarations with an unrecognized type. For example:

    int64_t int64val;

I did some searching on that error and was led to believe that int64_t is a type used on linux and that if you want to use it on windows you have to add a typedef for it. Ok, well it seemed to me that primitive types ought to be defined once in some central location. Unfortuantely, I don’t know how the project structure or build works so I tried adding the prescribed typedef to the 'problem' file, right before the error:

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

The result: ~108 fewer compiler errors. Yay! I considered this solid progress and continued to attempt fixes for whichever compile error would appear first in the build output because, with that many compile errors, they are obviously cascading.

The next 'first' compile error turned out to be for that same missing type. That bugged me because I knew for a fact this thing can get fixed once rather than in multiple places and who knows how many times it will turn up. I made an attempt at that single fix, encouraged by:

/* config.h files are created by autoconf/automake in the gnu world...
 * So You have to set up your own for visualc, which is done here
 * This version is currently set up for windows (VC6/7/8)

Defining it there as a stab in the dark failed to fix it though. Undeterred, I returned to inserting my "solution" into every src the build presented:

typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile
typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile
typedef __int64 int64_t; // <-- Mocky's clueless hackery for M$ compile

And in four shakes of a lamb’s tail all teh int64s are satisfied. On to the next:

Additional Visual C++ 2010 Build Output
src/common/rpgrules/psmoney.cpp(57): error C2146: syntax error : missing ')' before identifier 'SCNd64'

The offending code looks like:

    if (sscanf(moneyString,"%"SCNd64",%"SCNd64",%"SCNd64",%"SCNd64"",&bitcents,&denarius,&argents,&coppers) != 4)
        bitcents = denarius = argents = 0;
        if (sscanf(moneyString,"%"SCNd64"",&coppers) != 1)
            coppers = 0;

This one took me longer to figure out. I was thrown off by the nested quotes, because I didn’t know that quotes could nest. And how does nesting quotes like that even make any sense? Anyway, I tried several things and I got several clients that would build but then crash after login (presumably during the initial parse of money). Eventually I discovered that SCNd64 is a thing. Maybe M$ didn’t know about it either and I ought to have defined it.

src/common/rpgrules/psmoney.h line 34
#define SCNd64    "lld" // <-- Mocky's clueless hackery for M$ compile

I put it in the header file because that’s where the other #defines were located. That worked but I wasn’t done yet. Seems I had to deal with one more complaint:

Yet More Visual C++ 2010 Build Output
src/client/gui/pawsslot.cpp(393): error C3861: 'atoll': identifier not found

Pointing me to:

PlaceItem( icon, mesh, material, atoll(  count.GetData() ), atoll(quality.GetData() ) );

Some poking around in that same file reveals this clue near the top:

#include <stdlib.h>	//atoll//

A quick perusal of stdlib.h yields a handful of ato functions and, as expected, no atoll. A few of them even feature the return of our good buddy __int64. I unearthed some stackoverflow dude named nos posting that MSVC has _atoi64 instead of atoll. Lo and behold, _atoi64 is right there in stdlib.h, so I made my edit:

// On the following line, Mocky renamed `atoll` to `_atoi64` for M$ compile
PlaceItem( icon, mesh, material, _atoi64(  count.GetData() ), _atoi64(quality.GetData() ) );

With that done, the build succeeds and the client runs without crashing. HUZZAH!

Well, it crashes sometimes. It crashes anytime the number picker shows up when you want to move some number of items in your inventory. I can move just one, or the whole stack no problem. But if I pop up the number picker, when I subsequently click Ok or Cancel it crashes. I spent an hour on that one. I couldn’t get it to run in the VC++ debugger but I was able to attach a sysinternals debugger and even looked at my first core dump file. Those were no help. I couldn’t find the cause.

I let that issue be because I have a work around and I didn’t come this far to shave a yak, I came to build foxybot. And it was time to get started.

mihi - 2018-05-19 10:52:59

You probably figured it out by yourself, but for the other readers of the blog: In C/C quotes cannot nest either. What you are seeing here is the C/C way of (compile time) concatenating string literals, combined with a creative way of (not) using whitespace.

When you have

#define FOO "123"
#define BAR "456"
#define BAZ "890"

you can write


to get "1234567890" (as a single string literal).

In Java you would use the + operator for that (as you do for runtime concatenation of strings).

Mocky - 2018-05-19 12:16:16

Oh man, that makes so much more sense that what I was thinking. Also explains some other things I’ve seen. Thanks.

Add a Comment