Portability?
Moderator: Moderators
Portability?
Hi,
First of all, congratulations on this project, it looks great!
Now, I say that it *looks* great, because I can't actually play it :D
I'm running solely on linux systems, and therefore, TAspring is currently not an option for me. However, I am a developper and I'd like to attempt porting TAsprings to linux. After that... Well, TAspring is very similar in functionality (or planned functionality) to a project I was thinking about, so I might want to join in on the happy hacking :)
Is there anyone who has stepped forward for porting yet? Would it be okay with you to start on that work now?
Having a quick look through the source code, it shouldn't be too difficult to get ported.
- Replace OpenGL with SDL/OpenGL, and let SDL handle the specifics of getting a window set up and opengl initialized
- Replace DirectSound with OpenAL. It actually has a DirectSound3d backend driver, so nothing'll be lost on windows, and it'll make the sound code portable to ~10 platforms, including windows, linux, xbox, gamecube and PS2 :)
- Add support for BSD sockets alongside Winsock (this actually is extremely simple: leave a few function calls needed for winsock out), or a network abstraction lib if portability beyond windows and posix systems is desirable by other people
One thing that'll be a problem is the crashrpt library, which is specific to windows and MSVS. I haven't looked into it in detail, but the options are to either leave it out completely on non-windows platforms (fwiw, on linux a core dump'll get generated, so all debug info is not lost), reimplement the library for linux, or switch to a portable crash reporting lib, if such a thing exists.
That's my first take on the question, after skimming over the code. Is there anything else that could hurt portability that you can see being a big problem?
If you're interested in making this port happen, I can start looking into it more precisely and working on a patch.
Peace,
Dave.
First of all, congratulations on this project, it looks great!
Now, I say that it *looks* great, because I can't actually play it :D
I'm running solely on linux systems, and therefore, TAspring is currently not an option for me. However, I am a developper and I'd like to attempt porting TAsprings to linux. After that... Well, TAspring is very similar in functionality (or planned functionality) to a project I was thinking about, so I might want to join in on the happy hacking :)
Is there anyone who has stepped forward for porting yet? Would it be okay with you to start on that work now?
Having a quick look through the source code, it shouldn't be too difficult to get ported.
- Replace OpenGL with SDL/OpenGL, and let SDL handle the specifics of getting a window set up and opengl initialized
- Replace DirectSound with OpenAL. It actually has a DirectSound3d backend driver, so nothing'll be lost on windows, and it'll make the sound code portable to ~10 platforms, including windows, linux, xbox, gamecube and PS2 :)
- Add support for BSD sockets alongside Winsock (this actually is extremely simple: leave a few function calls needed for winsock out), or a network abstraction lib if portability beyond windows and posix systems is desirable by other people
One thing that'll be a problem is the crashrpt library, which is specific to windows and MSVS. I haven't looked into it in detail, but the options are to either leave it out completely on non-windows platforms (fwiw, on linux a core dump'll get generated, so all debug info is not lost), reimplement the library for linux, or switch to a portable crash reporting lib, if such a thing exists.
That's my first take on the question, after skimming over the code. Is there anything else that could hurt portability that you can see being a big problem?
If you're interested in making this port happen, I can start looking into it more precisely and working on a patch.
Peace,
Dave.
- [K.B.] Napalm Cobra
- Posts: 1222
- Joined: 16 Aug 2004, 06:15
Hm there is a bit of windows specific memory handling if you define SYNCIFY but since thats only a debugging help you dont usually need it.
There is some pbuffer code for the shadows which might cause problems.
Not sure about the hpiutil library.
Other than that not much that I can think of at the moment. Try to compile it and see :)
There is some pbuffer code for the shadows which might cause problems.
Not sure about the hpiutil library.
Other than that not much that I can think of at the moment. Try to compile it and see :)
I was waiting exactly for what SJ gave: input on the question and extra info I missed :)What are you waiting for?
- Concerning the memory handling, I can have a look for dropping in linux equivalents to the extra checks you do. Otherwise, I'll just not provide the option of declaring that constant in the linux compile scripts.
- Google tells me that pbuffers are integrated in nvidia's (and probably ati's also) hardware accelerated drivers, and the all-software opengl libraries also have them (feel the rich chunky MHz being drained from the machine...), though I've never messed with them myself. I'll see how things go with them.
- HPIutil will be a minor problem. Minor because we have the source code, so a platform-independant rewrite should be fairly painless.
However, this last point raises a possibly problematic issue: the current hpiutil library relies on type sizes being the same on all systems it runs on (ie. it dumps/loads structures to/from file directly). While this is not a problem for a windows-only system, it might be a source of headaches for a portable app. Is there a plan to replace HPI with another format?
If not, if the linux hpi implementation immediately proves problematic, I can try to put something together. If everything works at first, I'll leave it as it is, but the data format is something to consider for portability beyond the code in the long term.
That said, I'll get hacking.
I had a go at getting it to compile in mingw, which is the obvious first step towards portability (gcc is great like that).
Compiling the cpp files in the rts directory:
Lots of errors, far more warnings.
By the time I got bored, I ended up with 158 sucessfully compiled objects, with about 50 cpp files that didn't want to compile for one reason or annother. And this is after tweeking the more common header files to remove/include certain ISO C requirements.
I recommend that one of the developers who actually knows the source well enough to fix the awkward errors to download mingw, write a makefile, and just compile away. dev-cpp is a graphical front-end, which you will likly find easier.
I think the most common error was along these lines:
Builder.cpp:207: no matching function for call to `max(int, float)'
And the most annoying and pointless warnings were:
*.h:1:9: warning: #pragma once is obsolete
*.*:38:51: warning: no newline at end of file
so #ifndef protect your headers instead of #pragma once, and make sure there's a blank line at the end of all the files, and you'll be able to see the actual problems. :)
Once mingw stuff is compiling, it'll be far easier for any linux users to port it to thier favorite operating system. You'll probably have to do the byte-swapping yourself for big-endian archetectures.
With regards to linux memory management. Just use malloc/free instead of any complex memory usage. Linux will handle stuff to only commit as much memory as your program is using instead of committing all that your application reserves.
With regards to pbuffers, yes, linux supports them, using glx instead of wgl of course. pbuffers are still one of worst parts of opengl.
HPIUtil won't be any worse than the rest of your code. The complex parts of hpi files is zlib. The rest (reading at least) can be written in a 10k cpp file. Source porting will only be an issue on 9 or 7 bit byte systems, and those systems are silly and rare enough that they can be ignored (hence why most systems are
. For those systems, you're likly to have more issues finding a real c++ compiler than you are adapting the code to cope with wierd byte sizes.
So long as you don't use alignment pragmas and just use memcpy where appropriate, you'll have no problems with aligned access.
You also have some AVI code in there, which will need to be disableable for ports.
But without resyncing code, linux ports will be network-incompatable due to the floats. Perhaps use problem-less fixed-point ints instead? Just create a new class called fixed. :D
Compiling the cpp files in the rts directory:
Lots of errors, far more warnings.
By the time I got bored, I ended up with 158 sucessfully compiled objects, with about 50 cpp files that didn't want to compile for one reason or annother. And this is after tweeking the more common header files to remove/include certain ISO C requirements.
I recommend that one of the developers who actually knows the source well enough to fix the awkward errors to download mingw, write a makefile, and just compile away. dev-cpp is a graphical front-end, which you will likly find easier.
I think the most common error was along these lines:
Builder.cpp:207: no matching function for call to `max(int, float)'
And the most annoying and pointless warnings were:
*.h:1:9: warning: #pragma once is obsolete
*.*:38:51: warning: no newline at end of file
so #ifndef protect your headers instead of #pragma once, and make sure there's a blank line at the end of all the files, and you'll be able to see the actual problems. :)
Once mingw stuff is compiling, it'll be far easier for any linux users to port it to thier favorite operating system. You'll probably have to do the byte-swapping yourself for big-endian archetectures.
With regards to linux memory management. Just use malloc/free instead of any complex memory usage. Linux will handle stuff to only commit as much memory as your program is using instead of committing all that your application reserves.
With regards to pbuffers, yes, linux supports them, using glx instead of wgl of course. pbuffers are still one of worst parts of opengl.
HPIUtil won't be any worse than the rest of your code. The complex parts of hpi files is zlib. The rest (reading at least) can be written in a 10k cpp file. Source porting will only be an issue on 9 or 7 bit byte systems, and those systems are silly and rare enough that they can be ignored (hence why most systems are

So long as you don't use alignment pragmas and just use memcpy where appropriate, you'll have no problems with aligned access.
You also have some AVI code in there, which will need to be disableable for ports.
But without resyncing code, linux ports will be network-incompatable due to the floats. Perhaps use problem-less fixed-point ints instead? Just create a new class called fixed. :D
Why not I guess, but the errors you describe can be fairly quickly fixed by a brutal batched regexp replace/insert. Plus if I want to mess around implementing features after the port, I'll have to know my way around somewhat...Spike wrote:I recommend that one of the developers who actually knows the source well enough to fix the awkward errors to download mingw, write a makefile, and just compile away.
I know, optimistic memory allocation and stuff. I reckon the debug info SJ is talking about is more along the lines of export _MALLOC_DEBUG=1 or linking to electric-fence/valgrinding the binary to root out memory leaks.With regards to linux memory management. Just use malloc/free instead of any complex memory usage. Linux will handle stuff to only commit as much memory as your program is using instead of committing all that your application reserves.
Are you sure about that? I seem to remember that gcc takes liberties with alignment/packing in the higher optimization modes, which could badly mess up the raw access scheme.So long as you don't use alignment pragmas and just use memcpy where appropriate, you'll have no problems with aligned access.
Also, as a totally separate argument, I consider this kind of bashing obscure binary data in and out of a program without proper precautions fairly awful. But hey, that's not my decision to make, and as long as HPI remains "good enough", there are more important things to code.
What do you mean by AVI code? If the only need for AVI is for cinematics, there is an SDL extension library that handles playing AVI files onto SDL surfaces in a portable fashion. If the requirements are more involved it may take some convincing in SDL, but I'm fairly positive it's feasible.You also have some AVI code in there, which will need to be disableable for ports.
Now that really is a problem. Pity if linux users had to play separate from windows users :)But without resyncing code, linux ports will be network-incompatable due to the floats. Perhaps use problem-less fixed-point ints instead? Just create a new class called fixed. :D
The immediate solution would be to convert all floating point transmission to int, or altering float comparison functions to account for the precision loss.
Another option that might be worth considering is to integrate an RPC handling library that'd do all the inter-platform marshalling and data massaging automagically. Such a library I encountered recently is ICE, which seems extremely powerful, fast and flexible. Not only would it ease the data marshalling, it can also transmit full objects over the network, relay exceptions, and provides a cross-language RPC system (a PHP client can query the status of a C++ server as transparently as if it were all local PHP code). It also offers tools for hubbing and routing of procedure calls and firewall capabilities for "annoying" client filtering.
Basically, it defines itself as "CORBA, sped up several orders of magnitude, without the annoying/obscure/useless bits".
Then again, integrating such a beast, whilst giving incredible power and flexibility on the network side, might seem like swatting a fly with a thermonuclear plasma propelled grenade. But if only for the headache avoidance of having to handle data marshalling from one platform/architecture to another and the low level network transmission code would be nice as far as I'm concerned.
All the above is just an idea to consider of course, I wouldn't embark on stuff like that before getting a zero-warning/error compile out of gcc on linux, nor without approval and design.
*clenches teeth and sets compile flags to -g -Wall -Werror*
With "dumb" porting (replacing windows specific stuff with code that'll run on several platforms), medium to good chance I'd say. The problems that could remain after that phase are related to how each system stores things like numbers (35.3324689), and having to find a way to send this sort of data over the network without losing information (which'd make the game go out of sync).
But overall, when (more like "if") the port is fully completed, linux and windows users will be able to play each other without even noticing that anything is different.
But overall, when (more like "if") the port is fully completed, linux and windows users will be able to play each other without even noticing that anything is different.
I dont think the actuall storage of variables will cause that much unsync problems since that is rather well defined. The thing I worry about is how different compilers will optimize the calculations which will probably cause rounding off errors in floats.
Im not sure how well a fixed point representation could work. Spring has never been meant to use that so it will use both very big and small float numbers.
Im not sure how well a fixed point representation could work. Spring has never been meant to use that so it will use both very big and small float numbers.
Couldn't you just build some tolerance in with a "close enough" calculation, with periodic updates to prevent little errors from building up over time? That seems like it would be a pretty minor fix, since we should be talking about very small variances.Im not sure how well a fixed point representation could work. Spring has never been meant to use that so it will use both very big and small float numbers.
-
- Posts: 5
- Joined: 08 Oct 2004, 06:18
Diffs?
I was hoping to talk Dave into posting diffs for the work he has done so far. I will have some free time this weekend, and I would be very interested in helping with a linux port.
Right now I've just stepped out of a week of exams, so the diffs are basically non-existent. My first step is getting TAspring to compile successfully with mingw (okay, so I do run windows, in an emulator :D ), to iron out all the problems not related to windows/linux portability. After that... Compile on linux, correct any new strictly syntactic errors, and once everything but the libs is okay, start porting the libs and windows-specific code.
What I'd suggest, if the proposal to get hosted on BerliOS with subversion goes through, is to create a porting branch of the code we could work on. Until then (unless I get a makeshift svn repository running here I guess), synchronising work is going to be a little bothersome.
Until we do get some kind of code/project management going, we could start work on totally separate problems, like (1) getting taspring compiled on mingw and (2) writing a portable version of HPIutil, that is currently riddled with win32 api code. If that sounds okay with you, "pick one" :)
What I'd suggest, if the proposal to get hosted on BerliOS with subversion goes through, is to create a porting branch of the code we could work on. Until then (unless I get a makeshift svn repository running here I guess), synchronising work is going to be a little bothersome.
Until we do get some kind of code/project management going, we could start work on totally separate problems, like (1) getting taspring compiled on mingw and (2) writing a portable version of HPIutil, that is currently riddled with win32 api code. If that sounds okay with you, "pick one" :)
That's too bad. However, there is a solution. gcc is available for all platforms. Just compile with gcc on all platforms, and then (in theory) the float optimizations should be the same for all platforms. Even if it doesn't work first try, you should be able to pass flags upon compile to tell it to lay off float optimizations.Close enough stuff can never work in a low bandwith enviroment, differences just snowball too quickly.
Or, if you don't like gcc, use something else, like whatever eclipse uses internally.
Without starting a holy war, I would say that central cvs repositories are way 90's. In this millenium, stick to things that allow for distributed code repositories, like monotone.By the way, what code management system do you use to sync code? CVS? Subversion? (If the choice is open I'm very partial to svn, and can offer low-bandwidth hosting for a repository + bug tracker and code browser)
I'd tend to agree with you on the SCM side, except that imho all distributed SCMs are too far from providing realistic support right now.
- Arch (tla) is way too complex a UI
- Bazaar-ng is highly beta, not sth I'd entrust code to
- Monotone is interesting, but still a little to young for my taste
- Darcs has the most promising features (the "theory of patches" formalisation is great, and so is the UI), but on the preserving of repository integrity side, it seems to be way down there with cvs.
- Svk is the most promising on the integrity bit (uses libs written for subversion, which is A+ on the integrity side), but is a little young also.
Basically, I'm all for distribution, but not because it's the cool thing right now. It'll be great once we get something that mixes Darcs' formalisation with Svk's integrity management (which svk is working on it seems).
Until one of the above SCMs (or another, who knows) starts showing more maturity, I'll stick with Subversion (it took five years and is heavily designed to avoid the "let's just chuck code together and never mind what happens" syndrome, a serious approach that I like). That said, I'm watching Darcs/Svk/Monotone with growing interest (I've given up on Arch and it's forks for the time being).
Also, on a completely different note, it has been observed that developement with centralised scms follows a very different pattern to that which happens with decentralised scms. I don't think one is fundamentally better than the other, it depends on the project and the people working on it.
For instance, I find that a distributed scm for a heavy project is a bad, because you have difficulty in properly designing the software when everyone is just shooting off stuff between themselves (possibly circumventing the lead devs). And if you then veto inclusion of patches which come out of the blue after months' worth of work, you get forks and end up with a Linux situation (~8 popular patchsets, not counting each distro's patchset).
OTOH, for small (size in code, design or number of people involved), I find a distributed SCM takes away a the constraints of the centralised structure and allow people to work together much more efficiently. But just talking in code size, TAspring is certainly not a small project.
That said, I wouldn't like to be the one continuing a holy war here -- I'm just stating my views on the current state of things and why I said Subversion and not [insert distributed scm here] above. I'm not saying I know best, or any of the stuff that usually starts a flamewar (though I'm interested in the subject if the discussion does go on). :)
- Arch (tla) is way too complex a UI
- Bazaar-ng is highly beta, not sth I'd entrust code to
- Monotone is interesting, but still a little to young for my taste
- Darcs has the most promising features (the "theory of patches" formalisation is great, and so is the UI), but on the preserving of repository integrity side, it seems to be way down there with cvs.
- Svk is the most promising on the integrity bit (uses libs written for subversion, which is A+ on the integrity side), but is a little young also.
Basically, I'm all for distribution, but not because it's the cool thing right now. It'll be great once we get something that mixes Darcs' formalisation with Svk's integrity management (which svk is working on it seems).
Until one of the above SCMs (or another, who knows) starts showing more maturity, I'll stick with Subversion (it took five years and is heavily designed to avoid the "let's just chuck code together and never mind what happens" syndrome, a serious approach that I like). That said, I'm watching Darcs/Svk/Monotone with growing interest (I've given up on Arch and it's forks for the time being).
Also, on a completely different note, it has been observed that developement with centralised scms follows a very different pattern to that which happens with decentralised scms. I don't think one is fundamentally better than the other, it depends on the project and the people working on it.
For instance, I find that a distributed scm for a heavy project is a bad, because you have difficulty in properly designing the software when everyone is just shooting off stuff between themselves (possibly circumventing the lead devs). And if you then veto inclusion of patches which come out of the blue after months' worth of work, you get forks and end up with a Linux situation (~8 popular patchsets, not counting each distro's patchset).
OTOH, for small (size in code, design or number of people involved), I find a distributed SCM takes away a the constraints of the centralised structure and allow people to work together much more efficiently. But just talking in code size, TAspring is certainly not a small project.
That said, I wouldn't like to be the one continuing a holy war here -- I'm just stating my views on the current state of things and why I said Subversion and not [insert distributed scm here] above. I'm not saying I know best, or any of the stuff that usually starts a flamewar (though I'm interested in the subject if the discussion does go on). :)
Until the current discussions about projects management are over, I've created a Subversion repository on my own server in order to have some source control while working on the port.
https://svn.natulte.net/projects/taspring-linux/
I've imported the source code available from the download section, and am going to start with what Spike did: get taspring to compile cleanly on MingW, to get rid of all the gcc vs. VC.Net incompatibilities.
Oh, and *please* don't check out the whole repository right now: there's absolutely nothing to see, all the source is still the exact same as the one in the download section, and checking out from my server will slow my connection to a crawl.
https://svn.natulte.net/projects/taspring-linux/
I've imported the source code available from the download section, and am going to start with what Spike did: get taspring to compile cleanly on MingW, to get rid of all the gcc vs. VC.Net incompatibilities.
Oh, and *please* don't check out the whole repository right now: there's absolutely nothing to see, all the source is still the exact same as the one in the download section, and checking out from my server will slow my connection to a crawl.