Visual Studio 2010 Project File

For discussion of the code running behind the game

Moderator: Staff

Post Reply
SapphireStorm
Newbie
Posts: 4
Joined: Fri Jul 22, 2011 11:39 pm

Visual Studio 2010 Project File

Post by SapphireStorm » Tue Jul 26, 2011 12:42 am

Hi,

I was messing around with the old VS 2005/2008 project files and got a 2010 project up and running. However, it's still a little clunky. I have some questions which should hopefully help iron it out.

First, in video.cpp

Code: Select all

 ... line 1287
   for (int i = 0; i < NUM_SIDES; i++)
   {
      float fraction = i / (float)(NUM_SIDES - 1);
      float angle = fraction * M_PI * 2.0f;
      vertices[2+(i*2)+0] = cosf(angle) * radius;
      vertices[2+(i*2)+1] = sinf(angle) * radius;
   }

M_PI is undefined. Now, I'm assuming that's coming from math.h. I added the appropriate pre-processor define to make it compile. I just wanted to make sure that's correct.

Next, also in video.cpp there are a couple of OpenGL defines coming from extensions, namely GL_FRAMEBUFFER_EXT and GL_COLOR_ARRAY, which were undefined. I don't know where those come from in a Linux environment with the code as is. I included glew.h at the top of video.h and moved on. However, there's probably a better solution since HOA doesn't depend on glew.h and you're already getting the extensions by hand.

Finally, does the current version on SVN play through? Mine crashes after a few seconds of exploring in the first cave after the intro cut scene. An index for a vector is out of range in map_objects.cpp.

Image

I'm assuming the problem is on my end. However, I just wanted to make sure before I started sifting through compiler warnings.

The battle code works very nicely though.
User avatar
Roots
Dictator
Posts: 8668
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Visual Studio 2010 Project File

Post by Roots » Tue Jul 26, 2011 12:54 am

I'm not sure what to think about those issues in the video engine. That code hasn't been touched by a long time, and its been an even longer time since someone with significant OpenGL experience messed around with it. All I know is that it has worked for us on Linux and OS X, and the Windows Code::Blocks files haven't had any issue with it either that I'm aware of.


Yes, the current SVN version plays through. I tested it last night before I made a large commit, and I tested the cave map again just now to confirm. I'm not sure why you're having that problem. Especially if the Code::Blocks build on Windows doesn't have that issue (which I don't think it does, but I can't be sure).
Image
rujasu
Developer
Posts: 758
Joined: Sun Feb 25, 2007 5:40 am
Location: Maryland, USA

Re: Visual Studio 2010 Project File

Post by rujasu » Tue Jul 26, 2011 4:29 am

First off, thanks a lot for doing this. Would you be able to post a copy of the new project/solution and perhaps explain how you got the dependencies set up for us? We've had a lot of trouble with getting VS support working, and your help would be greatly appreciated.

Yes, the math.h header should be included -- that's <cmath>, right? It's an odd difference between VS and GCC; I thought we had fixed that already but I guess not.

I'm not sure about GLEW. My guess is that the Linux/Mac users have an up-to-date OpenGL whereas Windows often has an older one. (Our usual release, built with GCC, includes a DLL for OpenGL in the package.) So, including GLEW might actually be the right move, at least for the VS build. Maybe we can have GLEW included only on VS for the time being, using an #ifdef of some sort?

I haven't seen any out of range errors, so I can't offer much help there, at least at this point. Were you able to get the editor working?
nan
Newbie
Posts: 18
Joined: Sat May 28, 2011 12:57 pm

Re: Visual Studio 2010 Project File

Post by nan » Tue Jul 26, 2011 11:42 am

An index for a vector is out of range in map_objects.cpp.
This is a feature of MS STL implementation. They do bounds checking on containers for debug builds.

I can confirm this by adding an assert.

Code: Select all

   if (horizontal_adjustment == true) {
      for (uint16 i = start_point, j = 0; i <= end_point && i < _collision_grid[line_axis].size(); i++, j++) {
         assert(j < grid_line.size());
         grid_line[j] = (_collision_grid[line_axis][i] & sprite->context);
      }
   }
SapphireStorm
Newbie
Posts: 4
Joined: Fri Jul 22, 2011 11:39 pm

Re: Visual Studio 2010 Project File

Post by SapphireStorm » Wed Jul 27, 2011 5:37 am

Sorry. I didn't mean to imply your code was wrong and needed fixed. It's actually quite well done. It was more of a "How to proceed question".

I looked into those headers. The math.h solution is easy.

Code: Select all

... Snippet from Microsoft's implementation of math.h
#if defined(_USE_MATH_DEFINES) && !defined(_MATH_DEFINES_DEFINED)
#define _MATH_DEFINES_DEFINED

/* Define _USE_MATH_DEFINES before including math.h to expose these macro
 * definitions for common math constants.  These are placed under an #ifdef
 * since these commonly-defined names are not part of the C/C++ standards.
 */

/* Definitions of useful mathematical constants
 * M_E        - e
 * M_LOG2E    - log2(e)
 * M_LOG10E   - log10(e)
 * M_LN2      - ln(2)
 * M_LN10     - ln(10)
 * M_PI       - pi
 * M_PI_2     - pi/2
 * M_PI_4     - pi/4
 * M_1_PI     - 1/pi
 * M_2_PI     - 2/pi
 * M_2_SQRTPI - 2/sqrt(pi)
 * M_SQRT2    - sqrt(2)
 * M_SQRT1_2  - 1/sqrt(2)
 */

#define M_E        2.71828182845904523536
#define M_LOG2E    1.44269504088896340736
...

So, having the IDE define _USE_MATH_DEFINES directly solves this without having to change any Allacrost source.

The default OpenGL headers on Windows are another matter. They're literally dinosaurs! A tribute to a forgotten era of immediate mode pipelines and pre-nVidia graphical solutions. I guess Microsoft doesn't update them so they can push directX?

Code: Select all

/*++ BUILD Version: 0004    // Increment this if a change has global effects

Copyright (c) 1985-96, Microsoft Corporation

Module Name:

    gl.h

...

/* Version */
#define GL_VERSION_1_1                    1

...

As of now, I'm going forward with adding glew.h as a dependency for the VS version. There's one change to the source in each of the following: texture_controller.h, texture.h, and video.h. They all follow this format

Code: Select all

... Snippet from video.h
#ifdef _WIN32
   #include <windows.h> // needs to be included before gl.h
   #include <GL/glew.h>
#endif

#ifdef __APPLE__
   #include <OpenGL/gl.h>
   #include <OpenGL/glu.h>
#else
   #include <GL/gl.h>
   #include <GL/glu.h>
#endif

I don't know how this would affect the Code::Blocks solution. Hopefully, it comes package with GLEW too. We could always add an additional define for VS instead.

I think that covers most of my issues at the moment. Currently, the solution builds on both debug and release modes. The release version functions as intended as far as I can tell. The debug version bombs out when exploring maps because of the problem talked about earlier in the thread. However, you could debug battle or shop code with it at the moment.

*** The How Does It Work Section ***
1.) Compiling:
This was pretty straight forward. I just included the headers for the dependencies and let it rip. The only problems were the header implementation mismatches described earlier.

2.) Linking:
This was and always is extremely difficult on Windows when dealing with libraries not intended for the OS. Lua, Luabind, OpenAL, OpenGL, etc. no problem. You can just download or compile the VS 2010 libs and dlls. Iconv, intl, libjpeg, etc. are very difficult to link with a native Windows tool chain.

Each of them are dependent on some C or C++ run time. On Windows, there's a different version of these run times for literally every day of the year. And, you guessed it, they are generally not compatible with each other. So, when you start linking against these Linux libraries which are cross compiled with GCC or some random version of MSVC, you really don't know which C/C++ run time they're built against (unless you use Dependency Walker.) Depending on what you end of doing, you might have a project dependent on msvcrt.dll, msvcr50.dll, msvcr100.dll, msvcr80.dll, and whatever else. It might link. It might not. It might link and crash at run time. Who really knows.

Every version of VS targets specific C/C++ run times by default. You need to try and make sure all your dlls also target these run times. If you don't, you may or may not have problems.

The simplest solution is to make sure all your dlls are compiled with VS 2010. However, that's not always possible. I'm looking at you iconv and intl. If you can get those to compile with VS 2010, I would be absolutely amazed. As far as I know, their developers gave Windows' developers the finger.

So, the second solution is to link against static libraries and not use dlls for libraries you don't have the correct VS version for. This is how the notorious libjpeg links. The developers of libjpeg-turbo were kind enough to have static libs in their distribution.

Finally, you can always keep beating on your linker til it links them anyways. However, you need to be careful. Their is literally a text book example in your code base of what can go wrong. Check this out

Code: Select all

... Snippet from image.cpp around line 690
void ImageDescriptor::_GetJpgImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(Exception) {
   // open up the file (with C IO)
   FILE* fp = fopen(filename.c_str(), "rb");

   if (fp == NULL) {
      throw Exception("failed to open file: " + filename, __FILE__, __LINE__, __FUNCTION__);
      return;
   }

   // do our magical setup: create a jpeg decompressor and the relevant error stuff
   jpeg_decompress_struct cinfo;
   jpeg_error_mgr jerr;

   cinfo.err = jpeg_std_error(&jerr);
   jpeg_create_decompress(&cinfo);

   // tell jpeg where to look for the data...
   jpeg_stdio_src(&cinfo, fp);

If you dynamically link libjpeg, 'jpeg_stdio_src(&cinfo, fp);' blows up. Why? Well, FILE* fp clearly is dependent on the C run time; specifically, whichever run time VS 2010 is by default linking against. jpeg_stdio_src is also dependent on some C run time because it's taking a parameter defined by the standard of the run time. However, which one? The correct answer is not the same one as stdio.h. So, if the run times don't match, that function basically takes two different object definitions, treats them as equal objects, and passes them between dlls.

I hope that helped to clear up some of the confusion to what exactly is going on. If you have any more questions, just ask.

I've uploaded the necessary solution files and dependencies. To build, drop all of the project files and the dependency folder into the "game" directory. Overwrite anything that conflicts with existing files. Then, make the necessary changes to video.h, texture.h, and texture_controller.h to include GLEW. Finally, to run the solution you need to go through the dependencies folder and copy all the dlls into the "game" directory. All the dlls should be in their respective "bin" directory within the dependencies folder.

The project will put all intermediate files into game\Debug or game\Release directory depending on the configuration. It's configured to debug solutions directory in the "game" directory. Finally, the release version will automatically copy the exe into the "game" directory on a successful build if you would want to launch it from Windows Explorer.

I think that covers everything. I'm going to take a look at the level editor later this week and get it up and running.

Oh! One last thing. Intl and iconv are currently being linked dynamically. If you look at the output window in a debug build, you can see the run time absolutely raging about it. If anyone has some extra time, could you cross compile static libs for those using GCC? I mean, they're working as is. However, it would probably be better to resolve the issue before the house of cards collapses.

(Edit: I couldn't upload the file to the forums. The dependencies make the file size too large. What should I do?)
User avatar
Roots
Dictator
Posts: 8668
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Visual Studio 2010 Project File

Post by Roots » Thu Jul 28, 2011 5:02 am

[quote=SapphireStorm]
Sorry. I didn't mean to imply your code was wrong and needed fixed. It's actually quite well done. It was more of a "How to proceed question".
[/quote]

Oh don't worry about it. Even if you did imply that I wouldn't be offended and would probably agree with you. Finding that problem in the map code is actually something that we really should look into, though I don't have time right now to be digging in that area myself. The video engine issues I was just pointing out the reasons why that code was far from perfect.


Yeesh, compiling on Windows seems like such a PITA. (That's not to say that Linux isn't sometimes the same way...). I honestly don't have much to say or suggest on this matter as I am an uber noob when it comes to Windows development, so I typically leave such issues and discussions for others to decide. Its one of the few areas of Allacrost development that I don't stick my head in and start wreaking havoc. :heh:


As for your solution file, e-mail it to team@allacrost.org and we can put it up on our FTP or in to SVN, if you think its ready for that.
Image
SapphireStorm
Newbie
Posts: 4
Joined: Fri Jul 22, 2011 11:39 pm

Re: Visual Studio 2010 Project File

Post by SapphireStorm » Sun Jul 31, 2011 9:17 pm

Hey,

I got the map editor up and running. So, as of revision 2029, everything seems to work pretty well.

Source Changes:

I made some minor changes to the source. The changes in

\src\editor\grid.h
\src\editor\tileset_editor.h
\src\engine\texture.h
\src\engine\video.h

all revolve around GLEW being a dependency on VS. For all other compilers and IDE's, the source is basically unchanged for these files.

In \src\common\dialog.h, I changed

Code: Select all

   uint8 SetIndicator(uint8 type)
      { _indicator_symbol = type; }

to

Code: Select all

   void SetIndicator(uint8 type)
      { _indicator_symbol = type; }

which I think is what was intended.

VS Project Files:

I included a solution file, two project files, and two filter files. The solution is set up to build both Allacrost, and the map editor. However, I configured the solution to disable the building of the map editor by default. Distributing a dependency as large as Qt from your own FTP servers didn't make sense to me. There's a section on how to set it up towards the end of this post. It's actually surprisingly simple and straight forward.

All these files are intended to be in the \game\ directory.

Dependencies:

There's a “dependenciesVS2010.zip” file contained in the file I emailed. It contains all the libraries, DLLs, and headers needed to build Allacrost. For the map editor, it contains everything except Qt.

The root folder of the dependencies is intended to be in the \game\ directory. You can just unzip it and move it in there.

Therefore, if everything is placed correctly, it should look like:

…\game\allacrost.sln
…\game\allacrost.vcxproj
etc.

…\game\dependenciesVS2010\lua-5.1.4\
etc.

At this point you should be able to load up the solution file and build Allacrost.

Run Time:

Finally, in order to run the program, you need to move all the DLL dependencies into the \game\ directory. They are located in the “bin” or “dll” directory of their respective root directory. So, for example, the Lua run times are located in

…\dependenciesVS2010\lua-5.1.4\bin\

Now, you can run or debug Allacrost.

The Map Editor:

First, follow all the instructions for building Allacrost.

Next, go to Nokia's website and download the Qt libraries for visual studio. At the time I wrote this, the current version was 4.7.3 and for VS 2008. If, in the future, they start distributing for 2010, use that.

Then, again on Nokia's website, download and install the Qt Visual Studio Add-in.

That's all you need. I would open VS and make sure you can build a blank Qt forms template just to make sure your installation is correct. However, at this point, the map editor should build.

(If you want to run the map editor from the explorer, make sure to copy the necessary Qt DLLs into the \game\ directory.)

Current Issues:

Alas, all is not perfect. Here's a list of current, known problems:

1.) Both libiconv and libintl are compiled against the msvcrt.dll. While running Allacrost with the debugger attached, you will receive lots of C- Runtime warnings. Ideally, we would want these libraries calling into msvcr100.dll, which would resolve the warnings.

In other to achieve this, both libraries need to be built from source using the VS 2010 compiler OR they need to be linked statically. I tried the static approach. I built both libraries as static archives from source using MinGW and linked against the archives directly in VS. This approached worked for debug builds and removed the warnings. The release builds, however, crashed at run time.

Note: The map editor does not suffer from any of these warnings.

2.) The linker currently outputs a library file along with an executable. This means some header or library files in the dependencies are exporting functions. This is a benign problem. However, it's kind of annoying as it increases link times. I think I may have built the luabind libraries wrong or am including the wrong headers. That's just a guess though.
SapphireStorm
Newbie
Posts: 4
Joined: Fri Jul 22, 2011 11:39 pm

Re: Visual Studio 2010 Project File

Post by SapphireStorm » Sun Jul 31, 2011 9:36 pm

I just emailed all the files.

Yeesh, compiling on Windows seems like such a PITA.


Yeah, it is. Well, in Windows' defense, it's usually not too bad if everything you're using is engineered for Windows. Trying to cross compile things for VS makes things a tad more complicated. But, in general, they could/should slim down the amount of system DLLs they have floating around. That tends to cause a lot of problems.
nemesis
Senior Member
Posts: 157
Joined: Fri Apr 29, 2011 7:53 am
Location: Sachsen/Germany

Re: Visual Studio 2010 Project File

Post by nemesis » Mon Aug 01, 2011 7:24 am

SapphireStorm wrote:In \src\common\dialog.h, I changed

Code: Select all

   uint8 SetIndicator(uint8 type)
      { _indicator_symbol = type; }

to

Code: Select all

   void SetIndicator(uint8 type)
      { _indicator_symbol = type; }

which I think is what was intended.


Thanks for correcting this. :approve:

Did you send the files to roots?
rujasu
Developer
Posts: 758
Joined: Sun Feb 25, 2007 5:40 am
Location: Maryland, USA

Re: Visual Studio 2010 Project File

Post by rujasu » Mon Aug 01, 2011 2:33 pm

He emailed it. I'm going to take a look at it tonight. If I can get it to build, I'll put it out on SVN so the Windows developers can try it out.

Thanks a lot SapphireStorm!
rujasu
Developer
Posts: 758
Joined: Sun Feb 25, 2007 5:40 am
Location: Maryland, USA

Re: Visual Studio 2010 Project File

Post by rujasu » Tue Aug 02, 2011 6:14 am

Got a slow start on this. VC++ 2010 is just finishing setup, I'll look at the project tomorrow.
Post Reply