hello ,

Here's the "lost" app : Tetris (only release with some alpha py_s60 version

Code:
import appuifw
from graphics import *
import e32
import random
import time
from key_codes import *

appuifw.app.screen='full'
backup_img=Image.new((176,208))
draw=Draw(backup_img)

def handle_redraw(param):
    canvas_draw.blit(backup_img)

class Keyboard(object):
    def __init__(self,onevent=lambda:None):
        self._keyboard_state={}
        self._downs={}
        self._onevent=onevent
    def handle_event(self,event):
        if event['type'] == appuifw.EEventKeyDown:
            cod=event['scancode']
            if not self.is_down(cod):
                self._downs[cod]=self._downs.get(cod,0)+1
            self._keyboard_state[cod]=1
        elif event['type'] == appuifw.EEventKeyUp:
            self._keyboard_state[event['scancode']]=0
        self._onevent()
    def is_down(self,scancode):
        return self._keyboard_state.get(scancode,0)
    def pressed(self,scancode):
        if self._downs.get(scancode,0):
            self._downs[scancode]-=1
            return True
        return False

running=1
def quit():
    global running
    running=0
appuifw.app.exit_key_handler=quit


class Playfield(object):
    def __init__(self,size,draw,bordercolor=0xc0c0c0):
        self._data={}
        self._size=size
        self._draw=draw
        for x in range(0,size[0]):
            for y in range(0,size[1]):
                self[(x,y)]=0
        # Initialize playing field borders
        for y in range(-1,size[1]+1):
            self[(-1,y)]=bordercolor
            self[(size[0],y)]=bordercolor
        for x in range(-1,size[0]+1):
            self[(x,-1)]=bordercolor
            self[(x,size[1])]=bordercolor
        self.draw()
    def __getitem__(self,loc):
        return self._data.setdefault(tuple(loc),0)
    def __setitem__(self,loc,value):
        self._data[loc]=value
        self.update_loc(loc)
    def remove_row(self,row):
        for x in range(0,self._size[0]):
            self[(x,0)]=0
        for y in range(row,0,-1):
            for x in range(0,self._size[0]):
                self[(x,y)]=self[(x,y-1)]
    def row_is_full(self,row):
        for x in range(0,self._size[0]):
            if not self[(x,row)]:
                return False
        return True
    def update_loc(self,loc):
        w=8
        x,y=((loc[0]+1)*w,(loc[1]+1)*w)
        self._draw.rectangle((x,y,x+w,y+w),None,self[loc])
    def draw(self):
        w=8
        for loc in self._data:
            self.update_loc(loc)
# with draw.rectangle((x,y,x+w,y+w),fill=self[loc]) 472 ms
# without 89 ms
# draw.rectangle((x,y,x+w,y+w),fill=0xff0000,outline=0x00ff00) 375 ms
# draw.rectangle((x,y,x+w,y+w)) without params setting, kw parsing 125 ms

class Piece(object):
    def __init__(self,squares,color):
        self._squares=squares
        self._color=color
    def fits_in(self,loc,angle,field):
        for s in self._squares[angle]:
            if field[(s[0]+loc[0],s[1]+loc[1])]:
                return False
        return True
    def put_to(self,loc,angle,field):
        for s in self._squares[angle]:
            field[(s[0]+loc[0],s[1]+loc[1])]=self._color
    def remove_from(self,loc,angle,field):
        for s in self._squares[angle]:
            field[(s[0]+loc[0],s[1]+loc[1])]=0
    
pieces=(
    Piece({0: ((1,0),(0,1),(1,1),(2,1)), # _|_ block
           1: ((1,0),(1,1),(2,1),(1,2)), 
           2: ((0,1),(1,1),(2,1),(1,2)),
           3: ((1,0),(0,1),(1,1),(1,2))}, 0x808080),
    Piece({0: ((1,0),(1,1),(1,2),(1,3)), # ---- block
           1: ((0,1),(1,1),(2,1),(3,1)),
           2: ((1,0),(1,1),(1,2),(1,3)),  
           3: ((0,1),(1,1),(2,1),(3,1))}, 0xff0000),
    Piece({0: ((0,0),(1,0),(0,1),(1,1)), # square block
           1: ((0,0),(1,0),(0,1),(1,1)),
           2: ((0,0),(1,0),(0,1),(1,1)),
           3: ((0,0),(1,0),(0,1),(1,1))}, 0x00ffff),
    Piece({0: ((0,0),(1,0),(1,1),(2,1)), # -_ block
           1: ((2,0),(1,1),(2,1),(1,2)),
           2: ((0,0),(1,0),(1,1),(2,1)),
           3: ((2,0),(1,1),(2,1),(1,2))}, 0x00ff00),
    Piece({0: ((1,0),(2,0),(0,1),(1,1)), # _- block
           1: ((0,0),(0,1),(1,1),(1,2)),
           2: ((1,0),(2,0),(0,1),(1,1)), 
           3: ((0,0),(0,1),(1,1),(1,2))}, 0xff8000),
    Piece({0: ((1,0),(1,1),(1,2),(2,2)), # L-block 
           1: ((1,1),(2,1),(3,1),(1,2)),
           2: ((1,1),(2,1),(2,2),(2,3)),
           3: ((2,1),(0,2),(1,2),(2,2))}, 0x0080ff),
    Piece({0: ((2,0),(2,1),(2,2),(1,2)), # J-block 
           1: ((1,1),(1,2),(2,2),(3,2)),
           2: ((1,1),(2,1),(1,2),(1,3)),
           3: ((0,1),(1,1),(2,1),(2,2))}, 0xffff00))


lock=e32.Ao_lock()
keyboard=Keyboard(onevent=lock.signal)
canvas=appuifw.Canvas(event_callback=keyboard.handle_event,
                      redraw_callback=handle_redraw)
canvas_draw=Draw(canvas)
appuifw.app.body=canvas
draw_time=0
draw_count=0
fieldsize=(10,20)
playing=1
def draw_score(draw):
    draw.rectangle((102,6,169,31),None,0x103010)
    draw.text((107,26),u'Lines: %d'%lines,0xc0ffc0,font=u'LatinBold19')
    draw.rectangle((102,31,169,56),None,0x103010)
    draw.text((107,51),u'Level: %d'%level,0xc0ffc0,font=u'LatinBold19')

try:
    logo=Image.open(u'e:\\system\\apps\\python\\pythonpowered.png')
except:
    logo=Image.new((100,16))
    drl=Draw(logo)
    drl.clear(0)

while playing:
    lines=0
    level=1
    x,y=3,0
    angle=0
    piece=pieces[random.randint(0,len(pieces)-1)]
    drop_interval=0.5
    draw.clear(0x000000)
    draw.blit(logo,target=(106,100))
    draw_score(draw)
    field=Playfield(fieldsize,draw)
    previous_drop=time.clock()
    e32.ao_sleep(drop_interval,lock.signal)
    running=1
    while running:
        piece.remove_from((x,y),angle,field)
        while keyboard.pressed(EScancodeLeftArrow) and piece.fits_in((x-1,y),angle,field):
            x-=1
            lock.signal()
        while keyboard.pressed(EScancodeRightArrow) and piece.fits_in((x+1,y),angle,field):
            x+=1
            lock.signal()
        while keyboard.pressed(EScancodeUpArrow) and piece.fits_in((x,y),(angle-1)%4,field):
            angle=(angle-1)%4    
        if keyboard.pressed(EScancodeDownArrow):
            while piece.fits_in((x,y+1),angle,field):
                y+=1
        if time.clock()-previous_drop >= drop_interval:
            if piece.fits_in((x,y+1),angle,field):
                y+=1
            else:
                piece.put_to((x,y),angle,field)
                removed_lines=0
                for y in range(fieldsize[1]):
                    if field.row_is_full(y):
                        field.remove_row(y)
                        removed_lines += 1
                if removed_lines:
                    lines += removed_lines
                    level=int(lines/10)+1
                    drop_interval=0.5*(0.85**(level-1))
                    draw_score(draw)
                x,y=3,0
                angle=0
                piece=pieces[random.randint(0,len(pieces)-1)]
                if not piece.fits_in((x,y),angle,field):
                    appuifw.note(u'Game over!','info')
                    running=0
            previous_drop=time.clock()
            e32.ao_sleep(drop_interval,lock.signal)            
        piece.put_to((x,y),angle,field)
        start_draw=time.clock()
        handle_redraw(())
        end_draw=time.clock()
        draw_time += end_draw-start_draw
        draw_count += 1
        e32.ao_yield()
        lock.wait()
    playing=appuifw.query(u'Play again?','query')
    
print "%d draws, %f s total, avg time %f ms"%(draw_count,
                                              draw_time,
                                              draw_time/draw_count*1000)
appuifw.app.screen='normal'

For saad

PS : only change is code var name change ! It becomes cod var for code tag problems