Raspberry Pi port of OpenTTD

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Raspberry Pi port of OpenTTD

Post by Davespice »

Hello everyone;

This is my first post on the forum. I've always been an avid player of Open TTD.
I think this game may have made me drop a grade when I was at University :)

Anyway, I am sure some of you are aware of a new, cheap, Linux ARM computer called the Raspberry Pi.
If you've not heard about this before - the intention is to use these in education, rather like the old BBC Micro was, to create a whole new generation of programmers. In the UK they're probably going to be in every bedroom of every school kid. They only cost £25.

Image

They are rare as rocking horse droppings right now, but I have managed to get one.
Yesterday I did a build of OpenTDD directly on the device and it came out pretty well.

You'll see it has made the front page of the Raspberry Pi website and I've also done a post on my own blog about it.
Video here; http://www.youtube.com/watch?v=o18u4jeeUPY

The Raspberry Pi has quite a powerful GPU that can accelerate OpenGL ES and Open VG. So to take advantage of this some work would need to be done in order to make the game draw its graphics using these libraries. I haven’t done any of that, I just followed these build instructions (for Debian) and did a straight svn checkout and build.

The build process took about an hour to complete, but it does run quite well under an X desktop.
Especially so if I turn off Full Animation and Full Detail. Currently there are no accelerated X drivers, but those should come in due course.

I have one problem though!
When you want to destroy some track that you have put down by mistake it costs several hundred million bucks, I'm sure this shouldn't be so high - in fact, you receive income for it shouldn't you?

I'm not sure if this a bug in the code and I should update the svn working copy to an earlier, more stable version - or if it's some kind of arithmetic compiler issue to do with how floats or longs are handled by the ARM compiler. Any advice here would be greatly appreciated.

I think it may have been because I built the trunk and not svn.openttd.org/branches/1.2/ ...

Thanks in advance
Dave
Image
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4766
Joined: 09 Sep 2007 05:03
Location: home

Re: Raspberry Pi port of OpenTTD

Post by Alberth »

Track refunds have not been touched in a LONG time. In addition, given that everybody uses this function, we'd virtually instantly know about the problem.
Therefore, it looks like a problem in the ARM board or compiler.

OpenTTD does not use floating point, so no need to look into that, but I'd start by verifying whether the int sizes are really what they claim to be, and the reported big/little endian-ness of the machine.

Last but not least, if you have a 'normal' machine too, you can create the same situation at both machines using a debugger or so, and compare bit representations of numbers, perhaps that gives clues to what is wrong.
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

Hi Alberth!
Thanks for the suggestions, what I will do first is try a build from the 1.2 branch and if that has the same issue I will investigate further.
Image
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Raspberry Pi port of OpenTTD

Post by planetmaker »

No need to build the release branch. For these testing purposes better stick with trunk. If something needs fixing you'd have immediately the right branch and could easily create a patch (we usually only accept patches for trunk).
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

I think I've found where the issue is going to be in the code anyway;

in src/rail_cmd.cpp; CommandCost CmdRemoveSingleRail
or in src/rail.h; static inline Money RailClearCost (which CmdRemoveSingleRail calls into)
Image
Yexo
Tycoon
Tycoon
Posts: 3663
Joined: 20 Dec 2007 12:49

Re: Raspberry Pi port of OpenTTD

Post by Yexo »

I'd like to mention that the full name of the game is OpenTTD, not "Open Transport Tycoon".
Rubidium
OpenTTD Developer
OpenTTD Developer
Posts: 3815
Joined: 09 Feb 2006 19:15

Re: Raspberry Pi port of OpenTTD

Post by Rubidium »

The issue you got with the tracks might be a miscompilation of the compiler. Could you tell which version of the compiler you are using exactly? The problem might be 'worked around' by --enable-debug=3.
TrueBrain
OpenTTD Developer
OpenTTD Developer
Posts: 1370
Joined: 31 May 2004 09:21

Re: Raspberry Pi port of OpenTTD

Post by TrueBrain »

A word of warning: --enable-debug=3 makes your binary (a lot) slower, so I would suggest you don't publish that binary.

What you can also do, is download the binary as made by Debian: http://packages.debian.org/sid/openttd (also, Wheezy should work fine ).

It is reported to work on ARM just fine. This reinforces our believe it is a compiler issue, but one of our community members is running a few compiles to verify that (which sadly is a more-hour process). At least he can reproduce the issue, which makes debugging it slightly easier.

If you can supply us with both your GCC version and the information if the Debian binary works, that would greatly help us.
The only thing necessary for the triumph of evil is for good men to do nothing.
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

Hi guys;
I haven't tried the Debian package yet, probably won't have a chance to now until Tuesday next week (15th).
It's bank holiday weekend here in the UK.

GCC is (Debian 4.4.5-8) 4.4.5

I can tell you the exact line of code where the problem is though;
src/rail.h - line 351, method RailClearCost

Code: Select all

/**
 * Returns the 'cost' of clearing the specified railtype.
 * @param railtype The railtype being removed.
 * @return The cost.
 */
static inline Money RailClearCost(RailType railtype)
{
	/* Clearing rail in fact earns money, but if the build cost is set
	 * very low then a loophole exists where money can be made.
	 * In this case we limit the removal earnings to 3/4s of the build
	 * cost.
	 */
	assert(railtype < RAILTYPE_END);
	return max(_price[PR_CLEAR_RAIL], -RailBuildCost(railtype) * 3 / 4);
}
Just as a quick test/hack I changed the return line to this;

Code: Select all

return RailBuildCost(railtype);
That then cured the problem, although I understand this is no longer the correct behaviour for the game - this way building rail costs £90 and it costs about £75 to clear it - where it should give you income to some extent. I think the issue may be to do with the second parameter being passed into max. Perhaps some parentheses are required there or the problem is to do with how the result is being turned into a negative value.

Anyway, I hope this helps. I will test out the Debian package as requested and report back next week.
Image
TrueBrain
OpenTTD Developer
OpenTTD Developer
Posts: 1370
Joined: 31 May 2004 09:21

Re: Raspberry Pi port of OpenTTD

Post by TrueBrain »

That once again smells like a compiler issue ;) (given that line of code works fine on all our other supported platforms, which is not a small list). This raises the question: aren't there any other places in the code that are affected, or is this really the only line of code that is optimized wrongly? (unlikely, at best) It appears it is a problem with 64bit integers, which spawn over 2 registers on an ARM (as it is a 32bit CPU after all), where not all registers are marked as DO NOT USE correctly.

We do know of some GCC bugs in the ARM version of 4.4 series, which might (or might not) cause this problem; the jury is still out. The Debian package is compiled with 4.6, which is reported to work by some users. So how I see it there are 2 real solutions:

- use the Debian package (I hope you can confirm this next week).
- update your OS to Wheezy or Sid, which has 4.6 (Squeeze is getting old :P). I hope someone soon wants to try this out.

Other solutions would include finding out why this piece of code exactly fails in optimization, and 'fix' it. While doing, other code that are wrongly optimized should be patched up at the same time. Sounds as horrible as it is :D

Some random stuff you can try too, is removing the 'inline' part from that function, which might or might not help.


So, to summarize this up, as we don't have an ARM to test on, can you please test the following things (when ever you have the time again, and given nobody else fixed it in the meantime ;) ):

- Compile with --enable-debug=3 (disables inline and optimizations), and check if it works.
- Try the Debian package, and check if it works.
- Fiddle around with the function. Remove 'inline', replace the max() for an if-statement, stuff like that.
- If possible, update to Wheezy or Sid, and see if that resolves the issue if you compile manually.


Tnx for testing!
The only thing necessary for the triumph of evil is for good men to do nothing.
User avatar
ffpp
Engineer
Engineer
Posts: 125
Joined: 29 Jan 2010 12:56

Re: Raspberry Pi port of OpenTTD

Post by ffpp »

Very cool idea!

I almost got to work with an Rasberry Pi for my Master but am now working on a DreamPlug instead.
Not OpenTTD related, though ;)

Good luck with your project
User avatar
FooBar
Tycoon
Tycoon
Posts: 6553
Joined: 21 May 2007 11:47
Location: The Netherlands
Contact:

Re: Raspberry Pi port of OpenTTD

Post by FooBar »

Random idea:
Maybe the compiler somehow doesn't understand the minus in -RailBuildCost(railtype), you could try this instead:

return max(_price[PR_CLEAR_RAIL], RailBuildCost(railtype) * -3 / 4);
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Raspberry Pi port of OpenTTD

Post by Eddi »

that is really unlikely, as this kind of stuff is handled in the language frontend, which is shared across all architectures. and thus a more widespread target audience would be affected by such a fundamental mistake.
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

FooBar wrote:Random idea:
Maybe the compiler somehow doesn't understand the minus in -RailBuildCost(railtype), you could try this instead:

return max(_price[PR_CLEAR_RAIL], RailBuildCost(railtype) * -3 / 4);
I had enough time to do a quick rebuild this evening. So I made the suggested change above and presto - it did the trick!
I now get income from destroying track. Well done FooBar!

I also had a quick go at trying to install the official Debian openttd package - but there are a load of dependency issues.
The Raspberry Pi version of Debian is a kind of branch of the official one, you download it as an SD card image, burn it onto your SD card and boot the Pi up from it.

I'm not a Linux expert but I would be prepared to offer SSH/VNC access to my Pi to someone who fancies giving it a try.
PM me about this if anyone wants to do this.
Image
User avatar
FooBar
Tycoon
Tycoon
Posts: 6553
Joined: 21 May 2007 11:47
Location: The Netherlands
Contact:

Re: Raspberry Pi port of OpenTTD

Post by FooBar »

You're welcome :)

And that without having a clue about how compilers work. I just figured "if RailBuildCost(railtype) works, and assuming that basic math like max() and * and / work, then -RailBuildCost(railtype) must be the culprit. Solution: avoid -RailBuildCost(railtype) :P
Rubidium
OpenTTD Developer
OpenTTD Developer
Posts: 3815
Joined: 09 Feb 2006 19:15

Re: Raspberry Pi port of OpenTTD

Post by Rubidium »

That still leaves all other places that could be broken where such code is used, e.g. in graphs and AI code.

Nevertheless, working around this issue is a bad thing. It is near impossible to find all places where this could go wrong, unless you got some static analyser tool laying around. So you'll maybe fix a few cases, but it's still not fixed. You need to fix the compiler.
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

Rubidium wrote:That still leaves all other places that could be broken where such code is used, e.g. in graphs and AI code.

Nevertheless, working around this issue is a bad thing. It is near impossible to find all places where this could go wrong, unless you got some static analyser tool laying around. So you'll maybe fix a few cases, but it's still not fixed. You need to fix the compiler.
I only wanted to work around this issue as it was a serious gameplay problem.
I have spent a bit of time just playing the game and to me everything else appears to be in order. That said, I take your point completely.

Next week I'll try it with the --enable-debug=3 switch and see if that fixes it, but I might need some help using the binary that has been made by Debian.
Image
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

Hi guys;
Okay I have just done a build using ./configure --enable-debug=3 and this was the result.
It went through compiling everything and then when at the linking stage we get the following error;

Code: Select all

[SRC] Linking openttd
collect2: ld terminated with signal 9 [Killed]
make[1]: *** [openttd] Error 1
make[1]: leaving directory '/home/pi/openttd/objs/debug'
make: *** [all] Error 1
Any ideas folks? I've had a look around in the internet and most people say this issue is caused by lack of memory. The Pi has only got 256 MB of RAM so this could well be the cause. I expect the next step would be to cross compile from a x86 PC with a decent level of RAM. If anyone has any further suggestions they are welcome. Cheers!
Image
User avatar
Davespice
Engineer
Engineer
Posts: 8
Joined: 02 May 2012 09:29
Location: London UK

Re: Raspberry Pi port of OpenTTD

Post by Davespice »

Additional!
Hi again all, I have managed to get it to compile using --enable-debug=3. I just needed to allocate a bit of swap memory and that got it through the linking stage. Surprisingly, to me, this has produced a 62 MB executable file!

Does it fix the track refund issue? Yes it does (I made sure I reverted to the original code before I did the build). So I guess this way we can be confident that compilation has been done correctly. Although I am not sure it is such a good idea to have such a huge file?! Is there a way I can compile it disabling in-line optimisations but in release mode to give a more sensible sized executable?

Thanks, I am new to Linux development so any help is really appreciated.
Cheers!

EDIT: I think I have figured it out.
I found the gcc switch to turn off inline optimisations and ran configure like so (below), before running make.

Code: Select all

CFLAGS="-fno-inline" CXXFLAGS="-fno-inline" ./configure
This gave me a 9 MB executable (normally 6 MB), which is a bit better and the track refund issue is also okay. I'll do a bit of play testing and see how things go from here.
Image
TrueBrain
OpenTTD Developer
OpenTTD Developer
Posts: 1370
Joined: 31 May 2004 09:21

Re: Raspberry Pi port of OpenTTD

Post by TrueBrain »

Like said, don't distribute binaries made with --enable-debug=3 ;) They are supposed to be HUGE :D

Anyway, it is very clear to us that the compiler is at fault. GCC 4.6 seems to fix the issue, so upgrade to that would be best. I wouldn't release any binary with no-inline, as they are terrible slow :D


From what we can tell, it happens to functions which use certain math functions on 64bit integers and are to be inlined. It seems GCC remembers 'wrong' which registers are in use, and makes a boo-hoo because of it.
The only thing necessary for the triumph of evil is for good men to do nothing.
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: Ahrefs [Bot] and 5 guests