Menu

Porting BASeBlock To Linux, and thoughts on Mono

November 22, 2010 - .NET, C#, Games, Programming, Windows

No, Not the kissing disease, Infectious mononucleosis, the open-source .NET CLR interpreter and class library.

.NET; I might have ranted about this before, if not on my blog, elsewhere. most of my arguments were against it, being a VB6 using ignorant buffoon. In any case, I’ve found C# to be an awesome language. One of the obvious downsides is that for the most part programs written in C# using Windows forms cannot be run on other systems.

The concept of Mono is to change that; remember, C# isn’t a Microsoft standard, it’s an ECMA specification, and Microsoft holds no copyright over it or anything like that. Mono is a relatively huge undertaking; the creation of something on the scale of a Virtual machine as well as a class library is gargantuan, and of course there is very little hope for 100% success.

On the whole, Mono performs it’s primary goals admirably; there is a GTK# framework that can be used to develop windowed applications… of course then the installation on a windows PC would require the install of the Mono GTK# framework, but I digress. In any case, applications can be developed and the C# code interpreter (for on the fly syntax highlighting) as well as the compiler are top-notch and seem to work well.

My only beefs can of course be in the class library. Of course, re-implementing the class library provided by MS on non-windows systems is not something that can be done in a single afternoon; this stuff takes time. My attempts to create a Mono-compatible project have been stifled, however, by seemingly innocuous issues. AlLlow me to explain.

As many reader may be aware, I have been working on a “upgrade” of sorts to my now ancient “Poing” game, which can be found on my downloads page; the original game was written in Visual Basic 6, and, in it’s earlier incantations didn’t have a single Class; it was all based on User-Defined Types (structures for those privvy to C parlance) and functions; (short explanation: it was made before I understood classes). Later, after I had learned about classes, I refactored everything into classes. This is all rather redundant; in any case, I have since created a new project in C#, in an attempt to learn about GDI+ as well as what appeared to be a different (in some ways) painting model. As one can see by the youtube videos I have posted on it, development has gone well.

The idea occured to me, after Tux2 (of http://www.jrtechsupport.com/) managed to create a Mono-workable, if soundless, version of my earlier C# game, BCDodger that worked in Linux. Sound was unavailable as a result of my choice of sound library, the IRRKLANG library, while truly usable in Linux, doesn’t have a wrapper that works in Linux (or something, I don’t know… it uses DSound or something, I forget). In any case, I have since added the ability for various sound engines to be used, and have added working implementations for Open-Source and Linux-available Sound systems, such as NBass (as well as a broken fmod implementation, let’s ignore that though).

Much obliged, I had decided to try to get it working via Mono as well; this was facilitated by my recent reformatting of my laptop to run a dual boot Windows 7 and Mint 10 system. Installing MonoDevelop and all that, etc.

So, I of course open the project in Monodevelop, quite ready for errors relating to porting.

The version I am using is MonoDevelop (and I assume also Mono) version 2.4, for those following along.

My first hurdle was getting my Appdata files for the program in the right location; on windows systems they are placed in the application data folder; so too they would need to be on a Linux system. Thankfully, a quick C# program run on the Linux machine cured this issue:

Which gave me, on a Windows system:

Nothing particularly out of the ordinary there. So, running the program on a Linux machine:

which gave me what I needed: the appdata folder “BASeBlocks” needed to be copied to /home/bc_programming/.config.

Doing so was easy enough; the file manager on Mint 10 (dolphin) is different from windows explorer but hardly paradigm-breaking.

That copied, I simply threw the source folder as it was on the Visual Studio 2008 projects folder into the MonoDevelop projects folder (well, not really, it was /home/bc_programming/projects/ which I suppose means that any program that uses a projects folder will use it, oh well.)

psyched as I was I ripped into it with MonoDevelop, ready for anything! well, nearly anything.

My first error occured on line 107 of “Block.cs”:

Java programmers may be thinking “ew uppercase characters” to them I say be quiet you. Anyways, the problem here was that there was no “Sum()” Extension method defined. Which I found odd. Oh well, though, I simply created my own:

this solved the immediate issue of the “Sum()” extension method. (For more info on C# extension methods, see here)

My next hurdle was on line 540 of cBall.cs:

The error was something to the effect of not being able to pass a delegate or method group to a lambda expression.

oddly enough, the fix was the change the “q” to an x… and after it successfully built I was able to comment out the “new” line (with the x rather then a q) and uncomment the original. very odd.

In either case, now I was confronted with what I knew to be the biggest issue; the fact that I had to now discover how to set it up so that I was able to use the same nBASS library, but so that the nBASS library was “silently” made to use the BASS.so linux library, rather then bass.dll which wouldn’t load either way.

The first step in this process was in finding bass.so. Hoping for the best, I pulled up good ol’ synaptic package manager.

No luck there 🙁 so, I went into the depths of the internet….

the BASS for Linux (note the lack of the n prefix; it’s the core BASS library that the nBASS dll is wrapping) can be found here

this topic; or, the original post, to be precise, gives the download location for the Linux source files for BASS 2.4, which can be found at http://www.un4seen.com/stuff/bass24-linux.zip

So, I downloaded the zip file, extracted it to a folder, and am about to attempt to compile it. (there is a libbass.so that I could probably try, but I think I’ll compile it myself instead).

Before I continue, however, I would like to mention something that has most impressed me about Mint 10; the multiple desktops. Now, this is hardly a new feature; programs can be downloaded that do this on windows, and windows itself has built in API support for multiple desktops; however, what impresses me most is that when you activate a window on another screen, it switches to it; what I mean is, for example, in this instance my FF download window was on another desktop (no idea why) and when I went to open the downloads window via Tools->Downloads, it did the fancy compiz box animation (as I have selected in preferences) and switched to it. very cool. But enough if my gushing over the unexpected presense of sanity in the UI design of a Linux desktop environment! back to my attempts to get BaseBlock working on Linux.

my attempts to make the bass project, however, failed:

Oh the humanity! now I had to learn about this package nonsense. I first suspected perhaps, as evidence by the fact that it wasn’t found, said package wasn’t installed; so I did a quick sudo apt-get install libglade-2.0 … it reported it was installed already.

after a bit of effort, and installing a few dev packages, I gave up. I was able to resolve the missing dependencies but then it complained about a missing .h file (which was indeed missing and clearly should have been present) so I gave up on that, and am at the time currently trying to simply use the .so file included. An additionally problem that arises here is the obvious fact that I am using a x64 Linux system, working with C# code written on a x64 windows system but targeted towards a x86 system, problem being that to my understanding Linux is not as lenient when it comes to architecture differences; but I suppose I’ll figure that out for myself if it’s the case.

In any case, I am now attempting to get the nBASS library to wrapp around libbass.so rather then bass.dll; from my research if the imports are the same I should have no problem creating a dllmap entry in the appropriate config file. From the documentation it would seem that discovering where that config file goes is left as an exercise for the reader.

Actions:

pasted libbass.so in the “Debug” folder (alongside the dll).

Copied the BASeBlock.config file from the project root to the debug folder; renamed to Bass.Net.config.

opened preceding file in gedit; it now looks like this:

And now, I attempt to run BASeBlock… recall that it now compiles on Linux, so it’s just a matter of making it work. I could, in a worst case scenario, construct a “nullsound” driver that simply stubs out the sound playing interfaces. But that seems like a bit of a cop-out. IN any case, attempts to run it resulted in the same error; clearly either the documentation I was reading was incorrect or I was not interpreting it properly.

I did a few more googles and came upon this page, which, despite being about something completely different addressed the same problem; that is, translating the dllimport(whatever.dll) into imports of functions from Linux .so libraries. namely, it told me where the Mono parameter file was- /etc/mono/config. I quickly opened the feller using gedit:

I tossed in the line:

and crossed my fingers…

It still didn’t work. I guessed maybe mono only loaded that stuff up when it was started? So I restarted monodevelop.

excellent! a little progress. Now I was still getting the error, but it was complaining about libbass.so missing. At least we’re getting somewhere.

It still should have found the file; however, I decided that instead of just throwing it in the app directory (because god knows where Mono is truly looking for it; even putting ./libbass.so in the dllmap failed, so Mono clearly thinks something else is the “current” directory. Instead, I decided to simply cp it somewhere globally accessible;

It still didn’t work.

Anyway, I messed around with the config file and the dllmap attribute and no matter what I put it it refused to find the file; clearly I’m missing something obvious (maybe capitalization? a missing slash? who knows). In either case I decided to defer that work to later on; I’m sure there was more to be fixed afterwards.

So, I created the aforementioned “Null Sound” driver; it worked fine. compiled alright. Encountered a bunch of issues during startup relating to my use of the \ as a path separator, whereas Linux uses /, fixed this with a simple Replace to change all slashes to the slashes of the OS (Environment.PathSeparatorChar).

It still refuses to start; Some gdi plus error. I have no idea how to workaround this, since it seems to be related to the windows forms, and has nothing to do with my own code, but rather with some configuration option. I recall Tux2 working around a similar error in BCDodger but I wasn’t paying very close attention and forget what the fix was, or even if he mentioned it. Either way, at least now BASeBlock compiles on a linux system, and most of the code-related oversights have been resolved.

EDIT:

I’ve managed to solve both issues; not at once of course.

First, the loading issue was fixed; pretty troublesome. In my attempts to resolve the problem I created a number of projects that used the same Image.FromFile() method to load pictures, and they worked fine.

Clearly, the problem then was not in what was not visible; the difference between the two. I realized that the difference was pretty clear: in my test projects, I was loading the images from within the form’s Load event; in BASeBlock, they were being loaded in a static constructor. So I decided to try to load the images elsewhere; I converted the static constructor to a static function, and called that function in the form load; there were a few other changes that I needed to make, mostly in the form of initializers attempting to use values that wouldn’t have been initialized.

The game started and ran fine with the NullSound driver.

Now, to fix the Sound; I opted to try to get nBASS working.

the solution was actually quite simple; merely a dllmap for bass.dll to libbass.so, and placing the x64 libbass.so in usr/lib was enough, and sound worked fine.

Unfortunately, it’s still slow as hell but at least I think that’s Mono’s fault.

Have something to say about this post? Comment!

Tags: , , ,