Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodrigo Perez Fulloni <rodripf@gmail.com>2012-12-17 22:24:44 (GMT)
committer Rodrigo Perez Fulloni <rodripf@gmail.com>2012-12-17 22:24:44 (GMT)
commitf891b3a18c952b88967f7408bb942ef3c0cd111f (patch)
tree2a746cb54bdc837a892f908c85599fed7e103300
Final version 1.0HEADmaster
-rw-r--r--QR.pngbin0 -> 26250 bytes
-rw-r--r--Ropa.pngbin0 -> 663006 bytes
-rw-r--r--nbproject/private/private.properties0
-rw-r--r--nbproject/private/private.xml4
-rw-r--r--nbproject/project.properties5
-rw-r--r--nbproject/project.xml13
-rw-r--r--src/QueViaje.py221
-rw-r--r--src/QueViaje.pyobin0 -> 7969 bytes
-rw-r--r--src/SugarBar.py89
-rw-r--r--src/SugarBar.py.bakbin0 -> 1836 bytes
-rw-r--r--src/SugarBar.pyobin0 -> 3244 bytes
-rw-r--r--src/activity/activity-QueViaje.svg98
-rw-r--r--src/activity/activity.info8
-rw-r--r--src/audio/acierto.oggbin0 -> 30602 bytes
-rw-r--r--src/audio/error.oggbin0 -> 24942 bytes
-rw-r--r--src/audio/fondo.oggbin0 -> 2258533 bytes
-rw-r--r--src/audio/pasarPantalla.oggbin0 -> 93665 bytes
-rw-r--r--src/audio/victoria.oggbin0 -> 85135 bytes
-rw-r--r--src/carteles/Presentacion.pngbin0 -> 17647 bytes
-rw-r--r--src/carteles/bien.pngbin0 -> 331329 bytes
-rw-r--r--src/carteles/conoces_este_lugar.pngbin0 -> 7366 bytes
-rw-r--r--src/carteles/ganaste.pngbin0 -> 377460 bytes
-rw-r--r--src/carteles/genial.pngbin0 -> 413068 bytes
-rw-r--r--src/carteles/info_ciudad.pngbin0 -> 29421 bytes
-rw-r--r--src/carteles/info_nieve.pngbin0 -> 32315 bytes
-rw-r--r--src/carteles/info_verano.pngbin0 -> 52841 bytes
-rw-r--r--src/carteles/que_objeto_llevarias.pngbin0 -> 9417 bytes
-rw-r--r--src/carteles/que_te_pondrias_en_las_piernas.pngbin0 -> 20583 bytes
-rw-r--r--src/carteles/que_te_pondrias_en_los_pies.pngbin0 -> 28089 bytes
-rw-r--r--src/carteles/que_te_pondrias_para_ir_a_este_lugar.pngbin0 -> 17215 bytes
-rw-r--r--src/carteles/te_parece_que_hace_frio_o_calor.pngbin0 -> 13888 bytes
-rw-r--r--src/cosas/biquini.jpgbin0 -> 35709 bytes
-rw-r--r--src/cosas/botas.jpgbin0 -> 15371 bytes
-rw-r--r--src/cosas/buzo.jpgbin0 -> 22843 bytes
-rw-r--r--src/cosas/camisa.jpgbin0 -> 21597 bytes
-rw-r--r--src/cosas/championes.jpgbin0 -> 14092 bytes
-rw-r--r--src/cosas/chancletas.jpgbin0 -> 23343 bytes
-rw-r--r--src/cosas/gorrolana.jpgbin0 -> 47275 bytes
-rw-r--r--src/cosas/gorrosol.jpgbin0 -> 32148 bytes
-rw-r--r--src/cosas/jeans.jpgbin0 -> 21001 bytes
-rw-r--r--src/cosas/lentes.jpgbin0 -> 6960 bytes
-rw-r--r--src/cosas/paraguas.jpgbin0 -> 10660 bytes
-rw-r--r--src/cosas/short.jpgbin0 -> 31523 bytes
-rw-r--r--src/cosas/sombrero.JPGbin0 -> 10556 bytes
-rw-r--r--src/cosas/vestido.jpgbin0 -> 7163 bytes
-rw-r--r--src/cosas/zapatos.jpgbin0 -> 9093 bytes
-rw-r--r--src/data/__init__.py2
-rw-r--r--src/data/__init__.pyobin0 -> 213 bytes
-rw-r--r--src/data/ciudad.py11
-rw-r--r--src/data/ciudad.pyobin0 -> 828 bytes
-rw-r--r--src/data/lugar.py43
-rw-r--r--src/data/lugar.pyobin0 -> 1599 bytes
-rw-r--r--src/data/lugar.py~26
-rw-r--r--src/data/nieve.py8
-rw-r--r--src/data/nieve.pyobin0 -> 799 bytes
-rw-r--r--src/data/playa.py15
-rw-r--r--src/data/playa.pyobin0 -> 922 bytes
-rw-r--r--src/dist/QueViaje-1.xobin0 -> 6516027 bytes
-rw-r--r--src/libzbar.abin0 -> 812362 bytes
-rw-r--r--src/libzbar.la41
-rw-r--r--src/libzbar.so.0.2.0bin0 -> 589669 bytes
-rw-r--r--src/lugares/ciudad.jpgbin0 -> 303593 bytes
-rw-r--r--src/lugares/nieve.jpgbin0 -> 214898 bytes
-rw-r--r--src/lugares/playa.jpgbin0 -> 263991 bytes
-rw-r--r--src/pygame/.gitignore1
-rw-r--r--src/pygame/LGPL504
-rw-r--r--src/pygame/__init__.py304
-rw-r--r--src/pygame/__init__.pyobin0 -> 8639 bytes
-rw-r--r--src/pygame/_arraysurfarray.sobin0 -> 29399 bytes
-rw-r--r--src/pygame/_camera.sobin0 -> 88422 bytes
-rw-r--r--src/pygame/_camera_opencv_highgui.py98
-rw-r--r--src/pygame/_camera_vidcapture.py133
-rw-r--r--src/pygame/_numericsndarray.sobin0 -> 21944 bytes
-rw-r--r--src/pygame/_numericsurfarray.sobin0 -> 47321 bytes
-rw-r--r--src/pygame/_numpysndarray.py136
-rw-r--r--src/pygame/_numpysndarray.pyobin0 -> 2373 bytes
-rw-r--r--src/pygame/_numpysurfarray.py472
-rw-r--r--src/pygame/_numpysurfarray.pyobin0 -> 8748 bytes
-rw-r--r--src/pygame/base.sobin0 -> 35178 bytes
-rw-r--r--src/pygame/bufferproxy.sobin0 -> 21137 bytes
-rw-r--r--src/pygame/camera.py144
-rw-r--r--src/pygame/camera.pyobin0 -> 3375 bytes
-rw-r--r--src/pygame/cdrom.sobin0 -> 34874 bytes
-rw-r--r--src/pygame/color.sobin0 -> 62420 bytes
-rw-r--r--src/pygame/colordict.py679
-rw-r--r--src/pygame/colordict.pyobin0 -> 32391 bytes
-rw-r--r--src/pygame/compat.py47
-rw-r--r--src/pygame/compat.pyobin0 -> 1333 bytes
-rw-r--r--src/pygame/constants.sobin0 -> 30261 bytes
-rw-r--r--src/pygame/cursors.py300
-rw-r--r--src/pygame/cursors.pyobin0 -> 9267 bytes
-rw-r--r--src/pygame/display.sobin0 -> 53669 bytes
-rw-r--r--src/pygame/draw.sobin0 -> 85931 bytes
-rw-r--r--src/pygame/event.sobin0 -> 60238 bytes
-rw-r--r--src/pygame/fastevent.sobin0 -> 40849 bytes
-rw-r--r--src/pygame/freesansbold.ttfbin0 -> 98600 bytes
-rw-r--r--src/pygame/gfxdraw.sobin0 -> 160574 bytes
-rw-r--r--src/pygame/gp2x/.gitignore1
-rw-r--r--src/pygame/gp2x/__init__.py24
-rw-r--r--src/pygame/gp2x/constants.py21
-rw-r--r--src/pygame/gp2x/locals.py3
-rw-r--r--src/pygame/image.sobin0 -> 51718 bytes
-rw-r--r--src/pygame/imageext.sobin0 -> 47485 bytes
-rw-r--r--src/pygame/joystick.sobin0 -> 30490 bytes
-rw-r--r--src/pygame/key.sobin0 -> 19500 bytes
-rw-r--r--src/pygame/locals.py30
-rw-r--r--src/pygame/locals.pyobin0 -> 298 bytes
-rw-r--r--src/pygame/mac_scrap.py139
-rw-r--r--src/pygame/macosx.py28
-rw-r--r--src/pygame/mask.sobin0 -> 81716 bytes
-rw-r--r--src/pygame/midi.py615
-rw-r--r--src/pygame/mixer.sobin0 -> 61943 bytes
-rw-r--r--src/pygame/mixer_music.sobin0 -> 37548 bytes
-rw-r--r--src/pygame/mouse.sobin0 -> 23052 bytes
-rw-r--r--src/pygame/overlay.sobin0 -> 22186 bytes
-rw-r--r--src/pygame/pixelarray.sobin0 -> 85072 bytes
-rw-r--r--src/pygame/pkgdata.py66
-rw-r--r--src/pygame/pkgdata.pyobin0 -> 1516 bytes
-rw-r--r--src/pygame/pygame.icobin0 -> 1078 bytes
-rw-r--r--src/pygame/pygame_icon.bmpbin0 -> 630 bytes
-rw-r--r--src/pygame/pygame_icon.icnsbin0 -> 53627 bytes
-rw-r--r--src/pygame/pygame_icon.svg259
-rw-r--r--src/pygame/pygame_icon.tiffbin0 -> 61604 bytes
-rw-r--r--src/pygame/rect.sobin0 -> 66530 bytes
-rw-r--r--src/pygame/rwobject.sobin0 -> 28452 bytes
-rw-r--r--src/pygame/scrap.sobin0 -> 57520 bytes
-rw-r--r--src/pygame/sndarray.py187
-rw-r--r--src/pygame/sndarray.pyobin0 -> 2460 bytes
-rw-r--r--src/pygame/sprite.py1423
-rw-r--r--src/pygame/sprite.pyobin0 -> 27909 bytes
-rw-r--r--src/pygame/surface.sobin0 -> 435447 bytes
-rw-r--r--src/pygame/surfarray.py340
-rw-r--r--src/pygame/surfarray.pyobin0 -> 4356 bytes
-rw-r--r--src/pygame/surflock.sobin0 -> 21785 bytes
-rw-r--r--src/pygame/sysfont.py633
-rw-r--r--src/pygame/threads/.gitignore1
-rw-r--r--src/pygame/threads/Py25Queue.py216
-rw-r--r--src/pygame/threads/__init__.py310
-rw-r--r--src/pygame/threads/__init__.pyobin0 -> 6340 bytes
-rw-r--r--src/pygame/time.sobin0 -> 34279 bytes
-rw-r--r--src/pygame/transform.sobin0 -> 111014 bytes
-rw-r--r--src/pygame/version.py31
-rw-r--r--src/pygame/version.pyobin0 -> 214 bytes
-rw-r--r--src/setup.py3
-rw-r--r--src/sugargame/__init__.py1
-rw-r--r--src/sugargame/__init__.pyobin0 -> 168 bytes
-rw-r--r--src/sugargame/canvas.py62
-rw-r--r--src/sugargame/canvas.pyobin0 -> 1856 bytes
-rw-r--r--src/sugargame/event.py243
-rw-r--r--src/sugargame/event.pyobin0 -> 9346 bytes
-rw-r--r--src/zbar.sobin0 -> 155933 bytes
151 files changed, 8038 insertions, 0 deletions
diff --git a/QR.png b/QR.png
new file mode 100644
index 0000000..021bdfe
--- /dev/null
+++ b/QR.png
Binary files differ
diff --git a/Ropa.png b/Ropa.png
new file mode 100644
index 0000000..5fbaf39
--- /dev/null
+++ b/Ropa.png
Binary files differ
diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nbproject/private/private.properties
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
new file mode 100644
index 0000000..c1f155a
--- /dev/null
+++ b/nbproject/private/private.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..66119ee
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,5 @@
+java.lib.path=
+main.file=queviaje.py
+platform.active=Python_2.6.6
+python.lib.path=
+src.dir=src
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..506961d
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.python.project</type>
+ <configuration>
+ <data xmlns="http://nbpython.dev.java.net/ns/php-project/1">
+ <name>QueViaje</name>
+ <sources>
+ <root id="src.dir"/>
+ </sources>
+ <tests/>
+ </data>
+ </configuration>
+</project>
diff --git a/src/QueViaje.py b/src/QueViaje.py
new file mode 100644
index 0000000..64ca694
--- /dev/null
+++ b/src/QueViaje.py
@@ -0,0 +1,221 @@
+# -*- coding: utf-8 -*-
+
+__author__ = "rodripf"
+__date__ = "$17/10/2012 10:30:27 AM$"
+
+import sys
+sys.path.insert(0,"/home/olpc/Activities/QueViaje.activity")
+
+import pygame.camera
+
+import pygame
+from pygame.locals import *
+pygame.init()
+
+pygame.mixer.init()
+
+import os
+import random
+from SugarBar import SugarBar
+
+from threading import Timer
+
+from data.playa import Playa
+from data.ciudad import Ciudad
+from data.nieve import Nieve
+
+from sugar.activity import activity
+import sugargame.canvas
+
+class QueViaje(activity.Activity):
+ RESOLUCION = (1200, 900)
+ ACIERTOS_PARA_GANAR = 3
+ LUGAR_MUESTRA = (10,10)
+
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+
+ self.camara = True
+ self.mostrandoPista = False
+ self.mostrandoInfo = False
+ self.mostrandoPresentacion = False
+
+ self.cosas = [] #cosas que se estan mostrando
+ self.sb = SugarBar();
+
+ self.puntos = 0 #numero de aciertos
+ self.nivel = 0
+
+ self.sonidoError = pygame.mixer.Sound("audio/error.ogg")
+ self.sonidoAcierto = pygame.mixer.Sound("audio/acierto.ogg")
+ self.sonidoVictoria = pygame.mixer.Sound("audio/victoria.ogg")
+ self.sonidoPasraPantalla = pygame.mixer.Sound("audio/pasarPantalla.ogg")
+
+ self.IMGGenial = pygame.image.load("carteles/genial.png")
+ self.IMGBien = pygame.image.load("carteles/bien.png")
+ self.IMGGanaste = pygame.image.load("carteles/ganaste.png")
+
+ self.pistaActual = 1
+ self.pistas = []
+ self.pistas.append("carteles/conoces_este_lugar.png")
+ self.pistas.append("carteles/que_objeto_llevarias.png")
+ self.pistas.append("carteles/que_te_pondrias_en_las_piernas.png")
+ self.pistas.append("carteles/que_te_pondrias_en_los_pies.png")
+ self.pistas.append("carteles/que_te_pondrias_para_ir_a_este_lugar.png")
+ self.pistas.append("carteles/te_parece_que_hace_frio_o_calor.png")
+
+ self.info = []
+ self.info.append("carteles/Presentacion.png")
+ self.info.append("carteles/info_verano.png")
+ self.info.append("carteles/info_nieve.png")
+ self.info.append("carteles/info_ciudad.png")
+
+
+ #canvas
+ self.canv = sugargame.canvas.PygameCanvas(self)
+ self.set_canvas(self.canv)
+ self.canv.run_pygame(self.iniciar)
+
+
+
+ def iniciar(self):
+ self.screen = pygame.display.set_mode(self.RESOLUCION)
+ pygame.display.toggle_fullscreen()
+ pygame.mouse.set_visible(False)
+
+ self.mainLoop()
+
+ def mainLoop(self):
+ self.pl = Playa(self.screen, (0, 0))
+ self.musicaFondo()
+ going = True
+ while going:
+ events = pygame.event.get()
+
+
+ if self.camara:
+ self.sb.blitCameraImage(self.screen, (10,600))
+
+ result = self.sb.getAndAnalize()
+
+ for dato in result:
+ self.leido(dato)
+
+ pygame.display.update()
+ pygame.event.pump()
+ for e in events:
+ if e.type == QUIT or (e.type == KEYDOWN and e.key == pygame.K_ESCAPE):
+ self.sb.stop()
+ pygame.mixer.music.stop()
+ going = False
+ sys.exit()
+ if e.type == KEYDOWN and e.key == pygame.K_SPACE:
+
+ self.camara = not self.camara
+ if not self.camara:
+ self.pasarArriba()
+ elif e.type == KEYDOWN and e.key == K_p:
+ self.mostrandoPista = not self.mostrandoPista
+ if self.mostrandoPista:
+ self.mostrarPista()
+ else:
+ self.pasarArriba()
+#
+ elif e.type == KEYDOWN and e.key == K_i:
+ self.mostrandoInfo = not self.mostrandoInfo
+ if self.mostrandoInfo:
+ self.mostrarInfo()
+ else:
+ self.pasarArriba()
+ elif e.type == KEYDOWN and e.key == K_q:
+ self.mostrandoPresentacion = not self.mostrandoPresentacion
+ if self.mostrandoPresentacion:
+ self.mostrarPresentacion()
+ else:
+ self.pasarArriba()
+
+ def mostrarCosa(self, img):
+ cosa = pygame.image.load(os.path.join("cosas", img + ".jpg")).convert()
+ self.cosas.append(cosa)
+ self.screen.blit(cosa, self.LUGAR_MUESTRA)
+ t = Timer(3, self.pasarArriba)
+ t.start()
+
+ def pasarArriba(self):
+ self.pl.repaint()
+ i = 1
+ for c in self.cosas:
+ i += 1
+ self.screen.blit(c, (i * 200 + 10, 10))
+
+ def cambiarLugar(self, lugar):
+ if lugar == 0:
+ self.pl = Playa(self.screen, (0, 0))
+ elif lugar == 1:
+ self.pl = Nieve(self.screen, (0, 0))
+ elif lugar == 2:
+ self.pl = Ciudad(self.screen, (0, 0))
+ elif lugar == 3:
+ self.sonidoVictoria.play()
+ self.screen.blit(self.IMGGanaste, (50, 300))
+
+
+
+ self.pl.cargarDatos()
+ self.puntos = 0
+ self.cosas = []
+ self.sonidoPasraPantalla.play()
+
+
+
+
+ def leido(self, dato):
+ if self.pl.chequear(dato):
+ self.mostrarCosa(dato)
+ self.acierto()
+ self.puntos += 1
+ if self.puntos >= self.ACIERTOS_PARA_GANAR:
+ self.nivel += 1
+ t = Timer(3, self.cambiarLugar, [self.nivel,])
+ t.start()
+ else:
+ self.error()
+
+
+ def musicaFondo(self):
+ pygame.mixer.music.load("audio/fondo.ogg")
+ pygame.mixer.music.set_volume(0.6)
+ pygame.mixer.music.play(-1)
+
+ def error(self):
+ self.sonidoError.play()
+
+ def acierto(self):
+ self.sonidoAcierto.play()
+ r = random.randint(0, 1)
+ if r==0:
+ self.screen.blit(self.IMGGenial, (50, 300))
+ else:
+ self.screen.blit(self.IMGBien, (50, 300))
+ t = Timer(3, self.pasarArriba)
+ t.start()
+
+ def mostrarPista(self):
+ self.screen.blit(pygame.image.load(self.pistas[self.pistaActual]), (0,0))
+ self.pistaActual += 1
+ if self.pistaActual > len(self.pistas) - 1:
+ self.pistaActual = 0
+
+
+ def mostrarInfo(self):
+ self.screen.blit(pygame.image.load(self.info[self.nivel + 1]),(0,0))
+
+ def mostrarPresentacion(self):
+ self.screen.blit(pygame.image.load(self.info[0]), (0,0))
+
+
+
+if __name__ == "__main__":
+ qv = QueViaje()
+
+ qv.mainLoop()
diff --git a/src/QueViaje.pyo b/src/QueViaje.pyo
new file mode 100644
index 0000000..2c3a8d4
--- /dev/null
+++ b/src/QueViaje.pyo
Binary files differ
diff --git a/src/SugarBar.py b/src/SugarBar.py
new file mode 100644
index 0000000..cb4b388
--- /dev/null
+++ b/src/SugarBar.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+from ctypes import *
+cdll.LoadLibrary("./libzbar.so.0.2.0")
+import zbar
+
+import pygame
+import pygame.camera
+from pygame.locals import *
+
+
+
+pygame.init()
+pygame.camera.init()
+
+class SugarBar:
+ SIZE = (320, 240)
+
+ def __init__(self):
+ self.nueva = False
+ self.zImg = []
+ self.cam = pygame.camera.Camera("/dev/video0", self.SIZE, "YUV")
+ self.cam.start()
+
+ self.scanner = zbar.ImageScanner()
+ self.scanner.parse_config('disable')
+ self.scanner.parse_config('qrcode.enable')
+ self.scanner.enable_cache(True)
+
+ self.grayImg = pygame.Surface(self.SIZE, depth=8)
+ self.grayImg.set_palette([(x, x, x) for x in xrange(255)])
+ self.image = pygame.Surface(self.SIZE, depth=24)
+
+ self.mostrarCam = False
+
+
+ def getAndAnalize(self):
+ if self.cam.query_image():
+ self.nueva = True
+ self.cam.get_image(self.image)
+ arr3d = pygame.surfarray.pixels3d(self.image)
+ lumi = arr3d[0:self.SIZE[0], 0:self.SIZE[1], 0]
+ pygame.surfarray.blit_array(self.grayImg, lumi)
+
+ imgString = pygame.image.tostring(self.grayImg, "P")
+
+ self.zImg = zbar.Image(self.SIZE[0], self.SIZE[1], "Y800", imgString)
+ self.scanner.scan(self.zImg)
+
+ decoded = []
+
+ for symbol in self.zImg:
+ decoded.append(symbol.data)
+
+ return decoded
+
+ def blitCameraImage(self, display, position):
+ if self.nueva:
+ display.blit(self.grayImg, position)
+ self.nueva = False
+
+ def stop(self):
+ self.cam.stop()
+
+ def main(self):
+ display = pygame.display.set_mode(self.SIZE)
+ going = True
+ while going:
+ events = pygame.event.get()
+ for e in events:
+ if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE):
+ # close the camera safely
+ self.cam.stop()
+ going = False
+
+ elif e.type == KEYDOWN and e.key == pygame.K_c:
+ self.mostrarCam = not self.mostrarCam
+
+ res = self.getAndAnalize()
+ if not res == []:
+ print res
+ if self.mostrarCam:
+ self.blitCameraImage(display, (0, 0))
+ pygame.display.flip()
+
+
+if __name__ == "__main__":
+ d = SugarBar()
+ d.main()
diff --git a/src/SugarBar.py.bak b/src/SugarBar.py.bak
new file mode 100644
index 0000000..65232f1
--- /dev/null
+++ b/src/SugarBar.py.bak
Binary files differ
diff --git a/src/SugarBar.pyo b/src/SugarBar.pyo
new file mode 100644
index 0000000..2d2232d
--- /dev/null
+++ b/src/SugarBar.pyo
Binary files differ
diff --git a/src/activity/activity-QueViaje.svg b/src/activity/activity-QueViaje.svg
new file mode 100644
index 0000000..49f4508
--- /dev/null
+++ b/src/activity/activity-QueViaje.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="svg3799"
+ version="1.1"
+ inkscape:version="0.48.0 r9654"
+ sodipodi:docname="Documento nuevo 4">
+ <defs
+ id="defs3" />
+ <sodipodi:namedview
+ inkscape:document-units="px"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="67.919666"
+ inkscape:cy="24.391749"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1366"
+ inkscape:window-height="712"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1004.3622)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.29887733;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 47.166908,1049.867 -26.164033,-27.5723 c 0,0 -2.825119,-1.8493 -1.129844,-2.8816 1.69527,-1.0324 4.058298,-0.5854 4.058298,-0.5854 0,0 -0.837282,-2.8559 2.044681,-4.5764 2.88196,-1.7205 4.205085,0.6363 4.205085,0.6363 0,0 -1.323125,-2.3568 0.372149,-3.9054 1.69527,-1.5485 5.424869,-0.5161 5.424869,-0.5161 0,0 -19.269252,-7.7934 -27.9151404,-2.4598 -8.64588872,5.3338 -5.312192,24.8271 -5.312192,24.8271 0,0 -0.0051,-8.4085 2.7010684,-6.3487 0.8259082,0.6285 2.4653482,3.02 2.4653482,3.02 0,0 -0.9893001,-4.0507 1.3665742,-5.5664 0.8960906,-0.5764 4.1027616,3.1404 4.1027616,3.1404 0,0 -0.622276,-3.9919 1.581577,-5.1963 2.203854,-1.2044 3.752336,1.8407 3.752336,1.8407 l 26.920717,27.0041 z"
+ id="path2997"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccscscscscscscsccc" />
+ <path
+ transform="matrix(-0.02767762,0,0,0.02627197,12.294521,1023.2147)"
+ sodipodi:type="arc"
+ style="fill:#0000ff;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path2991"
+ sodipodi:cx="-607.14288"
+ sodipodi:cy="588.07648"
+ sodipodi:rx="438.57144"
+ sodipodi:ry="438.57144"
+ d="m -168.57144,588.07648 a 438.57144,438.57144 0 1 1 -877.14286,0 438.57144,438.57144 0 1 1 877.14286,0 z" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path2995"
+ sodipodi:cx="-597.14288"
+ sodipodi:cy="608.07648"
+ sodipodi:rx="282.85715"
+ sodipodi:ry="404.28571"
+ d="m -314.28574,608.07648 a 282.85715,404.28571 0 1 1 -565.71429,0 282.85715,404.28571 0 1 1 565.71429,0 z"
+ transform="matrix(-0.02144657,0,0,0.02833841,16.015352,1021.479)" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.29585063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 30.640832,1015.2197 c 0,0 -3.321315,-3.7949 -9.805786,-6.6862 -6.48447,-2.8913 -12.6526269,-1.0842 -12.6526269,-1.0842 0,0 -2.6886839,2.5298 -2.8468411,8.3125 -0.1581571,5.7827 2.2142101,13.3724 2.2142101,13.3724"
+ id="path3775"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.29585063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 24.314518,1018.6531 c 0,0 -3.163157,-2.8913 -7.117102,-5.4212 -3.953946,-2.5299 -9.1731566,-5.7826 -9.1731566,-5.7826 0,0 -0.3163142,4.8791 1.2652634,8.4932 1.5815792,3.6141 4.1121032,11.5653 4.1121032,11.5653"
+ id="path3777"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.29585063;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 19.253467,1020.0988 c 0,3.0721 0.07908,2.3492 0.07908,2.3492 l -2.728225,-0.8132"
+ id="path3779"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
diff --git a/src/activity/activity.info b/src/activity/activity.info
new file mode 100644
index 0000000..9101d86
--- /dev/null
+++ b/src/activity/activity.info
@@ -0,0 +1,8 @@
+[Activity]
+name = QueViaje
+service_name = uy.edu.fing.QueViaje
+exec = sugar-activity QueViaje.QueViaje
+icon = activity-QueViaje
+activity_version = 1
+license = GPLv3+
+show_launcher = yes
diff --git a/src/audio/acierto.ogg b/src/audio/acierto.ogg
new file mode 100644
index 0000000..108a40d
--- /dev/null
+++ b/src/audio/acierto.ogg
Binary files differ
diff --git a/src/audio/error.ogg b/src/audio/error.ogg
new file mode 100644
index 0000000..9456bc2
--- /dev/null
+++ b/src/audio/error.ogg
Binary files differ
diff --git a/src/audio/fondo.ogg b/src/audio/fondo.ogg
new file mode 100644
index 0000000..8b926fd
--- /dev/null
+++ b/src/audio/fondo.ogg
Binary files differ
diff --git a/src/audio/pasarPantalla.ogg b/src/audio/pasarPantalla.ogg
new file mode 100644
index 0000000..b05bf49
--- /dev/null
+++ b/src/audio/pasarPantalla.ogg
Binary files differ
diff --git a/src/audio/victoria.ogg b/src/audio/victoria.ogg
new file mode 100644
index 0000000..cd5b5f6
--- /dev/null
+++ b/src/audio/victoria.ogg
Binary files differ
diff --git a/src/carteles/Presentacion.png b/src/carteles/Presentacion.png
new file mode 100644
index 0000000..c519b66
--- /dev/null
+++ b/src/carteles/Presentacion.png
Binary files differ
diff --git a/src/carteles/bien.png b/src/carteles/bien.png
new file mode 100644
index 0000000..2abdc70
--- /dev/null
+++ b/src/carteles/bien.png
Binary files differ
diff --git a/src/carteles/conoces_este_lugar.png b/src/carteles/conoces_este_lugar.png
new file mode 100644
index 0000000..61c37da
--- /dev/null
+++ b/src/carteles/conoces_este_lugar.png
Binary files differ
diff --git a/src/carteles/ganaste.png b/src/carteles/ganaste.png
new file mode 100644
index 0000000..87a2663
--- /dev/null
+++ b/src/carteles/ganaste.png
Binary files differ
diff --git a/src/carteles/genial.png b/src/carteles/genial.png
new file mode 100644
index 0000000..3a8daa7
--- /dev/null
+++ b/src/carteles/genial.png
Binary files differ
diff --git a/src/carteles/info_ciudad.png b/src/carteles/info_ciudad.png
new file mode 100644
index 0000000..39816fc
--- /dev/null
+++ b/src/carteles/info_ciudad.png
Binary files differ
diff --git a/src/carteles/info_nieve.png b/src/carteles/info_nieve.png
new file mode 100644
index 0000000..a9e5a11
--- /dev/null
+++ b/src/carteles/info_nieve.png
Binary files differ
diff --git a/src/carteles/info_verano.png b/src/carteles/info_verano.png
new file mode 100644
index 0000000..ddb1e60
--- /dev/null
+++ b/src/carteles/info_verano.png
Binary files differ
diff --git a/src/carteles/que_objeto_llevarias.png b/src/carteles/que_objeto_llevarias.png
new file mode 100644
index 0000000..2245c56
--- /dev/null
+++ b/src/carteles/que_objeto_llevarias.png
Binary files differ
diff --git a/src/carteles/que_te_pondrias_en_las_piernas.png b/src/carteles/que_te_pondrias_en_las_piernas.png
new file mode 100644
index 0000000..25955bb
--- /dev/null
+++ b/src/carteles/que_te_pondrias_en_las_piernas.png
Binary files differ
diff --git a/src/carteles/que_te_pondrias_en_los_pies.png b/src/carteles/que_te_pondrias_en_los_pies.png
new file mode 100644
index 0000000..8c725a0
--- /dev/null
+++ b/src/carteles/que_te_pondrias_en_los_pies.png
Binary files differ
diff --git a/src/carteles/que_te_pondrias_para_ir_a_este_lugar.png b/src/carteles/que_te_pondrias_para_ir_a_este_lugar.png
new file mode 100644
index 0000000..30c40d5
--- /dev/null
+++ b/src/carteles/que_te_pondrias_para_ir_a_este_lugar.png
Binary files differ
diff --git a/src/carteles/te_parece_que_hace_frio_o_calor.png b/src/carteles/te_parece_que_hace_frio_o_calor.png
new file mode 100644
index 0000000..b5bb1a4
--- /dev/null
+++ b/src/carteles/te_parece_que_hace_frio_o_calor.png
Binary files differ
diff --git a/src/cosas/biquini.jpg b/src/cosas/biquini.jpg
new file mode 100644
index 0000000..0c2ddb9
--- /dev/null
+++ b/src/cosas/biquini.jpg
Binary files differ
diff --git a/src/cosas/botas.jpg b/src/cosas/botas.jpg
new file mode 100644
index 0000000..0ed646d
--- /dev/null
+++ b/src/cosas/botas.jpg
Binary files differ
diff --git a/src/cosas/buzo.jpg b/src/cosas/buzo.jpg
new file mode 100644
index 0000000..e18bd60
--- /dev/null
+++ b/src/cosas/buzo.jpg
Binary files differ
diff --git a/src/cosas/camisa.jpg b/src/cosas/camisa.jpg
new file mode 100644
index 0000000..bdea36c
--- /dev/null
+++ b/src/cosas/camisa.jpg
Binary files differ
diff --git a/src/cosas/championes.jpg b/src/cosas/championes.jpg
new file mode 100644
index 0000000..82e4638
--- /dev/null
+++ b/src/cosas/championes.jpg
Binary files differ
diff --git a/src/cosas/chancletas.jpg b/src/cosas/chancletas.jpg
new file mode 100644
index 0000000..c19fb4e
--- /dev/null
+++ b/src/cosas/chancletas.jpg
Binary files differ
diff --git a/src/cosas/gorrolana.jpg b/src/cosas/gorrolana.jpg
new file mode 100644
index 0000000..7a6f747
--- /dev/null
+++ b/src/cosas/gorrolana.jpg
Binary files differ
diff --git a/src/cosas/gorrosol.jpg b/src/cosas/gorrosol.jpg
new file mode 100644
index 0000000..99e3678
--- /dev/null
+++ b/src/cosas/gorrosol.jpg
Binary files differ
diff --git a/src/cosas/jeans.jpg b/src/cosas/jeans.jpg
new file mode 100644
index 0000000..32bbc82
--- /dev/null
+++ b/src/cosas/jeans.jpg
Binary files differ
diff --git a/src/cosas/lentes.jpg b/src/cosas/lentes.jpg
new file mode 100644
index 0000000..d96445c
--- /dev/null
+++ b/src/cosas/lentes.jpg
Binary files differ
diff --git a/src/cosas/paraguas.jpg b/src/cosas/paraguas.jpg
new file mode 100644
index 0000000..208a3be
--- /dev/null
+++ b/src/cosas/paraguas.jpg
Binary files differ
diff --git a/src/cosas/short.jpg b/src/cosas/short.jpg
new file mode 100644
index 0000000..c6d5c8d
--- /dev/null
+++ b/src/cosas/short.jpg
Binary files differ
diff --git a/src/cosas/sombrero.JPG b/src/cosas/sombrero.JPG
new file mode 100644
index 0000000..b02f37f
--- /dev/null
+++ b/src/cosas/sombrero.JPG
Binary files differ
diff --git a/src/cosas/vestido.jpg b/src/cosas/vestido.jpg
new file mode 100644
index 0000000..11493ec
--- /dev/null
+++ b/src/cosas/vestido.jpg
Binary files differ
diff --git a/src/cosas/zapatos.jpg b/src/cosas/zapatos.jpg
new file mode 100644
index 0000000..a2d6b1d
--- /dev/null
+++ b/src/cosas/zapatos.jpg
Binary files differ
diff --git a/src/data/__init__.py b/src/data/__init__.py
new file mode 100644
index 0000000..d0b43b7
--- /dev/null
+++ b/src/data/__init__.py
@@ -0,0 +1,2 @@
+__author__="nexo"
+__date__ ="$17/10/2012 06:23:15 PM$" \ No newline at end of file
diff --git a/src/data/__init__.pyo b/src/data/__init__.pyo
new file mode 100644
index 0000000..7d41e79
--- /dev/null
+++ b/src/data/__init__.pyo
Binary files differ
diff --git a/src/data/ciudad.py b/src/data/ciudad.py
new file mode 100644
index 0000000..f9f5cf7
--- /dev/null
+++ b/src/data/ciudad.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+
+__author__="rodripf"
+__date__ ="$31/10/2012 12:43:47 PM$"
+
+from lugar import Lugar
+
+class Ciudad(Lugar):
+ def cargarDatos(self):
+ self.nombre = "ciudad"
+ self.cosasPermitidas = [("camisa", 2), ("championes", 1), ("jeans", 1), ("vestido", 1), ("zapatos", 1)]
diff --git a/src/data/ciudad.pyo b/src/data/ciudad.pyo
new file mode 100644
index 0000000..87d1e45
--- /dev/null
+++ b/src/data/ciudad.pyo
Binary files differ
diff --git a/src/data/lugar.py b/src/data/lugar.py
new file mode 100644
index 0000000..b394344
--- /dev/null
+++ b/src/data/lugar.py
@@ -0,0 +1,43 @@
+__author__="nexo"
+__date__ ="$17/10/2012 06:24:01 PM$"
+
+import pygame
+from pygame.locals import *
+pygame.init()
+
+import os
+
+class Lugar():
+ def __init__(self, surfDest, posDest):
+ self.nombre = None
+ self.cosasPermitidas = []
+
+ self.cargarDatos()
+
+ self.img = pygame.image.load(os.path.join("lugares", self.nombre + ".jpg")).convert()
+
+ self.posDest = posDest
+ self.surfDest = surfDest
+
+ surfDest.blit(self.img, posDest)
+
+
+ def repaint(self):
+ self.surfDest.blit(self.img, self.posDest)
+
+ def cargarDatos(self):
+ """Abstracta"""
+ pass
+
+
+ def chequear(self, objeto):
+ """Chequea si es correcto un objeto corresponde al lugar"""
+ for o in self.cosasPermitidas:
+ if o[0] == objeto:
+ return True
+
+ return False
+
+
+if __name__ == "__main__":
+ print "Hello World"
diff --git a/src/data/lugar.pyo b/src/data/lugar.pyo
new file mode 100644
index 0000000..c6f52a3
--- /dev/null
+++ b/src/data/lugar.pyo
Binary files differ
diff --git a/src/data/lugar.py~ b/src/data/lugar.py~
new file mode 100644
index 0000000..26f9730
--- /dev/null
+++ b/src/data/lugar.py~
@@ -0,0 +1,26 @@
+__author__="nexo"
+__date__ ="$17/10/2012 06:24:01 PM$"
+
+import pygame
+from pygame.locals import *
+pygame.init()
+
+import os
+
+class Lugar():
+ def __init__(self, surfDest, posDest):
+ self.nombre = None
+ self.cosasPermitidas = []
+
+ self.cargarDatos()
+
+ img = pygame.image.load(os.path.join("lugares", self.nombre + ".jpg")).convert()
+ surfDest.blit(img, posDest)
+
+ def cargarDatos(self):
+ """Abstracta"""
+ pass
+
+
+if __name__ == "__main__":
+ print "Hello World"
diff --git a/src/data/nieve.py b/src/data/nieve.py
new file mode 100644
index 0000000..0821195
--- /dev/null
+++ b/src/data/nieve.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+from lugar import Lugar
+
+class Nieve(Lugar):
+ def cargarDatos(self):
+ self.nombre = "nieve"
+ self.cosasPermitidas = [("gorrolana", 2), ("bufanda", 1), ("guantes", 1), ("campera", 1), ("buzo", 2), ("orejeras", 2), ("paraguas", 2)] \ No newline at end of file
diff --git a/src/data/nieve.pyo b/src/data/nieve.pyo
new file mode 100644
index 0000000..301be00
--- /dev/null
+++ b/src/data/nieve.pyo
Binary files differ
diff --git a/src/data/playa.py b/src/data/playa.py
new file mode 100644
index 0000000..2962e41
--- /dev/null
+++ b/src/data/playa.py
@@ -0,0 +1,15 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+__author__="nexo"
+__date__ ="$17/10/2012 06:32:45 PM$"
+
+from lugar import Lugar
+
+class Playa(Lugar):
+ def cargarDatos(self):
+ self.nombre = "playa"
+ self.cosasPermitidas = [("chancletas", 2), ("gorrosol", 1), ("short", 1), ("biquini", 1), ("lentes", 2), ("sombrero", 3)]
+
+if __name__ == "__main__":
+ print "Hello World"
diff --git a/src/data/playa.pyo b/src/data/playa.pyo
new file mode 100644
index 0000000..f5090b5
--- /dev/null
+++ b/src/data/playa.pyo
Binary files differ
diff --git a/src/dist/QueViaje-1.xo b/src/dist/QueViaje-1.xo
new file mode 100644
index 0000000..520eefb
--- /dev/null
+++ b/src/dist/QueViaje-1.xo
Binary files differ
diff --git a/src/libzbar.a b/src/libzbar.a
new file mode 100644
index 0000000..35f0888
--- /dev/null
+++ b/src/libzbar.a
Binary files differ
diff --git a/src/libzbar.la b/src/libzbar.la
new file mode 100644
index 0000000..0f639d6
--- /dev/null
+++ b/src/libzbar.la
@@ -0,0 +1,41 @@
+# libzbar.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='libzbar.so.0'
+
+# Names of this library.
+library_names='libzbar.so.0.2.0 libzbar.so.0 libzbar.so'
+
+# The name of the static archive.
+old_library='libzbar.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=' -lSM -lICE -lX11 -ljpeg -lpthread -lrt'
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libzbar.
+current=2
+age=2
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/local/lib'
diff --git a/src/libzbar.so.0.2.0 b/src/libzbar.so.0.2.0
new file mode 100644
index 0000000..efbf8ba
--- /dev/null
+++ b/src/libzbar.so.0.2.0
Binary files differ
diff --git a/src/lugares/ciudad.jpg b/src/lugares/ciudad.jpg
new file mode 100644
index 0000000..3d135af
--- /dev/null
+++ b/src/lugares/ciudad.jpg
Binary files differ
diff --git a/src/lugares/nieve.jpg b/src/lugares/nieve.jpg
new file mode 100644
index 0000000..98bf62e
--- /dev/null
+++ b/src/lugares/nieve.jpg
Binary files differ
diff --git a/src/lugares/playa.jpg b/src/lugares/playa.jpg
new file mode 100644
index 0000000..1fcc204
--- /dev/null
+++ b/src/lugares/playa.jpg
Binary files differ
diff --git a/src/pygame/.gitignore b/src/pygame/.gitignore
new file mode 100644
index 0000000..a74b07a
--- /dev/null
+++ b/src/pygame/.gitignore
@@ -0,0 +1 @@
+/*.pyc
diff --git a/src/pygame/LGPL b/src/pygame/LGPL
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/src/pygame/LGPL
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/src/pygame/__init__.py b/src/pygame/__init__.py
new file mode 100644
index 0000000..1e8727e
--- /dev/null
+++ b/src/pygame/__init__.py
@@ -0,0 +1,304 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2001 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+"""Pygame is a set of Python modules designed for writing games.
+It is written on top of the excellent SDL library. This allows you
+to create fully featured games and multimedia programs in the python
+language. The package is highly portable, with games running on
+Windows, MacOS, OS X, BeOS, FreeBSD, IRIX, and Linux.
+"""
+
+import sys, os, string
+
+# check if is old windows... if so use directx video driver by default.
+# if someone sets this respect their setting...
+if not 'SDL_VIDEODRIVER' in os.environ:
+ # http://docs.python.org/lib/module-sys.html
+ # 0 (VER_PLATFORM_WIN32s) Win32s on Windows 3.1
+ # 1 (VER_PLATFORM_WIN32_WINDOWS) Windows 95/98/ME
+ # 2 (VER_PLATFORM_WIN32_NT) Windows NT/2000/XP
+ # 3 (VER_PLATFORM_WIN32_CE) Windows CE
+ if hasattr(sys, "getwindowsversion"):
+ try:
+ if (sys.getwindowsversion()[3] in [1,2] and
+ sys.getwindowsversion()[0] in [0,1,2,3,4,5]):
+ os.environ['SDL_VIDEODRIVER'] = 'directx'
+ except:
+ pass
+
+
+class MissingModule:
+ _NOT_IMPLEMENTED_ = True
+ def __init__(self, name, info='', urgent=0):
+ self.name = name
+ self.info = str(info)
+ try:
+ exc = sys.exc_info()
+ if exc[0] != None:
+ self.reason = "%s: %s" % (exc[0].__name__, str(exc[1]))
+ else:
+ self.reason = ""
+ finally:
+ del exc
+ self.urgent = urgent
+ if urgent:
+ self.warn()
+
+ def __getattr__(self, var):
+ if not self.urgent:
+ self.warn()
+ self.urgent = 1
+ MissingPygameModule = "%s module not available" % self.name
+ if self.reason:
+ MissingPygameModule += "\n(%s)" % self.reason
+ raise NotImplementedError(MissingPygameModule)
+
+ def __nonzero__(self):
+ return 0
+
+ def warn(self):
+ if self.urgent: type = 'import'
+ else: type = 'use'
+ message = '%s %s: %s' % (type, self.name, self.info)
+ if self.reason:
+ message += "\n(%s)" % self.reason
+ try:
+ import warnings
+ if self.urgent: level = 4
+ else: level = 3
+ warnings.warn(message, RuntimeWarning, level)
+ except ImportError:
+ print (message)
+
+
+
+#we need to import like this, each at a time. the cleanest way to import
+#our modules is with the import command (not the __import__ function)
+
+#first, the "required" modules
+from pygame.base import *
+from pygame.constants import *
+from pygame.version import *
+from pygame.rect import Rect
+from pygame.compat import geterror
+import pygame.rwobject
+import pygame.surflock
+import pygame.color
+Color = color.Color
+__version__ = ver
+
+#next, the "standard" modules
+#we still allow them to be missing for stripped down pygame distributions
+try: import pygame.cdrom
+except (ImportError,IOError):cdrom=MissingModule("cdrom", geterror(), 1)
+
+try: import pygame.cursors
+except (ImportError,IOError):cursors=MissingModule("cursors", geterror(), 1)
+
+try: import pygame.display
+except (ImportError,IOError):display=MissingModule("display", geterror(), 1)
+
+try: import pygame.draw
+except (ImportError,IOError):draw=MissingModule("draw", geterror(), 1)
+
+try: import pygame.event
+except (ImportError,IOError):event=MissingModule("event", geterror(), 1)
+
+try: import pygame.image
+except (ImportError,IOError):image=MissingModule("image", geterror(), 1)
+
+try: import pygame.joystick
+except (ImportError,IOError):joystick=MissingModule("joystick", geterror(), 1)
+
+try: import pygame.key
+except (ImportError,IOError):key=MissingModule("key", geterror(), 1)
+
+try: import pygame.mouse
+except (ImportError,IOError):mouse=MissingModule("mouse", geterror(), 1)
+
+try: import pygame.sprite
+except (ImportError,IOError):sprite=MissingModule("sprite", geterror(), 1)
+
+
+try: import pygame.threads
+except (ImportError,IOError):threads=MissingModule("threads", geterror(), 1)
+
+
+def warn_unwanted_files():
+ """ Used to warn about unneeded old files.
+ """
+
+ # a temporary hack to warn about camera.so and camera.pyd.
+ install_path= os.path.split(pygame.base.__file__)[0]
+ extension_ext = os.path.splitext(pygame.base.__file__)[1]
+
+ # here are the .so/.pyd files we need to ask to remove.
+ ext_to_remove = ["camera"]
+
+ # here are the .py/.pyo/.pyc files we need to ask to remove.
+ py_to_remove = ["color"]
+
+ if os.name == "e32": # Don't warn on Symbian. The color.py is used as a wrapper.
+ py_to_remove = []
+
+ # See if any of the files are there.
+ extension_files = ["%s%s" % (x, extension_ext) for x in ext_to_remove]
+
+ py_files = ["%s%s" % (x, py_ext)
+ for py_ext in [".py", ".pyc", ".pyo"]
+ for x in py_to_remove]
+
+ files = py_files + extension_files
+
+ unwanted_files = []
+ for f in files:
+ unwanted_files.append( os.path.join( install_path, f ) )
+
+
+
+ ask_remove = []
+ for f in unwanted_files:
+ if os.path.exists(f):
+ ask_remove.append(f)
+
+
+ if ask_remove:
+ message = "Detected old file(s). Please remove the old files:\n"
+
+ for f in ask_remove:
+ message += "%s " % f
+ message += "\nLeaving them there might break pygame. Cheers!\n\n"
+
+ try:
+ import warnings
+ level = 4
+ warnings.warn(message, RuntimeWarning, level)
+ except ImportError:
+ print (message)
+
+
+# disable, because we hopefully don't need it.
+#warn_unwanted_files()
+
+
+
+try: from pygame.surface import *
+except (ImportError,IOError):Surface = lambda:Missing_Function
+
+
+try:
+ import pygame.mask
+ from pygame.mask import Mask
+except (ImportError,IOError):Mask = lambda:Missing_Function
+
+try: from pygame.pixelarray import *
+except (ImportError,IOError): PixelArray = lambda:Missing_Function
+
+try: from pygame.overlay import *
+except (ImportError,IOError):Overlay = lambda:Missing_Function
+
+try: import pygame.time
+except (ImportError,IOError):time=MissingModule("time", geterror(), 1)
+
+try: import pygame.transform
+except (ImportError,IOError):transform=MissingModule("transform", geterror(), 1)
+
+#lastly, the "optional" pygame modules
+try:
+ import pygame.font
+ import pygame.sysfont
+ pygame.font.SysFont = pygame.sysfont.SysFont
+ pygame.font.get_fonts = pygame.sysfont.get_fonts
+ pygame.font.match_font = pygame.sysfont.match_font
+except (ImportError,IOError):font=MissingModule("font", geterror(), 0)
+
+# try and load pygame.mixer_music before mixer, for py2app...
+try:
+ import pygame.mixer_music
+ #del pygame.mixer_music
+ #print ("NOTE2: failed importing pygame.mixer_music in lib/__init__.py")
+except (ImportError,IOError):
+ pass
+
+try: import pygame.mixer
+except (ImportError,IOError):mixer=MissingModule("mixer", geterror(), 0)
+
+try: import pygame.movie
+except (ImportError,IOError):movie=MissingModule("movie", geterror(), 0)
+
+#try: import pygame.movieext
+#except (ImportError,IOError):movieext=MissingModule("movieext", geterror(), 0)
+
+try: import pygame.scrap
+except (ImportError,IOError):scrap=MissingModule("scrap", geterror(), 0)
+
+try: import pygame.surfarray
+except (ImportError,IOError):surfarray=MissingModule("surfarray", geterror(), 0)
+
+try: import pygame.sndarray
+except (ImportError,IOError):sndarray=MissingModule("sndarray", geterror(), 0)
+
+try: import pygame.fastevent
+except (ImportError,IOError):fastevent=MissingModule("fastevent", geterror(), 0)
+
+#there's also a couple "internal" modules not needed
+#by users, but putting them here helps "dependency finder"
+#programs get everything they need (like py2exe)
+try: import pygame.imageext; del pygame.imageext
+except (ImportError,IOError):pass
+
+def packager_imports():
+ """
+ Some additional things that py2app/py2exe will want to see
+ """
+ import atexit
+ import Numeric
+ import numpy
+ import OpenGL.GL
+ import pygame.macosx
+ import pygame.mac_scrap
+ import pygame.bufferproxy
+ import pygame.colordict
+
+#make Rects pickleable
+try:
+ import copy_reg
+except ImportError:
+ import copyreg as copy_reg
+def __rect_constructor(x,y,w,h):
+ return Rect(x,y,w,h)
+def __rect_reduce(r):
+ assert type(r) == Rect
+ return __rect_constructor, (r.x, r.y, r.w, r.h)
+copy_reg.pickle(Rect, __rect_reduce, __rect_constructor)
+
+
+#make Colors pickleable
+def __color_constructor(r,g,b,a):
+ return Color(r,g,b,a)
+def __color_reduce(c):
+ assert type(c) == Color
+ return __color_constructor, (c.r, c.g, c.b, c.a)
+copy_reg.pickle(Color, __color_reduce, __color_constructor)
+
+
+
+
+#cleanup namespace
+del pygame, os, sys, rwobject, surflock, MissingModule, copy_reg, geterror
diff --git a/src/pygame/__init__.pyo b/src/pygame/__init__.pyo
new file mode 100644
index 0000000..e510208
--- /dev/null
+++ b/src/pygame/__init__.pyo
Binary files differ
diff --git a/src/pygame/_arraysurfarray.so b/src/pygame/_arraysurfarray.so
new file mode 100644
index 0000000..19e18a5
--- /dev/null
+++ b/src/pygame/_arraysurfarray.so
Binary files differ
diff --git a/src/pygame/_camera.so b/src/pygame/_camera.so
new file mode 100644
index 0000000..a6ab840
--- /dev/null
+++ b/src/pygame/_camera.so
Binary files differ
diff --git a/src/pygame/_camera_opencv_highgui.py b/src/pygame/_camera_opencv_highgui.py
new file mode 100644
index 0000000..7709c3c
--- /dev/null
+++ b/src/pygame/_camera_opencv_highgui.py
@@ -0,0 +1,98 @@
+
+import pygame
+import numpy
+
+import opencv
+#this is important for capturing/displaying images
+from opencv import highgui
+
+
+
+def list_cameras():
+ """
+ """
+ # -1 for opencv means get any of them.
+ return [-1]
+
+def init():
+ pass
+
+def quit():
+ pass
+
+
+class Camera:
+
+ def __init__(self, device =0, size = (640,480), mode = "RGB"):
+ """
+ """
+ self.camera = highgui.cvCreateCameraCapture(device)
+ if not self.camera:
+ raise ValueError ("Could not open camera. Sorry.")
+
+
+ def set_controls(self, **kwargs):
+ """
+ """
+
+
+ def set_resolution(self, width, height):
+ """Sets the capture resolution. (without dialog)
+ """
+ # nothing to do here.
+ pass
+ def query_image(self):
+ return True
+
+ def stop(self):
+ pass
+
+ def start(self):
+ # do nothing here... since the camera is already open.
+ pass
+
+ def get_buffer(self):
+ """Returns a string containing the raw pixel data.
+ """
+ return self.get_surface().get_buffer()
+
+ def get_image(self, dest_surf = None):
+ return self.get_surface(dest_surf)
+
+ def get_surface(self, dest_surf = None):
+ camera = self.camera
+
+ im = highgui.cvQueryFrame(camera)
+ #convert Ipl image to PIL image
+ #print type(im)
+ if im:
+ xx = opencv.adaptors.Ipl2NumPy(im)
+ #print type(xx)
+ #print xx.iscontiguous()
+ #print dir(xx)
+ #print xx.shape
+ xxx = numpy.reshape(xx, (numpy.product(xx.shape),))
+
+ if xx.shape[2] != 3:
+ raise ValueError("not sure what to do about this size")
+
+ pg_img = pygame.image.frombuffer(xxx, (xx.shape[1],xx.shape[0]), "RGB")
+
+ # if there is a destination surface given, we blit onto that.
+ if dest_surf:
+ dest_surf.blit(pg_img, (0,0))
+ return dest_surf
+ #return pg_img
+
+
+
+if __name__ == "__main__":
+
+ # try and use this camera stuff with the pygame camera example.
+ import pygame.examples.camera
+
+ pygame.camera.Camera = Camera
+ pygame.camera.list_cameras = list_cameras
+ pygame.examples.camera.main()
+
+
diff --git a/src/pygame/_camera_vidcapture.py b/src/pygame/_camera_vidcapture.py
new file mode 100644
index 0000000..5b6a4f3
--- /dev/null
+++ b/src/pygame/_camera_vidcapture.py
@@ -0,0 +1,133 @@
+
+import pygame
+
+def list_cameras():
+ return [0]
+
+ # this just cycles through all the cameras trying to open them
+ cameras = []
+ for x in range(256):
+ try:
+ c = Camera(x)
+ except:
+ break
+ cameras.append(x)
+
+ return cameras
+
+
+def init():
+ global vidcap
+ import vidcap as vc
+ vidcap = vc
+
+def quit():
+ global vidcap
+ pass
+ del vidcap
+
+
+
+class Camera:
+
+ def __init__(self, device =0,
+ size = (640,480),
+ mode = "RGB",
+ show_video_window=0):
+ """device: VideoCapture enumerates the available video capture devices
+ on your system. If you have more than one device, specify
+ the desired one here. The device number starts from 0.
+
+ show_video_window: 0 ... do not display a video window (the default)
+ 1 ... display a video window
+
+ Mainly used for debugging, since the video window
+ can not be closed or moved around.
+ """
+ self.dev = vidcap.new_Dev(device, show_video_window)
+ width, height = size
+ self.dev.setresolution(width, height)
+
+ def display_capture_filter_properties(self):
+ """Displays a dialog containing the property page of the capture filter.
+
+ For VfW drivers you may find the option to select the resolution most
+ likely here.
+ """
+ self.dev.displaycapturefilterproperties()
+
+ def display_capture_pin_properties(self):
+ """Displays a dialog containing the property page of the capture pin.
+
+ For WDM drivers you may find the option to select the resolution most
+ likely here.
+ """
+ self.dev.displaycapturepinproperties()
+
+ def set_resolution(self, width, height):
+ """Sets the capture resolution. (without dialog)
+ """
+ self.dev.setresolution(width, height)
+
+ def get_buffer(self):
+ """Returns a string containing the raw pixel data.
+ """
+ return self.dev.getbuffer()
+
+ def start(self):
+ """
+ """
+ def set_controls(self, **kwargs):
+ """
+ """
+
+ def stop(self):
+ """
+ """
+
+ def get_image(self, dest_surf = None):
+ return self.get_surface(dest_surf)
+
+ def get_surface(self, dest_surf = None):
+ """Returns a pygame Surface.
+ """
+ abuffer, width, height = self.get_buffer()
+ if abuffer:
+ if 1:
+ surf = pygame.image.frombuffer(abuffer, (width, height), "RGB")
+
+ # swap it from a BGR surface to an RGB surface.
+ r,g,b,a = surf.get_masks()
+ surf.set_masks((b,g,r,a))
+
+ r,g,b,a = surf.get_shifts()
+ surf.set_shifts((b,g,r,a))
+
+ surf = pygame.transform.flip(surf, 0,1)
+
+ # if there is a destination surface given, we blit onto that.
+ if dest_surf:
+ dest_surf.blit(surf, (0,0))
+ return dest_surf
+
+ else:
+
+ # Need to flip the image.
+ surf = pygame.image.fromstring(abuffer, (width, height), "RGB", 1)
+ # swap it from a BGR surface to an RGB surface.
+ r,g,b,a = surf.get_masks()
+ surf.set_masks((b,g,r,a))
+
+ r,g,b,a = surf.get_shifts()
+ surf.set_shifts((b,g,r,a))
+ return surf
+
+
+if __name__ == "__main__":
+ import pygame.examples.camera
+
+ pygame.camera.Camera = Camera
+ pygame.camera.list_cameras = list_cameras
+ pygame.examples.camera.main()
+
+
diff --git a/src/pygame/_numericsndarray.so b/src/pygame/_numericsndarray.so
new file mode 100644
index 0000000..2f23e3c
--- /dev/null
+++ b/src/pygame/_numericsndarray.so
Binary files differ
diff --git a/src/pygame/_numericsurfarray.so b/src/pygame/_numericsurfarray.so
new file mode 100644
index 0000000..697748f
--- /dev/null
+++ b/src/pygame/_numericsurfarray.so
Binary files differ
diff --git a/src/pygame/_numpysndarray.py b/src/pygame/_numpysndarray.py
new file mode 100644
index 0000000..58c7fba
--- /dev/null
+++ b/src/pygame/_numpysndarray.py
@@ -0,0 +1,136 @@
+## pygame - Python Game Library
+## Copyright (C) 2008 Marcus von Appen
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Marcus von Appen
+## mva@sysfault.org
+
+"""pygame module for accessing sound sample data using numpy
+
+Functions to convert between numpy arrays and Sound objects. This module
+will only be available when pygame can use the external numpy package.
+
+Sound data is made of thousands of samples per second, and each sample
+is the amplitude of the wave at a particular moment in time. For
+example, in 22-kHz format, element number 5 of the array is the
+amplitude of the wave after 5/22000 seconds.
+
+Each sample is an 8-bit or 16-bit integer, depending on the data format.
+A stereo sound file has two values per sample, while a mono sound file
+only has one.
+"""
+
+import pygame
+import pygame.mixer as mixer
+import numpy
+
+def _array_samples(sound, raw):
+ # Info is a (freq, format, stereo) tuple
+ info = mixer.get_init ()
+ if not info:
+ raise pygame.error("Mixer not initialized")
+ fmtbytes = (abs (info[1]) & 0xff) >> 3
+ channels = info[2]
+ if raw:
+ data = sound.get_buffer ().raw
+ else:
+ data = sound.get_buffer ()
+
+ shape = (len (data) // fmtbytes, )
+ if channels > 1:
+ shape = (shape[0] // channels, channels)
+
+ # mixer.init () does not support different formats from the ones below,
+ # so MSB/LSB stuff is silently ignored.
+ typecode = { 8 : numpy.uint8, # AUDIO_U8
+ 16 : numpy.uint16, # AUDIO_U16 / AUDIO_U16SYS
+ -8 : numpy.int8, # AUDIO_S8
+ -16 : numpy.int16 # AUDUI_S16 / AUDIO_S16SYS
+ }[info[1]]
+
+ array = numpy.fromstring (data, typecode)
+ array.shape = shape
+ return array
+
+def array (sound):
+ """pygame._numpysndarray.array(Sound): return array
+
+ Copy Sound samples into an array.
+
+ Creates a new array for the sound data and copies the samples. The
+ array will always be in the format returned from
+ pygame.mixer.get_init().
+ """
+ return _array_samples(sound, True)
+
+def samples (sound):
+ """pygame._numpysndarray.samples(Sound): return array
+
+ Reference Sound samples into an array.
+
+ Creates a new array that directly references the samples in a Sound
+ object. Modifying the array will change the Sound. The array will
+ always be in the format returned from pygame.mixer.get_init().
+ """
+ # Info is a (freq, format, stereo) tuple
+ info = pygame.mixer.get_init ()
+ if not info:
+ raise pygame.error("Mixer not initialized")
+ fmtbytes = (abs (info[1]) & 0xff) >> 3
+ channels = info[2]
+ data = sound.get_buffer ()
+
+ shape = (data.length // fmtbytes, )
+ if channels > 1:
+ shape = (shape[0] // channels, channels)
+
+ # mixer.init () does not support different formats from the ones below,
+ # so MSB/LSB stuff is silently ignored.
+ typecode = { 8 : numpy.uint8, # AUDIO_U8
+ 16 : numpy.uint16, # AUDIO_U16
+ -8 : numpy.int8, # AUDIO_S8
+ -16 : numpy.int16 # AUDUI_S16
+ }[info[1]]
+
+ array = numpy.frombuffer (data, typecode)
+ array.shape = shape
+ return array
+
+def make_sound (array):
+ """pygame._numpysndarray.make_sound(array): return Sound
+
+ Convert an array into a Sound object.
+
+ Create a new playable Sound object from an array. The mixer module
+ must be initialized and the array format must be similar to the mixer
+ audio format.
+ """
+ # Info is a (freq, format, stereo) tuple
+ info = pygame.mixer.get_init ()
+ if not info:
+ raise pygame.error("Mixer not initialized")
+ channels = info[2]
+
+ shape = array.shape
+ if channels == 1:
+ if len (shape) != 1:
+ raise ValueError("Array must be 1-dimensional for mono mixer")
+ else:
+ if len (shape) != 2:
+ raise ValueError("Array must be 2-dimensional for stereo mixer")
+ elif shape[1] != channels:
+ raise ValueError("Array depth must match number of mixer channels")
+ return mixer.Sound (array)
diff --git a/src/pygame/_numpysndarray.pyo b/src/pygame/_numpysndarray.pyo
new file mode 100644
index 0000000..85f4e01
--- /dev/null
+++ b/src/pygame/_numpysndarray.pyo
Binary files differ
diff --git a/src/pygame/_numpysurfarray.py b/src/pygame/_numpysurfarray.py
new file mode 100644
index 0000000..8eac04d
--- /dev/null
+++ b/src/pygame/_numpysurfarray.py
@@ -0,0 +1,472 @@
+## pygame - Python Game Library
+## Copyright (C) 2007 Marcus von Appen
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Marcus von Appen
+## mva@sysfault.org
+
+"""pygame module for accessing surface pixel data using numpy
+
+Functions to convert pixel data between pygame Surfaces and Numpy
+arrays. This module will only be available when pygame can use the
+external Numpy package.
+
+Note, that numpyarray is an optional module. It requires that Numpy is
+installed to be used. If not installed, an exception will be raised when
+it is used. eg. ImportError: no module named numpy
+
+Every pixel is stored as a single integer value to represent the red,
+green, and blue colors. The 8bit images use a value that looks into a
+colormap. Pixels with higher depth use a bit packing process to place
+three or four values into a single number.
+
+The Numpy arrays are indexed by the X axis first, followed by the Y
+axis. Arrays that treat the pixels as a single integer are referred to
+as 2D arrays. This module can also separate the red, green, and blue
+color values into separate indices. These types of arrays are referred
+to as 3D arrays, and the last index is 0 for red, 1 for green, and 2 for
+blue.
+
+In contrast to Numeric Numpy does use unsigned 16bit integers, images
+with 16bit data will be treated as unsigned integers.
+"""
+
+import pygame
+import numpy
+import re
+
+def array2d (surface):
+ """pygame.numpyarray.array2d (Surface): return array
+
+ copy pixels into a 2d array
+
+ Copy the pixels from a Surface into a 2D array. The bit depth of the
+ surface will control the size of the integer values, and will work
+ for any type of pixel format.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ bpp = surface.get_bytesize ()
+ if bpp <= 0 or bpp > 4:
+ raise ValueError("unsupported bit depth for 2D array")
+
+ # Taken from Alex Holkner's pygame-ctypes package. Thanks a lot.
+ data = surface.get_buffer ().raw
+
+ # Remove extra pitch from each row.
+ width = surface.get_width ()
+ pitchdiff = surface.get_pitch () - width * bpp
+ if pitchdiff > 0:
+ pattern = re.compile ('(%s)%s' % ('.' * width * bpp, '.' * pitchdiff),
+ flags=re.DOTALL)
+ data = ''.join (pattern.findall (data))
+
+ if bpp == 3:
+ # Pad each triplet of bytes with another zero
+ pattern = re.compile ('...', flags=re.DOTALL)
+ data = '\0'.join (pattern.findall (data))
+ if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
+ data += '\0'
+ else:
+ data = '\0' + data
+ bpp = 4
+
+ typecode = (numpy.uint8, numpy.uint16, None, numpy.int32)[bpp - 1]
+ array = numpy.fromstring (data, typecode)
+ array.shape = (surface.get_height (), width)
+ array = numpy.transpose (array)
+ return array
+
+
+def pixels2d (surface):
+ """pygame.numpyarray.pixels2d (Surface): return array
+
+ reference pixels into a 2d array
+
+ Create a new 2D array that directly references the pixel values in a
+ Surface. Any changes to the array will affect the pixels in the
+ Surface. This is a fast operation since no data is copied.
+
+ Pixels from a 24-bit Surface cannot be referenced, but all other
+ Surface bit depths can.
+
+ The Surface this references will remain locked for the lifetime of
+ the array (see the Surface.lock - lock the Surface memory for pixel
+ access method).
+ """
+ bpp = surface.get_bytesize ()
+ if bpp == 3 or bpp < 1 or bpp > 4:
+ raise ValueError("unsupported bit depth for 2D reference array")
+
+ typecode = (numpy.uint8, numpy.uint16, None, numpy.int32)[bpp - 1]
+ array = numpy.frombuffer (surface.get_buffer (), typecode)
+ array.shape = surface.get_height (), surface.get_pitch () / bpp
+
+ # Padding correction for certain depth due to padding bytes.
+ array = array[:,:surface.get_width ()]
+ array = numpy.transpose (array)
+ return array
+
+def array3d (surface):
+ """pygame.numpyarray.array3d (Surface): return array
+
+ copy pixels into a 3d array
+
+ Copy the pixels from a Surface into a 3D array. The bit depth of the
+ surface will control the size of the integer values, and will work
+ for any type of pixel format.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ bpp = surface.get_bytesize ()
+ array = array2d (surface)
+
+ # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
+ # lot.
+ if bpp == 1:
+ palette = surface.get_palette ()
+ # Resolve the correct values using the color palette
+ pal_r = numpy.array ([c[0] for c in palette])
+ pal_g = numpy.array ([c[1] for c in palette])
+ pal_b = numpy.array ([c[2] for c in palette])
+ planes = [numpy.choose (array, pal_r),
+ numpy.choose (array, pal_g),
+ numpy.choose (array, pal_b)]
+ array = numpy.array (planes, numpy.uint8)
+ array = numpy.transpose (array, (1, 2, 0))
+ return array
+ elif bpp == 2:
+ # Taken from SDL_GetRGBA.
+ masks = surface.get_masks ()
+ shifts = surface.get_shifts ()
+ losses = surface.get_losses ()
+ vr = (array & masks[0]) >> shifts[0]
+ vg = (array & masks[1]) >> shifts[1]
+ vb = (array & masks[2]) >> shifts[2]
+ planes = [(vr << losses[0]) + (vr >> (8 - (losses[0] << 1))),
+ (vg << losses[1]) + (vg >> (8 - (losses[1] << 1))),
+ (vb << losses[2]) + (vb >> (8 - (losses[2] << 1)))]
+ array = numpy.array (planes, numpy.uint8)
+ return numpy.transpose (array, (1, 2, 0))
+ else:
+ masks = surface.get_masks ()
+ shifts = surface.get_shifts ()
+ losses = surface.get_losses ()
+ planes = [((array & masks[0]) >> shifts[0]), # << losses[0], Assume 0
+ ((array & masks[1]) >> shifts[1]), # << losses[1],
+ ((array & masks[2]) >> shifts[2])] # << losses[2]]
+ array = numpy.array (planes, numpy.uint8)
+ return numpy.transpose (array, (1, 2, 0))
+
+def pixels3d (surface):
+ """pygame.numpyarray.pixels3d (Surface): return array
+
+ reference pixels into a 3d array
+
+ Create a new 3D array that directly references the pixel values in a
+ Surface. Any changes to the array will affect the pixels in the
+ Surface. This is a fast operation since no data is copied.
+
+ This will only work on Surfaces that have 24-bit or 32-bit
+ formats. Lower pixel formats cannot be referenced.
+
+ The Surface this references will remain locked for the lifetime of
+ the array (see the Surface.lock - lock the Surface memory for pixel
+ access method).
+ """
+ bpp = surface.get_bytesize ()
+ if bpp < 3 or bpp > 4:
+ raise ValueError("unsupported bit depth for 3D reference array")
+ lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN
+
+ start = 0
+ step = 0
+
+ # Check for RGB or BGR surface.
+ shifts = surface.get_shifts ()
+ if shifts[0] == 16 and shifts[1] == 8 and shifts[2] == 0:
+ # RGB
+ if lilendian:
+ start = 2
+ step = -1
+ else:
+ start = 0
+ step = 1
+ elif shifts[2] == 16 and shifts[1] == 8 and shifts[0] == 0:
+ # BGR
+ if lilendian:
+ start = 0
+ step = 1
+ else:
+ start = 2
+ step = -1
+ else:
+ raise ValueError("unsupported colormasks for 3D reference array")
+
+ if bpp == 4 and not lilendian:
+ start += 1
+
+ array = numpy.ndarray \
+ (shape=(surface.get_width (), surface.get_height (), 3),
+ dtype=numpy.uint8, buffer=surface.get_buffer (),
+ offset=start, strides=(bpp, surface.get_pitch (),step))
+ return array
+
+def array_alpha (surface):
+ """pygame.numpyarray.array_alpha (Surface): return array
+
+ copy pixel alphas into a 2d array
+
+ Copy the pixel alpha values (degree of transparency) from a Surface
+ into a 2D array. This will work for any type of Surface
+ format. Surfaces without a pixel alpha will return an array with all
+ opaque values.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ if (surface.get_bytesize () == 1 or
+ surface.get_alpha () is None or
+ surface.get_masks ()[3] == 0):
+ # 1 bpp surfaces and surfaces without per-pixel alpha are always
+ # fully opaque.
+ array = numpy.empty (surface.get_width () * surface.get_height (),
+ numpy.uint8)
+ array.fill (0xff)
+ array.shape = surface.get_width (), surface.get_height ()
+ return array
+
+ array = array2d (surface)
+ if surface.get_bytesize () == 2:
+ # Taken from SDL_GetRGBA.
+ va = (array & surface.get_masks ()[3]) >> surface.get_shifts ()[3]
+ array = ((va << surface.get_losses ()[3]) +
+ (va >> (8 - (surface.get_losses ()[3] << 1))))
+ else:
+ # Taken from _numericsurfarray.c.
+ array = array >> surface.get_shifts ()[3] << surface.get_losses ()[3]
+ array = array.astype (numpy.uint8)
+ return array
+
+def pixels_alpha (surface):
+ """pygame.numpyarray.pixels_alpha (Surface): return array
+
+ reference pixel alphas into a 2d array
+
+ Create a new 2D array that directly references the alpha values
+ (degree of transparency) in a Surface. Any changes to the array will
+ affect the pixels in the Surface. This is a fast operation since no
+ data is copied.
+
+ This can only work on 32-bit Surfaces with a per-pixel alpha value.
+
+ The Surface this array references will remain locked for the
+ lifetime of the array.
+ """
+ if surface.get_bytesize () != 4:
+ raise ValueError("unsupported bit depth for alpha reference array")
+ lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN
+
+ # ARGB surface.
+ start = 0
+
+ if surface.get_shifts ()[3] == 24 and lilendian:
+ # RGBA surface.
+ start = 3
+ elif surface.get_shifts ()[3] == 0 and not lilendian:
+ start = 3
+ else:
+ raise ValueError("unsupported colormasks for alpha reference array")
+
+ array = numpy.ndarray \
+ (shape=(surface.get_width (), surface.get_height ()),
+ dtype=numpy.uint8, buffer=surface.get_buffer (),
+ offset=start, strides=(4, surface.get_pitch ()))
+ return array
+
+def array_colorkey (surface):
+ """pygame.numpyarray.array_colorkey (Surface): return array
+
+ copy the colorkey values into a 2d array
+
+ Create a new array with the colorkey transparency value from each
+ pixel. If the pixel matches the colorkey it will be fully
+ tranparent; otherwise it will be fully opaque.
+
+ This will work on any type of Surface format. If the image has no
+ colorkey a solid opaque array will be returned.
+
+ This function will temporarily lock the Surface as pixels are
+ copied.
+ """
+ colorkey = surface.get_colorkey ()
+ if colorkey == None:
+ # No colorkey, return a solid opaque array.
+ array = numpy.empty (surface.get_width () * surface.get_height (),
+ numpy.uint8)
+ array.fill (0xff)
+ array.shape = surface.get_width (), surface.get_height ()
+ return array
+
+ # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
+ # lot.
+ array = array2d (surface)
+ # Check each pixel value for the colorkey and mark it as opaque or
+ # transparent as needed.
+ val = surface.map_rgb (colorkey)
+ array = numpy.choose (numpy.equal (array, val),
+ (numpy.uint8 (0xff), numpy.uint8 (0)))
+ array.shape = surface.get_width (), surface.get_height ()
+ return array
+
+def make_surface (array):
+ """pygame.numpyarray.make_surface (array): return Surface
+
+ copy an array to a new surface
+
+ Create a new Surface that best resembles the data and format on the
+ array. The array can be 2D or 3D with any sized integer values.
+ """
+ # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
+ # lot.
+ bpp = 0
+ r = g = b = 0
+ shape = array.shape
+ if len (shape) == 2:
+ # 2D array
+ bpp = 8
+ r = 0xFF >> 6 << 5
+ g = 0xFF >> 5 << 2
+ b = 0xFF >> 6
+ elif len (shape) == 3 and shape[2] == 3:
+ bpp = 32
+ r = 0xff << 16
+ g = 0xff << 8
+ b = 0xff
+ else:
+ raise ValueError("must be a valid 2d or 3d array")
+
+ surface = pygame.Surface ((shape[0], shape[1]), 0, bpp, (r, g, b, 0))
+ blit_array (surface, array)
+ return surface
+
+def blit_array (surface, array):
+ """pygame.numpyarray.blit_array (Surface, array): return None
+
+ blit directly from a array values
+
+ Directly copy values from an array into a Surface. This is faster
+ than converting the array into a Surface and blitting. The array
+ must be the same dimensions as the Surface and will completely
+ replace all pixel values.
+
+ This function will temporarily lock the Surface as the new values
+ are copied.
+ """
+ bpp = surface.get_bytesize ()
+ if bpp <= 0 or bpp > 4:
+ raise ValueError("unsupported bit depth for surface")
+
+ shape = array.shape
+ width = surface.get_width ()
+
+ typecode = (numpy.uint8, numpy.uint16, None, numpy.uint32)[bpp - 1]
+ array = array.astype (typecode)
+
+ # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
+ # lot.
+ if len(shape) == 3 and shape[2] == 3:
+ array = numpy.transpose (array, (1, 0, 2))
+ shifts = surface.get_shifts ()
+ losses = surface.get_losses ()
+ array = (array[:,:,::3] >> losses[0] << shifts[0]) | \
+ (array[:,:,1::3] >> losses[1] << shifts[1]) | \
+ (array[:,:,2::3] >> losses[2] << shifts[2])
+ elif len (shape) == 2:
+ array = numpy.transpose (array)
+ else:
+ raise ValueError("must be a valid 2d or 3d array")
+
+ if width != shape[0] or surface.get_height () != shape[1]:
+ raise ValueError("array must match the surface dimensions")
+
+ itemsize = array.itemsize
+ data = array.tostring ()
+
+ if itemsize > bpp:
+ # Trim bytes from each element, keep least significant byte(s)
+ pattern = '%s(%s)' % ('.' * (itemsize - bpp), '.' * bpp)
+ if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
+ pattern = '(%s)%s' % ('.' * bpp, '.' * (itemsize - bpp))
+ data = ''.join (re.compile (pattern, flags=re.DOTALL).findall (data))
+ elif itemsize < bpp:
+ # Add pad bytes to each element, at most significant end
+ pad = '\0' * (bpp - itemsize)
+ pixels = re.compile ('.' * itemsize, flags=re.DOTALL).findall (data)
+ data = pad.join (pixels)
+ if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
+ data = data + pad
+ else:
+ data = pad + data
+
+ # Add zeros pad for pitch correction
+ pitchdiff = surface.get_pitch () - width * bpp
+ if pitchdiff > 0:
+ pad = '\0' * pitchdiff
+ rows = re.compile ('.' * width * bpp, flags=re.DOTALL).findall (data)
+ data = pad.join (rows) + pad
+
+ surface.get_buffer ().write (data, 0)
+
+def map_array (surface, array):
+ """pygame.numpyarray.map_array (Surface, array3d): return array2d
+
+ map a 3d array into a 2d array
+
+ Convert a 3D array into a 2D array. This will use the given Surface
+ format to control the conversion. Palette surface formats are not
+ supported.
+
+ Note: arrays do not need to be 3D, as long as the minor axis has
+ three elements giving the component colours, any array shape can be
+ used (for example, a single colour can be mapped, or an array of
+ colours).
+ """
+ # Taken from from Alex Holkner's pygame-ctypes package. Thanks a
+ # lot.
+ bpp = surface.get_bytesize ()
+ if bpp <= 1 or bpp > 4:
+ raise ValueError("unsupported bit depth for surface array")
+
+ shape = array.shape
+ if shape[-1] != 3:
+ raise ValueError("array must be a 3d array of 3-value color data")
+
+ shifts = surface.get_shifts ()
+ losses = surface.get_losses ()
+ if array.dtype != numpy.int32:
+ array = array.astype(numpy.int32)
+ out = array[...,0] >> losses[0] << shifts[0]
+ out[...] |= array[...,1] >> losses[1] << shifts[1]
+ out[...] |= array[...,2] >> losses[2] << shifts[2]
+ if surface.get_flags() & pygame.SRCALPHA:
+ out[...] |= numpy.int32(255) >> losses[3] << shifts[3]
+ return out
diff --git a/src/pygame/_numpysurfarray.pyo b/src/pygame/_numpysurfarray.pyo
new file mode 100644
index 0000000..612068a
--- /dev/null
+++ b/src/pygame/_numpysurfarray.pyo
Binary files differ
diff --git a/src/pygame/base.so b/src/pygame/base.so
new file mode 100644
index 0000000..6d7d135
--- /dev/null
+++ b/src/pygame/base.so
Binary files differ
diff --git a/src/pygame/bufferproxy.so b/src/pygame/bufferproxy.so
new file mode 100644
index 0000000..623e1c7
--- /dev/null
+++ b/src/pygame/bufferproxy.so
Binary files differ
diff --git a/src/pygame/camera.py b/src/pygame/camera.py
new file mode 100644
index 0000000..618e012
--- /dev/null
+++ b/src/pygame/camera.py
@@ -0,0 +1,144 @@
+
+_is_init = 0
+
+
+
+def init():
+ global list_cameras, Camera, colorspace, _is_init
+
+
+ import os,sys
+
+ use_opencv = False
+ use_vidcapture = False
+ use__camera = True
+
+
+ if sys.platform == 'win32':
+ use_vidcapture = True
+
+ elif "linux" in sys.platform:
+ use__camera = True
+
+ else:
+ use_opencv = True
+
+
+
+ # see if we have any user specified defaults in environments.
+ camera_env = os.environ.get("PYGAME_CAMERA", "")
+ if camera_env == "opencv":
+ use_opencv = True
+ if camera_env == "vidcapture":
+ use_vidcapture = True
+
+
+
+ # select the camera module to import here.
+
+ # the _camera module has some code which can be reused by other modules.
+ # it will also be the default one.
+ import _camera
+ colorspace = _camera.colorspace
+
+ if use__camera:
+ list_cameras = _camera.list_cameras
+ Camera = _camera.Camera
+
+ if use_opencv:
+ try:
+ import _camera_opencv_highgui
+ except:
+ _camera_opencv_highgui = None
+
+ if _camera_opencv_highgui:
+ _camera_opencv_highgui.init()
+
+ list_cameras = _camera_opencv_highgui.list_cameras
+ Camera = _camera_opencv_highgui.Camera
+
+ if use_vidcapture:
+ try:
+ import _camera_vidcapture
+ except:
+ _camera_vidcapture = None
+
+ if _camera_vidcapture:
+ _camera_vidcapture.init()
+ list_cameras = _camera_vidcapture.list_cameras
+ Camera = _camera_vidcapture.Camera
+
+
+
+ _is_init = 1
+ pass
+
+
+def quit():
+ global _is_init
+ _is_init = 0
+ pass
+
+
+def _check_init():
+ global _is_init
+ if not _is_init:
+ raise ValueError("Need to call camera.init() before using.")
+
+def list_cameras():
+ """
+ """
+ _check_init()
+ raise NotImplementedError()
+
+
+class Camera:
+
+ def __init__(self, device =0, size = (320, 200), mode = "RGB"):
+ """
+ """
+ _check_init()
+ raise NotImplementedError()
+
+ def set_resolution(self, width, height):
+ """Sets the capture resolution. (without dialog)
+ """
+ pass
+
+ def start(self):
+ """
+ """
+
+ def stop(self):
+ """
+ """
+
+ def get_buffer(self):
+ """
+ """
+
+ def set_controls(self, **kwargs):
+ """
+ """
+
+ def get_image(self, dest_surf = None):
+ """
+ """
+
+ def get_surface(self, dest_surf = None):
+ """
+ """
+
+
+
+if __name__ == "__main__":
+
+ # try and use this camera stuff with the pygame camera example.
+ import pygame.examples.camera
+
+ #pygame.camera.Camera = Camera
+ #pygame.camera.list_cameras = list_cameras
+ pygame.examples.camera.main()
+
+
+
diff --git a/src/pygame/camera.pyo b/src/pygame/camera.pyo
new file mode 100644
index 0000000..8e30504
--- /dev/null
+++ b/src/pygame/camera.pyo
Binary files differ
diff --git a/src/pygame/cdrom.so b/src/pygame/cdrom.so
new file mode 100644
index 0000000..228df21
--- /dev/null
+++ b/src/pygame/cdrom.so
Binary files differ
diff --git a/src/pygame/color.so b/src/pygame/color.so
new file mode 100644
index 0000000..931bb31
--- /dev/null
+++ b/src/pygame/color.so
Binary files differ
diff --git a/src/pygame/colordict.py b/src/pygame/colordict.py
new file mode 100644
index 0000000..75a83d3
--- /dev/null
+++ b/src/pygame/colordict.py
@@ -0,0 +1,679 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+THECOLORS = {
+'gray17' : (43, 43, 43, 255) ,
+'gold' : (255, 215, 0, 255) ,
+'gray10' : (26, 26, 26, 255) ,
+'yellow' : (255, 255, 0, 255) ,
+'gray11' : (28, 28, 28, 255) ,
+'grey61' : (156, 156, 156, 255) ,
+'grey60' : (153, 153, 153, 255) ,
+'darkseagreen' : (143, 188, 143, 255) ,
+'grey62' : (158, 158, 158, 255) ,
+'grey65' : (166, 166, 166, 255) ,
+'gray12' : (31, 31, 31, 255) ,
+'grey67' : (171, 171, 171, 255) ,
+'grey66' : (168, 168, 168, 255) ,
+'grey69' : (176, 176, 176, 255) ,
+'gray21' : (54, 54, 54, 255) ,
+'lightsalmon4' : (139, 87, 66, 255) ,
+'lightsalmon2' : (238, 149, 114, 255) ,
+'lightsalmon3' : (205, 129, 98, 255) ,
+'lightsalmon1' : (255, 160, 122, 255) ,
+'gray32' : (82, 82, 82, 255) ,
+'green4' : (0, 139, 0, 255) ,
+'gray30' : (77, 77, 77, 255) ,
+'gray31' : (79, 79, 79, 255) ,
+'green1' : (0, 255, 0, 255) ,
+'gray37' : (94, 94, 94, 255) ,
+'green3' : (0, 205, 0, 255) ,
+'green2' : (0, 238, 0, 255) ,
+'darkslategray1' : (151, 255, 255, 255) ,
+'darkslategray2' : (141, 238, 238, 255) ,
+'darkslategray3' : (121, 205, 205, 255) ,
+'aquamarine1' : (127, 255, 212, 255) ,
+'aquamarine3' : (102, 205, 170, 255) ,
+'aquamarine2' : (118, 238, 198, 255) ,
+'papayawhip' : (255, 239, 213, 255) ,
+'black' : (0, 0, 0, 255) ,
+'darkorange3' : (205, 102, 0, 255) ,
+'oldlace' : (253, 245, 230, 255) ,
+'lightgoldenrod4' : (139, 129, 76, 255) ,
+'gray90' : (229, 229, 229, 255) ,
+'orchid1' : (255, 131, 250, 255) ,
+'orchid2' : (238, 122, 233, 255) ,
+'orchid3' : (205, 105, 201, 255) ,
+'grey68' : (173, 173, 173, 255) ,
+'brown' : (165, 42, 42, 255) ,
+'purple2' : (145, 44, 238, 255) ,
+'gray80' : (204, 204, 204, 255) ,
+'antiquewhite3' : (205, 192, 176, 255) ,
+'antiquewhite2' : (238, 223, 204, 255) ,
+'antiquewhite1' : (255, 239, 219, 255) ,
+'palevioletred3' : (205, 104, 137, 255) ,
+'hotpink' : (255, 105, 180, 255) ,
+'lightcyan' : (224, 255, 255, 255) ,
+'coral3' : (205, 91, 69, 255) ,
+'gray8' : (20, 20, 20, 255) ,
+'gray9' : (23, 23, 23, 255) ,
+'grey32' : (82, 82, 82, 255) ,
+'bisque4' : (139, 125, 107, 255) ,
+'cyan' : (0, 255, 255, 255) ,
+'gray0' : (0, 0, 0, 255) ,
+'gray1' : (3, 3, 3, 255) ,
+'gray6' : (15, 15, 15, 255) ,
+'bisque1' : (255, 228, 196, 255) ,
+'bisque2' : (238, 213, 183, 255) ,
+'bisque3' : (205, 183, 158, 255) ,
+'skyblue' : (135, 206, 235, 255) ,
+'gray' : (190, 190, 190, 255) ,
+'darkturquoise' : (0, 206, 209, 255) ,
+'rosybrown4' : (139, 105, 105, 255) ,
+'deepskyblue3' : (0, 154, 205, 255) ,
+'grey63' : (161, 161, 161, 255) ,
+'indianred1' : (255, 106, 106, 255) ,
+'grey78' : (199, 199, 199, 255) ,
+'lightpink' : (255, 182, 193, 255) ,
+'gray88' : (224, 224, 224, 255) ,
+'gray22' : (56, 56, 56, 255) ,
+'red' : (255, 0, 0, 255) ,
+'grey11' : (28, 28, 28, 255) ,
+'lemonchiffon3' : (205, 201, 165, 255) ,
+'lemonchiffon2' : (238, 233, 191, 255) ,
+'lemonchiffon1' : (255, 250, 205, 255) ,
+'indianred3' : (205, 85, 85, 255) ,
+'violetred1' : (255, 62, 150, 255) ,
+'plum2' : (238, 174, 238, 255) ,
+'plum1' : (255, 187, 255, 255) ,
+'lemonchiffon4' : (139, 137, 112, 255) ,
+'gray99' : (252, 252, 252, 255) ,
+'grey13' : (33, 33, 33, 255) ,
+'grey55' : (140, 140, 140, 255) ,
+'darkcyan' : (0, 139, 139, 255) ,
+'chocolate4' : (139, 69, 19, 255) ,
+'lightgoldenrodyellow' : (250, 250, 210, 255) ,
+'gray54' : (138, 138, 138, 255) ,
+'lavender' : (230, 230, 250, 255) ,
+'chartreuse3' : (102, 205, 0, 255) ,
+'chartreuse2' : (118, 238, 0, 255) ,
+'chartreuse1' : (127, 255, 0, 255) ,
+'grey48' : (122, 122, 122, 255) ,
+'grey16' : (41, 41, 41, 255) ,
+'thistle' : (216, 191, 216, 255) ,
+'chartreuse4' : (69, 139, 0, 255) ,
+'darkorchid4' : (104, 34, 139, 255) ,
+'grey42' : (107, 107, 107, 255) ,
+'grey41' : (105, 105, 105, 255) ,
+'grey17' : (43, 43, 43, 255) ,
+'dimgrey' : (105, 105, 105, 255) ,
+'dodgerblue4' : (16, 78, 139, 255) ,
+'darkorchid2' : (178, 58, 238, 255) ,
+'darkorchid3' : (154, 50, 205, 255) ,
+'blue' : (0, 0, 255, 255) ,
+'rosybrown2' : (238, 180, 180, 255) ,
+'honeydew' : (240, 255, 240, 255) ,
+'gray18' : (46, 46, 46, 255) ,
+'cornflowerblue' : (100, 149, 237, 255) ,
+'grey91' : (232, 232, 232, 255) ,
+'gray14' : (36, 36, 36, 255) ,
+'gray15' : (38, 38, 38, 255) ,
+'gray16' : (41, 41, 41, 255) ,
+'maroon4' : (139, 28, 98, 255) ,
+'maroon3' : (205, 41, 144, 255) ,
+'maroon2' : (238, 48, 167, 255) ,
+'maroon1' : (255, 52, 179, 255) ,
+'gray13' : (33, 33, 33, 255) ,
+'gold3' : (205, 173, 0, 255) ,
+'gold2' : (238, 201, 0, 255) ,
+'gold1' : (255, 215, 0, 255) ,
+'grey79' : (201, 201, 201, 255) ,
+'palevioletred1' : (255, 130, 171, 255) ,
+'palevioletred2' : (238, 121, 159, 255) ,
+'gold4' : (139, 117, 0, 255) ,
+'gray41' : (105, 105, 105, 255) ,
+'gray84' : (214, 214, 214, 255) ,
+'mediumpurple' : (147, 112, 219, 255) ,
+'rosybrown1' : (255, 193, 193, 255) ,
+'lightblue2' : (178, 223, 238, 255) ,
+'lightblue3' : (154, 192, 205, 255) ,
+'grey57' : (145, 145, 145, 255) ,
+'lightblue1' : (191, 239, 255, 255) ,
+'lightblue4' : (104, 131, 139, 255) ,
+'gray33' : (84, 84, 84, 255) ,
+'skyblue4' : (74, 112, 139, 255) ,
+'grey97' : (247, 247, 247, 255) ,
+'skyblue1' : (135, 206, 255, 255) ,
+'gray27' : (69, 69, 69, 255) ,
+'skyblue3' : (108, 166, 205, 255) ,
+'skyblue2' : (126, 192, 238, 255) ,
+'lavenderblush1' : (255, 240, 245, 255) ,
+'darkgrey' : (169, 169, 169, 255) ,
+'lavenderblush3' : (205, 193, 197, 255) ,
+'darkslategrey' : (47, 79, 79, 255) ,
+'lavenderblush4' : (139, 131, 134, 255) ,
+'deeppink4' : (139, 10, 80, 255) ,
+'grey99' : (252, 252, 252, 255) ,
+'gray36' : (92, 92, 92, 255) ,
+'coral4' : (139, 62, 47, 255) ,
+'magenta3' : (205, 0, 205, 255) ,
+'lightskyblue4' : (96, 123, 139, 255) ,
+'mediumturquoise' : (72, 209, 204, 255) ,
+'gray34' : (87, 87, 87, 255) ,
+'floralwhite' : (255, 250, 240, 255) ,
+'grey39' : (99, 99, 99, 255) ,
+'grey36' : (92, 92, 92, 255) ,
+'grey37' : (94, 94, 94, 255) ,
+'grey34' : (87, 87, 87, 255) ,
+'gray26' : (66, 66, 66, 255) ,
+'royalblue2' : (67, 110, 238, 255) ,
+'grey33' : (84, 84, 84, 255) ,
+'turquoise1' : (0, 245, 255, 255) ,
+'grey31' : (79, 79, 79, 255) ,
+'steelblue1' : (99, 184, 255, 255) ,
+'sienna4' : (139, 71, 38, 255) ,
+'steelblue3' : (79, 148, 205, 255) ,
+'lavenderblush2' : (238, 224, 229, 255) ,
+'sienna1' : (255, 130, 71, 255) ,
+'steelblue4' : (54, 100, 139, 255) ,
+'sienna3' : (205, 104, 57, 255) ,
+'aquamarine4' : (69, 139, 116, 255) ,
+'lightyellow1' : (255, 255, 224, 255) ,
+'lightyellow2' : (238, 238, 209, 255) ,
+'lightsteelblue' : (176, 196, 222, 255) ,
+'lightyellow4' : (139, 139, 122, 255) ,
+'magenta2' : (238, 0, 238, 255) ,
+'lightskyblue1' : (176, 226, 255, 255) ,
+'lightgoldenrod' : (238, 221, 130, 255) ,
+'magenta4' : (139, 0, 139, 255) ,
+'gray87' : (222, 222, 222, 255) ,
+'greenyellow' : (173, 255, 47, 255) ,
+'navajowhite4' : (139, 121, 94, 255) ,
+'darkslategray4' : (82, 139, 139, 255) ,
+'olivedrab' : (107, 142, 35, 255) ,
+'navajowhite1' : (255, 222, 173, 255) ,
+'navajowhite2' : (238, 207, 161, 255) ,
+'darkgoldenrod1' : (255, 185, 15, 255) ,
+'sienna' : (160, 82, 45, 255) ,
+'blue1' : (0, 0, 255, 255) ,
+'yellow1' : (255, 255, 0, 255) ,
+'gray61' : (156, 156, 156, 255) ,
+'magenta1' : (255, 0, 255, 255) ,
+'grey52' : (133, 133, 133, 255) ,
+'orangered4' : (139, 37, 0, 255) ,
+'palegreen' : (152, 251, 152, 255) ,
+'gray86' : (219, 219, 219, 255) ,
+'grey80' : (204, 204, 204, 255) ,
+'seashell' : (255, 245, 238, 255) ,
+'royalblue' : (65, 105, 225, 255) ,
+'firebrick3' : (205, 38, 38, 255) ,
+'blue4' : (0, 0, 139, 255) ,
+'peru' : (205, 133, 63, 255) ,
+'gray60' : (153, 153, 153, 255) ,
+'aquamarine' : (127, 255, 212, 255) ,
+'grey53' : (135, 135, 135, 255) ,
+'tan4' : (139, 90, 43, 255) ,
+'darkgoldenrod' : (184, 134, 11, 255) ,
+'tan2' : (238, 154, 73, 255) ,
+'tan1' : (255, 165, 79, 255) ,
+'darkslategray' : (47, 79, 79, 255) ,
+'royalblue3' : (58, 95, 205, 255) ,
+'red2' : (238, 0, 0, 255) ,
+'red1' : (255, 0, 0, 255) ,
+'dodgerblue' : (30, 144, 255, 255) ,
+'violetred4' : (139, 34, 82, 255) ,
+'lightyellow' : (255, 255, 224, 255) ,
+'paleturquoise1' : (187, 255, 255, 255) ,
+'firebrick2' : (238, 44, 44, 255) ,
+'mediumaquamarine' : (102, 205, 170, 255) ,
+'lemonchiffon' : (255, 250, 205, 255) ,
+'chocolate' : (210, 105, 30, 255) ,
+'orchid4' : (139, 71, 137, 255) ,
+'maroon' : (176, 48, 96, 255) ,
+'gray38' : (97, 97, 97, 255) ,
+'darkorange4' : (139, 69, 0, 255) ,
+'mintcream' : (245, 255, 250, 255) ,
+'darkorange1' : (255, 127, 0, 255) ,
+'antiquewhite' : (250, 235, 215, 255) ,
+'darkorange2' : (238, 118, 0, 255) ,
+'grey18' : (46, 46, 46, 255) ,
+'grey19' : (48, 48, 48, 255) ,
+'grey38' : (97, 97, 97, 255) ,
+'moccasin' : (255, 228, 181, 255) ,
+'grey10' : (26, 26, 26, 255) ,
+'chocolate1' : (255, 127, 36, 255) ,
+'chocolate2' : (238, 118, 33, 255) ,
+'chocolate3' : (205, 102, 29, 255) ,
+'saddlebrown' : (139, 69, 19, 255) ,
+'grey15' : (38, 38, 38, 255) ,
+'darkslateblue' : (72, 61, 139, 255) ,
+'lightskyblue' : (135, 206, 250, 255) ,
+'gray69' : (176, 176, 176, 255) ,
+'gray68' : (173, 173, 173, 255) ,
+'deeppink' : (255, 20, 147, 255) ,
+'gray65' : (166, 166, 166, 255) ,
+'gray64' : (163, 163, 163, 255) ,
+'gray67' : (171, 171, 171, 255) ,
+'gray66' : (168, 168, 168, 255) ,
+'gray25' : (64, 64, 64, 255) ,
+'coral' : (255, 127, 80, 255) ,
+'gray63' : (161, 161, 161, 255) ,
+'gray62' : (158, 158, 158, 255) ,
+'goldenrod4' : (139, 105, 20, 255) ,
+'grey35' : (89, 89, 89, 255) ,
+'gray89' : (227, 227, 227, 255) ,
+'goldenrod1' : (255, 193, 37, 255) ,
+'goldenrod2' : (238, 180, 34, 255) ,
+'goldenrod3' : (205, 155, 29, 255) ,
+'springgreen1' : (0, 255, 127, 255) ,
+'springgreen2' : (0, 238, 118, 255) ,
+'springgreen3' : (0, 205, 102, 255) ,
+'springgreen4' : (0, 139, 69, 255) ,
+'mistyrose1' : (255, 228, 225, 255) ,
+'sandybrown' : (244, 164, 96, 255) ,
+'grey30' : (77, 77, 77, 255) ,
+'seashell2' : (238, 229, 222, 255) ,
+'seashell3' : (205, 197, 191, 255) ,
+'tan' : (210, 180, 140, 255) ,
+'seashell1' : (255, 245, 238, 255) ,
+'mistyrose3' : (205, 183, 181, 255) ,
+'magenta' : (255, 0, 255, 255) ,
+'pink' : (255, 192, 203, 255) ,
+'ivory2' : (238, 238, 224, 255) ,
+'ivory1' : (255, 255, 240, 255) ,
+'lightcyan2' : (209, 238, 238, 255) ,
+'mediumseagreen' : (60, 179, 113, 255) ,
+'ivory4' : (139, 139, 131, 255) ,
+'darkorange' : (255, 140, 0, 255) ,
+'powderblue' : (176, 224, 230, 255) ,
+'dodgerblue1' : (30, 144, 255, 255) ,
+'gray95' : (242, 242, 242, 255) ,
+'firebrick1' : (255, 48, 48, 255) ,
+'gray7' : (18, 18, 18, 255) ,
+'mistyrose4' : (139, 125, 123, 255) ,
+'tomato' : (255, 99, 71, 255) ,
+'indianred2' : (238, 99, 99, 255) ,
+'steelblue2' : (92, 172, 238, 255) ,
+'gray100' : (255, 255, 255, 255) ,
+'seashell4' : (139, 134, 130, 255) ,
+'grey89' : (227, 227, 227, 255) ,
+'grey88' : (224, 224, 224, 255) ,
+'grey87' : (222, 222, 222, 255) ,
+'grey86' : (219, 219, 219, 255) ,
+'grey85' : (217, 217, 217, 255) ,
+'grey84' : (214, 214, 214, 255) ,
+'midnightblue' : (25, 25, 112, 255) ,
+'grey82' : (209, 209, 209, 255) ,
+'grey81' : (207, 207, 207, 255) ,
+'yellow3' : (205, 205, 0, 255) ,
+'ivory3' : (205, 205, 193, 255) ,
+'grey22' : (56, 56, 56, 255) ,
+'gray85' : (217, 217, 217, 255) ,
+'violetred3' : (205, 50, 120, 255) ,
+'dodgerblue2' : (28, 134, 238, 255) ,
+'gray42' : (107, 107, 107, 255) ,
+'sienna2' : (238, 121, 66, 255) ,
+'grey72' : (184, 184, 184, 255) ,
+'grey73' : (186, 186, 186, 255) ,
+'grey70' : (179, 179, 179, 255) ,
+'palevioletred' : (219, 112, 147, 255) ,
+'lightslategray' : (119, 136, 153, 255) ,
+'grey77' : (196, 196, 196, 255) ,
+'grey74' : (189, 189, 189, 255) ,
+'slategray1' : (198, 226, 255, 255) ,
+'pink1' : (255, 181, 197, 255) ,
+'mediumpurple1' : (171, 130, 255, 255) ,
+'pink3' : (205, 145, 158, 255) ,
+'antiquewhite4' : (139, 131, 120, 255) ,
+'lightpink1' : (255, 174, 185, 255) ,
+'honeydew2' : (224, 238, 224, 255) ,
+'khaki4' : (139, 134, 78, 255) ,
+'darkolivegreen4' : (110, 139, 61, 255) ,
+'gray45' : (115, 115, 115, 255) ,
+'slategray3' : (159, 182, 205, 255) ,
+'darkolivegreen1' : (202, 255, 112, 255) ,
+'khaki1' : (255, 246, 143, 255) ,
+'khaki2' : (238, 230, 133, 255) ,
+'khaki3' : (205, 198, 115, 255) ,
+'lavenderblush' : (255, 240, 245, 255) ,
+'honeydew4' : (131, 139, 131, 255) ,
+'salmon3' : (205, 112, 84, 255) ,
+'salmon2' : (238, 130, 98, 255) ,
+'gray92' : (235, 235, 235, 255) ,
+'salmon4' : (139, 76, 57, 255) ,
+'gray49' : (125, 125, 125, 255) ,
+'gray48' : (122, 122, 122, 255) ,
+'linen' : (250, 240, 230, 255) ,
+'burlywood1' : (255, 211, 155, 255) ,
+'green' : (0, 255, 0, 255) ,
+'gray47' : (120, 120, 120, 255) ,
+'blueviolet' : (138, 43, 226, 255) ,
+'brown2' : (238, 59, 59, 255) ,
+'brown3' : (205, 51, 51, 255) ,
+'peachpuff' : (255, 218, 185, 255) ,
+'brown4' : (139, 35, 35, 255) ,
+'firebrick4' : (139, 26, 26, 255) ,
+'azure1' : (240, 255, 255, 255) ,
+'azure3' : (193, 205, 205, 255) ,
+'azure2' : (224, 238, 238, 255) ,
+'azure4' : (131, 139, 139, 255) ,
+'tomato4' : (139, 54, 38, 255) ,
+'orange4' : (139, 90, 0, 255) ,
+'firebrick' : (178, 34, 34, 255) ,
+'indianred' : (205, 92, 92, 255) ,
+'orange1' : (255, 165, 0, 255) ,
+'orange3' : (205, 133, 0, 255) ,
+'orange2' : (238, 154, 0, 255) ,
+'darkolivegreen' : (85, 107, 47, 255) ,
+'gray2' : (5, 5, 5, 255) ,
+'slategrey' : (112, 128, 144, 255) ,
+'gray81' : (207, 207, 207, 255) ,
+'darkred' : (139, 0, 0, 255) ,
+'gray3' : (8, 8, 8, 255) ,
+'lightsteelblue1' : (202, 225, 255, 255) ,
+'lightsteelblue2' : (188, 210, 238, 255) ,
+'lightsteelblue3' : (162, 181, 205, 255) ,
+'lightsteelblue4' : (110, 123, 139, 255) ,
+'tomato3' : (205, 79, 57, 255) ,
+'gray43' : (110, 110, 110, 255) ,
+'darkgoldenrod4' : (139, 101, 8, 255) ,
+'grey50' : (127, 127, 127, 255) ,
+'yellow4' : (139, 139, 0, 255) ,
+'mediumorchid' : (186, 85, 211, 255) ,
+'yellow2' : (238, 238, 0, 255) ,
+'darkgoldenrod2' : (238, 173, 14, 255) ,
+'darkgoldenrod3' : (205, 149, 12, 255) ,
+'chartreuse' : (127, 255, 0, 255) ,
+'mediumblue' : (0, 0, 205, 255) ,
+'gray4' : (10, 10, 10, 255) ,
+'springgreen' : (0, 255, 127, 255) ,
+'orange' : (255, 165, 0, 255) ,
+'gray5' : (13, 13, 13, 255) ,
+'lightsalmon' : (255, 160, 122, 255) ,
+'gray19' : (48, 48, 48, 255) ,
+'turquoise' : (64, 224, 208, 255) ,
+'lightseagreen' : (32, 178, 170, 255) ,
+'grey8' : (20, 20, 20, 255) ,
+'grey9' : (23, 23, 23, 255) ,
+'grey6' : (15, 15, 15, 255) ,
+'grey7' : (18, 18, 18, 255) ,
+'grey4' : (10, 10, 10, 255) ,
+'grey5' : (13, 13, 13, 255) ,
+'grey2' : (5, 5, 5, 255) ,
+'grey3' : (8, 8, 8, 255) ,
+'grey0' : (0, 0, 0, 255) ,
+'grey1' : (3, 3, 3, 255) ,
+'gray50' : (127, 127, 127, 255) ,
+'goldenrod' : (218, 165, 32, 255) ,
+'grey58' : (148, 148, 148, 255) ,
+'grey59' : (150, 150, 150, 255) ,
+'gray51' : (130, 130, 130, 255) ,
+'grey54' : (138, 138, 138, 255) ,
+'mediumorchid4' : (122, 55, 139, 255) ,
+'grey56' : (143, 143, 143, 255) ,
+'navajowhite3' : (205, 179, 139, 255) ,
+'mediumorchid1' : (224, 102, 255, 255) ,
+'grey51' : (130, 130, 130, 255) ,
+'mediumorchid3' : (180, 82, 205, 255) ,
+'mediumorchid2' : (209, 95, 238, 255) ,
+'cyan2' : (0, 238, 238, 255) ,
+'cyan3' : (0, 205, 205, 255) ,
+'gray23' : (59, 59, 59, 255) ,
+'cyan1' : (0, 255, 255, 255) ,
+'darkgreen' : (0, 100, 0, 255) ,
+'gray24' : (61, 61, 61, 255) ,
+'cyan4' : (0, 139, 139, 255) ,
+'darkviolet' : (148, 0, 211, 255) ,
+'peachpuff4' : (139, 119, 101, 255) ,
+'gray28' : (71, 71, 71, 255) ,
+'slateblue4' : (71, 60, 139, 255) ,
+'slateblue3' : (105, 89, 205, 255) ,
+'peachpuff1' : (255, 218, 185, 255) ,
+'peachpuff2' : (238, 203, 173, 255) ,
+'peachpuff3' : (205, 175, 149, 255) ,
+'gray29' : (74, 74, 74, 255) ,
+'paleturquoise' : (175, 238, 238, 255) ,
+'darkgray' : (169, 169, 169, 255) ,
+'grey25' : (64, 64, 64, 255) ,
+'darkmagenta' : (139, 0, 139, 255) ,
+'palegoldenrod' : (238, 232, 170, 255) ,
+'grey64' : (163, 163, 163, 255) ,
+'grey12' : (31, 31, 31, 255) ,
+'deeppink3' : (205, 16, 118, 255) ,
+'gray79' : (201, 201, 201, 255) ,
+'gray83' : (212, 212, 212, 255) ,
+'deeppink2' : (238, 18, 137, 255) ,
+'burlywood4' : (139, 115, 85, 255) ,
+'palevioletred4' : (139, 71, 93, 255) ,
+'deeppink1' : (255, 20, 147, 255) ,
+'slateblue2' : (122, 103, 238, 255) ,
+'grey46' : (117, 117, 117, 255) ,
+'royalblue4' : (39, 64, 139, 255) ,
+'yellowgreen' : (154, 205, 50, 255) ,
+'royalblue1' : (72, 118, 255, 255) ,
+'slateblue1' : (131, 111, 255, 255) ,
+'lightgoldenrod3' : (205, 190, 112, 255) ,
+'lightgoldenrod2' : (238, 220, 130, 255) ,
+'navy' : (0, 0, 128, 255) ,
+'orchid' : (218, 112, 214, 255) ,
+'ghostwhite' : (248, 248, 255, 255) ,
+'purple' : (160, 32, 240, 255) ,
+'darkkhaki' : (189, 183, 107, 255) ,
+'grey45' : (115, 115, 115, 255) ,
+'gray94' : (240, 240, 240, 255) ,
+'wheat4' : (139, 126, 102, 255) ,
+'gray96' : (245, 245, 245, 255) ,
+'gray97' : (247, 247, 247, 255) ,
+'wheat1' : (255, 231, 186, 255) ,
+'gray91' : (232, 232, 232, 255) ,
+'wheat3' : (205, 186, 150, 255) ,
+'wheat2' : (238, 216, 174, 255) ,
+'indianred4' : (139, 58, 58, 255) ,
+'coral2' : (238, 106, 80, 255) ,
+'coral1' : (255, 114, 86, 255) ,
+'violetred' : (208, 32, 144, 255) ,
+'rosybrown3' : (205, 155, 155, 255) ,
+'deepskyblue2' : (0, 178, 238, 255) ,
+'deepskyblue1' : (0, 191, 255, 255) ,
+'bisque' : (255, 228, 196, 255) ,
+'grey49' : (125, 125, 125, 255) ,
+'khaki' : (240, 230, 140, 255) ,
+'wheat' : (245, 222, 179, 255) ,
+'lightslateblue' : (132, 112, 255, 255) ,
+'mediumpurple3' : (137, 104, 205, 255) ,
+'gray55' : (140, 140, 140, 255) ,
+'deepskyblue' : (0, 191, 255, 255) ,
+'gray98' : (250, 250, 250, 255) ,
+'steelblue' : (70, 130, 180, 255) ,
+'aliceblue' : (240, 248, 255, 255) ,
+'lightskyblue2' : (164, 211, 238, 255) ,
+'lightskyblue3' : (141, 182, 205, 255) ,
+'lightslategrey' : (119, 136, 153, 255) ,
+'blue3' : (0, 0, 205, 255) ,
+'blue2' : (0, 0, 238, 255) ,
+'gainsboro' : (220, 220, 220, 255) ,
+'grey76' : (194, 194, 194, 255) ,
+'purple3' : (125, 38, 205, 255) ,
+'plum4' : (139, 102, 139, 255) ,
+'gray56' : (143, 143, 143, 255) ,
+'plum3' : (205, 150, 205, 255) ,
+'plum' : (221, 160, 221, 255) ,
+'lightgrey' : (211, 211, 211, 255) ,
+'mediumslateblue' : (123, 104, 238, 255) ,
+'mistyrose' : (255, 228, 225, 255) ,
+'lightcyan1' : (224, 255, 255, 255) ,
+'grey71' : (181, 181, 181, 255) ,
+'darksalmon' : (233, 150, 122, 255) ,
+'beige' : (245, 245, 220, 255) ,
+'grey24' : (61, 61, 61, 255) ,
+'azure' : (240, 255, 255, 255) ,
+'honeydew1' : (240, 255, 240, 255) ,
+'slategray2' : (185, 211, 238, 255) ,
+'dodgerblue3' : (24, 116, 205, 255) ,
+'slategray4' : (108, 123, 139, 255) ,
+'grey27' : (69, 69, 69, 255) ,
+'lightcyan3' : (180, 205, 205, 255) ,
+'cornsilk' : (255, 248, 220, 255) ,
+'tomato1' : (255, 99, 71, 255) ,
+'gray57' : (145, 145, 145, 255) ,
+'mediumvioletred' : (199, 21, 133, 255) ,
+'tomato2' : (238, 92, 66, 255) ,
+'snow4' : (139, 137, 137, 255) ,
+'grey75' : (191, 191, 191, 255) ,
+'snow2' : (238, 233, 233, 255) ,
+'snow3' : (205, 201, 201, 255) ,
+'snow1' : (255, 250, 250, 255) ,
+'grey23' : (59, 59, 59, 255) ,
+'cornsilk3' : (205, 200, 177, 255) ,
+'lightcoral' : (240, 128, 128, 255) ,
+'orangered' : (255, 69, 0, 255) ,
+'navajowhite' : (255, 222, 173, 255) ,
+'mediumpurple2' : (159, 121, 238, 255) ,
+'slategray' : (112, 128, 144, 255) ,
+'pink2' : (238, 169, 184, 255) ,
+'grey29' : (74, 74, 74, 255) ,
+'grey28' : (71, 71, 71, 255) ,
+'gray82' : (209, 209, 209, 255) ,
+'burlywood' : (222, 184, 135, 255) ,
+'mediumpurple4' : (93, 71, 139, 255) ,
+'mediumspringgreen' : (0, 250, 154, 255) ,
+'grey26' : (66, 66, 66, 255) ,
+'grey21' : (54, 54, 54, 255) ,
+'grey20' : (51, 51, 51, 255) ,
+'blanchedalmond' : (255, 235, 205, 255) ,
+'pink4' : (139, 99, 108, 255) ,
+'gray78' : (199, 199, 199, 255) ,
+'tan3' : (205, 133, 63, 255) ,
+'gray76' : (194, 194, 194, 255) ,
+'gray77' : (196, 196, 196, 255) ,
+'white' : (255, 255, 255, 255) ,
+'gray75' : (191, 191, 191, 255) ,
+'gray72' : (184, 184, 184, 255) ,
+'gray73' : (186, 186, 186, 255) ,
+'gray70' : (179, 179, 179, 255) ,
+'gray71' : (181, 181, 181, 255) ,
+'lightgray' : (211, 211, 211, 255) ,
+'ivory' : (255, 255, 240, 255) ,
+'gray46' : (117, 117, 117, 255) ,
+'gray74' : (189, 189, 189, 255) ,
+'lightyellow3' : (205, 205, 180, 255) ,
+'lightpink2' : (238, 162, 173, 255) ,
+'lightpink3' : (205, 140, 149, 255) ,
+'paleturquoise4' : (102, 139, 139, 255) ,
+'lightpink4' : (139, 95, 101, 255) ,
+'paleturquoise3' : (150, 205, 205, 255) ,
+'seagreen4' : (46, 139, 87, 255) ,
+'seagreen3' : (67, 205, 128, 255) ,
+'seagreen2' : (78, 238, 148, 255) ,
+'seagreen1' : (84, 255, 159, 255) ,
+'paleturquoise2' : (174, 238, 238, 255) ,
+'gray52' : (133, 133, 133, 255) ,
+'cornsilk4' : (139, 136, 120, 255) ,
+'cornsilk2' : (238, 232, 205, 255) ,
+'darkolivegreen3' : (162, 205, 90, 255) ,
+'cornsilk1' : (255, 248, 220, 255) ,
+'limegreen' : (50, 205, 50, 255) ,
+'darkolivegreen2' : (188, 238, 104, 255) ,
+'grey' : (190, 190, 190, 255) ,
+'violetred2' : (238, 58, 140, 255) ,
+'salmon1' : (255, 140, 105, 255) ,
+'grey92' : (235, 235, 235, 255) ,
+'grey93' : (237, 237, 237, 255) ,
+'grey94' : (240, 240, 240, 255) ,
+'grey95' : (242, 242, 242, 255) ,
+'grey96' : (245, 245, 245, 255) ,
+'grey83' : (212, 212, 212, 255) ,
+'grey98' : (250, 250, 250, 255) ,
+'lightgoldenrod1' : (255, 236, 139, 255) ,
+'palegreen1' : (154, 255, 154, 255) ,
+'red3' : (205, 0, 0, 255) ,
+'palegreen3' : (124, 205, 124, 255) ,
+'palegreen2' : (144, 238, 144, 255) ,
+'palegreen4' : (84, 139, 84, 255) ,
+'cadetblue' : (95, 158, 160, 255) ,
+'violet' : (238, 130, 238, 255) ,
+'mistyrose2' : (238, 213, 210, 255) ,
+'slateblue' : (106, 90, 205, 255) ,
+'grey43' : (110, 110, 110, 255) ,
+'grey90' : (229, 229, 229, 255) ,
+'gray35' : (89, 89, 89, 255) ,
+'turquoise3' : (0, 197, 205, 255) ,
+'turquoise2' : (0, 229, 238, 255) ,
+'burlywood3' : (205, 170, 125, 255) ,
+'burlywood2' : (238, 197, 145, 255) ,
+'lightcyan4' : (122, 139, 139, 255) ,
+'rosybrown' : (188, 143, 143, 255) ,
+'turquoise4' : (0, 134, 139, 255) ,
+'whitesmoke' : (245, 245, 245, 255) ,
+'lightblue' : (173, 216, 230, 255) ,
+'grey40' : (102, 102, 102, 255) ,
+'gray40' : (102, 102, 102, 255) ,
+'honeydew3' : (193, 205, 193, 255) ,
+'dimgray' : (105, 105, 105, 255) ,
+'grey47' : (120, 120, 120, 255) ,
+'seagreen' : (46, 139, 87, 255) ,
+'red4' : (139, 0, 0, 255) ,
+'grey14' : (36, 36, 36, 255) ,
+'snow' : (255, 250, 250, 255) ,
+'darkorchid1' : (191, 62, 255, 255) ,
+'gray58' : (148, 148, 148, 255) ,
+'gray59' : (150, 150, 150, 255) ,
+'cadetblue4' : (83, 134, 139, 255) ,
+'cadetblue3' : (122, 197, 205, 255) ,
+'cadetblue2' : (142, 229, 238, 255) ,
+'cadetblue1' : (152, 245, 255, 255) ,
+'olivedrab4' : (105, 139, 34, 255) ,
+'purple4' : (85, 26, 139, 255) ,
+'gray20' : (51, 51, 51, 255) ,
+'grey44' : (112, 112, 112, 255) ,
+'purple1' : (155, 48, 255, 255) ,
+'olivedrab1' : (192, 255, 62, 255) ,
+'olivedrab2' : (179, 238, 58, 255) ,
+'olivedrab3' : (154, 205, 50, 255) ,
+'orangered3' : (205, 55, 0, 255) ,
+'orangered2' : (238, 64, 0, 255) ,
+'orangered1' : (255, 69, 0, 255) ,
+'darkorchid' : (153, 50, 204, 255) ,
+'thistle3' : (205, 181, 205, 255) ,
+'thistle2' : (238, 210, 238, 255) ,
+'thistle1' : (255, 225, 255, 255) ,
+'salmon' : (250, 128, 114, 255) ,
+'gray93' : (237, 237, 237, 255) ,
+'thistle4' : (139, 123, 139, 255) ,
+'gray39' : (99, 99, 99, 255) ,
+'lawngreen' : (124, 252, 0, 255) ,
+'hotpink3' : (205, 96, 144, 255) ,
+'hotpink2' : (238, 106, 167, 255) ,
+'hotpink1' : (255, 110, 180, 255) ,
+'lightgreen' : (144, 238, 144, 255) ,
+'hotpink4' : (139, 58, 98, 255) ,
+'darkseagreen4' : (105, 139, 105, 255) ,
+'darkseagreen3' : (155, 205, 155, 255) ,
+'darkseagreen2' : (180, 238, 180, 255) ,
+'darkseagreen1' : (193, 255, 193, 255) ,
+'deepskyblue4' : (0, 104, 139, 255) ,
+'gray44' : (112, 112, 112, 255) ,
+'navyblue' : (0, 0, 128, 255) ,
+'darkblue' : (0, 0, 139, 255) ,
+'forestgreen' : (34, 139, 34, 255) ,
+'gray53' : (135, 135, 135, 255) ,
+'grey100' : (255, 255, 255, 255) ,
+'brown1' : (255, 64, 64, 255) ,
+}
diff --git a/src/pygame/colordict.pyo b/src/pygame/colordict.pyo
new file mode 100644
index 0000000..44f5ad3
--- /dev/null
+++ b/src/pygame/colordict.pyo
Binary files differ
diff --git a/src/pygame/compat.py b/src/pygame/compat.py
new file mode 100644
index 0000000..49cefc1
--- /dev/null
+++ b/src/pygame/compat.py
@@ -0,0 +1,47 @@
+"""Python 2.x/3.x compatibility tools"""
+
+import sys
+
+__all__ = ['geterror', 'long_', 'xrange_', 'ord_', 'unichr_',
+ 'unicode_', 'raw_input_']
+
+def geterror ():
+ return sys.exc_info()[1]
+
+try:
+ long_ = long
+except NameError:
+ long_ = int
+
+try:
+ xrange_ = xrange
+except NameError:
+ xrange_ = range
+
+def get_BytesIO():
+ try:
+ from cStringIO import StringIO as BytesIO
+ except ImportError:
+ from io import BytesIO
+ return BytesIO
+
+def ord_(o):
+ try:
+ return ord(o)
+ except TypeError:
+ return o
+
+try:
+ unichr_ = unichr
+except NameError:
+ unichr_ = chr
+
+try:
+ unicode_ = unicode
+except NameError:
+ unicode_ = str
+
+try:
+ raw_input_ = raw_input
+except NameError:
+ raw_input_ = input
diff --git a/src/pygame/compat.pyo b/src/pygame/compat.pyo
new file mode 100644
index 0000000..6494a76
--- /dev/null
+++ b/src/pygame/compat.pyo
Binary files differ
diff --git a/src/pygame/constants.so b/src/pygame/constants.so
new file mode 100644
index 0000000..e985921
--- /dev/null
+++ b/src/pygame/constants.so
Binary files differ
diff --git a/src/pygame/cursors.py b/src/pygame/cursors.py
new file mode 100644
index 0000000..80e20df
--- /dev/null
+++ b/src/pygame/cursors.py
@@ -0,0 +1,300 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+"""Set of cursor resources available for use. These cursors come
+in a sequence of values that are needed as the arguments for
+pygame.mouse.set_cursor(). to dereference the sequence in place
+and create the cursor in one step, call like this;
+pygame.mouse.set_cursor(*pygame.cursors.arrow).
+
+Here is a list of available cursors; arrow, diamond, ball,
+ broken_x, tri_left, tri_right
+
+There is also a sample string cursor named 'thickarrow_strings'.
+The compile() function can convert these string cursors into cursor byte data.
+"""
+
+#default pygame black arrow
+arrow = ((16, 16), (0, 0),
+ (0x00,0x00,0x40,0x00,0x60,0x00,0x70,0x00,0x78,0x00,0x7C,0x00,0x7E,0x00,0x7F,0x00,
+ 0x7F,0x80,0x7C,0x00,0x6C,0x00,0x46,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00),
+ (0x40,0x00,0xE0,0x00,0xF0,0x00,0xF8,0x00,0xFC,0x00,0xFE,0x00,0xFF,0x00,0xFF,0x80,
+ 0xFF,0xC0,0xFF,0x80,0xFE,0x00,0xEF,0x00,0x4F,0x00,0x07,0x80,0x07,0x80,0x03,0x00))
+
+diamond = ((16, 16), (7, 7),
+ (0, 0, 1, 0, 3, 128, 7, 192, 14, 224, 28, 112, 56, 56, 112, 28, 56,
+ 56, 28, 112, 14, 224, 7, 192, 3, 128, 1, 0, 0, 0, 0, 0),
+ (1, 0, 3, 128, 7, 192, 15, 224, 31, 240, 62, 248, 124, 124, 248, 62,
+ 124, 124, 62, 248, 31, 240, 15, 224, 7, 192, 3, 128, 1, 0, 0, 0))
+
+ball = ((16, 16), (7, 7),
+ (0, 0, 3, 192, 15, 240, 24, 248, 51, 252, 55, 252, 127, 254, 127, 254,
+ 127, 254, 127, 254, 63, 252, 63, 252, 31, 248, 15, 240, 3, 192, 0, 0),
+ (3, 192, 15, 240, 31, 248, 63, 252, 127, 254, 127, 254, 255, 255, 255,
+ 255, 255, 255, 255, 255, 127, 254, 127, 254, 63, 252, 31, 248, 15, 240,
+ 3, 192))
+
+broken_x = ((16, 16), (7, 7),
+ (0, 0, 96, 6, 112, 14, 56, 28, 28, 56, 12, 48, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12, 48, 28, 56, 56, 28, 112, 14, 96, 6, 0, 0),
+ (224, 7, 240, 15, 248, 31, 124, 62, 62, 124, 30, 120, 14, 112, 0, 0, 0,
+ 0, 14, 112, 30, 120, 62, 124, 124, 62, 248, 31, 240, 15, 224, 7))
+
+
+tri_left = ((16, 16), (1, 1),
+ (0, 0, 96, 0, 120, 0, 62, 0, 63, 128, 31, 224, 31, 248, 15, 254, 15, 254,
+ 7, 128, 7, 128, 3, 128, 3, 128, 1, 128, 1, 128, 0, 0),
+ (224, 0, 248, 0, 254, 0, 127, 128, 127, 224, 63, 248, 63, 254, 31, 255,
+ 31, 255, 15, 254, 15, 192, 7, 192, 7, 192, 3, 192, 3, 192, 1, 128))
+
+tri_right = ((16, 16), (14, 1),
+ (0, 0, 0, 6, 0, 30, 0, 124, 1, 252, 7, 248, 31, 248, 127, 240, 127, 240,
+ 1, 224, 1, 224, 1, 192, 1, 192, 1, 128, 1, 128, 0, 0),
+ (0, 7, 0, 31, 0, 127, 1, 254, 7, 254, 31, 252, 127, 252, 255, 248, 255,
+ 248, 127, 240, 3, 240, 3, 224, 3, 224, 3, 192, 3, 192, 1, 128))
+
+
+
+#here is an example string resource cursor. to use this;
+# curs, mask = pygame.cursors.compile_cursor(pygame.cursors.thickarrow_strings, 'X', '.')
+# pygame.mouse.set_cursor((24, 24), (0, 0), curs, mask)
+
+thickarrow_strings = ( #sized 24x24
+ "XX ",
+ "XXX ",
+ "XXXX ",
+ "XX.XX ",
+ "XX..XX ",
+ "XX...XX ",
+ "XX....XX ",
+ "XX.....XX ",
+ "XX......XX ",
+ "XX.......XX ",
+ "XX........XX ",
+ "XX........XXX ",
+ "XX......XXXXX ",
+ "XX.XXX..XX ",
+ "XXXX XX..XX ",
+ "XX XX..XX ",
+ " XX..XX ",
+ " XX..XX ",
+ " XX..XX ",
+ " XXXX ",
+ " XX ",
+ " ",
+ " ",
+ " ",
+)
+
+sizer_x_strings = ( #sized 24x16
+ " X X ",
+ " XX XX ",
+ " X.X X.X ",
+ " X..X X..X ",
+ " X...XXXXXXXX...X ",
+ "X................X ",
+ " X...XXXXXXXX...X ",
+ " X..X X..X ",
+ " X.X X.X ",
+ " XX XX ",
+ " X X ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+)
+sizer_y_strings = ( #sized 16x24
+ " X ",
+ " X.X ",
+ " X...X ",
+ " X.....X ",
+ " X.......X ",
+ "XXXXX.XXXXX ",
+ " X.X ",
+ " X.X ",
+ " X.X ",
+ " X.X ",
+ " X.X ",
+ " X.X ",
+ " X.X ",
+ "XXXXX.XXXXX ",
+ " X.......X ",
+ " X.....X ",
+ " X...X ",
+ " X.X ",
+ " X ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+)
+sizer_xy_strings = ( #sized 24x16
+ "XXXXXXXX ",
+ "X.....X ",
+ "X....X ",
+ "X...X ",
+ "X..X.X ",
+ "X.X X.X ",
+ "XX X.X X ",
+ "X X.X XX ",
+ " X.XX.X ",
+ " X...X ",
+ " X...X ",
+ " X....X ",
+ " X.....X ",
+ " XXXXXXXX ",
+ " ",
+ " ",
+)
+textmarker_strings = ( #sized 8x16
+ "ooo ooo ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ " o ",
+ "ooo ooo ",
+ " ",
+ " ",
+ " ",
+ " ",
+)
+
+
+
+def compile(strings, black='X', white='.',xor='o'):
+ """pygame.cursors.compile(strings, black, white,xor) -> data, mask
+compile cursor strings into cursor data
+
+This takes a set of strings with equal length and computes
+the binary data for that cursor. The string widths must be
+divisible by 8.
+
+The black and white arguments are single letter strings that
+tells which characters will represent black pixels, and which
+characters represent white pixels. All other characters are
+considered clear.
+
+This returns a tuple containing the cursor data and cursor mask
+data. Both these arguments are used when setting a cursor with
+pygame.mouse.set_cursor().
+"""
+
+ #first check for consistent lengths
+ size = len(strings[0]), len(strings)
+ if size[0] % 8 or size[1] % 8:
+ raise ValueError("cursor string sizes must be divisible by 8 %s" %
+ size)
+ for s in strings[1:]:
+ if len(s) != size[0]:
+ raise ValueError("Cursor strings are inconsistent lengths")
+
+ #create the data arrays.
+ #this could stand a little optimizing
+ maskdata = []
+ filldata = []
+ maskitem = fillitem = 0
+ step = 8
+ for s in strings:
+ for c in s:
+ maskitem = maskitem << 1
+ fillitem = fillitem << 1
+ step = step - 1
+ if c == black:
+ maskitem = maskitem | 1
+ elif c == white:
+ maskitem = maskitem | 1
+ fillitem = fillitem | 1
+ elif c == xor:
+ fillitem = fillitem | 1
+ if not step:
+ maskdata.append(maskitem)
+ filldata.append(fillitem)
+ maskitem = fillitem = 0
+ step = 8
+ return tuple(filldata), tuple(maskdata)
+
+
+
+
+def load_xbm(curs, mask):
+ """pygame.cursors.load_xbm(cursorfile, maskfile) -> cursor_args
+reads a pair of XBM files into set_cursor arguments
+
+Arguments can either be filenames or filelike objects
+with the readlines method. Not largely tested, but
+should work with typical XBM files.
+"""
+ def bitswap(num):
+ val = 0
+ for x in range(8):
+ b = num&(1<<x) != 0
+ val = val<<1 | b
+ return val
+ if type(curs) is type(''): curs = open(curs)
+ if type(mask) is type(''): mask = open(mask)
+ curs = curs.readlines()
+ mask = mask.readlines()
+ #avoid comments
+ for line in range(len(curs)):
+ if curs[line].startswith("#define"):
+ curs = curs[line:]
+ break
+ for line in range(len(mask)):
+ if mask[line].startswith("#define"):
+ mask = mask[line:]
+ break
+ #load width,height
+ width = int(curs[0].split()[-1])
+ height = int(curs[1].split()[-1])
+ #load hotspot position
+ if curs[2].startswith('#define'):
+ hotx = int(curs[2].split()[-1])
+ hoty = int(curs[3].split()[-1])
+ else:
+ hotx = hoty = 0
+
+ info = width, height, hotx, hoty
+
+ for line in range(len(curs)):
+ if curs[line].startswith('static char') or curs[line].startswith('static unsigned char'):
+ break
+ data = ' '.join(curs[line+1:]).replace('};', '').replace(',', ' ')
+ cursdata = []
+ for x in data.split():
+ cursdata.append(bitswap(int(x, 16)))
+ cursdata = tuple(cursdata)
+
+ for line in range(len(mask)):
+ if mask[line].startswith('static char') or mask[line].startswith('static unsigned char'):
+ break
+ data = ' '.join(mask[line+1:]).replace('};', '').replace(',', ' ')
+ maskdata = []
+ for x in data.split():
+ maskdata.append(bitswap(int(x, 16)))
+ maskdata = tuple(maskdata)
+ return info[:2], info[2:], cursdata, maskdata
diff --git a/src/pygame/cursors.pyo b/src/pygame/cursors.pyo
new file mode 100644
index 0000000..73c6e7f
--- /dev/null
+++ b/src/pygame/cursors.pyo
Binary files differ
diff --git a/src/pygame/display.so b/src/pygame/display.so
new file mode 100644
index 0000000..85c9bcc
--- /dev/null
+++ b/src/pygame/display.so
Binary files differ
diff --git a/src/pygame/draw.so b/src/pygame/draw.so
new file mode 100644
index 0000000..b1e30f7
--- /dev/null
+++ b/src/pygame/draw.so
Binary files differ
diff --git a/src/pygame/event.so b/src/pygame/event.so
new file mode 100644
index 0000000..0823117
--- /dev/null
+++ b/src/pygame/event.so
Binary files differ
diff --git a/src/pygame/fastevent.so b/src/pygame/fastevent.so
new file mode 100644
index 0000000..4aff5de
--- /dev/null
+++ b/src/pygame/fastevent.so
Binary files differ
diff --git a/src/pygame/freesansbold.ttf b/src/pygame/freesansbold.ttf
new file mode 100644
index 0000000..649ebdd
--- /dev/null
+++ b/src/pygame/freesansbold.ttf
Binary files differ
diff --git a/src/pygame/gfxdraw.so b/src/pygame/gfxdraw.so
new file mode 100644
index 0000000..94feade
--- /dev/null
+++ b/src/pygame/gfxdraw.so
Binary files differ
diff --git a/src/pygame/gp2x/.gitignore b/src/pygame/gp2x/.gitignore
new file mode 100644
index 0000000..a74b07a
--- /dev/null
+++ b/src/pygame/gp2x/.gitignore
@@ -0,0 +1 @@
+/*.pyc
diff --git a/src/pygame/gp2x/__init__.py b/src/pygame/gp2x/__init__.py
new file mode 100644
index 0000000..cb298e9
--- /dev/null
+++ b/src/pygame/gp2x/__init__.py
@@ -0,0 +1,24 @@
+
+
+# this lets me know that the module has not been imported.
+# we store it so we don't reimport a module each time the isgp2x function is called.
+_is_gp2x = -1
+
+def isgp2x():
+ """ Returns True if we are running on a gp2x, else False
+ """
+
+ if _is_gp2x == -1:
+ #TODO: FIXME: HACK: need to find a good way to do this.
+ # Use configure to put 'gp2x' in the version string?
+ import sys
+
+ if "arm" in sys.version:
+ _is_gp2x = True
+ else:
+ _is_gp2x = False
+ else:
+ return _is_gp2x
+
+
+
diff --git a/src/pygame/gp2x/constants.py b/src/pygame/gp2x/constants.py
new file mode 100644
index 0000000..6dd4508
--- /dev/null
+++ b/src/pygame/gp2x/constants.py
@@ -0,0 +1,21 @@
+
+# GP2X joystick button mappings
+BUTTON_UP = (0)
+BUTTON_DOWN = (4)
+BUTTON_LEFT = (2)
+BUTTON_RIGHT = (6)
+BUTTON_UPLEFT = (1)
+BUTTON_UPRIGHT = (7)
+BUTTON_DOWNLEFT = (3)
+BUTTON_DOWNRIGHT = (5)
+BUTTON_CLICK = (18)
+BUTTON_A = (12)
+BUTTON_B = (13)
+BUTTON_X = (14)
+BUTTON_Y = (15)
+BUTTON_L = (10)
+BUTTON_R = (11)
+BUTTON_START = (8)
+BUTTON_SELECT = (9)
+BUTTON_VOLUP = (16)
+BUTTON_VOLDOWN = (17)
diff --git a/src/pygame/gp2x/locals.py b/src/pygame/gp2x/locals.py
new file mode 100644
index 0000000..4d5670a
--- /dev/null
+++ b/src/pygame/gp2x/locals.py
@@ -0,0 +1,3 @@
+
+from pygame.gp2x.constants import *
+
diff --git a/src/pygame/image.so b/src/pygame/image.so
new file mode 100644
index 0000000..e01c326
--- /dev/null
+++ b/src/pygame/image.so
Binary files differ
diff --git a/src/pygame/imageext.so b/src/pygame/imageext.so
new file mode 100644
index 0000000..6655f72
--- /dev/null
+++ b/src/pygame/imageext.so
Binary files differ
diff --git a/src/pygame/joystick.so b/src/pygame/joystick.so
new file mode 100644
index 0000000..718a30a
--- /dev/null
+++ b/src/pygame/joystick.so
Binary files differ
diff --git a/src/pygame/key.so b/src/pygame/key.so
new file mode 100644
index 0000000..e7ceac1
--- /dev/null
+++ b/src/pygame/key.so
Binary files differ
diff --git a/src/pygame/locals.py b/src/pygame/locals.py
new file mode 100644
index 0000000..9b1f2fb
--- /dev/null
+++ b/src/pygame/locals.py
@@ -0,0 +1,30 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+
+
+"""Set of functions from PyGame that are handy to have in
+the local namespace for your module"""
+
+from pygame.constants import *
+from pygame.rect import Rect
+import pygame.color as color
+Color = color.Color
+
diff --git a/src/pygame/locals.pyo b/src/pygame/locals.pyo
new file mode 100644
index 0000000..0deb3a8
--- /dev/null
+++ b/src/pygame/locals.pyo
Binary files differ
diff --git a/src/pygame/mac_scrap.py b/src/pygame/mac_scrap.py
new file mode 100644
index 0000000..678c991
--- /dev/null
+++ b/src/pygame/mac_scrap.py
@@ -0,0 +1,139 @@
+#
+# These methods are called internally by pygame.scrap
+#
+from AppKit import *
+from Foundation import *
+
+import sys
+import tempfile
+import pygame.image
+from pygame.locals import SCRAP_TEXT, SCRAP_BMP, SCRAP_SELECTION, SCRAP_CLIPBOARD
+from cStringIO import StringIO
+from pygame.compat import unicode_
+
+ScrapPboardType = unicode_('org.pygame.scrap')
+
+
+err = "Only text has been implemented for scrap on mac. See lib/mac_scrap.py to debug."
+
+
+
+def init():
+ return 1
+
+def get(scrap_type):
+ board = NSPasteboard.generalPasteboard()
+
+ if 0:
+ print (board.types)
+ print (dir(board.types))
+ print (dir(board))
+ print (board.__doc__)
+
+ if scrap_type == SCRAP_TEXT:
+ return board.stringForType_(NSStringPboardType)
+ elif 1:
+ raise NotImplementedError(err)
+
+
+ elif 0 and scrap_type == SCRAP_BMP:
+ # We could try loading directly but I don't trust pygame's TIFF
+ # loading. This is slow and stupid but it does happen to work.
+ if not NSImage.canInitWithPasteboard_(board):
+ return None
+ img = NSImage.alloc().initWithPasteboard_(board)
+ data = img.TIFFRepresentation()
+ rep = NSBitmapImageRep.alloc().initWithData_(data)
+ if rep is None:
+ return None
+
+ # bug with bmp, out of memory error... so we use png.
+ #data = rep.representationUsingType_properties_(NSBMPFileType, None)
+ data = rep.representationUsingType_properties_(NSPNGFileType, None)
+ bmp = StringIO(data)
+ return pygame.image.load(bmp, "scrap.png")
+ #elif scrap_type in board.types:
+ elif scrap_type == SCRAP_BMP:
+ return board.dataForType_(scrap_type)
+ else:
+ return board.stringForType_(scrap_type)
+
+def put(scrap_type, thing):
+ board = NSPasteboard.generalPasteboard()
+ if scrap_type == SCRAP_TEXT:
+ board.declareTypes_owner_([NSStringPboardType, ScrapPboardType], None)
+ if isinstance(thing, unicode):
+ text_thing = thing
+ else:
+ text_thing = unicode(thing, 'utf-8')
+ board.setString_forType_(text_thing, NSStringPboardType)
+ board.setString_forType_(unicode_(''), ScrapPboardType)
+ elif 1:
+ raise NotImplementedError(err)
+
+
+
+
+
+ elif 0 and scrap_type == SCRAP_BMP:
+ # Don't use this code... we put the data in as a string.
+
+ #if type(thing) != type(pygame.Surface((1,1))):
+ # thing = pygame.image.fromstring(thing, len(thing) * 4, "RGBA")
+
+
+ # This is pretty silly, we shouldn't have to do this...
+ fh = tempfile.NamedTemporaryFile(suffix='.png')
+ pygame.image.save(thing, fh.name)
+ path = fh.name
+ if not isinstance(path, unicode):
+ path = unicode(path, sys.getfilesystemencoding())
+ img = NSImage.alloc().initByReferencingFile_(path)
+ tiff = img.TIFFRepresentation()
+ fh.close()
+ board.declareTypes_owner_([NSTIFFPboardType, ScrapPboardType], None)
+ board.setData_forType_(tiff, NSTIFFPboardType)
+ board.setString_forType_(unicode_(''), ScrapPboardType)
+ elif scrap_type == SCRAP_BMP:
+
+ other_type = scrap_type
+ board.declareTypes_owner_([other_type], None)
+ board.setData_forType_(thing, other_type)
+
+ else:
+ other_type = scrap_type
+ if 0:
+ board.declareTypes_owner_([NSStringPboardType, other_type], None)
+ board.setString_forType_(text_thing, NSStringPboardType)
+ elif 0:
+ board.declareTypes_owner_([other_type], None)
+ #board.setString_forType_(thing, other_type)
+ board.setData_forType_(thing, other_type)
+ else:
+ board.declareTypes_owner_([NSStringPboardType, other_type], None)
+ board.setString_forType_(thing, NSStringPboardType)
+
+ #board.setData_forType_(thing, other_type)
+
+
+
+
+
+def set_mode (mode):
+ # No diversion between clipboard and selection modes on MacOS X.
+ if mode not in [SCRAP_SELECTION, SCRAP_CLIPBOARD]:
+ raise ValueError("invalid clipboard mode")
+
+def contains (scrap_type):
+ return scrap_type in NSPasteboard.generalPasteboard ().types ()
+
+def get_types ():
+ typelist = []
+ types = NSPasteboard.generalPasteboard ().types ()
+ for t in types:
+ typelist.append (t)
+ return typelist
+
+def lost ():
+ board = NSPasteboard.generalPasteboard ()
+ return not board.availableTypeFromArray_ ([ScrapPboardType])
diff --git a/src/pygame/macosx.py b/src/pygame/macosx.py
new file mode 100644
index 0000000..db08582
--- /dev/null
+++ b/src/pygame/macosx.py
@@ -0,0 +1,28 @@
+import os, sys
+
+try:
+ import MacOS
+except:
+ MacOS = None
+
+from pygame.pkgdata import getResource
+
+from pygame import sdlmain_osx
+
+__all__ = ['Video_AutoInit']
+
+def Video_AutoInit():
+ """This is a function that's called from the c extension code
+ just before the display module is initialized"""
+ if MacOS and not MacOS.WMAvailable():
+ if not sdlmain_osx.WMEnable():
+ raise ImportError("Can not access the window manager. Use py2app or execute with the pythonw script.")
+ if not sdlmain_osx.RunningFromBundleWithNSApplication():
+ try:
+ default_icon_data = getResource('pygame_icon.tiff').read()
+ except IOError:
+ default_icon_data = None
+ sdlmain_osx.InstallNSApplication(default_icon_data)
+ if (os.getcwd() == '/') and len(sys.argv) > 1:
+ os.chdir(os.path.dirname(sys.argv[0]))
+ return True
diff --git a/src/pygame/mask.so b/src/pygame/mask.so
new file mode 100644
index 0000000..1d5b787
--- /dev/null
+++ b/src/pygame/mask.so
Binary files differ
diff --git a/src/pygame/midi.py b/src/pygame/midi.py
new file mode 100644
index 0000000..4620b92
--- /dev/null
+++ b/src/pygame/midi.py
@@ -0,0 +1,615 @@
+"""pygame.midi
+pygame module for interacting with midi input and output.
+
+The midi module can send output to midi devices, and get input
+from midi devices. It can also list midi devices on the system.
+
+Including real midi devices, and virtual ones.
+
+It uses the portmidi library. Is portable to which ever platforms
+portmidi supports (currently windows, OSX, and linux).
+
+This uses pyportmidi for now, but may use its own bindings at some
+point in the future. The pyportmidi bindings are included with pygame.
+
+New in pygame 1.9.0.
+"""
+
+
+#TODO:
+# - finish writing tests.
+# - likely as interactive tests... so you'd need to plug in a midi device.
+# - create a background thread version for input threads.
+# - that can automatically inject input into the event queue
+# once the input object is running. Like joysticks.
+
+
+
+
+import pygame
+import pygame.locals
+
+import atexit
+
+
+#
+MIDIIN = pygame.locals.USEREVENT + 10
+MIDIOUT = pygame.locals.USEREVENT + 11
+
+_init = False
+_pypm = None
+
+
+__all__ = [ "Input",
+ "MIDIIN",
+ "MIDIOUT",
+ "MidiException",
+ "Output",
+ "get_count",
+ "get_default_input_id",
+ "get_default_output_id",
+ "get_device_info",
+ "init",
+ "midis2events",
+ "quit",
+ "time",
+ ]
+
+__theclasses__ = ["Input", "Output"]
+
+
+def init():
+ """initialize the midi module
+ pygame.midi.init(): return None
+
+ Call the initialisation function before using the midi module.
+
+ It is safe to call this more than once.
+ """
+ global _init, _pypm
+ if not _init:
+ import pygame.pypm
+ _pypm = pygame.pypm
+
+ _pypm.Initialize()
+ _init = True
+ atexit.register(quit)
+
+
+def quit():
+ """uninitialize the midi module
+ pygame.midi.quit(): return None
+
+
+ Called automatically atexit if you don't call it.
+
+ It is safe to call this function more than once.
+ """
+ global _init, _pypm
+ if _init:
+ # TODO: find all Input and Output classes and close them first?
+ _pypm.Terminate()
+ _init = False
+ del _pypm
+ #del pygame._pypm
+
+def _check_init():
+ if not _init:
+ raise RuntimeError("pygame.midi not initialised.")
+
+def get_count():
+ """gets the number of devices.
+ pygame.midi.get_count(): return num_devices
+
+
+ Device ids range from 0 to get_count() -1
+ """
+ _check_init()
+ return _pypm.CountDevices()
+
+
+
+
+def get_default_input_id():
+ """gets default input device number
+ pygame.midi.get_default_input_id(): return default_id
+
+
+ Return the default device ID or -1 if there are no devices.
+ The result can be passed to the Input()/Ouput() class.
+
+ On the PC, the user can specify a default device by
+ setting an environment variable. For example, to use device #1.
+
+ set PM_RECOMMENDED_INPUT_DEVICE=1
+
+ The user should first determine the available device ID by using
+ the supplied application "testin" or "testout".
+
+ In general, the registry is a better place for this kind of info,
+ and with USB devices that can come and go, using integers is not
+ very reliable for device identification. Under Windows, if
+ PM_RECOMMENDED_OUTPUT_DEVICE (or PM_RECOMMENDED_INPUT_DEVICE) is
+ *NOT* found in the environment, then the default device is obtained
+ by looking for a string in the registry under:
+ HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Input_Device
+ and HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Output_Device
+ for a string. The number of the first device with a substring that
+ matches the string exactly is returned. For example, if the string
+ in the registry is "USB", and device 1 is named
+ "In USB MidiSport 1x1", then that will be the default
+ input because it contains the string "USB".
+
+ In addition to the name, get_device_info() returns "interf", which
+ is the interface name. (The "interface" is the underlying software
+ system or API used by PortMidi to access devices. Examples are
+ MMSystem, DirectX (not implemented), ALSA, OSS (not implemented), etc.)
+ At present, the only Win32 interface is "MMSystem", the only Linux
+ interface is "ALSA", and the only Max OS X interface is "CoreMIDI".
+ To specify both the interface and the device name in the registry,
+ separate the two with a comma and a space, e.g.:
+ MMSystem, In USB MidiSport 1x1
+ In this case, the string before the comma must be a substring of
+ the "interf" string, and the string after the space must be a
+ substring of the "name" name string in order to match the device.
+
+ Note: in the current release, the default is simply the first device
+ (the input or output device with the lowest PmDeviceID).
+ """
+ return _pypm.GetDefaultInputDeviceID()
+
+
+
+
+def get_default_output_id():
+ """gets default output device number
+ pygame.midi.get_default_output_id(): return default_id
+
+
+ Return the default device ID or -1 if there are no devices.
+ The result can be passed to the Input()/Ouput() class.
+
+ On the PC, the user can specify a default device by
+ setting an environment variable. For example, to use device #1.
+
+ set PM_RECOMMENDED_OUTPUT_DEVICE=1
+
+ The user should first determine the available device ID by using
+ the supplied application "testin" or "testout".
+
+ In general, the registry is a better place for this kind of info,
+ and with USB devices that can come and go, using integers is not
+ very reliable for device identification. Under Windows, if
+ PM_RECOMMENDED_OUTPUT_DEVICE (or PM_RECOMMENDED_INPUT_DEVICE) is
+ *NOT* found in the environment, then the default device is obtained
+ by looking for a string in the registry under:
+ HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Input_Device
+ and HKEY_LOCAL_MACHINE/SOFTWARE/PortMidi/Recommended_Output_Device
+ for a string. The number of the first device with a substring that
+ matches the string exactly is returned. For example, if the string
+ in the registry is "USB", and device 1 is named
+ "In USB MidiSport 1x1", then that will be the default
+ input because it contains the string "USB".
+
+ In addition to the name, get_device_info() returns "interf", which
+ is the interface name. (The "interface" is the underlying software
+ system or API used by PortMidi to access devices. Examples are
+ MMSystem, DirectX (not implemented), ALSA, OSS (not implemented), etc.)
+ At present, the only Win32 interface is "MMSystem", the only Linux
+ interface is "ALSA", and the only Max OS X interface is "CoreMIDI".
+ To specify both the interface and the device name in the registry,
+ separate the two with a comma and a space, e.g.:
+ MMSystem, In USB MidiSport 1x1
+ In this case, the string before the comma must be a substring of
+ the "interf" string, and the string after the space must be a
+ substring of the "name" name string in order to match the device.
+
+ Note: in the current release, the default is simply the first device
+ (the input or output device with the lowest PmDeviceID).
+ """
+ _check_init()
+ return _pypm.GetDefaultOutputDeviceID()
+
+
+def get_device_info(an_id):
+ """ returns information about a midi device
+ pygame.midi.get_device_info(an_id): return (interf, name, input, output, opened)
+
+ interf - a text string describing the device interface, eg 'ALSA'.
+ name - a text string for the name of the device, eg 'Midi Through Port-0'
+ input - 0, or 1 if the device is an input device.
+ output - 0, or 1 if the device is an output device.
+ opened - 0, or 1 if the device is opened.
+
+ If the id is out of range, the function returns None.
+ """
+ _check_init()
+ return _pypm.GetDeviceInfo(an_id)
+
+
+class Input(object):
+ """Input is used to get midi input from midi devices.
+ Input(device_id)
+ Input(device_id, buffer_size)
+
+ buffer_size -the number of input events to be buffered waiting to
+ be read using Input.read()
+ """
+
+ def __init__(self, device_id, buffer_size=4096):
+ """
+ The buffer_size specifies the number of input events to be buffered
+ waiting to be read using Input.read().
+ """
+ _check_init()
+
+ if device_id == -1:
+ raise MidiException("Device id is -1, not a valid output id. -1 usually means there were no default Output devices.")
+
+ try:
+ r = get_device_info(device_id)
+ except TypeError:
+ raise TypeError("an integer is required")
+ except OverflowError:
+ raise OverflowError("long int too large to convert to int")
+
+ # and now some nasty looking error checking, to provide nice error
+ # messages to the kind, lovely, midi using people of whereever.
+ if r:
+ interf, name, input, output, opened = r
+ if input:
+ try:
+ self._input = _pypm.Input(device_id, buffer_size)
+ except TypeError:
+ raise TypeError("an integer is required")
+ self.device_id = device_id
+
+ elif output:
+ raise MidiException("Device id given is not a valid input id, it is an output id.")
+ else:
+ raise MidiException("Device id given is not a valid input id.")
+ else:
+ raise MidiException("Device id invalid, out of range.")
+
+
+
+
+ def _check_open(self):
+ if self._input is None:
+ raise MidiException("midi not open.")
+
+
+
+ def close(self):
+ """ closes a midi stream, flushing any pending buffers.
+ Input.close(): return None
+
+ PortMidi attempts to close open streams when the application
+ exits -- this is particularly difficult under Windows.
+ """
+ _check_init()
+ if not (self._input is None):
+ self._input.Close()
+ self._input = None
+
+
+
+ def read(self, num_events):
+ """reads num_events midi events from the buffer.
+ Input.read(num_events): return midi_event_list
+
+ Reads from the Input buffer and gives back midi events.
+ [[[status,data1,data2,data3],timestamp],
+ [[status,data1,data2,data3],timestamp],...]
+ """
+ _check_init()
+ self._check_open()
+ return self._input.Read(num_events)
+
+
+ def poll(self):
+ """returns true if there's data, or false if not.
+ Input.poll(): return Bool
+
+ raises a MidiException on error.
+ """
+ _check_init()
+ self._check_open()
+
+ r = self._input.Poll()
+ if r == _pypm.TRUE:
+ return True
+ elif r == _pypm.FALSE:
+ return False
+ else:
+ err_text = GetErrorText(r)
+ raise MidiException( (r, err_text) )
+
+
+
+
+class Output(object):
+ """Output is used to send midi to an output device
+ Output(device_id)
+ Output(device_id, latency = 0)
+ Output(device_id, buffer_size = 4096)
+ Output(device_id, latency, buffer_size)
+
+ The buffer_size specifies the number of output events to be
+ buffered waiting for output. (In some cases -- see below --
+ PortMidi does not buffer output at all and merely passes data
+ to a lower-level API, in which case buffersize is ignored.)
+
+ latency is the delay in milliseconds applied to timestamps to determine
+ when the output should actually occur. (If latency is < 0, 0 is
+ assumed.)
+
+ If latency is zero, timestamps are ignored and all output is delivered
+ immediately. If latency is greater than zero, output is delayed until
+ the message timestamp plus the latency. (NOTE: time is measured
+ relative to the time source indicated by time_proc. Timestamps are
+ absolute, not relative delays or offsets.) In some cases, PortMidi
+ can obtain better timing than your application by passing timestamps
+ along to the device driver or hardware. Latency may also help you
+ to synchronize midi data to audio data by matching midi latency to
+ the audio buffer latency.
+
+ """
+
+ def __init__(self, device_id, latency = 0, buffer_size = 4096):
+ """Output(device_id)
+ Output(device_id, latency = 0)
+ Output(device_id, buffer_size = 4096)
+ Output(device_id, latency, buffer_size)
+
+ The buffer_size specifies the number of output events to be
+ buffered waiting for output. (In some cases -- see below --
+ PortMidi does not buffer output at all and merely passes data
+ to a lower-level API, in which case buffersize is ignored.)
+
+ latency is the delay in milliseconds applied to timestamps to determine
+ when the output should actually occur. (If latency is < 0, 0 is
+ assumed.)
+
+ If latency is zero, timestamps are ignored and all output is delivered
+ immediately. If latency is greater than zero, output is delayed until
+ the message timestamp plus the latency. (NOTE: time is measured
+ relative to the time source indicated by time_proc. Timestamps are
+ absolute, not relative delays or offsets.) In some cases, PortMidi
+ can obtain better timing than your application by passing timestamps
+ along to the device driver or hardware. Latency may also help you
+ to synchronize midi data to audio data by matching midi latency to
+ the audio buffer latency.
+ """
+
+ _check_init()
+ self._aborted = 0
+
+ if device_id == -1:
+ raise MidiException("Device id is -1, not a valid output id. -1 usually means there were no default Output devices.")
+
+ try:
+ r = get_device_info(device_id)
+ except TypeError:
+ raise TypeError("an integer is required")
+ except OverflowError:
+ raise OverflowError("long int too large to convert to int")
+
+ # and now some nasty looking error checking, to provide nice error
+ # messages to the kind, lovely, midi using people of whereever.
+ if r:
+ interf, name, input, output, opened = r
+ if output:
+ try:
+ self._output = _pypm.Output(device_id, latency)
+ except TypeError:
+ raise TypeError("an integer is required")
+ self.device_id = device_id
+
+ elif input:
+ raise MidiException("Device id given is not a valid output id, it is an input id.")
+ else:
+ raise MidiException("Device id given is not a valid output id.")
+ else:
+ raise MidiException("Device id invalid, out of range.")
+
+ def _check_open(self):
+ if self._output is None:
+ raise MidiException("midi not open.")
+
+ if self._aborted:
+ raise MidiException("midi aborted.")
+
+
+ def close(self):
+ """ closes a midi stream, flushing any pending buffers.
+ Output.close(): return None
+
+ PortMidi attempts to close open streams when the application
+ exits -- this is particularly difficult under Windows.
+ """
+ _check_init()
+ if not (self._output is None):
+ self._output.Close()
+ self._output = None
+
+ def abort(self):
+ """terminates outgoing messages immediately
+ Output.abort(): return None
+
+ The caller should immediately close the output port;
+ this call may result in transmission of a partial midi message.
+ There is no abort for Midi input because the user can simply
+ ignore messages in the buffer and close an input device at
+ any time.
+ """
+
+ _check_init()
+ if self._output:
+ self._output.Abort()
+ self._aborted = 1
+
+
+
+
+
+ def write(self, data):
+ """writes a list of midi data to the Output
+ Output.write(data)
+
+ writes series of MIDI information in the form of a list:
+ write([[[status <,data1><,data2><,data3>],timestamp],
+ [[status <,data1><,data2><,data3>],timestamp],...])
+ <data> fields are optional
+ example: choose program change 1 at time 20000 and
+ send note 65 with velocity 100 500 ms later.
+ write([[[0xc0,0,0],20000],[[0x90,60,100],20500]])
+ notes:
+ 1. timestamps will be ignored if latency = 0.
+ 2. To get a note to play immediately, send MIDI info with
+ timestamp read from function Time.
+ 3. understanding optional data fields:
+ write([[[0xc0,0,0],20000]]) is equivalent to
+ write([[[0xc0],20000]])
+
+ Can send up to 1024 elements in your data list, otherwise an
+ IndexError exception is raised.
+ """
+ _check_init()
+ self._check_open()
+
+ self._output.Write(data)
+
+
+ def write_short(self, status, data1 = 0, data2 = 0):
+ """write_short(status <, data1><, data2>)
+ Output.write_short(status)
+ Output.write_short(status, data1 = 0, data2 = 0)
+
+ output MIDI information of 3 bytes or less.
+ data fields are optional
+ status byte could be:
+ 0xc0 = program change
+ 0x90 = note on
+ etc.
+ data bytes are optional and assumed 0 if omitted
+ example: note 65 on with velocity 100
+ write_short(0x90,65,100)
+ """
+ _check_init()
+ self._check_open()
+ self._output.WriteShort(status, data1, data2)
+
+
+ def write_sys_ex(self, when, msg):
+ """writes a timestamped system-exclusive midi message.
+ Output.write_sys_ex(when, msg)
+
+ msg - can be a *list* or a *string*
+ when - a timestamp in miliseconds
+ example:
+ (assuming o is an onput MIDI stream)
+ o.write_sys_ex(0,'\\xF0\\x7D\\x10\\x11\\x12\\x13\\xF7')
+ is equivalent to
+ o.write_sys_ex(pygame.midi.time(),
+ [0xF0,0x7D,0x10,0x11,0x12,0x13,0xF7])
+ """
+ _check_init()
+ self._check_open()
+ self._output.WriteSysEx(when, msg)
+
+
+ def note_on(self, note, velocity=None, channel = 0):
+ """turns a midi note on. Note must be off.
+ Output.note_on(note, velocity=None, channel = 0)
+
+ Turn a note on in the output stream. The note must already
+ be off for this to work correctly.
+ """
+ if velocity is None:
+ velocity = 0
+
+ if not (0 <= channel <= 15):
+ raise ValueError("Channel not between 0 and 15.")
+
+ self.write_short(0x90+channel, note, velocity)
+
+ def note_off(self, note, velocity=None, channel = 0):
+ """turns a midi note off. Note must be on.
+ Output.note_off(note, velocity=None, channel = 0)
+
+ Turn a note off in the output stream. The note must already
+ be on for this to work correctly.
+ """
+ if velocity is None:
+ velocity = 0
+
+ if not (0 <= channel <= 15):
+ raise ValueError("Channel not between 0 and 15.")
+
+ self.write_short(0x80 + channel, note, velocity)
+
+
+ def set_instrument(self, instrument_id, channel = 0):
+ """select an instrument, with a value between 0 and 127
+ Output.set_instrument(instrument_id, channel = 0)
+
+ """
+ if not (0 <= instrument_id <= 127):
+ raise ValueError("Undefined instrument id: %d" % instrument_id)
+
+ if not (0 <= channel <= 15):
+ raise ValueError("Channel not between 0 and 15.")
+
+ self.write_short(0xc0+channel, instrument_id)
+
+
+
+def time():
+ """returns the current time in ms of the PortMidi timer
+ pygame.midi.time(): return time
+
+ The time is reset to 0, when the module is inited.
+ """
+ return _pypm.Time()
+
+
+
+def midis2events(midis, device_id):
+ """converts midi events to pygame events
+ pygame.midi.midis2events(midis, device_id): return [Event, ...]
+
+ Takes a sequence of midi events and returns list of pygame events.
+ """
+ evs = []
+ for midi in midis:
+
+ ((status,data1,data2,data3),timestamp) = midi
+
+ e = pygame.event.Event(MIDIIN,
+ status=status,
+ data1=data1,
+ data2=data2,
+ data3=data3,
+ timestamp=timestamp,
+ vice_id = device_id)
+ evs.append( e )
+
+
+ return evs
+
+
+
+
+
+class MidiException(Exception):
+ """exception that pygame.midi functions and classes can raise
+ MidiException(errno)
+ """
+ def __init__(self, value):
+ self.parameter = value
+ def __str__(self):
+ return repr(self.parameter)
+
+
+
diff --git a/src/pygame/mixer.so b/src/pygame/mixer.so
new file mode 100644
index 0000000..292a3b4
--- /dev/null
+++ b/src/pygame/mixer.so
Binary files differ
diff --git a/src/pygame/mixer_music.so b/src/pygame/mixer_music.so
new file mode 100644
index 0000000..81b6ed2
--- /dev/null
+++ b/src/pygame/mixer_music.so
Binary files differ
diff --git a/src/pygame/mouse.so b/src/pygame/mouse.so
new file mode 100644
index 0000000..fd3ffc6
--- /dev/null
+++ b/src/pygame/mouse.so
Binary files differ
diff --git a/src/pygame/overlay.so b/src/pygame/overlay.so
new file mode 100644
index 0000000..b5668a1
--- /dev/null
+++ b/src/pygame/overlay.so
Binary files differ
diff --git a/src/pygame/pixelarray.so b/src/pygame/pixelarray.so
new file mode 100644
index 0000000..8439472
--- /dev/null
+++ b/src/pygame/pixelarray.so
Binary files differ
diff --git a/src/pygame/pkgdata.py b/src/pygame/pkgdata.py
new file mode 100644
index 0000000..3882ad0
--- /dev/null
+++ b/src/pygame/pkgdata.py
@@ -0,0 +1,66 @@
+"""
+pkgdata is a simple, extensible way for a package to acquire data file
+resources.
+
+The getResource function is equivalent to the standard idioms, such as
+the following minimal implementation:
+
+ import sys, os
+
+ def getResource(identifier, pkgname=__name__):
+ pkgpath = os.path.dirname(sys.modules[pkgname].__file__)
+ path = os.path.join(pkgpath, identifier)
+ return file(os.path.normpath(path), mode='rb')
+
+When a __loader__ is present on the module given by __name__, it will defer
+getResource to its get_data implementation and return it as a file-like
+object (such as StringIO).
+"""
+
+__all__ = ['getResource']
+import sys
+import os
+from pygame.compat import get_BytesIO
+BytesIO = get_BytesIO()
+
+try:
+ from pkg_resources import resource_stream, resource_exists
+except ImportError:
+ def resource_exists(package_or_requirement, resource_name):
+ return False
+ def resource_stream(package_of_requirement, resource_name):
+ raise NotImplementedError
+
+def getResource(identifier, pkgname=__name__):
+ """
+ Acquire a readable object for a given package name and identifier.
+ An IOError will be raised if the resource can not be found.
+
+ For example:
+ mydata = getResource('mypkgdata.jpg').read()
+
+ Note that the package name must be fully qualified, if given, such
+ that it would be found in sys.modules.
+
+ In some cases, getResource will return a real file object. In that
+ case, it may be useful to use its name attribute to get the path
+ rather than use it as a file-like object. For example, you may
+ be handing data off to a C API.
+ """
+ if resource_exists(pkgname, identifier):
+ return resource_stream(pkgname, identifier)
+
+ mod = sys.modules[pkgname]
+ fn = getattr(mod, '__file__', None)
+ if fn is None:
+ raise IOError("%s has no __file__!" % repr(mod))
+ path = os.path.join(os.path.dirname(fn), identifier)
+ loader = getattr(mod, '__loader__', None)
+ if loader is not None:
+ try:
+ data = loader.get_data(path)
+ except IOError:
+ pass
+ else:
+ return BytesIO(data)
+ return open(os.path.normpath(path), 'rb')
diff --git a/src/pygame/pkgdata.pyo b/src/pygame/pkgdata.pyo
new file mode 100644
index 0000000..68eb279
--- /dev/null
+++ b/src/pygame/pkgdata.pyo
Binary files differ
diff --git a/src/pygame/pygame.ico b/src/pygame/pygame.ico
new file mode 100644
index 0000000..9444140
--- /dev/null
+++ b/src/pygame/pygame.ico
Binary files differ
diff --git a/src/pygame/pygame_icon.bmp b/src/pygame/pygame_icon.bmp
new file mode 100644
index 0000000..74aea77
--- /dev/null
+++ b/src/pygame/pygame_icon.bmp
Binary files differ
diff --git a/src/pygame/pygame_icon.icns b/src/pygame/pygame_icon.icns
new file mode 100644
index 0000000..2610a8d
--- /dev/null
+++ b/src/pygame/pygame_icon.icns
Binary files differ
diff --git a/src/pygame/pygame_icon.svg b/src/pygame/pygame_icon.svg
new file mode 100644
index 0000000..bbee79d
--- /dev/null
+++ b/src/pygame/pygame_icon.svg
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="60px"
+ height="80px"
+ viewBox="0 0 60 80"
+ enable-background="new 0 0 60 80"
+ xml:space="preserve"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="pygame_icon.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
+ id="metadata58"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs56"><inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 40 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="60 : 40 : 1"
+ inkscape:persp3d-origin="30 : 26.666667 : 1"
+ id="perspective60" /><inkscape:perspective
+ id="perspective2440"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" /><inkscape:perspective
+ id="perspective2453"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" /><inkscape:perspective
+ id="perspective3380"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" /><inkscape:perspective
+ id="perspective2421"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" /></defs><sodipodi:namedview
+ inkscape:window-height="778"
+ inkscape:window-width="1152"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="0.70710678"
+ inkscape:cx="-84.365192"
+ inkscape:cy="149.21001"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:current-layer="Layer_1" />
+
+
+<linearGradient
+ id="SVGID_1_"
+ gradientUnits="userSpaceOnUse"
+ x1="2.25"
+ y1="-709.8901"
+ x2="21.3792"
+ y2="-739.0623"
+ gradientTransform="matrix(1 0 0 -1 16.7773 -683.9258)">
+ <stop
+ offset="0"
+ style="stop-color:#F6F2EE"
+ id="stop8" />
+ <stop
+ offset="1"
+ style="stop-color:#C9C9C9"
+ id="stop10" />
+</linearGradient>
+
+<linearGradient
+ id="SVGID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="28.5786"
+ y1="-733.7891"
+ x2="29.9126"
+ y2="-709.7885"
+ gradientTransform="matrix(1 0 0 -1 16.7773 -683.9258)">
+ <stop
+ offset="0"
+ style="stop-color:#1E1E1E"
+ id="stop15" />
+ <stop
+ offset="0.0051"
+ style="stop-color:#1E1E1E"
+ id="stop17" />
+ <stop
+ offset="0.269"
+ style="stop-color:#818181"
+ id="stop19" />
+ <stop
+ offset="1"
+ style="stop-color:#F4F4F4"
+ id="stop21" />
+</linearGradient>
+
+<linearGradient
+ id="SVGID_3_"
+ gradientUnits="userSpaceOnUse"
+ x1="-2.604"
+ y1="-704.4819"
+ x2="28.278"
+ y2="-710.9611"
+ gradientTransform="matrix(1 0 0 -1 16.7773 -683.9258)">
+ <stop
+ offset="0"
+ style="stop-color:#1E1E1E"
+ id="stop26" />
+ <stop
+ offset="0.0051"
+ style="stop-color:#1E1E1E"
+ id="stop28" />
+ <stop
+ offset="0.269"
+ style="stop-color:#818181"
+ id="stop30" />
+ <stop
+ offset="1"
+ style="stop-color:#F4F4F4"
+ id="stop32" />
+</linearGradient>
+
+
+
+
+
+<linearGradient
+ id="SVGID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.9478"
+ y1="-710.1436"
+ x2="14.2379"
+ y2="-723.1246"
+ gradientTransform="matrix(1 0 0 -1 16.7773 -683.9258)">
+ <stop
+ offset="0"
+ style="stop-color:#CDFF62"
+ id="stop45" />
+ <stop
+ offset="1"
+ style="stop-color:#208D10"
+ id="stop47" />
+</linearGradient>
+
+
+
+<path
+ style="fill:#000000"
+ d="M 6.0625002,31.15625 C 5.4755912,32.75857 9.804432,36.245737 10.817862,38.715228 C 2.6294009,45.137224 3.114177,56.342511 13.0625,59.53125 C 13.925059,62.568817 13.43661,65.499102 13.03125,68.5625 C 22.181831,66.474865 31.979299,70.160448 41.1875,68.34375 C 41.70833,66.614583 42.22917,64.885417 42.75,63.15625 C 46.263429,63.066397 49.315872,61.38125 51.19368,59.167237 C 52.59928,56.8553 52.66245,55.874378 53.375,54.21875 C 53.42378,50.791067 53.971504,48.436474 50.146447,43.710786 C 52.968616,40.744393 57.665277,40.18157 57.509803,33.429536 C 54.840901,22.560563 53.553361,9.8348491 43.5625,10.875 C 34.983651,14.005339 34.517846,14.081982 26.600653,8.8479148 C 13.505974,5.7264452 9.819702,17.795952 6.0625002,31.15625 z"
+ id="path3438"
+ sodipodi:nodetypes="ccccccccccccc" /><path
+ style="opacity:1;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 34.83566,58.353365 C 34.83566,58.353365 27.111209,56.308647 19.852321,56.555879 C 16.902651,60.510116 11.859477,58.751271 8.7400901,56.2009 C 3.7897777,52.70351 4.7783555,41.611729 12.616342,40.133859 C 15.981685,40.043849 16.052433,42.239978 15.787268,43.344832 L 19.911305,44.966202 C 24.183161,48.278743 29.071391,48.788884 34.274165,49.025535 C 35.693377,48.596117 38.266467,49.827405 46.115186,44.383304 C 48.049466,44.274237 49.178075,44.65545 50.39527,46.155422 C 53.748612,52.07827 53.158448,59.554458 46.362067,61.724318 C 42.082123,63.218982 37.200554,62.775485 34.83566,58.353365 z M 29.007029,54.768175 L 32.15502,52.261618 C 31.795216,51.855794 31.403226,51.479619 31.024222,51.09341 C 29.766946,51.364815 28.264719,52.649626 27.452493,53.386611 C 28.206908,54.354204 28.045524,54.162504 29.007031,54.768175 L 29.007029,54.768175 z M 26.9625,51.775367 L 25.80625,50.590092 C 24.530621,51.016899 23.43357,51.686772 22.427971,52.525103 C 22.47497,53.123259 23.120953,53.617283 23.518966,54.081261 C 24.74624,53.439537 25.850799,52.594685 26.9625,51.775367 z"
+ id="path3297"
+ sodipodi:nodetypes="cccccccccccccccccccccc" /><path
+ style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 41.411185,63.538147 C 40.862001,65.230806 40.328,66.894226 39.620461,68.527689 C 39.609277,68.549793 39.85982,68.930791 33.804431,68.910322 C 32.809584,68.833796 36.590003,62.803491 36.590003,62.803491 C 38.030752,62.219124 40.456215,63.26514 41.411185,63.538147 z"
+ id="rect3232"
+ sodipodi:nodetypes="ccccc" /><path
+ style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 26.904673,46.797124 C 20.969146,45.334823 14.237796,41.647852 16.097175,34.698527 C 18.850352,29.350268 25.323633,28.578519 30.772091,28.649807 C 35.44377,29.134754 40.166669,30.377137 43.78779,33.457398 C 46.00654,35.394898 47.744868,38.546385 47.432368,40.921385 C 43.022816,47.679997 34.150015,48.575449 26.904673,46.797124 z M 40.154161,40.292924 L 40.714062,38.310191 C 38.339062,36.903941 35.705945,37.443389 35.705945,37.443389 C 36.43826,38.044487 37.386179,37.888872 39.277127,38.420195 C 39.360151,39.369328 39.816488,40.081708 40.154161,40.292924 z M 27.304173,36.985532 C 25.960113,35.721121 24.225545,35.413216 22.376245,35.657674 L 25.892092,36.680152 C 26.258467,37.396891 26.198758,38.528417 26.910334,38.725903 L 27.304173,36.985532 z"
+ id="path2400"
+ sodipodi:nodetypes="cccccccccccccccc" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3283"
+ width="3.6732819"
+ height="3.3059537"
+ x="40.804043"
+ y="54.378857"
+ ry="1.6529769" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3287"
+ width="3.6732819"
+ height="3.3059537"
+ x="40.620377"
+ y="47.338398"
+ ry="1.6529769" /><path
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.96399999;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 40.909092,46.77489 L 44.437231,45.064934 L 43.203464,50.108224 L 41.688312,56.147185 L 40.909092,46.77489 z"
+ id="rect2427"
+ sodipodi:nodetypes="ccccc" /><g
+ id="g3208"
+ transform="matrix(0.9952934,9.6907835e-2,-9.6907835e-2,0.9952934,4.9097047,-0.9777908)"><rect
+ y="47.96537"
+ x="11.168831"
+ height="2.943723"
+ width="8.0086584"
+ id="rect3204"
+ style="opacity:1;fill:#37483e;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><rect
+ transform="matrix(0,-1,1,0,0,0)"
+ y="13.593073"
+ x="-53.484848"
+ height="2.943723"
+ width="8.0086584"
+ id="rect3206"
+ style="opacity:1;fill:#37483e;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g><path
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.96399999;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 16.287879,41.233766 L 19.599567,44.285715 L 18.409091,47.770563 L 16.374458,52.683983 L 16.287879,41.233766 z"
+ id="path3200"
+ sodipodi:nodetypes="ccccc" /><path
+ style="opacity:1;fill:#536c5d;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 41.349896,61.651128 C 37.845105,61.086451 35.005761,58.62026 34.074909,55.332235 C 33.565586,53.533166 34.299285,50.653861 34.99236,48.906297 C 38.932124,48.021926 38.507685,48.159224 40.497273,47.497837 C 40.882703,48.083562 39.93799,47.223727 36.167071,50.28089 C 35.469597,51.031822 35.727921,51.743665 35.843393,52.597304 C 36.558201,53.980008 37.199452,54.489087 38.209684,54.475864 C 39.218234,54.357706 40.059555,53.692975 40.916276,53.181746 L 41.011827,54.122399 C 40.31447,54.421021 39.580602,55.571678 39.16289,56.137653 C 40.203945,57.712117 40.918611,58.31261 42.702701,58.916148 C 43.022191,58.786186 47.743183,55.892434 48.399619,55.424199 C 50.079153,53.218703 48.498372,51.202973 46.05089,51.048422 C 45.031785,51.583271 44.063793,52.212741 43.077884,52.80614 C 43.060535,52.80614 43.111108,52.551306 43.190269,52.239842 C 43.350727,51.608509 43.301237,51.665376 44.177133,51.105872 C 45.107366,50.511658 45.474486,49.894989 45.405993,49.0417 L 44.464821,47.081942 L 44.96347,45.083488 C 45.213265,44.864277 45.588176,44.759813 45.849667,44.624328 C 48.385224,45.729912 50.242988,47.532111 51.319238,50.10171 C 51.874261,51.604012 51.783228,53.177017 51.614538,54.729351 C 51.165478,57.018696 49.797475,58.645632 48.074135,60.111094 C 46.032381,61.549913 43.766487,61.796119 41.349896,61.651129 L 41.349896,61.651128 z"
+ id="path3279"
+ sodipodi:nodetypes="csccccccccccccssccccccccc" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3281"
+ width="3.6732819"
+ height="3.3059537"
+ x="36.855263"
+ y="49.756641"
+ ry="1.6529769" /><rect
+ style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3285"
+ width="3.6732819"
+ height="3.3059537"
+ x="44.385494"
+ y="52.174889"
+ ry="1.6529769" /><path
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.96399999000000003;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 17.261234,19.22186 C 18.687437,15.983179 19.868153,12.933425 23.7425,12.459102 C 27.443906,13.181308 29.102534,14.802085 29.89248,18.309789 C 30.809114,21.508426 29.131471,27.703534 27.726962,27.826041 C 21.197455,28.45626 21.026889,29.796059 20.182662,29.110936 C 15.932662,25.267186 17.261234,19.22186 17.261234,19.22186 z M 26.360848,27.159488 C 27.52292,26.707735 28.034238,25.361974 27.414877,24.385343 C 27.101272,23.890842 26.432691,23.511316 25.859921,23.502656 C 24.844676,23.48731 23.930592,24.671422 24.085461,25.80131 C 24.17975,26.489247 24.520131,26.951791 25.14171,27.236656 C 25.4834,27.393251 25.813235,27.372373 26.360849,27.159488 L 26.360848,27.159488 z"
+ id="path3303"
+ sodipodi:nodetypes="cccccccsssscc" /><path
+ style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 48.151277,41.561797 C 49.256131,37.584321 45.203928,33.206819 45.203928,33.206819 C 49.976899,28.831596 48.858908,28.983089 50.171239,26.453572 C 50.171239,26.453572 53.048624,15.362505 44.364468,14.014583 C 36.274365,15.236803 36.423234,22.224316 35.937396,28.361312 C 35.937396,28.361312 32.316792,28.095191 28.963273,27.592215 C 31.482341,23.968293 31.002331,18.485773 31.002331,18.485773 C 31.002331,18.485773 29.664696,11.455903 23.539696,11.424653 C 15.868054,13.999582 14.436386,23.401645 19.01722,29.334126 C 16.265187,31.803178 15.141944,34.093723 14.499327,37.819102 C 10.311827,38.319102 7.0945784,32.660279 7.4695784,30.785279 C 7.367652,29.370852 13.027429,9.397206 22.038308,9.4530173 C 25.29466,9.1407473 29.758071,12.311301 31.270794,13.490862 C 32.762223,14.653819 34.693473,15.569325 37.506274,14.41894 C 39.519655,13.595503 43.210123,12.131697 43.210123,12.131697 C 53.207838,12.811481 53.763945,21.872792 55.591076,30.215705 C 55.591076,30.215705 57.642055,34.675163 55.579555,37.362663 C 54.694475,39.173054 52.761728,39.873738 50.964504,40.725286 C 49.045682,41.197621 50.138565,41.003654 48.151272,41.561797 L 48.151277,41.561797 z"
+ id="path3277"
+ sodipodi:nodetypes="ccccccccccccsscccccc" /><path
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 36.789201,28.38606 C 36.426214,24.041015 37.074368,21.275933 39.141406,17.861334 C 40.854494,15.781043 42.027045,14.809894 45.529584,15.361908 C 48.777451,16.036821 50.817857,20.657491 48.8331,26.423784 C 48.11726,29.000261 46.343194,30.830078 44.150433,32.184218 L 36.789201,28.38606 z M 40.264281,28.957014 C 41.193715,28.681002 41.701862,28.084986 41.778687,27.180737 C 41.88186,25.966362 40.67561,25.124688 39.374241,25.503006 C 38.827321,25.661998 38.264184,26.203743 38.086649,26.741679 C 37.826966,28.497777 38.725234,28.941984 40.264281,28.957014 z"
+ id="path3305"
+ sodipodi:nodetypes="cccccccsscc" /><path
+ style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:0.96399999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 18.697774,64.320219 C 14.122532,54.163315 38.504358,55.978714 34.212234,65.380617 C 28.687716,67.70281 23.672679,67.080098 18.697774,64.320219 z"
+ id="path3307"
+ sodipodi:nodetypes="ccc" /></svg> \ No newline at end of file
diff --git a/src/pygame/pygame_icon.tiff b/src/pygame/pygame_icon.tiff
new file mode 100644
index 0000000..e779143
--- /dev/null
+++ b/src/pygame/pygame_icon.tiff
Binary files differ
diff --git a/src/pygame/rect.so b/src/pygame/rect.so
new file mode 100644
index 0000000..6f158e6
--- /dev/null
+++ b/src/pygame/rect.so
Binary files differ
diff --git a/src/pygame/rwobject.so b/src/pygame/rwobject.so
new file mode 100644
index 0000000..5bb0b8d
--- /dev/null
+++ b/src/pygame/rwobject.so
Binary files differ
diff --git a/src/pygame/scrap.so b/src/pygame/scrap.so
new file mode 100644
index 0000000..b852608
--- /dev/null
+++ b/src/pygame/scrap.so
Binary files differ
diff --git a/src/pygame/sndarray.py b/src/pygame/sndarray.py
new file mode 100644
index 0000000..90a1142
--- /dev/null
+++ b/src/pygame/sndarray.py
@@ -0,0 +1,187 @@
+## pygame - Python Game Library
+## Copyright (C) 2008 Marcus von Appen
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Marcus von Appen
+## mva@sysfault.org
+
+"""pygame module for accessing sound sample data
+
+Functions to convert between Numeric or numpy arrays and Sound
+objects. This module will only be available when pygame can use the
+external numpy or Numeric package.
+
+Sound data is made of thousands of samples per second, and each sample
+is the amplitude of the wave at a particular moment in time. For
+example, in 22-kHz format, element number 5 of the array is the
+amplitude of the wave after 5/22000 seconds.
+
+Each sample is an 8-bit or 16-bit integer, depending on the data format.
+A stereo sound file has two values per sample, while a mono sound file
+only has one.
+
+Supported array systems are
+
+ numpy
+ numeric
+
+The default will be numpy, if installed. Otherwise, Numeric will be set
+as default if installed. If neither numpy nor Numeric are installed, the
+module will raise an ImportError.
+
+The array type to use can be changed at runtime using the use_arraytype()
+method, which requires one of the above types as string.
+
+Note: numpy and Numeric are not completely compatible. Certain array
+manipulations, which work for one type, might behave differently or even
+completely break for the other.
+
+Additionally, in contrast to Numeric numpy can use unsigned 16-bit
+integers. Sounds with 16-bit data will be treated as unsigned integers,
+if the sound sample type requests this. Numeric instead always uses
+signed integers for the representation, which is important to keep in
+mind, if you use the module's functions and wonder about the values.
+"""
+
+import pygame
+
+# Global array type setting. See use_arraytype().
+__arraytype = None
+
+# Try to import the necessary modules.
+try:
+ import pygame._numpysndarray as numpysnd
+ __hasnumpy = True
+ __arraytype = "numpy"
+except ImportError:
+ __hasnumpy = False
+
+try:
+ import pygame._numericsndarray as numericsnd
+ __hasnumeric = True
+ if not __hasnumpy:
+ __arraytype = "numeric"
+except ImportError:
+ __hasnumeric = False
+
+if not __hasnumpy and not __hasnumeric:
+ raise ImportError("no module named numpy or Numeric found")
+
+def array (sound):
+ """pygame.sndarray.array(Sound): return array
+
+ Copy Sound samples into an array.
+
+ Creates a new array for the sound data and copies the samples. The
+ array will always be in the format returned from
+ pygame.mixer.get_init().
+ """
+ if __arraytype == "numeric":
+ return numericsnd.array (sound)
+ elif __arraytype == "numpy":
+ return numpysnd.array (sound)
+ raise NotImplementedError("sound arrays are not supported")
+
+def samples (sound):
+ """pygame.sndarray.samples(Sound): return array
+
+ Reference Sound samples into an array.
+
+ Creates a new array that directly references the samples in a Sound
+ object. Modifying the array will change the Sound. The array will
+ always be in the format returned from pygame.mixer.get_init().
+ """
+ if __arraytype == "numeric":
+ return numericsnd.samples (sound)
+ elif __arraytype == "numpy":
+ return numpysnd.samples (sound)
+ raise NotImplementedError("sound arrays are not supported")
+
+def make_sound (array):
+ """pygame.sndarray.make_sound(array): return Sound
+
+ Convert an array into a Sound object.
+
+ Create a new playable Sound object from an array. The mixer module
+ must be initialized and the array format must be similar to the mixer
+ audio format.
+ """
+ if __arraytype == "numeric":
+ return numericsnd.make_sound (array)
+ elif __arraytype == "numpy":
+ return numpysnd.make_sound (array)
+ raise NotImplementedError("sound arrays are not supported")
+
+def use_arraytype (arraytype):
+ """pygame.sndarray.use_arraytype (arraytype): return None
+
+ Sets the array system to be used for sound arrays.
+
+ Uses the requested array type for the module functions.
+ Currently supported array types are:
+
+ numeric
+ numpy
+
+ If the requested type is not available, a ValueError will be raised.
+ """
+ global __arraytype
+
+ arraytype = arraytype.lower ()
+ if arraytype == "numeric":
+ if __hasnumeric:
+ __arraytype = arraytype
+ else:
+ raise ValueError("Numeric arrays are not available")
+
+ elif arraytype == "numpy":
+ if __hasnumpy:
+ __arraytype = arraytype
+ else:
+ raise ValueError("numpy arrays are not available")
+ else:
+ raise ValueError("invalid array type")
+
+def get_arraytype ():
+ """pygame.sndarray.get_arraytype (): return str
+
+ Gets the currently active array type.
+
+ Returns the currently active array type. This will be a value of the
+ get_arraytypes() tuple and indicates which type of array module is
+ used for the array creation.
+ """
+ return __arraytype
+
+def get_arraytypes ():
+ """pygame.sndarray.get_arraytypes (): return tuple
+
+ Gets the array system types currently supported.
+
+ Checks, which array system types are available and returns them as a
+ tuple of strings. The values of the tuple can be used directly in
+ the use_arraytype () method.
+
+ If no supported array system could be found, None will be returned.
+ """
+ vals = []
+ if __hasnumeric:
+ vals.append ("numeric")
+ if __hasnumpy:
+ vals.append ("numpy")
+ if len (vals) == 0:
+ return None
+ return tuple (vals)
diff --git a/src/pygame/sndarray.pyo b/src/pygame/sndarray.pyo
new file mode 100644
index 0000000..d094140
--- /dev/null
+++ b/src/pygame/sndarray.pyo
Binary files differ
diff --git a/src/pygame/sprite.py b/src/pygame/sprite.py
new file mode 100644
index 0000000..5ed2af4
--- /dev/null
+++ b/src/pygame/sprite.py
@@ -0,0 +1,1423 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003, 2007 Pete Shinners
+## (C) 2004 Joe Wreschnig
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+"""pygame module with basic game object classes
+
+This module contains several simple classes to be used within games. There
+is the main Sprite class and several Group classes that contain Sprites.
+The use of these classes is entirely optional when using Pygame. The classes
+are fairly lightweight and only provide a starting place for the code
+that is common to most games.
+
+The Sprite class is intended to be used as a base class for the different
+types of objects in the game. There is also a base Group class that simply
+stores sprites. A game could create new types of Group classes that operate
+on specially customized Sprite instances they contain.
+
+The basic Sprite class can draw the Sprites it contains to a Surface. The
+Group.draw() method requires that each Sprite have a Surface.image attribute
+and a Surface.rect. The Group.clear() method requires these same attributes,
+and can be used to erase all the Sprites with background. There are also
+more advanced Groups: pygame.sprite.RenderUpdates() and
+pygame.sprite.OrderedUpdates().
+
+Lastly, this module contains several collision functions. These help find
+sprites inside multiple groups that have intersecting bounding rectangles.
+To find the collisions, the Sprites are required to have a Surface.rect
+attribute assigned.
+
+The groups are designed for high efficiency in removing and adding Sprites
+to them. They also allow cheap testing to see if a Sprite already exists in
+a Group. A given Sprite can exist in any number of groups. A game could use
+some groups to control object rendering, and a completely separate set of
+groups to control interaction or player movement. Instead of adding type
+attributes or bools to a derived Sprite class, consider keeping the
+Sprites inside organized Groups. This will allow for easier lookup later
+in the game.
+
+Sprites and Groups manage their relationships with the add() and remove()
+methods. These methods can accept a single or multiple targets for
+membership. The default initializers for these classes also takes a
+single or list of targets for initial membership. It is safe to repeatedly
+add and remove the same Sprite from a Group.
+
+While it is possible to design sprite and group classes that don't derive
+from the Sprite and AbstractGroup classes below, it is strongly recommended
+that you extend those when you add a Sprite or Group class.
+
+Sprites are not thread safe. So lock them yourself if using threads.
+"""
+
+##todo
+## a group that holds only the 'n' most recent elements.
+## sort of like the GroupSingle class, but holding more
+## than one sprite
+##
+## drawing groups that can 'automatically' store the area
+## underneath, so the can "clear" without needing a background
+## function. obviously a little slower than normal, but nice
+## to use in many situations. (also remember it must "clear"
+## in the reverse order that it draws :])
+##
+## the drawing groups should also be able to take a background
+## function, instead of just a background surface. the function
+## would take a surface and a rectangle on that surface to erase.
+##
+## perhaps more types of collision functions? the current two
+## should handle just about every need, but perhaps more optimized
+## specific ones that aren't quite so general but fit into common
+## specialized cases.
+
+import pygame
+from pygame import Rect
+from pygame.time import get_ticks
+
+# Don't depend on pygame.mask if it's not there...
+try:
+ from pygame.mask import from_surface
+except:
+ pass
+
+
+class Sprite(object):
+ """simple base class for visible game objects
+ pygame.sprite.Sprite(*groups): return Sprite
+
+ The base class for visible game objects. Derived classes will want to
+ override the Sprite.update() and assign a Sprite.image and
+ Sprite.rect attributes. The initializer can accept any number of
+ Group instances to be added to.
+
+ When subclassing the Sprite, be sure to call the base initializer before
+ adding the Sprite to Groups.
+ """
+
+ def __init__(self, *groups):
+ self.__g = {} # The groups the sprite is in
+ if groups: self.add(groups)
+
+ def add(self, *groups):
+ """add the sprite to groups
+ Sprite.add(*groups): return None
+
+ Any number of Group instances can be passed as arguments. The
+ Sprite will be added to the Groups it is not already a member of.
+ """
+ has = self.__g.__contains__
+ for group in groups:
+ if hasattr(group, '_spritegroup'):
+ if not has(group):
+ group.add_internal(self)
+ self.add_internal(group)
+ else: self.add(*group)
+
+ def remove(self, *groups):
+ """remove the sprite from groups
+ Sprite.remove(*groups): return None
+
+ Any number of Group instances can be passed as arguments. The Sprite will
+ be removed from the Groups it is currently a member of.
+ """
+ has = self.__g.__contains__
+ for group in groups:
+ if hasattr(group, '_spritegroup'):
+ if has(group):
+ group.remove_internal(self)
+ self.remove_internal(group)
+ else: self.remove(*group)
+
+ def add_internal(self, group):
+ self.__g[group] = 0
+
+ def remove_internal(self, group):
+ del self.__g[group]
+
+ def update(self, *args):
+ """method to control sprite behavior
+ Sprite.update(*args):
+
+ The default implementation of this method does nothing; it's just a
+ convenient "hook" that you can override. This method is called by
+ Group.update() with whatever arguments you give it.
+
+ There is no need to use this method if not using the convenience
+ method by the same name in the Group class.
+ """
+ pass
+
+ def kill(self):
+ """remove the Sprite from all Groups
+ Sprite.kill(): return None
+
+ The Sprite is removed from all the Groups that contain it. This won't
+ change anything about the state of the Sprite. It is possible to continue
+ to use the Sprite after this method has been called, including adding it
+ to Groups.
+ """
+ for c in self.__g.keys():
+ c.remove_internal(self)
+ self.__g.clear()
+
+ def groups(self):
+ """list of Groups that contain this Sprite
+ Sprite.groups(): return group_list
+
+ Return a list of all the Groups that contain this Sprite.
+ """
+ return self.__g.keys()
+
+ def alive(self):
+ """does the sprite belong to any groups
+ Sprite.alive(): return bool
+
+ Returns True when the Sprite belongs to one or more Groups.
+ """
+ return (len(self.__g) != 0)
+
+ def __repr__(self):
+ return "<%s sprite(in %d groups)>" % (self.__class__.__name__, len(self.__g))
+
+
+class DirtySprite(Sprite):
+ """a more featureful subclass of Sprite with more attributes
+ pygame.sprite.DirtySprite(*groups): return DirtySprite
+
+ Extra DirtySprite attributes with their default values:
+
+ dirty = 1
+ if set to 1, it is repainted and then set to 0 again
+ if set to 2 then it is always dirty ( repainted each frame,
+ flag is not reset)
+ 0 means that it is not dirty and therefor not repainted again
+
+ blendmode = 0
+ its the special_flags argument of blit, blendmodes
+
+ source_rect = None
+ source rect to use, remember that it is relative to
+ topleft (0,0) of self.image
+
+ visible = 1
+ normally 1, if set to 0 it will not be repainted
+ (you must set it dirty too to be erased from screen)
+
+ layer = 0
+ (READONLY value, it is read when adding it to the
+ LayeredUpdates, for details see doc of LayeredUpdates)
+ """
+
+ def __init__(self, *groups):
+
+ self.dirty = 1
+ self.blendmode = 0 # pygame 1.8, reffered as special_flags in
+ # the documentation of blit
+ self._visible = 1
+ self._layer = 0 # READ ONLY by LayeredUpdates or LayeredDirty
+ self.source_rect = None
+ Sprite.__init__(self, *groups)
+
+ def _set_visible(self, val):
+ """set the visible value (0 or 1) and makes the sprite dirty"""
+ self._visible = val
+ if self.dirty < 2:
+ self.dirty = 1
+
+ def _get_visible(self):
+ """returns the visible value of that sprite"""
+ return self._visible
+ visible = property(lambda self: self._get_visible(),\
+ lambda self, value:self._set_visible(value), \
+ doc="you can make this sprite disappear without removing it from the group,\n"+
+ "values 0 for invisible and 1 for visible")
+
+ def __repr__(self):
+ return "<%s DirtySprite(in %d groups)>" % (self.__class__.__name__, len(self.groups()))
+
+
+
+class AbstractGroup(object):
+ """A base for containers for sprites. It does everything
+ needed to behave as a normal group. You can easily inherit
+ a new group class from this, or the other groups below,
+ if you want to add more features.
+
+ Any AbstractGroup-derived sprite groups act like sequences,
+ and support iteration, len, and so on."""
+
+ # dummy val to identify sprite groups, and avoid infinite recursion.
+ _spritegroup = True
+
+ def __init__(self):
+ self.spritedict = {}
+ self.lostsprites = []
+
+ def sprites(self):
+ """sprites()
+ get a list of sprites in the group
+
+ Returns an object that can be looped over with a 'for' loop.
+ (For now it is always a list, but newer version of Python
+ could return different iterators.) You can also iterate directly
+ over the sprite group."""
+ return list(self.spritedict.keys())
+
+ def add_internal(self, sprite):
+ self.spritedict[sprite] = 0
+
+ def remove_internal(self, sprite):
+ r = self.spritedict[sprite]
+ if r is not 0:
+ self.lostsprites.append(r)
+ del(self.spritedict[sprite])
+
+ def has_internal(self, sprite):
+ return sprite in self.spritedict
+
+ def copy(self):
+ """copy()
+ copy a group with all the same sprites
+
+ Returns a copy of the group that is the same class
+ type, and has the same sprites in it."""
+ return self.__class__(self.sprites())
+
+ def __iter__(self):
+ return iter(self.sprites())
+
+ def __contains__(self, sprite):
+ return self.has(sprite)
+
+ def add(self, *sprites):
+ """add(sprite, list, or group, ...)
+ add sprite to group
+
+ Add a sprite or sequence of sprites to a group."""
+ for sprite in sprites:
+ # It's possible that some sprite is also an iterator.
+ # If this is the case, we should add the sprite itself,
+ # and not the objects it iterates over.
+ if isinstance(sprite, Sprite):
+ if not self.has_internal(sprite):
+ self.add_internal(sprite)
+ sprite.add_internal(self)
+ else:
+ try:
+ # See if sprite is an iterator, like a list or sprite
+ # group.
+ for spr in sprite:
+ self.add(spr)
+ except (TypeError, AttributeError):
+ # Not iterable, this is probably a sprite that happens
+ # to not subclass Sprite. Alternately, it could be an
+ # old-style sprite group.
+ if hasattr(sprite, '_spritegroup'):
+ for spr in sprite.sprites():
+ if not self.has_internal(spr):
+ self.add_internal(spr)
+ spr.add_internal(self)
+ elif not self.has_internal(sprite):
+ self.add_internal(sprite)
+ sprite.add_internal(self)
+
+ def remove(self, *sprites):
+ """remove(sprite, list, or group, ...)
+ remove sprite from group
+
+ Remove a sprite or sequence of sprites from a group."""
+ # This function behaves essentially the same as Group.add.
+ # Check for Spritehood, check for iterability, check for
+ # old-style sprite group, and fall back to assuming
+ # spritehood.
+ for sprite in sprites:
+ if isinstance(sprite, Sprite):
+ if self.has_internal(sprite):
+ self.remove_internal(sprite)
+ sprite.remove_internal(self)
+ else:
+ try:
+ for spr in sprite: self.remove(spr)
+ except (TypeError, AttributeError):
+ if hasattr(sprite, '_spritegroup'):
+ for spr in sprite.sprites():
+ if self.has_internal(spr):
+ self.remove_internal(spr)
+ spr.remove_internal(self)
+ elif self.has_internal(sprite):
+ self.remove_internal(sprite)
+ sprite.remove_internal(self)
+
+ def has(self, *sprites):
+ """has(sprite or group, ...)
+ ask if group has a sprite or sprites
+
+ Returns true if the given sprite or sprites are
+ contained in the group. You can also use 'sprite in group'
+ or 'subgroup in group'."""
+ # Again, this follows the basic pattern of Group.add and
+ # Group.remove.
+ for sprite in sprites:
+ if isinstance(sprite, Sprite):
+ return self.has_internal(sprite)
+
+ try:
+ for spr in sprite:
+ if not self.has(spr):
+ return False
+ return True
+ except (TypeError, AttributeError):
+ if hasattr(sprite, '_spritegroup'):
+ for spr in sprite.sprites():
+ if not self.has_internal(spr):
+ return False
+ return True
+ else:
+ return self.has_internal(sprite)
+
+ def update(self, *args):
+ """update(*args)
+ call update for all member sprites
+
+ calls the update method for all sprites in the group.
+ Passes all arguments on to the Sprite update function."""
+ for s in self.sprites(): s.update(*args)
+
+ def draw(self, surface):
+ """draw(surface)
+ draw all sprites onto the surface
+
+ Draws all the sprites onto the given surface."""
+ sprites = self.sprites()
+ surface_blit = surface.blit
+ for spr in sprites:
+ self.spritedict[spr] = surface_blit(spr.image, spr.rect)
+ self.lostsprites = []
+
+ def clear(self, surface, bgd):
+ """clear(surface, bgd)
+ erase the previous position of all sprites
+
+ Clears the area of all drawn sprites. the bgd
+ argument should be Surface which is the same
+ dimensions as the surface. The bgd can also be
+ a function which gets called with the passed
+ surface and the area to be cleared."""
+ try:
+ bgd.__call__
+ except AttributeError:
+ pass
+ else:
+ for r in self.lostsprites:
+ bgd(surface, r)
+ for r in self.spritedict.values():
+ if r is not 0: bgd(surface, r)
+ return
+ surface_blit = surface.blit
+ for r in self.lostsprites:
+ surface_blit(bgd, r, r)
+ for r in self.spritedict.values():
+ if r is not 0: surface_blit(bgd, r, r)
+
+ def empty(self):
+ """empty()
+ remove all sprites
+
+ Removes all the sprites from the group."""
+ for s in self.sprites():
+ self.remove_internal(s)
+ s.remove_internal(self)
+
+ def __nonzero__(self):
+ return (len(self.sprites()) != 0)
+
+ def __len__(self):
+ """len(group)
+ number of sprites in group
+
+ Returns the number of sprites contained in the group."""
+ return len(self.sprites())
+
+ def __repr__(self):
+ return "<%s(%d sprites)>" % (self.__class__.__name__, len(self))
+
+class Group(AbstractGroup):
+ """container class for many Sprites
+ pygame.sprite.Group(*sprites): return Group
+
+ A simple container for Sprite objects. This class can be inherited to
+ create containers with more specific behaviors. The constructor takes any
+ number of Sprite arguments to add to the Group. The group supports the
+ following standard Python operations:
+
+ in test if a Sprite is contained
+ len the number of Sprites contained
+ bool test if any Sprites are contained
+ iter iterate through all the Sprites
+
+ The Sprites in the Group are not ordered, so drawing and iterating the
+ Sprites is in no particular order.
+ """
+
+ def __init__(self, *sprites):
+ AbstractGroup.__init__(self)
+ self.add(*sprites)
+
+RenderPlain = Group
+RenderClear = Group
+
+class RenderUpdates(Group):
+ """Group class that tracks dirty updates
+ pygame.sprite.RenderUpdates(*sprites): return RenderUpdates
+
+ This class is derived from pygame.sprite.Group(). It has an extended draw()
+ method that tracks the changed areas of the screen.
+ """
+
+ def draw(self, surface):
+ spritedict = self.spritedict
+ surface_blit = surface.blit
+ dirty = self.lostsprites
+ self.lostsprites = []
+ dirty_append = dirty.append
+ for s in self.sprites():
+ r = spritedict[s]
+ newrect = surface_blit(s.image, s.rect)
+ if r is 0:
+ dirty_append(newrect)
+ else:
+ if newrect.colliderect(r):
+ dirty_append(newrect.union(r))
+ else:
+ dirty_append(newrect)
+ dirty_append(r)
+ spritedict[s] = newrect
+ return dirty
+
+class OrderedUpdates(RenderUpdates):
+ """RenderUpdates class that draws Sprites in order of addition
+ pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates
+
+ This class derives from pygame.sprite.RenderUpdates(). It maintains
+ the order in which the Sprites were added to the Group for rendering.
+ This makes adding and removing Sprites from the Group a little
+ slower than regular Groups.
+ """
+
+ def __init__(self, *sprites):
+ self._spritelist = []
+ RenderUpdates.__init__(self, *sprites)
+
+ def sprites(self):
+ return list(self._spritelist)
+
+ def add_internal(self, sprite):
+ RenderUpdates.add_internal(self, sprite)
+ self._spritelist.append(sprite)
+
+ def remove_internal(self, sprite):
+ RenderUpdates.remove_internal(self, sprite)
+ self._spritelist.remove(sprite)
+
+
+class LayeredUpdates(AbstractGroup):
+ """LayeredUpdates Group handles layers, that draws like OrderedUpdates.
+ pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates
+
+ This group is fully compatible with pygame.sprite.Sprite.
+
+ New in pygame 1.8.0
+ """
+
+ def __init__(self, *sprites, **kwargs):
+ """
+ You can set the default layer through kwargs using 'default_layer'
+ and an integer for the layer. The default layer is 0.
+
+ If the sprite you add has an attribute layer then that layer will
+ be used.
+ If the **kwarg contains 'layer' then the sprites passed will be
+ added to that layer (overriding the sprite.layer attribute).
+ If neither sprite has attribute layer nor kwarg then the default
+ layer is used to add the sprites.
+ """
+ self._spritelayers = {}
+ self._spritelist = []
+ AbstractGroup.__init__(self)
+ self._default_layer = kwargs.get('default_layer', 0)
+
+ self.add(*sprites, **kwargs)
+
+ def add_internal(self, sprite, layer=None):
+ """
+ Do not use this method directly. It is used by the group to add a
+ sprite internally.
+ """
+ self.spritedict[sprite] = Rect(0, 0, 0, 0) # add a old rect
+
+ if layer is None:
+ try:
+ layer = sprite._layer
+ except AttributeError:
+ layer = self._default_layer
+
+
+ self._spritelayers[sprite] = layer
+ if hasattr(sprite, '_layer'):
+ sprite._layer = layer
+
+ # add the sprite at the right position
+ # bisect algorithmus
+ sprites = self._spritelist # speedup
+ sprites_layers = self._spritelayers
+ leng = len(sprites)
+ low = 0
+ high = leng-1
+ mid = low
+ while(low<=high):
+ mid = low + (high-low)//2
+ if(sprites_layers[sprites[mid]]<=layer):
+ low = mid+1
+ else:
+ high = mid-1
+ # linear search to find final position
+ while(mid<leng and sprites_layers[sprites[mid]]<=layer):
+ mid += 1
+ sprites.insert(mid, sprite)
+
+ def add(self, *sprites, **kwargs):
+ """add a sprite or sequence of sprites to a group
+ LayeredUpdates.add(*sprites, **kwargs): return None
+
+ If the sprite(s) have an attribute layer then that is used
+ for the layer. If kwargs contains 'layer' then the sprite(s)
+ will be added to that argument (overriding the sprite layer
+ attribute). If neither is passed then the sprite(s) will be
+ added to the default layer.
+ """
+ layer = None
+ if 'layer' in kwargs:
+ layer = kwargs['layer']
+ if sprites is None or not sprites:
+ return
+ for sprite in sprites:
+ # It's possible that some sprite is also an iterator.
+ # If this is the case, we should add the sprite itself,
+ # and not the objects it iterates over.
+ if isinstance(sprite, Sprite):
+ if not self.has_internal(sprite):
+ self.add_internal(sprite, layer)
+ sprite.add_internal(self)
+ else:
+ try:
+ # See if sprite is an iterator, like a list or sprite
+ # group.
+ for spr in sprite:
+ self.add(spr, **kwargs)
+ except (TypeError, AttributeError):
+ # Not iterable, this is probably a sprite that happens
+ # to not subclass Sprite. Alternately, it could be an
+ # old-style sprite group.
+ if hasattr(sprite, '_spritegroup'):
+ for spr in sprite.sprites():
+ if not self.has_internal(spr):
+ self.add_internal(spr, layer)
+ spr.add_internal(self)
+ elif not self.has_internal(sprite):
+ self.add_internal(sprite, layer)
+ sprite.add_internal(self)
+
+ def remove_internal(self, sprite):
+ """
+ Do not use this method directly. It is used by the group to
+ add a sprite.
+ """
+ self._spritelist.remove(sprite)
+ # these dirty rects are suboptimal for one frame
+ self.lostsprites.append(self.spritedict[sprite]) # dirty rect
+ if hasattr(sprite, 'rect'):
+ self.lostsprites.append(sprite.rect) # dirty rect
+
+ self.spritedict.pop(sprite, 0)
+ self._spritelayers.pop(sprite)
+
+ def sprites(self):
+ """returns a ordered list of sprites (first back, last top).
+ LayeredUpdates.sprites(): return sprites
+ """
+ return list(self._spritelist)
+
+ def draw(self, surface):
+ """draw all sprites in the right order onto the passed surface.
+ LayeredUpdates.draw(surface): return Rect_list
+ """
+ spritedict = self.spritedict
+ surface_blit = surface.blit
+ dirty = self.lostsprites
+ self.lostsprites = []
+ dirty_append = dirty.append
+ for spr in self.sprites():
+ rec = spritedict[spr]
+ newrect = surface_blit(spr.image, spr.rect)
+ if rec is 0:
+ dirty_append(newrect)
+ else:
+ if newrect.colliderect(rec):
+ dirty_append(newrect.union(rec))
+ else:
+ dirty_append(newrect)
+ dirty_append(rec)
+ spritedict[spr] = newrect
+ return dirty
+
+ def get_sprites_at(self, pos):
+ """returns a list with all sprites at that position.
+ LayeredUpdates.get_sprites_at(pos): return colliding_sprites
+
+ Bottom sprites first, top last.
+ """
+ _sprites = self._spritelist
+ rect = Rect(pos, (0, 0))
+ colliding_idx = rect.collidelistall(_sprites)
+ colliding = []
+ colliding_append = colliding.append
+ for i in colliding_idx:
+ colliding_append(_sprites[i])
+ return colliding
+
+ def get_sprite(self, idx):
+ """returns the sprite at the index idx from the groups sprites
+ LayeredUpdates.get_sprite(idx): return sprite
+
+ Raises IndexOutOfBounds if the idx is not within range.
+ """
+ return self._spritelist[idx]
+
+ def remove_sprites_of_layer(self, layer_nr):
+ """removes all sprites from a layer and returns them as a list
+ LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites
+ """
+ sprites = self.get_sprites_from_layer(layer_nr)
+ self.remove(sprites)
+ return sprites
+
+
+ #---# layer methods
+ def layers(self):
+ """returns a list of layers defined (unique), sorted from botton up.
+ LayeredUpdates.layers(): return layers
+ """
+ layers = set()
+ for layer in self._spritelayers.values():
+ layers.add(layer)
+ return list(layers)
+
+ def change_layer(self, sprite, new_layer):
+ """changes the layer of the sprite
+ LayeredUpdates.change_layer(sprite, new_layer): return None
+
+ sprite must have been added to the renderer. It is not checked.
+ """
+ sprites = self._spritelist # speedup
+ sprites_layers = self._spritelayers # speedup
+
+ sprites.remove(sprite)
+ sprites_layers.pop(sprite)
+
+ # add the sprite at the right position
+ # bisect algorithmus
+ leng = len(sprites)
+ low = 0
+ high = leng-1
+ mid = low
+ while(low<=high):
+ mid = low + (high-low)//2
+ if(sprites_layers[sprites[mid]]<=new_layer):
+ low = mid+1
+ else:
+ high = mid-1
+ # linear search to find final position
+ while(mid<leng and sprites_layers[sprites[mid]]<=new_layer):
+ mid += 1
+ sprites.insert(mid, sprite)
+ if hasattr(sprite, 'layer'):
+ sprite.layer = new_layer
+
+ # add layer info
+ sprites_layers[sprite] = new_layer
+
+ def get_layer_of_sprite(self, sprite):
+ """
+ Returns the layer that sprite is currently in. If the sprite is not
+ found then it will return the default layer.
+ """
+ return self._spritelayers.get(sprite, self._default_layer)
+
+ def get_top_layer(self):
+ """returns the top layer
+ LayeredUpdates.get_top_layer(): return layer
+ """
+ return self._spritelayers[self._spritelist[-1]]
+
+ def get_bottom_layer(self):
+ """returns the bottom layer
+ LayeredUpdates.get_bottom_layer(): return layer
+ """
+ return self._spritelayers[self._spritelist[0]]
+
+ def move_to_front(self, sprite):
+ """brings the sprite to front layer
+ LayeredUpdates.move_to_front(sprite): return None
+
+ Brings the sprite to front, changing sprite layer to topmost layer
+ (added at the end of that layer).
+ """
+ self.change_layer(sprite, self.get_top_layer())
+
+ def move_to_back(self, sprite):
+ """moves the sprite to the bottom layer
+ LayeredUpdates.move_to_back(sprite): return None
+
+ Moves the sprite to the bottom layer, moving it behind
+ all other layers and adding one additional layer.
+ """
+ self.change_layer(sprite, self.get_bottom_layer()-1)
+
+ def get_top_sprite(self):
+ """returns the topmost sprite
+ LayeredUpdates.get_top_sprite(): return Sprite
+ """
+ return self._spritelist[-1]
+
+ def get_sprites_from_layer(self, layer):
+ """returns all sprites from a layer, ordered by how they where added
+ LayeredUpdates.get_sprites_from_layer(layer): return sprites
+
+ Returns all sprites from a layer, ordered by how they where added.
+ It uses linear search and the sprites are not removed from layer.
+ """
+ sprites = []
+ sprites_append = sprites.append
+ sprite_layers = self._spritelayers
+ for spr in self._spritelist:
+ if sprite_layers[spr] == layer:
+ sprites_append(spr)
+ elif sprite_layers[spr]>layer:# break after because no other will
+ # follow with same layer
+ break
+ return sprites
+
+ def switch_layer(self, layer1_nr, layer2_nr):
+ """switches the sprites from layer1 to layer2
+ LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None
+
+ The layers number must exist, it is not checked.
+ """
+ sprites1 = self.remove_sprites_of_layer(layer1_nr)
+ for spr in self.get_sprites_from_layer(layer2_nr):
+ self.change_layer(spr, layer1_nr)
+ self.add(sprites1, layer=layer2_nr)
+
+
+class LayeredDirty(LayeredUpdates):
+ """LayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates.
+ pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty
+
+ This group requires pygame.sprite.DirtySprite or any sprite that
+ has the following attributes:
+ image, rect, dirty, visible, blendmode (see doc of DirtySprite).
+
+ It uses the dirty flag technique and is therefore faster than the
+ pygame.sprite.RenderUpdates if you have many static sprites. It
+ also switches automatically between dirty rect update and full
+ screen drawing, so you do no have to worry what would be faster.
+
+ Same as for the pygame.sprite.Group.
+ You can specify some additional attributes through kwargs:
+ _use_update: True/False default is False
+ _default_layer: default layer where sprites without a layer are added.
+ _time_threshold: treshold time for switching between dirty rect mode
+ and fullscreen mode, defaults to 1000./80 == 1000./fps
+
+ New in pygame 1.8.0
+ """
+
+ def __init__(self, *sprites, **kwargs):
+ """Same as for the pygame.sprite.Group.
+ pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty
+
+ You can specify some additional attributes through kwargs:
+ _use_update: True/False default is False
+ _default_layer: the default layer where the sprites without a layer are
+ added.
+ _time_threshold: treshold time for switching between dirty rect mode and
+ fullscreen mode, defaults to 1000./80 == 1000./fps
+ """
+ LayeredUpdates.__init__(self, *sprites, **kwargs)
+ self._clip = None
+
+ self._use_update = False
+
+ self._time_threshold = 1000./80. # 1000./ fps
+
+
+ self._bgd = None
+ for key, val in kwargs.items():
+ if key in ['_use_update', '_time_threshold', '_default_layer']:
+ if hasattr(self, key):
+ setattr(self, key, val)
+
+ def add_internal(self, sprite, layer=None):
+ """Do not use this method directly. It is used by the group to add a
+ sprite internally.
+ """
+ # check if all attributes needed are set
+ if not hasattr(sprite, 'dirty'):
+ raise AttributeError()
+ if not hasattr(sprite, "visible"):
+ raise AttributeError()
+ if not hasattr(sprite, "blendmode"):
+ raise AttributeError()
+
+ if not isinstance(sprite, DirtySprite):
+ raise TypeError()
+
+ if sprite.dirty == 0: # set it dirty if it is not
+ sprite.dirty = 1
+
+ LayeredUpdates.add_internal(self, sprite, layer)
+
+ def draw(self, surface, bgd=None):
+ """draw all sprites in the right order onto the passed surface.
+ LayeredDirty.draw(surface, bgd=None): return Rect_list
+
+ You can pass the background too. If a background is already set,
+ then the bgd argument has no effect.
+ """
+ # speedups
+ _orig_clip = surface.get_clip()
+ _clip = self._clip
+ if _clip is None:
+ _clip = _orig_clip
+
+
+ _surf = surface
+ _sprites = self._spritelist
+ _old_rect = self.spritedict
+ _update = self.lostsprites
+ _update_append = _update.append
+ _ret = None
+ _surf_blit = _surf.blit
+ _rect = Rect
+ if bgd is not None:
+ self._bgd = bgd
+ _bgd = self._bgd
+
+ _surf.set_clip(_clip)
+ # -------
+ # 0. deside if normal render of flip
+ start_time = get_ticks()
+ if self._use_update: # dirty rects mode
+ # 1. find dirty area on screen and put the rects into _update
+ # still not happy with that part
+ for spr in _sprites:
+ if 0 < spr.dirty:
+ # chose the right rect
+ if spr.source_rect:
+ _union_rect = _rect(spr.rect.topleft, spr.source_rect.size)
+ else:
+ _union_rect = _rect(spr.rect)
+
+ _union_rect_collidelist = _union_rect.collidelist
+ _union_rect_union_ip = _union_rect.union_ip
+ i = _union_rect_collidelist(_update)
+ while -1 < i:
+ _union_rect_union_ip(_update[i])
+ del _update[i]
+ i = _union_rect_collidelist(_update)
+ _update_append(_union_rect.clip(_clip))
+
+ _union_rect = _rect(_old_rect[spr])
+ _union_rect_collidelist = _union_rect.collidelist
+ _union_rect_union_ip = _union_rect.union_ip
+ i = _union_rect_collidelist(_update)
+ while -1 < i:
+ _union_rect_union_ip(_update[i])
+ del _update[i]
+ i = _union_rect_collidelist(_update)
+ _update_append(_union_rect.clip(_clip))
+ # can it be done better? because that is an O(n**2) algorithm in
+ # worst case
+
+ # clear using background
+ if _bgd is not None:
+ for rec in _update:
+ _surf_blit(_bgd, rec, rec)
+
+ # 2. draw
+ for spr in _sprites:
+ if 1 > spr.dirty:
+ if spr._visible:
+ # sprite not dirty, blit only the intersecting part
+ _spr_rect = spr.rect
+ if spr.source_rect is not None:
+ _spr_rect = Rect(spr.rect.topleft, spr.source_rect.size)
+ _spr_rect_clip = _spr_rect.clip
+ for idx in _spr_rect.collidelistall(_update):
+ # clip
+ clip = _spr_rect_clip(_update[idx])
+ _surf_blit(spr.image, clip, \
+ (clip[0]-_spr_rect[0], \
+ clip[1]-_spr_rect[1], \
+ clip[2], \
+ clip[3]), spr.blendmode)
+ else: # dirty sprite
+ if spr._visible:
+ _old_rect[spr] = _surf_blit(spr.image, spr.rect, \
+ spr.source_rect, spr.blendmode)
+ if spr.dirty == 1:
+ spr.dirty = 0
+ _ret = list(_update)
+ else: # flip, full screen mode
+ if _bgd is not None:
+ _surf_blit(_bgd, (0, 0))
+ for spr in _sprites:
+ if spr._visible:
+ _old_rect[spr] = _surf_blit(spr.image, spr.rect, spr.source_rect,spr.blendmode)
+ _ret = [_rect(_clip)] # return only the part of the screen changed
+
+
+ # timing for switching modes
+ # how to find a good treshold? it depends on the hardware it runs on
+ end_time = get_ticks()
+ if end_time-start_time > self._time_threshold:
+ self._use_update = False
+ else:
+ self._use_update = True
+
+## # debug
+## print " check: using dirty rects:", self._use_update
+
+ # emtpy dirty reas list
+ _update[:] = []
+
+ # -------
+ # restore original clip
+ _surf.set_clip(_orig_clip)
+ return _ret
+
+ def clear(self, surface, bgd):
+ """used to set background
+ Group.clear(surface, bgd): return None
+ """
+ self._bgd = bgd
+
+ def repaint_rect(self, screen_rect):
+ """repaints the given area
+ LayeredDirty.repaint_rect(screen_rect): return None
+
+ screen_rect is in screencoordinates.
+ """
+ self.lostsprites.append(screen_rect.clip(self._clip))
+
+ def set_clip(self, screen_rect=None):
+ """ clip the area where to draw. Just pass None (default) to reset the clip
+ LayeredDirty.set_clip(screen_rect=None): return None
+ """
+ if screen_rect is None:
+ self._clip = pygame.display.get_surface().get_rect()
+ else:
+ self._clip = screen_rect
+ self._use_update = False
+
+ def get_clip(self):
+ """clip the area where to draw. Just pass None (default) to reset the clip
+ LayeredDirty.get_clip(): return Rect
+ """
+ return self._clip
+
+ def change_layer(self, sprite, new_layer):
+ """changes the layer of the sprite
+ change_layer(sprite, new_layer): return None
+
+ sprite must have been added to the renderer. It is not checked.
+ """
+ LayeredUpdates.change_layer(self, sprite, new_layer)
+ if sprite.dirty == 0:
+ sprite.dirty = 1
+
+
+ def set_timing_treshold(self, time_ms):
+ """sets the treshold in milliseconds
+ set_timing_treshold(time_ms): return None
+
+ Default is 1000./80 where 80 is the fps I want to switch to full screen mode.
+ """
+ self._time_threshold = time_ms
+
+
+
+
+
+
+
+class GroupSingle(AbstractGroup):
+ """A group container that holds a single most recent item.
+ This class works just like a regular group, but it only
+ keeps a single sprite in the group. Whatever sprite has
+ been added to the group last, will be the only sprite in
+ the group.
+
+ You can access its one sprite as the .sprite attribute.
+ Assigning to this attribute will properly remove the old
+ sprite and then add the new one."""
+
+ def __init__(self, sprite = None):
+ AbstractGroup.__init__(self)
+ self.__sprite = None
+ if sprite is not None: self.add(sprite)
+
+ def copy(self):
+ return GroupSingle(self.__sprite)
+
+ def sprites(self):
+ if self.__sprite is not None: return [self.__sprite]
+ else: return []
+
+ def add_internal(self, sprite):
+ if self.__sprite is not None:
+ self.__sprite.remove_internal(self)
+ self.__sprite = sprite
+
+ def __nonzero__(self): return (self.__sprite is not None)
+
+ def _get_sprite(self):
+ return self.__sprite
+
+ def _set_sprite(self, sprite):
+ self.add_internal(sprite)
+ sprite.add_internal(self)
+ return sprite
+
+ sprite = property(_get_sprite, _set_sprite, None,
+ "The sprite contained in this group")
+
+ def remove_internal(self, sprite):
+ if sprite is self.__sprite: self.__sprite = None
+
+ def has_internal(self, sprite):
+ return (self.__sprite is sprite)
+
+ # Optimizations...
+ def __contains__(self, sprite): return (self.__sprite is sprite)
+
+
+
+
+
+# some different collision detection functions that could be used.
+
+def collide_rect(left, right):
+ """collision detection between two sprites, using rects.
+ pygame.sprite.collide_rect(left, right): return bool
+
+ Tests for collision between two sprites. Uses the
+ pygame rect colliderect function to calculate the
+ collision. Intended to be passed as a collided
+ callback function to the *collide functions.
+ Sprites must have a "rect" attributes.
+
+ New in pygame 1.8.0
+ """
+ return left.rect.colliderect(right.rect)
+
+class collide_rect_ratio:
+ """A callable class that checks for collisions between
+ two sprites, using a scaled version of the sprites
+ rects.
+
+ Is created with a ratio, the instance is then intended
+ to be passed as a collided callback function to the
+ *collide functions.
+
+ New in pygame 1.8.1
+ """
+
+ def __init__( self, ratio ):
+ """Creates a new collide_rect_ratio callable. ratio is
+ expected to be a floating point value used to scale
+ the underlying sprite rect before checking for
+ collisions.
+ """
+
+ self.ratio = ratio
+
+ def __call__( self, left, right ):
+ """pygame.sprite.collide_rect_ratio(ratio)(left, right): bool
+ collision detection between two sprites, using scaled rects.
+
+ Tests for collision between two sprites. Uses the
+ pygame rect colliderect function to calculate the
+ collision, after scaling the rects by the stored ratio.
+ Sprites must have a "rect" attributes.
+ """
+
+ ratio = self.ratio
+
+ leftrect = left.rect
+ width = leftrect.width
+ height = leftrect.height
+ leftrect = leftrect.inflate( width * ratio - width, height * ratio - height )
+
+ rightrect = right.rect
+ width = rightrect.width
+ height = rightrect.height
+ rightrect = rightrect.inflate( width * ratio - width, height * ratio - height )
+
+ return leftrect.colliderect( rightrect )
+
+def collide_circle( left, right ):
+ """collision detection between two sprites, using circles.
+ pygame.sprite.collide_circle(left, right): return bool
+
+ Tests for collision between two sprites, by testing to
+ see if two circles centered on the sprites overlap. If
+ the sprites have a "radius" attribute, that is used to
+ create the circle, otherwise a circle is created that
+ is big enough to completely enclose the sprites rect as
+ given by the "rect" attribute. Intended to be passed as
+ a collided callback function to the *collide functions.
+ Sprites must have a "rect" and an optional "radius"
+ attribute.
+
+ New in pygame 1.8.0
+ """
+
+ xdistance = left.rect.centerx - right.rect.centerx
+ ydistance = left.rect.centery - right.rect.centery
+ distancesquared = xdistance ** 2 + ydistance ** 2
+ try:
+ leftradiussquared = left.radius ** 2
+ except AttributeError:
+ leftrect = left.rect
+ leftradiussquared = ( leftrect.width ** 2 + leftrect.height ** 2 ) / 4
+ try:
+ rightradiussquared = right.radius ** 2
+ except AttributeError:
+ rightrect = right.rect
+ rightradiussquared = ( rightrect.width ** 2 + rightrect.height ** 2 ) / 4
+ return distancesquared < leftradiussquared + rightradiussquared
+
+class collide_circle_ratio( object ):
+ """A callable class that checks for collisions between
+ two sprites, using a scaled version of the sprites radius.
+
+ Is created with a ratio, the instance is then intended
+ to be passed as a collided callback function to the
+ *collide functions.
+
+ New in pygame 1.8.1
+ """
+
+ def __init__( self, ratio ):
+ """Creates a new collide_circle_ratio callable. ratio is
+ expected to be a floating point value used to scale
+ the underlying sprite radius before checking for
+ collisions.
+ """
+ self.ratio = ratio
+ # Constant value that folds in division for diameter to radius,
+ # when calculating from a rect.
+ self.halfratio = ratio ** 2 / 4.0
+
+ def __call__( self, left, right ):
+ """pygame.sprite.collide_circle_radio(ratio)(left, right): return bool
+ collision detection between two sprites, using scaled circles.
+
+ Tests for collision between two sprites, by testing to
+ see if two circles centered on the sprites overlap, after
+ scaling the circles radius by the stored ratio. If
+ the sprites have a "radius" attribute, that is used to
+ create the circle, otherwise a circle is created that
+ is big enough to completely enclose the sprites rect as
+ given by the "rect" attribute. Intended to be passed as
+ a collided callback function to the *collide functions.
+ Sprites must have a "rect" and an optional "radius"
+ attribute.
+ """
+
+ ratio = self.ratio
+ xdistance = left.rect.centerx - right.rect.centerx
+ ydistance = left.rect.centery - right.rect.centery
+ distancesquared = xdistance ** 2 + ydistance ** 2
+ # Optimize for not containing radius attribute, as if radius was
+ # set consistently, would probably be using collide_circle instead.
+ if hasattr( left, "radius" ):
+ leftradiussquared = (left.radius * ratio) ** 2
+
+ if hasattr( right, "radius" ):
+ rightradiussquared = (right.radius * ratio) ** 2
+ else:
+ halfratio = self.halfratio
+ rightrect = right.rect
+ rightradiussquared = (rightrect.width ** 2 + rightrect.height ** 2) * halfratio
+ else:
+ halfratio = self.halfratio
+ leftrect = left.rect
+ leftradiussquared = (leftrect.width ** 2 + leftrect.height ** 2) * halfratio
+
+ if hasattr( right, "radius" ):
+ rightradiussquared = (right.radius * ratio) ** 2
+ else:
+ rightrect = right.rect
+ rightradiussquared = (rightrect.width ** 2 + rightrect.height ** 2) * halfratio
+ return distancesquared < leftradiussquared + rightradiussquared
+
+def collide_mask(left, right):
+ """collision detection between two sprites, using masks.
+ pygame.sprite.collide_mask(SpriteLeft, SpriteRight): bool
+
+ Tests for collision between two sprites, by testing if
+ thier bitmasks overlap. If the sprites have a "mask"
+ attribute, that is used as the mask, otherwise a mask is
+ created from the sprite image. Intended to be passed as
+ a collided callback function to the *collide functions.
+ Sprites must have a "rect" and an optional "mask"
+ attribute.
+
+ New in pygame 1.8.0
+ """
+ xoffset = right.rect[0] - left.rect[0]
+ yoffset = right.rect[1] - left.rect[1]
+ try:
+ leftmask = left.mask
+ except AttributeError:
+ leftmask = from_surface(left.image)
+ try:
+ rightmask = right.mask
+ except AttributeError:
+ rightmask = from_surface(right.image)
+ return leftmask.overlap(rightmask, (xoffset, yoffset))
+
+def spritecollide(sprite, group, dokill, collided = None):
+ """find Sprites in a Group that intersect another Sprite
+ pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list
+
+ Return a list containing all Sprites in a Group that intersect with another
+ Sprite. Intersection is determined by comparing the Sprite.rect attribute
+ of each Sprite.
+
+ The dokill argument is a bool. If set to True, all Sprites that collide
+ will be removed from the Group.
+
+ The collided argument is a callback function used to calculate if two sprites
+ are colliding. it should take two sprites as values, and return a bool
+ value indicating if they are colliding. If collided is not passed, all sprites
+ must have a "rect" value, which is a rectangle of the sprite area, which will
+ be used to calculate the collision.
+ """
+ crashed = []
+ if collided is None:
+ # Special case old behaviour for speed.
+ spritecollide = sprite.rect.colliderect
+ if dokill:
+ for s in group.sprites():
+ if spritecollide(s.rect):
+ s.kill()
+ crashed.append(s)
+ else:
+ for s in group:
+ if spritecollide(s.rect):
+ crashed.append(s)
+ else:
+ if dokill:
+ for s in group.sprites():
+ if collided(sprite, s):
+ s.kill()
+ crashed.append(s)
+ else:
+ for s in group:
+ if collided(sprite, s):
+ crashed.append(s)
+ return crashed
+
+def groupcollide(groupa, groupb, dokilla, dokillb, collided = None):
+ """pygame.sprite.groupcollide(groupa, groupb, dokilla, dokillb) -> dict
+ collision detection between group and group
+
+ given two groups, this will find the intersections
+ between all sprites in each group. it returns a
+ dictionary of all sprites in the first group that
+ collide. the value for each item in the dictionary
+ is a list of the sprites in the second group it
+ collides with. the two dokill arguments control if
+ the sprites from either group will be automatically
+ removed from all groups.
+ collided is a callback function used to calculate if
+ two sprites are colliding. it should take two sprites
+ as values, and return a bool value indicating if
+ they are colliding. if collided is not passed, all
+ sprites must have a "rect" value, which is a
+ rectangle of the sprite area, which will be used
+ to calculate the collision."""
+ crashed = {}
+ SC = spritecollide
+ if dokilla:
+ for s in groupa.sprites():
+ c = SC(s, groupb, dokillb, collided)
+ if c:
+ crashed[s] = c
+ s.kill()
+ else:
+ for s in groupa:
+ c = SC(s, groupb, dokillb, collided)
+ if c:
+ crashed[s] = c
+ return crashed
+
+def spritecollideany(sprite, group, collided = None):
+ """pygame.sprite.spritecollideany(sprite, group) -> sprite
+ finds any sprites that collide
+
+ given a sprite and a group of sprites, this will
+ return return any single sprite that collides with
+ with the given sprite. If there are no collisions
+ this returns None.
+
+ if you don't need all the features of the
+ spritecollide function, this function will be a
+ bit quicker.
+
+ collided is a callback function used to calculate if
+ two sprites are colliding. it should take two sprites
+ as values, and return a bool value indicating if
+ they are colliding. if collided is not passed, all
+ sprites must have a "rect" value, which is a
+ rectangle of the sprite area, which will be used
+ to calculate the collision."""
+ if collided is None:
+ # Special case old behaviour for speed.
+ spritecollide = sprite.rect.colliderect
+ for s in group:
+ if spritecollide(s.rect):
+ return s
+ else:
+ for s in group:
+ if collided(sprite, s):
+ return s
+ return None
diff --git a/src/pygame/sprite.pyo b/src/pygame/sprite.pyo
new file mode 100644
index 0000000..68cf225
--- /dev/null
+++ b/src/pygame/sprite.pyo
Binary files differ
diff --git a/src/pygame/surface.so b/src/pygame/surface.so
new file mode 100644
index 0000000..d827d3e
--- /dev/null
+++ b/src/pygame/surface.so
Binary files differ
diff --git a/src/pygame/surfarray.py b/src/pygame/surfarray.py
new file mode 100644
index 0000000..33e2cb1
--- /dev/null
+++ b/src/pygame/surfarray.py
@@ -0,0 +1,340 @@
+## pygame - Python Game Library
+## Copyright (C) 2007 Marcus von Appen
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Marcus von Appen
+## mva@sysfault.org
+
+"""pygame module for accessing surface pixel data using array interfaces
+
+Functions to convert pixel data between pygame Surfaces and arrays. This
+module will only be functional when pygame can use the external Numpy or
+Numeric packages.
+
+Every pixel is stored as a single integer value to represent the red,
+green, and blue colors. The 8bit images use a value that looks into a
+colormap. Pixels with higher depth use a bit packing process to place
+three or four values into a single number.
+
+The arrays are indexed by the X axis first, followed by the Y
+axis. Arrays that treat the pixels as a single integer are referred to
+as 2D arrays. This module can also separate the red, green, and blue
+color values into separate indices. These types of arrays are referred
+to as 3D arrays, and the last index is 0 for red, 1 for green, and 2 for
+blue.
+
+Supported array types are
+
+ numpy
+ numeric
+
+The default will be numpy, if installed. Otherwise, Numeric will be set
+as default if installed. If neither numpy nor Numeric are installed, the
+module will raise an ImportError.
+
+The array type to use can be changed at runtime using the use_arraytype()
+method, which requires one of the above types as string.
+
+Note: numpy and Numeric are not completely compatible. Certain array
+manipulations, which work for one type, might behave differently or even
+completely break for the other.
+
+Additionally, in contrast to Numeric numpy does use unsigned 16-bit
+integers. Images with 16-bit data will be treated as unsigned
+integers. Numeric instead uses signed integers for the representation,
+which is important to keep in mind, if you use the module's functions
+and wonder about the values.
+"""
+
+import pygame
+
+# Global array type setting. See use_arraytype().
+__arraytype = None
+
+# Try to import the necessary modules.
+try:
+ import pygame._numpysurfarray as numpysf
+ __hasnumpy = True
+ __arraytype = "numpy"
+except ImportError:
+ __hasnumpy = False
+
+try:
+ import pygame._numericsurfarray as numericsf
+ __hasnumeric = True
+ if not __hasnumpy:
+ __arraytype = "numeric"
+except ImportError:
+ __hasnumeric = False
+
+if not __hasnumpy and not __hasnumeric:
+ raise ImportError("no module named numpy or Numeric found")
+
+from _arraysurfarray import blit_array
+
+def array2d (surface):
+ """pygame.surfarray.array2d (Surface): return array
+
+ Copy pixels into a 2d array.
+
+ Copy the pixels from a Surface into a 2D array. The bit depth of the
+ surface will control the size of the integer values, and will work
+ for any type of pixel format.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ if __arraytype == "numeric":
+ return numericsf.array2d (surface)
+ elif __arraytype == "numpy":
+ return numpysf.array2d (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def pixels2d (surface):
+ """pygame.surfarray.pixels2d (Surface): return array
+
+ Reference pixels into a 2d array.
+
+ Create a new 2D array that directly references the pixel values in a
+ Surface. Any changes to the array will affect the pixels in the
+ Surface. This is a fast operation since no data is copied.
+
+ Pixels from a 24-bit Surface cannot be referenced, but all other
+ Surface bit depths can.
+
+ The Surface this references will remain locked for the lifetime of
+ the array (see the Surface.lock - lock the Surface memory for pixel
+ access method).
+ """
+ if __arraytype == "numeric":
+ return numericsf.pixels2d (surface)
+ elif __arraytype == "numpy":
+ return numpysf.pixels2d (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def array3d (surface):
+ """pygame.surfarray.array3d (Surface): return array
+
+ Copy pixels into a 3d array.
+
+ Copy the pixels from a Surface into a 3D array. The bit depth of the
+ surface will control the size of the integer values, and will work
+ for any type of pixel format.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ if __arraytype == "numeric":
+ return numericsf.array3d (surface)
+ elif __arraytype == "numpy":
+ return numpysf.array3d (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def pixels3d (surface):
+ """pygame.surfarray.pixels3d (Surface): return array
+
+ Reference pixels into a 3d array.
+
+ Create a new 3D array that directly references the pixel values in a
+ Surface. Any changes to the array will affect the pixels in the
+ Surface. This is a fast operation since no data is copied.
+
+ This will only work on Surfaces that have 24-bit or 32-bit
+ formats. Lower pixel formats cannot be referenced.
+
+ The Surface this references will remain locked for the lifetime of
+ the array (see the Surface.lock - lock the Surface memory for pixel
+ access method).
+ """
+ if __arraytype == "numeric":
+ return numericsf.pixels3d (surface)
+ elif __arraytype == "numpy":
+ return numpysf.pixels3d (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def array_alpha (surface):
+ """pygame.surfarray.array_alpha (Surface): return array
+
+ Copy pixel alphas into a 2d array.
+
+ Copy the pixel alpha values (degree of transparency) from a Surface
+ into a 2D array. This will work for any type of Surface
+ format. Surfaces without a pixel alpha will return an array with all
+ opaque values.
+
+ This function will temporarily lock the Surface as pixels are copied
+ (see the Surface.lock - lock the Surface memory for pixel access
+ method).
+ """
+ if __arraytype == "numeric":
+ return numericsf.array_alpha (surface)
+ elif __arraytype == "numpy":
+ return numpysf.array_alpha (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def pixels_alpha (surface):
+ """pygame.surfarray.pixels_alpha (Surface): return array
+
+ Reference pixel alphas into a 2d array.
+
+ Create a new 2D array that directly references the alpha values
+ (degree of transparency) in a Surface. Any changes to the array will
+ affect the pixels in the Surface. This is a fast operation since no
+ data is copied.
+
+ This can only work on 32-bit Surfaces with a per-pixel alpha value.
+
+ The Surface this array references will remain locked for the
+ lifetime of the array.
+ """
+ if __arraytype == "numeric":
+ return numericsf.pixels_alpha (surface)
+ elif __arraytype == "numpy":
+ return numpysf.pixels_alpha (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def array_colorkey (surface):
+ """pygame.surfarray.array_colorkey (Surface): return array
+
+ Copy the colorkey values into a 2d array.
+
+ Create a new array with the colorkey transparency value from each
+ pixel. If the pixel matches the colorkey it will be fully
+ tranparent; otherwise it will be fully opaque.
+
+ This will work on any type of Surface format. If the image has no
+ colorkey a solid opaque array will be returned.
+
+ This function will temporarily lock the Surface as pixels are
+ copied.
+ """
+ if __arraytype == "numeric":
+ return numericsf.array_colorkey (surface)
+ elif __arraytype == "numpy":
+ return numpysf.array_colorkey (surface)
+ raise NotImplementedError("surface arrays are not supported")
+
+def make_surface (array):
+ """pygame.surfarray.make_surface (array): return Surface
+
+ Copy an array to a new surface.
+
+ Create a new Surface that best resembles the data and format on the
+ array. The array can be 2D or 3D with any sized integer values.
+ """
+ if __arraytype == "numeric":
+ return numericsf.make_surface (array)
+ elif __arraytype == "numpy":
+ return numpysf.make_surface (array)
+ raise NotImplementedError("surface arrays are not supported")
+
+##def blit_array (surface, array):
+## """pygame.surfarray.blit_array (Surface, array): return None
+##
+## Blit directly from a array values.
+##
+## Directly copy values from an array into a Surface. This is faster
+## than converting the array into a Surface and blitting. The array
+## must be the same dimensions as the Surface and will completely
+## replace all pixel values.
+##
+## This function will temporarily lock the Surface as the new values
+## are copied.
+## """
+## if __arraytype == "numeric":
+## return numericsf.blit_array (surface, array)
+## elif __arraytype == "numpy":
+## return numpysf.blit_array (surface, array)
+## raise NotImplementedError("surface arrays are not supported")
+
+def map_array (surface, array):
+ """pygame.surfarray.map_array (Surface, array3d): return array2d
+
+ Map a 3D array into a 2D array.
+
+ Convert a 3D array into a 2D array. This will use the given Surface
+ format to control the conversion. Palette surface formats are not
+ supported.
+ """
+ if __arraytype == "numeric":
+ return numericsf.map_array (surface, array)
+ elif __arraytype == "numpy":
+ return numpysf.map_array (surface, array)
+ raise NotImplementedError("surface arrays are not supported")
+
+def use_arraytype (arraytype):
+ """pygame.surfarray.use_arraytype (arraytype): return None
+
+ Sets the array system to be used for surface arrays.
+
+ Uses the requested array type for the module functions.
+ Currently supported array types are:
+
+ numeric
+ numpy
+
+ If the requested type is not available, a ValueError will be raised.
+ """
+ global __arraytype
+
+ arraytype = arraytype.lower ()
+ if arraytype == "numeric":
+ if __hasnumeric:
+ __arraytype = arraytype
+ else:
+ raise ValueError("Numeric arrays are not available")
+
+ elif arraytype == "numpy":
+ if __hasnumpy:
+ __arraytype = arraytype
+ else:
+ raise ValueError("numpy arrays are not available")
+ else:
+ raise ValueError("invalid array type")
+
+def get_arraytype ():
+ """pygame.surfarray.get_arraytype (): return str
+
+ Gets the currently active array type.
+
+ Returns the currently active array type. This will be a value of the
+ get_arraytypes() tuple and indicates which type of array module is
+ used for the array creation.
+ """
+ return __arraytype
+
+def get_arraytypes ():
+ """pygame.surfarray.get_arraytypes (): return tuple
+
+ Gets the array system types currently supported.
+
+ Checks, which array system types are available and returns them as a
+ tuple of strings. The values of the tuple can be used directly in
+ the use_arraytype () method.
+
+ If no supported array system could be found, None will be returned.
+ """
+ vals = []
+ if __hasnumeric:
+ vals.append ("numeric")
+ if __hasnumpy:
+ vals.append ("numpy")
+ if len (vals) == 0:
+ return None
+ return tuple (vals)
+
diff --git a/src/pygame/surfarray.pyo b/src/pygame/surfarray.pyo
new file mode 100644
index 0000000..2852ccb
--- /dev/null
+++ b/src/pygame/surfarray.pyo
Binary files differ
diff --git a/src/pygame/surflock.so b/src/pygame/surflock.so
new file mode 100644
index 0000000..2b58744
--- /dev/null
+++ b/src/pygame/surflock.so
Binary files differ
diff --git a/src/pygame/sysfont.py b/src/pygame/sysfont.py
new file mode 100644
index 0000000..175879a
--- /dev/null
+++ b/src/pygame/sysfont.py
@@ -0,0 +1,633 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+"sysfont, used in the font module to find system fonts"
+
+import os, sys
+
+#Python 3 compatibility
+try:
+ bytes
+except NameError:
+ def toascii(raw):
+ return raw.decode('ascii', 'ignore').encode('ascii')
+else:
+ def toascii(raw):
+ return raw.decode('ascii', 'ignore')
+
+#create simple version of the font name
+def _simplename(name):
+ return ''.join([c.lower() for c in name if c.isalnum()])
+
+
+#insert a font and style into the font dictionary
+def _addfont(name, bold, italic, font, fontdict):
+ if name not in fontdict:
+ fontdict[name] = {}
+ fontdict[name][bold, italic] = font
+
+
+#read the fonts on windows
+# Info taken from:
+# http://www.microsoft.com/typography/fonts/winxp.htm
+# with extra files added from:
+# http://www.ampsoft.net/webdesign-l/windows-fonts-by-version.html
+# File name, family, (Bold, Italic)
+_XP_default_font_files = [
+ ('ahronbd.ttf', 'Aharoni', True, False),
+ ('andlso.ttf', 'Andalus', False, False),
+ ('angsa.ttf', 'Angsana New', False, False),
+ ('angsab.ttf', 'Angsana New', True, False),
+ ('angsai.ttf', 'Angsana New', False, True),
+ ('angsaz.ttf', 'Angsana New', True, True),
+ ('angsau.ttf', 'AngsanaUPC', False, False),
+ ('angsaub.ttf', 'AngsanaUPC', True, False),
+ ('angsaui.ttf', 'AngsanaUPC', False, True),
+ ('angsauz.ttf', 'AngsanaUPC', True, True),
+ ('artro.ttf', 'Arabic Transparent', False, False),
+ ('artrbdo.ttf', 'Arabic Transparent', True, False),
+ ('agatha.ttf', 'Agatha', False, False),
+ ('arial.ttf', 'Arial', False, False),
+ ('arialbd.ttf', 'Arial', True, False),
+ ('ariali.ttf', 'Arial', False, True),
+ ('arialbi.ttf', 'Arial', True, True),
+ ('ariblk.ttf', 'Arial Black', False, False),
+ ('browa.ttf', 'Browallia New', False, False),
+ ('browab.ttf', 'Browallia New', True, False),
+ ('browai.ttf', 'Browallia New', False, True),
+ ('browaz.ttf', 'Browallia New', True, True),
+ ('browau.ttf', 'BrowalliaUPC', False, False),
+ ('browaub.ttf', 'BrowalliaUPC', True, False),
+ ('browaui.ttf', 'BrowalliaUPC', False, True),
+ ('browauz.ttf', 'BrowalliaUPC', True, True),
+ ('comic.ttf', 'Comic Sans MS', False, False),
+ ('comicbd.ttf', 'Comic Sans MS', True, False),
+ ('cordia.ttf', 'Cordia New', False, False),
+ ('cordiab.ttf', 'Cordia New', True, False),
+ ('cordiai.ttf', 'Cordia New', False, True),
+ ('cordiaz.ttf', 'Cordia New', True, True),
+ ('cordiau.ttf', 'CordiaUPC', False, False),
+ ('cordiaub.ttf', 'CordiaUPC', True, False),
+ ('cordiaui.ttf', 'CordiaUPC', False, True),
+ ('cordiauz.ttf', 'CordiaUPC', True, True),
+ ('cour.ttf', 'Courier New', False, False),
+ ('courbd.ttf', 'Courier New', True, False),
+ ('couri.ttf', 'Courier New', False, True),
+ ('courbi.ttf', 'Courier New', True, True),
+ ('david.ttf', 'David', False, False),
+ ('davidbd.ttf', 'David', True, False),
+ ('davidtr.ttf', 'David Transparent', False, False),
+ ('upcdl.ttf', 'DilleniaUPC', False, False),
+ ('upcdb.ttf', 'DilleniaUPC', True, False),
+ ('upcdi.ttf', 'DilleniaUPC', False, True),
+ ('upcdbi.ttf', 'DilleniaUPC', True, True),
+ ('estre.ttf', 'Estrangelo Edessa', False, False),
+ ('upcel.ttf', 'EucrosialUPC', False, False),
+ ('upceb.ttf', 'EucrosialUPC', True, False),
+ ('upcei.ttf', 'EucrosialUPC', False, True),
+ ('upcebi.ttf', 'EucrosialUPC', True, True),
+ ('mriamfx.ttf', 'Fixed Miriam Transparent', False, False),
+ ('framd.ttf', 'Franklin Gothic Medium', False, False),
+ ('framdit.ttf', 'Franklin Gothic Medium', False, True),
+ ('frank.ttf', 'FrankRuehl', False, False),
+ ('upcfl.ttf', 'FreesialUPC', False, False),
+ ('upcfb.ttf', 'FreesialUPC', True, False),
+ ('upcfi.ttf', 'FreesialUPC', False, True),
+ ('upcfbi.ttf', 'FreesialUPC', True, True),
+ ('gautami.ttf', 'Gautami', False, False),
+ ('georgia.ttf', 'Georgia', False, False),
+ ('georgiab.ttf', 'Georgia', True, False),
+ ('georgiai.ttf', 'Georgia', False, True),
+ ('georgiaz.ttf', 'Georgia', True, True),
+ ('impact.ttf', 'Impact', False, False),
+ ('upcil.ttf', 'IrisUPC', False, False),
+ ('upcib.ttf', 'IrisUPC', True, False),
+ ('upcii.ttf', 'IrisUPC', False, True),
+ ('upcibi.ttf', 'IrisUPC', True, True),
+ ('upcjl.ttf', 'JasmineUPC', False, False),
+ ('upcjb.ttf', 'JasmineUPC', True, False),
+ ('upcji.ttf', 'JasmineUPC', False, True),
+ ('upcjbi.ttf', 'JasmineUPC', True, True),
+ ('upckl.ttf', 'KodchiangUPC', False, False),
+ ('upckb.ttf', 'KodchiangUPC', True, False),
+ ('upcki.ttf', 'KodchiangUPC', False, True),
+ ('upckbi.ttf', 'KodchiangUPC', True, True),
+ ('latha.ttf', 'Latha', False, False),
+ ('lvnm.ttf', 'Levenim MT', False, False),
+ ('lvnmbd.ttf', 'Levenim MT', True, False),
+ ('upcll.ttf', 'LilyUPC', False, False),
+ ('upclb.ttf', 'LilyUPC', True, False),
+ ('upcli.ttf', 'LilyUPC', False, True),
+ ('upclbi.ttf', 'LilyUPC', True, True),
+ ('lucon.ttf', 'Lucida Console', False, False),
+ ('l_10646.ttf', 'Lucida Sans Unicode', False, False),
+ ('mangal.ttf', 'Mangal', False, False),
+ ('marlett.ttf', 'Marlett', False, False),
+ ('micross.ttf', 'Microsoft Sans Serif', False, False),
+ ('mriam.ttf', 'Miriam', False, False),
+ ('mriamc.ttf', 'Miriam Fixed', False, False),
+ ('mriamtr.ttf', 'Miriam Transparent', False, False),
+ ('mvboli.ttf', 'MV Boli', False, False),
+ ('nrkis.ttf', 'Narkisim', False, False),
+ ('pala.ttf', 'Falatino Linotype', False, False),
+ ('palab.ttf', 'Falatino Linotype', True, False),
+ ('palai.ttf', 'Falatino Linotype', False, True),
+ ('palabi.ttf', 'Falatino Linotype', True, True),
+ ('raavi.ttf', 'Raavi', False, False),
+ ('rod.ttf', 'Rod', False, False),
+ ('rodtr.ttf', 'Rod Transparent', False, False),
+ ('shruti.ttf', 'Shruti', False, False),
+ ('simpo.ttf', 'Simplified Arabic', False, False),
+ ('simpbdo.ttf', 'Simplified Arabic', True, False),
+ ('simpfxo.ttf', 'Simplified Arabic Fixed', False, False),
+ ('sylfaen.ttf', 'Sylfaen', False, False),
+ ('symbol.ttf', 'Symbol', False, False),
+ ('tahoma.ttf', 'Tahoma', False, False),
+ ('tahomabd.ttf', 'Tahoma', True, False),
+ ('times.ttf', 'Times New Roman', False, False),
+ ('timesbd.ttf', 'Times New Roman', True, False),
+ ('timesi.ttf', 'Times New Roman', False, True),
+ ('timesbi.ttf', 'Times New Roman', True, True),
+ ('trado.ttf', 'Traditional Arabic', False, False),
+ ('tradbdo.ttf', 'Traditional Arabic', True, False),
+ ('Trebuc.ttf', 'Trebuchet MS', False, False),
+ ('Trebucbd.ttf', 'Trebuchet MS', True, False),
+ ('Trebucit.ttf', 'Trebuchet MS', False, True),
+ ('Trebucbi.ttf', 'Trebuchet MS', True, True),
+ ('tunga.ttf', 'Tunga', False, False),
+ ('verdana.ttf', 'Verdana', False, False),
+ ('verdanab.ttf', 'Verdana', True, False),
+ ('verdanai.ttf', 'Verdana', False, True),
+ ('verdanaz.ttf', 'Verdana', True, True),
+ ('webdings.ttf', 'Webdings', False, False),
+ ('wingding.ttf', 'Wingdings', False, False),
+ ('simhei.ttf', 'SimHei', False, False),
+ ('simfang.ttf', 'FangSong_GB2312', False, False),
+ ('kaiu.ttf', 'DFKai-SB', False, False),
+ ('simkai.ttf', 'KaiTi_GB2312', False, False),
+ ('msgothic.ttc', 'MS Gothic', False, False),
+ ('msmincho.ttc', 'MS Mincho', False, False),
+ ('gulim.ttc', 'Gulim', False, False),
+ ('mingliu.ttc', 'Mingliu', False, False),
+ ('simsun.ttc', 'Simsun', False, False),
+ ('batang.ttc', 'Batang', False, False),
+ ]
+
+
+
+
+def initsysfonts_win32():
+ try:
+ import _winreg
+ except ImportError:
+ import winreg as _winreg
+
+ if 'WINDIR' in os.environ:
+ windir = os.environ['WINDIR']
+ elif 'windir' in os.environ:
+ windir = os.environ['windir']
+ else:
+ windir = "C:\\Windows\\"
+
+
+ fonts = {}
+ mods = 'demibold', 'narrow', 'light', 'unicode', 'bt', 'mt'
+ fontdir = os.path.join(windir, "Fonts")
+
+ #this is a list of registry keys containing information
+ #about fonts installed on the system.
+ keys = []
+
+ #add recognized fonts from the fonts directory because the default
+ #fonts may not be entered in the registry.
+ win_font_files_mapping = dict(
+ [(file_name.lower(), (_simplename(name), bold, italic))
+ for file_name, name, bold, italic in _XP_default_font_files])
+
+ font_dir_path = os.path.join(windir, 'fonts')
+ try:
+ font_file_paths = glob.glob(os.path.join(font_dir_path, '*.tt?'))
+ except Exception:
+ pass
+ else:
+ for font in font_file_paths:
+ file_name = os.path.basename(font)
+ try:
+ name, bold, italic = win_font_file_mapping[file_name]
+ except KeyError:
+ pass
+ else:
+ _addfont(name, bold, italic, font, fonts)
+
+ #add additional fonts entered in the registry.
+
+ #find valid registry keys containing font information.
+ possible_keys = [
+ r"SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts",
+ r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",
+ r"SOFTWARE\Microsoft\Windows[NT]\CurrentVersion\Fonts",
+ ]
+
+ for key_name in possible_keys:
+ try:
+ key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name)
+ keys.append(key)
+ except WindowsError:
+ pass
+
+ for key in keys:
+ fontdict = {}
+ for i in range(_winreg.QueryInfoKey(key)[1]):
+ try: name, font, t = _winreg.EnumValue(key,i)
+ except EnvironmentError: break
+
+ # try and handle windows unicode strings for some file names.
+
+ # here are two documents with some information about it:
+ # http://www.python.org/peps/pep-0277.html
+ # https://www.microsoft.com/technet/archive/interopmigration/linux/mvc/lintowin.mspx#ECAA
+ try:
+ font = str(font)
+ except UnicodeEncodeError:
+ # MBCS is the windows encoding for unicode file names.
+ try:
+ font = font.encode('MBCS')
+ except:
+ # no goodness with str or MBCS encoding... skip this font.
+ continue
+
+ if font[-4:].lower() not in [".ttf", ".ttc"]:
+ continue
+ if os.sep not in font:
+ font = os.path.join(fontdir, font)
+
+ if name[-10:] == '(TrueType)':
+ name = name[:-11]
+ name = name.lower().split()
+
+ bold = italic = 0
+ for m in mods:
+ if m in name:
+ name.remove(m)
+ if 'bold' in name:
+ name.remove('bold')
+ bold = 1
+ if 'italic' in name:
+ name.remove('italic')
+ italic = 1
+ name = ''.join(name)
+
+ name=_simplename(name)
+
+ _addfont(name, bold, italic, font, fonts)
+
+ return fonts
+
+
+
+
+
+_OSX_default_font_files = {
+ 'albayan': {(False, False): '/Library/Fonts/AlBayan.ttf',
+ (True, False): '/Library/Fonts/AlBayanBold.ttf'},
+ 'andalemono': {(False, False): '/Library/Fonts/Andale Mono.ttf'},
+ 'applebraille': {(False, False): '/System/Library/Fonts/Apple Braille Outline 6 Dot.ttf'},
+ 'applegothic': {(False, False): '/System/Library/Fonts/AppleGothic.ttf'},
+ 'applesymbols': {(False, False): '/System/Library/Fonts/Apple Symbols.ttf'},
+ 'arial': {(False, False): '/Library/Fonts/Arial.ttf',
+ (False, True): '/Library/Fonts/Arial Italic.ttf',
+ (True, False): '/Library/Fonts/Arial Bold.ttf',
+ (True, True): '/Library/Fonts/Arial Bold Italic.ttf'},
+ 'arialblack': {(False, False): '/Library/Fonts/Arial Black.ttf'},
+ 'arialhebrew': {(False, False): '/Library/Fonts/ArialHB.ttf',
+ (True, False): '/Library/Fonts/ArialHBBold.ttf'},
+ 'arialnarrow': {(False, False): '/Library/Fonts/Arial Narrow.ttf',
+ (False, True): '/Library/Fonts/Arial Narrow Italic.ttf',
+ (True, False): '/Library/Fonts/Arial Narrow Bold.ttf',
+ (True, True): '/Library/Fonts/Arial Narrow Bold Italic.ttf'},
+ 'arialroundedmtbold': {(False, False): '/Library/Fonts/Arial Rounded Bold.ttf'},
+ 'arialunicodems': {(False, False): '/Library/Fonts/Arial Unicode.ttf'},
+ 'ayuthaya': {(False, False): '/Library/Fonts/Ayuthaya.ttf'},
+ 'baghdad': {(False, False): '/Library/Fonts/Baghdad.ttf'},
+ 'brushscriptmt': {(False, True): '/Library/Fonts/Brush Script.ttf'},
+ 'chalkboard': {(False, False): '/Library/Fonts/Chalkboard.ttf',
+ (True, False): '/Library/Fonts/ChalkboardBold.ttf'},
+ 'comicsansms': {(False, False): '/Library/Fonts/Comic Sans MS.ttf',
+ (True, False): '/Library/Fonts/Comic Sans MS Bold.ttf'},
+ 'corsivahebrew': {(False, False): '/Library/Fonts/Corsiva.ttf',
+ (True, False): '/Library/Fonts/CorsivaBold.ttf'},
+ 'couriernew': {(False, False): '/Library/Fonts/Courier New.ttf',
+ (False, True): '/Library/Fonts/Courier New Italic.ttf',
+ (True, False): '/Library/Fonts/Courier New Bold.ttf',
+ (True, True): '/Library/Fonts/Courier New Bold Italic.ttf'},
+ 'decotypenaskh': {(False, False): '/Library/Fonts/DecoTypeNaskh.ttf'},
+ 'devanagarimt': {(False, False): '/Library/Fonts/DevanagariMT.ttf',
+ (True, False): '/Library/Fonts/DevanagariMTBold.ttf'},
+ 'euphemiaucas': {(False, False): '/Library/Fonts/EuphemiaCASRegular.ttf',
+ (False, True): '/Library/Fonts/EuphemiaCASItalic.ttf',
+ (True, False): '/Library/Fonts/EuphemiaCASBold.ttf'},
+ 'gb18030bitmap': {(False, False): '/Library/Fonts/NISC18030.ttf'},
+ 'geezapro': {(False, False): '/System/Library/Fonts/Geeza Pro.ttf',
+ (True, False): '/System/Library/Fonts/Geeza Pro Bold.ttf'},
+ 'georgia': {(False, False): '/Library/Fonts/Georgia.ttf',
+ (False, True): '/Library/Fonts/Georgia Italic.ttf',
+ (True, False): '/Library/Fonts/Georgia Bold.ttf',
+ (True, True): '/Library/Fonts/Georgia Bold Italic.ttf'},
+ 'gujaratimt': {(False, False): '/Library/Fonts/GujaratiMT.ttf',
+ (True, False): '/Library/Fonts/GujaratiMTBold.ttf'},
+ 'gurmukhimt': {(False, False): '/Library/Fonts/Gurmukhi.ttf'},
+ 'impact': {(False, False): '/Library/Fonts/Impact.ttf'},
+ 'inaimathi': {(False, False): '/Library/Fonts/InaiMathi.ttf'},
+ 'kailasa': {(False, False): '/Library/Fonts/Kailasa.ttf'},
+ 'kokonor': {(False, False): '/Library/Fonts/Kokonor.ttf'},
+ 'krungthep': {(False, False): '/Library/Fonts/Krungthep.ttf'},
+ 'kufistandardgk': {(False, False): '/Library/Fonts/KufiStandardGK.ttf'},
+ 'liheipro': {(False, False): '/System/Library/Fonts/ Pro.ttf'},
+ 'lisongpro': {(False, False): '/Library/Fonts/ Pro.ttf'},
+ 'microsoftsansserif': {(False, False): '/Library/Fonts/Microsoft Sans Serif.ttf'},
+ 'mshtakan': {(False, False): '/Library/Fonts/MshtakanRegular.ttf',
+ (False, True): '/Library/Fonts/MshtakanOblique.ttf',
+ (True, False): '/Library/Fonts/MshtakanBold.ttf',
+ (True, True): '/Library/Fonts/MshtakanBoldOblique.ttf'},
+ 'nadeem': {(False, False): '/Library/Fonts/Nadeem.ttf'},
+ 'newpeninimmt': {(False, False): '/Library/Fonts/NewPeninimMT.ttf',
+ (True, False): '/Library/Fonts/NewPeninimMTBoldInclined.ttf'},
+ 'plantagenetcherokee': {(False, False): '/Library/Fonts/PlantagenetCherokee.ttf'},
+ 'raanana': {(False, False): '/Library/Fonts/Raanana.ttf',
+ (True, False): '/Library/Fonts/RaananaBold.ttf'},
+ 'sathu': {(False, False): '/Library/Fonts/Sathu.ttf'},
+ 'silom': {(False, False): '/Library/Fonts/Silom.ttf'},
+ 'stfangsong': {(False, False): '/Library/Fonts/.ttf'},
+ 'stheiti': {(False, False): '/System/Library/Fonts/.ttf'},
+ 'stkaiti': {(False, False): '/Library/Fonts/.ttf'},
+ 'stsong': {(False, False): '/Library/Fonts/.ttf'},
+ 'tahoma': {(False, False): '/Library/Fonts/Tahoma.ttf',
+ (True, False): '/Library/Fonts/Tahoma Bold.ttf'},
+ 'thonburi': {(False, False): '/System/Library/Fonts/Thonburi.ttf',
+ (True, False): '/System/Library/Fonts/ThonburiBold.ttf'},
+ 'timesnewroman': {(False, False): '/Library/Fonts/Times New Roman.ttf',
+ (False, True): '/Library/Fonts/Times New Roman Italic.ttf',
+ (True, False): '/Library/Fonts/Times New Roman Bold.ttf',
+ (True, True): '/Library/Fonts/Times New Roman Bold Italic.ttf'},
+ 'trebuchetms': {(False, False): '/Library/Fonts/Trebuchet MS.ttf',
+ (False, True): '/Library/Fonts/Trebuchet MS Italic.ttf',
+ (True, False): '/Library/Fonts/Trebuchet MS Bold.ttf',
+ (True, True): '/Library/Fonts/Trebuchet MS Bold Italic.ttf'},
+ 'verdana': {(False, False): '/Library/Fonts/Verdana.ttf',
+ (False, True): '/Library/Fonts/Verdana Italic.ttf',
+ (True, False): '/Library/Fonts/Verdana Bold.ttf',
+ (True, True): '/Library/Fonts/Verdana Bold Italic.ttf'},
+ 'webdings': {(False, False): '/Library/Fonts/Webdings.ttf'},
+ 'wingdings': {(False, False): '/Library/Fonts/Wingdings.ttf'},
+ 'wingdings2': {(False, False): '/Library/Fonts/Wingdings 2.ttf'},
+ 'wingdings3': {(False, False): '/Library/Fonts/Wingdings 3.ttf'}}
+
+
+def _search_osx_font_paths(fonts):
+
+ for name, details in _OSX_default_font_files.items():
+ for k, apath in details.items():
+ if os.path.exists(apath):
+ bold, italic = k
+ _addfont(name, bold, italic, apath, fonts)
+
+
+def initsysfonts_darwin():
+ """ read the fonts on OSX.
+ """
+ # if the X11 binary exists... try and use that.
+ # Not likely to be there on pre 10.4.x ...
+ # so still need to do other OSX specific method below.
+ if os.path.exists("/usr/X11/bin/fc-list"):
+ fonts = initsysfonts_unix()
+
+ # we look for the default paths.
+ _search_osx_font_paths(fonts)
+
+ return fonts
+
+
+
+
+
+ paths = ['/Library/Fonts',
+ '~/Library/Fonts',
+ '/Local/Library/Fonts',
+ '/Network/Library/Fonts']
+ fonts = {}
+ for p in paths:
+ if os.path.isdir(p):
+ pass
+ #os.path.walk(p, _fontwalk, fonts)
+ return fonts
+
+
+
+
+#read the fonts on unix
+def initsysfonts_unix():
+ import subprocess
+
+ fonts = {}
+
+ # we use the fc-list from fontconfig to get a list of fonts.
+
+ try:
+ # note, we capture stderr so if fc-list isn't there to stop stderr printing.
+ flout, flerr = subprocess.Popen('fc-list : file family style', shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ close_fds=True).communicate()
+ except Exception:
+ return fonts
+
+ entries = toascii(flout)
+ try:
+ for line in entries.split('\n'):
+ try:
+ filename, family, style = line.split(':', 2)
+ if filename[-4:].lower() in ['.ttf', '.ttc']:
+ bold = style.find('Bold') >= 0
+ italic = style.find('Italic') >= 0
+ oblique = style.find('Oblique') >= 0
+ for name in family.split(','):
+ if name:
+ break
+ else:
+ name = os.path.splitext(os.path.basename(filename))[0]
+ _addfont(_simplename(name),
+ bold, italic or oblique, filename, fonts)
+ except Exception:
+ # try the next one.
+ pass
+ except Exception:
+ pass
+
+ return fonts
+
+
+
+#create alias entries
+def create_aliases():
+ aliases = (
+ ('monospace', 'misc-fixed', 'courier', 'couriernew', 'console',
+ 'fixed', 'mono', 'freemono', 'bitstreamverasansmono',
+ 'verasansmono', 'monotype', 'lucidaconsole'),
+ ('sans', 'arial', 'helvetica', 'swiss', 'freesans',
+ 'bitstreamverasans', 'verasans', 'verdana', 'tahoma'),
+ ('serif', 'times', 'freeserif', 'bitstreamveraserif', 'roman',
+ 'timesroman', 'timesnewroman', 'dutch', 'veraserif',
+ 'georgia'),
+ ('wingdings', 'wingbats'),
+ )
+ for set in aliases:
+ found = None
+ fname = None
+ for name in set:
+ if name in Sysfonts:
+ found = Sysfonts[name]
+ fname = name
+ break
+ if not found:
+ continue
+ for name in set:
+ if name not in Sysfonts:
+ Sysalias[name] = found
+
+
+Sysfonts = {}
+Sysalias = {}
+
+#initialize it all, called once
+def initsysfonts():
+ if sys.platform == 'win32':
+ fonts = initsysfonts_win32()
+ elif sys.platform == 'darwin':
+ fonts = initsysfonts_darwin()
+ else:
+ fonts = initsysfonts_unix()
+ Sysfonts.update(fonts)
+ create_aliases()
+ if not Sysfonts: #dummy so we don't try to reinit
+ Sysfonts[None] = None
+
+
+
+#the exported functions
+
+def SysFont(name, size, bold=False, italic=False):
+ """pygame.font.SysFont(name, size, bold=False, italic=False) -> Font
+ create a pygame Font from system font resources
+
+ This will search the system fonts for the given font
+ name. You can also enable bold or italic styles, and
+ the appropriate system font will be selected if available.
+
+ This will always return a valid Font object, and will
+ fallback on the builtin pygame font if the given font
+ is not found.
+
+ Name can also be a comma separated list of names, in
+ which case set of names will be searched in order. Pygame
+ uses a small set of common font aliases, if the specific
+ font you ask for is not available, a reasonable alternative
+ may be used.
+ """
+ import pygame.font
+
+ if not Sysfonts:
+ initsysfonts()
+
+ gotbold = gotitalic = False
+ fontname = None
+ if name:
+ allnames = name
+ for name in allnames.split(','):
+ name = _simplename(name)
+ styles = Sysfonts.get(name)
+ if not styles:
+ styles = Sysalias.get(name)
+ if styles:
+ while not fontname:
+ plainname = styles.get((False, False))
+ fontname = styles.get((bold, italic))
+ if not fontname:
+ fontname = plainname
+ elif plainname != fontname:
+ gotbold = bold
+ gotitalic = italic
+ if fontname: break
+
+ font = pygame.font.Font(fontname, size)
+ if bold and not gotbold:
+ font.set_bold(1)
+ if italic and not gotitalic:
+ font.set_italic(1)
+
+ return font
+
+
+def get_fonts():
+ """pygame.font.get_fonts() -> list
+ get a list of system font names
+
+ Returns the list of all found system fonts. Note that
+ the names of the fonts will be all lowercase with spaces
+ removed. This is how pygame internally stores the font
+ names for matching.
+ """
+ if not Sysfonts:
+ initsysfonts()
+ return list(Sysfonts.keys())
+
+
+def match_font(name, bold=0, italic=0):
+ """pygame.font.match_font(name, bold=0, italic=0) -> name
+ find the filename for the named system font
+
+ This performs the same font search as the SysFont()
+ function, only it returns the path to the TTF file
+ that would be loaded. The font name can be a comma
+ separated list of font names to try.
+
+ If no match is found, None is returned.
+ """
+ if not Sysfonts:
+ initsysfonts()
+
+ fontname = None
+ allnames = name
+ for name in allnames.split(','):
+ name = _simplename(name)
+ styles = Sysfonts.get(name)
+ if not styles:
+ styles = Sysalias.get(name)
+ if styles:
+ while not fontname:
+ fontname = styles.get((bold, italic))
+ if italic:
+ italic = 0
+ elif bold:
+ bold = 0
+ elif not fontname:
+ fontname = list(styles.values())[0]
+ if fontname: break
+ return fontname
+
+
diff --git a/src/pygame/threads/.gitignore b/src/pygame/threads/.gitignore
new file mode 100644
index 0000000..a74b07a
--- /dev/null
+++ b/src/pygame/threads/.gitignore
@@ -0,0 +1 @@
+/*.pyc
diff --git a/src/pygame/threads/Py25Queue.py b/src/pygame/threads/Py25Queue.py
new file mode 100644
index 0000000..603c1bd
--- /dev/null
+++ b/src/pygame/threads/Py25Queue.py
@@ -0,0 +1,216 @@
+"""A multi-producer, multi-consumer queue."""
+
+from time import time as _time
+
+from collections import deque
+
+__all__ = ['Empty', 'Full', 'Queue']
+
+class Empty(Exception):
+ "Exception raised by Queue.get(block=0)/get_nowait()."
+ pass
+
+class Full(Exception):
+ "Exception raised by Queue.put(block=0)/put_nowait()."
+ pass
+
+class Queue:
+ """Create a queue object with a given maximum size.
+
+ If maxsize is <= 0, the queue size is infinite.
+ """
+ def __init__(self, maxsize=0):
+ try:
+ import threading
+ except ImportError:
+ import dummy_threading as threading
+ self._init(maxsize)
+ # mutex must be held whenever the queue is mutating. All methods
+ # that acquire mutex must release it before returning. mutex
+ # is shared between the three conditions, so acquiring and
+ # releasing the conditions also acquires and releases mutex.
+ self.mutex = threading.Lock()
+ # Notify not_empty whenever an item is added to the queue; a
+ # thread waiting to get is notified then.
+ self.not_empty = threading.Condition(self.mutex)
+ # Notify not_full whenever an item is removed from the queue;
+ # a thread waiting to put is notified then.
+ self.not_full = threading.Condition(self.mutex)
+ # Notify all_tasks_done whenever the number of unfinished tasks
+ # drops to zero; thread waiting to join() is notified to resume
+ self.all_tasks_done = threading.Condition(self.mutex)
+ self.unfinished_tasks = 0
+
+ def task_done(self):
+ """Indicate that a formerly enqueued task is complete.
+
+ Used by Queue consumer threads. For each get() used to fetch a task,
+ a subsequent call to task_done() tells the queue that the processing
+ on the task is complete.
+
+ If a join() is currently blocking, it will resume when all items
+ have been processed (meaning that a task_done() call was received
+ for every item that had been put() into the queue).
+
+ Raises a ValueError if called more times than there were items
+ placed in the queue.
+ """
+ self.all_tasks_done.acquire()
+ try:
+ unfinished = self.unfinished_tasks - 1
+ if unfinished <= 0:
+ if unfinished < 0:
+ raise ValueError('task_done() called too many times')
+ self.all_tasks_done.notifyAll()
+ self.unfinished_tasks = unfinished
+ finally:
+ self.all_tasks_done.release()
+
+ def join(self):
+ """Blocks until all items in the Queue have been gotten and processed.
+
+ The count of unfinished tasks goes up whenever an item is added to the
+ queue. The count goes down whenever a consumer thread calls task_done()
+ to indicate the item was retrieved and all work on it is complete.
+
+ When the count of unfinished tasks drops to zero, join() unblocks.
+ """
+ self.all_tasks_done.acquire()
+ try:
+ while self.unfinished_tasks:
+ self.all_tasks_done.wait()
+ finally:
+ self.all_tasks_done.release()
+
+ def qsize(self):
+ """Return the approximate size of the queue (not reliable!)."""
+ self.mutex.acquire()
+ n = self._qsize()
+ self.mutex.release()
+ return n
+
+ def empty(self):
+ """Return True if the queue is empty, False otherwise (not reliable!)."""
+ self.mutex.acquire()
+ n = self._empty()
+ self.mutex.release()
+ return n
+
+ def full(self):
+ """Return True if the queue is full, False otherwise (not reliable!)."""
+ self.mutex.acquire()
+ n = self._full()
+ self.mutex.release()
+ return n
+
+ def put(self, item, block=True, timeout=None):
+ """Put an item into the queue.
+
+ If optional args 'block' is true and 'timeout' is None (the default),
+ block if necessary until a free slot is available. If 'timeout' is
+ a positive number, it blocks at most 'timeout' seconds and raises
+ the Full exception if no free slot was available within that time.
+ Otherwise ('block' is false), put an item on the queue if a free slot
+ is immediately available, else raise the Full exception ('timeout'
+ is ignored in that case).
+ """
+ self.not_full.acquire()
+ try:
+ if not block:
+ if self._full():
+ raise Full
+ elif timeout is None:
+ while self._full():
+ self.not_full.wait()
+ else:
+ if timeout < 0:
+ raise ValueError("'timeout' must be a positive number")
+ endtime = _time() + timeout
+ while self._full():
+ remaining = endtime - _time()
+ if remaining <= 0.0:
+ raise Full
+ self.not_full.wait(remaining)
+ self._put(item)
+ self.unfinished_tasks += 1
+ self.not_empty.notify()
+ finally:
+ self.not_full.release()
+
+ def put_nowait(self, item):
+ """Put an item into the queue without blocking.
+
+ Only enqueue the item if a free slot is immediately available.
+ Otherwise raise the Full exception.
+ """
+ return self.put(item, False)
+
+ def get(self, block=True, timeout=None):
+ """Remove and return an item from the queue.
+
+ If optional args 'block' is true and 'timeout' is None (the default),
+ block if necessary until an item is available. If 'timeout' is
+ a positive number, it blocks at most 'timeout' seconds and raises
+ the Empty exception if no item was available within that time.
+ Otherwise ('block' is false), return an item if one is immediately
+ available, else raise the Empty exception ('timeout' is ignored
+ in that case).
+ """
+ self.not_empty.acquire()
+ try:
+ if not block:
+ if self._empty():
+ raise Empty
+ elif timeout is None:
+ while self._empty():
+ self.not_empty.wait()
+ else:
+ if timeout < 0:
+ raise ValueError("'timeout' must be a positive number")
+ endtime = _time() + timeout
+ while self._empty():
+ remaining = endtime - _time()
+ if remaining <= 0.0:
+ raise Empty
+ self.not_empty.wait(remaining)
+ item = self._get()
+ self.not_full.notify()
+ return item
+ finally:
+ self.not_empty.release()
+
+ def get_nowait(self):
+ """Remove and return an item from the queue without blocking.
+
+ Only get an item if one is immediately available. Otherwise
+ raise the Empty exception.
+ """
+ return self.get(False)
+
+ # Override these methods to implement other queue organizations
+ # (e.g. stack or priority queue).
+ # These will only be called with appropriate locks held
+
+ # Initialize the queue representation
+ def _init(self, maxsize):
+ self.maxsize = maxsize
+ self.queue = deque()
+
+ def _qsize(self):
+ return len(self.queue)
+
+ # Check whether the queue is empty
+ def _empty(self):
+ return not self.queue
+
+ # Check whether the queue is full
+ def _full(self):
+ return self.maxsize > 0 and len(self.queue) == self.maxsize
+
+ # Put a new item in the queue
+ def _put(self, item):
+ self.queue.append(item)
+
+ # Get an item from the queue
+ def _get(self):
+ return self.queue.popleft()
diff --git a/src/pygame/threads/__init__.py b/src/pygame/threads/__init__.py
new file mode 100644
index 0000000..4931865
--- /dev/null
+++ b/src/pygame/threads/__init__.py
@@ -0,0 +1,310 @@
+"""
+* Experimental *
+
+Like the map function, but can use a pool of threads.
+
+Really easy to use threads. eg. tmap(f, alist)
+
+If you know how to use the map function, you can use threads.
+"""
+
+__author__ = "Rene Dudfield"
+__version__ = "0.3.0"
+__license__ = 'Python license'
+
+import traceback, sys
+
+from pygame.compat import geterror
+
+if sys.version_info[0] == 3:
+ from multiprocessing import JoinableQueue as Queue
+ from queue import Empty
+elif (sys.version_info[0] == 2 and sys.version_info[1] < 5):
+ from Py25Queue import Queue
+ from Py25Queue import Empty
+else:
+ # use up to date version
+ from Queue import Queue
+ from Queue import Empty
+
+import threading
+Thread = threading.Thread
+
+STOP = object()
+FINISH = object()
+
+# DONE_ONE = object()
+# DONE_TWO = object()
+
+# a default worker queue.
+_wq = None
+
+# if we are using threads or not. This is the number of workers.
+_use_workers = 0
+
+# Set this to the maximum for the amount of Cores/CPUs
+# Note, that the tests early out.
+# So it should only test the best number of workers +2
+MAX_WORKERS_TO_TEST = 64
+
+
+
+def init(number_of_workers = 0):
+ """ Does a little test to see if threading is worth it.
+ Sets up a global worker queue if it's worth it.
+
+ Calling init() is not required, but is generally better to do.
+ """
+ global _wq, _use_workers
+
+ if number_of_workers:
+ _use_workers = number_of_workers
+ else:
+ _use_workers = benchmark_workers()
+
+ # if it is best to use zero workers, then use that.
+ _wq = WorkerQueue(_use_workers)
+
+
+
+
+def quit():
+ """ cleans up everything.
+ """
+ global _wq, _use_workers
+ _wq.stop()
+ _wq = None
+ _use_workers = False
+
+
+def benchmark_workers(a_bench_func = None, the_data = None):
+ """ does a little test to see if workers are at all faster.
+ Returns the number of workers which works best.
+ Takes a little bit of time to run, so you should only really call
+ it once.
+ You can pass in benchmark data, and functions if you want.
+ a_bench_func - f(data)
+ the_data - data to work on.
+ """
+ global _use_workers
+
+ #TODO: try and make this scale better with slower/faster cpus.
+ # first find some variables so that using 0 workers takes about 1.0 seconds.
+ # then go from there.
+
+
+ # note, this will only work with pygame 1.8rc3+
+ # replace the doit() and the_data with something that releases the GIL
+
+
+ import pygame
+ import pygame.transform
+ import time
+
+ if not a_bench_func:
+ def doit(x):
+ return pygame.transform.scale(x, (544, 576))
+ else:
+ doit = a_bench_func
+
+ if not the_data:
+ thedata = []
+ for x in range(10):
+ thedata.append(pygame.Surface((155,155), 0, 32))
+ else:
+ thedata = the_data
+
+ best = time.time() + 100000000
+ best_number = 0
+ last_best = -1
+
+ for num_workers in range(0, MAX_WORKERS_TO_TEST):
+
+ wq = WorkerQueue(num_workers)
+ t1 = time.time()
+ for xx in range(20):
+ print ("active count:%s" % threading.activeCount())
+ results = tmap(doit, thedata, worker_queue = wq)
+ t2 = time.time()
+
+ wq.stop()
+
+
+ total_time = t2 - t1
+ print ("total time num_workers:%s: time:%s:" % (num_workers, total_time))
+
+ if total_time < best:
+ last_best = best_number
+ best_number =num_workers
+ best = total_time
+
+ if num_workers - best_number > 1:
+ # We tried to add more, but it didn't like it.
+ # so we stop with testing at this number.
+ break
+
+
+ return best_number
+
+
+
+
+class WorkerQueue(object):
+
+ def __init__(self, num_workers = 20):
+ self.queue = Queue()
+ self.pool = []
+ self._setup_workers(num_workers)
+
+ def _setup_workers(self, num_workers):
+ """ Sets up the worker threads
+ NOTE: undefined behaviour if you call this again.
+ """
+ self.pool = []
+
+ for _ in range(num_workers):
+ self.pool.append(Thread(target=self.threadloop))
+
+ for a_thread in self.pool:
+ a_thread.setDaemon(True)
+ a_thread.start()
+
+
+ def do(self, f, *args, **kwArgs):
+ """ puts a function on a queue for running later.
+ """
+ self.queue.put((f, args, kwArgs))
+
+
+ def stop(self):
+ """ Stops the WorkerQueue, waits for all of the threads to finish up.
+ """
+ self.queue.put(STOP)
+ for thread in self.pool:
+ thread.join()
+
+
+ def threadloop(self): #, finish = False):
+ """ Loops until all of the tasks are finished.
+ """
+ while True:
+ args = self.queue.get()
+ if args is STOP:
+ self.queue.put(STOP)
+ self.queue.task_done()
+ break
+ else:
+ try:
+ args[0](*args[1], **args[2])
+ finally:
+ # clean up the queue, raise the exception.
+ self.queue.task_done()
+ #raise
+
+
+ def wait(self):
+ """ waits until all tasks are complete.
+ """
+ self.queue.join()
+
+class FuncResult:
+ """ Used for wrapping up a function call so that the results are stored
+ inside the instances result attribute.
+ """
+ def __init__(self, f, callback = None, errback = None):
+ """ f - is the function we that we call
+ callback(result) - this is called when the function(f) returns
+ errback(exception) - this is called when the function(f) raises
+ an exception.
+ """
+ self.f = f
+ self.exception = None
+ self.callback = callback
+ self.errback = errback
+
+ def __call__(self, *args, **kwargs):
+
+ #we try to call the function here. If it fails we store the exception.
+ try:
+ self.result = self.f(*args, **kwargs)
+ if self.callback:
+ self.callback(self.result)
+ except Exception:
+ self.exception = geterror()
+ if self.errback:
+ self.errback(self.exception)
+
+
+def tmap(f, seq_args, num_workers = 20, worker_queue = None, wait = True, stop_on_error = True):
+ """ like map, but uses a thread pool to execute.
+ num_workers - the number of worker threads that will be used. If pool
+ is passed in, then the num_workers arg is ignored.
+ worker_queue - you can optionally pass in an existing WorkerQueue.
+ wait - True means that the results are returned when everything is finished.
+ False means that we return the [worker_queue, results] right away instead.
+ results, is returned as a list of FuncResult instances.
+ stop_on_error -
+ """
+
+ if worker_queue:
+ wq = worker_queue
+ else:
+ # see if we have a global queue to work with.
+ if _wq:
+ wq = _wq
+ else:
+ if num_workers == 0:
+ return map(f, seq_args)
+
+ wq = WorkerQueue(num_workers)
+
+ # we short cut it here if the number of workers is 0.
+ # normal map should be faster in this case.
+ if len(wq.pool) == 0:
+ return map(f, seq_args)
+
+ #print ("queue size:%s" % wq.queue.qsize())
+
+
+ #TODO: divide the data (seq_args) into even chunks and
+ # then pass each thread a map(f, equal_part(seq_args))
+ # That way there should be less locking, and overhead.
+
+
+
+ results = []
+ for sa in seq_args:
+ results.append(FuncResult(f))
+ wq.do(results[-1], sa)
+
+
+ #wq.stop()
+
+ if wait:
+ #print ("wait")
+ wq.wait()
+ #print ("after wait")
+ #print ("queue size:%s" % wq.queue.qsize())
+ if wq.queue.qsize():
+ raise Exception("buggy threadmap")
+ # if we created a worker queue, we need to stop it.
+ if not worker_queue and not _wq:
+ #print ("stoping")
+ wq.stop()
+ if wq.queue.qsize():
+ um = wq.queue.get()
+ if not um is STOP:
+ raise Exception("buggy threadmap")
+
+
+ # see if there were any errors. If so raise the first one. This matches map behaviour.
+ # TODO: the traceback doesn't show up nicely.
+ # NOTE: TODO: we might want to return the results anyway? This should be an option.
+ if stop_on_error:
+ error_ones = filter(lambda x:x.exception, results)
+ if error_ones:
+ raise error_ones[0].exception
+
+ return map(lambda x:x.result, results)
+ else:
+ return [wq, results]
diff --git a/src/pygame/threads/__init__.pyo b/src/pygame/threads/__init__.pyo
new file mode 100644
index 0000000..6d335ba
--- /dev/null
+++ b/src/pygame/threads/__init__.pyo
Binary files differ
diff --git a/src/pygame/time.so b/src/pygame/time.so
new file mode 100644
index 0000000..1dcaf56
--- /dev/null
+++ b/src/pygame/time.so
Binary files differ
diff --git a/src/pygame/transform.so b/src/pygame/transform.so
new file mode 100644
index 0000000..79863b5
--- /dev/null
+++ b/src/pygame/transform.so
Binary files differ
diff --git a/src/pygame/version.py b/src/pygame/version.py
new file mode 100644
index 0000000..283fb65
--- /dev/null
+++ b/src/pygame/version.py
@@ -0,0 +1,31 @@
+## pygame - Python Game Library
+## Copyright (C) 2000-2003 Pete Shinners
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Library General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Library General Public License for more details.
+##
+## You should have received a copy of the GNU Library General Public
+## License along with this library; if not, write to the Free
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## Pete Shinners
+## pete@shinners.org
+
+"""Simply the current installed pygame version. The version information is
+stored in the regular pygame module as 'pygame.ver'. Keeping the version
+information also available in a separate module allows you to test the
+pygame version without importing the main pygame module.
+
+The python version information should always compare greater than any previous
+releases. (hmm, until we get to versions > 10)
+"""
+
+ver = '1.9.1release'
+vernum = 1,9,1
diff --git a/src/pygame/version.pyo b/src/pygame/version.pyo
new file mode 100644
index 0000000..ad10b80
--- /dev/null
+++ b/src/pygame/version.pyo
Binary files differ
diff --git a/src/setup.py b/src/setup.py
new file mode 100644
index 0000000..6ea61a6
--- /dev/null
+++ b/src/setup.py
@@ -0,0 +1,3 @@
+#!/usr/bin/python
+from sugar.activity import bundlebuilder
+bundlebuilder.start()
diff --git a/src/sugargame/__init__.py b/src/sugargame/__init__.py
new file mode 100644
index 0000000..439eb0c
--- /dev/null
+++ b/src/sugargame/__init__.py
@@ -0,0 +1 @@
+__version__ = '1.1'
diff --git a/src/sugargame/__init__.pyo b/src/sugargame/__init__.pyo
new file mode 100644
index 0000000..a097d95
--- /dev/null
+++ b/src/sugargame/__init__.pyo
Binary files differ
diff --git a/src/sugargame/canvas.py b/src/sugargame/canvas.py
new file mode 100644
index 0000000..980cb73
--- /dev/null
+++ b/src/sugargame/canvas.py
@@ -0,0 +1,62 @@
+import os
+import gtk
+import gobject
+import pygame
+import event
+
+CANVAS = None
+
+class PygameCanvas(gtk.EventBox):
+
+ """
+ mainwindow is the activity intself.
+ """
+ def __init__(self, mainwindow, pointer_hint = True):
+ gtk.EventBox.__init__(self)
+
+ global CANVAS
+ assert CANVAS == None, "Only one PygameCanvas can be created, ever."
+ CANVAS = self
+
+ # Initialize Events translator before widget gets "realized".
+ self.translator = event.Translator(mainwindow, self)
+
+ self._mainwindow = mainwindow
+
+ self.set_flags(gtk.CAN_FOCUS)
+
+ self._socket = gtk.Socket()
+ self.add(self._socket)
+ self.show_all()
+
+ def run_pygame(self, main_fn):
+ # Run the main loop after a short delay. The reason for the delay is that the
+ # Sugar activity is not properly created until after its constructor returns.
+ # If the Pygame main loop is called from the activity constructor, the
+ # constructor never returns and the activity freezes.
+ gobject.idle_add(self._run_pygame_cb, main_fn)
+
+ def _run_pygame_cb(self, main_fn):
+ assert pygame.display.get_surface() is None, "PygameCanvas.run_pygame can only be called once."
+
+ # Preinitialize Pygame with the X window ID.
+ assert pygame.display.get_init() == False, "Pygame must not be initialized before calling PygameCanvas.run_pygame."
+ os.environ['SDL_WINDOWID'] = str(self._socket.get_id())
+ pygame.init()
+
+ # Restore the default cursor.
+ self._socket.window.set_cursor(None)
+
+ # Initialize the Pygame window.
+ r = self.get_allocation()
+ pygame.display.set_mode((r.width, r.height), pygame.RESIZABLE)
+
+ # Hook certain Pygame functions with GTK equivalents.
+ self.translator.hook_pygame()
+
+ # Run the Pygame main loop.
+ main_fn()
+ return False
+
+ def get_pygame_widget(self):
+ return self._socket
diff --git a/src/sugargame/canvas.pyo b/src/sugargame/canvas.pyo
new file mode 100644
index 0000000..9dc8f47
--- /dev/null
+++ b/src/sugargame/canvas.pyo
Binary files differ
diff --git a/src/sugargame/event.py b/src/sugargame/event.py
new file mode 100644
index 0000000..4cc3be8
--- /dev/null
+++ b/src/sugargame/event.py
@@ -0,0 +1,243 @@
+import gtk
+import gobject
+import pygame
+import pygame.event
+import logging
+
+class _MockEvent(object):
+ def __init__(self, keyval):
+ self.keyval = keyval
+
+class Translator(object):
+ key_trans = {
+ 'Alt_L': pygame.K_LALT,
+ 'Alt_R': pygame.K_RALT,
+ 'Control_L': pygame.K_LCTRL,
+ 'Control_R': pygame.K_RCTRL,
+ 'Shift_L': pygame.K_LSHIFT,
+ 'Shift_R': pygame.K_RSHIFT,
+ 'Super_L': pygame.K_LSUPER,
+ 'Super_R': pygame.K_RSUPER,
+ 'KP_Page_Up' : pygame.K_KP9,
+ 'KP_Page_Down' : pygame.K_KP3,
+ 'KP_End' : pygame.K_KP1,
+ 'KP_Home' : pygame.K_KP7,
+ 'KP_Up' : pygame.K_KP8,
+ 'KP_Down' : pygame.K_KP2,
+ 'KP_Left' : pygame.K_KP4,
+ 'KP_Right' : pygame.K_KP6,
+
+ }
+
+ mod_map = {
+ pygame.K_LALT: pygame.KMOD_LALT,
+ pygame.K_RALT: pygame.KMOD_RALT,
+ pygame.K_LCTRL: pygame.KMOD_LCTRL,
+ pygame.K_RCTRL: pygame.KMOD_RCTRL,
+ pygame.K_LSHIFT: pygame.KMOD_LSHIFT,
+ pygame.K_RSHIFT: pygame.KMOD_RSHIFT,
+ }
+
+ def __init__(self, mainwindow, inner_evb):
+ """Initialise the Translator with the windows to which to listen"""
+ self._mainwindow = mainwindow
+ self._inner_evb = inner_evb
+
+ # Enable events
+ # (add instead of set here because the main window is already realized)
+ self._mainwindow.add_events(
+ gtk.gdk.KEY_PRESS_MASK | \
+ gtk.gdk.KEY_RELEASE_MASK \
+ )
+
+ self._inner_evb.set_events(
+ gtk.gdk.POINTER_MOTION_MASK | \
+ gtk.gdk.POINTER_MOTION_HINT_MASK | \
+ gtk.gdk.BUTTON_MOTION_MASK | \
+ gtk.gdk.BUTTON_PRESS_MASK | \
+ gtk.gdk.BUTTON_RELEASE_MASK
+ )
+
+ self._mainwindow.set_flags(gtk.CAN_FOCUS)
+ self._inner_evb.set_flags(gtk.CAN_FOCUS)
+
+ # Callback functions to link the event systems
+ self._mainwindow.connect('unrealize', self._quit_cb)
+ self._inner_evb.connect('key_press_event', self._keydown_cb)
+ self._inner_evb.connect('key_release_event', self._keyup_cb)
+ self._inner_evb.connect('button_press_event', self._mousedown_cb)
+ self._inner_evb.connect('button_release_event', self._mouseup_cb)
+ self._inner_evb.connect('motion-notify-event', self._mousemove_cb)
+ self._inner_evb.connect('expose-event', self._expose_cb)
+ self._inner_evb.connect('configure-event', self._resize_cb)
+
+ # Internal data
+ self.__stopped = False
+ self.__keystate = [0] * 323
+ self.__button_state = [0,0,0]
+ self.__mouse_pos = (0,0)
+ self.__repeat = (None, None)
+ self.__held = set()
+ self.__held_time_left = {}
+ self.__held_last_time = {}
+ self.__tick_id = None
+
+ def hook_pygame(self):
+ pygame.key.get_pressed = self._get_pressed
+ pygame.key.set_repeat = self._set_repeat
+ pygame.mouse.get_pressed = self._get_mouse_pressed
+ pygame.mouse.get_pos = self._get_mouse_pos
+
+ def _expose_cb(self, event, widget):
+ if pygame.display.get_init():
+ pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
+ return True
+
+ def _resize_cb(self, widget, event):
+ evt = pygame.event.Event(pygame.VIDEORESIZE,
+ size=(event.width,event.height), width=event.width, height=event.height)
+ pygame.event.post(evt)
+ return False # continue processing
+
+ def _quit_cb(self, data=None):
+ self.__stopped = True
+ pygame.event.post(pygame.event.Event(pygame.QUIT))
+
+ def _keydown_cb(self, widget, event):
+ key = event.keyval
+ if key in self.__held:
+ return True
+ else:
+ if self.__repeat[0] is not None:
+ self.__held_last_time[key] = pygame.time.get_ticks()
+ self.__held_time_left[key] = self.__repeat[0]
+ self.__held.add(key)
+
+ return self._keyevent(widget, event, pygame.KEYDOWN)
+
+ def _keyup_cb(self, widget, event):
+ key = event.keyval
+ if self.__repeat[0] is not None:
+ if key in self.__held:
+ # This is possibly false if set_repeat() is called with a key held
+ del self.__held_time_left[key]
+ del self.__held_last_time[key]
+ self.__held.discard(key)
+
+ return self._keyevent(widget, event, pygame.KEYUP)
+
+ def _keymods(self):
+ mod = 0
+ for key_val, mod_val in self.mod_map.iteritems():
+ mod |= self.__keystate[key_val] and mod_val
+ return mod
+
+ def _keyevent(self, widget, event, type):
+ key = gtk.gdk.keyval_name(event.keyval)
+ if key is None:
+ # No idea what this key is.
+ return False
+
+ keycode = None
+ if key in self.key_trans:
+ keycode = self.key_trans[key]
+ elif hasattr(pygame, 'K_'+key.upper()):
+ keycode = getattr(pygame, 'K_'+key.upper())
+ elif hasattr(pygame, 'K_'+key.lower()):
+ keycode = getattr(pygame, 'K_'+key.lower())
+ elif key == 'XF86Start':
+ # view source request, specially handled...
+ self._mainwindow.view_source()
+ else:
+ print 'Key %s unrecognized' % key
+
+ if keycode is not None:
+ if type == pygame.KEYDOWN:
+ mod = self._keymods()
+ self.__keystate[keycode] = type == pygame.KEYDOWN
+ if type == pygame.KEYUP:
+ mod = self._keymods()
+ ukey = unichr(gtk.gdk.keyval_to_unicode(event.keyval))
+ if ukey == '\000':
+ ukey = ''
+ evt = pygame.event.Event(type, key=keycode, unicode=ukey, mod=mod)
+ self._post(evt)
+
+ return True
+
+ def _get_pressed(self):
+ return self.__keystate
+
+ def _get_mouse_pressed(self):
+ return self.__button_state
+
+ def _mousedown_cb(self, widget, event):
+ self.__button_state[event.button-1] = 1
+ return self._mouseevent(widget, event, pygame.MOUSEBUTTONDOWN)
+
+ def _mouseup_cb(self, widget, event):
+ self.__button_state[event.button-1] = 0
+ return self._mouseevent(widget, event, pygame.MOUSEBUTTONUP)
+
+ def _mouseevent(self, widget, event, type):
+ evt = pygame.event.Event(type, button=event.button, pos=(event.x, event.y))
+ self._post(evt)
+ return True
+
+ def _mousemove_cb(self, widget, event):
+ # From http://www.learningpython.com/2006/07/25/writing-a-custom-widget-using-pygtk/
+ # if this is a hint, then let's get all the necessary
+ # information, if not it's all we need.
+ if event.is_hint:
+ x, y, state = event.window.get_pointer()
+ else:
+ x = event.x
+ y = event.y
+ state = event.state
+
+ rel = (x - self.__mouse_pos[0], y - self.__mouse_pos[1])
+ self.__mouse_pos = (x, y)
+
+ self.__button_state = [
+ state & gtk.gdk.BUTTON1_MASK and 1 or 0,
+ state & gtk.gdk.BUTTON2_MASK and 1 or 0,
+ state & gtk.gdk.BUTTON3_MASK and 1 or 0,
+ ]
+
+ evt = pygame.event.Event(pygame.MOUSEMOTION,
+ pos=self.__mouse_pos, rel=rel, buttons=self.__button_state)
+ self._post(evt)
+ return True
+
+ def _tick_cb(self):
+ cur_time = pygame.time.get_ticks()
+ for key in self.__held:
+ delta = cur_time - self.__held_last_time[key]
+ self.__held_last_time[key] = cur_time
+
+ self.__held_time_left[key] -= delta
+ if self.__held_time_left[key] <= 0:
+ self.__held_time_left[key] = self.__repeat[1]
+ self._keyevent(None, _MockEvent(key), pygame.KEYDOWN)
+
+ return True
+
+ def _set_repeat(self, delay=None, interval=None):
+ if delay is not None and self.__repeat[0] is None:
+ self.__tick_id = gobject.timeout_add(10, self._tick_cb)
+ elif delay is None and self.__repeat[0] is not None:
+ gobject.source_remove(self.__tick_id)
+ self.__repeat = (delay, interval)
+
+ def _get_mouse_pos(self):
+ return self.__mouse_pos
+
+ def _post(self, evt):
+ try:
+ pygame.event.post(evt)
+ except pygame.error, e:
+ if str(e) == 'Event queue full':
+ print "Event queue full!"
+ pass
+ else:
+ raise e
diff --git a/src/sugargame/event.pyo b/src/sugargame/event.pyo
new file mode 100644
index 0000000..e0ca3e6
--- /dev/null
+++ b/src/sugargame/event.pyo
Binary files differ
diff --git a/src/zbar.so b/src/zbar.so
new file mode 100644
index 0000000..93842c8
--- /dev/null
+++ b/src/zbar.so
Binary files differ