Showing posts with label python. Show all posts
Showing posts with label python. Show all posts
13 comments Tuesday, November 20, 2007

After releasing PSP Stackless Python 2.5.1 last week, I started working on a project site to host the files, sources, documentation and issues for my Stackless Python port for the PSP.

You can reach the project here: http://pspstacklesspython.googlecode.com/

There you will find the Stackless Python 2.5.1 for PSP, now including a readme to clarify the installation and usage process, a Wiki that contains information on module usage, references to the modules ported by fraca7, build the interpreter from source, etc... I tried to condensate all information I posted on this blog to have it in one central place.

In the project page, one can create issues to report problems, feature requests and even patches to correct problems.

I created a zipped source for the last release and I`m also in process of uploading the code to the SVN repository.

I hope this makes the Stackless Python for PSP widespread and within reach of everyone, also dont forget to keep an eye on Stackless Examples Project, where you can find nice use cases for it.

Carlos

15 comments Wednesday, November 14, 2007

After working some time on it, I have updated the Stackless Python for PSP to version 2.5.1, the latest version released and made the application user mode tested on 3.71 firmware.

In this release, I have fixes the problem exiting the application (where it locked the PSP) and tested many other functionality.

Here follows changes between last version:

- The SSL has been removed for now because it was not working on latest release.
- Fixed time and datetime modules to display correct dates and times based on PSP timezones and DST.
- Fixed problems on sys and os modules
- Ported to user mode and 3.xx kernel.

I hope many people could test this release and post feedbacks about it.

The package can be downloaded from here: http://stacklesspsp.googlepages.com/StacklessPSP2.5.1_1.zip

The installation is the same, put the "python" directory on your MS root and place the EBOOT.PBP in your PSP/GAME3xx or GAME dir if you set it to run 3.xx apps.

Check my older posts about module usage and tips. Also check this video posted by Domino Man showing a simple demo provided in this zip.

Carlos

0 comments Wednesday, August 1, 2007

This morning I was delighted to see a post by Muharem Hrnjadovic post about Stackless Python. Its great to see that its usage is getting widespread and its benefits demonstrated and shown to everyone.

I'm telling this because some time ago I started to play with Erlang and liked it a lot. Because of work issues I didn't have enough time to keep my studies (I plan to buy Joe Armstrong's book) but I found it a great language and with its focus on parallel processing made me think about a comparison with Stackless.

For my surprise, it happened today on Muharen's post. He did a great job creating both apps and comparing them even with graphics demonstrating the results. It showed that Stackless is great for the job and should be considered for a lot more projects than it is now.

For more information on Stackless visit www.stackless.com, the Stackless mailing list or the Stackless Examples project hosted on http://code.google.com/p/stacklessexamples/ where we have an increasing number of samples and day to day use cases.

8 comments Monday, July 2, 2007

As the time goes by, a lot of progress has been made in my Stackless port for the Sony PSP.

Here I will list everything that changed since the last published archive:

  • Time function returns correct date based on PSP Timezone
  • OGG Vorbis support
    • I have added a basic OGG Vorbis support for the port. The API is based on oggplayer from PSPMediaCenter. The problem is that i loads the entire file into memory and playbacks it from there. On MP3 this doesnt happens.. more below.
    • The API for the OGG is very simple, a sample application follows at the end of the post.
  • MP3 Support
    • Its here! With the great help from Ghoti (thanks Rein) the MP3 streaming playback is now available transparently. What streaming means? Your application wont load the entire file into memory for playback. The application creates a buffer and loads small chunks from disk as needed. This leaves a lot of memory to the interpreter and you play with. In my tests, my interpreter have around 18Mb RAM available.
    • A small demo is in the bottom of this post.
  • SSL Support
    • This is the latest addition. Since I cant test all its functionality, I need someone to test it for me. I made a small test where a import socket; hasattr(socket, "ssl")returned "True" so I assumed everything was fine.
All this progress couldn't be made without the help of a lot of people. Jerome for its awesome Python port, Jim for his oggplayer and mp3player libraries based on libTremor and libMad. Ghoti for the MP3 streaming support and all guys that ported the libraries to PSP.

Now I will start tracking the released versions using my own version numbers after a _ character.

This new release is named: PSP-Stackless-2.4.4_1.zip and can be downloaded here.

Here are some example apps:

OGG Playback:

import pspogg, psp2d

pspogg.init(2)
pspogg.load('REALTEST.OGG')

pspogg.play()

while 1:
pad = psp2d.Controller()
if pspogg.endofstream() == 1 or pad.cross:
print pspogg.getsec()
print "end of stream"
pspogg.end()
break

print "exit"

MP3 Playback:

import pspmp3, psp2d

pspmp3.init(1)
pspmp3.load('test.mp3')
pspmp3.play()

while 1:
global lastPad
pad = psp2d.Controller()
if pspmp3.endofstream() == 1 or pad.cross:
print pspmp3.gettime()
pspmp3.end()
break

print "exit"

SSL Support:

import socket
print hasattr(socket, "ssl")


The modules have the following API:

pspogg

pspogg.init(ch) Initializes the OGGVorbis subsystem.
pspogg.load(file) Loads an OGG file.
pspogg.stop() Stop OGG playback.
pspogg.pause() Pauses OGG playback, call again to unpause.
pspogg.play() Play a loaded OGG file.
pspogg.endofstream() Returns 1 if stream has ended.
pspogg.getsec() Returns the stream play time in seconds.
pspogg.getmin() Returns the stream play time in minutes.
pspogg.gethour() Returns the stream play time in hours.
pspogg.volume(vol) Sets the OGG subsystem volume.
pspogg.end() Stops playback and free up used memory.

pspmp3

pspmp3.init(ch) Initializes the MP3 subsystem.
pspmp3.load(file) Loads a MP3 file.
pspmp3.stop() Stop MP3 playback.
pspmp3.pause() Pauses MP3 playback, call again to unpause.
pspmp3.play() Play a loaded MP3 file.
pspmp3.endofstream() Returns 1 if stream has ended.
pspmp3.gettime() Returns the stream play time in format HH:MM:SS.
pspmp3.freetune() Free up used memory and releases MP3 subsystem.
pspmp3.end() Stops playback and calls freetune.

Carlos
carlosedp+themindcaster@gmail.com

2 comments Monday, June 25, 2007

As promised, today I will start a series of small tutorials for the Stackless usage.

The examples will be focused on PSP but they can all be implemented for Pygame, just switch the graphic functions in psp2d.

A great package that helps a lot the development is the psp mockup libraries. They mimic the psp2d module and translates them to Pygame. With an installation of Python and Pygame you can test all your programs in PC before putting them in the PSP.

Well, lets start the tutorial, the code is very documented and can be easily understood, if you have any questions, contact me over the commentaries or my email - carlosedp+themindcaster at gmail.com

The full code package can be downloaded here.

The Stackless for PSP can be downloaded here.

# -*- coding: iso-8859-1 -*-

'''
This is an example on using Stackless Python in PSP. The idea is based on a
tutorial created by Sakya.

Here we have the concept of agent based programming where the player, the NPC
and the render engine as an agent doing its actions.

The player agent waits for the user input captured from the keypad.

The NPC agent starts running aroundn the screen in a predefined pattern.

The render engine does all the drawing job clearing the screen and putting each
agent in its own place.

As you can see, all the logic is very simplified because of the flexibility
stackless gives to us. Every agent can have its own behaviour and optionally
follow some "world" rules defined for example in a separate Agent.

This "World" could detect collisions, handle communications between agents and
interact with other elements. This can be an exercise to the user.

'''
import psp2d, pspos
from time import time
import sys
import stackless

# Set processor and bus speed
pspos.setclock(222)
pspos.setbus(111)

# Creates the screen and its background color (Black)
screen = psp2d.Screen()
screen.clear(psp2d.Color(0,0,0,255))

# Loads the font
font = psp2d.Font('font.png')

# Loads the character movement images
spriteImages = []
spriteImages.append((psp2d.Image('amg1_bk1.png'), psp2d.Image('amg1_bk2.png'))) #Direction = north = 0
spriteImages.append((psp2d.Image('amg1_fr1.png'), psp2d.Image('amg1_fr2.png'))) #Direction = south = 1
spriteImages.append((psp2d.Image('amg1_lf1.png'), psp2d.Image('amg1_lf2.png'))) #Direction = west = 2
spriteImages.append((psp2d.Image('amg1_rt1.png'), psp2d.Image('amg1_rt2.png'))) #Direction = east = 3


# Creates the Agent base class
class Agent(object):
def __init__(self):
self.ch = stackless.channel() # Communication channel (not used here)
self.running = True # Flag to control the running status
stackless.tasklet(self.runAction)() # Creates the agent tasklet

def runAction(self):
# Here we define the main action, a repetition of the function self.action()
while self.running:
# Runs the action
self.action()
# Give other tasklets its turn
stackless.schedule()

def action(self):
# In the base class do nothing
pass

class player(Agent):
def __init__(self, rend):
Agent.__init__(self)
self.rend = rend # Reference to the renderer tasklet
self.boolSprite = False
self.direction = 1
self.speed = 3
self.posX = 30
self.posY = 30
self.lastPad = time()
self.rend.agents.append(self) # Adds this agent to the renderer
self.sprite = spriteImages[self.direction][int(self.boolSprite)]

def action(self):
self.sprite = spriteImages[self.direction][int(self.boolSprite)]
pad = psp2d.Controller()
if pad.cross:
print "exit"
self.rend.exit()
elif pad.triangle:
screen.saveToFile("ms0:/PSP/PHOTO/screenshot.png")
elif pad.down and (not self.lastPad or time() - self.lastPad >= 0.05):
#Draw the player facing south:
self.lastPad = time()
self.direction = 1
if self.posY + self.sprite.height + self.speed <>
self.posY += self.speed
self.boolSprite = not self.boolSprite
elif pad.up and (not self.lastPad or time() - self.lastPad >= 0.05):
#Draw the player facing north:
self.lastPad = time()
self.direction = 0
if self.posY - self.speed >= 0:
self.posY -= self.speed
self.boolSprite = not self.boolSprite
elif pad.left and (not self.lastPad or time() - self.lastPad >= 0.05):
#Draw the player facing west:
self.lastPad = time()
self.direction = 2
if self.posX - self.speed >= 0:
self.posX -= self.speed
self.boolSprite = not self.boolSprite
elif pad.right and (not self.lastPad or time() - self.lastPad >= 0.05):
#Draw the player facing east:
self.lastPad = time()
self.direction = 3
if self.posX + self.sprite.width + self.speed <>
self.posX += self.speed
self.boolSprite = not self.boolSprite

class NPC(Agent):
def __init__(self, rend):
Agent.__init__(self)
self.rend = rend
self.boolSprite = False
self.direction = 0
self.speed = 5
self.posX = 230
self.posY = 230
self.lastPad = time()
self.rend.agents.append(self)
self.sprite = spriteImages[self.direction][int(self.boolSprite)]
self.count = 20

def action(self):
# This NPC runs around the screen changing its direction when touches the border.
self.sprite = spriteImages[self.direction][int(self.boolSprite)]
if self.direction == 0 and (not self.lastPad or time() - self.lastPad >= 0.05):
self.lastPad = time()
if self.posY - self.speed >= 20:
self.posY -= self.speed
self.boolSprite = not self.boolSprite
else:
self.direction = 2
if self.direction == 2 and (not self.lastPad or time() - self.lastPad >= 0.05):
self.lastPad = time()
if self.posX - self.speed > 0:
self.posX -= self.speed
self.boolSprite = not self.boolSprite
else:
self.direction = 1
if self.direction == 1 and (not self.lastPad or time() - self.lastPad >= 0.05):
self.lastPad = time()
if self.posY + self.sprite.height + self.speed <>
self.posY += self.speed
self.boolSprite = not self.boolSprite
else:
self.direction = 3
if self.direction == 3 and (not self.lastPad or time() - self.lastPad >= 0.05):
self.lastPad = time()
if self.posX + self.sprite.width + self.speed <>
self.posX += self.speed
self.boolSprite = not self.boolSprite
else:
self.direction = 0


class render(Agent):
# This is the renderer agent
def __init__(self):
Agent.__init__(self)
self.agents = []

def exit(self):
# When the player calls the exit, tell all Agents to stop running
for agent in self.agents:
agent.running = False
self.running = False

def action(self):
# Each frame the renderer clears the screen, writes the text and draws each
# registered agent.
screen.clear(psp2d.Color(0,0,0,255))
font.drawText(screen, 10, 225, "Move your character with directional")
font.drawText(screen, 10, 240, "Triangle takes screenshot")
font.drawText(screen, 10, 255, "Press X to exit")
for agent in self.agents:
screen.blit(agent.sprite, 0, 0, agent.sprite.width, agent.sprite.height, agent.posX, agent.posY, True)
screen.swap()


# Creates the renderer object
rend = render()
# Creates a player Agent
play = player(rend)
# Creates one NPC that runs around the screen
NPC1 = NPC(rend)

# Starts the game loop
stackless.run()





13 comments Monday, June 18, 2007

About 3 weeks ago, I got a Sony PSP, since only playing games isnt enought for me, I started fiddling around for so called "Homebrew" software for it.

The homebrew community for PSP is quite big and mostly around C coding but surprisingly I found that a guy named Jerome made Python-psp, awesome port of Python 2.4.3 and PSP graphic, sound and network API to Python modules.

Based on that and my bare knowledge of C, I decided to start working on a Stackless Python port for it.

I recently saw the great work from Richard Tew in porting Stackless to Nintendo DS and decided to give a try. Checked out the 2.4.3 PSP port from python-psp repository and merged the Stackless 2.4.4 tag into it.

The first thing to be done, was fixing up some conflicts mostly related to IO and threads. Next Richard pointed me out that the Stackless needs to save and restore stack pointers and this is done in assembly.

Based on trial and error, it took me a day to figure out and have a compiled interpreter.

To finish it all, I ran the stackless unittests and some Stackless applications from the Stackless Examples Project and found that its all working.

I hope other people could try it out and maybe find some bugs, probably I will make the source available and the diff patches too.

The next thing in my roadmap is porting Python and Stackless Python 2.5.1 to PSP, hope it wont be much trouble.

The download is temporarily stored on Stackless Examples project. As soon as I decide to host it or anyone else do, it will be here:

http://stacklessexamples.googlecode.com/files/PSP-Stackless-2.4.4.zip

To install just create a folder in your /PSP/GAME150 folder and place the EBOOT.PBP there.
The python folder is the libraries and must be placed on your memory stick root.

For more information check the Python-psp page.

Thanks a lot for Jerome for the amazing work on the Python port and Richard Tew for the Stackless porting!

Any questions contact me directly.

4 comments Tuesday, May 22, 2007

In the last days, i've been committed to learn C++ so I can port performance critical methods in my Python apps to it. I found a great site - www.cplusplus.com with a nice tutorial worth a look.

I started reading thru a lot of documentation on how to create Python C modules but all those PyObjects and all made a mess in my head.

Looking in the Python-Ogre (Python bindings for the wonderful Ogre3D engine), I found that they use a new code generator for boost-python called Py++.

I heard a lot about boost and its qualities so I figured out that this was the best option and with Py++ to create the wrapper files it became easier.

The problem was not how to create the wrapper files and generate the modules but and install that bunch of packages and modules on windows was a pain.

What you will need:

- Compiler (I'm using VS2005 Express since its free)
- Platform SDK R2 (Windows headers)
- Python (Of course...)
- 2 eggs ... oops... forget this one
- Boost installer for Windows Easier to install, better than compile yourself.
- GCC-XML
- Pygccxml

The resumed installation procedure is:

- Install the compiler and the platform SDK
- Configure your compiler to use the 'libs', 'includes' and 'bins' from the SDK
- Configure the vcvars32.bat file to add the SDK paths to it so the Compile console finds the headers.
- Run the boost installer, it will download the needed packages from a mirror. I installed the base packages and the Python lib.
- Unpack and run 'python setup.py install' on GCC-XML. In my case, it have not compiled with VC2005 so I unpacked myself and followed the instructions here. Then I compiled using the generated solution file.
- Install the pygccxml package 'python setup.py build install'
- Install the py++ package 'python setup.py build install'

Thats it for now... in my next post I will post some examples and procedures for generating the C++ modules.

0 comments Friday, May 11, 2007

Reading a post from a Planet PythonBrasil blog today, our friend Rodrigo Cacilhas has proposed some approaches on the Oddwords puzzle where the objective is to invert the odd words in a phrase.

The post can be seen here: http://kodumaro.blogspot.com/2007/05/oddwording.html

I created a small solution based on list comprehension and the and-or trick. It´s like this:

text= "abc def ghi"

print " ".join([(x%2 == 0 and y or y[::-1]) for x,y in enumerate(text.split())])

It shows how powerful list comprehensions can be.