Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorolpc <olpc@xo-0D-2D-97.localdomain>2009-01-17 18:41:32 (GMT)
committer olpc <olpc@xo-0D-2D-97.localdomain>2009-01-17 18:41:32 (GMT)
commit9e64dbd7cd3093353f87e5a69006d8c449a58313 (patch)
tree8f9aa1da589d22956f59d05a2bbf4a34a7efa775
parentb30efd562477d84c2820e1f18987b2a1516c6d40 (diff)
adding trimmed pygame from SVN
-rwxr-xr-xpygame/__init__.py227
-rwxr-xr-xpygame/base.sobin0 -> 35738 bytes
-rwxr-xr-xpygame/bitmask.h138
-rwxr-xr-xpygame/bufferproxy.sobin0 -> 21392 bytes
-rwxr-xr-xpygame/camera.h118
-rwxr-xr-xpygame/camera.sobin0 -> 103889 bytes
-rwxr-xr-xpygame/canvas.h1846
-rwxr-xr-xpygame/color.sobin0 -> 53937 bytes
-rwxr-xr-xpygame/colordict.py679
-rwxr-xr-xpygame/constants.sobin0 -> 32321 bytes
-rwxr-xr-xpygame/drwfile.h77
-rwxr-xr-xpygame/gp2x/__init__.py24
-rwxr-xr-xpygame/gp2x/constants.py21
-rwxr-xr-xpygame/gp2x/locals.py3
-rwxr-xr-xpygame/gtk_types.h130
-rwxr-xr-xpygame/locals.py30
-rwxr-xr-xpygame/mask.h34
-rwxr-xr-xpygame/mask.sobin0 -> 88171 bytes
-rwxr-xr-xpygame/palette.h458
-rwxr-xr-xpygame/pgopengl.h16
-rwxr-xr-xpygame/pkgdata.py65
-rwxr-xr-xpygame/pygame.h651
-rwxr-xr-xpygame/pygamedocs.h925
-rwxr-xr-xpygame/rect.sobin0 -> 71204 bytes
-rwxr-xr-xpygame/rwobject.sobin0 -> 30413 bytes
-rwxr-xr-xpygame/scale.h61
-rwxr-xr-xpygame/surface.h274
-rwxr-xr-xpygame/surface.sobin0 -> 582519 bytes
-rwxr-xr-xpygame/surflock.sobin0 -> 21825 bytes
-rwxr-xr-xpygame/sysfont.py309
-rwxr-xr-xpygame/transform.sobin0 -> 126891 bytes
-rwxr-xr-xpygame/version.py31
32 files changed, 6117 insertions, 0 deletions
diff --git a/pygame/__init__.py b/pygame/__init__.py
new file mode 100755
index 0000000..6252695
--- /dev/null
+++ b/pygame/__init__.py
@@ -0,0 +1,227 @@
+## 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
+def _check_darwin():
+ try:
+ from objc import loadBundleFunctions
+ import AppKit
+ import Foundation
+ except ImportError:
+ raise ImportError("PyObjC 1.2 or later is required to use pygame on Mac OS X. http://pygame.org/wiki/PyObjC")
+
+if sys.platform == 'darwin':
+ _check_darwin()
+
+
+# check if is old windows... if so use directx video driver by default.
+# if someone sets this respect their setting...
+if not os.environ.get('SDL_VIDEODRIVER', ''):
+ # 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:
+ def __init__(self, name, info='', urgent=0):
+ self.name = name
+ self.info = str(info)
+ 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
+ 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)
+ 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
+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), msg:cdrom=MissingModule("cdrom", msg, 1)
+
+try: import pygame.cursors
+except (ImportError,IOError), msg:cursors=MissingModule("cursors", msg, 1)
+
+try: import pygame.display
+except (ImportError,IOError), msg:display=MissingModule("display", msg, 1)
+
+try: import pygame.draw
+except (ImportError,IOError), msg:draw=MissingModule("draw", msg, 1)
+
+try: import pygame.event
+except (ImportError,IOError), msg:event=MissingModule("event", msg, 1)
+
+try: import pygame.image
+except (ImportError,IOError), msg:image=MissingModule("image", msg, 1)
+
+try: import pygame.joystick
+except (ImportError,IOError), msg:joystick=MissingModule("joystick", msg, 1)
+
+try: import pygame.key
+except (ImportError,IOError), msg:key=MissingModule("key", msg, 1)
+
+try: import pygame.mouse
+except (ImportError,IOError), msg:mouse=MissingModule("mouse", msg, 1)
+
+try: import pygame.sprite
+except (ImportError,IOError), msg:sprite=MissingModule("sprite", msg, 1)
+
+
+try: import pygame.threads
+except (ImportError,IOError), msg:threads=MissingModule("threads", msg, 1)
+
+
+
+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), msg:time=MissingModule("time", msg, 1)
+
+try: import pygame.transform
+except (ImportError,IOError), msg:transform=MissingModule("transform", msg, 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), msg:font=MissingModule("font", msg, 0)
+
+try: import pygame.mixer
+except (ImportError,IOError), msg:mixer=MissingModule("mixer", msg, 0)
+
+try: import pygame.movie
+except (ImportError,IOError), msg:movie=MissingModule("movie", msg, 0)
+
+#try: import pygame.movieext
+#except (ImportError,IOError), msg:movieext=MissingModule("movieext", msg, 0)
+
+try: import pygame.scrap
+except (ImportError,IOError), msg:scrap=MissingModule("scrap", msg, 0)
+
+try: import pygame.numpyarray
+except (ImportError,IOError), msg:numpyarray=MissingModule("numpyarray", msg, 0)
+
+try: import pygame.surfarray
+except (ImportError,IOError), msg:surfarray=MissingModule("surfarray", msg, 0)
+
+try: import pygame.sndarray
+except (ImportError,IOError), msg:sndarray=MissingModule("sndarray", msg, 0)
+
+try: import pygame.fastevent
+except (ImportError,IOError), msg:fastevent=MissingModule("fastevent", msg, 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
+
+try:
+ import pygame.mixer_music
+ del pygame.mixer_music
+ print "NOTE2: failed importing pygame.mixer_music in lib/__init__.py"
+except (ImportError,IOError):
+ pass
+
+def packager_imports():
+ """
+ Some additional things that py2app/py2exe will want to see
+ """
+ import Numeric
+ import numpy
+ import OpenGL.GL
+ import pygame.macosx
+ import pygame.mac_scrap
+
+#make Rects pickleable
+import 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)
+
+#cleanup namespace
+del pygame, os, sys, rwobject, surflock, MissingModule, copy_reg
diff --git a/pygame/base.so b/pygame/base.so
new file mode 100755
index 0000000..90f46c3
--- /dev/null
+++ b/pygame/base.so
Binary files differ
diff --git a/pygame/bitmask.h b/pygame/bitmask.h
new file mode 100755
index 0000000..9e4dcbf
--- /dev/null
+++ b/pygame/bitmask.h
@@ -0,0 +1,138 @@
+/*
+ Bitmask 1.7 - A pixel-perfect collision detection library.
+
+ Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount
+ function which is copyright (C) Donald W. Gillies, 1992.
+
+ 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
+ */
+#ifndef BITMASK_H
+#define BITMASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+/* Define INLINE for different compilers. If your compiler does not
+ support inlining then there might be a performance hit in
+ bitmask_overlap_area().
+*/
+#ifndef INLINE
+# ifdef __GNUC__
+# define INLINE inline
+# else
+# ifdef _MSC_VER
+# define INLINE __inline
+# else
+# define INLINE
+# endif
+# endif
+#endif
+
+#define BITMASK_W unsigned long int
+#define BITMASK_W_LEN (sizeof(BITMASK_W)*CHAR_BIT)
+#define BITMASK_W_MASK (BITMASK_W_LEN - 1)
+#define BITMASK_N(n) ((BITMASK_W)1 << (n))
+
+typedef struct bitmask
+{
+ int w,h;
+ BITMASK_W bits[1];
+} bitmask_t;
+
+/* Creates a bitmask of width w and height h, where
+ w and h must both be greater than 0.
+ The mask is automatically cleared when created.
+ */
+bitmask_t *bitmask_create(int w, int h);
+
+/* Frees all the memory allocated by bitmask_create for m. */
+void bitmask_free(bitmask_t *m);
+
+/* Clears all bits in the mask */
+void bitmask_clear(bitmask_t *m);
+
+/* Sets all bits in the mask */
+void bitmask_fill(bitmask_t *m);
+
+/* Flips all bits in the mask */
+void bitmask_invert(bitmask_t *m);
+
+/* Counts the bits in the mask */
+unsigned int bitmask_count(bitmask_t *m);
+
+/* Returns nonzero if the bit at (x,y) is set. Coordinates start at
+ (0,0) */
+static INLINE int bitmask_getbit(const bitmask_t *m, int x, int y)
+{
+ return (m->bits[x/BITMASK_W_LEN*m->h + y] & BITMASK_N(x & BITMASK_W_MASK)) != 0;
+}
+
+/* Sets the bit at (x,y) */
+static INLINE void bitmask_setbit(bitmask_t *m, int x, int y)
+{
+ m->bits[x/BITMASK_W_LEN*m->h + y] |= BITMASK_N(x & BITMASK_W_MASK);
+}
+
+/* Clears the bit at (x,y) */
+static INLINE void bitmask_clearbit(bitmask_t *m, int x, int y)
+{
+ m->bits[x/BITMASK_W_LEN*m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK);
+}
+
+/* Returns nonzero if the masks overlap with the given offset.
+ The overlap tests uses the following offsets (which may be negative):
+
+ +----+----------..
+ |A | yoffset
+ | +-+----------..
+ +--|B
+ |xoffset
+ | |
+ : :
+*/
+int bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
+
+/* Like bitmask_overlap(), but will also give a point of intersection.
+ x and y are given in the coordinates of mask a, and are untouched
+ if there is no overlap. */
+int bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b,
+ int xoffset, int yoffset, int *x, int *y);
+
+/* Returns the number of overlapping 'pixels' */
+int bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
+
+/* Fills a mask with the overlap of two other masks. A bitwise AND. */
+void bitmask_overlap_mask (const bitmask_t *a, const bitmask_t *b, bitmask_t *c, int xoffset, int yoffset);
+
+/* Draws mask b onto mask a (bitwise OR). Can be used to compose large
+ (game background?) mask from several submasks, which may speed up
+ the testing. */
+
+void bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
+
+void bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
+
+/* Return a new scaled bitmask, with dimensions w*h. The quality of the
+ scaling may not be perfect for all circumstances, but it should
+ be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */
+bitmask_t *bitmask_scale(const bitmask_t *m, int w, int h);
+
+#ifdef __cplusplus
+} /* End of extern "C" { */
+#endif
+
+#endif
diff --git a/pygame/bufferproxy.so b/pygame/bufferproxy.so
new file mode 100755
index 0000000..8407672
--- /dev/null
+++ b/pygame/bufferproxy.so
Binary files differ
diff --git a/pygame/camera.h b/pygame/camera.h
new file mode 100755
index 0000000..921ad96
--- /dev/null
+++ b/pygame/camera.h
@@ -0,0 +1,118 @@
+/*
+ pygame - Python Game Library
+
+ 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
+
+*/
+
+#include "pygame.h"
+#include "pygamedocs.h"
+
+#if defined(__unix__)
+ #include <structmember.h>
+ #include <stringobject.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+
+ #include <fcntl.h> /* low-level i/o */
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/mman.h>
+ #include <sys/ioctl.h>
+
+ #include <asm/types.h> /* for videodev2.h */
+
+ #include <linux/videodev.h>
+ #include <linux/videodev2.h>
+#endif
+
+#define CLEAR(x) memset (&(x), 0, sizeof (x))
+#define SAT(c) if (c & (~255)) { if (c < 0) c = 0; else c = 255; }
+#define SAT2(c) ((c) & (~255) ? ((c) < 0 ? 0 : 255) : (c))
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define RGB_OUT 1
+#define YUV_OUT 2
+#define HSV_OUT 4
+#define CAM_V4L 1
+#define CAM_V4L2 2
+
+struct buffer
+{
+ void * start;
+ size_t length;
+};
+
+typedef struct
+{
+ PyObject_HEAD
+ char* device_name;
+ int camera_type;
+ unsigned long pixelformat;
+ unsigned int color_out;
+ struct buffer* buffers;
+ unsigned int n_buffers;
+ int width;
+ int height;
+ int size;
+ int hflip;
+ int vflip;
+ int brightness;
+ int fd;
+} PyCameraObject;
+
+/* internal functions for colorspace conversion */
+void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace);
+void rgb24_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
+void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
+void rgb_to_yuv (const void* src, void* dst, int length,
+ unsigned long source, SDL_PixelFormat* format);
+void rgb_to_hsv (const void* src, void* dst, int length,
+ unsigned long source, SDL_PixelFormat* format);
+void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
+void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format);
+void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format);
+void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format);
+void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format);
+
+#if defined(__unix__)
+/* internal functions specific to v4l2 */
+char** v4l2_list_cameras (int* num_devices);
+int v4l2_get_control (int fd, int id, int *value);
+int v4l2_set_control (int fd, int id, int value);
+PyObject* v4l2_read_raw (PyCameraObject* self);
+int v4l2_xioctl (int fd, int request, void *arg);
+int v4l2_process_image (PyCameraObject* self, const void *image,
+ unsigned int buffer_size, SDL_Surface* surf);
+int v4l2_query_buffer (PyCameraObject* self);
+int v4l2_read_frame (PyCameraObject* self, SDL_Surface* surf);
+int v4l2_stop_capturing (PyCameraObject* self);
+int v4l2_start_capturing (PyCameraObject* self);
+int v4l2_uninit_device (PyCameraObject* self);
+int v4l2_init_mmap (PyCameraObject* self);
+int v4l2_init_device (PyCameraObject* self);
+int v4l2_close_device (PyCameraObject* self);
+int v4l2_open_device (PyCameraObject* self);
+
+/* internal functions specific to v4l */
+int v4l_open_device (PyCameraObject* self);
+int v4l_init_device(PyCameraObject* self);
+int v4l_start_capturing(PyCameraObject* self);
+#endif
diff --git a/pygame/camera.so b/pygame/camera.so
new file mode 100755
index 0000000..84ebd4d
--- /dev/null
+++ b/pygame/camera.so
Binary files differ
diff --git a/pygame/canvas.h b/pygame/canvas.h
new file mode 100755
index 0000000..bbed722
--- /dev/null
+++ b/pygame/canvas.h
@@ -0,0 +1,1846 @@
+/*
+ Copyright 2008 by Jens Andersson and Wade Brainerd.
+ This file is part of Colors! XO.
+
+ Colors is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Colors 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Colors. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef _CANVAS_H_
+#define _CANVAS_H_
+
+#include "colorsc.h"
+#include "drwfile.h"
+
+// Uncomment this to print all executed drawing commands to stdout.
+//#define CANVAS_DEBUG_COMMANDS
+
+// Structure for passing pixel data to and from Python.
+struct SurfaceA8R8G8B8
+{
+ int width, height;
+ int stride;
+ unsigned int* pixels;
+};
+
+// Structure for passing buffers of draw commands to and from Python.
+struct DrawCommandBuffer
+{
+ DrawCommandBuffer()
+ {
+ cmds = NULL;
+ ncommands = 0;
+ }
+
+ DrawCommandBuffer(const char* _cmds, int _ncommands)
+ {
+ cmds = (char*)malloc(_ncommands*sizeof(unsigned int));
+ memcpy(cmds, _cmds, _ncommands*sizeof(unsigned int));
+ ncommands = _ncommands;
+ }
+
+ DrawCommandBuffer(const DrawCommandBuffer& b)
+ {
+ cmds = (char*)malloc(b.ncommands*sizeof(unsigned int));
+ memcpy(cmds, b.cmds, b.ncommands*sizeof(unsigned int));
+ ncommands = b.ncommands;
+ }
+
+ ~DrawCommandBuffer()
+ {
+ if (cmds)
+ {
+ free((void*)cmds);
+ cmds = NULL;
+ }
+ }
+
+ const DrawCommandBuffer& operator=(const DrawCommandBuffer& b)
+ {
+ if (cmds)
+ free((void*)cmds);
+ cmds = (char*)malloc(b.ncommands*sizeof(unsigned int));
+ memcpy(cmds, b.cmds, b.ncommands*sizeof(unsigned int));
+ ncommands = b.ncommands;
+ return *this;
+ }
+
+ void append(const DrawCommandBuffer& b)
+ {
+ char* newcmds = (char*)malloc((ncommands+b.ncommands)*sizeof(unsigned int));
+ if (cmds)
+ {
+ memcpy(newcmds, cmds, ncommands*sizeof(unsigned int));
+ free(cmds);
+ }
+ memcpy(newcmds + ncommands*sizeof(unsigned int), b.cmds, b.ncommands*sizeof(unsigned int));
+ cmds = newcmds;
+ ncommands = ncommands + b.ncommands;
+ }
+
+ void clear()
+ {
+ if (cmds)
+ {
+ free(cmds);
+ cmds = NULL;
+ }
+ ncommands = 0;
+ }
+
+ ByteBuffer get_bytes()
+ {
+ ByteBuffer buf;
+ buf.size = ncommands*sizeof(unsigned int);
+ buf.data = cmds;
+ return buf;
+ }
+
+ char* cmds;
+ int ncommands;
+
+ static DrawCommandBuffer create_from_string(const char* cmds, int ncommands)
+ {
+ return DrawCommandBuffer(cmds, ncommands);
+ }
+};
+
+struct DrawCommand
+{
+ enum
+ {
+ TYPE_DRAW = 0,
+ TYPE_DRAWEND = 1,
+ TYPE_COLORCHANGE = 2,
+ TYPE_SIZECHANGE = 3,
+ };
+
+ int type;
+ Pos pos;
+ Color color;
+ int pressure;
+ bool flipx;
+ bool flipy;
+ bool is_text;
+ uint32_t text;
+ int brush_control;
+ int brush_type;
+ float size;
+ float opacity;
+
+ DrawCommand()
+ {
+ type = TYPE_DRAW;
+ pressure = 0;
+ flipx = false;
+ flipy = false;
+ is_text = false;
+ text = 0;
+ brush_control = 0;
+ brush_type = 0;
+ size = 0;
+ opacity = 0;
+ }
+
+ static DrawCommand create_color_change(const Color& c)
+ {
+ DrawCommand cmd;
+ cmd.type = TYPE_COLORCHANGE;
+ cmd.color = c;
+ return cmd;
+ }
+
+ static DrawCommand create_draw(const Pos& pos, int pressure)
+ {
+ DrawCommand cmd;
+ cmd.type = TYPE_DRAW;
+ cmd.pos = pos;
+ cmd.pressure = pressure;
+ return cmd;
+ }
+
+ static DrawCommand create_end_draw(int pressure)
+ {
+ DrawCommand cmd;
+ cmd.type = TYPE_DRAWEND;
+ cmd.pressure = pressure;
+ return cmd;
+ }
+
+ static DrawCommand create_size_change(int brush_control, int brush_type, float size, float opacity)
+ {
+ DrawCommand cmd;
+ cmd.type = TYPE_SIZECHANGE;
+ cmd.brush_control = brush_control;
+ cmd.brush_type = brush_type;
+ cmd.size = size;
+ cmd.opacity = opacity;
+ return cmd;
+ }
+
+ static DrawCommand create_flip(bool flipx)
+ {
+ DrawCommand cmd;
+ cmd.type = TYPE_COLORCHANGE;
+ cmd.flipx = flipx;
+ cmd.flipy = !flipx;
+ return cmd;
+ }
+};
+
+struct BrushType
+{
+ enum
+ {
+ BRUSHTYPE_HARD = 0,
+ BRUSHTYPE_SOFT = 1,
+ BRUSHTYPE_CURSOR = 2,
+ NUM_BRUSHES = 3,
+ };
+
+ static const int DIST_TABLE_WIDTH = 256; // Width of distance lookup-table
+ static const int DIST_TABLE_CENTER = DIST_TABLE_WIDTH / 2; // Center of distance lookup-table
+
+ static const int BRUSH_TABLE_WIDTH = 256; // Width of brush lookup-table
+ static const int BRUSH_TABLE_HEIGHT = 65; // Height of 65 allows a brushsize down to 1.0f
+
+ static const float EXTRA_BRUSH_SCALE = 1.023f; // Scales down the brush-size so we don't index-out-of-range.
+
+ static unsigned char distance_tbl[DIST_TABLE_WIDTH][DIST_TABLE_WIDTH];
+
+ unsigned char intensity_tbl[BRUSH_TABLE_WIDTH][BRUSH_TABLE_HEIGHT];
+
+ // Creates a simple sqrt-lookup table.
+ static void create_distance_table()
+ {
+ for (int x = 0; x < DIST_TABLE_WIDTH; x++)
+ for (int y = 0; y < DIST_TABLE_WIDTH; y++)
+ {
+ int dx = x - DIST_TABLE_CENTER;
+ int dy = y - DIST_TABLE_CENTER;
+ float dist = sqrtf(float(dx * dx + dy * dy));
+ distance_tbl[x][y] = (unsigned char)min(255.0f, dist*255/DIST_TABLE_CENTER);
+ }
+ }
+
+ // Calculates a gradient between 0 and 1 where the derivate of both 0 and 1 is 0.
+ // This function is used to calculate the falloff of the brushes.
+ float smooth_step(float a)
+ {
+ return sinf((a*a - 0.5f) * 3.14159f) * 0.5f + 0.5f;
+ }
+
+ void create_brush(float brush_border, float amp)
+ {
+ // Find at what range from brush-center the brush intensity goes below 2
+ float max_r = 0;
+ for (int i = BRUSH_TABLE_WIDTH-1; i >= 0; i--)
+ {
+ float f = float(i) / BRUSH_TABLE_WIDTH;
+ float f2 = 1.0f - (f - brush_border) / (1.0f - brush_border);
+ if (round(smooth_step(f2) * amp) >= 2)
+ {
+ max_r = i;
+ break;
+ }
+ }
+
+ // Calculate a scale-factor so the brush optimally uses the area
+ float r = float(max_r + 2) / BRUSH_TABLE_WIDTH / BRUSH_TABLE_WIDTH;
+
+ for (int y = 0; y < BRUSH_TABLE_HEIGHT; y++)
+ {
+ // Each line in the brush-table is calculated for a specific brush-size
+ // This has two functions:
+ // 1. Be able to simulate the effect of resampling of the "perfect" big brush to a smaller one to improve precision
+ // 2. Compensate for the need to scale small brushes to avoid index out of range during rastering
+
+ // Calculate scale for this width
+ float brushscale = EXTRA_BRUSH_SCALE + y * 2.0f / 64.0f;
+
+ // Calculate brush
+ unsigned int intensity_row[BRUSH_TABLE_WIDTH];
+ for (int i = 0; i < BRUSH_TABLE_WIDTH; i++)
+ {
+ float f = min(i * r * brushscale, 1.0f); // Apply the two different scales
+ if (f < brush_border)
+ intensity_row[i] = int(amp);
+ else
+ {
+ float f2 = 1.0f - (f - brush_border) / (1.0f - brush_border);
+ f2 = smooth_step(f2) * amp; // Make sure the border-falloff is smooth
+ intensity_row[i] = int(round(f2));
+ }
+ }
+
+ // Simulate the effect of resampling
+ int blurradius = int(round(y * BRUSH_TABLE_WIDTH / (brushscale * 64.0f)));
+ float maxintensity = 0;
+ for (int x = 0; x < BRUSH_TABLE_WIDTH; x++)
+ {
+ float l = 0;
+ for (int x2 = x - blurradius; x2 < x + blurradius + 1; x2++)
+ {
+ int i = min(max(x2, 0), BRUSH_TABLE_WIDTH-1);
+ if (i < BRUSH_TABLE_WIDTH)
+ l += intensity_row[i];
+ }
+ float intensity = l / (blurradius * 2 + 1);
+ if (intensity > maxintensity)
+ maxintensity = intensity;
+ intensity_tbl[x][y] = int(intensity);
+ }
+ }
+ }
+
+ void create_hard_brush()
+ {
+ create_brush(0.8f, 255);
+ }
+
+ void create_soft_brush()
+ {
+ create_brush(0.0f, 128);
+ }
+
+ void create_cursor()
+ {
+ }
+};
+
+class Brush
+{
+public:
+ enum
+ {
+ BRUSHCONTROL_VARIABLEOPACITY = 1,
+ BRUSHCONTROL_VARIABLESIZE = 2,
+ };
+
+ static BrushType brush_type[BrushType::NUM_BRUSHES];
+
+ Color color;
+ int type;
+ int size;
+ int control;
+ float opacity;
+
+ Brush()
+ {
+ type = BrushType::BRUSHTYPE_HARD;
+ color = Color(255, 255, 255, 255);
+ size = 32;
+ control = 0;
+ opacity = 1.0f;
+ }
+
+ Brush(const Brush& a)
+ {
+ type = a.type;
+ color = a.color;
+ size = a.size;
+ control = a.control;
+ opacity = a.opacity;
+ }
+};
+
+// The canvas represents the current state of the user's painting. It maintains both the pixels representing the
+// image, and also the complete list of drawing commands that contributed to the image.
+class Canvas
+{
+public:
+ // Dimensions of the reference picture (webcam snapshot).
+ static const int REFERENCE_WIDTH = 640;
+ static const int REFERENCE_HEIGHT = 480;
+
+ // Dimensions of the videopaint buffer.
+ static const int VIDEO_WIDTH = 80;
+ static const int VIDEO_HEIGHT = 60;
+
+ enum
+ {
+ DRAWBRUSH_TYPE_NORMAL = 0,
+ DRAWBRUSH_TYPE_OLDCURSOR = 1,
+ DRAWBRUSH_TYPE_DIRECT = 2,
+ DRAWBRUSH_TYPE_GETCOLOR = 3,
+ DRAWBRUSH_TYPE_CURSOR = 4,
+ };
+
+ // List of drawing commands that make up the painting.
+ vector<DrawCommand> commands;
+
+ // Canvas dimensions.
+ int width;
+ int height;
+
+ // Current state of the canvas pixels.
+ unsigned int* image;
+
+ // Backup and alpha channel are used for multiple purposes. See description in Drawing section.
+ unsigned int* image_backup;
+ unsigned char* alpha;
+
+ // Shared (master) picture for collaborative painting.
+ unsigned int* image_shared;
+
+ // Reference (webcam snapshot) picture.
+ unsigned short* image_reference;
+
+ // Videopaint variables.
+ unsigned int* image_video[2];
+ int video_idx;
+ Pos videopaint_pos;
+ float videopaint_pressure;
+
+ // Current brush state.
+ Brush brush;
+
+ // Variables for interpolating the brush across strokes.
+ Pos lastpos;
+ Pos lastorgpos;
+ float lastpressure;
+
+ // Dimensions of the canvas that have been modified since the last call to reset_dirty_rect.
+ Pos dirtymin;
+ Pos dirtymax;
+
+ // Dimensions and state of the current stroke.
+ Pos strokemin;
+ Pos strokemax;
+ bool stroke;
+ int idle_while_drawing;
+ int drawtype;
+
+ // VCR playback variables.
+ bool playing;
+ int playback;
+ int playback_speed;
+
+ // True if the canvas has been modified since the last save.
+ bool modified;
+
+ Canvas(int width, int height) : width(width), height(height)
+ {
+ image = new unsigned int[width*height];
+ image_backup = new unsigned int[width*height];
+ alpha = new unsigned char[width*height];
+
+ image_shared = new unsigned int[width*height];
+
+ image_reference = new unsigned short[REFERENCE_WIDTH*REFERENCE_HEIGHT];
+ memset(image_reference, 0, REFERENCE_WIDTH*REFERENCE_HEIGHT*sizeof(unsigned short));
+
+ image_video[0] = new unsigned int[VIDEO_WIDTH*VIDEO_HEIGHT];
+ image_video[1] = new unsigned int[VIDEO_WIDTH*VIDEO_HEIGHT];
+ memset(image_video[0], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned int));
+ memset(image_video[1], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned int));
+ video_idx = 0;
+
+ clear();
+
+ // Initialize lookup table.
+ BrushType::create_distance_table();
+
+ // Initialize brushes.
+ Brush::brush_type[BrushType::BRUSHTYPE_HARD].create_hard_brush();
+ Brush::brush_type[BrushType::BRUSHTYPE_SOFT].create_soft_brush();
+ Brush::brush_type[BrushType::BRUSHTYPE_CURSOR].create_cursor();
+
+ reset_brush();
+
+ lastpos = Pos(0,0);
+ lastorgpos = Pos(0,0);
+ lastpressure = 0;
+
+ dirtymin = Pos(FLT_MAX,FLT_MAX);
+ dirtymax = Pos(-FLT_MAX,-FLT_MAX);
+
+ strokemin = Pos(0,0);
+ strokemax = Pos(0,0);
+ stroke = false;
+
+ playing = false;
+ playback = 0;
+ playback_speed = 1;
+ modified = false;
+
+ idle_while_drawing = 0;
+
+ drawtype = DRAWBRUSH_TYPE_NORMAL;
+ }
+
+ ~Canvas()
+ {
+ delete[] image;
+ delete[] image_backup;
+ delete[] image_shared;
+ delete[] alpha;
+ }
+
+ // Clears the entire canvas (command history and image).
+ void clear()
+ {
+ commands.clear();
+ clear_image();
+ }
+
+ // Changes the size of the canvas.
+ // Rather than trying to repaint everything from scratch, we simply quickly rescale it.
+ void resize(int new_width, int new_height)
+ {
+ unsigned int* new_image = new unsigned int[new_width*new_height];
+ unsigned int* new_image_backup = new unsigned int[new_width*new_height];
+ unsigned char* new_alpha = new unsigned char[new_width*new_height];
+ unsigned int* new_image_shared = new unsigned int[new_width*new_height];
+
+ int dx = (1<<16) * width / new_width;
+ int dy = (1<<16) * height / new_height;
+ int ry = 0;
+ for (int y = 0; y < new_height; y++)
+ {
+ int rx = 0;
+ for (int x = 0; x < new_width; x++)
+ {
+ int sofs = (ry>>16)*width + (rx>>16);
+ int dofs = y*new_width+x;
+ new_image[dofs] = image[sofs];
+ new_image_backup[dofs] = image_backup[sofs];
+ new_alpha[dofs] = alpha[sofs];
+ new_image_shared[dofs] = image_shared[sofs];
+ rx += dx;
+ }
+ ry += dy;
+ }
+
+ delete[] image;
+ delete[] image_backup;
+ delete[] alpha;
+ delete[] image_shared;
+
+ width = new_width;
+ height = new_height;
+
+ image = new_image;
+ image_backup = new_image_backup;
+ alpha = new_alpha;
+ image_shared = new_image_shared;
+ }
+
+ // Resets the brush to a random color and a default size and type.
+ void reset_brush()
+ {
+ // Choose a suitable random brush color.
+ srand(clock());
+ int c0 = rand()%3;
+ int c1 = c0 + 1 + rand()%2;
+ if (c1 > 2)
+ c1 -= 3;
+ brush.type = BrushType::BRUSHTYPE_HARD;
+ brush.color = Color::create_from_a8r8g8b8(0xff000000 | (255 << (c0 * 8) | ((rand()%255) << (c1 * 8))));
+ brush.size = width/16;
+ brush.control = Brush::BRUSHCONTROL_VARIABLESIZE;
+ brush.opacity = 1.0f;
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Shared image.
+ //
+ // The shared image is used in collaborative painting, and contains the current 'master' state of the canvas
+ //
+ // The user can paint ahead of the master state, but when a new master state is received the canvas
+ // state will be reset to the shared image. Before this happens though, the user commands are transmitted
+ // to the activity host, so they will be received again as a new master image later and not be lost.
+ void save_shared_image()
+ {
+ memcpy(image_shared, image, width*height*sizeof(unsigned int));
+ }
+
+ void restore_shared_image()
+ {
+ memcpy(image, image_shared, width*height*sizeof(unsigned int));
+ memcpy(image_backup, image_shared, width*height*sizeof(unsigned int));
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Drawing
+ //
+ // These methods are for drawing to and clearing the canvas.
+ //
+ // Drawing is not done directly to the canvas. The way the brush system works, the brush shapes are
+ // actually drawn into the alpha channel of the canvas, and the alpha channel is used to blend the
+ // brush color over the backup image to create the real image.
+ //
+ // The net effect this is that during a stroke, which may overlap itself many times over, the brush color
+ // will only be applied to any particular canvas pixel up to the defined brush transparency level.
+ // This is the core of our "natural media" engine.
+
+ void clear_image()
+ {
+ memset(image, 0xff, width*height*sizeof(unsigned int));
+ memset(image_backup, 0xff, width*height*sizeof(unsigned int));
+ memset(alpha, 0, width*height*sizeof(unsigned char));
+
+ memset(image_shared, 0xff, width*height*sizeof(unsigned int));
+
+ dirtymin = Pos(0, 0);
+ dirtymax = Pos(width, height);
+ }
+
+ // Called from command_draw and calculates a temporary brush size depending on pressure/alpha (0-255).
+ float get_variable_brush_size(float pressure)
+ {
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLESIZE)
+ {
+ float size = pressure * brush.size / 255.0f;
+ if (size < 2.0f)
+ size = 2.0f;
+ return size;
+ }
+ else
+ return brush.size;
+ }
+
+ // Called each tick while stylus is touching the screen and draws the selected brush into the Alpha of the Canvas.
+ void command_draw(const Pos& pos, int pressure, bool forced)
+ {
+ lastorgpos = pos;
+
+ if (brush.control == 0)
+ pressure = 255;
+
+ int size, opacity;
+ if (!stroke)
+ {
+ // This is a new stroke. Just draw the brush on incoming position, store the information needed for interpolation and wait for next call
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLESIZE)
+ size = int(get_variable_brush_size(pressure));
+ else
+ size = brush.size;
+
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLEOPACITY)
+ opacity = int(round(pressure * brush.opacity));
+ else
+ opacity = int(round(255.0f * brush.opacity));
+ draw_brush(pos, size, opacity);
+
+ // Reset stroke dirty regions
+ strokemin = pos;
+ strokemax = pos;
+
+ lastpos = pos;
+ lastpressure = pressure;
+ idle_while_drawing = 0;
+ stroke = true;
+ }
+ else
+ {
+ // This is continous stroke. Interpolate from last postion/pressure
+
+ // Calculate the stroke-distance
+ float distx = pos.x - lastpos.x;
+ float disty = pos.y - lastpos.y;
+ float dista = pressure - lastpressure;
+ float distance = sqrtf(distx * distx + disty * disty);
+ if (distance == 0.0f) // To avoid division by zero. None or very small movements are handled later
+ distance = 0.0001f;
+
+ // Calculate interpolation constants
+ float dx = distx / distance;
+ float dy = disty / distance;
+ float da = dista / distance;
+
+ // Calculate the spacing between two brush-stamp. Normal spacing is 25% of brushsize.
+ float spacing = 0.225f;
+
+ // Do this special spacing only for just VariableOpacity with Hard brush to avoid banding
+ // Decrease spacing if pressure is changing rapidly
+ if (da != 0 && brush.control == Brush::BRUSHCONTROL_VARIABLEOPACITY && brush.type == BrushType::BRUSHTYPE_HARD)
+ spacing = min(0.225f, max(fabsf(15.0f / brush.size / (da * brush.opacity)), 0.05f));
+
+ // Calculate the distance between two brushes from spacing
+ float spacingdistance = get_variable_brush_size(lastpressure) * spacing;
+ if (distance < spacingdistance)
+ {
+ // Too small movement to interpolate
+ idle_while_drawing++;
+ if (idle_while_drawing > 15 || forced)
+ {
+ // We've been idling too long. Draw the brush and reduce idle-counter
+ // Idle-counter is invalid during playback, since playback only records input that actually drew something
+ idle_while_drawing = 10;
+
+ lastpos = pos;
+ lastpressure = pressure;
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLEOPACITY)
+ draw_brush(pos, int(get_variable_brush_size(lastpressure)), int(round(pressure * brush.opacity)));
+ else
+ draw_brush(pos, int(get_variable_brush_size(lastpressure)), int(round(255.0f * brush.opacity)));
+ }
+ return;
+ }
+
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLESIZE)
+ {
+ // Brush size is controlled by pressure
+ while (distance >= spacingdistance)
+ {
+ // Interpolate stroke
+ lastpressure += da * spacingdistance;
+ lastpos.x += dx * spacingdistance;
+ lastpos.y += dy * spacingdistance;
+ distance -= spacingdistance;
+
+ float brushsize = get_variable_brush_size(int(lastpressure));
+ if (brush.control & Brush::BRUSHCONTROL_VARIABLEOPACITY)
+ draw_brush(lastpos, int(get_variable_brush_size(int(lastpressure))), int(round(pressure * brush.opacity)));
+ else
+ draw_brush(lastpos, int(get_variable_brush_size(int(lastpressure))), int(round(255.0f * brush.opacity)));
+
+ // Since brush-size may have changed, we need to calculate new spacing
+ spacingdistance = brushsize * spacing;
+ }
+ }
+ else
+ {
+ // Brush size is static, so we can pre-multiply the interpolation constants
+ dx *= spacingdistance;
+ dy *= spacingdistance;
+ da *= spacingdistance;
+ while (distance >= spacingdistance)
+ {
+ lastpressure += da;
+ lastpos.x += dx;
+ lastpos.y += dy;
+ distance -= spacingdistance;
+
+ draw_brush(lastpos, brush.size, int(round(lastpressure * brush.opacity)));
+ }
+ }
+ }
+ }
+
+ // Called when stylus stops touching the screen.
+ void command_enddraw()
+ {
+ if (!stroke)
+ return;
+
+ // Copy current image to backup image and clear alpha in the region of the stroke.
+ int x0 = max(min(int(strokemin.x), width), 0);
+ int x1 = max(min(int(strokemax.x), width), 0);
+ int y0 = max(min(int(strokemin.y), height), 0);
+ int y1 = max(min(int(strokemax.y), height), 0);
+ for (int y = y0; y < y1; y++)
+ {
+ memcpy(&image_backup[y*width+x0], &image[y*width+x0], (x1-x0)*sizeof(unsigned int));
+ memset(&alpha[y*width+x0], 0, (x1-x0)*sizeof(unsigned char));
+ }
+
+ stroke = false;
+ }
+
+ // The canvas keeps track of the area that has been modified by draw commands, this is called the 'dirty' rectangle.
+ // The dirty rectangle keeps accumulating until reset_dirty_rect is called, at which point it is cleared to empty.
+ void reset_dirty_rect()
+ {
+ dirtymin = Pos(FLT_MAX,FLT_MAX);
+ dirtymax = Pos(-FLT_MAX,-FLT_MAX);
+ }
+
+ // Rasters a brush with specified width and opacity into alpha at a specified position using lookup-tables.
+ void draw_brush(const Pos& pos, int brushwidth, int opacity)
+ {
+ //printf("draw_brush %f,%f width=%d opacity=%d\n", pos.x, pos.y, brushwidth, opacity);
+
+ // Enforce minimum brush size.
+ if (brushwidth<2) brushwidth = 2;
+
+ // Calculate drawing rectangle.
+ float halfwidth = brushwidth/2;
+ float p0x = pos.x - halfwidth;
+ float p0y = pos.y - halfwidth;
+ float p1x = pos.x + halfwidth + 1;
+ float p1y = pos.y + halfwidth + 1;
+
+ int x0 = int(max(min(p0x, p1x), 0.0f));
+ int x1 = int(min(max(p0x, p1x), float(width)));
+ int y0 = int(max(min(p0y, p1y), 0.0f));
+ int y1 = int(min(max(p0y, p1y), float(height)));
+
+ // Accumulate dirty regions.
+ strokemin = Pos::create_from_min(strokemin, Pos(x0, y0));
+ strokemax = Pos::create_from_max(strokemax, Pos(x1, y1));
+ dirtymin = Pos::create_from_min(dirtymin, Pos(x0, y0));
+ dirtymax = Pos::create_from_max(dirtymax, Pos(x1, y1));
+
+ // Calculate interpolation constants
+ float db = (BrushType::DIST_TABLE_WIDTH-1) / float(brushwidth);
+
+ float xb = max(0.0f, BrushType::DIST_TABLE_CENTER - (pos.x - x0) * db);
+ float yb = max(0.0f, BrushType::DIST_TABLE_CENTER - (pos.y - y0) * db);
+
+ // Select which line of the brush-lookup-table to use that most closely matches the current brush width
+ int brushidx = int(float(BrushType::BRUSH_TABLE_HEIGHT) / brushwidth);
+
+ // Interpolate the distance table over the area. For each pixel find the distance, and look the
+ // brush-intensity up in the brush-table
+ if (drawtype == DRAWBRUSH_TYPE_NORMAL)
+ {
+ for (int y = y0; y < y1; y++)
+ {
+ float x2b = xb;
+ for (int x = x0; x < x1; x++)
+ {
+ // Find brush-intensity and mulitply that with incoming opacity
+ int lookup = BrushType::distance_tbl[int(x2b)][int(yb)];
+ int intensity = fixed_scale(Brush::brush_type[brush.type].intensity_tbl[lookup][brushidx], opacity);
+
+ // New Alpha = Brush Intensity + Old Alpha - (Brush Intensity * Old Alpha)
+ // Also make sure the result is clamped to the incoming opacity and isn't lower than the alpha
+ // already stored
+ int base = alpha[y*width+x];
+ int a = max(min(intensity + base - ((intensity * base) >> 8), opacity), base);
+ alpha[y*width+x] = a;
+
+ Color i = Color::create_from_a8r8g8b8(image_backup[y*width+x]);
+ i = Color::create_from_lerp(brush.color, i, a);
+ image[y*width+x] = i.get_a8r8g8b8();
+
+ x2b += db;
+ }
+ yb += db;
+ }
+ }
+ else if (drawtype == DRAWBRUSH_TYPE_GETCOLOR)
+ {
+ // Calculate color from a weighted average of the area that the brush touches.
+ Color c(0, 0, 0, 0);
+ for (int y = y0; y < y1; y++)
+ {
+ float x2b = xb;
+ for (int x = x0; x < x1; x++)
+ {
+ int lookup = BrushType::distance_tbl[int(x2b)][int(yb)];
+ int intensity = fixed_scale(Brush::brush_type[brush.type].intensity_tbl[lookup][brushidx], opacity);
+ Color i = Color::create_from_a8r8g8b8(image[y*width+x]);
+ c.r += i.r * intensity;
+ c.g += i.g * intensity;
+ c.b += i.b * intensity;
+ c.a += intensity;
+ x2b += db;
+ }
+ yb += db;
+ }
+ brush.color.r = c.r / c.a;
+ brush.color.g = c.g / c.a;
+ brush.color.b = c.b / c.a;
+ }
+ }
+
+ // Return the color underneath the pos.
+ Color pickup_color(const Pos& pos)
+ {
+ int x = int(max(min(pos.x, float(width)), 0.0f));
+ int y = int(max(min(pos.y, float(height)), 0.0f));
+ return Color::create_from_a8r8g8b8(image[y*width+x]);
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Playback
+ //
+ // These allow the canvas to be treated like a VCR, playing back and rewinding drawing commands
+ // to recreate the state of the canvas at different times.
+
+ void add_command(const DrawCommand& cmd)
+ {
+ commands.push_back(cmd);
+ modified = true;
+ }
+
+ void play_command(const DrawCommand& cmd, bool add)
+ {
+ if (cmd.type == DrawCommand::TYPE_DRAW)
+ {
+#ifdef CANVAS_DEBUG_COMMANDS
+ printf("TYPE_DRAW x=%f y=%f pressure=%d\n", cmd.pos.x, cmd.pos.y, cmd.pressure);
+#endif
+ Pos relpos = cmd.pos * Pos(width, height);
+ bool forcedraw = !add; // If we are not adding, we are playing back
+ command_draw(relpos, cmd.pressure, forcedraw);
+ }
+ else if (cmd.type == DrawCommand::TYPE_DRAWEND)
+ {
+#ifdef CANVAS_DEBUG_COMMANDS
+ printf("TYPE_DRAWEND pressure=%d\n", cmd.pressure);
+#endif
+ //if self.stroke and (self.lastpos.x != self.lastorgpos.x or self.lastpos.y != self.lastorgpos.y):
+ // self.command_draw(self.lastorgpos, cmd.pressure, add)
+ command_enddraw();
+ }
+ else if (cmd.type == DrawCommand::TYPE_COLORCHANGE)
+ {
+#ifdef CANVAS_DEBUG_COMMANDS
+ printf("TYPE_COLORCHANGE flipx=%d flipy=%d r=%d g=%d b=%d a=%d\n", cmd.flipx, cmd.flipy, cmd.color.r, cmd.color.g, cmd.color.b, cmd.color.a);
+#endif
+ if (cmd.flipx || cmd.flipy)
+ {
+ // fixme
+ //pygame.transform.flip(self.image, cmd.flipx, cmd.flipy)
+ }
+ else
+ brush.color = cmd.color;
+ }
+ else if (cmd.type == DrawCommand::TYPE_SIZECHANGE)
+ {
+#ifdef CANVAS_DEBUG_COMMANDS
+ printf("TYPE_SIZECHANGE size=%f control=%d type=%d opacity=%f\n", cmd.size, cmd.brush_control, cmd.brush_type, cmd.opacity);
+#endif
+ brush.size = int(cmd.size * width);
+ if (brush.size < 2)
+ brush.size = 2;
+ brush.control = cmd.brush_control;
+ brush.type = cmd.brush_type;
+ if (cmd.opacity > 0)
+ brush.opacity = cmd.opacity;
+ }
+
+#ifdef CANVAS_DEBUG_COMMANDS
+ fflush(stdout);
+#endif
+
+ if (add)
+ add_command(cmd);
+ }
+
+ bool playback_done()
+ {
+ return playback < 0 || playback >= (int)commands.size();
+ }
+
+ int playback_length()
+ {
+ return (int)commands.size();
+ }
+
+ int playback_pos()
+ {
+ return playback;
+ }
+
+ void start_playback()
+ {
+ command_enddraw();
+ clear_image();
+ playback = 0;
+ playing = true;
+ }
+
+ void pause_playback()
+ {
+ playing = false;
+ }
+
+ void resume_playback()
+ {
+ playing = true;
+ }
+
+ void stop_playback()
+ {
+ command_enddraw();
+ playback = -1;
+ playing = false;
+ }
+
+ void finish_playback()
+ {
+ while (!playback_done())
+ play_command(commands[playback++], false);
+ }
+
+ // This is used to avoid leaving the playback state in the middle of a stroke.
+ void playback_finish_stroke()
+ {
+ while (stroke && !playback_done())
+ play_command(commands[playback++], false);
+ }
+
+ void playback_to(int pos)
+ {
+ while (playback < pos && !playback_done())
+ play_command(commands[playback++], false);
+ }
+
+ void playback_step_to(int pos)
+ {
+ if (playback < pos && !playback_done())
+ play_command(commands[playback++], false);
+ }
+
+ // Same as playback_to, except it breaks if more than timeout seconds are taken.
+ void playback_to_timed(int pos, float timeout)
+ {
+ clock_t start = clock();
+ clock_t end = (clock_t)(start + timeout * CLOCKS_PER_SEC);
+ printf("start: %d end: %d CLOCKS_PER_SEC: %d\n", (int)start, (int)end, (int)CLOCKS_PER_SEC);
+ while (playback < pos && !playback_done() && clock() < end)
+ play_command(commands[playback++], false);
+ //if (clock() > end)
+ // printf("killed by timeout.\n");
+ }
+
+ void set_playback_speed(int speed)
+ {
+ playback_speed = speed;
+ }
+
+ void truncate_at_playback()
+ {
+ commands.resize(playback+1);
+ }
+
+ void update_playback()
+ {
+ if (playing)
+ {
+ for (int i = 0; i < playback_speed; i++)
+ {
+ if (!playback_done())
+ play_command(commands[playback++], false);
+ }
+ }
+ }
+
+ int get_num_commands()
+ {
+ return commands.size();
+ }
+
+ void play_range(int from, int to)
+ {
+ for (int i = from; i < to; i++)
+ play_command(commands[i], false);
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Blit
+ //
+ // Draws a region of the canvas into a GdkImage for display on the screen, with optional scaling
+ // and darkening.
+
+ void blit_1x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay)
+ {
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ // Clip destination rectangle. Source clipping is handled per pixel.
+ if (dest_x < 0)
+ {
+ dest_w += dest_x;
+ dest_x = 0;
+ }
+ if (dest_y < 0)
+ {
+ dest_h += dest_y;
+ dest_y = 0;
+ }
+ if (dest_x+dest_w > img->width)
+ dest_w = img->width - dest_x;
+ if (dest_y+dest_h > img->height)
+ dest_h = img->height - dest_y;
+
+ int csy = src_y;
+ for (int cdy = dest_y; cdy < dest_y+dest_h; cdy++)
+ {
+ unsigned short* __restrict row = &pixels[cdy*pitch+dest_x];
+
+ // If out of bounds vertically, fill row with the background color.
+ if (csy < 0 || csy >= height)
+ {
+ for (int cdx = 0; cdx < dest_w; cdx++)
+ {
+ unsigned int rgb = 0;
+ *row++ = rgb;
+ }
+ }
+ else
+ {
+ unsigned int* __restrict src = &image[csy*width+src_x];
+
+ int cdx = 0;
+ int csx = src_x;
+
+ // Fill any portion that is to the left of the src image with
+ // background color.
+ while (csx < 0 && cdx < dest_w)
+ {
+ unsigned int rgb = 0;
+ *row++ = rgb;
+ src++;
+ csx++;
+ cdx++;
+ }
+
+ // Copy the pixels.
+ if (overlay)
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ p &= ~0x03030303;
+ p >>= 2;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ *row++ = rgb;
+ src++;
+ csx++;
+ cdx++;
+ }
+ }
+ else
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ *row++ = rgb;
+ src++;
+ csx++;
+ cdx++;
+ }
+ }
+
+ // Fill any portion to the right of src with background pixels.
+ while (cdx < dest_w)
+ {
+ unsigned int rgb = 0;
+ *row++ = rgb;
+ src++;
+ csx++;
+ cdx++;
+ }
+ }
+
+ csy++;
+ }
+ }
+
+ void blit_2x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay)
+ {
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ // Clip destination rectangle. Source clipping is handled per pixel.
+ if (dest_x < 0)
+ {
+ dest_w += dest_x;
+ dest_x = 0;
+ }
+ if (dest_y < 0)
+ {
+ dest_h += dest_y;
+ dest_y = 0;
+ }
+ if (dest_x+dest_w > img->width-2)
+ dest_w = (img->width-2) - dest_x;
+ if (dest_y+dest_h > img->height-2)
+ dest_h = (img->height-2) - dest_y;
+
+ int csy = src_y;
+ for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 2)
+ {
+ unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x];
+ unsigned short* __restrict row1 = row0 + pitch;
+
+ // If out of bounds vertically, fill row with the background color.
+ if (csy < 0 || csy >= height)
+ {
+ for (int cdx = 0; cdx < dest_w; cdx += 2)
+ {
+ unsigned int rgb = 0;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ }
+ }
+ else
+ {
+ unsigned int* __restrict src = &image[csy*width+src_x];
+
+ int cdx = 0;
+ int csx = src_x;
+
+ // Fill any portion that is to the left of the src image with
+ // background color.
+ while (csx < 0 && cdx < dest_w)
+ {
+ unsigned int rgb = 0;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ src++;
+ csx++;
+ cdx += 2;
+ }
+
+ // Copy the pixels.
+ if (overlay)
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ p &= ~0x03030303;
+ p >>= 2;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ src++;
+ csx++;
+ cdx += 2;
+ }
+ }
+ else
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ src++;
+ csx++;
+ cdx += 2;
+ }
+ }
+
+ // Fill any portion to the right of src with background pixels.
+ while (cdx < dest_w)
+ {
+ unsigned int rgb = 0;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ src++;
+ csx++;
+ cdx += 2;
+ }
+ }
+
+ csy++;
+ }
+ }
+
+ void blit_4x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay)
+ {
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ // Clip rectangle.
+ // Clip destination rectangle. Source clipping is handled per pixel.
+ if (dest_x < 0)
+ {
+ dest_w += dest_x;
+ dest_x = 0;
+ }
+ if (dest_y < 0)
+ {
+ dest_h += dest_y;
+ dest_y = 0;
+ }
+ if (dest_x + dest_w > img->width-4)
+ dest_w = (img->width-4) - dest_x;
+ if (dest_y + dest_h > img->height-4)
+ dest_h = (img->height-4) - dest_y;
+
+ int csy = src_y;
+ for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 4)
+ {
+ unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x];
+ unsigned short* __restrict row1 = row0 + pitch;
+ unsigned short* __restrict row2 = row1 + pitch;
+ unsigned short* __restrict row3 = row2 + pitch;
+
+#define FILL_PIXEL(rgb) \
+ row0[0] = rgb; row0[1] = rgb; row0[2] = rgb; row0[3] = rgb; \
+ row1[0] = rgb; row1[1] = rgb; row1[2] = rgb; row1[3] = rgb; \
+ row2[0] = rgb; row2[1] = rgb; row2[2] = rgb; row2[3] = rgb; \
+ row3[0] = rgb; row3[1] = rgb; row3[2] = rgb; row3[3] = rgb; \
+ row0 += 4; row1 += 4; row2 += 4; row3 += 4;
+
+ if (csy < 0 || csy >= height)
+ {
+ for (int cdx = 0; cdx < dest_w; cdx += 4)
+ {
+ FILL_PIXEL(0)
+ }
+ }
+ else
+ {
+ unsigned int* __restrict src = &image[csy*width+src_x];
+
+ int cdx = 0;
+ int csx = src_x;
+
+ while (csx < 0 && cdx < dest_w)
+ {
+ FILL_PIXEL(0)
+
+ src++;
+ csx++;
+ cdx += 4;
+ }
+
+ if (overlay)
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ p &= ~0x03030303;
+ p >>= 2;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ FILL_PIXEL(rgb)
+
+ src++;
+ csx++;
+ cdx += 4;
+ }
+ }
+ else
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ FILL_PIXEL(rgb)
+
+ src++;
+ csx++;
+ cdx += 4;
+ }
+ }
+
+ while (cdx < dest_w)
+ {
+ FILL_PIXEL(0)
+
+ src++;
+ csx++;
+ cdx += 4;
+ }
+ }
+
+#undef FILL_PIXEL
+
+ csy++;
+ }
+ }
+
+ void blit_8x(GdkImage* img, int src_x, int src_y, int dest_x, int dest_y, int dest_w, int dest_h, bool overlay)
+ {
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ // Clip rectangle.
+ // Clip destination rectangle. Source clipping is handled per pixel.
+ if (dest_x < 0)
+ {
+ dest_w += dest_x;
+ dest_x = 0;
+ }
+ if (dest_y < 0)
+ {
+ dest_h += dest_y;
+ dest_y = 0;
+ }
+ if (dest_x + dest_w > img->width-8)
+ dest_w = (img->width-8) - dest_x;
+ if (dest_y + dest_h > img->height-8)
+ dest_h = (img->height-8) - dest_y;
+
+ int csy = src_y;
+ for (int cdy = dest_y; cdy < dest_y+dest_h; cdy += 8)
+ {
+ unsigned short* __restrict row0 = &pixels[cdy*pitch+dest_x];
+ unsigned short* __restrict row1 = row0 + pitch;
+ unsigned short* __restrict row2 = row1 + pitch;
+ unsigned short* __restrict row3 = row2 + pitch;
+ unsigned short* __restrict row4 = row3 + pitch;
+ unsigned short* __restrict row5 = row4 + pitch;
+ unsigned short* __restrict row6 = row5 + pitch;
+ unsigned short* __restrict row7 = row6 + pitch;
+
+#define FILL_PIXEL(rgb) \
+ row0[0] = rgb; row0[1] = rgb; row0[2] = rgb; row0[3] = rgb; row0[4] = rgb; row0[5] = rgb; row0[6] = rgb; row0[7] = rgb; \
+ row1[0] = rgb; row1[1] = rgb; row1[2] = rgb; row1[3] = rgb; row1[4] = rgb; row1[5] = rgb; row1[6] = rgb; row1[7] = rgb; \
+ row2[0] = rgb; row2[1] = rgb; row2[2] = rgb; row2[3] = rgb; row2[4] = rgb; row2[5] = rgb; row2[6] = rgb; row2[7] = rgb; \
+ row3[0] = rgb; row3[1] = rgb; row3[2] = rgb; row3[3] = rgb; row3[4] = rgb; row3[5] = rgb; row3[6] = rgb; row3[7] = rgb; \
+ row4[0] = rgb; row4[1] = rgb; row4[2] = rgb; row4[3] = rgb; row4[4] = rgb; row4[5] = rgb; row4[6] = rgb; row4[7] = rgb; \
+ row5[0] = rgb; row5[1] = rgb; row5[2] = rgb; row5[3] = rgb; row5[4] = rgb; row5[5] = rgb; row5[6] = rgb; row5[7] = rgb; \
+ row6[0] = rgb; row6[1] = rgb; row6[2] = rgb; row6[3] = rgb; row6[4] = rgb; row6[5] = rgb; row6[6] = rgb; row6[7] = rgb; \
+ row7[0] = rgb; row7[1] = rgb; row7[2] = rgb; row7[3] = rgb; row7[4] = rgb; row7[5] = rgb; row7[6] = rgb; row7[7] = rgb; \
+ row0 += 8; row1 += 8; row2 += 8; row3 += 8; row4 += 8; row5 += 8; row6 += 8; row7 += 8;
+
+ if (csy < 0 || csy >= height)
+ {
+ for (int cdx = 0; cdx < dest_w; cdx += 8)
+ {
+ FILL_PIXEL(0)
+ }
+ }
+ else
+ {
+ unsigned int* __restrict src = &image[csy*width+src_x];
+
+ int cdx = 0;
+ int csx = src_x;
+
+ while (csx < 0 && cdx < dest_w)
+ {
+ FILL_PIXEL(0)
+
+ src++;
+ csx++;
+ cdx += 8;
+ }
+
+ if (overlay)
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ p &= ~0x03030303;
+ p >>= 2;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ FILL_PIXEL(rgb)
+
+ src++;
+ csx++;
+ cdx += 8;
+ }
+ }
+ else
+ {
+ while (csx < width && cdx < dest_w)
+ {
+ unsigned int p = *src;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ FILL_PIXEL(rgb)
+
+ src++;
+ csx++;
+ cdx += 8;
+ }
+ }
+
+ while (cdx < dest_w)
+ {
+ unsigned int rgb = 0;
+ FILL_PIXEL(rgb)
+
+ src++;
+ csx++;
+ cdx += 8;
+ }
+ }
+
+#undef FILL_PIXEL
+
+ csy++;
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Videopaint
+ //
+ // This code currently attempts to track a green object in the webcam and treat it as a
+ // mouse cursor, using the detected size to control the brush size.
+
+ void downsize_video(unsigned int* dest_pixels, GstBuffer* buf, int vwidth, int vheight)
+ {
+ if (vwidth != VIDEO_WIDTH*8 || vheight != VIDEO_HEIGHT*8 || buf->size != vwidth*vheight*sizeof(unsigned short))
+ {
+ printf("Invalid Gst video buffer size %d (%dx%d)\n", buf->size, vwidth, vheight);
+ return;
+ }
+
+ unsigned int* source_pixels = (unsigned int*)buf->data;
+
+ for (int y = 0; y < VIDEO_HEIGHT; y++)
+ {
+ unsigned int* __restrict src = &source_pixels[(y*4)*vwidth];
+ unsigned int* __restrict dest = &dest_pixels[y*VIDEO_WIDTH];
+ for (int x = 0; x < VIDEO_WIDTH; x++)
+ {
+ *dest = *src;
+ src += 4;
+ dest++;
+ }
+ }
+ }
+
+ void videopaint_motion(GstBuffer* buf, int vwidth, int vheight)
+ {
+ downsize_video(image_video[1], buf, vwidth, vheight);
+
+ unsigned int* pixels0 = image_video[0];
+ unsigned int* pixels1 = image_video[1];
+ double cx = 0, cy = 0, cnt = 0;
+ for (int y = 0; y < VIDEO_HEIGHT; y++)
+ {
+ unsigned int* __restrict row = &pixels1[y*VIDEO_WIDTH];
+ unsigned int* destrow = &pixels0[y*VIDEO_WIDTH];
+ for (int x = 0; x < VIDEO_WIDTH; x++)
+ {
+ // Convert YUYV to HSV
+ Color c = Color::yuv_to_hsv(*row);
+ // Threshold green
+ if ((c.r > 80) && (c.r < 150) && (c.g > 100)) {
+ destrow[0] = 0xffff;
+ cnt++;
+ cx += (80-x);
+ cy += y;
+ } else {
+ destrow[0] = 0;
+ }
+ row++;
+ destrow++;
+ }
+ }
+
+ if (cnt > 0)
+ {
+ cx /= cnt;
+ cy /= cnt;
+ // The mouse coordinates are scaled somewhat, as the nature of the video processing causes the blob to leave
+ // the screen partially and become smaller (and less significant) towards the edges.
+ videopaint_pos = Pos(
+ map_range(cx, 0, VIDEO_WIDTH, -0.2f, 1.2f),
+ map_range(cy, 0, VIDEO_HEIGHT, -0.2f, 1.2f));
+ // todo- estimate size
+ videopaint_pressure = map_range(cnt, 0, (VIDEO_WIDTH*VIDEO_HEIGHT)/8, 0, 255);
+ // Mark mouse pixel in red.
+ int rx = int(cx);
+ int ry = int(cy);
+ unsigned short red = Color(255,0,0,0).get_r5g6b5();
+ for (int x = -3; x <= 3; x++)
+ for (int y = -3; y <= 3; y++)
+ image_video[0][ry+y*VIDEO_WIDTH+rx+x] = red;
+ }
+ }
+
+ void blit_videopaint(GdkImage* img)
+ {
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ for (int y = 0; y < VIDEO_HEIGHT; y++)
+ {
+ unsigned int* __restrict src = &image_video[0][y*VIDEO_WIDTH];
+ unsigned short* __restrict dest = &pixels[y*pitch];
+ for (int x = 0; x < VIDEO_WIDTH; x++)
+ {
+ unsigned int p = *src++;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ *dest++ = rgb;
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Reference image
+ //
+ // The reference image is a snapshot taken by the webcam that can transparently displayed over the canvas.
+ // Note that painting currently cannot take place while the reference image is shown.
+
+ void set_reference_buffer(GstBuffer* buf, int vwidth, int vheight)
+ {
+ if (vwidth != REFERENCE_WIDTH || vheight != REFERENCE_HEIGHT || buf->size != vwidth*vheight*sizeof(unsigned short))
+ {
+ printf("Invalid Gst reference buffer size %d\n", buf->size);
+ return;
+ }
+ memcpy(image_reference, buf->data, min(buf->size, REFERENCE_WIDTH*REFERENCE_HEIGHT*sizeof(unsigned short)));
+ }
+
+ void render_reference_overlay()
+ {
+ // Uses image_backup to blend over the canvas without affecting the contents of the canvas.
+ // Scales up from whatever REFERENCE_WIDTH/REFERENCE_HEIGHT are to the canvas size.
+ int dx = (1<<16) * REFERENCE_WIDTH / width;
+ int dy = (1<<16) * REFERENCE_HEIGHT / height;
+ int ry = 0;
+ for (int y = 0; y < height; y++, ry += dy)
+ {
+ int rx = 0;
+ for (int x = 0; x < width; x++, rx += dx)
+ {
+ Color r = Color::create_from_r5g6b5(image_reference[(ry>>16)*REFERENCE_WIDTH+(rx>>16)]);
+ r = Color::create_from_yuv(r.r, r.g, r.b);
+ Color b = Color::create_from_a8r8g8b8(image_backup[y*width+x]);
+ image[y*width+x] = Color::create_from_lerp(r, b, 192).get_a8r8g8b8();
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Overlay
+ //
+ // These functions basically just temporarily darken the entire canvas so that a PyGTK overlay
+ // like the brush controls can be drawn on top, and look like it has a translucent black background.
+
+ void render_overlay()
+ {
+ // Since the image is backed up in image_backup, it's ok to destroy the contents of image since
+ // clear_overlay will just restore it from image_backup.
+ for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
+ {
+ unsigned int i = image_backup[y*width+x];
+ i &= ~0x03030303;
+ i >>= 2;
+ image[y*width+x] = i;
+ }
+ }
+
+ void clear_overlay()
+ {
+ memcpy(image, image_backup, width*height*sizeof(unsigned int));
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Load & Save
+
+ void upgrade_drw_header(DRW_Header* hdr, DRW_Command* cmds)
+ {
+ if (hdr->version == DRW_Header::ID) // Paying for old bug
+ hdr->version = 1002;
+
+ if (hdr->version < DRW_VERSION)
+ {
+ for(int i = 0; i < hdr->ncommands; i++)
+ {
+ DRW_Command* cmd = &cmds[i];
+ if (hdr->version < 1001)
+ {
+ if (cmd->type == DrawCommand::TYPE_DRAW)
+ {
+ cmd->x = int(round(cmd->x * 1024.0f / 2047.0f + 512.0f));
+ cmd->x = int(round(cmd->y * 1024.0f / 2047.0f + 512.0f));
+ }
+ }
+
+ if (hdr->version < 1002)
+ {
+ if (cmd->type == DrawCommand::TYPE_SIZECHANGE)
+ {
+ int type = (cmd->brushtype << 2) | cmd->brushcontrol;
+ switch(type)
+ {
+ case 0: cmd->brushtype = BrushType::BRUSHTYPE_HARD; cmd->brushcontrol = Brush::BRUSHCONTROL_VARIABLEOPACITY; break;
+ case 2: cmd->brushtype = BrushType::BRUSHTYPE_SOFT; cmd->brushcontrol = Brush::BRUSHCONTROL_VARIABLEOPACITY; break;
+ case 4: cmd->brushtype = BrushType::BRUSHTYPE_HARD; cmd->brushcontrol = 0; break;
+ case 6: cmd->brushtype = BrushType::BRUSHTYPE_SOFT; cmd->brushcontrol = 0; break;
+ }
+ cmd->size -= (1 << 6);
+ }
+ }
+ }
+ hdr->version = DRW_VERSION;
+ }
+ }
+
+ bool load(const char* filename)
+ {
+ FILE* drwfile = fopen(filename, "rb");
+ if (!drwfile)
+ return false;
+
+ int r;
+
+ DRW_Header header;
+ r = fread(&header, 1, sizeof(DRW_Header), drwfile);
+
+ // Backward compatible code for early versions when there was no header and the filesize is used
+ // to determine the number of commands.
+ if (header.id != DRW_Header::ID)
+ {
+ header.colorsversion_initial = 0;
+ fseek(drwfile, 0, SEEK_END);
+ header.ncommands = ftell(drwfile) / 4;
+ fseek(drwfile, 0, SEEK_SET);
+ }
+
+ DRW_Command* cmds = (DRW_Command*)malloc(header.ncommands*sizeof(DRW_Command));
+ r = fread(cmds, 1, header.ncommands*sizeof(DRW_Command), drwfile);
+
+ fclose(drwfile);
+
+ upgrade_drw_header(&header, cmds);
+
+ clear();
+ convert_from_drw(cmds, 0, header.ncommands);
+
+ free(cmds);
+
+ return true;
+ }
+
+ bool save(const char* filename)
+ {
+ FILE* drwfile = fopen(filename, "wb");
+ if (!drwfile)
+ return false;
+
+ int r;
+
+ DRW_Header header;
+ header.id = DRW_Header::ID;
+ header.version = DRW_VERSION;
+ header.colorsversion_initial = DRW_VERSION;
+ header.colorsversion_saved = DRW_VERSION;
+ header.strokes = 0;
+ header.time = 0;
+ header.timessaved = 0;
+ header.ncommands = commands.size();
+ r = fwrite(&header, 1, sizeof(DRW_Header), drwfile);
+
+ DRW_Command* cmds;
+ convert_to_drw(&cmds, 0, commands.size());
+
+ r = fwrite(cmds, sizeof(DRW_Command), commands.size(), drwfile);
+ free(cmds);
+
+ fclose(drwfile);
+
+ return true;
+ }
+
+ void convert_from_drw(DRW_Command* cmds, int start, int ncommands)
+ {
+ commands.resize(start+ncommands);
+ for (int i = 0; i < ncommands; i++)
+ {
+ DRW_Command* drw = &cmds[i];
+ DrawCommand* cmd = &commands[start+i];
+
+ cmd->type = drw->type;
+ cmd->pos.x = (drw->x-512.0f) / 1024.0f;
+ cmd->pos.y = (drw->y-512.0f) / 1024.0f;
+ cmd->pressure = drw->alpha;
+
+ cmd->color = Color::create_from_a8r8g8b8(drw->col);
+ cmd->flipx = drw->flipx;
+ cmd->flipy = drw->flipy;
+
+ cmd->brush_control = drw->brushcontrol;
+ cmd->brush_type = drw->brushtype;
+ cmd->size = drw->size / float(1 << 15);
+ cmd->opacity = drw->opacity / 255.0f;
+ }
+ }
+
+ void convert_to_drw(DRW_Command** cmds, int start, int ncommands)
+ {
+ *cmds = (DRW_Command*)malloc(sizeof(DRW_Command) * ncommands);
+
+ for (int i = 0; i < ncommands; i++)
+ {
+ DRW_Command* drw = &(*cmds)[i];
+ DrawCommand* cmd = &commands[start+i];
+
+ drw->type = cmd->type;
+
+ if (cmd->type == DrawCommand::TYPE_DRAW)
+ {
+ drw->x = int((cmd->pos.x*1024)+512);
+ drw->y = int((cmd->pos.y*1024)+512);
+ drw->alpha = cmd->pressure;
+ }
+ else if (cmd->type == DrawCommand::TYPE_DRAWEND)
+ {
+ drw->alpha = cmd->pressure;
+ }
+ else if (cmd->type == DrawCommand::TYPE_COLORCHANGE)
+ {
+ drw->flipx = cmd->flipx;
+ drw->flipy = cmd->flipy;
+ drw->col = cmd->color.get_a8r8g8b8();
+ }
+ else if (cmd->type == DrawCommand::TYPE_SIZECHANGE)
+ {
+ drw->brushcontrol = cmd->brush_control;
+ drw->brushtype = cmd->brush_type;
+ drw->size = int(cmd->size * float(1<<15));
+ drw->opacity = int(cmd->opacity * 255.0f);
+ }
+ }
+ }
+
+ DrawCommandBuffer send_drw_commands(int start, int ncommands)
+ {
+ DrawCommandBuffer buf;
+ buf.ncommands = ncommands;
+ convert_to_drw((DRW_Command**)&buf.cmds, start, ncommands);
+ return buf;
+ }
+
+ void receive_drw_commands(const DrawCommandBuffer& buf, int start)
+ {
+ convert_from_drw((DRW_Command*)buf.cmds, start, buf.ncommands);
+ }
+};
+
+#endif
+
diff --git a/pygame/color.so b/pygame/color.so
new file mode 100755
index 0000000..7b30264
--- /dev/null
+++ b/pygame/color.so
Binary files differ
diff --git a/pygame/colordict.py b/pygame/colordict.py
new file mode 100755
index 0000000..75a83d3
--- /dev/null
+++ b/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/pygame/constants.so b/pygame/constants.so
new file mode 100755
index 0000000..1e9ca9c
--- /dev/null
+++ b/pygame/constants.so
Binary files differ
diff --git a/pygame/drwfile.h b/pygame/drwfile.h
new file mode 100755
index 0000000..f581f9b
--- /dev/null
+++ b/pygame/drwfile.h
@@ -0,0 +1,77 @@
+/*
+ Copyright 2008 by Jens Andersson and Wade Brainerd.
+ This file is part of Colors! XO.
+
+ Colors is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Colors 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Colors. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef _DRWFILE_H_
+#define _DRWFILE_H_
+
+#define DRW_VERSION 1070
+
+struct DRW_Command
+{
+ union
+ {
+ struct
+ {
+ unsigned int type0 : 2;
+ unsigned int alpha : 8;
+ unsigned int x : 11;
+ unsigned int y : 11;
+ };
+
+ struct
+ {
+ unsigned int type1 : 2;
+ unsigned int col : 24;
+ unsigned int flipx : 1;
+ unsigned int flipy : 1;
+ };
+
+ struct
+ {
+ unsigned int type2 : 2;
+ unsigned int size : 16;
+ unsigned int brushcontrol : 2;
+ unsigned int brushtype : 2;
+ unsigned int opacity : 8;
+ };
+
+ struct
+ {
+ unsigned int type : 2;
+ unsigned int undef : 30;
+ };
+
+ int raw;
+ };
+};
+
+struct DRW_Header
+{
+ static const unsigned int ID = 0x436f6c21; // 'Col!'
+
+ unsigned int id;
+ unsigned int version;
+ int colorsversion_initial;
+ int colorsversion_saved;
+ int strokes;
+ int time;
+ int timessaved;
+ int dummy[8];
+ int ncommands;
+};
+
+#endif
diff --git a/pygame/gp2x/__init__.py b/pygame/gp2x/__init__.py
new file mode 100755
index 0000000..cb298e9
--- /dev/null
+++ b/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/pygame/gp2x/constants.py b/pygame/gp2x/constants.py
new file mode 100755
index 0000000..6dd4508
--- /dev/null
+++ b/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/pygame/gp2x/locals.py b/pygame/gp2x/locals.py
new file mode 100755
index 0000000..4d5670a
--- /dev/null
+++ b/pygame/gp2x/locals.py
@@ -0,0 +1,3 @@
+
+from pygame.gp2x.constants import *
+
diff --git a/pygame/gtk_types.h b/pygame/gtk_types.h
new file mode 100755
index 0000000..f3e26bd
--- /dev/null
+++ b/pygame/gtk_types.h
@@ -0,0 +1,130 @@
+// This file serves to allow access to a limited subset of GTK and GStreamer objects passed from PyGTK, without the full
+// GLib + GTK + GST development environment.
+//
+// Obviously, it is limited to working with a specific version of GTK, PyGTK and GStreamer, but these structures appear
+// to be fairly stable.
+#ifndef GTK_TYPES_H
+#define GTK_TYPES_H
+
+#include <stdint.h>
+
+typedef uint8_t guint8;
+typedef int32_t gint;
+typedef uint32_t guint;
+typedef uint16_t guint16;
+typedef uint64_t guint64;
+typedef void* gpointer;
+
+struct GTypeClass;
+struct GData;
+
+struct _GTypeInstance
+{
+ /*< private >*/
+ GTypeClass *g_class;
+};
+
+typedef struct _GTypeInstance GTypeInstance;
+
+struct _GObject
+{
+ GTypeInstance g_type_instance;
+
+ /*< private >*/
+ guint ref_count;
+ GData *qdata;
+};
+
+typedef struct _GObject GObject;
+
+typedef enum
+{
+ GDK_IMAGE_NORMAL,
+ GDK_IMAGE_SHARED,
+ GDK_IMAGE_FASTEST
+} GdkImageType;
+
+typedef enum
+{
+ GDK_LSB_FIRST,
+ GDK_MSB_FIRST
+} GdkByteOrder;
+
+struct GdkVisual;
+struct GdkColormap;
+
+typedef struct {
+ GObject parent_instance;
+
+
+ GdkImageType type; /* read only. */
+ GdkVisual *visual; /* read only. visual used to create the image */
+ GdkByteOrder byte_order; /* read only. */
+ gint width; /* read only. */
+ gint height; /* read only. */
+ guint16 depth; /* read only. */
+ guint16 bpp; /* read only. bytes per pixel */
+ guint16 bpl; /* read only. bytes per line */
+ guint16 bits_per_pixel; /* read only. bits per pixel */
+ gpointer mem;
+
+ GdkColormap *colormap; /* read only. */
+} GdkImage;
+
+struct GSList;
+
+typedef struct {
+ PyObject_HEAD
+ GObject *obj;
+ PyObject *inst_dict; /* the instance dictionary -- must be last */
+ PyObject *weakreflist; /* list of weak references */
+ GSList *closures;
+} PyGObject;
+
+struct _GstMiniObject {
+ GTypeInstance instance;
+ /*< public >*/ /* with COW */
+ gint refcount;
+ guint flags;
+
+ /*< private >*/
+ gpointer _gst_reserved;
+};
+
+typedef struct _GstMiniObject GstMiniObject;
+
+struct GstCaps;
+
+typedef guint64 GstClockTime;
+
+#define GST_PADDING 4
+
+struct _GstBuffer {
+ GstMiniObject mini_object;
+
+ /*< public >*/ /* with COW */
+ /* pointer to data and its size */
+ guint8 *data;
+ guint size;
+
+ /* timestamp */
+ GstClockTime timestamp;
+ GstClockTime duration;
+
+ /* the media type of this buffer */
+ GstCaps *caps;
+
+ /* media specific offset */
+ guint64 offset;
+ guint64 offset_end;
+
+ guint8 *malloc_data;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+typedef struct _GstBuffer GstBuffer;
+
+#endif
+
diff --git a/pygame/locals.py b/pygame/locals.py
new file mode 100755
index 0000000..9b1f2fb
--- /dev/null
+++ b/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/pygame/mask.h b/pygame/mask.h
new file mode 100755
index 0000000..169615f
--- /dev/null
+++ b/pygame/mask.h
@@ -0,0 +1,34 @@
+#include <Python.h>
+#include "bitmask.h"
+
+#define PYGAMEAPI_MASK_NUMSLOTS 1
+#define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API"
+
+typedef struct {
+ PyObject_HEAD
+ bitmask_t *mask;
+} PyMaskObject;
+
+#define PyMask_AsBitmap(x) (((PyMaskObject*)x)->mask)
+
+#ifndef PYGAMEAPI_MASK_INTERNAL
+
+#define PyMask_Type (*(PyTypeObject*)PyMASK_C_API[0])
+#define PyMask_Check(x) ((x)->ob_type == &PyMask_Type)
+
+#define import_pygame_mask() { \
+ PyObject *module = PyImport_ImportModule("pygame.mask"); \
+ if (module != NULL) { \
+ PyObject *dict = PyModule_GetDict(module); \
+ PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(c_api)) { \
+ void** localptr = (void**) PyCObject_AsVoidPtr(c_api); \
+ memcpy(PyMASK_C_API, localptr, sizeof(void*)*PYGAMEAPI_MASK_NUMSLOTS); \
+ } Py_DECREF(module); \
+ } \
+}
+
+#endif /* !defined(PYGAMEAPI_MASK_INTERNAL) */
+
+static void* PyMASK_C_API[PYGAMEAPI_MASK_NUMSLOTS] = {NULL};
+
diff --git a/pygame/mask.so b/pygame/mask.so
new file mode 100755
index 0000000..6fa7ca2
--- /dev/null
+++ b/pygame/mask.so
Binary files differ
diff --git a/pygame/palette.h b/pygame/palette.h
new file mode 100755
index 0000000..03d51eb
--- /dev/null
+++ b/pygame/palette.h
@@ -0,0 +1,458 @@
+/*
+ Copyright 2008 by Jens Andersson and Wade Brainerd.
+ This file is part of Colors! XO.
+
+ Colors is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Colors 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Colors. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef _PALETTE_H_
+#define _PALETTE_H_
+
+#include "colorsc.h"
+#include "canvas.h"
+
+// The Palette is the color wheel and triangle that are part of the brush controls dialog.
+// This class manages rendering the palette as efficiently as possible into GdkImage objects which are
+// then displayed on the screen.
+// It also manages responding to mouse inputs that are passed from the Python code.
+class Palette
+{
+public:
+ static const int WHEEL_WIDTH = 75;
+
+ int size;
+
+ float palette_h, palette_s, palette_v;
+
+ Pos triangle_cursor;
+ bool triangle_capture;
+ bool wheel_capture;
+
+ Palette(int size) : size(size)
+ {
+ palette_h = palette_s = palette_v = 0;
+ triangle_capture = false;
+ }
+
+ float get_wheel_radius()
+ {
+ return size - WHEEL_WIDTH/2;
+ }
+
+ void rgb_to_hsv(float r, float g, float b, float* h, float* s, float* v)
+ {
+ float mn = min(min(r, g), b);
+ float mx = max(max(r, g), b);
+ *v = mx; // v
+ float delta = mx - mn;
+ if (mx != 0)
+ *s = delta / mx; // s
+ else
+ {
+ // r = g = b = 0 // s = 0, v is undefined
+ *s = 0;
+ *h = -1;
+ return;
+ }
+ if (delta == 0)
+ *h = 0;
+ else if (r == mx)
+ *h = ( g - b ) / delta; // between yellow & magenta
+ else if (g == mx)
+ *h = 2 + ( b - r ) / delta; // between cyan & yellow
+ else
+ *h = 4 + ( r - g ) / delta; // between magenta & cyan
+ *h *= 60; // degrees
+ if (*h < 0)
+ *h += 360;
+ }
+
+ void hsv_to_rgb(float* r, float* g, float* b, float h, float s, float v)
+ {
+ if (s == 0)
+ {
+ // achromatic (grey)
+ *r = *g = *b = v;
+ return;
+ }
+ h /= 60; // sector 0 to 5
+ int i = int(floorf(h));
+ float f = h - i; // factorial part of h
+ float p = v * (1-s);
+ float q = v * (1-s * f);
+ float t = v * (1-s * (1 - f));
+ switch (i)
+ {
+ case 0: *r = v; *g = t; *b = p; break;
+ case 1: *r = q; *g = v; *b = p; break;
+ case 2: *r = p; *g = v; *b = t; break;
+ case 3: *r = p; *g = q; *b = v; break;
+ case 4: *r = t; *g = p; *b = v; break;
+ default:
+ case 5: *r = v; *g = p; *b = q; break;
+ }
+ }
+
+ void set_color(const Color& c)
+ {
+ rgb_to_hsv(c.r/255.0f, c.g/255.0f, c.b/255.0f, &palette_h, &palette_s, &palette_v);
+
+ // I couldn't work out an exact solution to the blobby triangle position, so I'm using a relaxation algorithm.
+ // It usually takes less than 10 iterations to converge and only runs when you first open the palette.
+ Pos p0, p1, p2;
+ get_triangle_points(&p0, &p1, &p2);
+ float side = distance(p0, p1);
+
+ Pos p = (p0+p1+p2)*(1.0f/3.0f);
+ float epsilon = 0.001f;
+ int max_iterations = 50;
+ for (int i = 0; i < max_iterations; i++)
+ {
+ float d0 = distance(p, p0);
+ float d0ok = fabsf((side-d0)-palette_s*side);
+ p = p + ((p0-p)/length(p0-p)) * (d0-(1.0f-palette_s)*side);
+
+ float d2 = distance(p, p2);
+ float d2ok = fabsf(d2-palette_v*side);
+ p = p + ((p2-p)/length(p2-p)) * (d2-palette_v*side);
+
+ if (d0ok <= epsilon && d2ok <= epsilon) break;
+ }
+ triangle_cursor = p;
+ }
+
+ Color get_color()
+ {
+ float r, g, b;
+ hsv_to_rgb(&r, &g, &b, palette_h, palette_s, palette_v);
+ return Color::create_from_float(r, g, b, 1.0f);
+ }
+
+ float sqr(float a)
+ {
+ return a*a;
+ }
+
+ float dot(const Pos& a, const Pos& b)
+ {
+ return a.x*b.x + a.y*b.y;
+ }
+
+ float length(const Pos& a)
+ {
+ return sqrtf(dot(a,a));
+ }
+
+ float length_sqr(const Pos& a)
+ {
+ return dot(a,a);
+ }
+
+ float distance(const Pos& a, const Pos& b)
+ {
+ return length(a-b);
+ }
+
+ float distance_sqr(const Pos& a, const Pos& b)
+ {
+ return length_sqr(a-b);
+ }
+
+ Pos normalize(const Pos& a)
+ {
+ return a/length(a);
+ }
+
+ void get_triangle_points(Pos* p0, Pos* p1, Pos* p2)
+ {
+ Pos center(size/2, size/2);
+ *p0 = center + Pos::create_from_angle(palette_h+0.0f, size/2-WHEEL_WIDTH);
+ *p1 = center + Pos::create_from_angle(palette_h+120.0f, size/2-WHEEL_WIDTH);
+ *p2 = center + Pos::create_from_angle(palette_h+240.0f, size/2-WHEEL_WIDTH);
+ }
+
+ // The wheel never changes, so it can be rendered once here. This also clears the image background.
+ void render_wheel(GdkImage* image)
+ {
+ if (image->width != size || image->height != size || image->bits_per_pixel != 16)
+ {
+ fprintf(stderr, "Error: Invalid Palette GdkImage.\n");
+ return;
+ }
+
+ Color bkg(64, 64, 64, 0);
+
+ float wheel_radius = size/2;
+ float ring_min_sqr = sqr(wheel_radius-WHEEL_WIDTH);
+ float ring_max_sqr = sqr(wheel_radius);
+
+ unsigned short* pixels = (unsigned short*)image->mem;
+ int stride = image->bpl/sizeof(unsigned short);
+
+ for (int y = 0; y < size; y++)
+ {
+ unsigned short* row = &pixels[y*stride];
+ for (int x = 0; x < size; x++)
+ {
+ // Get radius from center of palette.
+ float dx = x-wheel_radius;
+ float dy = y-wheel_radius;
+ float dist_sqr = dx*dx + dy*dy;
+
+ // Inside color wheel ring? Draw the wheel.
+ if (dist_sqr >= ring_min_sqr && dist_sqr < ring_max_sqr)
+ {
+ // Calculate HSV from wheel angle.
+ float h = atan2f(dy, dx)*180.0f/PI;
+ while (h<0) h += 360.0f;
+ while (h>360.0f) h -= 360.0f;
+ float r, g, b;
+ hsv_to_rgb(&r, &g, &b, h, 1.0f, 1.0f);
+ *row++ = Color::create_from_float(r, g, b, 1).get_r5g6b5();
+ }
+ else
+ *row++ = bkg.get_r5g6b5();
+ }
+ }
+ }
+
+ // Clears out the inner circle and redraws the color triangle, as fast as possible.
+ // Scales up implicitly by 2x to improve performance.
+ // The appearance was an accident which creates a kind of blobby triangle, like the intersection of three circles.
+ // But I like the look so I'm keeping it!
+ void render_triangle(GdkImage* image)
+ {
+ if (image->width != size || image->height != size || image->bits_per_pixel != 16 || (size&1))
+ {
+ fprintf(stderr, "Error: Invalid Palette GdkImage.\n");
+ return;
+ }
+
+ Color bkg(64, 64, 64, 0);
+ unsigned short bkgc = bkg.get_r5g6b5();
+
+ Pos p0, p1, p2;
+ get_triangle_points(&p0, &p1, &p2);
+ float triangle_side = distance(p0, p1);
+ float triangle_side_sqr = triangle_side*triangle_side;
+ float inv_triangle_side = 1.0f/triangle_side;
+
+ float wheel_radius = size/2;
+ float ring_min_sqr = sqr(wheel_radius-WHEEL_WIDTH);
+
+ int x0 = WHEEL_WIDTH;
+ int x1 = size-WHEEL_WIDTH;
+
+ unsigned short* pixels = (unsigned short*)image->mem;
+ int stride = image->bpl/sizeof(unsigned short);
+
+ Pos p(x0,x0);
+ for (int y = x0; y < x1; y+=2, p.y += 2.0f)
+ {
+ p.x = x0;
+ unsigned short* __restrict row0 = &pixels[(y+0)*stride+x0];
+ unsigned short* __restrict row1 = &pixels[(y+1)*stride+x0];
+ for (int x = x0; x < x1; x+=2, p.x += 2.0f)
+ {
+ // Calculate position inside triangle. If inside, then use as HSV.
+ float d0_sqr = distance_sqr(p, p0);
+ float d1_sqr = distance_sqr(p, p1);
+ float d2_sqr = distance_sqr(p, p2);
+ if (d0_sqr <= triangle_side_sqr && d1_sqr <= triangle_side_sqr && d2_sqr <= triangle_side_sqr)
+ {
+ float r, g, b;
+ hsv_to_rgb(&r, &g, &b, palette_h, 1.0f-sqrtf(d0_sqr)*inv_triangle_side, sqrtf(d2_sqr)*inv_triangle_side);
+ unsigned short c = Color::create_from_float(r, g, b, 1).get_r5g6b5();
+ row0[0] = c;
+ row0[1] = c;
+ row1[0] = c;
+ row1[1] = c;
+ }
+ else
+ {
+ // Inside ring? Clear to background.
+ if (distance_sqr(p, Pos(wheel_radius, wheel_radius)) < ring_min_sqr)
+ {
+ row0[0] = bkgc;
+ row0[1] = bkgc;
+ row1[0] = bkgc;
+ row1[1] = bkgc;
+ }
+ }
+ row0 += 2;
+ row1 += 2;
+ }
+ }
+ }
+
+ Pos get_wheel_pos()
+ {
+ float a = palette_h*PI/180.0f;
+ float r = size/2 - WHEEL_WIDTH/2;
+ return Pos(size/2+r*cosf(a), size/2+r*sinf(a));
+ }
+
+ Pos get_triangle_pos()
+ {
+ return triangle_cursor;
+ }
+
+ void process_mouse(int mx, int my)
+ {
+ Pos p0, p1, p2;
+ get_triangle_points(&p0, &p1, &p2);
+
+ // If the triangle has the mouse capture, clip the mouse position to within the blobby triangle.
+ if (!wheel_capture)
+ {
+ if (triangle_capture)
+ {
+ Pos p(mx, my);
+ float d0 = distance(p, p0);
+ float d1 = distance(p, p1);
+ float d2 = distance(p, p2);
+ float side = distance(p0, p1)-1;
+ if (d0 > side || d1 > side || d2 > side)
+ {
+ Pos far_point = p0;
+ float far_dist = d0;
+ if (d1 > far_dist) { far_point = p1; far_dist = d1; }
+ if (d2 > far_dist) { far_point = p2; far_dist = d2; }
+ p = far_point + normalize(p-far_point) * side;
+ mx = int(p.x);
+ my = int(p.y);
+ }
+ }
+
+ // Now check to see if it's on the triangle.
+ float side = 1.0f/distance(p0, p1);
+ Pos p(mx, my);
+ float d0 = distance(p, p0)*side;
+ float d1 = distance(p, p1)*side;
+ float d2 = distance(p, p2)*side;
+ if (d0 <= 1.0f && d1 <= 1.0f && d2 <= 1.0f)
+ {
+ triangle_capture = true;
+ triangle_cursor = p;
+ palette_s = 1.0f-d0;
+ palette_v = d2;
+ }
+ }
+
+ if (!triangle_capture)
+ {
+ // Check to see if the mouse is in the wheel ring.
+ int dx = mx-size/2;
+ int dy = my-size/2;
+ float dist = sqrtf(dx*dx + dy*dy);
+ if (dist >= size/2-WHEEL_WIDTH || wheel_capture)
+ {
+ wheel_capture = true;
+ float h = atan2f(float(dy), float(dx))*180.0f/PI;
+ while (h<0) h += 360.0f;
+ while (h>360.0f) h -= 360.0f;
+ // Rotate the triangle cursor with the wheel.
+ triangle_cursor = Pos::create_from_rotation(triangle_cursor, (p0+p1+p2)/3.0f, (h-palette_h)*PI/180.0f);
+ palette_h = h;
+ }
+ }
+ }
+
+ void process_mouse_release()
+ {
+ triangle_capture = false;
+ wheel_capture = false;
+ }
+};
+
+// The BrushPreview is a simple preview of the current brush as displayed in the Brush Controls panel.
+// This class handles rendering the brush preview to a GdkImage to be displayed on the screen.
+class BrushPreview
+{
+public:
+ int size;
+
+ Brush brush;
+
+ BrushPreview(int size) : size(size)
+ {
+ }
+
+ void render(GdkImage* image)
+ {
+ if (image->width != size || image->height != size || image->bits_per_pixel != 16 || (size&1))
+ {
+ fprintf(stderr, "Error: Invalid BrushPreview GdkImage.\n");
+ return;
+ }
+
+ // Minimum brush size.
+ if (brush.size<2) brush.size = 2;
+
+ // Calculate interpolation constants
+ float db = (BrushType::DIST_TABLE_WIDTH-1) / float(brush.size);
+
+ float xb = BrushType::DIST_TABLE_CENTER - (size/2)*db;
+ float yb = BrushType::DIST_TABLE_CENTER - (size/2)*db;
+
+ // Select which line of the brush-lookup-table to use that most closely matches the current brush width
+ int brushidx = int(float(BrushType::BRUSH_TABLE_HEIGHT) / brush.size);
+
+ int opacity = int(round(255.0f * brush.opacity));
+
+ unsigned short* pixels = (unsigned short*)image->mem;
+ int stride = image->bpl/sizeof(unsigned short);
+
+ // Interpolate the distance table over the area. For each pixel find the distance, and look the
+ // brush-intensity up in the brush-table
+ for (int y = 0; y < size; y+=2)
+ {
+ float x2b = xb;
+ unsigned short* __restrict row0 = &pixels[(y+0)*stride];
+ unsigned short* __restrict row1 = &pixels[(y+1)*stride];
+ for (int x = 0; x < size; x+=2)
+ {
+ // Find brush-intensity and mulitply that with incoming opacity
+ if (x2b >= 0 && x2b < BrushType::DIST_TABLE_WIDTH && yb >= 0 && yb < BrushType::DIST_TABLE_WIDTH)
+ {
+ int lookup = BrushType::distance_tbl[int(x2b)][int(yb)];
+ int intensity = fixed_scale(Brush::brush_type[brush.type].intensity_tbl[lookup][brushidx], opacity);
+ Color i = Color::create_from_a8r8g8b8(0xffffffff);
+ //Color i = Color::create_from_a8r8g8b8(image[y*size+x]);
+ i = Color::create_from_lerp(brush.color, i, intensity);
+ unsigned short c = i.get_r5g6b5();
+ row0[0] = c;
+ row0[1] = c;
+ row1[0] = c;
+ row1[1] = c;
+ }
+ else
+ {
+ row0[0] = 0xffff;
+ row0[1] = 0xffff;
+ row1[0] = 0xffff;
+ row1[1] = 0xffff;
+ }
+
+ row0 += 2;
+ row1 += 2;
+
+ x2b += db*2;
+ }
+ yb += db*2;
+ }
+ }
+};
+
+#endif
+
diff --git a/pygame/pgopengl.h b/pygame/pgopengl.h
new file mode 100755
index 0000000..7f9fd95
--- /dev/null
+++ b/pygame/pgopengl.h
@@ -0,0 +1,16 @@
+#if !defined(PGOPENGL_H)
+#define PGOPENGL_H
+
+/** This header includes definitions of Opengl functions as pointer types for
+ ** use with the SDL function SDL_GL_GetProcAddress.
+ **/
+
+#if defined(_WIN32)
+#define GL_APIENTRY __stdcall
+#else
+#define GL_APIENTRY
+#endif
+
+typedef void (GL_APIENTRY *GL_glReadPixels_Func)(int, int, int, int, unsigned int, unsigned int, void*);
+
+#endif
diff --git a/pygame/pkgdata.py b/pygame/pkgdata.py
new file mode 100755
index 0000000..0783498
--- /dev/null
+++ b/pygame/pkgdata.py
@@ -0,0 +1,65 @@
+"""
+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 cStringIO import StringIO
+
+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, "%r has no __file__!"
+ 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 StringIO(data)
+ return file(os.path.normpath(path), 'rb')
diff --git a/pygame/pygame.h b/pygame/pygame.h
new file mode 100755
index 0000000..2f360c0
--- /dev/null
+++ b/pygame/pygame.h
@@ -0,0 +1,651 @@
+/*
+ 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
+*/
+
+#ifndef PYGAME_H
+#define PYGAME_H
+
+/** This header file includes all the definitions for the
+ ** base pygame extensions. This header only requires
+ ** SDL and Python includes. The reason for functions
+ ** prototyped with #define's is to allow for maximum
+ ** python portability. It also uses python as the
+ ** runtime linker, which allows for late binding. For more
+ ** information on this style of development, read the Python
+ ** docs on this subject.
+ ** http://www.python.org/doc/current/ext/using-cobjects.html
+ **
+ ** If using this to build your own derived extensions,
+ ** you'll see that the functions available here are mainly
+ ** used to help convert between python objects and SDL objects.
+ ** Since this library doesn't add a lot of functionality to
+ ** the SDL libarary, it doesn't need to offer a lot either.
+ **
+ ** When initializing your extension module, you must manually
+ ** import the modules you want to use. (this is the part about
+ ** using python as the runtime linker). Each module has its
+ ** own import_xxx() routine. You need to perform this import
+ ** after you have initialized your own module, and before
+ ** you call any routines from that module. Since every module
+ ** in pygame does this, there are plenty of examples.
+ **
+ ** The base module does include some useful conversion routines
+ ** that you are free to use in your own extension.
+ **
+ ** When making changes, it is very important to keep the
+ ** FIRSTSLOT and NUMSLOT constants up to date for each
+ ** section. Also be sure not to overlap any of the slots.
+ ** When you do make a mistake with this, it will result
+ ** is a dereferenced NULL pointer that is easier to diagnose
+ ** than it could be :]
+ **/
+#if defined(HAVE_SNPRINTF) /* defined in python.h (pyerrors.h) and SDL.h (SDL_config.h) */
+#undef HAVE_SNPRINTF /* remove GCC redefine warning */
+#endif
+
+#include <Python.h>
+
+#if defined(HAVE_SNPRINTF)
+#undef HAVE_SNPRINTF
+#endif
+
+#ifdef MS_WIN32 /*Python gives us MS_WIN32, SDL needs just WIN32*/
+#ifndef WIN32
+#define WIN32
+#endif
+#endif
+
+#include <SDL.h>
+
+/* macros used throughout the source */
+#define RAISE(x,y) (PyErr_SetString((x), (y)), (PyObject*)NULL)
+
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 3
+# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
+# define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
+# define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
+#endif
+
+/* Py_ssize_t availability. */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+typedef intargfunc ssizeargfunc;
+typedef intobjargproc ssizeobjargproc;
+typedef intintargfunc ssizessizeargfunc;
+typedef intintobjargproc ssizessizeobjargproc;
+typedef getreadbufferproc readbufferproc;
+typedef getwritebufferproc writebufferproc;
+typedef getsegcountproc segcountproc;
+typedef getcharbufferproc charbufferproc;
+#endif
+
+#define PyType_Init(x) (((x).ob_type) = &PyType_Type)
+#define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API"
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ( (a) > (b) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+#endif
+
+/* test sdl initializations */
+#define VIDEO_INIT_CHECK() \
+ if(!SDL_WasInit(SDL_INIT_VIDEO)) \
+ return RAISE(PyExc_SDLError, "video system not initialized")
+
+#define CDROM_INIT_CHECK() \
+ if(!SDL_WasInit(SDL_INIT_CDROM)) \
+ return RAISE(PyExc_SDLError, "cdrom system not initialized")
+
+#define JOYSTICK_INIT_CHECK() \
+ if(!SDL_WasInit(SDL_INIT_JOYSTICK)) \
+ return RAISE(PyExc_SDLError, "joystick system not initialized")
+
+/* BASE */
+#define PYGAMEAPI_BASE_FIRSTSLOT 0
+#define PYGAMEAPI_BASE_NUMSLOTS 13
+#ifndef PYGAMEAPI_BASE_INTERNAL
+#define PyExc_SDLError ((PyObject*)PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT])
+
+#define PyGame_RegisterQuit \
+ (*(void(*)(void(*)(void)))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 1])
+
+#define IntFromObj \
+ (*(int(*)(PyObject*, int*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 2])
+
+#define IntFromObjIndex \
+ (*(int(*)(PyObject*, int, int*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 3])
+
+#define TwoIntsFromObj \
+ (*(int(*)(PyObject*, int*, int*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 4])
+
+#define FloatFromObj \
+ (*(int(*)(PyObject*, float*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 5])
+
+#define FloatFromObjIndex \
+ (*(float(*)(PyObject*, int, float*)) \
+ PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 6])
+
+#define TwoFloatsFromObj \
+ (*(int(*)(PyObject*, float*, float*)) \
+ PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 7])
+
+#define UintFromObj \
+ (*(int(*)(PyObject*, Uint32*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 8])
+
+#define UintFromObjIndex \
+ (*(int(*)(PyObject*, int, Uint32*)) \
+ PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 9])
+
+#define PyGame_Video_AutoQuit \
+ (*(void(*)(void))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 10])
+
+#define PyGame_Video_AutoInit \
+ (*(int(*)(void))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 11])
+
+#define RGBAFromObj \
+ (*(int(*)(PyObject*, Uint8*))PyGAME_C_API[PYGAMEAPI_BASE_FIRSTSLOT + 12])
+
+#define import_pygame_base() { \
+ PyObject *_module = PyImport_ImportModule("pygame.base"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_BASE_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_BASE_FIRSTSLOT] = localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* RECT */
+#define PYGAMEAPI_RECT_FIRSTSLOT \
+ (PYGAMEAPI_BASE_FIRSTSLOT + PYGAMEAPI_BASE_NUMSLOTS)
+#define PYGAMEAPI_RECT_NUMSLOTS 4
+
+typedef struct {
+ int x, y;
+ int w, h;
+}GAME_Rect;
+
+typedef struct {
+ PyObject_HEAD
+ GAME_Rect r;
+ PyObject *weakreflist;
+} PyRectObject;
+
+#define PyRect_AsRect(x) (((PyRectObject*)x)->r)
+#ifndef PYGAMEAPI_RECT_INTERNAL
+#define PyRect_Check(x) \
+ ((x)->ob_type == (PyTypeObject*)PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 0])
+#define PyRect_Type (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 0])
+#define PyRect_New \
+ (*(PyObject*(*)(SDL_Rect*))PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 1])
+#define PyRect_New4 \
+ (*(PyObject*(*)(int,int,int,int))PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 2])
+#define GameRect_FromObject \
+ (*(GAME_Rect*(*)(PyObject*, GAME_Rect*)) \
+ PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 3])
+
+#define import_pygame_rect() { \
+ PyObject *_module = PyImport_ImportModule("pygame.rect"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_RECT_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_RECT_FIRSTSLOT] = localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* CDROM */
+#define PYGAMEAPI_CDROM_FIRSTSLOT \
+ (PYGAMEAPI_RECT_FIRSTSLOT + PYGAMEAPI_RECT_NUMSLOTS)
+#define PYGAMEAPI_CDROM_NUMSLOTS 2
+
+typedef struct {
+ PyObject_HEAD
+ int id;
+} PyCDObject;
+
+#define PyCD_AsID(x) (((PyCDObject*)x)->id)
+#ifndef PYGAMEAPI_CDROM_INTERNAL
+#define PyCD_Check(x) \
+ ((x)->ob_type == (PyTypeObject*)PyGAME_C_API[PYGAMEAPI_CDROM_FIRSTSLOT + 0])
+#define PyCD_Type (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_CDROM_FIRSTSLOT + 0])
+#define PyCD_New \
+ (*(PyObject*(*)(int))PyGAME_C_API[PYGAMEAPI_CDROM_FIRSTSLOT + 1])
+
+#define import_pygame_cd() { \
+ PyObject *_module = PyImport_ImportModule("pygame.cdrom"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_CDROM_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_CDROM_FIRSTSLOT] = localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* JOYSTICK */
+#define PYGAMEAPI_JOYSTICK_FIRSTSLOT \
+ (PYGAMEAPI_CDROM_FIRSTSLOT + PYGAMEAPI_CDROM_NUMSLOTS)
+#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2
+
+typedef struct {
+ PyObject_HEAD
+ int id;
+} PyJoystickObject;
+
+#define PyJoystick_AsID(x) (((PyJoystickObject*)x)->id)
+
+#ifndef PYGAMEAPI_JOYSTICK_INTERNAL
+#define PyJoystick_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 0])
+
+#define PyJoystick_Type \
+ (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 0])
+#define PyJoystick_New \
+ (*(PyObject*(*)(int))PyGAME_C_API[PYGAMEAPI_JOYSTICK_FIRSTSLOT + 1])
+
+#define import_pygame_joystick() { \
+ PyObject *_module = PyImport_ImportModule("pygame.joystick"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_JOYSTICK_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_JOYSTICK_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* DISPLAY */
+#define PYGAMEAPI_DISPLAY_FIRSTSLOT \
+ (PYGAMEAPI_JOYSTICK_FIRSTSLOT + PYGAMEAPI_JOYSTICK_NUMSLOTS)
+#define PYGAMEAPI_DISPLAY_NUMSLOTS 2
+typedef struct {
+ PyObject_HEAD
+ SDL_VideoInfo info;
+} PyVidInfoObject;
+
+#define PyVidInfo_AsVidInfo(x) (((PyVidInfoObject*)x)->info)
+#ifndef PYGAMEAPI_DISPLAY_INTERNAL
+#define PyVidInfo_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_DISPLAY_FIRSTSLOT + 0])
+
+#define PyVidInfo_Type \
+ (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 0])
+#define PyVidInfo_New \
+ (*(PyObject*(*)(SDL_VideoInfo*)) \
+ PyGAME_C_API[PYGAMEAPI_DISPLAY_FIRSTSLOT + 1])
+#define import_pygame_display() { \
+ PyObject *_module = PyImport_ImportModule("pygame.display"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_DISPLAY_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_DISPLAY_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* SURFACE */
+#define PYGAMEAPI_SURFACE_FIRSTSLOT \
+ (PYGAMEAPI_DISPLAY_FIRSTSLOT + PYGAMEAPI_DISPLAY_NUMSLOTS)
+#define PYGAMEAPI_SURFACE_NUMSLOTS 3
+typedef struct {
+ PyObject_HEAD
+ SDL_Surface* surf;
+ struct SubSurface_Data* subsurface; /*ptr to subsurface data (if a
+ * subsurface)*/
+ PyObject *weakreflist;
+ PyObject *locklist;
+ PyObject *dependency;
+} PySurfaceObject;
+#define PySurface_AsSurface(x) (((PySurfaceObject*)x)->surf)
+#ifndef PYGAMEAPI_SURFACE_INTERNAL
+#define PySurface_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 0])
+#define PySurface_Type \
+ (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 0])
+#define PySurface_New \
+ (*(PyObject*(*)(SDL_Surface*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 1])
+#define PySurface_Blit \
+ (*(int(*)(PyObject*,PyObject*,SDL_Rect*,SDL_Rect*,int)) \
+ PyGAME_C_API[PYGAMEAPI_SURFACE_FIRSTSLOT + 2])
+
+#define import_pygame_surface() { \
+ PyObject *_module = PyImport_ImportModule("pygame.surface"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_SURFACE_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_SURFACE_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ _module = PyImport_ImportModule("pygame.surflock"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_SURFLOCK_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_SURFLOCK_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* SURFLOCK */ /*auto import/init by surface*/
+#define PYGAMEAPI_SURFLOCK_FIRSTSLOT \
+ (PYGAMEAPI_SURFACE_FIRSTSLOT + PYGAMEAPI_SURFACE_NUMSLOTS)
+#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8
+struct SubSurface_Data
+{
+ PyObject* owner;
+ int pixeloffset;
+ int offsetx, offsety;
+};
+
+typedef struct
+{
+ PyObject_HEAD
+ PyObject *surface;
+ PyObject *lockobj;
+ PyObject *weakrefs;
+} PyLifetimeLock;
+
+#ifndef PYGAMEAPI_SURFLOCK_INTERNAL
+#define PyLifetimeLock_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 0])
+#define PySurface_Prep(x) \
+ if(((PySurfaceObject*)x)->subsurface) \
+ (*(*(void(*)(PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 1]))(x)
+
+#define PySurface_Unprep(x) \
+ if(((PySurfaceObject*)x)->subsurface) \
+ (*(*(void(*)(PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 2]))(x)
+
+#define PySurface_Lock \
+ (*(int(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 3])
+#define PySurface_Unlock \
+ (*(int(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 4])
+#define PySurface_LockBy \
+ (*(int(*)(PyObject*,PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 5])
+#define PySurface_UnlockBy \
+ (*(int(*)(PyObject*,PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 6])
+#define PySurface_LockLifetime \
+ (*(PyObject*(*)(PyObject*,PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 7])
+#endif
+
+
+/* EVENT */
+#define PYGAMEAPI_EVENT_FIRSTSLOT \
+ (PYGAMEAPI_SURFLOCK_FIRSTSLOT + PYGAMEAPI_SURFLOCK_NUMSLOTS)
+#define PYGAMEAPI_EVENT_NUMSLOTS 4
+
+typedef struct {
+ PyObject_HEAD
+ int type;
+ PyObject* dict;
+} PyEventObject;
+
+#ifndef PYGAMEAPI_EVENT_INTERNAL
+#define PyEvent_Check(x) \
+ ((x)->ob_type == (PyTypeObject*)PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 0])
+#define PyEvent_Type \
+ (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 0])
+#define PyEvent_New \
+ (*(PyObject*(*)(SDL_Event*))PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 1])
+#define PyEvent_New2 \
+ (*(PyObject*(*)(int, PyObject*))PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 2])
+#define PyEvent_FillUserEvent \
+ (*(int (*)(PyEventObject*, SDL_Event*)) \
+ PyGAME_C_API[PYGAMEAPI_EVENT_FIRSTSLOT + 3])
+#define import_pygame_event() { \
+ PyObject *_module = PyImport_ImportModule("pygame.event"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_EVENT_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_EVENT_FIRSTSLOT] = localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+
+/* RWOBJECT */
+/*the rwobject are only needed for C side work, not accessable from python*/
+#define PYGAMEAPI_RWOBJECT_FIRSTSLOT \
+ (PYGAMEAPI_EVENT_FIRSTSLOT + PYGAMEAPI_EVENT_NUMSLOTS)
+#define PYGAMEAPI_RWOBJECT_NUMSLOTS 4
+#ifndef PYGAMEAPI_RWOBJECT_INTERNAL
+#define RWopsFromPython \
+ (*(SDL_RWops*(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 0])
+#define RWopsCheckPython \
+ (*(int(*)(SDL_RWops*))PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 1])
+#define RWopsFromPythonThreaded \
+ (*(SDL_RWops*(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 2])
+#define RWopsCheckPythonThreaded \
+ (*(int(*)(SDL_RWops*))PyGAME_C_API[PYGAMEAPI_RWOBJECT_FIRSTSLOT + 3])
+#define import_pygame_rwobject() { \
+ PyObject *_module = PyImport_ImportModule("pygame.rwobject"); \
+ if (_module != NULL) { \
+ PyObject *_dict = PyModule_GetDict(_module); \
+ PyObject *_c_api = PyDict_GetItemString(_dict, \
+ PYGAMEAPI_LOCAL_ENTRY); \
+ if(PyCObject_Check(_c_api)) { \
+ int i; void** localptr = (void**)PyCObject_AsVoidPtr(_c_api); \
+ for(i = 0; i < PYGAMEAPI_RWOBJECT_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_RWOBJECT_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF(_module); \
+ } \
+ }
+#endif
+
+/* BufferProxy */
+typedef struct
+{
+ PyObject_HEAD
+ PyObject *dict; /* dict for subclassing */
+ PyObject *weakrefs; /* Weakrefs for subclassing */
+ void *buffer; /* Pointer to the buffer of the parent object. */
+ Py_ssize_t length; /* Length of the buffer. */
+ PyObject *parent; /* Parent object associated with this object. */
+ PyObject *lock; /* Lock object for the surface. */
+
+} PyBufferProxy;
+
+#define PYGAMEAPI_BUFFERPROXY_FIRSTSLOT \
+ (PYGAMEAPI_RWOBJECT_FIRSTSLOT + PYGAMEAPI_RWOBJECT_NUMSLOTS)
+#define PYGAMEAPI_BUFFERPROXY_NUMSLOTS 2
+#ifndef PYGAMEAPI_BUFFERPROXY_INTERNAL
+#define PyBufferProxy_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_BUFFERPROXY_FIRSTSLOT + 0])
+#define PyBufferProxy_New \
+ (*(PyObject*(*)(PyObject*, void*, Py_ssize_t, PyObject*)) \
+ PyGAME_C_API[PYGAMEAPI_BUFFERPROXY_FIRSTSLOT + 1])
+#define import_pygame_bufferproxy() \
+ { \
+ PyObject *_module = PyImport_ImportModule ("pygame.bufferproxy");\
+ if (_module != NULL) \
+ { \
+ PyObject *_dict = PyModule_GetDict (_module); \
+ PyObject *_c_api = PyDict_GetItemString \
+ (_dict, PYGAMEAPI_LOCAL_ENTRY); \
+ if (PyCObject_Check (_c_api)) \
+ { \
+ int i; \
+ void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
+ for (i = 0; i < PYGAMEAPI_BUFFERPROXY_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_BUFFERPROXY_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF (_module); \
+ } \
+ }
+#endif /* PYGAMEAPI_BUFFERPROXY_INTERNAL */
+
+/* PixelArray */
+#define PYGAMEAPI_PIXELARRAY_FIRSTSLOT \
+ (PYGAMEAPI_BUFFERPROXY_FIRSTSLOT + PYGAMEAPI_BUFFERPROXY_NUMSLOTS)
+#define PYGAMEAPI_PIXELARRAY_NUMSLOTS 2
+#ifndef PYGAMEAPI_PIXELARRAY_INTERNAL
+#define PyPixelArray_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_PIXELARRAY_FIRSTSLOT + 0])
+#define PyPixelArray_New \
+ (*(PyObject*(*)) PyGAME_C_API[PYGAMEAPI_PIXELARRAY_FIRSTSLOT + 1])
+#define import_pygame_pixelarray() \
+ { \
+ PyObject *_module = PyImport_ImportModule ("pygame.pixelarray"); \
+ if (_module != NULL) \
+ { \
+ PyObject *_dict = PyModule_GetDict (_module); \
+ PyObject *_c_api = PyDict_GetItemString \
+ (_dict, PYGAMEAPI_LOCAL_ENTRY); \
+ if (PyCObject_Check (_c_api)) \
+ { \
+ int i; \
+ void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
+ for (i = 0; i < PYGAMEAPI_PIXELARRAY_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_PIXELARRAY_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF (_module); \
+ } \
+ }
+#endif /* PYGAMEAPI_PIXELARRAY_INTERNAL */
+
+/* Color */
+#define PYGAMEAPI_COLOR_FIRSTSLOT \
+ (PYGAMEAPI_PIXELARRAY_FIRSTSLOT + PYGAMEAPI_PIXELARRAY_NUMSLOTS)
+#define PYGAMEAPI_COLOR_NUMSLOTS 3
+#ifndef PYGAMEAPI_COLOR_INTERNAL
+#define PyColor_Check(x) \
+ ((x)->ob_type == (PyTypeObject*) \
+ PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 0])
+#define PyColor_New \
+ (*(PyObject*(*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 1])
+#define RGBAFromColorObj \
+ (*(int(*)(PyObject*, Uint8*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 2])
+#define import_pygame_color() \
+ { \
+ PyObject *_module = PyImport_ImportModule ("pygame.color"); \
+ if (_module != NULL) \
+ { \
+ PyObject *_dict = PyModule_GetDict (_module); \
+ PyObject *_c_api = PyDict_GetItemString \
+ (_dict, PYGAMEAPI_LOCAL_ENTRY); \
+ if (PyCObject_Check (_c_api)) \
+ { \
+ int i; \
+ void** localptr = (void**) PyCObject_AsVoidPtr (_c_api); \
+ for (i = 0; i < PYGAMEAPI_COLOR_NUMSLOTS; ++i) \
+ PyGAME_C_API[i + PYGAMEAPI_COLOR_FIRSTSLOT] = \
+ localptr[i]; \
+ } \
+ Py_DECREF (_module); \
+ } \
+ }
+#endif /* PYGAMEAPI_COLOR_INTERNAL */
+
+#ifndef NO_PYGAME_C_API
+#define PYGAMEAPI_TOTALSLOTS \
+ (PYGAMEAPI_COLOR_FIRSTSLOT + PYGAMEAPI_COLOR_NUMSLOTS)
+static void* PyGAME_C_API[PYGAMEAPI_TOTALSLOTS] = { NULL };
+#endif
+
+/*last platform compiler stuff*/
+#if defined(macintosh) && defined(__MWERKS__)
+#define PYGAME_EXPORT __declspec(export)
+#else
+#define PYGAME_EXPORT
+#endif
+
+#endif /* PYGAME_H */
diff --git a/pygame/pygamedocs.h b/pygame/pygamedocs.h
new file mode 100755
index 0000000..cd53f50
--- /dev/null
+++ b/pygame/pygamedocs.h
@@ -0,0 +1,925 @@
+/* Auto generated file: with makeref.py . Docs go in src/ *.doc . */
+#define DOC_PYGAME "the top level pygame package"
+
+#define DOC_PYGAMEINIT "pygame.init(): return (numpass, numfail)\ninitialize all imported pygame modules"
+
+#define DOC_PYGAMEQUIT "pygame.quit(): return None\nuninitialize all pygame modules"
+
+#define DOC_PYGAMEERROR "raise pygame.error, message\nstandard pygame exception"
+
+#define DOC_PYGAMEGETERROR "pygame.get_error(): return errorstr\nget the current error message"
+
+#define DOC_PYGAMEGETSDLVERSION "pygame.get_sdl_version(): return major, minor, patch\nget the version number of SDL"
+
+#define DOC_PYGAMEGETSDLBYTEORDER "pygame.get_sdl_byteorder(): return int\nget the byte order of SDL"
+
+#define DOC_PYGAMEREGISTERQUIT "register_quit(callable): return None\nregister a function to be called when pygame quits"
+
+#define DOC_PYGAMEVERSION "module pygame.version\nsmall module containing version information"
+
+#define DOC_PYGAMEVERSIONVER "pygame.version.ver = '1.2'\nversion number as a string"
+
+#define DOC_PYGAMEVERSIONVERNUM "pygame.version.vernum = (1, 5, 3)\ntupled integers of the version"
+
+#define DOC_PYGAMECAMERA "pygame module for camera use"
+
+#define DOC_PYGAMECAMERACOLORSPACE "pygame.camera.colorspace(Surface, format, DestSurface = None): return Surface\nSurface colorspace conversion"
+
+#define DOC_PYGAMECAMERALISTCAMERAS "pygame.camera.list_cameras(): return [cameras]\nreturns a list of available cameras"
+
+#define DOC_PYGAMECAMERACAMERA "pygame.camera.Camera(device, (width, height), format): return Camera\nload a camera"
+
+#define DOC_CAMERASTART "Camera.start(): return None\nopens, initializes, and starts capturing"
+
+#define DOC_CAMERASTOP "Camera.stop(): return None\nstops, uninitializes, and closes the camera"
+
+#define DOC_CAMERAGETCONTROLS "Camera.get_controls(): return (hflip = bool, vflip = bool)\ngets current values of user controls"
+
+#define DOC_CAMERASETCONTROLS "Camera.set_controls(hflip = bool, vflip = bool): return (hflip = bool, vflip = bool)\nchanges camera settings if supported by the camera"
+
+#define DOC_CAMERAGETSIZE "Camera.get_size(): return (width, height)\nreturns the dimensions of the images being recorded"
+
+#define DOC_CAMERAQUERYIMAGE "Camera.query_image(): return bool\nchecks if a frame is ready"
+
+#define DOC_CAMERAGETIMAGE "Camera.get_image(Surface = None): return Surface\ncaptures an image as a Surface"
+
+#define DOC_CAMERAGETRAW "Camera.get_raw(): return string\nreturns an unmodified image as a string"
+
+#define DOC_PYGAMECDROM "pygame module for audio cdrom control"
+
+#define DOC_PYGAMECDROMINIT "pygame.cdrom.init(): return None\ninitialize the cdrom module"
+
+#define DOC_PYGAMECDROMQUIT "pygame.cdrom.quit(): return None\nuninitialize the cdrom module"
+
+#define DOC_PYGAMECDROMGETINIT "pygame.cdrom.get_init(): return bool\ntrue if the cdrom module is initialized"
+
+#define DOC_PYGAMECDROMGETCOUNT "pygame.cdrom.get_count(): return count\nnumber of cd drives on the system"
+
+#define DOC_PYGAMECDROMCD "pygame.cdrom.CD(id): return CD\nclass to manage a cdrom drive"
+
+#define DOC_CDINIT "CD.init(): return None\ninitialize a cdrom drive for use"
+
+#define DOC_CDQUIT "CD.quit(): return None\nuninitialize a cdrom drive for use"
+
+#define DOC_CDGETINIT "CD.get_init(): return bool\ntrue if this cd device initialized"
+
+#define DOC_CDPLAY "CD.play(track, start=None, end=None): return None\nstart playing audio"
+
+#define DOC_CDSTOP "CD.stop(): return None\nstop audio playback"
+
+#define DOC_CDPAUSE "CD.pause(): return None\ntemporarily stop audio playback"
+
+#define DOC_CDRESUME "CD.resume(): return None\nunpause audio playback"
+
+#define DOC_CDEJECT "CD.eject(): return None\neject or open the cdrom drive"
+
+#define DOC_CDGETID "CD.get_id(): return id\nthe index of the cdrom drive"
+
+#define DOC_CDGETNAME "CD.get_name(): return name\nthe system name of the cdrom drive"
+
+#define DOC_CDGETBUSY "CD.get_busy(): return bool\ntrue if the drive is playing audio"
+
+#define DOC_CDGETPAUSED "CD.get_paused(): return bool\ntrue if the drive is paused"
+
+#define DOC_CDGETCURRENT "CD.get_current(): return track, seconds\nthe current audio playback position"
+
+#define DOC_CDGETEMPTY "CD.get_empty(): return bool\nFalse if a cdrom is in the drive"
+
+#define DOC_CDGETNUMTRACKS "CD.get_numtracks(): return count\nthe number of tracks on the cdrom"
+
+#define DOC_CDGETTRACKAUDIO "CD.get_track_audio(track): return bool\ntrue if the cdrom track has audio data"
+
+#define DOC_CDGETALL "CD.get_all(): return [(audio, start, end, lenth), ...]\nget all track information"
+
+#define DOC_CDGETTRACKSTART "CD.get_track_start(track): return seconds\nstart time of a cdrom track"
+
+#define DOC_CDGETTRACKLENGTH "CD.get_track_length(track): return seconds\nlength of a cdrom track"
+
+#define DOC_PYGAMECOLOR "pygame.Color(name): Return Color\npygame.Color(r, g, b, a): Return Color\npygame.Color(rgbvalue): Return Color\npygame object for color representations"
+
+#define DOC_COLORR "Color.r: Return int\nGets or sets the red value of the Color."
+
+#define DOC_COLORG "Color.g: Return int\nGets or sets the green value of the Color."
+
+#define DOC_COLORB "Color.b: Return int\nGets or sets the blue value of the Color."
+
+#define DOC_COLORA "Color.a: Return int\nGets or sets the alpha value of the Color."
+
+#define DOC_COLORCMY "Color.cmy: Return tuple\nGets or sets the CMY representation of the Color."
+
+#define DOC_COLORHSVA "Color.hsva: Return tuple\nGets or sets the HSVA representation of the Color."
+
+#define DOC_COLORHSLA "Color.hsla: Return tuple\nGets or sets the HSLA representation of the Color."
+
+#define DOC_COLORI1I2I3 "Color.i1i2i3: Return tuple\nGets or sets the I1I2I3 representation of the Color."
+
+#define DOC_COLORNORMALIZE "Color.normalize(): Return tuple\nReturns the normalized RGBA values of the Color."
+
+#define DOC_COLORCORRECTGAMMA "Color.correct_gamma (gamma): Return Color\nApplies a certain gamma value to the Color."
+
+#define DOC_PYGAMECURSORS "pygame module for cursor resources"
+
+#define DOC_PYGAMECURSORSCOMPILE "pygame.cursor.compile(strings, black='X', white='.', xor='o'): return data, mask\ncreate binary cursor data from simple strings"
+
+#define DOC_PYGAMECURSORSLOADXBM "pygame.cursors.load_xbm(cursorfile, maskfile=None): return cursor_args\nload cursor data from an xbm file"
+
+#define DOC_PYGAMEDISPLAY "pygame module to control the display window and screen"
+
+#define DOC_PYGAMEDISPLAYINIT "pygame.display.init(): return None\ninitialize the display module"
+
+#define DOC_PYGAMEDISPLAYQUIT "pygame.display.quit(): return None\nuninitialize the display module"
+
+#define DOC_PYGAMEDISPLAYGETINIT "pygame.display.get_init(): return bool\ntrue if the display module is initialized"
+
+#define DOC_PYGAMEDISPLAYSETMODE "pygame.display.set_mode(resolution=(0,0), flags=0, depth=0): return Surface\ninitialize a window or screen for display"
+
+#define DOC_PYGAMEDISPLAYGETSURFACE "pygame.display.get_surface(): return Surface\nget a reference to the currently set display surface"
+
+#define DOC_PYGAMEDISPLAYFLIP "pygame.display.flip(): return None\nupdate the full display Surface to the screen"
+
+#define DOC_PYGAMEDISPLAYUPDATE "pygame.display.update(rectangle=None): return None\npygame.display.update(rectangle_list): return None\nupdate portions of the screen for software displays"
+
+#define DOC_PYGAMEDISPLAYGETDRIVER "pygame.display.get_driver(): return name\nget the name of the pygame display backend"
+
+#define DOC_PYGAMEDISPLAYINFO "pygame.display.Info(): return VideoInfo\nCreate a video display information object"
+
+#define DOC_PYGAMEDISPLAYGETWMINFO "pygame.display.get_wm_info(): return dict\nGet information about the current windowing system"
+
+#define DOC_PYGAMEDISPLAYLISTMODES "pygame.display.list_modes(depth=0, flags=pygame.FULLSCREEN): return list\nget list of available fullscreen modes"
+
+#define DOC_PYGAMEDISPLAYMODEOK "pygame.display.mode_ok(size, flags=0, depth=0): return depth\npick the best color depth for a display mode"
+
+#define DOC_PYGAMEDISPLAYGLGETATTRIBUTE "pygame.display.gl_get_attribute(flag): return value\nget the value for an opengl flag for the current display"
+
+#define DOC_PYGAMEDISPLAYGLSETATTRIBUTE "pygame.display.gl_set_attribute(flag, value): return None\nrequest an opengl display attribute for the display mode"
+
+#define DOC_PYGAMEDISPLAYGETACTIVE "pygame.display.get_active(): return bool\ntrue when the display is active on the display"
+
+#define DOC_PYGAMEDISPLAYICONIFY "pygame.display.iconify(): return bool\niconify the display surface"
+
+#define DOC_PYGAMEDISPLAYTOGGLEFULLSCREEN "pygame.display.toggle_fullscreen(): return bool\nswitch between fullscreen and windowed displays"
+
+#define DOC_PYGAMEDISPLAYSETGAMMA "pygame.display.set_gamma(red, green=None, blue=None): return bool\nchange the hardware gamma ramps"
+
+#define DOC_PYGAMEDISPLAYSETGAMMARAMP "change the hardware gamma ramps with a custom lookup\npygame.display.set_gamma_ramp(red, green, blue): return bool\nset_gamma_ramp(red, green, blue): return bool"
+
+#define DOC_PYGAMEDISPLAYSETICON "pygame.display.set_icon(Surface): return None\nchange the system image for the display window"
+
+#define DOC_PYGAMEDISPLAYSETCAPTION "pygame.display.set_caption(title, icontitle=None): return None\nset the current window caption"
+
+#define DOC_PYGAMEDISPLAYGETCAPTION "pygame.display.get_caption(): return (title, icontitle)\nget the current window caption"
+
+#define DOC_PYGAMEDISPLAYSETPALETTE "pygame.display.set_palette(palette=None): return None\nset the display color palette for indexed displays"
+
+#define DOC_PYGAMEDRAW "pygame module for drawing shapes"
+
+#define DOC_PYGAMEDRAWRECT "pygame.draw.rect(Surface, color, Rect, width=0): return Rect\ndraw a rectangle shape"
+
+#define DOC_PYGAMEDRAWPOLYGON "pygame.draw.polygon(Surface, color, pointlist, width=0): return Rect\ndraw a shape with any number of sides"
+
+#define DOC_PYGAMEDRAWCIRCLE "pygame.draw.circle(Surface, color, pos, radius, width=0): return Rect\ndraw a circle around a point"
+
+#define DOC_PYGAMEDRAWELLIPSE "pygame.draw.ellipse(Surface, color, Rect, width=0): return Rect\ndraw a round shape inside a rectangle"
+
+#define DOC_PYGAMEDRAWARC "pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1): return Rect\ndraw a partial section of an ellipse"
+
+#define DOC_PYGAMEDRAWLINE "pygame.draw.line(Surface, color, start_pos, end_pos, width=1): return Rect\ndraw a straight line segment"
+
+#define DOC_PYGAMEDRAWLINES "pygame.draw.lines(Surface, color, closed, pointlist, width=1): return Rect\ndraw multiple contiguous line segments"
+
+#define DOC_PYGAMEDRAWAALINE "pygame.draw.aaline(Surface, color, startpos, endpos, blend=1): return Rect\ndraw fine antialiased lines"
+
+#define DOC_PYGAMEDRAWAALINES "pygame.draw.aalines(Surface, color, closed, pointlist, blend=1): return Rect"
+
+#define DOC_PYGAMEEVENT "pygame module for interacting with events and queues"
+
+#define DOC_PYGAMEEVENTPUMP "pygame.event.pump(): return None\ninternally process pygame event handlers"
+
+#define DOC_PYGAMEEVENTGET "pygame.event.get(): return Eventlist\npygame.event.get(type): return Eventlist\npygame.event.get(typelist): return Eventlist\nget events from the queue"
+
+#define DOC_PYGAMEEVENTPOLL "pygame.event.poll(): return Event\nget a single event from the queue"
+
+#define DOC_PYGAMEEVENTWAIT "pygame.event.wait(): return Event\nwait for a single event from the queue"
+
+#define DOC_PYGAMEEVENTPEEK "pygame.event.peek(type): return bool\npygame.event.peek(typelist): return bool\ntest if event types are waiting on the queue"
+
+#define DOC_PYGAMEEVENTCLEAR "pygame.event.clear(): return None\npygame.event.clear(type): return None\npygame.event.clear(typelist): return None\nremove all events from the queue"
+
+#define DOC_PYGAMEEVENTEVENTNAME "pygame.event.event_name(type): return string\nget the string name from and event id"
+
+#define DOC_PYGAMEEVENTSETBLOCKED "pygame.event.set_blocked(type): return None\npygame.event.set_blocked(typelist): return None\npygame.event.set_blocked(None): return None\ncontrol which events are allowed on the queue"
+
+#define DOC_PYGAMEEVENTSETALLOWED "pygame.event.set_allowed(type): return None\npygame.event.set_allowed(typelist): return None\npygame.event.set_allowed(None): return None\ncontrol which events are allowed on the queue"
+
+#define DOC_PYGAMEEVENTGETBLOCKED "pygame.event.get_blocked(type): return bool\ntest if a type of event is blocked from the queue"
+
+#define DOC_PYGAMEEVENTSETGRAB "pygame.event.set_grab(bool): return None\ncontrol the sharing of input devices with other applications"
+
+#define DOC_PYGAMEEVENTGETGRAB "pygame.event.get_grab(): return bool\ntest if the program is sharing input devices"
+
+#define DOC_PYGAMEEVENTPOST "pygame.event.post(Event): return None\nplace a new event on the queue"
+
+#define DOC_PYGAMEEVENTEVENT "pygame.event.Event(type, dict): return Event\npygame.event.Event(type, **attributes): return Event\ncreate a new event object"
+
+#define DOC_PYGAMEFONT "pygame module for loading and rendering fonts"
+
+#define DOC_PYGAMEFONTINIT "pygame.font.init(): return None\ninitialize the font module"
+
+#define DOC_PYGAMEFONTQUIT "pygame.font.quit(): return None\nuninitialize the font module"
+
+#define DOC_PYGAMEFONTGETINIT "pygame.font.get_init(): return bool\ntrue if the font module is initialized"
+
+#define DOC_PYGAMEFONTGETDEFAULTFONT "pygame.font.get_default_font(): return string\nget the filename of the default font"
+
+#define DOC_PYGAMEFONTGETFONTS "pygame.font.get_fonts(): return list of strings\nget all available fonts"
+
+#define DOC_PYGAMEFONTMATCHFONT "pygame.font.match_font(name, bold=False, italic=False): return path\nfind a specific font on the system"
+
+#define DOC_PYGAMEFONTSYSFONT "pygame.font.SysFont(name, size, bold=False, italic=False): return Font\ncreate a Font object from the system fonts"
+
+#define DOC_PYGAMEFONTFONT "pygame.font.Font(filename, size): return Font\npygame.font.Font(object, size): return Font\ncreate a new Font object from a file"
+
+#define DOC_FONTRENDER "Font.render(text, antialias, color, background=None): return Surface\ndraw text on a new Surface"
+
+#define DOC_FONTSIZE "Font.size(text): return (width, height)\ndetermine the amount of space needed to render text"
+
+#define DOC_FONTSETUNDERLINE "Font.set_underline(bool): return None\ncontrol if text is rendered with an underline"
+
+#define DOC_FONTGETUNDERLINE "Font.get_underline(): return bool\ncheck if text will be rendered with an underline"
+
+#define DOC_FONTSETBOLD "Font.set_bold(bool): return None\nenable fake rendering of bold text"
+
+#define DOC_FONTGETBOLD "Font.get_bold(): return bool\ncheck if text will be rendered bold"
+
+#define DOC_FONTSETITALIC "Font.set_bold(bool): return None\nenable fake rendering of italic text"
+
+#define DOC_FONTMETRICS "Font.metrics(text): return list\nGets the metrics for each character in the pased string."
+
+#define DOC_FONTGETITALIC "Font.get_italic(): return bool\ncheck if the text will be rendered italic"
+
+#define DOC_FONTGETLINESIZE "Font.get_linesize(): return int\nget the line space of the font text"
+
+#define DOC_FONTGETHEIGHT "Font.get_height(): return int\nget the height of the font"
+
+#define DOC_FONTGETASCENT "Font.get_ascent(): return int\nget the ascent of the font"
+
+#define DOC_FONTGETDESCENT "Font.get_descent(): return int\nget the descent of the font"
+
+#define DOC_PYGAMEIMAGE "pygame module for image transfer"
+
+#define DOC_PYGAMEIMAGELOAD "pygame.image.load(filename): return Surface\npygame.image.load(fileobj, namehint=""): return Surface\nload new image from a file"
+
+#define DOC_PYGAMEIMAGESAVE "pygame.image.save(Surface, filename): return None\nsave an image to disk"
+
+#define DOC_PYGAMEIMAGEGETEXTENDED "pygame.image.get_extended(): return bool\ntest if extended image formats can be loaded"
+
+#define DOC_PYGAMEIMAGETOSTRING "pygame.image.tostring(Surface, format, flipped=False): return string\ntransfer image to string buffer"
+
+#define DOC_PYGAMEIMAGEFROMSTRING "pygame.image.fromstring(string, size, format, flipped=False): return Surface\ncreate new Surface from a string buffer"
+
+#define DOC_PYGAMEIMAGEFROMBUFFER "pygame.image.frombuffer(string, size, format): return Surface\ncreate a new Surface that shares data inside a string buffer"
+
+#define DOC_PYGAMEJOYSTICK "pygame module for interacting with joystick devices"
+
+#define DOC_PYGAMEJOYSTICKINIT "pygame.joystick.init(): return None\ninitialize the joystick module"
+
+#define DOC_PYGAMEJOYSTICKQUIT "pygame.joystick.quit(): return None\nuninitialize the joystick module"
+
+#define DOC_PYGAMEJOYSTICKGETINIT "pygame.joystick.get_init(): return bool\ntrue if the joystick module is initialized"
+
+#define DOC_PYGAMEJOYSTICKGETCOUNT "pygame.joystick.get_count(): return count\nnumber of joysticks on the system"
+
+#define DOC_PYGAMEJOYSTICKJOYSTICK "pygame.joystick.Joystick(id): return Joystick\ncreate a new Joystick object"
+
+#define DOC_JOYSTICKINIT "Joystick.init(): return None\ninitialize the Joystick"
+
+#define DOC_JOYSTICKQUIT "Joystick.quit(): return None\nuninitialize the Joystick"
+
+#define DOC_JOYSTICKGETINIT "Joystick.get_init(): return bool\ncheck if the Joystick is initialized"
+
+#define DOC_JOYSTICKGETID "Joystick.get_id(): return int\nget the Joystick ID"
+
+#define DOC_JOYSTICKGETNAME "Joystick.get_name(): return string\nget the Joystick system name"
+
+#define DOC_JOYSTICKGETNUMAXES "Joystick.get_numaxes(): return int\nget the number of axes on a Joystick"
+
+#define DOC_JOYSTICKGETAXIS "Joystick.get_axis(axis_number): return float\nget the current position of an axis"
+
+#define DOC_JOYSTICKGETNUMBALLS "Joystick.get_numballs(): return int\nget the number of trackballs on a Joystick"
+
+#define DOC_JOYSTICKGETBALL "Joystick.get_ball(ball_number): return x, y\nget the relative position of a trackball"
+
+#define DOC_JOYSTICKGETNUMBUTTONS "Joystick.get_numbuttons(): return int\nget the number of buttons on a Joystick"
+
+#define DOC_JOYSTICKGETBUTTON "Joystick.get_button(button): return bool\nget the current button state"
+
+#define DOC_JOYSTICKGETNUMHATS "Joystick.get_numhats(): return int\nget the number of hat controls on a Joystick"
+
+#define DOC_JOYSTICKGETHAT "Joystick.get_hat(hat_number): return x, y\nget the position of a joystick hat"
+
+#define DOC_PYGAMEKEY "pygame module to work with the keyboard"
+
+#define DOC_PYGAMEKEYGETFOCUSED "pygame.key.get_focused(): return bool\ntrue if the display is receiving keyboard input from the system"
+
+#define DOC_PYGAMEKEYGETPRESSED "pygame.key.get_pressed(): return bools\nget the state of all keyboard buttons"
+
+#define DOC_PYGAMEKEYGETMODS "pygame.key.get_mods(): return int\ndetermine which modifier keys are being held"
+
+#define DOC_PYGAMEKEYSETMODS "pygame.key.set_mods(int): return None\ntemporarily set which modifier keys are pressed"
+
+#define DOC_PYGAMEKEYSETREPEAT "pygame.key.set_repeat(): return None\npygame.key.set_repeat(delay, interval): return None\ncontrol how held keys are repeated"
+
+#define DOC_PYGAMEKEYGETREPEAT "pygame.key.get_repeat(): return (delay, interval)\nsee how held keys are repeated"
+
+#define DOC_PYGAMEKEYNAME "pygame.key.name(key): return string\nget the name of a key identifier"
+
+#define DOC_PYGAMECONTANTS "Pygame constants"
+
+#define DOC_DISPLAY "The following constants are used by the display module and Surfaces"
+
+#define DOC_EVENTS "These constants define the various event types"
+
+#define DOC_KEYBOARD "These constants represent the keys on the keyboard."
+
+#define DOC_MODIFIERS "These constants represent the modifier keys on the keyboard."
+
+#define DOC_TIME "These constants define the various time constants"
+
+#define DOC_PYGAMEMASK "pygame module for image masks."
+
+#define DOC_PYGAMEMASKFROMSURFACE "pygame.mask.from_surface(Surface, threshold = 127) -> Mask\nReturns a Mask from the given surface."
+
+#define DOC_PYGAMEMASKFROMTHRESHOLD "pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None) -> Mask\nCreates a mask by thresholding Surfaces"
+
+#define DOC_PYGAMEMASKMASK "pygame.Mask((width, height)): return Mask\npygame object for representing 2d bitmasks"
+
+#define DOC_MASKGETSIZE "Mask.get_size() -> width,height\nReturns the size of the mask."
+
+#define DOC_MASKGETAT "Mask.get_at((x,y)) -> int\nReturns nonzero if the bit at (x,y) is set."
+
+#define DOC_MASKSETAT "Mask.set_at((x,y),value)\nSets the position in the mask given by x and y."
+
+#define DOC_MASKOVERLAP "Mask.overlap(othermask, offset) -> x,y\nReturns the point of intersection if the masks overlap with the given offset - or None if it does not overlap."
+
+#define DOC_MASKOVERLAPAREA "Mask.overlap_area(othermask, offset) -> numpixels\nReturns the number of overlapping 'pixels'."
+
+#define DOC_MASKOVERLAPMASK "Mask.overlap_mask(othermask, offset) -> Mask\nReturns a mask of the overlapping pixels"
+
+#define DOC_MASKFILL "Mask.fill()\nSets all bits to 1"
+
+#define DOC_MASKCLEAR "Mask.clear()\nSets all bits to 0"
+
+#define DOC_MASKINVERT "Mask.invert()\nFlips the bits in a Mask"
+
+#define DOC_MASKSCALE "Mask.scale((x, y)) -> Mask\nResizes a mask"
+
+#define DOC_MASKDRAW "Mask.draw(othermask, offset)\nDraws a mask onto another"
+
+#define DOC_MASKERASE "Mask.erase(othermask, offset)\nErases a mask from another"
+
+#define DOC_MASKCOUNT "Mask.count() -> pixels\nReturns the number of set pixels"
+
+#define DOC_MASKCENTROID "Mask.centroid() -> (x, y)\nReturns the centroid of the pixels in a Mask"
+
+#define DOC_MASKANGLE "Mask.angle() -> theta\nReturns the orientation of the pixels"
+
+#define DOC_MASKOUTLINE "Mask.outline(every = 1) -> [(x,y), (x,y) ...]\nlist of points outlining an object"
+
+#define DOC_MASKCONNECTEDCOMPONENT "Mask.connected_component((x,y) = None) -> Mask\nReturns a mask of a connected region of pixels."
+
+#define DOC_MASKCONNECTEDCOMPONENTS "Mask.connected_components(min = 0) -> [Masks]\nReturns a list of masks of connected regions of pixels."
+
+#define DOC_MASKGETBOUNDINGRECTS "Mask.get_bounding_rects() -> Rects\nReturns a list of bounding rects of regions of set pixels."
+
+#define DOC_PYGAMEMIXER "pygame module for loading and playing sounds"
+
+#define DOC_PYGAMEMIXERINIT "pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=3072): return None\ninitialize the mixer module"
+
+#define DOC_PYGAMEMIXERPREINIT "pygame.mixer.pre_init(frequency=0, size=0, channels=0, buffersize=0): return None\npreset the mixer init arguments"
+
+#define DOC_PYGAMEMIXERQUIT "pygame.mixer.quit(): return None\nuninitialize the mixer"
+
+#define DOC_PYGAMEMIXERGETINIT "pygame.mixer.get_init(): return (frequency, format, channels)\ntest if the mixer is initialized"
+
+#define DOC_PYGAMEMIXERSTOP "pygame.mixer.stop(): return None\nstop playback of all sound channels"
+
+#define DOC_PYGAMEMIXERPAUSE "pygame.mixer.pause(): return None\ntemporarily stop playback of all sound channels"
+
+#define DOC_PYGAMEMIXERUNPAUSE "pygame.mixer.unpause(): return None\nresume paused playback of sound channels"
+
+#define DOC_PYGAMEMIXERFADEOUT "pygame.mixer.fadeout(time): return None\nfade out the volume on all sounds before stopping"
+
+#define DOC_PYGAMEMIXERSETNUMCHANNELS "pygame.mixer.set_num_channels(count): return None\nset the total number of playback channels"
+
+#define DOC_PYGAMEMIXERGETNUMCHANNELS "get the total number of playback channels"
+
+#define DOC_PYGAMEMIXERSETRESERVED "pygame.mixer.set_reserved(count): return None\nreserve channels from being automatically used"
+
+#define DOC_PYGAMEMIXERFINDCHANNEL "pygame.mixer.find_channel(force=False): return Channel\nfind an unused channel"
+
+#define DOC_PYGAMEMIXERGETBUSY "pygame.mixer.get_busy(): return bool\ntest if any sound is being mixed"
+
+#define DOC_PYGAMEMIXERSOUND "pygame.mixer.Sound(filename): return Sound\npygame.mixer.Sound(buffer): return Sound\npygame.mixer.Sound(object): return Sound\nCreate a new Sound object from a file"
+
+#define DOC_SOUNDPLAY "Sound.play(loops=0, maxtime=0, fade_ms=0): return Channel\nbegin sound playback"
+
+#define DOC_SOUNDSTOP "Sound.stop(): return None\nstop sound playback"
+
+#define DOC_SOUNDFADEOUT "Sound.fadeout(time): return None\nstop sound playback after fading out"
+
+#define DOC_SOUNDSETVOLUME "Sound.set_volume(value): return None\nset the playback volume for this Sound"
+
+#define DOC_SOUNDGETVOLUME "Sound.get_volume(): return value\nget the playback volume"
+
+#define DOC_SOUNDGETNUMCHANNELS "Sound.get_num_channels(): return count\ncount how many times this Sound is playing"
+
+#define DOC_SOUNDGETLENGTH "Sound.get_length(): return seconds\nget the length of the Sound"
+
+#define DOC_SOUNDGETBUFFER "Sound.get_buffer(): return BufferProxy\nacquires a buffer object for the sameples of the Sound."
+
+#define DOC_PYGAMEMIXERCHANNEL "pygame.mixer.Channel(id): return Channel\nCreate a Channel object for controlling playback"
+
+#define DOC_CHANNELPLAY "Channel.play(Sound, loops=0, maxtime=0, fade_ms=0): return None\nplay a Sound on a specific Channel"
+
+#define DOC_CHANNELSTOP "Channel.stop(): return None\nstop playback on a Channel"
+
+#define DOC_CHANNELPAUSE "Channel.pause(): return None\ntemporarily stop playback of a channel"
+
+#define DOC_CHANNELUNPAUSE "Channel.unpause(): return None\nresume pause playback of a channel"
+
+#define DOC_CHANNELFADEOUT "Channel.fadeout(time): return None\nstop playback after fading channel out"
+
+#define DOC_CHANNELSETVOLUME "Channel.set_volume(value): return None\nChannel.set_volume(left, right): return None\nset the volume of a playing channel"
+
+#define DOC_CHANNELGETVOLUME "Channel.get_volume(): return value\nget the volume of the playing channel"
+
+#define DOC_CHANNELGETBUSY "Channel.get_busy(): return bool\ncheck if the channel is active"
+
+#define DOC_CHANNELGETSOUND "Channel.get_sound(): return Sound\nget the currently playing Sound"
+
+#define DOC_CHANNELQUEUE "Channel.queue(Sound): return None\nqueue a Sound object to follow the current"
+
+#define DOC_CHANNELGETQUEUE "Channel.get_queue(): return Sound\nreturn any Sound that is queued"
+
+#define DOC_CHANNELSETENDEVENT "Channel.set_endevent(): return None\nChannel.set_endevent(type): return None\nhave the channel send an event when playback stops"
+
+#define DOC_CHANNELGETENDEVENT "Channel.get_endevent(): return type\nget the event a channel sends when playback stops"
+
+#define DOC_PYGAMEMOUSE "pygame module to work with the mouse"
+
+#define DOC_PYGAMEMOUSEGETPRESSED "pygame.moouse.get_pressed(): return (button1, button2, button3)\nget the state of the mouse buttons"
+
+#define DOC_PYGAMEMOUSEGETPOS "pygame.mouse.get_pos(): return (x, y)\nget the mouse cursor position"
+
+#define DOC_PYGAMEMOUSEGETREL "pygame.mouse.get_rel(): return (x, y)\nget the amount of mouse movement"
+
+#define DOC_PYGAMEMOUSESETPOS "pygame.mouse.set_pos([x, y]): return None\nset the mouse cursor position"
+
+#define DOC_PYGAMEMOUSESETVISIBLE "pygame.mouse.set_visible(bool): return bool\nhide or show the mouse cursor"
+
+#define DOC_PYGAMEMOUSEGETFOCUSED "pygame.mouse.get_focused(): return bool\ncheck if the display is receiving mouse input"
+
+#define DOC_PYGAMEMOUSESETCURSOR "pygame.mouse.set_cursor(size, hotspot, xormasks, andmasks): return None\nset the image for the system mouse cursor"
+
+#define DOC_PYGAMEMOUSEGETCURSOR "pygame.mouse.get_cursor(): return (size, hotspot, xormasks, andmasks)\nget the image for the system mouse cursor"
+
+#define DOC_PYGAMEMOVIE "pygame module for playback of mpeg video"
+
+#define DOC_PYGAMEMOVIEMOVIE "pygame.movie.Movie(filename): return Movie\npygame.movie.Movie(object): return Movie\nload an mpeg movie file"
+
+#define DOC_MOVIEPLAY "Movie.play(loops=0): return None\nstart playback of a movie"
+
+#define DOC_MOVIESTOP "Movie.stop(): return None\nstop movie playback"
+
+#define DOC_MOVIEPAUSE "Movie.pause(): return None\ntemporarily stop and resume playback"
+
+#define DOC_MOVIESKIP "Movie.skip(seconds): return None\nadvance the movie playback position"
+
+#define DOC_MOVIEREWIND "Movie.rewind(): return None\nrestart the movie playback"
+
+#define DOC_MOVIERENDERFRAME "Movie.render_frame(frame_number): return frame_number\nset the current video frame"
+
+#define DOC_MOVIEGETFRAME "Movie.get_frame(): return frame_number\nget the current video frame"
+
+#define DOC_MOVIEGETTIME "Movie.get_time(): return seconds\nget the current vide playback time"
+
+#define DOC_MOVIEGETBUSY "Movie.get_busy(): return bool\ncheck if the movie is currently playing"
+
+#define DOC_MOVIEGETLENGTH "Movie.get_length(): return seconds\nthe total length of the movie in seconds"
+
+#define DOC_MOVIEGETSIZE "Movie.get_size(): return (width, height)\nget the resolution of the video"
+
+#define DOC_MOVIEHASVIDEO "Movie.get_video(): return bool\ncheck if the movie file contains video"
+
+#define DOC_MOVIEHASAUDIO "Movie.get_audio(): return bool\ncheck if the movie file contains audio"
+
+#define DOC_MOVIESETVOLUME "Movie.set_volume(value): return None\nset the audio playback volume"
+
+#define DOC_MOVIESETDISPLAY "Movie.set_display(Surface, rect=None): return None\nset the video target Surface"
+
+#define DOC_PYGAMEMIXERMUSIC "pygame module for controlling streamed audio"
+
+#define DOC_PYGAMEMIXERMUSICLOAD "pygame.mixer.music.load(filename): return None\nLoad a music file for playback"
+
+#define DOC_PYGAMEMIXERMUSICPLAY "pygame.mixer.music.play(loops=0, start=0.0): return None\nStart the playback of the music stream"
+
+#define DOC_PYGAMEMIXERMUSICREWIND "pygame.mixer.music.rewind(): return None\nrestart music"
+
+#define DOC_PYGAMEMIXERMUSICSTOP "pygame.mixer.music.stop(): return None\nstop the music playback"
+
+#define DOC_PYGAMEMIXERMUSICPAUSE "pygame.mixer.music.pause(): return None\ntemporarily stop music playback"
+
+#define DOC_PYGAMEMIXERMUSICUNPAUSE "pygame.mixer.music.unpause(): return None\nresume paused music"
+
+#define DOC_PYGAMEMIXERMUSICFADEOUT "pygame.mixer.music.fadeout(time): return None\nstop music playback after fading out"
+
+#define DOC_PYGAMEMIXERMUSICSETVOLUME "pygame.mixer.music.set_volume(value): return None\nset the music volume"
+
+#define DOC_PYGAMEMIXERMUSICGETVOLUME "pygame.mixer.music.get_volume(): return value\nget the music volume"
+
+#define DOC_PYGAMEMIXERMUSICGETBUSY "pygame.mixer.music.get_busy(): return bool\ncheck if the music stream is playing"
+
+#define DOC_PYGAMEMIXERMUSICGETPOS "pygame.mixer.music.get_pos(): return time\nget the music play time"
+
+#define DOC_PYGAMEMIXERMUSICQUEUE "pygame.mixer.music.queue(filename): return None\nqueue a music file to follow the current"
+
+#define DOC_PYGAMEMIXERMUSICSETENDEVENT "pygame.mixer.music.set_endevent(): return None\npygame.mixer.music.set_endevent(type): return None\nhave the music send an event when playback stops"
+
+#define DOC_PYGAMEMIXERMUSICGETENDEVENT "pygame.mixer.music.get_endevent(): return type\nget the event a channel sends when playback stops"
+
+#define DOC_PYGAMEOVERLAY "pygame.Overlay(format, (width, height)): return Overlay\npygame object for video overlay graphics"
+
+#define DOC_OVERLAYDISPLAY "Overlay.display((y, u, v)): return None\nOverlay.display(): return None\nset the overlay pixel data"
+
+#define DOC_OVERLAYSETLOCATION "Overlay.set_location(rect): return None\ncontrol where the overlay is displayed"
+
+#define DOC_OVERLAYGETHARDWARE "Overlay.get_hardware(rect): return int\ntest if the Overlay is hardware accelerated"
+
+#define DOC_PYGAMEPIXELARRAY "pygame.PixelArray(Surface): return PixelArray\npygame object for direct pixel access of surfaces"
+
+#define DOC_PIXELARRAYSURFACE "PixelArray.surface: Return Surface\nGets the Surface the PixelArray uses."
+
+#define DOC_PIXELARRAYMAKESURFACE "PixelArray.make_surface (): Return Surface\nCreates a new Surface from the current PixelArray."
+
+#define DOC_PIXELARRAYREPLACE "PixelArray.replace (color, repcolor, distance=0, weights=(0.299, 0.587, 0.114)): Return None\nReplaces the passed color in the PixelArray with another one."
+
+#define DOC_PIXELARRAYEXTRACT "PixelArray.extract (color, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray\nExtracts the passed color from the PixelArray."
+
+#define DOC_PIXELARRAYCOMPARE "PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray\nCompares the PixelArray with another one."
+
+#define DOC_PYGAMERECT "pygame.Rect(left, top, width, height): return Rect\npygame.Rect((left, top), (width, height)): return Rect\npygame.Rect(object): return Rect\npygame object for storing rectangular coordinates"
+
+#define DOC_RECTMOVE "Rect.move(x, y): return Rect\nmoves the rectangle"
+
+#define DOC_RECTMOVEIP "Rect.move_ip(x, y): return None\nmoves the rectangle, in place"
+
+#define DOC_RECTINFLATE "Rect.inflate(x, y): return Rect\ngrow or shrink the rectangle size"
+
+#define DOC_RECTINFLATEIP "Rect.inflate_ip(x, y): return None\ngrow or shrink the rectangle size, in place"
+
+#define DOC_RECTCLAMP "Rect.clamp(Rect): return Rect\nmoves the rectangle inside another"
+
+#define DOC_RECTCLAMPIP "Rect.clamp_ip(Rect): return None\nmoves the rectangle inside another, in place"
+
+#define DOC_RECTCLIP "Rect.clip(Rect): return Rect\ncrops a rectangle inside another"
+
+#define DOC_RECTUNION "Rect.union(Rect): return Rect\njoins two rectangles into one"
+
+#define DOC_RECTUNIONIP "Rect.union_ip(Rect): return None\njoins two rectangles into one, in place"
+
+#define DOC_RECTUNIONALL "Rect.unionall(Rect_sequence): return Rect\nthe union of many rectangles"
+
+#define DOC_RECTUNIONALLIP "Rect.unionall_ip(Rect_sequence): return None\nthe union of many rectangles, in place"
+
+#define DOC_RECTFIT "Rect.fit(Rect): return Rect\nresize and move a rectangle with aspect ratio"
+
+#define DOC_RECTNORMALIZE "Rect.normalize(): return None\ncorrect negative sizes"
+
+#define DOC_RECTCONTAINS "Rect.contains(Rect): return bool\ntest if one rectangle is inside another"
+
+#define DOC_RECTCOLLIDEPOINT "Rect.collidepoint(x, y): return bool\nRect.collidepoint((x,y)): return bool\ntest if a point is inside a rectangle"
+
+#define DOC_RECTCOLLIDERECT "Rect.colliderect(Rect): return bool\ntest if two rectangles overlap"
+
+#define DOC_RECTCOLLIDELIST "Rect.collidelist(list): return index\ntest if one rectangle in a list intersects"
+
+#define DOC_RECTCOLLIDELISTALL "Rect.collidelistall(list): return indices\ntest if all rectangles in a list intersect"
+
+#define DOC_RECTCOLLIDEDICT "Rect.collidedict(dict): return (key, value)\ntest if one rectangle in a dictionary intersects"
+
+#define DOC_RECTCOLLIDEDICTALL "Rect.collidedictall(dict): return [(key, value), ...]\ntest if all rectangles in a dictionary intersect"
+
+#define DOC_PYGAMESCRAP "pygame module for clipboard support."
+
+#define DOC_PYGAMESCRAPINIT "scrap.init () -> None\nInitializes the scrap module."
+
+#define DOC_PYGAMESCRAPGET "scrap.get (type) -> string\nGets the data for the specified type from the clipboard."
+
+#define DOC_PYGAMESCRAPGETTYPES "scrap.get_types () -> list\nGets a list of the available clipboard types."
+
+#define DOC_PYGAMESCRAPPUT "scrap.put(type, data) -> None\nPlaces data into the clipboard."
+
+#define DOC_PYGAMESCRAPCONTAINS "scrap.contains (type) -> bool\nChecks, whether a certain type is available in the clipboard."
+
+#define DOC_PYGAMESCRAPLOST "scrap.lost() -> bool\nChecks whether the clipboard is currently owned by the application."
+
+#define DOC_PYGAMESCRAPSETMODE "scrap.set_mode(mode) -> None\nSets the clipboard access mode."
+
+#define DOC_PYGAMESNDARRAY "pygame module for accessing sound sample data"
+
+#define DOC_PYGAMESNDARRAYARRAY "pygame.sndarray.array(Sound): return array\ncopy Sound samples into an array"
+
+#define DOC_PYGAMESNDARRAYSAMPLES "pygame.sndarray.samples(Sound): return array\nreference Sound samples into an array"
+
+#define DOC_PYGAMESNDARRAYMAKESOUND "pygame.sndarray.make_sound(array): return Sound\nconvert an array into a Sound object"
+
+#define DOC_PYGAMESNDARRAYUSEARRAYTYPE "pygame.sndarray.use_arraytype (arraytype): return None\nSets the array system to be used for sound arrays"
+
+#define DOC_PYGAMESNDARRAYGETARRAYTYPE "pygame.sndarray.get_arraytype (): return str\nGets the currently active array type."
+
+#define DOC_PYGAMESNDARRAYGETARRAYTYPES "pygame.sndarray.get_arraytypes (): return tuple\nGets the array system types currently supported."
+
+#define DOC_PYGAMESPRITE "pygame module with basic game object classes"
+
+#define DOC_PYGAMESPRITESPRITE "pygame.sprite.Sprite(*groups): return Sprite\nsimple base class for visible game objects"
+
+#define DOC_SPRITEUPDATE "Sprite.update(*args):\nmethod to control sprite behavior"
+
+#define DOC_SPRITEADD "Sprite.add(*groups): return None\nadd the sprite to groups"
+
+#define DOC_SPRITEREMOVE "Sprite.remove(*groups): return None\nremove the sprite from groups"
+
+#define DOC_SPRITEKILL "Sprite.kill(): return None\nremove the Sprite from all Groups"
+
+#define DOC_SPRITEALIVE "Sprite.alive(): return bool\ndoes the sprite belong to any groups"
+
+#define DOC_SPRITEGROUPS "Sprite.groups(): return group_list\nlist of Groups that contain this Sprite"
+
+#define DOC_PYGAMESPRITEDIRTYSPRITE "pygame.sprite.DirtySprite(*groups): return DirtySprite\na more featureful subclass of Sprite with more attributes"
+
+#define DOC_ ""
+
+#define DOC_PYGAMESPRITEGROUP "pygame.sprite.Group(*sprites): return Group\ncontainer class for many Sprites"
+
+#define DOC_GROUPSPRITES "Group.sprites(): return sprite_list\nlist of the Sprites this Group contains"
+
+#define DOC_GROUPCOPY "Group.copy(): return Group\nduplicate the Group"
+
+#define DOC_GROUPADD "Group.add(*sprites): return None\nadd Sprites to this Group"
+
+#define DOC_GROUPREMOVE "Group.remove(*sprites): return None\nremove Sprites from the Group"
+
+#define DOC_GROUPHAS "Group.has(*sprites): return None\ntest if a Group contains Sprites"
+
+#define DOC_GROUPUPDATE "Group.update(*args): return None\ncall the update method on contained Sprites"
+
+#define DOC_GROUPDRAW "Group.draw(Surface): return None\nblit the Sprite images"
+
+#define DOC_GROUPCLEAR "Group.clear(Surface_dest, background): return None\ndraw a background over the Sprites"
+
+#define DOC_GROUPEMPTY "Group.empty(): return None\nremove all Sprites"
+
+#define DOC_PYGAMESPRITERENDERUPDATES "pygame.sprite.RenderUpdates(*sprites): return RenderUpdates\nGroup class that tracks dirty updates"
+
+#define DOC_RENDERUPDATESDRAW "RenderUpdates.draw(surface): return Rect_list\nblit the Sprite images and track changed areas"
+
+#define DOC_PYGAMESPRITEORDEREDUPDATES "pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates\nRenderUpdates class that draws Sprites in order of addition"
+
+#define DOC_PYGAMESPRITELAYEREDUPDATES "pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates\nLayeredUpdates Group handles layers, that draws like OrderedUpdates."
+
+#define DOC_LAYEREDUPDATESADD "LayeredUpdates.add(*sprites, **kwargs): return None\nadd a sprite or sequence of sprites to a group"
+
+#define DOC_LAYEREDUPDATESSPRITES "LayeredUpdates.sprites(): return sprites\nreturns a ordered list of sprites (first back, last top)."
+
+#define DOC_LAYEREDUPDATESDRAW "LayeredUpdates.draw(surface): return Rect_list\ndraw all sprites in the right order onto the passed surface."
+
+#define DOC_LAYEREDUPDATESGETSPRITESAT "LayeredUpdates.get_sprites_at(pos): return colliding_sprites\nreturns a list with all sprites at that position."
+
+#define DOC_LAYEREDUPDATESGETSPRITE "LayeredUpdates.get_sprite(idx): return sprite\nreturns the sprite at the index idx from the groups sprites"
+
+#define DOC_LAYEREDUPDATESREMOVESPRITESOFLAYER "LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites\nremoves all sprites from a layer and returns them as a list."
+
+#define DOC_LAYEREDUPDATESLAYERS "LayeredUpdates.layers(): return layers\nreturns a list of layers defined (unique), sorted from botton up."
+
+#define DOC_LAYEREDUPDATESCHANGELAYER "LayeredUpdates.change_layer(sprite, new_layer): return None\nchanges the layer of the sprite"
+
+#define DOC_LAYEREDUPDATESGETLAYEROFSPRITE "LayeredUpdates.get_layer_of_sprite(sprite): return layer\nreturns the layer that sprite is currently in."
+
+#define DOC_LAYEREDUPDATESGETTOPLAYER "LayeredUpdates.get_top_layer(): return layer\nreturns the top layer"
+
+#define DOC_LAYEREDUPDATESGETBOTTOMLAYER "LayeredUpdates.get_bottom_layer(): return layer\nreturns the bottom layer"
+
+#define DOC_LAYEREDUPDATESMOVETOFRONT "LayeredUpdates.move_to_front(sprite): return None\nbrings the sprite to front layer"
+
+#define DOC_LAYEREDUPDATESMOVETOBACK "LayeredUpdates.move_to_back(sprite): return None\nmoves the sprite to the bottom layer"
+
+#define DOC_LAYEREDUPDATESGETTOPSPRITE "LayeredUpdates.get_top_sprite(): return Sprite\nreturns the topmost sprite"
+
+#define DOC_LAYEREDUPDATESGETSPRITESFROMLAYER "LayeredUpdates.get_sprites_from_layer(layer): return sprites\nreturns all sprites from a layer, ordered by how they where added"
+
+#define DOC_LAYEREDUPDATESSWITCHLAYER "LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None\nswitches the sprites from layer1 to layer2"
+
+#define DOC_PYGAMESPRITELAYEREDDIRTY "pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty\nLayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates."
+
+#define DOC_LAYEREDDIRTYDRAW "LayeredDirty.draw(surface, bgd=None): return Rect_list\ndraw all sprites in the right order onto the passed surface."
+
+#define DOC_LAYEREDDIRTYCLEAR "LayeredDirty.clear(surface, bgd): return None\nused to set background"
+
+#define DOC_LAYEREDDIRTYREPAINTRECT "LayeredDirty.repaint_rect(screen_rect): return None\nrepaints the given area"
+
+#define DOC_LAYEREDDIRTYSETCLIP "LayeredDirty.set_clip(screen_rect=None): return None\nclip the area where to draw. Just pass None (default) to reset the clip"
+
+#define DOC_LAYEREDDIRTYGETCLIP "LayeredDirty.get_clip(): return Rect\nclip the area where to draw. Just pass None (default) to reset the clip"
+
+#define DOC_LAYEREDDIRTYCHANGELAYER "change_layer(sprite, new_layer): return None\nchanges the layer of the sprite"
+
+#define DOC_LAYEREDDIRTYSETTIMINGTRESHOLD "set_timing_treshold(time_ms): return None\nsets the treshold in milliseconds"
+
+#define DOC_PYGAMESPRITEGROUPSINGLE "pygame.sprite.GroupSingle(sprite=None): return GroupSingle\nGroup container that holds a single Sprite"
+
+#define DOC_PYGAMESPRITESPRITECOLLIDE "pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list\nfind Sprites in a Group that intersect another Sprite"
+
+#define DOC_PYGAMESPRITECOLLIDERECT "pygame.sprite.collide_rect(left, right): return bool\ncollision detection between two sprites, using rects."
+
+#define DOC_PYGAMESPRITECOLLIDERECTRATIO "pygame.sprite.collide_rect_ratio(ratio): return collided_callable\ncollision detection between two sprites, using rects scaled to a ratio."
+
+#define DOC_PYGAMESPRITECOLLIDECIRCLE "pygame.sprite.collide_circle(left, right): return bool\ncollision detection between two sprites, using circles."
+
+#define DOC_PYGAMESPRITECOLLIDECIRCLERATIO "pygame.sprite.collide_circle_ratio(ratio): return collided_callable\ncollision detection between two sprites, using circles scaled to a ratio."
+
+#define DOC_PYGAMESPRITECOLLIDEMASK "pygame.sprite.collide_mask(SpriteLeft, SpriteRight): return bool\ncollision detection between two sprites, using masks."
+
+#define DOC_PYGAMESPRITEGROUPCOLLIDE "pygame.sprite.groupcollide(group1, group2, dokill1, dokill2): return Sprite_dict\nfind all Sprites that collide between two Groups"
+
+#define DOC_PYGAMESPRITESPRITECOLLIDEANY "pygame.sprite.spritecollideany(sprite, group): return bool\nsimple test if a Sprite intersects anything in a Group"
+
+#define DOC_ ""
+
+#define DOC_PYGAMESURFACE "pygame.Surface((width, height), flags=0, depth=0, masks=None): return Surface\npygame.Surface((width, height), flags=0, Surface): return Surface\npygame object for representing images"
+
+#define DOC_SURFACEBLIT "Surface.blit(source, dest, area=None, special_flags = 0): return Rect\ndraw one image onto another"
+
+#define DOC_SURFACECONVERT "Surface.convert(Surface): return Surface\nSurface.convert(depth, flags=0): return Surface\nSurface.convert(masks, flags=0): return Surface\nSurface.convert(): return Surface\nchange the pixel format of an image"
+
+#define DOC_SURFACECONVERTALPHA "Surface.convert_alpha(Surface): return Surface\nSurface.convert_alpha(): return Surface\nchange the pixel format of an image including per pixel alphas"
+
+#define DOC_SURFACECOPY "Surface.copy(): return Surface\ncreate a new copy of a Surface"
+
+#define DOC_SURFACEFILL "Surface.fill(color, rect=None, special_flags=0): return Rect\nfill Surface with a solid color"
+
+#define DOC_SURFACESETCOLORKEY "Surface.set_colorkey(Color, flags=0): return None\nSurface.set_colorkey(None): return None\nSet the transparent colorkey"
+
+#define DOC_SURFACEGETCOLORKEY "Surface.get_colorkey(): return RGB or None\nGet the current transparent colorkey"
+
+#define DOC_SURFACESETALPHA "Surface.set_alpha(value, flags=0): return None\nSurface.set_alpha(None): return None\nset the alpha value for the full Surface image"
+
+#define DOC_SURFACEGETALPHA "Surface.get_alpha(): return int_value or None\nget the current Surface transparency value"
+
+#define DOC_SURFACELOCK "Surface.lock(): return None\nlock the Surface memory for pixel access"
+
+#define DOC_SURFACEUNLOCK "Surface.unlock(): return None\nunlock the Surface memory from pixel access"
+
+#define DOC_SURFACEMUSTLOCK "Surface.mustlock(): return bool\ntest if the Surface requires locking"
+
+#define DOC_SURFACEGETLOCKED "Surface.get_locked(): return bool\ntest if the Surface is current locked"
+
+#define DOC_SURFACEGETLOCKS "Surface.get_locks(): return tuple\nGets the locks for the Surface"
+
+#define DOC_SURFACEGETAT "Surface.get_at((x, y)): return Color\nget the color value at a single pixel"
+
+#define DOC_SURFACESETAT "Surface.set_at((x, y), Color): return None\nset the color value for a single pixel"
+
+#define DOC_SURFACEGETPALETTE "Surface.get_palette(): return [RGB, RGB, RGB, ...]\nget the color index palette for an 8bit Surface"
+
+#define DOC_SURFACEGETPALETTEAT "Surface.get_palette_at(index): return RGB\nget the color for a single entry in a palette"
+
+#define DOC_SURFACESETPALETTE "Surface.set_palette([RGB, RGB, RGB, ...]): return None\nset the color palette for an 8bit Surface"
+
+#define DOC_SURFACESETPALETTEAT "Surface.set_at(index, RGB): return None\nset the color for a single index in an 8bit Surface palette"
+
+#define DOC_SURFACEMAPRGB "Surface.map_rgb(Color): return mapped_int\nconvert a color into a mapped color value"
+
+#define DOC_SURFACEUNMAPRGB "Surface.map_rgb(mapped_int): return Color\nconvert a mapped integer color value into a Color"
+
+#define DOC_SURFACESETCLIP "Surface.set_clip(rect): return None\nSurface.set_clip(None): return None\nset the current clipping area of the Surface"
+
+#define DOC_SURFACEGETCLIP "Surface.get_clip(): return Rect\nget the current clipping area of the Surface"
+
+#define DOC_SURFACESUBSURFACE "Surface.subsurface(Rect): return Surface\ncreate a new surface that references its parent"
+
+#define DOC_SURFACEGETPARENT "Surface.get_parent(): return Surface\nfind the parent of a subsurface"
+
+#define DOC_SURFACEGETABSPARENT "Surface.get_abs_parent(): return Surface\nfind the top level parent of a subsurface"
+
+#define DOC_SURFACEGETOFFSET "Surface.get_offset(): return (x, y)\nfind the position of a child subsurface inside a parent"
+
+#define DOC_SURFACEGETABSOFFSET "Surface.get_abs_offset(): return (x, y)\nfind the absolute position of a child subsurface inside its top level parent"
+
+#define DOC_SURFACEGETSIZE "Surface.get_size(): return (width, height)\nget the dimensions of the Surface"
+
+#define DOC_SURFACEGETWIDTH "Surface.get_width(): return width\nget the width of the Surface"
+
+#define DOC_SURFACEGETHEIGHT "Surface.get_height(): return height\nget the height of the Surface"
+
+#define DOC_SURFACEGETRECT "Surface.get_rect(**kwargs): return Rect\nget the rectangular area of the Surface"
+
+#define DOC_SURFACEGETBITSIZE "Surface.get_bitsize(): return int\nget the bit depth of the Surface pixel format"
+
+#define DOC_SURFACEGETBYTESIZE "Surface.get_bytesize(): return int\nget the bytes used per Surface pixel"
+
+#define DOC_SURFACEGETFLAGS "Surface.get_flags(): return int\nget the additional flags used for the Surface"
+
+#define DOC_SURFACEGETPITCH "Surface.get_pitch(): return int\nget the number of bytes used per Surface row"
+
+#define DOC_SURFACEGETMASKS "Surface.get_masks(): return (R, G, B, A)\nthe bitmasks needed to convert between a color and a mapped integer"
+
+#define DOC_SURFACESETMASKS "Surface.set_masks((r,g,b,a)): return None\nset the bitmasks needed to convert between a color and a mapped integer"
+
+#define DOC_SURFACEGETSHIFTS "Surface.get_shifts(): return (R, G, B, A)\nthe bit shifts needed to convert between a color and a mapped integer"
+
+#define DOC_SURFACESETSHIFTS "Surface.get_shifts((r,g,b,a)): return None\nsets the bit shifts needed to convert between a color and a mapped integer"
+
+#define DOC_SURFACEGETLOSSES "Surface.get_losses(): return (R, G, B, A)\nthe significant bits used to convert between a color and a mapped integer"
+
+#define DOC_SURFACEGETBOUNDINGRECT "Surface.get_bounding_rect(min_alpha = 1): return Rect\nfind the smallest rect containing data"
+
+#define DOC_SURFACEGETBUFFER "Surface.get_buffer(): return BufferProxy\nacquires a buffer object for the pixels of the Surface."
+
+#define DOC_PYGAMESURFARRAY "pygame module for accessing surface pixel data using array interfaces"
+
+#define DOC_PYGAMESURFARRAYARRAY2D "pygame.surfarray.array2d(Surface): return array\nCopy pixels into a 2d array"
+
+#define DOC_PYGAMESURFARRAYPIXELS2D "pygame.surfarray.pixels2d(Surface): return array\nReference pixels into a 2d array"
+
+#define DOC_PYGAMESURFARRAYARRAY3D "pygame.surfarray.array3d(Surface): return array\nCopy pixels into a 3d array"
+
+#define DOC_PYGAMESURFARRAYPIXELS3D "pygame.surfarray.pixels3d(Surface): return array\nReference pixels into a 3d array"
+
+#define DOC_PYGAMESURFARRAYARRAYALPHA "pygame.surfarray.array_alpha(Surface): return array\nCopy pixel alphas into a 2d array"
+
+#define DOC_PYGAMESURFARRAYPIXELSALPHA "pygame.surfarray.pixels_alpha(Surface): return array\nReference pixel alphas into a 2d array"
+
+#define DOC_PYGAMESURFARRAYARRAYCOLORKEY "pygame.surfarray.array_colorkey(Surface): return array\nCopy the colorkey values into a 2d array"
+
+#define DOC_PYGAMESURFARRAYMAKESURFACE "pygame.surfarray.make_surface(array): return Surface\nCopy an array to a new surface"
+
+#define DOC_PYGAMESURFARRAYBLITARRAY "pygame.surfarray.blit_array(Surface, array): return None\nBlit directly from a array values"
+
+#define DOC_PYGAMESURFARRAYMAPARRAY "pygame.surfarray.map_array(Surface, array3d): return array2d\nMap a 3d array into a 2d array"
+
+#define DOC_PYGAMESURFARRAYUSEARRAYTYPE "pygame.surfarray.use_arraytype (arraytype): return None\nSets the array system to be used for surface arrays"
+
+#define DOC_PYGAMESURFARRAYGETARRAYTYPE "pygame.surfarray.get_arraytype (): return str\nGets the currently active array type."
+
+#define DOC_PYGAMESURFARRAYGETARRAYTYPES "pygame.surfarray.get_arraytypes (): return tuple\nGets the array system types currently supported."
+
+#define DOC_PYGAMETIME "pygame module for monitoring time"
+
+#define DOC_PYGAMETIMEGETTICKS "pygame.time.get_ticks(): return milliseconds\nget the time in milliseconds"
+
+#define DOC_PYGAMETIMEWAIT "pygame.time.wait(milliseconds): return time\npause the program for an amount of time"
+
+#define DOC_PYGAMETIMEDELAY "pygame.time.delay(milliseconds): return time\npause the program for an amount of time"
+
+#define DOC_PYGAMETIMESETTIMER "pygame.time.set_timer(eventid, milliseconds): return None\nrepeatedly create an event on the event queue"
+
+#define DOC_PYGAMETIMECLOCK "pygame.time.Clock(): return Clock\ncreate an object to help track time"
+
+#define DOC_CLOCKTICK "Clock.tick(framerate=0): return milliseconds\ncontrol timer events\nupdate the clock"
+
+#define DOC_CLOCKTICKBUSYLOOP "Clock.tick_busy_loop(framerate=0): return milliseconds\ncontrol timer events\nupdate the clock"
+
+#define DOC_CLOCKGETTIME "Clock.get_time(): return milliseconds\ntime used in the previous tick"
+
+#define DOC_CLOCKGETRAWTIME "Clock.get_rawtime(): return milliseconds\nactual time used in the previous tick"
+
+#define DOC_CLOCKGETFPS "Clock.get_fps(): return float\ncompute the clock framerate"
+
+#define DOC_PYGAMETRANSFORM "pygame module to transform surfaces"
+
+#define DOC_PYGAMETRANSFORMFLIP "pygame.transform.flip(Surface, xbool, ybool): return Surface\nflip vertically and horizontally"
+
+#define DOC_PYGAMETRANSFORMSCALE "pygame.transform.scale(Surface, (width, height), DestSurface = None): return Surface\nresize to new resolution"
+
+#define DOC_PYGAMETRANSFORMROTATE "pygame.transform.rotate(Surface, angle): return Surface\nrotate an image"
+
+#define DOC_PYGAMETRANSFORMROTOZOOM "pygame.transform.rotozoom(Surface, angle, scale): return Surface\nfiltered scale and rotation"
+
+#define DOC_PYGAMETRANSFORMSCALE2X "pygame.transform.scale2x(Surface, DestSurface = None): Surface\nspecialized image doubler"
+
+#define DOC_PYGAMETRANSFORMSMOOTHSCALE "pygame.transform.smoothscale(Surface, (width, height), DestSurface = None): return Surface\nscale a surface to an arbitrary size smoothly"
+
+#define DOC_PYGAMETRANSFORMGETSMOOTHSCALEBACKEND "pygame.transform.get_smoothscale_backend(): return String\nreturn smoothscale filter version in use: 'GENERIC', 'MMX', or 'SSE'"
+
+#define DOC_PYGAMETRANSFORMSETSMOOTHSCALEBACKEND "pygame.transform.get_smoothscale_backend(type): return None\nset smoothscale filter version to one of: 'GENERIC', 'MMX', or 'SSE'"
+
+#define DOC_PYGAMETRANSFORMCHOP "pygame.transform.chop(Surface, rect): return Surface\ngets a copy of an image with an interior area removed"
+
+#define DOC_PYGAMETRANSFORMLAPLACIAN "pygame.transform.laplacian(Surface, DestSurface = None): return Surface\nfind edges in a surface"
+
+#define DOC_PYGAMETRANSFORMAVERAGESURFACES "pygame.transform.average_surfaces(Surfaces, DestSurface = None): return Surface\nfind the average surface from many surfaces."
+
+#define DOC_PYGAMETRANSFORMAVERAGECOLOR "pygame.transform.average_color(Surface, Rect = None): return Color\nfinds the average color of a surface"
+
+#define DOC_PYGAMETRANSFORMTHRESHOLD "pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = 1, Surface = None, inverse = False): return num_threshold_pixels\nfinds which, and how many pixels in a surface are within a threshold of a color."
+
diff --git a/pygame/rect.so b/pygame/rect.so
new file mode 100755
index 0000000..582284e
--- /dev/null
+++ b/pygame/rect.so
Binary files differ
diff --git a/pygame/rwobject.so b/pygame/rwobject.so
new file mode 100755
index 0000000..e799a3d
--- /dev/null
+++ b/pygame/rwobject.so
Binary files differ
diff --git a/pygame/scale.h b/pygame/scale.h
new file mode 100755
index 0000000..aad9238
--- /dev/null
+++ b/pygame/scale.h
@@ -0,0 +1,61 @@
+/*
+ pygame - Python Game Library
+ Copyright (C) 2000-2001 Pete Shinners
+ Copyright (C) 2007 Rene Dudfield, Richard Goedeken
+
+ 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
+*/
+
+/* Pentium MMX/SSE smoothscale routines
+ * Available on Win32 or GCC on a Pentium.
+ * Sorry, no Win64 support yet for Visual C builds, but it can be added.
+ */
+
+#if !defined(SCALE_HEADER)
+#define SCALE_HEADER
+
+#if (defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))) || defined(MS_WIN32)
+#define SCALE_MMX_SUPPORT
+
+/* These functions implement an area-averaging shrinking filter in the X-dimension.
+ */
+void filter_shrink_X_MMX(Uint8 *srcpix, Uint8 *dstpix, int height, int srcpitch, int dstpitch, int srcwidth, int dstwidth);
+
+void filter_shrink_X_SSE(Uint8 *srcpix, Uint8 *dstpix, int height, int srcpitch, int dstpitch, int srcwidth, int dstwidth);
+
+/* These functions implement an area-averaging shrinking filter in the Y-dimension.
+ */
+void filter_shrink_Y_MMX(Uint8 *srcpix, Uint8 *dstpix, int width, int srcpitch, int dstpitch, int srcheight, int dstheight);
+
+void filter_shrink_Y_SSE(Uint8 *srcpix, Uint8 *dstpix, int width, int srcpitch, int dstpitch, int srcheight, int dstheight);
+
+/* These functions implement a bilinear filter in the X-dimension.
+ */
+void filter_expand_X_MMX(Uint8 *srcpix, Uint8 *dstpix, int height, int srcpitch, int dstpitch, int srcwidth, int dstwidth);
+
+void filter_expand_X_SSE(Uint8 *srcpix, Uint8 *dstpix, int height, int srcpitch, int dstpitch, int srcwidth, int dstwidth);
+
+/* These functions implement a bilinear filter in the Y-dimension.
+ */
+void filter_expand_Y_MMX(Uint8 *srcpix, Uint8 *dstpix, int width, int srcpitch, int dstpitch, int srcheight, int dstheight);
+
+void filter_expand_Y_SSE(Uint8 *srcpix, Uint8 *dstpix, int width, int srcpitch, int dstpitch, int srcheight, int dstheight);
+
+#endif /* #if (defined(__GNUC__) && .....) */
+
+#endif /* #if !defined(SCALE_HEADER) */
diff --git a/pygame/surface.h b/pygame/surface.h
new file mode 100755
index 0000000..a2f49ee
--- /dev/null
+++ b/pygame/surface.h
@@ -0,0 +1,274 @@
+/*
+ pygame - Python Game Library
+ Copyright (C) 2000-2001 Pete Shinners
+ 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
+
+ Pete Shinners
+ pete@shinners.org
+*/
+
+#ifndef SURFACE_H
+#define SURFACE_H
+
+#include <SDL.h>
+#include "pygame.h"
+
+#define PYGAME_BLEND_ADD 0x1
+#define PYGAME_BLEND_SUB 0x2
+#define PYGAME_BLEND_MULT 0x3
+#define PYGAME_BLEND_MIN 0x4
+#define PYGAME_BLEND_MAX 0x5
+
+#define PYGAME_BLEND_RGB_ADD 0x1
+#define PYGAME_BLEND_RGB_SUB 0x2
+#define PYGAME_BLEND_RGB_MULT 0x3
+#define PYGAME_BLEND_RGB_MIN 0x4
+#define PYGAME_BLEND_RGB_MAX 0x5
+
+#define PYGAME_BLEND_RGBA_ADD 0x6
+#define PYGAME_BLEND_RGBA_SUB 0x7
+#define PYGAME_BLEND_RGBA_MULT 0x8
+#define PYGAME_BLEND_RGBA_MIN 0x9
+#define PYGAME_BLEND_RGBA_MAX 0x10
+
+
+
+
+
+#define GET_PIXEL(pxl, bpp, source) \
+ switch (bpp) \
+ { \
+ case 2: \
+ pxl = *((Uint16 *) (source)); \
+ break; \
+ case 4: \
+ pxl = *((Uint32 *) (source)); \
+ break; \
+ default: \
+ { \
+ Uint8 *b = (Uint8 *) source; \
+ pxl = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? \
+ b[0] + (b[1] << 8) + (b[2] << 16) : \
+ (b[0] << 16) + (b[1] << 8) + b[2]; \
+ } \
+ break; \
+ }
+
+#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt) \
+ _sR = ((px & fmt->Rmask) >> fmt->Rshift); \
+ _sR = (_sR << fmt->Rloss) + (_sR >> (8 - (fmt->Rloss << 1))); \
+ _sG = ((px & fmt->Gmask) >> fmt->Gshift); \
+ _sG = (_sG << fmt->Gloss) + (_sG >> (8 - (fmt->Gloss << 1))); \
+ _sB = ((px & fmt->Bmask) >> fmt->Bshift); \
+ _sB = (_sB << fmt->Bloss) + (_sB >> (8 - (fmt->Bloss << 1))); \
+ if (fmt->Amask) \
+ { \
+ _sA = ((px & fmt->Amask) >> fmt->Ashift); \
+ _sA = (_sA << fmt->Aloss) + (_sA >> (8 - (fmt->Aloss << 1))); \
+ } \
+ else \
+ { \
+ _sA = 255; \
+ }
+
+#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \
+ sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \
+ sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \
+ sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \
+ sa = 255;
+
+
+
+
+
+
+
+#define CREATE_PIXEL(buf, r, g, b, a, bp, ft) \
+ switch (bp) \
+ { \
+ case 2: \
+ *((Uint16 *) (buf)) = \
+ ((r >> ft->Rloss) << ft->Rshift) | \
+ ((g >> ft->Gloss) << ft->Gshift) | \
+ ((b >> ft->Bloss) << ft->Bshift) | \
+ ((a >> ft->Aloss) << ft->Ashift); \
+ break; \
+ case 4: \
+ *((Uint32 *) (buf)) = \
+ ((r >> ft->Rloss) << ft->Rshift) | \
+ ((g >> ft->Gloss) << ft->Gshift) | \
+ ((b >> ft->Bloss) << ft->Bshift) | \
+ ((a >> ft->Aloss) << ft->Ashift); \
+ break; \
+ }
+
+/* Pretty good idea from Tom Duff :-). */
+#define LOOP_UNROLLED4(code, n, width) \
+ n = (width + 3) / 4; \
+ switch (width & 3) \
+ { \
+ case 0: do { code; \
+ case 3: code; \
+ case 2: code; \
+ case 1: code; \
+ } while (--n > 0); \
+ }
+
+/* Used in the srcbpp == dstbpp == 1 blend functions */
+#define REPEAT_3(code) \
+ code; \
+ code; \
+ code;
+
+#define REPEAT_4(code) \
+ code; \
+ code; \
+ code; \
+ code;
+
+
+#define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
+ tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
+ tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
+ tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255);
+
+#define BLEND_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
+ tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
+ tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
+ tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0);
+
+#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
+ dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
+ dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
+ dB = (dB && sB) ? (dB * sB) >> 8 : 0;
+
+#define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
+ if(sR < dR) { dR = sR; } \
+ if(sG < dG) { dG = sG; } \
+ if(sB < dB) { dB = sB; }
+
+#define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
+ if(sR > dR) { dR = sR; } \
+ if(sG > dG) { dG = sG; } \
+ if(sB > dB) { dB = sB; }
+
+
+
+
+
+
+#define BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
+ tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
+ tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
+ tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255); \
+ tmp = dA + sA; dA = (tmp <= 255 ? tmp : 255);
+
+#define BLEND_RGBA_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
+ tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
+ tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
+ tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0); \
+ tmp = dA - sA; dA = (tmp >= 0 ? tmp : 0);
+
+#define BLEND_RGBA_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
+ dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
+ dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
+ dB = (dB && sB) ? (dB * sB) >> 8 : 0; \
+ dA = (dA && sA) ? (dA * sA) >> 8 : 0;
+
+#define BLEND_RGBA_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
+ if(sR < dR) { dR = sR; } \
+ if(sG < dG) { dG = sG; } \
+ if(sB < dB) { dB = sB; } \
+ if(sA < dA) { dA = sA; }
+
+#define BLEND_RGBA_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
+ if(sR > dR) { dR = sR; } \
+ if(sG > dG) { dG = sG; } \
+ if(sB > dB) { dB = sB; } \
+ if(sA > dA) { dA = sA; }
+
+
+
+
+
+
+
+
+
+
+
+#if 1
+/* Choose an alpha blend equation. If the sign is preserved on a right shift
+ * then use a specialized, faster, equation. Otherwise a more general form,
+ * where all additions are done before the shift, is needed.
+*/
+#if (-1 >> 1) < 0
+#define ALPHA_BLEND_COMP(sC, dC, dA) ((((sC - dC) * sA + sC) >> 8) + dC)
+#else
+#define ALPHA_BLEND_COMP(sC, dC, dA) (((dC << 8) + (sC - dC) * sA + sC) >> 8)
+#endif
+
+#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
+ do { \
+ if (dA) \
+ { \
+ dR = ALPHA_BLEND_COMP(sR, dR, dA); \
+ dG = ALPHA_BLEND_COMP(sG, dG, dA); \
+ dB = ALPHA_BLEND_COMP(sB, dB, dA); \
+ dA = sA + dA - ((sA * dA) / 255); \
+ } \
+ else \
+ { \
+ dR = sR; \
+ dG = sG; \
+ dB = sB; \
+ dA = sA; \
+ } \
+ } while(0)
+#elif 0
+#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
+ do { \
+ if(sA){ \
+ if(dA && sA < 255){ \
+ int dContrib = dA*(255 - sA)/255; \
+ dA = sA+dA - ((sA*dA)/255); \
+ dR = (dR*dContrib + sR*sA)/dA; \
+ dG = (dG*dContrib + sG*sA)/dA; \
+ dB = (dB*dContrib + sB*sA)/dA; \
+ }else{ \
+ dR = sR; \
+ dG = sG; \
+ dB = sB; \
+ dA = sA; \
+ } \
+ } \
+ } while(0)
+#endif
+
+int
+surface_fill_blend (SDL_Surface *surface, SDL_Rect *rect, Uint32 color,
+ int blendargs);
+
+int
+pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
+
+int
+pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
+
+#endif /* SURFACE_H */
diff --git a/pygame/surface.so b/pygame/surface.so
new file mode 100755
index 0000000..52e9dc0
--- /dev/null
+++ b/pygame/surface.so
Binary files differ
diff --git a/pygame/surflock.so b/pygame/surflock.so
new file mode 100755
index 0000000..0561d23
--- /dev/null
+++ b/pygame/surflock.so
Binary files differ
diff --git a/pygame/sysfont.py b/pygame/sysfont.py
new file mode 100755
index 0000000..ae0cf91
--- /dev/null
+++ b/pygame/sysfont.py
@@ -0,0 +1,309 @@
+## 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
+
+
+#create simple version of the font name
+def _simplename(name):
+ for char in '_ -':
+ name = name.replace(char, '')
+ name = name.lower()
+ name = name.replace('-', '')
+ name = name.replace("'", '')
+ return name
+
+
+#insert a font and style into the font dictionary
+def _addfont(name, bold, italic, font, fontdict):
+ if not fontdict.has_key(name):
+ fontdict[name] = {}
+ fontdict[name][bold, italic] = font
+
+
+#read the fonts on windows
+def initsysfonts_win32():
+ import _winreg
+ fonts = {}
+ mods = 'demibold', 'narrow', 'light', 'unicode', 'bt', 'mt'
+ fontdir = os.path.join(os.environ['WINDIR'], "Fonts")
+
+ #this is a list of registry keys containing information
+ #about fonts installed on the system.
+ keys = []
+
+ #find valid registry keys containing font information.
+ possible_keys = [
+ r"SOFTWARE\Microsoft\Windows\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
+
+
+#read of the fonts on osx (fill me in!)
+def initsysfonts_darwin():
+ 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():
+ fonts = {}
+
+ # we use the fc-list from fontconfig to get a list of fonts.
+
+ try:
+ # note, we use popen3 for if fc-list isn't there to stop stderr printing.
+ flin, flout, flerr = os.popen3('fc-list : file family style')
+ except:
+ return fonts
+
+ try:
+ for line in flout:
+ 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
+ _addfont(_simplename(family), bold, italic or oblique, filename, fonts)
+ except:
+ # try the next one.
+ pass
+ except:
+ 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 Sysfonts.has_key(name):
+ found = Sysfonts[name]
+ fname = name
+ break
+ if not found:
+ continue
+ for name in set:
+ if not Sysfonts.has_key(name):
+ 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 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 = styles.values()[0]
+ if fontname: break
+ return fontname
+
+
diff --git a/pygame/transform.so b/pygame/transform.so
new file mode 100755
index 0000000..006b2a8
--- /dev/null
+++ b/pygame/transform.so
Binary files differ
diff --git a/pygame/version.py b/pygame/version.py
new file mode 100755
index 0000000..3742b04
--- /dev/null
+++ b/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.0pre'
+vernum = 1,8,1