Simutrans Wiki Manual
The official on-line manual for Simutrans. Read and contribute.

CEGUI integration project

Started by Markohs, February 04, 2012, 12:12:48 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


 Well, looking it might be possible to change the UI system to shift their design to the PAK designers, and seeing this change will only simplify Simutrans 3D development, I start another project to integrate CEGUI in the current simutrans code.

What's the purpose of this project?
- Base the UI in a library that allows modyfing it's appearance without recompiling Simutrans, since the description it's in external files.
- Make the UI more customizable.
- Free the Simutrans coders from the UI coding so they can spend time on other areas of the project.
- Throw all this responsability to the PAK creators. Simutrans has to have a default UI, that will look the more similar possible to the current one. Pak mantainers will be able to override the default GUI and customize it.
- To have a UI that's well suited for use in a 3D enviroment.

Design decisions so far:

- CEGUI supports various renderers, including DirectX, OpenGL , Ogre3D and Irrlitch. Since OpenGL is the more open and multiplatform one, I'll develop with it. Should be no problem to switch to other renderers.   
-  The idea is just porting the GUI to CEGUI, and render the rest of the scene in a framebuffer fashion, using the current code to write to a plain texture, that will stay after the GUI. This has been tested in simutrans 3D and has given acceptable framerate, very similar to current simutrans code.
- CEGUI doesn't handle inputs by itself. Thsi is a design decision. So the initial plan is to stick to SDL for the keyboard and mouse.

Problems that might arise:

- I might have chosen the wrong GUI framework for this project, even from what I saw, it looks like the more complete and suited one. A list can be found here.
- CEGUI might not work in Haiku, even I've read some comments about at least some package for it being developed.
- I don't see any information about Amiga OS, even through CEGUI has some AmigaOS widgets implemented, I don't know if it can be compiled there.
- Cegui has some dependences:
* FreeType2
*  Perl C Regular Expression
*  Xerces-C++
* ...

All those libraries seem reasonable to me, MIT and BSD are compatible with simutrans license as far as I know. Freetype handles non latin texts good I guess, even I'm not an expert, but I guess it supports unicode.

I'm open to all kind of comments from the whole simutrans community, just post here.


A more flexible UI framework allowing customization, great. Throwing it at the PAK creators, maybe not great; Simply for consistencies sake. Different PAKs are really just different graphics for the same game, same game ->> should be same basic UI. It's bad enough switching PAKs now with the annoyingly different key bindings, imagine a whole different UI in each. aaiieee!


Well, the idea is have a default UI that will work just as it works the current one. Just that the pak creators can customize windows borders, to put a recent example. And that whould only affect to the UI in that PAK. Or maybe different aligns in the finances windows or whatever. This GUI even allows the PAK developers to modify the UI even further, using LUA.

But the basic, default, non-modified GUI will do and look the same as the current one.

We can allways define what the PAK creators can and can't modify, if we feel it's a game breaking setting.

UPDATE: I'll need some gimp sessions to get the current bitmaps to work! :)

Just one question, the file that's shipped on the binaries skin/menu.WindowSkin.pak is generated from runk\skins.src\skins.* ? What's the aero version for?


This is an alternative skin, following the MAC look. (Try it out.)


I think the CEGUI framework looks very promising. I feel a bit uncertain since this effort overlaps so much with my ideas for Simutrans Iron Bite, but on the other hand we can also learn from each other. Let's see how things will evolve, I have good trust in you after your work with Simutrans3D!


I see, Prissi, thank you. :)

Don't worry Hajo, we'll find the way to make everyone happy :) .

ATM I'm messing around with makeobj and the pak format, to check out how can I extract the UI frames of the PAK on the fly. need to generate a bitmap with all the windows/buttons/mousecursors.

Another option whould require the PAK developers to supply an imagemap of all their widgets. I'll keep you updated.


By the way, I see simutrans fonts are in .bdf format, looks like Freetype supports them but I'm having problems opening them. Where did this fonts came from?

Also, the file skin\menu.WindowSkin.pak has just the minimum number is items to be able to show the pak selection screen, but how do you generate it? if it's from trunk\sinks\skins.png it lacks a mousecursor, how comes the SDL version comes with a mousecursor already?


There is a mouse pointer Pak in pakset. You browse the svn e.g. of pak128.


yeah, i grabbed the pak128 one already, but wondered where did the game get the default one from :)


The mouse cursor is from SDL.

freetype does not work on many platforms, thus it was not incorporated to simutrans.


ok, thank you. :)

Making some progresses here so far, but replicating the simutrans GUI it's a bit time consuming since I have to write all widget descriptions in the XML description CEGUI uses. I'm also having to learn to use GIMP again, but well.. :)

I didn't even began integrating it with simutrans, this will take some time.

About Freetype, well, it's not 100% necessary, image-mapped glyphs are supported. But anyway a platform that doesn't suport freetype it's prolly not going to suport OpenGL anyway.

I see simutrans can be built in: "Microsoft Windows, Linux, BeOS, Intel Mac OS X, iPhone and recently AmigaOS 4.x". I only see BeOS and AmigaOS as a problem here I guess, no?

Any platform without Freetype support doesn't really have much future, maybe. Even my old ipod has freetype libraries built in according the copyright.


Extending UI customisation would help with efforts to produce versions of the game for touch-based devices (e.g. iPhone) as well. Likewise use of OpenGL to render. I'd argue that giving pakset authors complete control of the UI would be a positive thing. Maybe we should stop thinking about Simutrans as a game, and start thinking of it as a game engine which allows multiple games (paksets) to exist.
Use Firefox? Interested in IPv6? Try SixOrNot the IPv6 status indicator for Firefox.
Why not try playing Simutrans online? See the Game Servers board for details.


Quote from: Timothy on February 06, 2012, 09:36:34 AM
Maybe we should stop thinking about Simutrans as a game, and start thinking of it as a game engine which allows multiple games (paksets) to exist.

Yeah, I think that way too. The hard part of this integration seems to be getting each pak icons straight from the PAK and not forcing the PAK to supply a imagemap of all it's buttons.

This includes:
- Top buttonbar
- Extra toolbars for each way type
- Mouse icons
- In the vehicle depot window(vehicles preview and selection)
- In the line management window there is also a pixmap for each line type.

I'm sure I miss a few still.

It whould be way easier if I could just use a super imagemap supplied by each PAK, with all the required icons and a description of their purpose.

Another option is modifyng the pak creation tools so they ALSO create a descriptor and a imagemap I could use. I had a look to the makeobj source and this should not be hard to do.

On this first design I'm just thinking about a golbal UI that will apply to all pak's.  Allowing each pak to override the default behaviour is the second part of the project, and should be planned carefully.

Quite tedious work, to be honest, but it's needed now anyway for Simutrans 3D, I can't postpone this any longer. :)

Even through my initial inention was leave the GUI as it is now.


Since you're touching the toolbar icons, could the pakset provide globally the background button and the single pak only the image on it (with 0xE7FFFF transparency) ?
This way a pakset could switch easily the buttons layout e.g. from grey to blue without having to re-make manually scores of them.


 I'd like to use 32-bit pixels here, with a 8-bit alphachannel and 8 bit per pixel.

Yes, that can be done and I'll do it. But current icon images don't have transparent zones, they will have to be redone to take advantage of this, and then they will not be backwards compatible.

But it's ok, I'll do it.


Well, removing a known background (i.e. the  empty base button) is rather straightforward using Imagemagick.
For backward compatibility, I would say this can wait till your development is merged into trunk, then this replacement could take place painlessly.


At the moment I honestly am not sure that there will be a simutrans version release with require OpenGL HW support to work for the next few years.

But for the 3D enhanced paks anyway new paks will be reuired. Thus those efforts will be realized there first, imho.

Do not underestimate backwards compatibility. During all that time, simutrans only required very very few radical changes to paksets. (The last was the new menu system, and before 16 bit graphics.) Simutrans till can use vehicles made for 84.00.


 I understand your predictions, prissi, but I really hope I have a working HW-accelerated simutrans in 6 months or so.

And about the backwards-compatibility, that's true, but it's also true if has limited the game development in some ways, like for example partial transparencies on sprites to menction a recent request. It has maybe taken you developers to spend time on some places of the code just to mantain compatibility while you might have liked to spend it anywere else. But you are the developers, you know way better than me where do you spind the more time coding in. I think sprite drawing and GUI maintenance have taken lots of your time, but I might be wrong.

This project I have in my hands will allow partially transparent GUI elements, windows animations and to give a bit more sophisticated look to simutrans, and simplify the GUI maintenance since most of the descriptions are in XML files now, not compiled in in C++. And faster performance in the future when I apply the HW support to the game map too.

But I'm not asking for a change, yet. I want to deliver the new engine, show to everybody that works, and it works at least as fast as the current simutrans engine. Backwards compatibility can allways be achieved by developing tools to upgrade old PAK files.

Then the changes will come, if the version has acceptation in the community.


By the way, does any 2D artist volunteers to some small works for this projects? it's a easy task, it's basically making a skin for basic simutrans, not really much work, but my skills on Gimp make me lose lots of time, and it looks awful :)

It's basically adding and rework items to this image, making them similar to current simutrans frames:

Here is the model:

I'll tell you the details if you mail me.


Ok, I worded it wrongly. I think there will be still not only HW-accelerated required version of simutrans released for some time, as this would out many of the players.


Maybe I should have used some smileys, my english it's not good and I might have sounded harsh. :)

No, really, I understand what you said, I was just explaining my view of the situation. I planned it that way, I think it's reasonable to think I will have a playable HW-accelerated version in sixth months, but I can't be sure, because I find new difficulties on the project every step I take. But now I think I'm on the right track. :)


This thread inspired me into making a version of that uses OpenGL instead of GDI to actually put the pixels on the screen. Unfortuanatly, I could not get the dirty rectangle stuff to work, so everything is copied to the screen (via texture) every frame. Runs smoothly in near HD resolutions nevertheless.

I don't know if this would be useful for just integrating CEGUI into Simutrans, where CEGUI could then be rendered on top of the quad textured with the Simutrans map, or maybe the Simutrans map texture could be applied to a CEGUI component. My code is Windows specific, but it should be possible to use SDL to set up OpenGL. Maybe I'll look into that next, unless Markohs wants to code it.


Any new backend is highly embraced. But why using OpenGL on windows and not "native" DirectX?


Maybe because it's not so "native" in other OSes?

Perhaps the purpose is not to work twice...


He wrote he used windows specific functions. (I would really suggest to post a patch.) If window specific function, then the natural question is why not using DirectX in the first place?


Yea, I'm very curious to see that patch, Ters, didn't see your post yet till now. :)

I've had problems with the dirty tile code too, check the asserts in simgraph, they triggered for me, don't really know yet were is the problem. About copying it to screen I don't know what do you mean, don't you use OpenGL to render straight to the window? Why do you use GDI, where do you copy from and were to?

Yes, mixing CEGUI with your code should be easy, using a render-to-texture overlay or making both components write on the same buffer one after the other.

About using OpenGL, it's okay, because it's multiplatform, my approach was using ogre, to get more flexibility, some layer of abstraction, easier scene manipulation and the possibility of choosing betweek OpenGL or Direct3D by the user.

I'd like to have a look to your code. :)

Well, I was going to update this thread with my progress this week. It has not been much.

I spent some time managing to mix OpenGL with a SDL window, plus CEGUI working on it. I've managed to get it working, without much problems.

What has been more time-exhausting is learning more about the CEGUI framework and its XML layout, lookandfeel and event modules, plus some pixelart editing (that at the end I discarded and decided to proceed with the defautl skin and wait for some artists to do the magic in the future).

Well, I don't have much to show yet, I'll just post a SS with the current PAK selection window, that doesn't really work and it's just a stub. But well, it's the first window that looks more-or-less ok. All that layout is 100% customizable editing .xml files, no code recompilation needed.

To give an idea of how this window is created, you just import the layout. There is even a visual layout editor where you can position all the widgets easily and create the .layout.

Of course, all data now is static, the only dynamic is the Add PAK, that just adds one line, with a static text. But of course this can be done dynamic easy.

This window for example is defined as:

<?xml version="1.0" encoding="UTF-8"?>

<GUILayout >
        <Window Type="WindowsLook/FrameWindow" Name="FrameWindow" >
            <Property Name="Text" >PAK Selection
            <Property Name="AlwaysOnTop" Value="True" />
            <Property Name="TitlebarFont" Value="Commonwealth-10" />
            <Property Name="TitlebarEnabled" Value="True" />
            <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.05,0},{0.95,0},{0.95,0}}" />
            <Property Name="DragMovingEnabled" Value="False" />
            <Property Name="CloseButtonEnabled" Value="False" />
            <Window Type="WindowsLook/StaticText" Name="StaticText" >
                <Property Name="Text" >Choose one graphics set for playing.
To avoid seeing this dialogue define a path by:
- adding &apos;pak_file_path = pak/&apos; to your
- using &apos;-objects pakxyz/&apos; on the command line</Property>
                <Property Name="HorzExtent" Value="402" />
                <Property Name="VertExtent" Value="92.6897" />
                <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{0.2,0}}" />
                <Window Type="WindowsLook/Button" Name="ADDPAK" >
                    <Property Name="Text" Value="Add PAK" />
                    <Property Name="UnifiedAreaRect" Value="{{0.631118,0},{0.327662,0},{0.881118,0},{0.577662,0}}" />
            <Window Type="WindowsLook/ItemListbox" Name="PakList" >
                <Property Name="UnifiedAreaRect" Value="{{0.000868,0},{0.2,0},{1,0},{1,0}}" />

and each "entry" is:

<?xml version="1.0" encoding="UTF-8"?>

<GUILayout >
    <Window Type="WindowsLook/ListboxItem" Name="PakLine" >
        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
        <Window Type="WindowsLook/StaticText" Name="PakLine/Name" >
            <Property Name="Text" Value="TEST" />
            <Property Name="HorzExtent" Value="80" />
            <Property Name="VertExtent" Value="27.6283" />
            <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{0.5,0},{1,0}}" />


I used OpenGL because it's easier to get off the ground, as long as one stick to version 1.1 functions. With Direct3D, one needs to use vertex buffers from the start. When I started, I also did not know how little platform neutral OpenGL code I would end up with, so I thought it could be somewhat easy to port. But what is most important about the choice of OpenGL was that I almost started writing this on my Linux computer.
As for my problem with dirty rectangles, it mostly worked, except when the entire screen needed a repaint, such as when panning. When printing out the coordinates and sizes passed to dr_textur, it appeared that full screen refreshes are done using many full width strips of limited height. OpenGL, on my machine at least, appears to not like that for some reason.


DirectX has also a 2D interface (was it DirectDraw?). But in the end it just uses the GDI routines, which were anyway hardware accelerated ...


CEGUI appears to work with 3D APIs only, so DirectDraw isn't an option in this thread.


Directdraw 2D APIS have been removed from DirectX, since version 9 I think. All must be done in 3D if I'm not wrong.


I went to Wikipedia to get updated about the state of DirectDraw. Back when I last did DirectX programming, DirectDraw just seemed to have reached a point where there was nothing more to add, so Microsoft just stopped making new versions. It is still possible to use the old ones, though.

But at the end of the article, there is a link to something called Direct2D. Looks like there still is need for accelerated 2D, but it appears that Direct2D is not a pure raster graphics API like DirectDraw. It's Windows 6.1 only, however, so it would be less portable than an older Windows API.


But anyway, Ters, I think there is no need to use 2D routines, just rendering the shapes with a camera with identity projection ash I guess you do now should be enough, no?

I don't understand exactly what does your code do, you said:

This thread inspired me into making a version of that uses OpenGL instead of GDI to actually put the pixels on the screen. Unfortuanatly, I could not get the dirty rectangle stuff to work, so everything is copied to the screen (via texture)

So, if you are using OpenGL to put the pixels on the screen, why do you need extra windows-native code?

Are you just drawing to a texture using the code as it is now and you just project the texture to screen? Or do you hook in the dr_textur method and just project using a texture in that section of the screen?

On both aproaches I don't know where you have the windows dependency.

My code started as just simutrans writing to a texture instead of the SDL framebuffer, and just rendering the texture full screen each frame.

That approach worked, but had no performance advantage compared to the current SDL/native version, they had almost the same performance, but 3D code was sightly slower. And that's normal, because the only thing that changed is witing to a texture, instead of the screen.

I made a second approach, substituting that texture writing process by renderoperations, basically each display_img_aux, etc, turned into one renderoperation of the image. This approach was slower than current code.

The new aproach I have pending is actually using OpenGL to draw the entire row in less passes, one for each texture atlas.

The idea is:

1) Create a textureatlas for all the ground shapes.
2) Create n textureatlas for the rest of objects, they won't fit in a textureatlas.

3) On each frame:
   a) Render the whole terrain fundaments in just one pass. Cost: O(1)
   b) Render the rest of objects, in steps of one line, from the top row to the one in the bottom, using the needed atlases. Cost: O(height*num_atlas)

If all the dings and objects fitted in one big textureatlas we whould be able to render step b in just one pass too, but simutrans pak's have too much sprites to do that, they won't fit even on a 8K x 8K texture.


simsys_* includes also other code like the processing of keystrokes or opening viewports and mouse support. If OpenGL can do all this, a should be easily possible.


Yes it can, I have that already, so far I've done 2 versions:

- Ogre3D as renderer and OIS to handle input.
- OpenGL as renderer and SDL to handle input (this one has the advantage to not having to rewrite the event handling code, specially important on the keyboard part).

The perfect mix whould be Ogre3D as renderer and SDL for input, I'll use that at the end, I think. It's perfectly possible according this.


In addition to what prissi writes about simsys_*.cc, the functions to set up OpenGL are specific to each platform. OpenGL is only a set of commands to draw graphics somewhere. Platform specific functions are needed to create a window, change display resoulution (for fullscreen) and make it clear that the following OpenGL commands should go to that window.
As long as Simutrans doesn't go full 3D, running CEGUI directly on OpenGL would require less dependencies than Ogre3D, since OpenGL is available on most platforms of interest pretty much by default. On platforms without OpenGL support, Ogre3D would be of little help anyway.
With full 3D, libraries like Ogre3D will be worth including, but that's another thread.