Tag: Texture

April 2012 Update: Iain’s cracked the play-without-playfield-texture-or-don’t-play-at-all issue; the trick is to use PlayOnLinux, which forces use of Wine 1.2.2 for FP! See details in the comment here!

I used to play Visual Pinball back in the day on Windows, and when combined with PinMAME for the ROM side of things it was awesome! But when I moved to Linux the PC gaming basically stopped. However, the other day I picked up Williams Pinball Classics for the 360 – and it’s absolutely brilliant! So this got me thinking about whether Future Pinball (the newer incarnation of Visual Pinball) can run in Linux – and with some tweaking, it can!

Without the tweaks you’re likely to get two specific problems:

You can’t start a game (the table loads, lights flash, you can nudge the table and change the camera angles but the game just won’t start), and

There’s no sound.

The good news is that both of these can be fixed with a little bit of tweaking! The bad news is that unless you have a videocard with a lot of VRAM (I’m going to guess 1024MB minimum, as the issue occurs on my 512MB card under Gnome Shell) then tables which you download (but strangely not the Sci-Fi table that comes with FP) are likely to be missing the larger textures such as playfields. This is pretty odd as I can fire up FP in a XP virtual machine with 128MB of video RAM allocated (with far less performance, FPS-wise) and the textures will display without issue – they just don’t like to appear through Wine! So if this is a deal-breaker for you then you might be better off trying Future Pinball under an XP virtual machine, or calling the whole thing off. But if you want to get Future Pinball working in Linux, then we can make it happen…

Note: Wine automatically guesses the availble video RAM on your graphics card, and I’ve got to say, I have no idea if its guess is accurate. I took a look at the Wine useful registry keys and I don’t even have the direct3d key to modify the video RAM settings (because installing DirectX in Wine is considered bad-form, apparently), so I’ve no idea how to tell wine to allocate a reasonable amount of video RAM. Perhaps this will change in the future.

Step 1 – Installing Wine

To play Future Pinball you’re going to need a copy of the Wine (Wine Is Not an Emulator) “emulator”, which you can grab from your distro repositories or from WineHQ directly. So either run the following (or your distro’s equivilent package installing command) or grab it from synaptic package manager or such:

Then, get it to autodetect your drives by going to the Drives tab and clicking on, you guessed it, [Autodetect], like this:Wine configuration - detecting drives. Your setup will obviously look a bit different depending on the drives you have mounted.

Once that’s done, click [OK] to close down Wine Configuration. By default, Wine creates a hidden folder called .wine in your home directory where it places its files, including the folder that acts as your C: drive in the folder ~/.wine/drive_c.

Once these are downloaded, navigate to the directory you downloaded them to from the commandline and run:

wine ./FuturePinballSetup_v1.9.1.20101231.exe

Accept the licence, click Next/Next/Finish etc. and that’s done. Future Pinball will now be installed in ~/.wine/drive_c/Games/Future Pinball.

Now install the the Sci-Fi table by running:

wine ./Sci-Fi\ Classic.exe

You’ll want to change the installation directory from the default of C:\Program Files\Future Pinball to C:\Games\Future Pinball during the install wizard for this. Don’t bother creating a Tables folder though, as the table itself contains a top-level Tables folder – so just pointing it at C:\Games\Future Pinball will be fine.

Step 3 – Configuration and Tweaking

By default, Wine will attempt to run things as Windows XP (as opposed to 2000, or ME, or Vista or 7 etc). This is fine, but as things stand we’re still not going to be able to play any pinball just yet because Future Pinball itself wants to run as Administrator when running in Windows… but we don’t have a Windows Administrator account (in fact, this same issue appears when running FP in Windows natively – if you don’t “Run As Administrator” it, you can’t start a game) – and unfortunately no, sudo won’t cut it ;) So next we need to workaround this by adding a dll and telling Wine to prefer it.

To do this, download the file: oleaut32.dll and place it in your ~/.wine/drive_c/Games/Future\ Pinball/ folder, then run winecfg again. This time you should see “Future Pinball.exe” in the applications pane of the Applications tab – so click on it to select it:

Now click on the Libraries tab, then on the New Overide for Library dropdown. Find the listing for the file oleaut32, click on it then click [Add] (you can leave the default settings as “native, builtin”. With that done, you should see something like this:

With the new DLL taking precedence over the Wine built-in we’ll be able to start a game of pinball, so just hit [OK] to save and close the Wine configuration settings and we’re ready to get our flippers on =D

Step 4 – Launch without PulseAudio

Wine doesn’t natively support PulseAudio, although it’s fine with Alsa. So to play with sound we’ll need to bypass PulseAudio with the pasuspender util. To do this, all we have to do is launch Future Pinball like this:

With that done, just press F4 to bring up the table selection window and you should see something like this:

Now click on [Load and Play Table] and we’re good to go.

Step 5 – Play a Mean Pinball

Future Pinball is like an arcade emulator, so you have to “insert a coin” before you can play. The main keys are:

5/6/7/8 – Insert coin for player 1/2/3/4 respectively

1/2/3/4 – Start 1/2/3/4 player game

Enter – Launch ball (i.e. shoot ball w/ plunger to start game)

Left/Right shift – Left/Right flippers

Space – Nudge table

F1-F8 – Different camera views

F9 – show stats (fps etc.)

So to start a single player game you might press 5 to insert a coin, 1 to start a 1 player game, then Enter to launch the ball – and you’re off! This isn’t my video, and it’s prolly not running on Linux, but this is the kind of stuff FP is capable of:

6 – Cleaning up

FP doesn’t close down cleanly in Wine, so you have to assist it with a bit o’ the old kill -9 ;)

Update: FP will close down properly on Wine 1.5 onwards, so you won’t need to perform these steps. When I originally wrote this I was using Wine 1.3.something.

And on the off-chance that pulseaudio stops working, just run the following and it’ll restart for you:

pulseaudio -k

Many thanks to Christopher Leatherly and everyone who had a hand in Future Pinball for its existence, to Mahen for his posts on the WineHQ Future Pinball entry for the fixes needed to get everything running, and to everyone who’s worked on Wine =D

Cheers!

Final Technical Notes

I did try to install FP through the fpwine FP installer script, but it’s legacy because some of the wine options called are deprecated, so I found a modification of the script on ubuntuforums-fr.org, which with suitable tweaking (DCOM98.EXE would throw a fit on install) would install FP into its own ~/.fpwine “shell” but although that added overrides for the oleaut32.dll, ole32.dll, rsaenh.dll and crypt.dll, I still couldn’t get all the textures working in downloaded tables (which would work fine in an XP virtual machine). If I could specify how much VRAM I had to Wine, I think the issue would be solved.

Also, a workaround to minimise VRAM is to disable loading the textures into the editor (available in FP from Preferences | Editor Options…) – but at least for me, it doesn’t minimise VRAM usage enough. And if you’re trying to minimise VRAM and get textures working you’ll probably want to enable non-power-of-2 textures (Preferences | Video / Rendering Options…), try starting tables off at minimum detail settings (i.e. no High Quality textures), and re-start Wine/FP between table reloads as alledgedly it leaks memory (including VRAM), which is only going to make things worse each table you load.

Finally, the fpwine script likes to install version 5.6 of VBScript (vbs56men.exe), which I found completely knackered the table scripts, so I’ve found its best to avoid installing it and leave Wine alone with its own VBScript functionality.

I’m -sure- this is all doable somehow… I just haven’t managed to crack it yet, and it might be the case that Wine needs further work before it can be cracked at all.

The Sci-Fi table works perfectly, but it still feels like 4th and inches to get everthing working 100%…

I’m working on using OpenCV to get Kinect sensor data via OpenNI, and needed a way to get a matrix (cv::Mat) into an OpenGL texture – so I wrote a function to do just that – woo! Apologies in advance for the terrible juggling ;-)

The function used to perform the sensor data to texture conversion is:

There’s one very important issue to watch out for when using OpenCV and OpenNI together which I’ve commented in the code, but I’ll place here as well as it can be a real deal breaker:

There appears to be a threading issue with the OpenCV grab() function where if you try to grab the device before it’s ready to provide the next frame it takes up to 2 seconds to provide the frame, which it might do for a little while before crashing the XnSensorServer process & then you can’t get any more frames without restarting the application. This results in horrible, stuttery framerates and garbled sensor data.

I’ve found that this can be worked around by playing an mp3 in the background. No, really. I’m guessing the threading of the mp3 player introduces some kind of latency which prevents the grab() function being called too soon. Try it if you don’t believe me!

So just be aware that if you’re using a Kinect you have to be careful with the grab() function… The source code used to create the above video is provided in full after the jump, if you’re interested.

I wrote an article a while back about loading images to use as textures in OpenGL, and in it I’d written my own single line image to texture-handle function because I couldn’t get the built-in ilutGLLoadImage function to work. Since I’ve been getting blank looks and failure to compile reports about it, I thought I’d go and take a look at it again, and this time ilutGLLoadImage seems to work just fine, so let’s document it up properly shall we?

Pre-requisites

A copy of GLEW (GL Extension Wrangler – to make the functionality in your OpenGL drivers availble for use)

A copy of GLFW (GL FrameWork – to quickly and easily set up a OpenGL context)

An image to load

Preparation and libraries

Create a new project in your IDE of choice, and link in the following libraries:

You’ll have to figure out where the libraries are on your own system but these are where they are on mine, where a /usr/local/ address indicates packages I’ve build myself, /usr/lib/ indicates standard system installed packages, and no prefix uses any paths defined by the compiler (in this case /usr/ where the lib and include directories are assumed). I’ve also added /usr/local/ to the include path so that any headers in /usr/local/include/ are picked up before any in /usr/include. Yes, library paths are a pain ;)

Also, be sure that your project includes its own directory as the working directory (i.e. the directory to be in when executing) so that you can place your image (in this example, a file called abstract-image.jpg) in the main project directory and it’ll be picked up when we try to load it. The way that you specify the working directory will vary depending on the IDE you’re using, but in Code::Blocks you set it from Project | Properties | Build targets like this:

Source Code

Create a new project with source code something like this:

#include <iostream>

#include <cstdlib>

#include <GL/glew.h> // Include GLEW, which pulls in OpenGL headers as required

#include <GL/glfw.h> // Include OpenGL Framework headers

#define ILUT_USE_OPENGL // This MUST be defined before calling the DevIL headers or we don't get OpenGL functionality

#include <IL/il.h>

#include <IL/ilu.h>

#include <IL/ilut.h>

GLuint textureHandle;// Create a uint to store the handle to our texture

I was playing around with FBOs and rendering to textures the other week and came up with this. A spinning yellow torus is rendered to a texture, then a second spinning torus is textured using the texture we just created of the first spinning torus… Yeah, I need to stop using donuts as my test objects.

Just learning some GLSL and playing about with vertex and fragment shaders – not a bad first start, but it’s going to take a significant amount of time and effort to get to really writing some descent shaders – it’s just very, very different from fixed-pipeline stuff… What you’re looking at is a texture where I’ve drawn some stuff on it in bright red, and then in the fragment shader anything found in the texture to be bright red gets discarded, effectively leaving in empty, like a cut-out =D

All in, the project’s around 500 lines of source, with the shaders being merely:

sampler2D myTexture;// Apparently this should not be a uniform variable as you shouldn't loop through uniform variables for performance reasons...
varying vec2 vTexCoord;// Pass through from our vertex shader. Should be type "in" in more recent versions of GLSLvoid main (void){
vec4 color = texture2D(myTexture, vTexCoord);if(color.r>0.9&&(color.g<0.15&& color.b<0.15))
discard;
gl_FragColor = color;}

The Linux Code::Blocks project will all source & image can be found below, but you’ll need to have or install libGL, libGLEW, libglfw, libIL, libILU, libILUT for it to work right out of the box. The linkage details are all in the Code::Blocks project file (and also in the .depend file if you don’t use C::B) so you can see what you need if there’s anything missing.

Update: Ha! Hadn’t thought of this before, but I guess what I’m really doing is Chroma-Keying (or Colour-Keying, whatever you prefer)… And you can do the same thing in SDL/OpenGL without using any shaders like this.