Python And Pygame


klikklak

Oh neat, it's a ... field.
Joined
Jul 23, 2006
Messages
845
Location
helsinki, finland
Website
Visit site
what's the status of python currently? And specifically of pygame? It's an alternative to GLbasic and Fenix I'd rather learn, because python would be generally useful for scripting, while basic is not.
 
I'm also very interested in Python/Pygame for the wiz. Seeing how it was ported to the GP2X a long while ago, it should be possible.
At the moment I'm trying to port it, but I'm useless.
 
I ported it months ago, it is out there somewhere. ED reckons it doesn't work on the latest firmware, but I don't know. It is a real bugger to cross compile.
 
Yeah, I remembered reading that python had been done, didn't know you also ported pygame. And it's a pity that it's broken currently. And a shame that it's a pain to compile. Personally I couldn't even get the cross compilation chain working (couldn't figure out codeblocks), so it looks like I'm useless as well.
 
Yep, it only worked with FW pre 1.0.0. And it was slow... about the same speed as on the gp2x.
 
Orkie was so kind to give me the link to Python 2.6/Pygame: http://x11.gp2x.de/openwiz/python-wiz-2.6.tar.bz2
Thanks Orkie!

Some pygame gotchas:
  • font module is missing
  • touchscreen (mouse input) does not work
  • can only load BMP files
  • WIZ button definitions are in pygame.gp2x.locals
  • screen HWSURFACE flag suffers from the usual tearing issue (use SWSURFACE instead)
Example .gpe file for running a python script:

Code:
#!/bin/sh

PYTHONHOME=/mnt/sd/python  # does not have to be there, change this to wherever your python install is
export PYTHONHOME
PYTHONPATH=${PYTHONHOME}/lib/python2.6/site-packages:$PYTHONPATH
PYTHONPATH=${PYTHONHOME}/lib/python2.6/lib-dynload:$PYTHONPATH
PYTHONPATH=${PYTHONHOME}/lib/python2.6:$PYTHONPATH
PYTHONPATH=${PYTHONHOME}:$PYTHONPATH
export PYTHONPATH

LD_LIBRARY_PATH=${PYTHONHOME}/extras:${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH

${PYTHONHOME}/python2.6 -OOu example.py > ./example.log 2>&1

sync

cd /usr/gp2x
./gp2xmenu
 
torpor said:
Man, this is great .. one more step towards pyglet! :)

That's right. Though, pyglet uses GL_QUADs instead of triangles, and those
are not supported by OpenGL ES (afaik). Also, I don't know if/how AVBin works,
and if it's portable, so pyglet might not be able to use any sound.
Other than that, it might work, since it's pure python (and therefore slow :p).
 
Last edited by a moderator:
Argh, you're right about GL_QUADS, hadn't thought of that .. a pity, because there are some nice pyglet games out there that would be a quick and dirty port if we had it ..

Yeah, python. Its slow, but not so bad, and the advantage of being able to use the machine itself to do development overweighs the performance hit. In an ideal world, we'd have pygame+pyglet on the WIZ, and g_ether too, so that all we need to do is write python on the device .. no cross-compiling, no major heavy build environment on another machine to maintain, etc.
 
Didn't work here with the 1.1.0 FW by the way. Edit: Bad line endings. It does work.

>can only load BMP files

That's clearly the biggest issue. Well, there are 32bit BMPs, but support for that is generally pretty poor (pygame for example doesn't support it). TGA is a very simple format and covers most things one might need.

>Though, pyglet uses GL_QUADs instead of triangles [...]

The draw texture extension is a much better choice for simple 1:1 blits. And you can also always break the quads into triangles on the native side.
 
aho said:
Didn't work here with the 1.1.0 FW by the way. Edit: Bad line endings. It does work.

>can only load BMP files

That's clearly the biggest issue. Well, there are 32bit BMPs, but support for that is generally pretty poor (pygame for example doesn't support it). TGA is a very simple format and covers most things one might need.

That was my problem with Barbie Seahorse Adventures. I have a complete working version for GP2X and WIZ Pre 1.0.0 (though very slow on both machines, but that would be optimizing and using Hardware layer on WIZ to make it playable).
However, it uses PNG. And as those PNGs use an alpha channel, I can't convert them to BMP...
 
Last edited:
There is some ugly hack for 32bit BMPs on the pygame wiki, but I think it might be better to write a simple 32bit TGA loader. There is a simple 12 byte header (ignore)... then width and height as little endian 2 byte shorts. Then bpp and bits per channel as bytes. And finally the pixel data.

It's very easy to handle if you only intend to cover 24/32bit w/o any extras.

Edit: bpp is a byte and there is another bits per channel byte by the looks of it.
 
Edit: Ignore this. Check page 2 for something better.

TGA loader (tga.py):
Code:
import pygame
from struct import unpack

def load(filename):
    try:
        print 'reading %s' % filename
        f=open(filename,'rb')
        data=f.read()
        f.close()
        
        header=unpack('hhBB',data[12:18])
        w=header[0]
        h=header[1]
        bpp=header[2]
        bpc=header[3]
        
        surface=pygame.Surface((w,h),pygame.SRCALPHA,32)
        surface.lock()
        offset=18
        try:
            for y in xrange(h):
                yf=h-y-1
                for x in xrange(w):
                    surface.set_at((x,yf),(
                        ord(data[offset+2]), #r
                        ord(data[offset+1]), #g
                        ord(data[offset+0]), #b
                        ord(data[offset+3])  #a
                    ))
                    offset+=4
        finally:
            surface.unlock()
    except:
        raise
    return surface

Code:
#import:
import tga
#load:
img=tga.load('foo32bit.tga') #only handles uncompressed 32bit tgas and nothing else
#draw:
screen.blit(img,(x,y))
 
There was an off-by-one error. Forgot to subtract one in that "yf=h-y-1" line. Thanks to JustBurn for pointing that out. :)
 
wizbutton.png


http://kaioa.com/k/wizbutton.zip (22kb) Edit: link was wrong :f

Press the buttons and they get highlighted on screen. That rect just moves around. Press + and - to exit.

Things to note:

  • The timing is horribly wrong. It reports 100fps (if no buttons are pressed) instead of 50fps. But even then the animation actually runs slower than it should (by about 20-30%, I guess).
  • LOADING TAKES FOREVER - seriously. It takes 5 minutes and 5 seconds to load. (A progress bar appears after a few seconds.)
  • The long loading time and the big drop in frames if buttons are pressed are partially my fault. For each button there is one 320x240 image which is completely transparent apart from the highlighted button. So, if you press 4 buttons at the same time, 5 320x240 images will be drawn. It also means that there are a whopping 20 320x240 images to be loaded (+ the font console).
  • The most interesting bit is probably the minimalistic text renderer. It's based on one of my other bitmap font renderers but it only does the bare minimum (single line and left aligned).

Pygame on the Wiz really needs a proper image loader.
 
New version. Loads in 7 seconds! Wee!

http://kaioa.com/k/wizbutton2b.zip (23kb)

Archive contains Pyr.java which can convert images to 32bit pyr images. Using a custom format allowed me to utilize pygame.image.frombuffer, which is about as good as a native "raw" loader.

Edit: Replaced the timing with pygame.time.get_ticks(). The displayed fps seem to be accurate now. However, the resolution is pretty bad. It's 10msec.
 
Aww... gzip fails... :/

Code:
Traceback (most recent call last):
  File "wizbutton.py", line 11, in <module>
    import pyz
  File "/mnt/sd/wizbutton3/pyz.py", line 1, in <module>
    import pygame,gzip
  File "/mnt/sd/python/lib/python2.6/gzip.py", line 9, in <module>
    import zlib
ImportError: /mnt/sd/python/lib/python2.6/lib-dynload/zlib.so: undefined symbol: inflateEnd

Using gzip would have turned my format into a sort-of PNG (PNG also uses Deflate). With the magic of gzip the wasteful images of my demo app only take 18.5kb instead of 6.2mb.
 
Evil workaround:
Code:
import pygame
from struct import unpack

#import gzip
import subprocess

def load(filename):
    try:
        print 'reading %s' % filename
        '
        f=gzip.open(filename,'rb')
        data=f.read()
        f.close()
        '
        p=subprocess.Popen('gunzip -cd %s' % filename,bufsize=4096,stdout=subprocess.PIPE,shell=True)
        data=p.stdout.read()
        p.stdout.close()

        header=unpack('hh',data[:4])
        w=header[0]
        h=header[1]
        surface=pygame.image.frombuffer(data[4:],(w,h),'RGBA').convert_alpha()
    except:
        raise
    return surface

It's quite a bit slower than using Python's gzip. At least on Windows. I hope that the slightly increased CPU usage is canceled out by the smaller reads. SD cards are somewhat slow after all. Compared to reading raw this sorta indirect way of loading deflated data takes about twice as long. Not bad, but I really do hope that fixing gzip will improve performance a bit.

If you want to run code like this on Windows, you'll need unxutils' gunzip.exe.
 
Last edited by a moderator:
Back
Top