Tuesday, March 24, 2009

FoF - PyOpenGL = miniFoF (possibly for n810)

After spending some time on the Frets-on-Fire code I have managed to liberate it from PyOpenGL dependency.

In first step, I bypassed all the GUI code, without making any changes to the audio and input processing components. So I ended up with a completely blank window with a default song playing and me pressing the keyboard frets blindly.

In second step, I wrote only few lines of code to draw the notes on the screen using basic pygame.draw functions.

Here is a screen shot of the minimal UI.



Then I realized that, in theory this minimal version can also run on n810. I tested it in Diablo SDK and it runs. I couldn't hear the sound, but that's an issue with my scratchbox settings. I am sure that this will run on n810, however I am not sure if it will have real time response times. Unfortunately, I don't have a n810 to try this on (mine must be changing hands in black market as I write this :( ). Nevertheless I made necessary changes so that someone can try it on real n810 if they wish to.

If you have played FoF on keyboard, you would know F1-F5 keys are used to control frets and RETURN key is used to pluck the string. One possible way to achieve this with n810 is to use the keys on the keypad.

Following mockup should give you an idea.



F1 = Quote, F2 = K, F3 = H, F4 = F, F5 = S

In place of RETURN we can use the square key as shown above, but I couldn't find what its keycode is. So for now I have assigned that functionality to Q. If someone can provide with that keycode in pygame, I will fix it.

The gameplay is for single song only. I have bypassed all the menus for now. As the song starts the goal is to hit the note when it reaches the white line. You can play different songs by specifying their name as --play command line option.

This is not (yet) a single click install app, however.

I have put together the steps that you will need to follow, to get it working on actual n810. Those should work to the best of my knowledge, but you may run into errors. If you do, please report them in comments and I can help with them.

If you are interested in the changes I had to make, then here is the list of changes starting from the baseline FoF code (r1165 - r1176)

Give it a try. If it runs slow, let me know how slow. There still must be bunch of code paths that we can eliminate to improve the response times.

Wednesday, March 18, 2009

FoF update

After the Frets-on-Fire-on-Fremantle post, the feasibility of it on real actual hardware was discussed on maemo mailing list and in comments. It became clear that it's not sufficient to get FoF running in SDK to prove that it will also run on final hardware. We will have to work on the OpenGL GUI to make it happen.

So I dived into the internals of FoF. And this is what I've come up with so far. (Click on image for detailed view)



It is far from a formal UML diagram, but it tries to capture the elaborate architecture of FoF code.

I am experimenting with some parts of the above diagram. Let's see how it goes.

That's all for now... BTW, I posted inkface v0.2.3 yesterday (highlights - all tests running in Diablo SDK, basic Clutter support). Check the detailed changelog here.

Thursday, March 12, 2009

Twitter client with inkface-pygame v0.2.2

Here is an update on the Inkface library. But before that let me give a background of the project for the benefit of new readers that will be reading this post via Planet Maemo.

Inkface is an SVG based GUI framework. Unlike the desktops - where GUI components need to be keyboard/mouse friendly; the handheld GUIs need to be finger friendly. Therefore the handheld GUI components should be naturally manipulatable - like parts of an image. Therefore inkface provides a framework in which, GUI is composed in an image editor like Inkscape, instead of rigidly coded in the program. The various elements of SVG image are presented as python objects to the programmer who can then write his program logic using these elements as widgets.

The current version of inkface uses pycairo for vector graphics rendering and uses pygame as backend surface to draw on. A clutter backend is in the plans.

With that background, let me show a demo of an app that I designed (in Inkscape) and coded (in python) using inkface-pygame library v0.2.2. It's a twitter client. The demo shows how the GUI can be changed vastly by merely changing the SVG files and doing no change in the code at all. (the --theme option tells the app to just use a different set of SVG files) The first one is the default theme and the later has a vintage look.



The whole GUI consists of only 2 SVG images (corresponding to 2 screens - login and main twits page). So to create a new theme one only needs to create/change these two SVG files in Inkscape. Compare this to the traditional approach where a theme consists of tens of PNG images of specific sizes.

I was aiming to release it as an app for diablo, but I had to postpone the plan. For improving the performance during animation, I used pygame's features that are only available in v1.8.x and I later found that Diablo ships with pygame v1.7.x. So I need to work around this incompatibility before I release it for n8x0 devices.

For more information on the project check out the wiki. You can download v0.2.2 tarball from here. It is pure python code and can be tried on desktop. For details on the changelog of v0.2.2 check my post on the mailing list here.

Wednesday, March 04, 2009

Frets on Fire on Maemo 5 (Fremantle)

Couple days ago I played Frets on Fire (FoF) for the first time. I was totally hooked on to it. After going through its hilarious tutorial and starting with a pathetic performance, I managed to score 37K points with 87% accuracy on the "Defy the Machine" song a few moments ago.

Couple days ago Nokia released the alpha version of Maemo 5 SDK (Fremantle) too.

I woke up next morning with an inevitable thought of porting the former on the later.

After a day's work here is a video demo of "Frets on Fire" running in the Maemo scratchbox SDK. And find below a list of things I had to do to get it working.

[If you don't know about FoF, it's an open source Guitar Hero clone that runs on many desktop platforms. It is written completely in python. While playing it you hold your keyboard in an unusual fashion so that it simulates a rockstar's guitar. (wikipedia)]



In future we can tweak FoF's UI so that the strings could be pressed against the frets using the touch screen itself.

There is no sound in the video, but it's just because I couldn't channel the sound through two layers of virtualization and into the video recorder software. I could hear the songs alright though after transporting them over wire using pulseaudio.

[Note that scratchbox is running on Ubuntu which itself is a KVM virtual machine. That should put the poor framerate into perspective.]

Here are the things I had to do:
  • Fremantle SDK doesn't have python distutils. In diablo it comes from extras repo, so I borrowed it from there as well. (Added diablo extras repo in /etc/apt/sources.list)
  • Fremantle SDK has a bug that I had discussed on mailing list during pre-alpha release, due to which the SDL/pygame applications cannot use the OpenGL support of the SDK. Due to same bug, FoF would also not work. After some googling I figured out the root cause and a work around. I built a private version of libsdl with --enable-video-opengl option. That did the trick. I have filed a bug to get this fixed in Fremantle.
  • I also had to build custom packages of PIL (python imaging library) and numpy. I believe these libraries are available in diablo through extras repository, so I guess they will also be available in fremantle in future.
  • Next I had to modify src/Input.py to comment out pygame's joystick initialization code.
  • The really tough part was getting sound working. I found an old post to get sound working in scratchbox. Although it was a correct procedure, it didn't work for me. After a while I remembered from the Maemo summit that Fremantle runs pulseaudio (as opposed to esound in diablo). After that I did some googling and figured how to transport the sound over network using pulseaudio server and client. Here are couple useful links. [1] [2]
  • The job on sound wasn't over yet. FoF runs all its music from ogg files. pygame won't play ogg files on fremantle. I dabbled into recompiling SDL_mixer with ogg support, but that didn't help. Then another discussion from Maemo summit came to mind, and I remembered for some (non-technical ?!) reason Maemo doesn't play ogg. So to get around it, I converted all .ogg files into .wav using ffmpeg. Changed the code wherever necessary to replace the file name extensions from ogg to wav. That did the trick and finally I could hear the sound.
  • The game by default used 600x480 resolution. After some analysis of the code, I found fretsonfire.ini file in my home directory. I changed it to set the resolution to 800x480 to fit into the Xephyr window.
  • There is one thing that I couldn't get to work. Arrow keys won't work. I found that the scan codes sent through Xephyr to the pygame were different from what are put in pygame constants.

... so when Nokia releases that next device, we will have an electric guitar in our pocket. :)

Sunday, March 01, 2009

Static IP configuration on Fedora 10

Until last week Hathway (my ISP in Mumbai) was asking me to do DHCP discovery for IP address. After the n/w stopped working yesterday I called their service rep. One of them couldn't resolve it yesterday, so he forwarded me to another guy who turned out to be a funny experience - he gave me all the static IP config valus - and when the network still won't work he started blaming it on computer virus and ultimately rust on my network cable (!) Fortunately for me (and also for him) the modem was little sluggish in picking up the change and the network started working.

I had booted my new computer in Vista (yeah I know! argh!) and it worked fine. Surprisingly my Fedora 10 on Macbook and also the Fedora 10 on desktop won't respond to the static IP information. It took me 4 hours to figure out that there was nothing wrong in my knowledge of the network scripts. I got the clue when I found the system doing DHCP discovery even when I had set it to static IP. I figured it was because of the NetworkManager (seen as that taskbar network icon). When I googled, it became clear that configuring Fedora 10 with static IP is a known problem and the culprit is NetworkManager and/or system-config-network utility. This thread (#14) is pretty much helpful, but the working solution (or workaround) is not definite.

Here is what worked for me (at least for this box).

# Stop NetworkManager
sudo service NetworkManager stop

# Disable NetworkManager service
sudo chkconfig NetworkManager off

# Enable netwok service
sudo chkconfig network on

# Run system-config-network
# Edit the ethernet device under Device tab
# Under "Manual IP Address settings" put static IP Address.
# Leave Subnet mask and Default Gateway blank
# Change to Route tab
# Add route Dest 0.0.0.0 Netmask 0.0.0.0 Gateway
# Add route Dest Netmask Gateway
# Change to DNS tab to put addresses of DNS servers
# Check "Activate device when computer starts" same as ONBOOT=yes (I guess)
# Save the settings

sudo service network restart

At this point network should be working. If it doesn't don't get surprised. The same steps don't help me setup my Macbook Fedora 10 with static IP. Maybe I have screwed it beyond repair. I will wait for the router to arrive, to get my macbook online.



Ads:
Linux Administration Handbook (2nd Edition) (Best tips on Linux administration I found in this book. Own it myself.)
Fedora Bible 2010 Edition: Featuring Fedora Linux 12
Linux Networking Cookbook