From 9e64dbd7cd3093353f87e5a69006d8c449a58313 Mon Sep 17 00:00:00 2001 From: olpc Date: Sat, 17 Jan 2009 18:41:32 +0000 Subject: adding trimmed pygame from SVN --- (limited to 'pygame') 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 +/* 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 + #include + #include + #include + #include + #include + + #include /* low-level i/o */ + #include + #include + #include + #include + #include + #include + #include + + #include /* for videodev2.h */ + + #include + #include +#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 . +*/ +#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 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 . +*/ +#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 + +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 +#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 . +*/ +#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 + +#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 + +/* 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 +#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 -- cgit v0.9.1