Aug 24 2012

Playing Red Alert 2 with Network using Wine

Few months ago, I bought a MacBook air and I’m pretty satisfied. One of the problems I’ve encountered, Is playing old games.

Every now and then, You will find an old game that you wish to play again. The problem is, that most of the old games doesn’t have a mac version, and even if so not an intel processor mac version.

One of those old games I wished to play was Red Alert 2. I’ve been in a friend house in the north, and he had a copy of the game, and we decided why not giving it a shot.

I’ve tried to launch the game with Wine, and it launched perfectly, the only problem was that network play didn’t work at all.

The first problem was that Red Alert 2 uses IPX which is a obsolete and most OS doesn’t support any longer. Luckily, someone else solved that problem for me, and created a patch that converts the IPX to UDP. All you need to do, is to extract this patch to the Red Alert 2 directory. What the patch does is pretty simple, the name of the DLL is “wsock32.dll” so when the process tries to load winsock, instead of getting the original Windows DLL, it will get our new DLL which hooks three major functions: socket, bind and sendto (and some other minor ones in order to trick the process to believe it is using IPX). The changes in those function replaces all the IPX socket creation request with UDP socket, and the IPX message sending with UDP broadcast.

This solution worked perfectly on Windows, but didn’t work at all on my Mac while using Wine.

The first problem with Wine was that the new DLL wasn’t even loaded. The reason for that is that Wine has some built-in implementation for well-known DLLs such as wsock32. But, Luckily enough, has the ability to override this behavior. The user will have to launch winecfg and add an overwrite rule for wsock32 (selecting native first, and then built-in).

Now the solution worked only partially, Still when clicking on “Network” on the main menu nothing happened, but when going to Options->Network it seemed like the game thinks that IPX is available. After some debugging (Launching OllyDbg on Wine is weird!) I’ve found out that the binding of the sockets fails with the error: WSAEACCES. After few minutes trying to figure out why, I’ve discovered that the default port the patch is using is 320. But all-in-all, the game is running on a unix-based OS, meaning, all ports under 1024 requires special privileges.

The first solution I thought of was to patch-the-patch so it will use another port. But then I’ve discovered that this port is not hard-coded. Meaning, The patch extracts the port from somewhere in the binding of the IPX. After playing around a bit with the configuration I’ve figured out that the way to affect the port was to change the “Socket Number” parameter in the game (Options->Network  screen). When I’ve changed it to 1000 suddenly everything worked (This value is not the port that will be used, but only influence it. Changing it to 1000 will change the port to be 59459 which is good enough).

NOTE: All of your clients must have the same socket number so they will be able to communicate with each other, otherwise they won’t be able to find each other.


Dec 18 2011

Compiling LyX on Mac

When you learn mathematics at the university, and you are a bit of computer’s freak, you will probably want to take lecture notes on the computer.

You are all probably familiar with $latex \LaTeX$ (if not, well… It’s the standard way to write type equations). The best editor for LaTeX is LyX (Well, maybe best is a strong word, The less of all evil is much better).

Recently I’ve bought a new MacBook Air (Mac OS X Lion version 10.7.2. i7 processor), And I’m using it in the university to take some lecture notes. Unfortunately, the LyX release version for mac is a little bit buggy… (for example, when you try to open a file when another file is open it fails most of the time, and if you insist LyX will probably crash. Some characters, such as $latex \Omega$, are not being displayed on editor mode). So I’ve decided to download the source code from their SVN and compile the latest development version.

To make a long story short, I’ve encountered a lot of errors, And I’ve decided to list them here so if you will get them you will be able to solve them much quicker than me.

First error – ICONV_CONST not defined

The first error I’ve encountered was the following:

docstream.cpp: In member function ‘std::codecvt_base::result<unnamed>::iconv_codecvt_facet::do_iconv(void*, const char**, size_t*, char**, size_t*) const’:
docstream.cpp:264: error: expected `>' before ‘ICONV_CONST’
docstream.cpp:264: error: expected `(' before ‘ICONV_CONST’
docstream.cpp:264: error: ‘ICONV_CONST’ was not declared in this scope
docstream.cpp:264: error: expected primary-expression before ‘>’ token

Here the solution is simple. The problem is that the configure doesn’t config the ICONV_CONST properly. The solution to edit the config.h file located in the lyx-devel directory, and add the following line:

#define ICONV_CONST

And now it will work wonderfully.

Second error – Undefined symbols for arh

The second error was much more annoying, and I’ve even destroyed my Mac by mistake while trying to solve it (Had to reinstall it). The solution is a bit more difficult, but no worries.

The error I got, was the following linking error:

Undefined symbols for architecture x86_64:
  "_libiconv_open", referenced from:
      lyx::IconvProcessor::init()     in liblyxsupport.a(unicode.o)
      (anonymous namespace)::iconv_codecvt_facet::iconv_codecvt_facet(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode, unsigned long)in liblyxsupport.a(docstream.o)
  "_libiconv", referenced from:
      lyx::IconvProcessor::convert(char const*, unsigned long, char*, unsigned long)in liblyxsupport.a(unicode.o)
      (anonymous namespace)::iconv_codecvt_facet::do_out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&) constin liblyxsupport.a(docstream.o)
      (anonymous namespace)::iconv_codecvt_facet::do_in(__mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&) constin liblyxsupport.a(docstream.o)
  "_libiconv_close", referenced from:
      lyx::IconvProcessor::convert(char const*, unsigned long, char*, unsigned long)in liblyxsupport.a(unicode.o)
      lyx::IconvProcessor::Impl::~Impl()in liblyxsupport.a(unicode.o)
      (anonymous namespace)::iconv_codecvt_facet::~iconv_codecvt_facet()in liblyxsupport.a(docstream.o)
      (anonymous namespace)::iconv_codecvt_facet::~iconv_codecvt_facet()in liblyxsupport.a(docstream.o)
ld: symbol(s) not found for architecture x86_64

There seems to be a problem with the built-in libiconv library that comes with the OS. The solution was to get the latest source code from GNU, and installing it.

The way to install it is as follows:

Download the archive file, open a terminal in the folder with the archive and type the following commands:

tar -xzvf libiconv-1.14.tar.gz
cd libiconv-1.14

./configure '--prefix=/usr/local' 'CC=gcc -arch i386 -arch x86_64' 'CXX=g++ -arch i386 -arch x86_64' 'CPP=gcc -E' 'CXXCPP=g++ -E'

make
sudo make install

Note: It is very important NOT to install the lib to “/usr/lib“. but to “/usr/local/lib” (That’s they way I’ve messed up my all OS, and it wouldn’t boot afterwards).

After installing the libiconv, you will need to configure and install LyX  using the following commands (assuming you are in the lyx-devel directory):

LDFLAGS="-L/usr/local/lib" ./configure --with-version-suffix=-2.0 --with-libiconv-prefix=/usr/local --with-x=no --disable-stdlib-debug

make
make install

Note: You will probably encounter again the first error I had, because running the configure recreate the config.h file. Just reedit the config.h file as mentioned in the last section.

And that’s it!

It seems like in the current development version the opening bug is fixed, but the missing symbols are still missing. Hopefully it will be fixed soon (I’m looking into it).