Archive

Archive for December, 2006

Python function for creating “ASCII-art”

December 27th, 2006

Just threw together a little function to produce “ASCII-art” from a BMP-file using the BMPDecoder class I posted about earlier today to give an example of what you can do with it.
It can of course be improved a lot, but I probably won’t (so feel free to do it yourself).
Since this module uses the BMPDecode module, you of course need it for it to work.

Download:
Download the python module here (without BMPDecode)
tar.gz archive containing this module + BMPDecode
zip archive containing this module + BMPDecode

You can see an example of the output here:
ASCII art of my kitten

Resized image of the browser displaying the output:
kitten

(Yes, I’m aware of the fact that normal ASCII-art does not use colors, but just ASCII-characters to produce pictures that way)

buffi Programming & scripting, Python

Test-application for drawing using BMPDecode and pygame

December 26th, 2006

Might as well post the application I wrote for testing the BMPDecoder.
It has pygame as a dependency since it uses it’s SDL-bindings to draw to screen.

If you want to play around with BMPDecode it is nice to have something to test the code with.
Download test-application

An example of the text output of the test application (header data)

> python testdecoder.py 4bitc.bmp
self.bfType:  BM
self.bfSize:  922
self.bfReserved1:
self.bfReserved2:
self.bfOffBits:  118
self.biSize:  40
self.biWidth:  127
self.biHeight:  64
self.biPlanes:  1
self.biBitCount:  4
self.biCompression:  2
self.biSizeImage:  804
self.biXPelsPerMeter:  0
self.biYPelsPerMeter:  0
self.biClrUsed:  0
self.biClrImportant:  0

It also draws the bitmap using pygame (an ugly pixel-drawing hack I made… there are probably better ways).

Screenshot of some instances of the program:

Also… on another note.
Did you know that imagemagick converts 4-bit bitmaps (or pretty much any bitmap) to a 24-bit bitmap when using convert for doing resizing or whatever?
I didn’t :)

buffi Programming & scripting, Python

BMPDecoder in python. BMPDecode version 1.0 released

December 26th, 2006

Just got finished with a release on a small project I’ve been working on to learn how windows bitmaps are constructed. Learned a whole lot creating this module and perhaps it might be useful for someone… Feel free to comment this post with feedback, or simply email me (bjokem-4@student.ltu.se). The module is open source (GPL-license).

Download!
Files only available in archives since GPL requires the license to be bundled.
Download! (updated 1.1)

- BMPDecode version 1.0 -
Features:

Kan decode all commonly used bmp encodings as well as some not so commonly used. Some of the weirder formats such as OS/2 version 1 bitmaps are not included (yet). The decoded object grants easy access to the color of each individual pixel, as well as header-data.

The supported BMP-encodings so far are

  • 1-bit bitmaps
  • 4-bit bitmaps
  • 4-bit rle-4 compressed bitmaps
  • 8-bit bitmaps
  • 4-bit rle-8 compressed bitmaps
  • 16-bit bitmaps (rgb555)
  • 24-bit bitmaps
  • 32-bit bitmaps (rgb888)

Example of using the module

>>> import bmpdecode
>>> decoder = bmpdecode.BMPDecoder("cat.bmp")
>>> decoder.get_height()
410
>>> decoder.get_width()
509
>>> decoder.print_fileheader()
self.bfType:  BM
self.bfSize:  626534
self.bfReserved1:
self.bfReserved2:
self.bfOffBits:  54
>>> decoder.print_fileinfoheader()
self.biSize:  40
self.biWidth:  509
self.biHeight:  410
self.biPlanes:  1
self.biBitCount:  24
self.biCompression:  0
self.biSizeImage:  626480
self.biXPelsPerMeter:  2834
self.biYPelsPerMeter:  2834
self.biClrUsed:  0
self.biClrImportant:  0
>>> decoder.get_pixel_rgb(100,100)
(66, 62, 63)
>>> decoder.get_pixel_rgb(220,107)
(45, 39, 39)
>>> decoder.get_pixel_hexclr(220,107)
'0x2d2727'
>>> decoder.get_pixel_hexclr(10,10)
'0x352d20'

Documentation

Module contains all documentation. Here is the output of help(bmpdecode)

DESCRIPTION
    BMPDecoder:
    A module for decoding BMP-images. Grants easy access to the color of
    individual pixels.

    Revision history:

    v1.0 - 25/12-2006: Bjorn Kempen. First release.
    1,4,8,16,24,32 bit bitmaps supported
    4bit and 8bit rle-compressed bitmaps supported

    Contact information:

    Bjorn Kempen
    bjokem-4@student.ltu.se
    http://www.buffis.com

CLASSES
    BMPDecoder

    class BMPDecoder
     |  Class for decoding BMP-images.
     |  Supported encodings are:
     |  1-bit bitmap
     |  4-bit bitmap
     |  8-bit bitmap
     |  16-bit bitmap (using rgb555 bitmask)
     |  24-bit bitmap
     |  32-bit bitmap (default 32bit only. no bitfield implementation yet)
     |  4-bit rle_4 compressed bitmap
     |  8-bit rle_8 compressed bitmap
     |
     |  Unsupported encodings:
     |  16-bit bitmaps with bitfields
     |  32-bit bitmaps with bitfields
     |  32-bit transparency
     |  OS/2 version 1 bitmap
     |  OS/2 version 2 bitmap
     |
     |  Chances that you will encounter a BMP not suited for decoding using this module
     |  during ordinary use is extremely slim.
     |
     |  Methods defined here:
     |
     |  __init__(self, filename)
     |      BMPDecoder(filename) -> a BMPDecoder object from the
     |      bitmap contained in the file which the filename specify
     |
     |  get_height(self)
     |      getHeight() -> height as an integer
     |      Returns the height of the bitmap.
     |
     |  get_pixel_hexclr(self, x, y)
     |      get_pixel_hexclr(position x, position y) -> color of pixel at
     |      (x,y) as a hexadecimal color (0x######)
     |      Returns the color of a pixel in a bitmap as a hex color
     |
     |  get_pixel_rgb(self, x, y)
     |      get_pixel_rgb(position x, position y) -> color of pixel at
     |      (x,y) as a (r,g,b) tuple
     |      Returns the color of a pixel in a bitmap as a tuple of
     |      its components in red, green and blue
     |
     |  get_width(self)
     |      Returns the width of the bitmap.
     |      getWidth() -> width as an integer
     |
     |  print_fileheader(self)
     |      printFileHeader() -> no return value
     |      Prints the file header of the bitmap.
     |      This header contains information about the file that you most likely wont need
     |
     |  print_fileinfoheader(self)
     |      printFileInfoHeader() -> no return value
     |      Prints the file info header of the bitmap.
     |      This header contains information about the bitmap,
     |      such as width, height, encoding and so on

buffi Programming & scripting, Python

Fun with python. Persistent variables in functions

December 25th, 2006

Say that you want a function to keep track of the number of times you have called it. For this it would be easiest with some kind of persistent variable to increase each time the function is called.
This means that the first time you call the function, you need to set up that variable. All other calls should just increase it. There is a simple hack to do this

def doStuff():
  try:
    #Will throw exception if not set
    doStuff.timesUsed+=1

    ##
    #Insert stuff to do each time the function is called here
    ##
    print "Function call!"

  except AttributeError:
    doStuff.timesUsed = 0 # set up the variable

    ##
    #Put other stuff to call the first
    #time the function is called here
    ##
    print "First call!"

    doStuff() #recursive call. Will not throw exception now

Some output testing this:

>>> doStuff()
First call!
Function call!
>>> doStuff()
Function call!
>>> doStuff()
Function call!
>>> doStuff()
Function call!
>>> doStuff.timesUsed
4

buffi Programming & scripting, Python

Faking a quake terminal (like kuake / yakuake) in FVWM

December 20th, 2006

This guide assumes you have a basic understanding about configuring FVWM. You don’t need to be an expert (I’m not) but you should at least know how FvwmButton’s work.

I used KDE for a long time, and a big part of the reason for that is yakuake which is probably the best terminal available. For those who don’t know what it is, it is a terminal emulator that behaves like the quake console. That is, when you press a button it comes scrolling down/up. Very handy.

Yakuake doesn’t work very well in FVWM. It kind of works… but there are a bunch of bugs, such as text overlapping and what not.
However by editing your FVWM configuration file you can replicate the functions of yakuake rather nicely, and also add some nice extras.

The key is the Panel option in FvwmButtons. This enables you to drop down a FvwmButton from anywhere by clicking another FvwmButton. If you also would want to enabel this drop down terminal to a keyboard button, then the FakeClick method fixes that decently. It is a bit buggy if you move your mouse too much while toggling but it is good enough.

Simply create a button swallowing the terminal you want to have as a drop down console, and then make another button call the console button by Panel. Specify where it should drop down and that’s pretty much it.

Setup the button

DestroyFunc StartFunction
AddToFunc StartFunction
+ I Module FvwmButtons MenuButtons

The button calling the panel. You should add the Panel-call to any of you buttons instead of using this (but this is an example)

DestroyModuleConfig MenuButtons: *
*MenuButtons: Rows 1
*MenuButtons: Columns 1
*MenuButtons: Back black
*MenuButtons: Geometry 50x50-2-2
*MenuButtons: (1x1, Panel(down, delay 0, steps 30, position root left 0 0) \\
    SubPanel "Module FvwmButtons SubPanel")

The subpanel that holds the terminal

DestroyModuleConfig SubPanel: *
*SubPanel: Geometry 1280x350
*SubPanel: Rows 1
*SubPanel: Columns 1
*SubPanel: (1x1, Swallow(UseOld,NoHints,Respawn) "xterm" `Exec exec xterm`)

Now you have a button which you can click to get down the console holding an xterm. If you want to bind this to a button then use FakeClick like this to fool your system that you are clicking the button (ugly fix but the only one I’ve found).

The button press calls a function…

Key f12 A N press_fakebutton

The function quickly places the mouse cursor over the button, fakes a click and returns it.

DestroyFunc press_fakebutton
AddToFunc press_fakebutton
+ I SetEnv CURSOR_X $[pointer.x]
+ I SetEnv CURSOR_Y $[pointer.y]
+ I All [MenuButtons] WarpToWindow 25p 25p #middle of button
+ I FakeClick depth 0 press 1 wait 10 release 1
+ I WindowId root 1 WarpToWindow $[CURSOR_X]p $[CURSOR_Y]p

Adding styles to the SubPanel is smart. Displaying it on all pages for an example is quite nice.
Also feel free to use another terminal with tab support if you want to be able to use a tabbed console like in yakuake. Or maybe a drop down python interpreter instead? It’s of course possible to have the drop down console have more than 1 row/col and have them swallow other applications as well. The possibilities are endless ;)

Here are some screenshot of how it can look (without any style tags).
Please do not complain on this configuration as it is work in progress :)



I would love to be proven wrong and have some easier way to do this but right now this is my method of choice. Please feel free to comment.

buffi FVWM, Programming & scripting

Background image in your FvwmPager

December 19th, 2006

This guide assumes you have a basic understanding about configuring FVWM. You don’t need to be an expert (I’m not) but you should at least know a little bit about what you’re doing when configuring it. The python script will probably need some editing since it is unlikely that we have the same resolutions/number of screens so knowing a bit of python helps, but I believe that the code is rather easy to read and change. This is pretty much just a guideline for how you can solve this problem and not a finished fix/program that does it for you so prepare to get your hands dirty…

It is actually rather tricky to use your actual desktop background as a background image in the FvwmPager.
I’m gonna use my own setup as an example since it uses xinerama for two monitors, which has different resolutions making it even trickier.

First lets chose some images to use as backgrounds.
For my widescreen monitor I use this one
bg1

…and for my regular monitor I use this one
bg2

The complete background would then look like this.

(thumbnailed)

The pictures are obviously resized from their original sizes, but you get the point.
Place your background(s) in a subfolder to you fvwm-config. For an example I used ~/.fvwm/img/wallp/
Then we need to code a script that creates the background for the pager.

I chose to use a pager with a 3×3 grid of pages with size (200p,100p).
That means that the picture output of the script should look like this
grid

This means that the script should

  1. Take your background images as input
  2. Merge these into a single image with the correct dimensions
  3. Produce a grid with thumbnails of this image to use as background for your pager

I wrote a script in python to do just this. If you only use one monitor and as such one background picture you can simplify this a lot. Dependencies are python and imagemagick.

#!/usr/bin/python
"""
Script used for creating a background for FvwmPager in FVWM
Created 2006 by Bjorn Kempen
http://buffis.com
bjokem-4@student.ltu.se
"""

import os, sys

wpfolder = "/home/buffi/.fvwm/img/wallp/"
bg1,bg2=(wpfolder+sys.argv[1],wpfolder+sys.argv[2])
try:
    tmp1=open(bg1,"r") # try to open first background
    tmp2=open(bg2,"r") # try to open second background
except:
    print "ERROR! Wrong filenames: (%s,%s)"%(bg1,bg2)

bg1thumb,bg2thumb=(wpfolder+"th_"+sys.argv[1].replace("jpg","png"), \\
    wpfolder+"th_"+sys.argv[2].replace("jpg","png"))
finalname,finalthumb = (wpfolder+"bg.png",wpfolder+"th_bg.png")
gridpic = wpfolder+"grid.png"
pagerw,pagerh = 200,100 #width x height
numrows, numcols = 3,3
vborder=1 #fix for vertical borders, change to tweak thumbsize
hborder=1 #fix for horizontal borders, change to tweak thumbsize

#resolution of thumb
thumbres = "%dx%d"%(pagerw/numrows-hborder,pagerh/numcols-vborder)

#first pic for wide-screen monitor, to png and resized
os.system("convert -resize 1440x900! %s %s"%(bg1,bg1thumb))

#second pic for regular monitor, to png and resized
os.system("convert -resize 1280x1024! %s %s"%(bg2,bg2thumb))

#merge to xinerama background
os.system("convert +append %s %s %s"%(bg1thumb,bg2thumb,finalname))

#create thumbnail for use with pager
os.system("convert -resize %s! %s %s"%(thumbres,finalname,finalthumb))

#Make the final grid background
os.system("montage %s -geometry +0+0 %s"%("%s "%finalthumb*9, gridpic))

Download here!

Make sure you run this script when you change your background, or run it automagically when you start X if you’re into that kind of stuff (it will take a few seconds so I wouldn’t recommend it).

Then in you .fvwm2rc configuration, let it link your desktop background aswell as pager background to the images produced by the script.
Here is a copy+paste from my config containing these rows.

Load the background image at start/restart

# The StartFunction is used at start and restart
DestroyFunc StartFunction
AddToFunc StartFunction
...unrelated stuff...
+ I Module FvwmButtons PagerButton
+ I Exec exec fvwm-root -r ~/.fvwm/img/wallp/bg.png

Used to get 3×3 grid in pager

##### General stuff ########
DeskTopSize 3x3

Set up the background for the pager

KillModule FvwmPager
...unrelated stuff...
*FvwmPager: Pixmap ~/.fvwm/img/wallp/grid.png
...unrelated stuff...

Swallow the pager into a button

DestroyModuleConfig PagerButton: *
*PagerButton: Geometry 200x100-1-1
*PagerButton: Back black
*PagerButton: Rows 1
*PagerButton: Columns 1
*PagerButton(1x1, Frame 2, Swallow "FvwmPager" "FvwmPager 0 0")

If you know what you are doing you should end up with something similar to this very basic config of mine…


(bottom right corner)

If there are any easier way to achieve this, please drop me a comment. I might have reinvented the wheel here :)

buffi FVWM, Programming & scripting

HRAP Sanwa-mod for dummies

December 19th, 2006

So you wanna be like all the other cool dudes and have a Sanwa modded Hori Real Arcade Pro?
Nowadays everyone and their mother has a Sanwa-modded stick, but I still couldn’t find any decent guide for how to actually do it, even though it is really simple if you have any experience in the field of not being a moron.

However, if you are an American or simply just want to doublecheck that you are doing everything right, a guide would be nice so here it is.

When the stick is already open, why not also put in an octagonal gate and a new balltop? This is even easier so it shouldnt really require a guide but here it is anyways.

Step 1. Buy parts (duh)

Get the following (for each stick to mod):
8 sanwabuttons (standard size)
1 octagonal gate (optional)
1 cool new balltop (optional) (I used the mesh-thingies)

You can get these parts in Japan or on the interweb.

Step 2. Get tools

You need:
A “normalsized” starshaped screwdriver
A bolt-remover-thingie
A flat headed screwdriver (optional, but makes things easier)

If you don’t know where to get tools you shouldn’t be doing this.

Step 3. Unscrew the bottom screws

Flip the HRAP upside down and locate the 8 screws at the bottom. Unscrew all of them and remove the bottom plating. It might stick a little so you can use the flat headed screwdriver to make this easier.
You will now see a big hunk of plastic.

Step 4. Locate and unscrew bolts at the bottom

There are 6 bolts located under the screws that you can see at the top of the stick. Remove these. Remove the screws also.

Step 5. Remove cover

Turn the stick back so that it is standing correctly and you will notice that the top plate is loose. It is however still connected by wires to the PCB so just lift it up and flip it upsidedown so that you have easy access to the components.

Step 6. Remove quick connects and add new buttons

Remove the quick connects from one of the buttons by plying it of with the flat screwdriver. Remove the button from the mounting plate and snap in a new Sanwa(TM) one in its place. Then refit the quick connects on the new button.
Repeat this until all buttons are in place.

Step 7 (Optional for balltop). Change balltop

Locate the middle of the bottom of the joystick and insert your flat headed screwdriver in the flat headed screwdriver shaped area. Then hold it in position as you unscrew the balltop from the other side of the mounting plate. Then refit your new balltop and tighten it with the screwdriver.

Step 8 (Optional for octagate). Change gate

Locate the piece of plastic at the bottom of the joystick that has a squareshaped hole in it. You will se that it is fitted on there by four “levers”. Remove these piece by pulling the levers inward to get it unstuck. Then simple insert the new octagate in its place.

Step 9. Put it back together

Do steps 3-5 again but backwards.

Step 10. Enjoy!

Finally you can get the fast responses that you need in final fantasy X. Start flaming forums about how cool your stick are right away!

buffi Gaming Hardware

Putting a LS-32-01 in a Hori Real Arcade Pro 1 (old version)

December 19th, 2006

IMPORTANT!: Hori released two version of the HRAP1. Only the first one of them has the seimitsu mounting plate. Mounting a LS3201 in a “new version” HRAP1 is a lot trickier

Nowadays everyone seem to think the Sanwa is the only way to fly. Something that isn’t all that common knowledge apparently is that a lot of japanese arcade fighter cabinets uses Seimitsu joysticks instead though.

What is the difference between these sticks then you might ask?

Sanwa sticks needs to be moved a lot more to hit the microswitches which registers presses in directions, which of course doesn’t need to be a bad thing in fighters. If you prefer it that way then thats fine by me, however if you only prefer sanwa because of the fact that “everyone else is doing it” then I don’t like you :)

Something that is pretty common knowledge however is that japanese shooter cabinets usually use Seimitsu sticks. In my honest opinion Swimitsu sticks and Sanwa sticks can’t even be compared when playing shooters. Sanwa sticks are way to lose and I can’t get any feeling of control when using them for these kind of games. In other games like puzzlegames or fighters however it’s pretty even for me. Ilike both Sanwa and Seimitsu but I’m leaning more towards Seimitsu right now.

Anyways… one of the most common models of Seimitsu being used nowadays is the LS-32. The original LS-32 uses solder-on microswitches for its connection which isn’t a bad thing (soldered connections usually are better than pinconnector connections). However in this mod we are going to use the newer LS-32-01 which uses a 5pin header. The reason for this is that the stock Hori Real Arcade pro uses a Sanwa JLF-TP-8Y-SK which also use this header. This means that we can completely avoid soldering anything. There seem to be a few difference about the mounting of the sticks though, but it’s easily solvable.

Anyways, here goes…

Step 1: Buy parts

Parts needed:
1 LS-32-01
ls32

Step 2: Get tools

Tools needed:
Star shaped screwdriver or Electric Screw Fastener
Flat header screwdriver
Bolt remover thingie
Knife

Step 3. Unscrew the bottom screws

Flip the HRAP upside down and locate the 8 screws at the bottom. Unscrew all of them and remove the bottom plating. It might stick a little so you can use the flat headed screwdriver to make this easier. You will now see a big hunk of plastic.

Step 4. Locate and unscrew bolts at the bottom

There are 6 bolts located under the screws that you can see at the top of the stick. Remove these. Remove the screws also.

Step 5. Remove cover

Turn the stick back so that it is standing correctly and you will notice that the top plate is loose. It is however still connected by wires to the PCB so just lift it up and flip it upsidedown so that you have easy access to the joystick.

Step 6. Remove the balltop

Locate the middle of the bottom of the joystick and insert your flat headed screwdriver in the flat headed screwdriver shaped area. Then hold it in position as you unscrew the balltop from the other side of the mounting plate. There is also 2 plastic pieces for the joystick on the balltop. Remove these aswell.

Step 7. Remove connector

For some reason Hori decided to use a glue gun to prevent us from changing sticks. Locate the white 5-ping connector connecting the sticks with the cables from it. You will see that it is glued on. Use the knife to scrape away enough glue so that you can safely unplug the connector and the unplug it.

Step 8. Remove old joystick

The joystick is fastened with 4 screws. Remove these and then put away the old stick. You can probably sell it on ebay or something later.

Step 9. Insert Seimitsu joystick

Here is the part that can be a bit tricky. You will notice that if you try to fit the stick the same way that the Sanwa was facing with the connector in the same direction it wont fit. If you however flip it 90 degrece then it fits like a charm. Rotate the stick so that the 5pin connector is facing down on the stick (away from the autofire hole that is) and then screw it in with 1 screw each on the left and right side (yup, that will be enough)

This means that you cant simple plug in the old connector as it will be mapped wrong. The solution for this is in the next step.

Step 10. Rotate the controller PCB
Under the stick you will see a few things. First a blue plastic restrictor. Under that one a smaller blue restrictor and under that one a metal plate securing a printed circuit board containing the switches for the stick. You need to remove the restrictors, unscrew this plate and rotate the PCB so the 5pin connector socket is facing the same way that the sanwa-sticks connector was facing. Then simply plug in the connector and everything should work.

Unfortunately I can’t find my pictures of this, but it is rather straight forward.

Step 11. Test it

Put the flat plastic protector back on the top of the stick and then screw on the balltop of your choice. The plastic stick shaft protector from the sanwa won’t fit a seimitsu so just put that one aside.

Now everything should be mounted so flip the component plate back to its regular position and plug it into your ps2 to check that you made step 10 correctly. If for an example pushing up on the stick results in the ps2 registering right then just switch those cables and so on, but hopefully it should be fint. Doublechecking is always good anyways.

Step 12. Put it back together

Do step 3-5 but backwards.

Step 13. Enjoy!

Shooters might actually be playable with a stick now ;)

buffi Gaming Hardware

Blog blog blog blog

December 19th, 2006

“A blog is a user generated website where entries are made in journal style and displayed in a reverse chronological order.”
Ok then, I guess this is a blog. Wikipedia never lies.

I’ll do my best to actually posting something useful but don’t get your hopes up.

Also, since everyone else is using wordpress and I’m a huge fan of being mainstream, so will I.

buffi Uninteresting