diff -Nru pygame-1.8.0release/async_sub.py pygame-1.8.1release/async_sub.py --- pygame-1.8.0release/async_sub.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/async_sub.py 2008-07-15 09:42:43.000000000 -0400 @@ -0,0 +1,243 @@ +################################################################################ +""" + +Modification of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554 + +""" + +#################################### IMPORTS ################################### + +import os +import subprocess +import errno +import time +import sys +import unittest +import tempfile + +if subprocess.mswindows: + from win32file import ReadFile, WriteFile + from win32pipe import PeekNamedPipe + import win32api + import msvcrt + +else: + from signal import SIGINT, SIGTERM, SIGKILL + import select + import fcntl + +################################### CONSTANTS ################################## + +PIPE = subprocess.PIPE + +################################################################################ + +class Popen(subprocess.Popen): + def recv(self, maxsize=None): + return self._recv('stdout', maxsize) + + def recv_err(self, maxsize=None): + return self._recv('stderr', maxsize) + + def send_recv(self, input='', maxsize=None): + return self.send(input), self.recv(maxsize), self.recv_err(maxsize) + + def read_async(self, wait=.1, e=1, tr=5, stderr=0): + if tr < 1: + tr = 1 + x = time.time()+ wait + y = [] + r = '' + pr = self.recv + if stderr: + pr = self.recv_err + while time.time() < x or r: + r = pr() + if r is None: + if e: + raise Exception("Other end disconnected!") + else: + break + elif r: + y.append(r) + else: + time.sleep(max((x-time.time())/tr, 0)) + return ''.join(y) + + def send_all(self, data): + while len(data): + sent = self.send(data) + if sent is None: + raise Exception("Other end disconnected!") + data = buffer(data, sent) + + def get_conn_maxsize(self, which, maxsize): + if maxsize is None: + maxsize = 1024 + elif maxsize < 1: + maxsize = 1 + return getattr(self, which), maxsize + + def _close(self, which): + getattr(self, which).close() + setattr(self, which, None) + + if subprocess.mswindows: + def kill(self): + # Recipes + #http://me.in-berlin.de/doc/python/faq/windows.html#how-do-i-emulate-os-kill-in-windows + #http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347462 + + """kill function for Win32""" + + win32api.TerminateProcess(int(self._handle), 0) # returns None + # handle, # exit code + + def send(self, input): + if not self.stdin: + return None + + try: + x = msvcrt.get_osfhandle(self.stdin.fileno()) + (errCode, written) = WriteFile(x, input) + except ValueError: + return self._close('stdin') + except (subprocess.pywintypes.error, Exception), why: + if why[0] in (109, errno.ESHUTDOWN): + return self._close('stdin') + raise + + return written + + def _recv(self, which, maxsize): + conn, maxsize = self.get_conn_maxsize(which, maxsize) + if conn is None: + return None + + try: + x = msvcrt.get_osfhandle(conn.fileno()) + (read, nAvail, nMessage) = PeekNamedPipe(x, 0) + if maxsize < nAvail: + nAvail = maxsize + if nAvail > 0: + (errCode, read) = ReadFile(x, nAvail, None) + except ValueError: + return self._close(which) + except (subprocess.pywintypes.error, Exception), why: + if why[0] in (109, errno.ESHUTDOWN): + return self._close(which) + raise + + if self.universal_newlines: + read = self._translate_newlines(read) + return read + + else: + def kill(self): + for i, sig in enumerate([SIGTERM, SIGKILL] * 2): + if i % 2 == 0: os.kill(self.pid, sig) + time.sleep((i * (i % 2) / 5.0) + 0.01) + + killed_pid, stat = os.waitpid(self.pid, os.WNOHANG) + if killed_pid != 0: return + + def send(self, input): + if not self.stdin: + return None + + if not select.select([], [self.stdin], [], 0)[1]: + return 0 + + try: + written = os.write(self.stdin.fileno(), input) + except OSError, why: + if why[0] == errno.EPIPE: #broken pipe + return self._close('stdin') + raise + + return written + + def _recv(self, which, maxsize): + conn, maxsize = self.get_conn_maxsize(which, maxsize) + if conn is None: + return None + + flags = fcntl.fcntl(conn, fcntl.F_GETFL) + if not conn.closed: + fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK) + + try: + if not select.select([conn], [], [], 0)[0]: + return '' + + r = conn.read(maxsize) + if not r: + return self._close(which) + + if self.universal_newlines: + r = self._translate_newlines(r) + return r + finally: + if not conn.closed: + fcntl.fcntl(conn, fcntl.F_SETFL, flags) + +################################################################################ + +def proc_in_time_or_kill(cmd, time_out, wd = None, env = None): + proc = Popen ( + cmd, cwd = wd, env = env, + stdin = subprocess.PIPE, stdout = subprocess.PIPE, + stderr = subprocess.STDOUT, universal_newlines = 1 + ) + + ret_code = None + response = [] + + t = time.time() + while ret_code is None and ((time.time() -t) < time_out): + ret_code = proc.poll() + response += [proc.read_async(wait=0.1, e=0)] + + if ret_code is None: + ret_code = '"Process timed out (time_out = %s secs) ' % time_out + try: + proc.kill() + ret_code += 'and was successfully terminated"' + except Exception, e: + ret_code += 'and termination failed (exception: %s)"' % e + + return ret_code, ''.join(response) + +################################################################################ + +class AsyncTest(unittest.TestCase): + def test_proc_in_time_or_kill(self): + ret_code, response = proc_in_time_or_kill( + [sys.executable, '-c', 'while 1: pass'], time_out = 1 + ) + + self.assert_( 'rocess timed out' in ret_code ) + self.assert_( 'successfully terminated' in ret_code ) + +################################################################################ + +def _example(): + if sys.platform == 'win32': + shell, commands, tail = ('cmd', ('echo "hello"', 'echo "HELLO WORLD"'), '\r\n') + else: + shell, commands, tail = ('sh', ('ls', 'echo HELLO WORLD'), '\n') + + a = Popen(shell, stdin=PIPE, stdout=PIPE) + print a.read_async(), + for cmd in commands: + a.send_all(cmd + tail) + print a.read_async(), + a.send_all('exit' + tail) + print a.read_async(e=0) + a.wait() + +################################################################################ + +if __name__ == '__main__': + if 1: unittest.main() + else: _example() \ No newline at end of file diff -Nru pygame-1.8.0release/configtest/test_config_msys.py pygame-1.8.1release/configtest/test_config_msys.py --- pygame-1.8.0release/configtest/test_config_msys.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/configtest/test_config_msys.py 2008-07-07 01:58:00.000000000 -0400 @@ -0,0 +1,130 @@ +# program test_config_msys.py + +"""Test config_msys.py against a dummy directory structure. + +This test must be performed on an MSYS console. +""" + +import os +import os.path +import sys + +test_dir = './testdir' +if not os.path.isdir(test_dir): + print "Test directory %s not found." % test_dir + +os.environ['LOCALBASE'] = test_dir +sys.path.append('..') + +import dll +import config_msys + +import unittest + +dependencies = dict([(dep.name, dep) for dep in config_msys.main()]) + + +class RunConfigTestCase(unittest.TestCase): + """Test dependencies returned by config_msys.main()""" + + class Dependency(object): + # Holds dependency info + def __init__(self, name=None, inc_dir_rel=None, lib_dir_rel=None, libs=None): + if libs is None: + if name is None: + libs = [] + else: + libs = [dll.name_to_root(name)] + self.libs = libs + self.inc_dir = None + self.lib_dir = None + if inc_dir_rel is not None: + self.inc_dir = '%s/%s' % (test_dir, inc_dir_rel) + if lib_dir_rel is not None: + self.lib_dir = '%s/%s' % (test_dir, lib_dir_rel) + + # Pygame dependencies + expectations = { + 'SDL': Dependency('SDL', 'include/sdl', 'lib'), # ? uses sdl-config script + 'FONT': Dependency('FONT', 'include/sdl', 'lib'), + 'IMAGE': Dependency('IMAGE', 'include/sdl', 'lib'), + 'MIXER': Dependency('MIXER', 'include', 'lib'), # A deviant include dir + 'SMPEG': Dependency('SMPEG', 'include', 'lib'), # ? uses smpeg-config script + 'PNG': Dependency('PNG', 'include', 'lib'), + 'JPEG': Dependency('JPEG', 'include/sdl', 'lib'), # A deviant include dir + 'SCRAP': Dependency(libs=['user32', 'gdi32']), + 'COPYLIB_SDL': Dependency('SDL', lib_dir_rel='bin/sdl.dll'), + 'COPYLIB_FONT': Dependency('FONT', lib_dir_rel='bin/sdl_ttf.dll'), # Where DLLs likely are + 'COPYLIB_IMAGE': Dependency('IMAGE', lib_dir_rel='bin/sdl_image.dll'), + 'COPYLIB_MIXER': Dependency('MIXER', lib_dir_rel='lib/sdl_mixer.dll'), # Where the search starts + 'COPYLIB_SMPEG': Dependency('SMPEG', lib_dir_rel='bin/smpeg.dll'), + 'COPYLIB_TIFF': Dependency('TIFF', lib_dir_rel='bin/libtiff.dll'), + 'COPYLIB_PNG': Dependency('PNG', lib_dir_rel='bin/libpng13.dll'), + 'COPYLIB_JPEG': Dependency('JPEG', lib_dir_rel='bin/jpeg.dll'), + 'COPYLIB_Z': Dependency('Z', lib_dir_rel='bin/zlib1.dll'), + 'COPYLIB_VORBISFILE': Dependency('VORBISFILE', lib_dir_rel='bin/libvorbisfile-3.dll'), + 'COPYLIB_VORBIS': Dependency('VORBIS', lib_dir_rel='bin/libvorbis-0.dll'), + 'COPYLIB_OGG': Dependency('OGG', lib_dir_rel='bin/libogg-0.dll'), + } + + def test_dependencies(self): + """Ensure all dependencies are present""" + self.failUnlessEqual(len(dependencies), len(self.expectations)) + for name in self.expectations: + self.failUnless(name in dependencies, name) + + def test_dll_match(self): + """Ensure DLLs match with dll.py.""" + for name in dll.regexs: + self.failUnless('COPYLIB_' + name in dependencies, name) + + def test_found(self): + """Ensure all dependencies were found""" + for dep in dependencies.values(): + self.failUnless(dep.found, dep.name) + + # def test_not_found(self): + # No easy way to test the case where something is missing + + def test_libs(self): + """Ensure each dependency has the proper libraries""" + from config_msys import DependencyProg + + for name, dep in dependencies.items(): + if isinstance(dep, DependencyProg): + # Do not know how to test this one. + continue + dlibs = dep.libs + elibs = self.expectations[name].libs + self.failUnlessEqual(dlibs, elibs, "%s: %s != %s" % (name, dlibs, elibs)) + + def test_proper_include_paths(self): + """Ensure each dependency has found its include directory""" + from config_msys import DependencyProg + + for name, dep in dependencies.items(): + if isinstance(dep, DependencyProg): + # Do not know how to test this one. + continue + dinc_dir = dep.inc_dir + if dinc_dir is not None: + dinc_dir = dinc_dir.lower() + einc_dir = self.expectations[name].inc_dir + self.failUnlessEqual(dinc_dir, einc_dir, "%s: %s != %s" % (name, dinc_dir, einc_dir)) + + def test_proper_library_path(self): + """Ensure each dependency has found its library directory/DLL file""" + from config_msys import DependencyProg + + for name, dep in dependencies.items(): + if isinstance(dep, DependencyProg): + # Do not know how to test this one. + continue + dlib_dir = dep.lib_dir + if dlib_dir is not None: + dlib_dir = dlib_dir.lower() + elib_dir = self.expectations[name].lib_dir + self.failUnlessEqual(dlib_dir, elib_dir, "%s: %s != %s" % (name, dlib_dir, elib_dir)) + +if __name__ == '__main__': + unittest.main() diff -Nru pygame-1.8.0release/configtest/test_config_win.py pygame-1.8.1release/configtest/test_config_win.py --- pygame-1.8.0release/configtest/test_config_win.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/configtest/test_config_win.py 2008-07-07 01:58:00.000000000 -0400 @@ -0,0 +1,118 @@ +# program test_config_msys.py + +"""Test config_msys.py for against a dummy directory structure. + +This test must be performed on an MSYS console. +""" + +import sys +sys.path.append('..') +import config_win +import dll + +import unittest +import os + +test_dir = 'testdir' +if not os.path.isdir(test_dir): + print "Test directory %s not found." % test_dir +os.chdir(os.path.join(test_dir, 'include')) + +dependencies = dict([(dep.name, dep) for dep in config_win.main()]) + + +class RunConfigTestCase(unittest.TestCase): + """Test dependencies returned by config_win.main()""" + + class Dependency(object): + # Holds dependency info + def __init__(self, name=None, inc_dir_rel=None, lib_dir_rel=None, libs=None): + if libs is None: + if name is None: + libs = [] + else: + libs = [dll.name_to_root(name)] + self.libs = libs + self.inc_dir = None + self.lib_dir = None + if inc_dir_rel is not None: + self.inc_dir = '%s/%s' % ('..', inc_dir_rel) + if lib_dir_rel is not None: + self.lib_dir = '%s/%s' % ('..', lib_dir_rel) + + # Pygame dependencies + expectations = { + 'SDL': Dependency('SDL', 'sdl-1.2.12/include', 'sdl-1.2.12/visualc/sdl/release'), + 'FONT': Dependency('FONT', 'sdl_ttf-2.0.9', 'sdl_ttf-2.0.9/release'), + 'IMAGE': Dependency('IMAGE', 'sdl_image-1.2.6', 'sdl_image-1.2.6/visualc/release'), + 'MIXER': Dependency('MIXER', 'sdl_mixer-1.2.8', 'sdl_mixer-1.2.8/release'), + 'SMPEG': Dependency('SMPEG', 'smpeg', 'smpeg/release'), + 'PNG': Dependency('PNG', 'libpng-1.2.19', 'libpng-1.2.19/lib'), + 'JPEG': Dependency('JPEG', 'jpeg-6b', 'jpeg-6b/release'), + 'SCRAP': Dependency(libs=['user32', 'gdi32']), + 'COPYLIB_SDL': Dependency('SDL', + lib_dir_rel='sdl-1.2.12/visualc/sdl/release/sdl.dll'), + 'COPYLIB_FONT': Dependency('FONT', + lib_dir_rel='sdl_ttf-2.0.9/release/sdl_ttf.dll'), + 'COPYLIB_IMAGE': Dependency('IMAGE', + lib_dir_rel='sdl_image-1.2.6/visualc/release/sdl_image.dll'), + 'COPYLIB_MIXER': Dependency('MIXER', + lib_dir_rel='sdl_mixer-1.2.8/release/sdl_mixer.dll'), + 'COPYLIB_SMPEG': Dependency('SMPEG', lib_dir_rel='smpeg/release/smpeg.dll'), + 'COPYLIB_TIFF': Dependency('TIFF', lib_dir_rel='tiff-3.8.2/release/libtiff.dll'), + 'COPYLIB_PNG': Dependency('PNG', lib_dir_rel='libpng-1.2.19/lib/libpng13.dll'), + 'COPYLIB_JPEG': Dependency('JPEG', lib_dir_rel='jpeg-6b/release/jpeg.dll'), + 'COPYLIB_Z': Dependency('Z', lib_dir_rel='zlib-1.2.3/release/zlib1.dll'), + 'COPYLIB_VORBISFILE': Dependency('VORBISFILE', + lib_dir_rel='libvorbis-1.2.0/release/libvorbisfile-3.dll'), + 'COPYLIB_VORBIS': Dependency('VORBIS', + lib_dir_rel='libvorbis-1.2.0/release/libvorbis-0.dll'), + 'COPYLIB_OGG': Dependency('OGG', lib_dir_rel='libogg-1.1.3/release/libogg-0.dll'), + } + + def test_dependencies(self): + """Ensure all dependencies are present""" + self.failUnlessEqual(len(dependencies), len(self.expectations)) + for name in self.expectations: + self.failUnless(name in dependencies, name) + + def test_dll_match(self): + """Ensure DLLs match with dll.py.""" + for name in dll.regexs: + self.failUnless('COPYLIB_' + name in dependencies, name) + + def test_found(self): + """Ensure all dependencies were found""" + for dep in dependencies.values(): + self.failUnless(dep.found, dep.name) + + # def test_not_found(self): + # No easy way to test the case where something is missing + + def test_libs(self): + """Ensure each dependency has the proper libraries""" + for name, dep in dependencies.items(): + dlibs = dep.libs + elibs = self.expectations[name].libs + self.failUnlessEqual(dlibs, elibs, "%s: %s != %s" % (name, dlibs, elibs)) + + def test_proper_include_paths(self): + """Ensure each dependency has found its include directory""" + for name, dep in dependencies.items(): + dinc_dir = dep.inc_dir + if dinc_dir is not None: + dinc_dir = dinc_dir.lower() + einc_dir = self.expectations[name].inc_dir + self.failUnlessEqual(dinc_dir, einc_dir, "%s: %s != %s" % (name, dinc_dir, einc_dir)) + + def test_proper_library_path(self): + """Ensure each dependency has found its library directory/DLL file""" + for name, dep in dependencies.items(): + dlib_dir = dep.lib_dir + if dlib_dir is not None: + dlib_dir = dlib_dir.lower() + elib_dir = self.expectations[name].lib_dir + self.failUnlessEqual(dlib_dir, elib_dir, "%s: %s != %s" % (name, dlib_dir, elib_dir)) + +if __name__ == '__main__': + unittest.main() diff -Nru pygame-1.8.0release/configtest/test_dll.py pygame-1.8.1release/configtest/test_dll.py --- pygame-1.8.0release/configtest/test_dll.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/configtest/test_dll.py 2008-07-07 01:58:00.000000000 -0400 @@ -0,0 +1,93 @@ +# program test_dll.py + +"""A unit test on the dll.py module that confirms file matching patterns""" + +import sys + +sys.path.append('..') + +import dll + +import unittest + +class MatchTestCase(unittest.TestCase): + + test_cases = [ + ('SDL', ['SDL.dll', 'sdl.DLL', 'libsdl.dll'], ['sdl.dll.a']), + ('MIXER', ['SDL_mixer.dll', 'sdl_MIXER.DLL', 'libsdl_mixer.dll'], ['sdl_mixer.dll.a']), + ('IMAGE', ['SDL_image.dll', 'sdl_IMAGE.DLL', 'libsdl_image.dll'], ['sdl_image.dll.a']), + ('FONT', ['SDL_ttf.dll', 'sdl_TTF.DLL', 'libsdl_ttf.dll'], ['sdl_ttf.dll.a']), + ('SMPEG', ['smpeg.dll', 'SMPEG.DLL', 'libsmpeg.dll'], ['smpeg.dll.a']), + ('TIFF', ['tiff.dll', 'TIFF.DLL', 'libtiff.dll'], ['tiff.dll.a']), + ('JPEG', ['jpeg.dll', 'JPEG.DLL', 'libjpeg.dll'], ['jpeg.dll.a']), + ('PNG', ['libpng13.dll', 'LIBPNG13.DLL', 'libpng12.dll', 'png12.dll', 'png13.dll'], + ['libpng.dll', 'libpng13.dll.a']), + ('Z', ['zlib1.dll', 'ZLIB1.DLL'], ['z.dll', 'libzlib1.dll', 'zlib1.dll.a']), + ('VORBIS', ['vorbis.dll', 'VORBIS.DLL', 'libvorbis-0.dll'], ['libvorbis-1.dll', 'libvorbis-0.dll.a']), + ('VORBISFILE', ['vorbisfile.dll', 'VORBISFILE.DLL', 'libvorbisfile-3.dll'], + ['libvorbisfile-0.dll', 'libvorbisfile-3.dll.a']), + ('OGG', ['ogg.dll', 'OGG.DLL', 'libogg-0.dll'], ['libogg-1.dll', 'libogg-0.dll.a']), + ] + + def test_compat(self): + """Validate the test cases""" + self.failUnlessEqual(len(self.test_cases), len(dll.regexs)) + for name, valid_files, invalid_files in self.test_cases: + self.failUnless(name in dll.regexs, name) + + def test_match(self): + """Ensure certain file names match""" + for name, valid_files, invalid_files in self.test_cases: + test = dll.tester(name) + for f in valid_files: + self.failUnless(test(f), f) + + def test_failed_match(self): + """Ensure certain file names do not match""" + for name, valid_files, invalid_files in self.test_cases: + test = dll.tester(name) + for f in invalid_files: + self.failUnless(not test(f), f) + +class DependencyLookupTestCase(unittest.TestCase): + def test_no_dependencies(self): + """Ensure no dependencies are returned for a library with non""" + self.failUnlessEqual(list(dll.dependencies(['SDL'])), ['SDL']) + + def test_not_found(self): + """Ensure an empty dependency list is returned for an unrecognized library""" + self.failUnless(not dll.dependencies(['?'])) + + def test_multiple_dependencies(self): + """Ensure dependencies are recursively traced""" + expected_libs = ['vorbisfile', 'vorbis', 'ogg'] + libs = dll.dependencies(['vorbisfile']) + self.failUnlessEqual(len(libs), len(expected_libs)) + for lib in expected_libs: + self.failUnless(lib in libs) + + def test_multiple_libs(self): + """Ensure mutliple libraries in a list are handled""" + expected_libs = ['SDL', 'z'] # Chosen for not having dependencies + libs = dll.dependencies(expected_libs) + self.failUnlessEqual(len(libs), len(expected_libs)) + for lib in expected_libs: + self.failUnless(lib in libs) + + def test_no_libs(self): + """Check special case of an empty library list""" + self.failUnless(not dll.dependencies([])) + +class RootNameLookupTestCase(unittest.TestCase): + def test_found(self): + """Ensure name -> file root name works for at least one case""" + self.failUnlessEqual(dll.name_to_root('FONT'), 'SDL_ttf') + + def test_not_found(self): + """Ensure an exception is raised for an unrecognized name""" + def test(): + dll.name_to_root('*') + self.failUnlessRaises(KeyError, test) + +if __name__ == '__main__': + unittest.main() diff -Nru pygame-1.8.0release/configtest/test_msys.py pygame-1.8.1release/configtest/test_msys.py --- pygame-1.8.0release/configtest/test_msys.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/configtest/test_msys.py 2008-07-07 01:58:00.000000000 -0400 @@ -0,0 +1,325 @@ +# program test_msys.py + +"""Test msys.py. + +This test requires that MSYS is installed and configured for MinGW.""" + +import sys +sys.path.append('..') + +import msys + +import unittest +import re +import os + +has_drive = msys.has_drive + +class FstabRegexTestCase(unittest.TestCase): + + def setUp(self): + self.pattern = re.compile(msys.FSTAB_REGEX, re.MULTILINE) + + def test_firstline(self): + """Ensure first line is checked""" + fstab = ('c:/xxx /mingw\n' + 'c:/foobar /msys\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/xxx') + + def test_middleline(self): + """Ensure a middle line is checked""" + fstab = ('c:/xxx /msys\n' + 'c:/foobar /mingw\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/foobar') + + def test_lastline(self): + """Ensure the last line is checked""" + fstab = ('c:/xxx /msys\n' + 'c:/foobar /whatever\n' + 'c:/yyy /mingw\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/yyy') + + def test_notfound(self): + """Ensure no match when /mingw is missing""" + fstab = ('c:/xxx /msys\n' + 'c:/foobar /whatever\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + def test_extra(self): + """Ensure no match for something like /mingwx""" + fstab = 'c:/xxx /mingwx\n' + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + def test_extra_entries(self): + """Ensure extra entries are allowed on the line""" + fstab = 'c:/xxx /mingw x' + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/xxx') + + def test_crlf(self): + """Ensure \\r\\n line endings are handled""" + fstab = ('c:/xxx /msys\r\n' + 'c:/foobar /mingw\r\n' + 'c:/yyy /something\r\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/foobar') + + def test_leading_space(self): + """Ensure leading space is ignored""" + fstabs = [' c:/xxx /mingw\n', ' c:/xxx /mingw\n', '\tc:/xxx /mingw\n'] + for fstab in fstabs: + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/xxx') + + def test_multiple_spaces(self): + """Ensure multiple spaces are ingored""" + fstabs = ['c:/foobar /mingw\n', 'c:/foobar /mingw\n', 'c:/foobar\t /mingw\n'] + for fstab in fstabs: + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/foobar') + + def test_multi_element_path(self): + """Ensure a multi-element path is recognized""" + fstab = ('c:/xxx /msys\n' + 'c:/foo/bar /mingw\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/foo/bar') + + def test_backslash(self): + """Ensure the backslashes is recognized as a path separator""" + fstab = ('c:\\xxx /msys\n' + 'c:\\foobar /mingw\n' + 'c:\\yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:\\foobar') + + def test_upper_case(self): + """Ensure upper case letters are accepted""" + fstab = ('c:/xxx /msys\n' + 'C:/FOOBAR /mingw\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'C:/FOOBAR') + + def test_non_letters(self): + """Ensure non-letter characters are accepted""" + fstab = ('c:/xxx /msys\n' + 'c:/-57.2(_)/s /mingw\n' + 'c:/yyy /something') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], 'c:/-57.2(_)/s') + + def test_no_drive_letter(self): + """Ensure a missing drive letter is accepted""" + fstab = ('c:/xxx /msys\n' + '/foobar /mingw\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], '/foobar') + + def test_relative_path(self): + """Ensure a relative path is rejected""" + fstab = ('c:/xxx /msys\n' + 'c/foobar /mingw\n' + 'c:/yyy /something\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + def test_invalid_characters(self): + """Ensure invalid characters are rejected""" + fstab = ('c:/*xxx /mingw\n' + 'c:/?foobar /mingw\n' + 'c:/%yyy /mingw\n' + '_:/%zzz /mingw\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + def test_drive_letters(self): + """Ensure drive letters a to z are accepted""" + for d in 'abcdefghijklmnopqrstuvwxyz': + path = '%s:/xxx' % d + fstab = '%s /mingw' % path + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], path) + + def test_upper_case_drive_letters(self): + """Ensure drive letters A to Z are accepted""" + for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': + path = '%s:/xxx' % d + fstab = '%s /mingw' % path + ma = self.pattern.search(fstab) + self.failUnless(ma is not None) + self.failUnlessEqual(ma.groupdict()['path'], path) + + def test_doubled_separators(self): + """Does the regular expression reject doubled path separators?""" + fstab = ('c:/\\xxx /mingw\n' + 'c://foobar /mingw\n' + 'c:\\\\yyy /mingw\n' + 'c:\\/zzz /mingw\n') + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + def test_root_directory(self): + """Does the regular expression reject the root directory?""" + # This just documents a quirk of the regular expression + fstab = 'c:/ /mingw\n' + ma = self.pattern.search(fstab) + self.failUnless(ma is None) + + +class MsysToWindowsTestCase(unittest.TestCase): + """Test Msys.msys_to_windows""" + some_file_name = 'foo.txt' + + def setUp(self): + self.msys = msys.Msys() + + def test_path_usr(self): + """Ensure /usr translates""" + self.failUnlessEqual(self.msys.msys_to_windows('/usr'), + self.msys.msys_root.replace(os.sep, '/')) + + def test_path_usr_somefile(self): + """Ensure /usr/..... translates""" + msys_path = '/usr/%s' % self.some_file_name + win_path = os.path.join(self.msys.msys_root, self.some_file_name).replace(os.sep, '/') + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + def test_path_mingw(self): + """Ensure /mingw translates""" + self.failUnlessEqual(self.msys.msys_to_windows('/mingw'), + self.msys.mingw_root.replace(os.sep, '/')) + + def test_path_mingw_something(self): + """Ensure /mingw/.... translates""" + msys_path = '/mingw/%s' % self.some_file_name + win_path = os.path.join(self.msys.mingw_root, self.some_file_name).replace(os.sep, '/') + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + def test_path_root(self): + """Ensure / translates""" + self.failUnlessEqual(self.msys.msys_to_windows('/'), + self.msys.msys_root.replace(os.sep, '/')) + + def test_path_root_something(self): + """Ensure /.... translates""" + msys_path = '/%s' % self.some_file_name + win_path = os.path.join(self.msys.msys_root, self.some_file_name).replace(os.sep, '/') + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + def test_drive_letter_absolute(self): + """Ensure x:/.... translates""" + for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': + msys_path = '/%s/%s' % (d, self.some_file_name) + win_path = '%s:/%s' % (d, self.some_file_name) + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + def test_drive_letter_relative(self): + """Ensure x:.... translates""" + for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': + msys_path = '%s:dir/%s' % (d, self.some_file_name) + win_path = os.path.join('%s:' % d, 'dir', self.some_file_name).replace(os.sep, '/') + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + def test_path_relative(self): + """Ensure relative paths translate""" + msys_path = './dir/%s' % self.some_file_name + win_path = os.path.join('.', 'dir', self.some_file_name).replace(os.sep, '/') + self.failUnlessEqual(self.msys.msys_to_windows(msys_path), win_path) + + +class WindowsToMsysTestCase(unittest.TestCase): + """Test Msys.windows_to_msys""" + + some_file_name = 'foo.txt' + + def setUp(self): + self.msys = msys.Msys() + + def test_path_root(self): + """Ensure MSYS directory maps to /usr""" + win_path = os.path.join(self.msys.msys_root, self.some_file_name) + msys_path = '/usr/%s' % self.some_file_name + self.failUnlessEqual(self.msys.windows_to_msys(win_path), msys_path) + + def test_path_mingw(self): + """Ensure MinGW directory maps to /mingw""" + win_path = os.path.join(self.msys.mingw_root, self.some_file_name) + msys_path = '/mingw/%s' % self.some_file_name + self.failUnlessEqual(self.msys.windows_to_msys(win_path), msys_path) + + def test_drive_letter(self): + """Ensure x:/.... translates""" + for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': + win_path = '%s:\%s' % (d, self.some_file_name) + msys_path = '/%s/%s' % (d, self.some_file_name) + self.failUnlessEqual(self.msys.windows_to_msys(win_path), msys_path) + + def test_foward_slashes(self): + """Ensure forward slashes in a Windows path are recognized""" + self.failUnlessEqual(self.msys.windows_to_msys('C:/one/two'), '/C/one/two') + + +class ShellTestCase(unittest.TestCase): + + def setUp(self): + self.msys = msys.Msys() + self.testscript_path = os.path.abspath('.\\testscript') + open(self.testscript_path, 'wb').write('echo $XXXYYYZZZ\n') + self.msys.environ['XXXYYYZZZ'] = 'passed' + + def tearDown(self): + try: + os.remove(self.testscript_path) + except StandardError: + pass + + def test_environment(self): + """Ensure MINGW_ROOT_DIRECTORY is set""" + self.failUnlessEqual(self.msys.environ['MINGW_ROOT_DIRECTORY'], + self.msys.mingw_root) + + def test_shell_script_return_value(self): + """Ensure run_shell_script returns the return value of the shell""" + self.failUnlessEqual(self.msys.run_shell_script('exit 0'), 0) + self.failUnlessEqual(self.msys.run_shell_script('exit 42'), 42) + + def test_shell_script_environment(self): + """Ensure environment variables are passed to the shell""" + script = 'test x"$SOMETHING" == xsomevalue' + self.msys.environ['SOMETHING'] = 'somevalue' + working_dir = os.getcwd() + self.failUnlessEqual(self.msys.run_shell_script(script), 0) + self.failUnlessEqual(os.getcwd(), working_dir) + + def test_shell_command(self): + """Ensure msys_shell_command works""" + cmd = self.msys.windows_to_msys(self.testscript_path) + working_dir = os.getcwd() + self.failUnlessEqual(self.msys.run_shell_command([cmd]).strip(), 'passed') + self.failUnlessEqual(os.getcwd(), working_dir) + +if __name__ == '__main__': + unittest.main() diff -Nru pygame-1.8.0release/debian/changelog pygame-1.8.1release/debian/changelog --- pygame-1.8.0release/debian/changelog 2008-08-17 14:39:45.000000000 -0400 +++ pygame-1.8.1release/debian/changelog 2008-08-17 14:39:46.000000000 -0400 @@ -1,3 +1,11 @@ +pygame (1.8.1release-0ubuntu1) intrepid; urgency=low + + * New upstream release. (LP: #255823) + * debian/control: Bumped Standards-Version to 3.8.0 + * Created debian/watch + + -- Andrew Starr-Bochicchio Sun, 17 Aug 2008 14:31:28 -0400 + pygame (1.8.0release-0ubuntu1) intrepid; urgency=low * Merge from Debian experimental, remaining Ubuntu changes: diff -Nru pygame-1.8.0release/debian/control pygame-1.8.1release/debian/control --- pygame-1.8.0release/debian/control 2008-08-17 14:39:45.000000000 -0400 +++ pygame-1.8.1release/debian/control 2008-08-17 14:39:46.000000000 -0400 @@ -5,7 +5,7 @@ XSBC-Original-Maintainer: Ed Boraas Uploaders: Joe Wreschnig Build-Depends: debhelper (>= 5.0.38), python-all-dev (>= 2.3.5-11), libsdl1.2-dev (>= 1.2.2-3.1), libsdl-image1.2-dev (>= 1.2.0-1.1), libsdl-mixer1.2-dev (>= 1.2.0-1.1), libsdl-ttf2.0-dev (>= 1.2.2-1.1), libsmpeg-dev (>= 0.4.5+cvs20030824-1.3), sharutils, python-numeric (>= 24.2-3), python-central (>= 0.5.6), quilt -Standards-Version: 3.7.2 +Standards-Version: 3.8.0 XS-Python-Version: >= 2.3 Package: python-pygame diff -Nru pygame-1.8.0release/debian/watch pygame-1.8.1release/debian/watch --- pygame-1.8.0release/debian/watch 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/debian/watch 2008-08-17 14:39:46.000000000 -0400 @@ -0,0 +1,3 @@ +version=3 + +ftp://pygame.org/pub/pygame/pygame-(.*)release\.tar\.gz diff -Nru pygame-1.8.0release/docs/index.html pygame-1.8.1release/docs/index.html --- pygame-1.8.0release/docs/index.html 2008-03-28 18:33:06.000000000 -0400 +++ pygame-1.8.1release/docs/index.html 2008-07-07 01:57:55.000000000 -0400 @@ -18,6 +18,7 @@
 
Cdrom ||  + Color ||  Cursors ||  Display ||  Draw ||  @@ -35,6 +36,7 @@ Pygame ||  Pixelarray ||  Rect ||  + Scrap ||  Sndarray ||  Sprite ||  Surface ||  @@ -115,6 +117,7 @@
Index
A list of all functions, classes, and methods in the Pygame package.
Cdrom
How to access and control the CD audio devices.
+
Color
Color representation.
Cursors
Loading and compiling cursor images.
Display
Configuring the display surface.
Draw
Drawing simple shapes like lines and ellipses to surfaces.
@@ -131,6 +134,7 @@
Pygame
Top level functions to manage Pygame.
PixelArray
Manipulate image pixel data.
Rect
Flexible container for a rectangle.
+
Scrap
Native clipboard access.
Sndarray
Manipulate sound sample data.
Sprite
Higher level objects to represent game images.
Surface
Objects for images and the screen.
diff -Nru pygame-1.8.0release/docs/ref/cdrom.html pygame-1.8.1release/docs/ref/cdrom.html --- pygame-1.8.0release/docs/ref/cdrom.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/cdrom.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,310 +1,311 @@ - - -cdrom - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - - -pygame.cdrom
- - + + +cdrom - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.cdrom
+ + diff -Nru pygame-1.8.0release/docs/ref/color.html pygame-1.8.1release/docs/ref/color.html --- pygame-1.8.0release/docs/ref/color.html 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/docs/ref/color.html 2008-07-15 10:20:54.000000000 -0400 @@ -0,0 +1,160 @@ + + +color - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.Color
+ + diff -Nru pygame-1.8.0release/docs/ref/cursors.html pygame-1.8.1release/docs/ref/cursors.html --- pygame-1.8.0release/docs/ref/cursors.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/cursors.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,127 +1,128 @@ - - -cursors - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - -
-pygame.cursors
- - + + +cursors - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + + +pygame.cursors
+ + diff -Nru pygame-1.8.0release/docs/ref/display.html pygame-1.8.1release/docs/ref/display.html --- pygame-1.8.0release/docs/ref/display.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/display.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,346 +1,347 @@ - - -display - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - - -pygame.display
- - + + +display - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.display
+ + diff -Nru pygame-1.8.0release/docs/ref/draw.html pygame-1.8.1release/docs/ref/draw.html --- pygame-1.8.0release/docs/ref/draw.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/draw.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,151 +1,152 @@ - - -draw - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - -
-pygame.draw
- - + + +draw - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.draw
+ + diff -Nru pygame-1.8.0release/docs/ref/event.html pygame-1.8.1release/docs/ref/event.html --- pygame-1.8.0release/docs/ref/event.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/event.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,238 +1,239 @@ - - -event - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - -
-pygame.event
- - + + +event - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.event
+ + diff -Nru pygame-1.8.0release/docs/ref/font.html pygame-1.8.1release/docs/ref/font.html --- pygame-1.8.0release/docs/ref/font.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/font.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,287 +1,288 @@ - - -font - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - -
-pygame.font
- - + + +font - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + +
+pygame.font
+ + diff -Nru pygame-1.8.0release/docs/ref/image.html pygame-1.8.1release/docs/ref/image.html --- pygame-1.8.0release/docs/ref/image.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/image.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,159 +1,160 @@ - - -image - Pygame Documentation - - - - - - -

pygame documentation
- ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
 
- -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
-
- - -
-pygame.image
- - + + +image - Pygame Documentation + + + + + + +

pygame documentation
+ ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
 
+ +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
+
+ + + +pygame.image
+ + diff -Nru pygame-1.8.0release/docs/ref/index.html pygame-1.8.1release/docs/ref/index.html --- pygame-1.8.0release/docs/ref/index.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/index.html 2008-07-17 17:27:38.000000000 -0400 @@ -15,6 +15,7 @@
 
Cdrom ||  +Color ||  Cursors ||  Display ||  Draw ||  @@ -79,6 +80,19 @@
  • pygame.cdrom.init - initialize the cdrom module
  • pygame.cdrom.quit - uninitialize the cdrom module
  • +
  • pygame.Color - pygame object for color representations
  • +
      +
    • Color.a - Gets or sets the alpha value of the Color.
    • +
    • Color.b - Gets or sets the blue value of the Color.
    • +
    • Color.cmy - Gets or sets the CMY representation of the Color.
    • +
    • Color.correct_gamma - Applies a certain gamma value to the Color.
    • +
    • Color.g - Gets or sets the green value of the Color.
    • +
    • Color.hsla - Gets or sets the HSLA representation of the Color.
    • +
    • Color.hsva - Gets or sets the HSVA representation of the Color.
    • +
    • Color.i1i2i3 - Gets or sets the I1I2I3 representation of the Color.
    • +
    • Color.normalize - Returns the normalized RGBA values of the Color.
    • +
    • Color.r - Gets or sets the red value of the Color.
    • +
  • pygame.cursors - pygame module for cursor resources
  • pygame.mask - pygame module for image masks.
  • pygame.mixer - pygame module for loading and playing sounds
  • -
  • pygame.PixelArray - pygame Object for direct pixel access of surfaces
  • +
  • pygame.PixelArray - pygame object for direct pixel access of surfaces
  • pygame.Rect - pygame object for storing rectangular coordinates
  • @@ -325,7 +345,6 @@
  • Rect.clamp - moves the rectangle inside another
  • Rect.clamp_ip - moves the rectangle inside another, in place
  • Rect.clip - crops a rectangle inside another
  • -
  • Rect.clip_ip - crops a rectangle inside another, in place
  • Rect.collidedict - test if one rectangle in a dictionary intersects
  • Rect.collidedictall - test if all rectangles in a dictionary intersect
  • Rect.collidelist - test if one rectangle in a list intersects
  • @@ -344,7 +363,7 @@
  • Rect.unionall - the union of many rectangles
  • Rect.unionall_ip - the union of many rectangles, in place
  • -
  • pygame.scrap -
  • +
  • pygame.scrap - pygame module for clipboard support.
  • pygame.sprite - pygame module with basic game object classes
  • @@ -250,11 +254,20 @@ Surface.get_locked
      test if the Surface is current locked
      Surface.get_locked(): return bool
      -

      Returns True when the Surface is locked. It doesn't matter how many times the Surface is locked. Surfaces that do not need locking (see mustlock()) will always return True.

      +

      Returns True when the Surface is locked. It doesn't matter how many times the Surface is locked.

       

    + +Surface.get_locks
      + Gets the locks for the Surface
      + Surface.get_locks(): return tuple
      +

      Returns the currently existing locks for the Surface.

      +  
      +
    + +
    Surface.get_at
      get the color value at a single pixel
      @@ -348,7 +361,7 @@
      Surface.get_clip
        - get the current clipping are of the Surface
        + get the current clipping area of the Surface
        Surface.get_clip(): return Rect

        Return a rectangle of the current clipping area. The Surface will always return a valid rectangle that will never be outside the bounds of the image. If the Surface has had None set for the clipping area, the Surface will return a rectangle with the full area of the Surface.

         
        @@ -509,6 +522,15 @@
      +
      +Surface.set_masks
        + set the bitmasks needed to convert between a color and a mapped integer
        + Surface.set_masks((r,g,b,a)): return None
        +

        This is not needed for normal Pygame usage. New in pygame 1.8.1

        +  
        +
      + +
      Surface.get_shifts
        the bit shifts needed to convert between a color and a mapped integer
        @@ -519,6 +541,15 @@
      +
      +Surface.set_shifts
        + sets the bit shifts needed to convert between a color and a mapped integer
        + Surface.get_shifts((r,g,b,a)): return None
        +

        This is not needed for normal Pygame usage. New in pygame 1.8.1

        +  
        +
      + +
      Surface.get_losses
        the significant bits used to convert between a color and a mapped integer
        diff -Nru pygame-1.8.0release/docs/ref/surfarray.html pygame-1.8.1release/docs/ref/surfarray.html --- pygame-1.8.0release/docs/ref/surfarray.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/surfarray.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,213 +1,214 @@ - - -surfarray - Pygame Documentation - - - - - - -

        pygame documentation
        - ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
         
        - -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
        -
        - - -
        -pygame.surfarray
        - - + + +surfarray - Pygame Documentation + + + + + + +

        pygame documentation
        + ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
         
        + +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
        +
        + + +
        +pygame.surfarray
        + + diff -Nru pygame-1.8.0release/docs/ref/time.html pygame-1.8.1release/docs/ref/time.html --- pygame-1.8.0release/docs/ref/time.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/time.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,167 +1,169 @@ - - -time - Pygame Documentation - - - - - - -

        pygame documentation
        - ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
         
        - -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
        -
        - - -
        -pygame.time
        - - + + +time - Pygame Documentation + + + + + + +

        pygame documentation
        + ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
         
        + +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
        +
        + + + +pygame.time
        + + diff -Nru pygame-1.8.0release/docs/ref/transform.html pygame-1.8.1release/docs/ref/transform.html --- pygame-1.8.0release/docs/ref/transform.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/docs/ref/transform.html 2008-07-15 10:20:54.000000000 -0400 @@ -1,168 +1,169 @@ - - -transform - Pygame Documentation - - - - - - -

        pygame documentation
        - ||  - Pygame Home  ||  - Help Contents  || - Reference Index  || -
         
        - -Cdrom ||  -Cursors ||  -Display ||  -Draw ||  -Event ||  -Font ||  -Image ||  -Joystick ||  -Key ||  -Mask ||  -Mixer ||  -Mouse ||  -Movie ||  -Music ||  -Overlay ||  -Pixelarray ||  -Pygame ||  -Rect ||  -Scrap ||  -Sndarray ||  -Sprite ||  -Surface ||  -Surfarray ||  -Time ||  -Transform -
        -
        - - - -pygame.transform
        - - + + +transform - Pygame Documentation + + + + + + +

        pygame documentation
        + ||  + Pygame Home  ||  + Help Contents  || + Reference Index  || +
         
        + +Cdrom ||  +Color ||  +Cursors ||  +Display ||  +Draw ||  +Event ||  +Font ||  +Image ||  +Joystick ||  +Key ||  +Mask ||  +Mixer ||  +Mouse ||  +Movie ||  +Music ||  +Overlay ||  +Pixelarray ||  +Pygame ||  +Rect ||  +Scrap ||  +Sndarray ||  +Sprite ||  +Surface ||  +Surfarray ||  +Time ||  +Transform +
        +
        + + +
        +pygame.transform
        + + diff -Nru pygame-1.8.0release/docs/util/doclate.html pygame-1.8.1release/docs/util/doclate.html --- pygame-1.8.0release/docs/util/doclate.html 2006-06-08 03:13:24.000000000 -0400 +++ pygame-1.8.1release/docs/util/doclate.html 1969-12-31 19:00:00.000000000 -0500 @@ -1,6 +0,0 @@ -{name} -
        -{usage} -
          -{docs} -

         
        \ No newline at end of file diff -Nru pygame-1.8.0release/docs/util/listlate.html pygame-1.8.1release/docs/util/listlate.html --- pygame-1.8.0release/docs/util/listlate.html 2006-06-08 03:13:24.000000000 -0400 +++ pygame-1.8.1release/docs/util/listlate.html 1969-12-31 19:00:00.000000000 -0500 @@ -1,3 +0,0 @@ -
        {name} - -{quick} - diff -Nru pygame-1.8.0release/docs/util/makedocs.py pygame-1.8.1release/docs/util/makedocs.py --- pygame-1.8.0release/docs/util/makedocs.py 2006-06-08 03:13:24.000000000 -0400 +++ pygame-1.8.1release/docs/util/makedocs.py 1969-12-31 19:00:00.000000000 -0500 @@ -1,443 +0,0 @@ -"""take all the PyGame source and create html documentation""" - -import fnmatch, glob, os, types - - -DOCPATTERN = '*static char*doc_*=*' - -SOURCES = ['../../src/*.c'] -IGNORE_SOURCES = ['rwobject.c'] -PYTHONSRC = ['color', 'cursors', 'version', 'sprite', 'sysfont'] - -OUTPUTDIR = '../ref/' -PAGETEMPLATE = open('pagelate.html').readlines() -DOCTEMPLATE = open('doclate.html').readlines() -LISTTEMPLATE = open('listlate.html').readlines() -INDEXTEMPLATE = ['{mod}.{name} - {quick}
        '] - -INDEXSTART = "\n


        Full Index
          \n\n" -INDEXEND = "\n
        \n" - -MODULETOC = "" - - -mainindex_desc = """ - -The pygame documentation is mainly generated automatically from the -source code. Each module and object in the package is broken into its -own page in the reference documentation. The names of the objects are -capitalized, while the regular module names are lower case. -
         
        -The pygame documentation also comes with a full set of tutorials. -You can find links to these tutorials and other documentation files below. - - -""" - - - -def filltemplate(template, info): - output = [] - for line in template: - line = line.rstrip() - pos = 0 - while 1: - pos = line.find('{', pos) - if pos == -1: break - end = line.find('}', pos) - if end == -1: - pos += 1 - continue - lookname = line[pos+1:end] - match = info.get(lookname, '') - if not match: - pos = end - continue - try:line = line[:pos] + match + line[end+1:] - except: - print lookname, type(match), match - raise - pos += len(match) - (end-pos) - output.append(line) - return '\n'.join(output) + '\n' - - - -def readsource(filename): - documents = [] - file = open(filename) - #read source - while 1: - line = file.readline() - if not line: break - if fnmatch.fnmatch(line, DOCPATTERN) and line.find(';') == -1: - lines = [line] - while 1: - line = file.readline() - if line.find("NODOC") >= 0 or line[0]=='#': continue - if not line or line.find('"') == -1: break - line = line[line.find('"')+1:line.rfind('"')] - line = line.rstrip() - if line == '\\n': - line = '
         
        ' - elif line.endswith('\\n'): - line = line[:-2] - lines.append(line) - documents.append(lines) - return documents - - -def getpydoclines(doc): - if doc is None: return - lines = [] - for line in doc.split('\n'): - if line == '': - line = '
         
        ' - lines.append(line) - return lines - - -def readpysource(name): - modulename = 'pygame.' + name - documents = [] - module = getattr(__import__(modulename), name) - title = ' /*DOC*/ static char doc_pygame_' + name + '_MODULE[] =\n' - documents.append([title] + getpydoclines(module.__doc__)) - modname = name - for name, obj in module.__dict__.items(): - if type(obj) in (types.ClassType, types.TypeType): - title = ' /*DOC*/ static char doc_%s[] =\n'%(name) - initdocs = [] - if hasattr(obj, '__init__'): - init = getattr(obj, '__init__') - if hasattr(init, '__doc__'): - initdocs = getpydoclines(init.__doc__) - if not initdocs: initdocs = [] - try: - docs = getpydoclines(obj.__doc__) - if docs: - quick = '(class) - ' + docs[0] - usage = 'pygame.%s.%s()'%(modname,name) - if initdocs: - usage = 'pygame.%s.%s'%(modname,name) + initdocs[0][initdocs[0].find('('):] - docs = [usage, quick, '']+docs+['
         
        ']+initdocs[2:] - documents.append([title] + docs) - - except AttributeError: - documents.append([title] + ['%s.%s'&(modname,name),'noclassdocs']) - for methname, meth in obj.__dict__.items(): - if methname[0] == '_': continue - if type(meth) is not types.FunctionType: continue - title = ' /*DOC*/ static char doc_%s_%s[] =\n'%(name,methname) - try: - docs = getpydoclines(meth.__doc__) - if docs: - docs[0] = ('pygame.%s.%s?'%(modname,name))+docs[0] - documents.append([title] + docs) - except AttributeError: pass - - elif type(obj) in (types.FunctionType,):# types.BuiltinFunctionType): - if not hasattr(obj, '__doc__'): continue - title = ' /*DOC*/ static char doc_' + name + '[] =\n' - doclines = getpydoclines(obj.__doc__) - if doclines: - documents.append([title] + doclines) - return documents - - -def parsedocs(docs): - modules = {} - extras = {} - funcs = [] - - for d in docs: - #print d - modpos = d[0].find('_MODULE') - extpos = d[0].find('_EXTRA') - - if modpos != -1: - start = d[0].rfind(' ', 0, modpos) - name = d[0][start+5:modpos] - modules[name] = '\n'.join(d[1:]) - elif extpos != -1: - start = d[0].rfind(' ', 0, extpos) - name = d[0][start+5:extpos] - extras[name] = '\n'.join(d[1:]) - else: - obj = {'docs':['no documentation']} - name = d[1][:d[1].find('(')] - dot = name.rfind('.') - name = name.replace('?', '.') - if dot == -1: - print 'NODOTFOUND, MISC:', name, dot - obj['category'] = 'misc' - obj['name'] = name - obj['fullname'] = name - else: - obj['category'] = name[:dot].replace('.', '_') - obj['name'] = name[dot+1:] - obj['fullname'] = name - try: - obj['usage'] = d[1].replace('?', '.') - obj['quick'] = d[2] - obj['docs'] = d[4:] - except IndexError: pass - #print '##APPEND FUNC:', obj['name'] - funcs.append(obj) - - return [modules, extras, funcs] - - -def getdocinfo(file, prefix=''): - path = '/'.join((prefix, file[3:]))[1:] - prettyname = (os.path.splitext(os.path.split(file)[-1])[0]) - prettyname = prettyname[0].capitalize() + prettyname[1:] - if file.find('html') >= 0: - info = open(file).readlines(2)[1] - else: - info = open(file).readline().strip().capitalize() - return path, prettyname, info - - -def findtutorials(): - fileline = '
      • %s - %s
      • ' - texthead = 'Included With Pygame
        ' - tuthead = 'Tutorials
        ' - texts1 = ['../../readme.html', '../../install.html', '../LGPL', '../logos.html'] - texts = [fileline%x for x in [getdocinfo(x) for x in texts1]] - finaltext = texthead + '\n'.join(texts) - htmlfiles = glob.glob('../tut/*.html') + glob.glob('../tut/*/*.html') - tuts1 = [x.replace('\\','/') for x in htmlfiles] - tuts1.sort() - tuts = [fileline%(x[0],x[1],x[2][9:]) for x in [getdocinfo(x) for x in tuts1] if x[2].startswith('TUTORIAL:')] - finaltut = tuthead + '\n'.join(tuts) - return finaltut + '
         
        ' + finaltext - - -def lookupdoc(docs, name, category): - for d in docs: - if d['fullname'] == category + '.' + name: - return d - if d['fullname'] == name or d['name'] == name: - return d - - -def htmlize(doc, obj, func): - for i in range(len(doc)): - line = doc[i] - line = line.replace('<<', '<<').replace('>>', '>>') - pos = 0 - while 1: - pos = line.find('(', pos+1) - if pos == -1: break - if line[pos-1].isspace(): continue - start = line.rfind(' ', 0, pos) - start2 = line.rfind('\n', 0, pos) - start = max(max(start, start2), 0) - lookname = line[start+1:pos] - if lookname.startswith('ygame'): - lookname = 'p' + lookname - start -= 1 - elif lookname[1:].startswith('pygame'): - lookname = lookname[1:] - start += 1 - match = lookupdoc(func, lookname, obj['category']) - if not match: - #print 'NOMATCH: "'+ obj['category'] +'" "' + lookname + '"' - continue - end = line.find(')', pos)+1 - if match['fullname'] == obj['fullname']: - link = '%s' % line[start+1:end] - else: - if match['category'] == obj['category']: - dest = '#%s' % (match['name']) - else: - dest = '%s.html#%s' % (match['category'], match['name']) - link = '%s' % (dest, line[start+1:end]) - line = line[:start+1] + link + line[end:] - pos += len(link) - (pos-start) - doc[i] = line - - -def buildlinks(alldocs): - mod, ext, func = alldocs - for obj in func: - doc = obj['docs'] - htmlize(doc, obj, func) - for k,i in mod.items(): - doc = [i] - obj = {'category': k, 'fullname':''} - htmlize(doc, obj, func) - mod[k] = doc[0] - for k,i in ext.items(): - doc = [i] - obj = {'category': k, 'fullname':''} - htmlize(doc, obj, func) - ext[k] = doc[0] - - -def categorize(allfuncs): - cats = {} - for f in allfuncs: - cat = f['category'] - if not cats.has_key(cat): - cats[cat] = [] - cats[cat].append(f) - return cats - - - -def create_toc(allfuncs, prefix=''): - mods = {} - for f in allfuncs: - cat = f['category'] - mods[cat] = '' - - l_mod = [] - l_py = [] - l_type = [] - for m in mods.keys(): - if m[7:] in PYTHONSRC: - l = l_py - elif m[0].lower() == m[0]: - l = l_mod - else: - l = l_type - - file = m.replace('.', '_') + '.html' - if m[:7] == 'pygame_': - m = m[7:] - str = '%s' % (prefix, file, m) - l.append(str) - - l_py.sort() - l_mod.sort() - l_type.sort() - - str = '' - items_per_line = 6 - for x in range(0, len(l_mod), items_per_line): - row = l_mod[x:x+items_per_line] - str += '|| ' + ' || \n'.join(row) + ' ||
        \n' - str += ' 
        ' - for x in range(0, len(l_type), items_per_line): - row = l_type[x:x+items_per_line] - str += '|| ' + ' || \n'.join(row) + ' ||
        \n' - str += ' 
        ' - for x in range(0, len(l_py), items_per_line): - row = l_py[x:x+items_per_line] - str += '|| ' + ' || \n'.join(row) + ' ||
        \n' - - return str - - -def namesort(a,b): return cmp(a['name'], b['name']) - - -def writefuncdoc(alldocs): - modules, extras, funcs = alldocs - for cat, docs in funcs.items(): - htmldocs = [] - htmllist = [] - docs.sort(namesort) - for d in docs: - d['docs'] = '\n'.join(d['docs']) - htmldocs.append(filltemplate(DOCTEMPLATE, d)) - htmllist.append(filltemplate(LISTTEMPLATE, d)) - modinfo = modules.get(cat, '') - extrainfo = extras.get(cat, None) - if extrainfo: - modinfo += '

         

        ' + extrainfo - - finalinfo = {'title': cat.replace('_', '.'), - 'docs': '\n'.join(htmldocs), - 'index': '\n'.join(htmllist), - 'toc': MODULETOC, - 'module': modinfo, - 'mainpage': '../index.html', - 'logo': '../pygame_tiny.gif'} - page = filltemplate(PAGETEMPLATE, finalinfo) - file = open(OUTPUTDIR + cat + '.html', 'w') - file.write(page) - file.close() - - - -def makefullindex(alldocs): - modules, extras, funcs = alldocs - fullindex = [] - for cat, docs in funcs.items(): - htmldocs = [] - htmllist = [] - docs.sort(namesort) - for d in docs: - name = d['category'].replace('_', '.') - if name.startswith('pygame.'): - name = name[7:] - d['mod'] = name - s = filltemplate(INDEXTEMPLATE, d) - fullindex.append(s) - fullindex.sort() - return INDEXSTART + ''.join(fullindex) + INDEXEND - - - -def main(): - #find all sources - files = [] - for s in SOURCES: - files += glob.glob(s) - for f in files[:]: - if os.path.split(f)[1] in IGNORE_SOURCES: - files.remove(f) - - #load all sources - print 'read c sources...' - rawdocs = [] - for f in files: - rawdocs += readsource(f) - - print 'read python sources...' - for f in PYTHONSRC: - rawdocs += readpysource(f) - - - #parse sources - alldocs = parsedocs(rawdocs) - - #find and create hyperlinks - buildlinks(alldocs) - - #create table of contents - global MODULETOC - pathed_toc = create_toc(alldocs[2], 'ref/') - MODULETOC = create_toc(alldocs[2]) - - #categorize - alldocs[2] = categorize(alldocs[2]) - #write html - print 'writing...' - writefuncdoc(alldocs) - - fulldocs = findtutorials() + makefullindex(alldocs) - fulldocs = fulldocs - - - - #create index - finalinfo = {'title': 'Pygame Documentation', - 'docs': fulldocs, - 'index': mainindex_desc, - 'toc': pathed_toc, - 'module': ' ', - 'mainpage': 'index.html', - 'logo': 'pygame_tiny.gif', - } - page = filltemplate(PAGETEMPLATE, finalinfo) - file = open('../index.html', 'w') - file.write(page) - file.close() - - -if __name__ == '__main__': - main() diff -Nru pygame-1.8.0release/docs/util/pagelate.html pygame-1.8.1release/docs/util/pagelate.html --- pygame-1.8.0release/docs/util/pagelate.html 2006-06-08 03:13:24.000000000 -0400 +++ pygame-1.8.1release/docs/util/pagelate.html 1969-12-31 19:00:00.000000000 -0500 @@ -1,36 +0,0 @@ - -{title} - - - -
        -
        - -
        - pygame   documentation -
        - - ||  - Home  ||  - Help Contents  || -
         
        - -{toc} - -
        -
        -

        {title}

        -{module} - -
        - - -{index} -
        - -
        - -{docs} - -
        - diff -Nru pygame-1.8.0release/examples/blend_fill.py pygame-1.8.1release/examples/blend_fill.py --- pygame-1.8.0release/examples/blend_fill.py 2007-05-29 18:08:22.000000000 -0400 +++ pygame-1.8.1release/examples/blend_fill.py 2008-07-07 01:58:39.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python import sys, os import pygame from pygame.locals import * diff -Nru pygame-1.8.0release/examples/cursors.py pygame-1.8.1release/examples/cursors.py --- pygame-1.8.0release/examples/cursors.py 2006-06-08 03:13:28.000000000 -0400 +++ pygame-1.8.1release/examples/cursors.py 2008-07-07 01:58:39.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python import pygame Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/examples/data/blue.mpg and /tmp/IykkPtY_EN/pygame-1.8.1release/examples/data/blue.mpg differ Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/examples/data/house_lo.mp3 and /tmp/IykkPtY_EN/pygame-1.8.1release/examples/data/house_lo.mp3 differ Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/examples/data/house_lo.ogg and /tmp/IykkPtY_EN/pygame-1.8.1release/examples/data/house_lo.ogg differ diff -Nru pygame-1.8.0release/examples/eventlist.py pygame-1.8.1release/examples/eventlist.py --- pygame-1.8.0release/examples/eventlist.py 2006-06-08 03:13:28.000000000 -0400 +++ pygame-1.8.1release/examples/eventlist.py 2008-07-07 01:58:40.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python """Eventlist is a sloppy style of pygame, but is a handy tool for learning about pygame events and input. At the diff -Nru pygame-1.8.0release/examples/fastevents.py pygame-1.8.1release/examples/fastevents.py --- pygame-1.8.0release/examples/fastevents.py 2006-06-08 03:13:28.000000000 -0400 +++ pygame-1.8.1release/examples/fastevents.py 2008-07-07 01:58:40.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python """ This is a stress test for the fastevents module. *Fast events does not appear faster!* diff -Nru pygame-1.8.0release/examples/headless_no_windows_needed.py pygame-1.8.1release/examples/headless_no_windows_needed.py --- pygame-1.8.0release/examples/headless_no_windows_needed.py 2008-02-11 02:43:28.000000000 -0500 +++ pygame-1.8.1release/examples/headless_no_windows_needed.py 2008-07-07 01:58:40.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python """How to use pygame with no windowing system, like on headless servers. Thumbnail generation with scaling is an example of what you can do with pygame. @@ -20,8 +21,8 @@ import pygame.transform -if 0: - #some platforms might need to init the display for some parts of pygame. +if 1: + #some platforms need to init the display for some parts of pygame. import pygame.display pygame.display.init() screen = pygame.display.set_mode((1,1)) diff -Nru pygame-1.8.0release/examples/mask.py pygame-1.8.1release/examples/mask.py --- pygame-1.8.0release/examples/mask.py 2007-09-01 01:21:56.000000000 -0400 +++ pygame-1.8.1release/examples/mask.py 2008-07-07 01:58:39.000000000 -0400 @@ -1,3 +1,4 @@ +#!/usr/bin/env python import sys, random import pygame, pygame.image, pygame.surface, pygame.time, pygame.display diff -Nru pygame-1.8.0release/examples/overlay.py pygame-1.8.1release/examples/overlay.py --- pygame-1.8.0release/examples/overlay.py 2006-06-08 03:13:28.000000000 -0400 +++ pygame-1.8.1release/examples/overlay.py 2008-07-07 01:58:40.000000000 -0400 @@ -1,4 +1,4 @@ -#! /bin/env python +#!/usr/bin/env python import sys import pygame diff -Nru pygame-1.8.0release/examples/pixelarray.py pygame-1.8.1release/examples/pixelarray.py --- pygame-1.8.0release/examples/pixelarray.py 2008-01-19 21:26:49.000000000 -0500 +++ pygame-1.8.1release/examples/pixelarray.py 2008-07-07 01:58:40.000000000 -0400 @@ -1,53 +1,104 @@ -import pygame -from pygame.locals import * +#!/usr/bin/env python +import os, pygame pygame.init () -screen = pygame.display.set_mode ((200, 200)) -pygame.display.flip () -rect = screen.get_rect () +screen = pygame.display.set_mode ((255, 255)) +surface = pygame.Surface ((255, 255)) -while 1: - event = pygame.event.wait () - if event.type == QUIT: - break - if event.type == MOUSEBUTTONDOWN: - - # Create the PixelArray - ar = pygame.PixelArray (screen) - - # Fill the x columns with a white color. This will create two - # vertical, small rects. - ar[3:5] = (255, 255, 255) - ar[-4:-2] = (255, 255, 255) - - # - for px in xrange (rect.width): - # A diagonal line from the topleft to the bottomright - ar[px][px] = (255, 255, 255) - - # A diagonal line from the bottomright to the topleft. - ar[px][-px] = (255, 255, 255) - - # Horizontal, small rects. - ar[px][3:5] = (255, 255, 255) - ar[px][-4:-2] = (255, 255, 255) - - # Note, that something like - # - # array[2:4][3:5] = ... - # - # will _not_ cause a rectangular manipulation. Instead it - # will be first sliced to a two-column array, which then - # shall be sliced by columns once more, which will fail due - # an IndexError. - # - # This is caused by the slicing mechanisms in python and an - # absolutely correct behaviour. Instead create a single - # columned slice first, which you can manipulate then (as - # done above in e.g. ar[px][3:5] = (255, 255, 255). - # - - del ar +pygame.display.flip () - pygame.display.flip () +def show (image): + screen.fill ((255, 255, 255)) + screen.blit (image, (0, 0)) + pygame.display.flip () + while 1: + event = pygame.event.wait () + if event.type == pygame.QUIT: + raise SystemExit + if event.type == pygame.MOUSEBUTTONDOWN: + break + +# Create the PixelArray. +ar = pygame.PixelArray (surface) +r, g, b = 0, 0, 0 +# Do some easy gradient effect. +for y in xrange (255): + r, g, b = y, y, y + ar[:,y] = (r, g, b) +del ar +show (surface) + +# We have made some gradient effect, now flip it. +ar = pygame.PixelArray (surface) +ar[:] = ar[:,::-1] +del ar +show (surface) + +# Every second column will be made blue +ar = pygame.PixelArray (surface) +ar[::2] = (0, 0, 255) +del ar +show (surface) + +# Every second row will be made green +ar = pygame.PixelArray (surface) +ar[:,::2] = (0, 255, 0) +del ar +show (surface) + +# Manipulate the image. Flip it around the y axis. +surface = pygame.image.load (os.path.join ('data', 'arraydemo.bmp')) +ar = pygame.PixelArray (surface) +ar[:] = ar[:,::-1] +del ar +show (surface) + +# Flip the image around the x axis. +ar = pygame.PixelArray (surface) +ar[:] = ar[::-1,:] +del ar +show (surface) + +# Every second column will be made white. +ar = pygame.PixelArray (surface) +ar[::2] = (255, 255, 255) +del ar +show (surface) + +# Flip the image around both axes, restoring it's original layout. +ar = pygame.PixelArray (surface) +ar[:] = ar[::-1,::-1] +del ar +show (surface) + +# Scale it by throwing each second pixel away. +surface = pygame.image.load (os.path.join ('data', 'arraydemo.bmp')) +ar = pygame.PixelArray (surface) +sf2 = ar[::2,::2].make_surface () +del ar +show (sf2) + +# Replace anything looking like the blue color from the text. +ar = pygame.PixelArray (surface) +ar.replace ((60, 60, 255), (0, 255, 0), 0.06) +del ar +show (surface) + +# Extract anything which might be somewhat black. +surface = pygame.image.load (os.path.join ('data', 'arraydemo.bmp')) +ar = pygame.PixelArray (surface) +ar2 = ar.extract ((0, 0, 0), 0.07) +sf2 = ar2.surface +del ar, ar2 +show (sf2) + +# Compare two images. +surface = pygame.image.load (os.path.join ('data', 'alien1.gif')) +surface2 = pygame.image.load (os.path.join ('data', 'alien2.gif')) +ar1 = pygame.PixelArray (surface) +ar2 = pygame.PixelArray (surface2) +ar3 = ar1.compare (ar2, 0.07) +sf3 = ar3.surface +del ar1, ar2, ar3 +show (sf3) diff -Nru pygame-1.8.0release/install.html pygame-1.8.1release/install.html --- pygame-1.8.0release/install.html 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/install.html 2008-07-07 01:58:40.000000000 -0400 @@ -39,11 +39,9 @@ One other thing the windows binaries are missing is the Numeric or numpy Python packages. You can easily install this separately and it will allow you to use the pygame "surfarray" module. This module is optional, so there is no need -to do this. There are binary installers from the Numeric download page. -http://sourceforge.net/project/showfiles.php?group_id=1369. A Numeric for Windows python 2.5 can be found on the download page: http://www.pygame.org/download.shtml. -

        Numpy is newer than Numeric, so you should probably use that... - however both are not entirely compatible. Instead of numpy you can also use PixelArray, which - is built into pygame.


        +to do this. A Numeric for Windows python 2.5 can be found on the download page: http://www.pygame.org/download.shtml. There are older binary installers from the Numeric download page. +http://sourceforge.net/project/showfiles.php?group_id=1369. +

        PixelArray, which is built into pygame 1.8+, and is usually quite a lot faster is the recommended array implementation to use. Numpy is newer than Numeric, however both are not entirely compatible.


        Unix Binary Packages

        For many unix systems, the easiest way to install pygame is @@ -72,11 +70,13 @@ Mac OS X Binaries

        For Mac OS X 10.3 and above, binary packages are available from -pythonmac.org packages: http://www.pygame.org/download.shtml +http://www.pygame.org/download.shtml

        This package includes almost of the dependencies required for pygame (SDL, SDL_image, etc.), but you need PyObjC 1.2 or later, and may -also want to get Numeric, numpy and PyOpenGL. +also want to get Numeric, numpy and PyOpenGL. A PyObjC 1.4 installer is also made available on the download page. +

        If you want to use the Apple system python, you will need to compile from source at this time - since most people prefer to leave the system python alone, and use the python downloaded from python.org. See http://pygame.org/wiki/MacCompile for current instructions for compiling from source on Mac OSX. +

        pygame is also available from the fink, and macports distributions.

        To build self-contained pygame applications, you should use py2app. There is an example in: diff -Nru pygame-1.8.0release/lib/color.py pygame-1.8.1release/lib/color.py --- pygame-1.8.0release/lib/color.py 2006-06-08 03:13:25.000000000 -0400 +++ pygame-1.8.1release/lib/color.py 1969-12-31 19:00:00.000000000 -0500 @@ -1,127 +0,0 @@ -## 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 - -"""Manipulate colors""" - - -try: - from colordict import THECOLORS -except ImportError: - #the colordict module isn't available - THECOLORS = {} - - - -def Color(colorname): - """pygame.color.Color(colorname) -> RGBA - Get RGB values from common color names - - The color name can be the name of a common english color, - or a "web" style color in the form of 0xFF00FF. The english - color names are defined by the standard 'rgb' colors for X11. - With the hex color formatting you may optionally include an - alpha value, the formatting is 0xRRGGBBAA. You may also specify - a hex formatted color by starting the string with a '#'. - The color name used is case insensitive and whitespace is ignored. - """ - - if colorname[:2] == '0x' or colorname[0] == '#': #webstyle - if colorname[0] == '#': - colorname = colorname[1:] - else: - colorname = colorname[2:] - a = 255 - try: - r = int('0x' + colorname[0:2], 16) - g = int('0x' + colorname[2:4], 16) - b = int('0x' + colorname[4:6], 16) - if len(colorname) > 6: - a = int('0x' + colorname[6:8], 16) - except ValueError: - raise ValueError, "Illegal hex color" - return r, g, b, a - - else: #color name - #no spaces and lowercase - name = colorname.replace(' ', '').lower() - try: - return THECOLORS[name] - except KeyError: - raise ValueError, "Illegal color name, " + name - - - -def _splitcolor(color, defaultalpha=255): - try: - second = int(color) - r = g = b = color - a = defaultalpha - except TypeError: - if len(color) == 4: - r, g, b, a = color - elif len(color) == 3: - r, g, b = color - a = defaultalpha - return r, g, b, a - - -def add(color1, color2): - """pygame.color.add(color1, color2) -> RGBA - add two colors - - Add the RGB values of two colors together. If one of the - colors is only a single numeric value, it is applied to the - RGB components of the first color. Color values will be clamped - to the maximum color value of 255. - """ - r1, g1, b1, a1 = _splitcolor(color1) - r2, g2, b2, a2 = _splitcolor(color2) - m, i = min, int - return m(i(r1+r2), 255), m(i(g1+g2), 255), m(i(b1+b2), 255), m(i(a1+a2), 255) - - -def subtract(color1, color2): - """pygame.color.subtract(color1, color2) -> RGBA - subtract two colors - - Subtract the RGB values of two colors together. If one of the - colors is only a single numeric value, it is applied to the - RGB components of the first color. Color values will be clamped - to the minimum color value of 0. - """ - r1, g1, b1, a1 = _splitcolor(color1) - r2, g2, b2, a2 = _splitcolor(color2, 0) - m, i = max, int - return m(i(r1-r2), 0), m(i(g1-g2), 0), m(i(b1-b2), 0), m(i(a1-a2), 0) - - -def multiply(color1, color2): - """pygame.color.multiply(color1, color2) -> RGBA - multiply two colors - - Multiply the RGB values of two colors together. If one of the - colors is only a single numeric value, it is applied to the - RGB components of the first color. - """ - r1, g1, b1, a1 = _splitcolor(color1) - r2, g2, b2, a2 = _splitcolor(color2) - m, i = min, int - return m(i(r1*r2)/255, 255), m(i(g1*g2)/255, 255), m(i(b1*b2)/255, 255), m(i(a1*a2)/255, 255) - diff -Nru pygame-1.8.0release/lib/__init__.py pygame-1.8.1release/lib/__init__.py --- pygame-1.8.0release/lib/__init__.py 2008-03-05 03:16:07.000000000 -0500 +++ pygame-1.8.1release/lib/__init__.py 2008-07-07 01:58:09.000000000 -0400 @@ -36,6 +36,24 @@ 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 @@ -114,10 +132,18 @@ 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: from pygame.mask import * +try: + import pygame.mask + from pygame.mask import Mask except (ImportError,IOError):Mask = lambda:Missing_Function try: from pygame.pixelarray import * diff -Nru pygame-1.8.0release/lib/_numpysndarray.py pygame-1.8.1release/lib/_numpysndarray.py --- pygame-1.8.0release/lib/_numpysndarray.py 2008-01-29 02:48:06.000000000 -0500 +++ pygame-1.8.1release/lib/_numpysndarray.py 2008-07-07 01:58:09.000000000 -0400 @@ -37,22 +37,17 @@ import pygame.mixer as mixer import numpy -def array (sound): - """pygame._numpysndarray.array(Sound): return array - - Copy Sound samples into an array. - - Creates a new array for the sound data and copies the samples. The - array will always be in the format returned from - pygame.mixer.get_init(). - """ +def _array_samples(sound, raw): # Info is a (freq, format, stereo) tuple info = mixer.get_init () if not info: raise pygame.error, "Mixer not initialized" fmtbytes = (abs (info[1]) & 0xff) >> 3 - channels = mixer.get_num_channels () - data = sound.get_buffer ().raw + channels = info[2] + if raw: + data = sound.get_buffer ().raw + else: + data = sound.get_buffer () shape = (len (data) / channels * fmtbytes, ) if channels > 1: @@ -70,6 +65,17 @@ array.shape = shape return array +def array (sound): + """pygame._numpysndarray.array(Sound): return array + + Copy Sound samples into an array. + + Creates a new array for the sound data and copies the samples. The + array will always be in the format returned from + pygame.mixer.get_init(). + """ + return _array_samples(sound, True) + def samples (sound): """pygame._numpysndarray.samples(Sound): return array diff -Nru pygame-1.8.0release/lib/_numpysurfarray.py pygame-1.8.1release/lib/_numpysurfarray.py --- pygame-1.8.0release/lib/_numpysurfarray.py 2008-01-19 21:26:48.000000000 -0500 +++ pygame-1.8.1release/lib/_numpysurfarray.py 2008-07-07 01:58:09.000000000 -0400 @@ -181,37 +181,39 @@ bpp = surface.get_bytesize () if bpp < 3 or bpp > 4: raise ValueError, "unsupported bit depth for 3D reference array" + lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN start = 0 step = 0 - end = 0 # Check for RGB or BGR surface. shifts = surface.get_shifts () if shifts[0] == 16 and shifts[1] == 8 and shifts[2] == 0: # RGB - end = None - if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN: + if lilendian: start = 2 step = -1 else: start = 0 step = 1 - else: + elif shifts[2] == 16 and shifts[1] == 8 and shifts[0] == 0: # BGR - end = 3 - if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN: + if lilendian: start = 0 step = 1 else: start = 2 step = -1 + else: + raise ValueError, "unsupported colormasks for 3D reference array" + + if bpp == 4 and not lilendian: + start += 1 - array = numpy.frombuffer (surface.get_buffer (), numpy.uint8) - array.shape = surface.get_height (), surface.get_pitch () - array = array[:,:surface.get_width () * bpp] - array.shape = surface.get_width (), surface.get_height (), bpp - array = array[:,:,start:end:step] + array = numpy.ndarray \ + (shape=(surface.get_width (), surface.get_height (), 3), + dtype=numpy.uint8, buffer=surface.get_buffer (), + offset=start, strides=(bpp, surface.get_pitch (),step)) return array def array_alpha (surface): @@ -261,20 +263,24 @@ """ if surface.get_bytesize () != 4: raise ValueError, "unsupported bit depth for alpha reference array" + lilendian = pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN # ARGB surface. start = 0 - if surface.get_shifts ()[3] == 24: + if surface.get_shifts ()[3] == 24 and lilendian: # RGBA surface. start = 3 + elif surface.get_shifts ()[3] == 0 and not lilendian: + start = 3 + else: + raise ValueError, "unsupported colormasks for alpha reference array" - width, height = surface.get_width (), surface.get_height () - array = numpy.frombuffer (surface.get_buffer (), numpy.uint8) - array.shape = height, surface.get_pitch () - array = array[:, start::4] - array = array[:, :width * 4] - return numpy.transpose (array) + array = numpy.ndarray \ + (shape=(surface.get_width (), surface.get_height ()), + dtype=numpy.uint8, buffer=surface.get_buffer (), + offset=start, strides=(4, surface.get_pitch ())) + return array def array_colorkey (surface): """pygame.numpyarray.array_colorkey (Surface): return array @@ -327,7 +333,9 @@ if len (shape) == 2: # 2D array bpp = 8 - + r = 0xFF >> 6 << 5 + g = 0xFF >> 5 << 2 + b = 0xFF >> 6 elif len (shape) == 3 and shape[2] == 3: bpp = 32 r = 0xff << 16 @@ -382,7 +390,7 @@ itemsize = array.itemsize data = array.tostring () - + if itemsize > bpp: # Trim bytes from each element, keep least significant byte(s) pattern = '%s(%s)' % ('.' * (itemsize - bpp), '.' * bpp) diff -Nru pygame-1.8.0release/lib/sprite.doc pygame-1.8.1release/lib/sprite.doc --- pygame-1.8.0release/lib/sprite.doc 2006-06-08 03:13:25.000000000 -0400 +++ pygame-1.8.1release/lib/sprite.doc 2008-07-07 01:58:10.000000000 -0400 @@ -26,34 +26,35 @@ The groups are designed for high efficiency in removing and adding Sprites to them. They also allow cheap testing to see if a Sprite already exists in -a Group. A given Sprite can exist in any number of groups. A game could use some -groups to control object rendering, and a completely separate set of groups -to control interaction or player movement. Instead of adding type attributes -or booleans to a derived Sprite class, consider keeping the Sprites inside -organized Groups. This will allow for easier lookup later in the game. +a Group. A given Sprite can exist in any number of groups. A game could use +some groups to control object rendering, and a completely separate set of +groups to control interaction or player movement. Instead of adding type +attributes or bools to a derived Sprite class, consider keeping the +Sprites inside organized Groups. This will allow for easier lookup later +in the game. Sprites and Groups manage their relationships with the add() and remove() -methods. These methods can accept a single or multiple targets for membership. -The default initializers for these classes also takes a single or list of -targets for initial membership. It is safe to repeatedly add and remove -the same Sprite from a Group. - -While it is possible to design sprite and group classes that don't derive from -the Sprite and AbstractGroup classes below, it is strongly recommended that -you extend those when you add a Sprite or Group class. +methods. These methods can accept a single or multiple targets for +membership. The default initializers for these classes also takes a +single or list of targets for initial membership. It is safe to repeatedly +add and remove the same Sprite from a Group. + +While it is possible to design sprite and group classes that don't derive +from the Sprite and AbstractGroup classes below, it is strongly recommended +that you extend those when you add a Sprite or Group class. Sprites are not thread safe. So lock them yourself if using threads.

        - Sprite simple base class for visible game objects pygame.sprite.Sprite(*groups): return Sprite -The base class for visible game objects. Derived classes will want to override -the Sprite.update() and assign a Sprite.image and Sprite.rect attributes. -The initializer can accept any number of Group instances to be added to. +The base class for visible game objects. Derived classes will want to +override the Sprite.update() and assign a Sprite.image and +Sprite.rect attributes. The initializer can accept any number of +Group instances to be added to. When subclassing the Sprite, be sure to call the base initializer before adding the Sprite to Groups. @@ -68,8 +69,8 @@ convenient "hook" that you can override. This method is called by Group.update() with whatever arguments you give it. -There is no need to use this method if not using the convenience method -by the same name in the Group class. +There is no need to use this method if not using the convenience +method by the same name in the Group class. @@ -124,6 +125,40 @@ + +DirtySprite +a more featureful subclass of Sprite with more attributes +pygame.sprite.DirtySprite(*groups): return DirtySprite + +Extra DirtySprite attributes with their default values: + +dirty = 1 + if set to 1, it is repainted and then set to 0 again + if set to 2 then it is always dirty ( repainted each frame, + flag is not reset) + 0 means that it is not dirty and therefor not repainted again + +blendmode = 0 + its the special_flags argument of blit, blendmodes + +source_rect = None + source rect to use, remember that it is relative to + topleft (0,0) of self.image + +visible = 1 + normally 1, if set to 0 it will not be repainted + (you must set it dirty too to be erased from screen) + +layer = 0 + (READONLY value, it is read when adding it to the + LayeredRenderGroup, for details see doc of LayeredRenderGroup) +
        + + + + + + Group container class for many Sprites pygame.sprite.Group(*sprites): return Group @@ -135,11 +170,11 @@ in test if a Sprite is contained len the number of Sprites contained - bool test if any Sprites are contained + bool test if any Sprites are contained iter iterate through all the Sprites -The Sprites in the Group are not ordered, so drawing and iterating the Sprites -is in no particular order. +The Sprites in the Group are not ordered, so drawing and iterating the +Sprites is in no particular order.
        @@ -167,7 +202,6 @@ - add add Sprites to this Group Group.add(*sprites): return None @@ -292,12 +326,257 @@ RenderUpdates class that draws Sprites in order of addition pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates -This class derives from pygame.sprite.RenderUpdates(). It maintains the order -in which the Sprites were added to the Group for rendering. This makes adding and removing -Sprites from the Group a little slower than regular Groups. +This class derives from pygame.sprite.RenderUpdates(). It maintains +the order in which the Sprites were added to the Group for rendering. +This makes adding and removing Sprites from the Group a little slower +than regular Groups. + + + + +LayeredUpdates +LayeredUpdates Group handles layers, that draws like OrderedUpdates. +pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates + +This group is fully compatible with pygame.sprite.Sprite. + +You can set the default layer through kwargs using 'default_layer' +and an integer for the layer. The default layer is 0. + +If the sprite you add has an attribute layer then that layer will +be used. +If the **kwarg contains 'layer' then the sprites passed will be +added to that layer (overriding the sprite.layer attribute). +If neither sprite has attribute layer nor **kwarg then the default +layer is used to add the sprites. + +New in pygame 1.8.0 +
        + + + +add +add a sprite or sequence of sprites to a group +LayeredUpdates.add(*sprites, **kwargs): return None + +If the sprite(s) have an attribute layer then that is used +for the layer. If **kwargs contains 'layer' then the sprite(s) +will be added to that argument (overriding the sprite layer +attribute). If neither is passed then the sprite(s) will be +added to the default layer. + + + + +sprites +returns a ordered list of sprites (first back, last top). +LayeredUpdates.sprites(): return sprites + + + + +draw +draw all sprites in the right order onto the passed surface. +LayeredUpdates.draw(surface): return Rect_list + + + + +get_sprites_at +returns a list with all sprites at that position. +LayeredUpdates.get_sprites_at(pos): return colliding_sprites + +Bottom sprites first, top last. + + + + +get_sprite +returns the sprite at the index idx from the groups sprites +LayeredUpdates.get_sprite(idx): return sprite + +Raises IndexOutOfBounds if the idx is not within range. + + + + +remove_sprites_of_layer +removes all sprites from a layer and returns them as a list. +LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites + + + + +layers +returns a list of layers defined (unique), sorted from botton up. +LayeredUpdates.layers(): return layers + + + + +change_layer +changes the layer of the sprite +LayeredUpdates.change_layer(sprite, new_layer): return None + +sprite must have been added to the renderer. It is not checked. + + + + +get_layer_of_sprite +returns the layer that sprite is currently in. +LayeredUpdates.get_layer_of_sprite(sprite): return layer + +If the sprite is not found then it will return the default layer. + + + + +get_top_layer +returns the top layer +LayeredUpdates.get_top_layer(): return layer + + + + +get_bottom_layer +returns the bottom layer +LayeredUpdates.get_bottom_layer(): return layer + + + + +move_to_front +brings the sprite to front layer +LayeredUpdates.move_to_front(sprite): return None + +Brings the sprite to front, changing sprite layer to topmost layer +(added at the end of that layer). + + + + +move_to_back +moves the sprite to the bottom layer +LayeredUpdates.move_to_back(sprite): return None + +Moves the sprite to the bottom layer, moving it behind +all other layers and adding one additional layer. + + + + +get_top_sprite +returns the topmost sprite +LayeredUpdates.get_top_sprite(): return Sprite + + + + +get_sprites_from_layer +returns all sprites from a layer, ordered by how they where added +LayeredUpdates.get_sprites_from_layer(layer): return sprites + +Returns all sprites from a layer, ordered by how they where added. +It uses linear search and the sprites are not removed from layer. + + + + +switch_layer +switches the sprites from layer1 to layer2 +LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None + +The layers number must exist, it is not checked. + + + + + +LayeredDirty +LayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates. +pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty + +This group requires pygame.sprite.DirtySprite or any sprite that +has the following attributes: + image, rect, dirty, visible, blendmode (see doc of DirtySprite). + +It uses the dirty flag technique and is therefore faster than the +pygame.sprite.RenderUpdates if you have many static sprites. It +also switches automatically between dirty rect update and full +screen drawing, so you do no have to worry what would be faster. + +Same as for the pygame.sprite.Group. +You can specify some additional attributes through kwargs: + _use_update: True/False default is False + _default_layer: default layer where sprites without a layer are added. + _time_threshold: treshold time for switching between dirty rect mode + and fullscreen mode, defaults to 1000./80 == 1000./fps + +New in pygame 1.8.0 +
        + + + +draw +draw all sprites in the right order onto the passed surface. +LayeredDirty.draw(surface, bgd=None): return Rect_list + +You can pass the background too. If a background is already set, +then the bgd argument has no effect. + + + + +clear +used to set background +LayeredDirty.clear(surface, bgd): return None + + + + +repaint_rect +repaints the given area +LayeredDirty.repaint_rect(screen_rect): return None + +screen_rect is in screencoordinates. + + + + +set_clip +clip the area where to draw. Just pass None (default) to reset the clip +LayeredDirty.set_clip(screen_rect=None): return None + + + + +get_clip +clip the area where to draw. Just pass None (default) to reset the clip +LayeredDirty.get_clip(): return Rect + + + + +change_layer +changes the layer of the sprite +change_layer(sprite, new_layer): return None + +sprite must have been added to the renderer. It is not checked. + + + + +set_timing_treshold +sets the treshold in milliseconds +set_timing_treshold(time_ms): return None + +Default is 1000./80 where 80 is the fps I want to switch to full screen mode. + + GroupSingle Group container that holds a single Sprite pygame.sprite.GroupSingle(sprite=None): return GroupSingle @@ -314,17 +593,126 @@ spritecollide find Sprites in a Group that intersect another Sprite -pygame.sprite.spritecollide(sprite, group, dokill): return Sprite_list +pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list Return a list containing all Sprites in a Group that intersect with another Sprite. Intersection is determined by comparing the Sprite.rect attribute of each Sprite. -The dokill argument is a boolean. If set to True, all Sprites that collide +The dokill argument is a bool. If set to True, all Sprites that collide will be removed from the Group. + +The collided argument is a callback function used to calculate if two sprites +are colliding. it should take two sprites as values, and return a bool +value indicating if they are colliding. If collided is not passed, all sprites +must have a "rect" value, which is a rectangle of the sprite area, which will +be used to calculate the collision. + +collided callables: + collide_rect, collide_rect_ratio, collide_circle, + collide_circle_ratio, collide_mask + + + + +collide_rect +collision detection between two sprites, using rects. +pygame.sprite.collide_rect(left, right): return bool + +Tests for collision between two sprites. Uses the +pygame rect colliderect function to calculate the +collision. Intended to be passed as a collided +callback function to the *collide functions. +Sprites must have a "rect" attributes. + +New in pygame 1.8.0 + + + + +collide_rect_ratio +collision detection between two sprites, using rects scaled to a ratio. +pygame.sprite.collide_rect_ratio(ratio): return collided_callable + +A callable class that checks for collisions between two sprites, +using a scaled version of the sprites rects. + +Is created with a ratio, the instance is then intended to be passed +as a collided callback function to the *collide functions. + +A ratio is a floating point number - 1.0 is the same size, 2.0 is twice as +big, and 0.5 is half the size. + +New in pygame 1.8.1 + + + + +collide_circle +collision detection between two sprites, using circles. +pygame.sprite.collide_circle(left, right): return bool + +Tests for collision between two sprites, by testing to +see if two circles centered on the sprites overlap. If +the sprites have a "radius" attribute, that is used to +create the circle, otherwise a circle is created that +is big enough to completely enclose the sprites rect as +given by the "rect" attribute. Intended to be passed as +a collided callback function to the *collide functions. +Sprites must have a "rect" and an optional "radius" +attribute. + +New in pygame 1.8.1 + +collide_circle_ratio +collision detection between two sprites, using circles scaled to a ratio. +pygame.sprite.collide_circle_ratio(ratio): return collided_callable + +A callable class that checks for collisions between two sprites, +using a scaled version of the sprites radius. + +Is created with a floating point ratio, the instance is then intended +to be passed as a collided callback function to the *collide functions. + +A ratio is a floating point number - 1.0 is the same size, 2.0 is twice as +big, and 0.5 is half the size. + +The created callable tests for collision between two sprites, by testing to +see if two circles centered on the sprites overlap, after +scaling the circles radius by the stored ratio. If +the sprites have a "radius" attribute, that is used to +create the circle, otherwise a circle is created that +is big enough to completely enclose the sprites rect as +given by the "rect" attribute. Intended to be passed as +a collided callback function to the *collide functions. +Sprites must have a "rect" and an optional "radius" +attribute. + +New in pygame 1.8.1 + + + + +collide_mask +collision detection between two sprites, using masks. +pygame.sprite.collide_mask(SpriteLeft, SpriteRight): return bool + +Tests for collision between two sprites, by testing if +thier bitmasks overlap. If the sprites have a "mask" +attribute, that is used as the mask, otherwise a mask is +created from the sprite image. Intended to be passed as +a collided callback function to the *collide functions. +Sprites must have a "rect" and an optional "mask" +attribute. + +New in pygame 1.8.0 + + + + groupcollide find all Sprites that collide between two Groups pygame.sprite.groupcollide(group1, group2, dokill1, dokill2): return Sprite_dict @@ -352,4 +740,10 @@ This collision test can be faster than pygame.sprite.spritecollide() since it has less work to do. + + + + + + diff -Nru pygame-1.8.0release/lib/sprite.py pygame-1.8.1release/lib/sprite.py --- pygame-1.8.0release/lib/sprite.py 2008-03-03 05:54:00.000000000 -0500 +++ pygame-1.8.1release/lib/sprite.py 2008-07-07 01:58:09.000000000 -0400 @@ -18,40 +18,51 @@ ## Pete Shinners ## pete@shinners.org -""" -This module contains a base class for sprite objects. Also -several different group classes you can use to store and -identify the sprites. Some of the groups can be used to -draw the sprites they contain. Lastly there are a handful -of collision detection functions to help you quickly find -intersecting sprites in a group. - -The way the groups are designed, it is very efficient at -adding and removing sprites from groups. This makes the -groups a perfect use for cataloging or tagging different -sprites. instead of keeping an identifier or type as a -member of a sprite class, just store the sprite in a -different set of groups. this ends up being a much better -way to loop through, find, and effect different sprites. -It is also a very quick to test if a sprite is contained -in a given group. - -You can manage the relationship between groups and sprites -from both the groups and the actual sprite classes. Both -have add() and remove() functions that let you add sprites -to groups and groups to sprites. Both have initializing -functions that can accept a list of containers or sprites. - -The methods to add and remove sprites from groups are -smart enough to not delete sprites that aren't already part -of a group, and not add sprites to a group if it already -exists. You may also pass a sequence of sprites or groups -to these functions and each one will be used. - -While it is possible to design sprite and group classes -that don't derive from the Sprite and AbstractGroup classes -below, it is strongly recommended that you extend those -when you add a Sprite or Group class. +"""pygame module with basic game object classes + +This module contains several simple classes to be used within games. There +is the main Sprite class and several Group classes that contain Sprites. +The use of these classes is entirely optional when using Pygame. The classes +are fairly lightweight and only provide a starting place for the code +that is common to most games. + +The Sprite class is intended to be used as a base class for the different +types of objects in the game. There is also a base Group class that simply +stores sprites. A game could create new types of Group classes that operate +on specially customized Sprite instances they contain. + +The basic Sprite class can draw the Sprites it contains to a Surface. The +Group.draw() method requires that each Sprite have a Surface.image attribute +and a Surface.rect. The Group.clear() method requires these same attributes, +and can be used to erase all the Sprites with background. There are also +more advanced Groups: pygame.sprite.RenderUpdates() and +pygame.sprite.OrderedUpdates(). + +Lastly, this module contains several collision functions. These help find +sprites inside multiple groups that have intersecting bounding rectangles. +To find the collisions, the Sprites are required to have a Surface.rect +attribute assigned. + +The groups are designed for high efficiency in removing and adding Sprites +to them. They also allow cheap testing to see if a Sprite already exists in +a Group. A given Sprite can exist in any number of groups. A game could use +some groups to control object rendering, and a completely separate set of +groups to control interaction or player movement. Instead of adding type +attributes or bools to a derived Sprite class, consider keeping the +Sprites inside organized Groups. This will allow for easier lookup later +in the game. + +Sprites and Groups manage their relationships with the add() and remove() +methods. These methods can accept a single or multiple targets for +membership. The default initializers for these classes also takes a +single or list of targets for initial membership. It is safe to repeatedly +add and remove the same Sprite from a Group. + +While it is possible to design sprite and group classes that don't derive +from the Sprite and AbstractGroup classes below, it is strongly recommended +that you extend those when you add a Sprite or Group class. + +Sprites are not thread safe. So lock them yourself if using threads. """ ##todo @@ -78,31 +89,37 @@ from pygame import Rect from pygame.time import get_ticks - +# Don't depend on pygame.mask if it's not there... +try: + from pygame.mask import from_surface +except: + pass class Sprite(object): - """The base class for your visible game objects. - The sprite class is meant to be used as a base class - for the objects in your game. It just provides functions - to maintain itself in different groups. - - You can initialize a sprite by passing it a group or sequence - of groups to be contained in. - - When you subclass Sprite, you must call this - pygame.sprite.Sprite.__init__(self) before you add the sprite - to any groups, or you will get an error.""" + """simple base class for visible game objects + pygame.sprite.Sprite(*groups): return Sprite + + The base class for visible game objects. Derived classes will want to + override the Sprite.update() and assign a Sprite.image and + Sprite.rect attributes. The initializer can accept any number of + Group instances to be added to. + + When subclassing the Sprite, be sure to call the base initializer before + adding the Sprite to Groups. + """ def __init__(self, *groups): self.__g = {} # The groups the sprite is in if groups: self.add(groups) def add(self, *groups): - """add(group or list of of groups, ...) - add a sprite to container + """add the sprite to groups + Sprite.add(*groups): return None - Add the sprite to a group or sequence of groups.""" + Any number of Group instances can be passed as arguments. The + Sprite will be added to the Groups it is not already a member of. + """ has = self.__g.has_key for group in groups: if hasattr(group, '_spritegroup'): @@ -112,10 +129,12 @@ else: self.add(*group) def remove(self, *groups): - """remove(group or list of groups, ...) - remove a sprite from container + """remove the sprite from groups + Sprite.remove(*groups): return None - Remove the sprite from a group or sequence of groups.""" + Any number of Group instances can be passed as arguments. The Sprite will + be removed from the Groups it is currently a member of. + """ has = self.__g.has_key for group in groups: if hasattr(group, '_spritegroup'): @@ -131,33 +150,45 @@ del self.__g[group] def update(self, *args): + """method to control sprite behavior + Sprite.update(*args): + + The default implementation of this method does nothing; it's just a + convenient "hook" that you can override. This method is called by + Group.update() with whatever arguments you give it. + + There is no need to use this method if not using the convenience + method by the same name in the Group class. + """ pass def kill(self): - """kill() - remove this sprite from all groups + """remove the Sprite from all Groups + Sprite.kill(): return None - Removes the sprite from all the groups that contain - it. The sprite still exists after calling this, - so you could use it to remove a sprite from all groups, - and then add it to some other groups.""" + The Sprite is removed from all the Groups that contain it. This won't + change anything about the state of the Sprite. It is possible to continue + to use the Sprite after this method has been called, including adding it + to Groups. + """ for c in self.__g.keys(): c.remove_internal(self) self.__g.clear() def groups(self): - """groups() -> list of groups - list used sprite containers + """list of Groups that contain this Sprite + Sprite.groups(): return group_list - Returns a list of all the groups that contain this - sprite. These are not returned in any meaningful order.""" + Return a list of all the Groups that contain this Sprite. + """ return self.__g.keys() def alive(self): - """alive() -> bool - check to see if the sprite is in any groups + """does the sprite belong to any groups + Sprite.alive(): return bool - Returns true if this sprite is a member of any groups.""" + Returns True when the Sprite belongs to one or more Groups. + """ return (len(self.__g) != 0) def __repr__(self): @@ -165,30 +196,35 @@ class DirtySprite(Sprite): - """ - DirtySprite has new attributes: - - dirty: if set to 1, it is repainted and then set to 0 again - if set to 2 then it is always dirty ( repainted each frame, - flag is not reset) - 0 means that it is not dirty and therefor not repainted again - blendmode: its the special_flags argument of blit, blendmodes - source_rect: source rect to use, remember that it relative to - topleft (0,0) of self.image - visible: normally 1, if set to 0 it will not be repainted - (you must set it dirty too to be erased from screen) + """a more featureful subclass of Sprite with more attributes + pygame.sprite.DirtySprite(*groups): return DirtySprite + + Extra DirtySprite attributes with their default values: + + dirty = 1 + if set to 1, it is repainted and then set to 0 again + if set to 2 then it is always dirty ( repainted each frame, + flag is not reset) + 0 means that it is not dirty and therefor not repainted again + + blendmode = 0 + its the special_flags argument of blit, blendmodes + + source_rect = None + source rect to use, remember that it is relative to + topleft (0,0) of self.image + + visible = 1 + normally 1, if set to 0 it will not be repainted + (you must set it dirty too to be erased from screen) + + layer = 0 + (READONLY value, it is read when adding it to the + LayeredUpdates, for details see doc of LayeredUpdates) """ def __init__(self, *groups): - """ - Same as pygame.sprite.Sprite but initializes the new attributes to - default values: - dirty = 1 (to be always dirty you have to set it) - blendmode = 0 - layer = 0 (READONLY value, it is read when adding it to the - LayeredRenderGroup, for details see doc of - LayeredRenderGroup) - """ + self.dirty = 1 self.blendmode = 0 # pygame 1.8, reffered as special_flags in # the documentation of blit @@ -202,15 +238,17 @@ self._visible = val if self.dirty < 2: self.dirty = 1 + def _get_visible(self): """returns the visible value of that sprite""" return self._visible visible = property(lambda self: self._get_visible(),\ lambda self, value:self._set_visible(value), \ - doc="you can make this sprite disappear without removing it from the group, values 0 for invisible and 1 for visible") + doc="you can make this sprite disappear without removing it from the group,\n"+ + "values 0 for invisible and 1 for visible") def __repr__(self): - return "<%s DirtySprite(in %d groups)>" % (self.__class__.__name__, len(self.__g)) + return "<%s DirtySprite(in %d groups)>" % (self.__class__.__name__, len(self.groups())) @@ -415,11 +453,22 @@ return "<%s(%d sprites)>" % (self.__class__.__name__, len(self)) class Group(AbstractGroup): - """The basic Group class you will want to use. - It supports all of the above operations and methods. + """container class for many Sprites + pygame.sprite.Group(*sprites): return Group + + A simple container for Sprite objects. This class can be inherited to + create containers with more specific behaviors. The constructor takes any + number of Sprite arguments to add to the Group. The group supports the + following standard Python operations: + + in test if a Sprite is contained + len the number of Sprites contained + bool test if any Sprites are contained + iter iterate through all the Sprites - The RenderPlain and RenderClear groups are aliases to Group - for compatibility.""" + The Sprites in the Group are not ordered, so drawing and iterating the + Sprites is in no particular order. + """ def __init__(self, *sprites): AbstractGroup.__init__(self) @@ -429,13 +478,12 @@ RenderClear = Group class RenderUpdates(Group): - """A sprite group that's more efficient at updating. - This group supports drawing to the screen, but its draw method - also returns a list of the Rects updated by the draw (and any - clears in between the last draw and the current one). You - can use pygame.display.update(renderupdates_group.draw(screen)) - to minimize the updated part of the screen. This can usually - make things much faster.""" + """Group class that tracks dirty updates + pygame.sprite.RenderUpdates(*sprites): return RenderUpdates + + This class is derived from pygame.sprite.Group(). It has an extended draw() + method that tracks the changed areas of the screen. + """ def draw(self, surface): spritedict = self.spritedict @@ -458,15 +506,21 @@ return dirty class OrderedUpdates(RenderUpdates): - """RenderUpdates, but the sprites are drawn in the order they were added. - More recently added sprites are drawn last (and so, above other - sprites).""" + """RenderUpdates class that draws Sprites in order of addition + pygame.sprite.OrderedUpdates(*spites): return OrderedUpdates + + This class derives from pygame.sprite.RenderUpdates(). It maintains + the order in which the Sprites were added to the Group for rendering. + This makes adding and removing Sprites from the Group a little + slower than regular Groups. + """ def __init__(self, *sprites): self._spritelist = [] RenderUpdates.__init__(self, *sprites) - def sprites(self): return list(self._spritelist) + def sprites(self): + return list(self._spritelist) def add_internal(self, sprite): RenderUpdates.add_internal(self, sprite) @@ -478,13 +532,12 @@ class LayeredUpdates(AbstractGroup): - """ - LayeredRenderGroup - - A group that handles layers. For drawing it uses the same metod as the - pygame.sprite.OrderedUpdates. + """LayeredUpdates Group handles layers, that draws like OrderedUpdates. + pygame.sprite.LayeredUpdates(*spites, **kwargs): return LayeredUpdates This group is fully compatible with pygame.sprite.Sprite. + + New in pygame 1.8.0 """ def __init__(self, *sprites, **kwargs): @@ -494,7 +547,7 @@ If the sprite you add has an attribute layer then that layer will be used. - If the kwarg contain 'layer' then the sprites passed will be + If the **kwarg contains 'layer' then the sprites passed will be added to that layer (overriding the sprite.layer attribute). If neither sprite has attribute layer nor kwarg then the default layer is used to add the sprites. @@ -547,11 +600,9 @@ sprites.insert(mid, sprite) def add(self, *sprites, **kwargs): - """add(sprite, list, or group, ...) - add sprite to group + """add a sprite or sequence of sprites to a group + LayeredUpdates.add(*sprites, **kwargs): return None - Add a sprite or sequence of sprites to a group. - If the sprite(s) have an attribute layer then that is used for the layer. If kwargs contains 'layer' then the sprite(s) will be added to that argument (overriding the sprite layer @@ -605,14 +656,14 @@ self._spritelayers.pop(sprite) def sprites(self): - """ - Returns a ordered list of sprites (first back, last top). + """returns a ordered list of sprites (first back, last top). + LayeredUpdates.sprites(): return sprites """ return list(self._spritelist) def draw(self, surface): - """ - Draw all sprites in the right order onto the passed surface. + """draw all sprites in the right order onto the passed surface. + LayeredUpdates.draw(surface): return Rect_list """ spritedict = self.spritedict surface_blit = surface.blit @@ -634,8 +685,9 @@ return dirty def get_sprites_at(self, pos): - """ - Returns a list with all sprites at that position. + """returns a list with all sprites at that position. + LayeredUpdates.get_sprites_at(pos): return colliding_sprites + Bottom sprites first, top last. """ _sprites = self._spritelist @@ -648,15 +700,16 @@ return colliding def get_sprite(self, idx): - """ - Returns the sprite at the index idx from the sprites(). - Raises IndexOutOfBounds. + """returns the sprite at the index idx from the groups sprites + LayeredUpdates.get_sprite(idx): return sprite + + Raises IndexOutOfBounds if the idx is not within range. """ return self._spritelist[idx] def remove_sprites_of_layer(self, layer_nr): - """ - Removes all sprites from a layer and returns them as a list. + """removes all sprites from a layer and returns them as a list + LayeredUpdates.remove_sprites_of_layer(layer_nr): return sprites """ sprites = self.get_sprites_from_layer(layer_nr) self.remove(sprites) @@ -665,8 +718,8 @@ #---# layer methods def layers(self): - """ - Returns a list of layers defined (unique), sorted from botton up. + """returns a list of layers defined (unique), sorted from botton up. + LayeredUpdates.layers(): return layers """ layers = set() for layer in self._spritelayers.values(): @@ -674,8 +727,9 @@ return list(layers) def change_layer(self, sprite, new_layer): - """ - Changes the layer of the sprite. + """changes the layer of the sprite + LayeredUpdates.change_layer(sprite, new_layer): return None + sprite must have been added to the renderer. It is not checked. """ sprites = self._spritelist # speedup @@ -714,41 +768,45 @@ return self._spritelayers.get(sprite, self._default_layer) def get_top_layer(self): - """ - Returns the number of the top layer. + """returns the top layer + LayeredUpdates.get_top_layer(): return layer """ return self._spritelayers[self._spritelist[-1]] -#### return max(self._spritelayers.values()) def get_bottom_layer(self): - """ - Returns the number of the bottom layer. + """returns the bottom layer + LayeredUpdates.get_bottom_layer(): return layer """ return self._spritelayers[self._spritelist[0]] -#### return min(self._spritelayers.values()) def move_to_front(self, sprite): - """ - Brings the sprite to front, changing the layer o the sprite - to be in the topmost layer (added at the end of that layer). + """brings the sprite to front layer + LayeredUpdates.move_to_front(sprite): return None + + Brings the sprite to front, changing sprite layer to topmost layer + (added at the end of that layer). """ self.change_layer(sprite, self.get_top_layer()) def move_to_back(self, sprite): - """ + """moves the sprite to the bottom layer + LayeredUpdates.move_to_back(sprite): return None + Moves the sprite to the bottom layer, moving it behind all other layers and adding one additional layer. """ self.change_layer(sprite, self.get_bottom_layer()-1) def get_top_sprite(self): - """ - Returns the topmost sprite. + """returns the topmost sprite + LayeredUpdates.get_top_sprite(): return Sprite """ return self._spritelist[-1] def get_sprites_from_layer(self, layer): - """ + """returns all sprites from a layer, ordered by how they where added + LayeredUpdates.get_sprites_from_layer(layer): return sprites + Returns all sprites from a layer, ordered by how they where added. It uses linear search and the sprites are not removed from layer. """ @@ -764,8 +822,9 @@ return sprites def switch_layer(self, layer1_nr, layer2_nr): - """ - Switches the sprites from layer1 to layer2. + """switches the sprites from layer1 to layer2 + LayeredUpdates.switch_layer(layer1_nr, layer2_nr): return None + The layers number must exist, it is not checked. """ sprites1 = self.remove_sprites_of_layer(layer1_nr) @@ -775,19 +834,32 @@ class LayeredDirty(LayeredUpdates): - """ - Yet another group. It uses the dirty flag technique and is therefore - faster than the pygame.sprite.RenderUpdates if you have many static - sprites. It also switches automatically between dirty rect update and - full screen rawing, so you do no have to worry what would be faster. It - only works with the DirtySprite or any sprite that has the following - attributes: image, rect, dirty, visible, blendmode (see doc of - DirtySprite). + """LayeredDirty Group is for DirtySprites. Subclasses LayeredUpdates. + pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty + + This group requires pygame.sprite.DirtySprite or any sprite that + has the following attributes: + image, rect, dirty, visible, blendmode (see doc of DirtySprite). + + It uses the dirty flag technique and is therefore faster than the + pygame.sprite.RenderUpdates if you have many static sprites. It + also switches automatically between dirty rect update and full + screen drawing, so you do no have to worry what would be faster. + + Same as for the pygame.sprite.Group. + You can specify some additional attributes through kwargs: + _use_update: True/False default is False + _default_layer: default layer where sprites without a layer are added. + _time_threshold: treshold time for switching between dirty rect mode + and fullscreen mode, defaults to 1000./80 == 1000./fps + + New in pygame 1.8.0 """ def __init__(self, *sprites, **kwargs): - """ - Same as for the pygame.sprite.Group. + """Same as for the pygame.sprite.Group. + pygame.sprite.LayeredDirty(*spites, **kwargs): return LayeredDirty + You can specify some additional attributes through kwargs: _use_update: True/False default is False _default_layer: the default layer where the sprites without a layer are @@ -810,8 +882,7 @@ setattr(self, key, val) def add_internal(self, sprite, layer=None): - """ - Do not use this method directly. It is used by the group to add a + """Do not use this method directly. It is used by the group to add a sprite internally. """ # check if all attributes needed are set @@ -831,8 +902,9 @@ LayeredUpdates.add_internal(self, sprite, layer) def draw(self, surface, bgd=None): - """ - Draws all sprites on the surface you pass in. + """draw all sprites in the right order onto the passed surface. + LayeredDirty.draw(surface, bgd=None): return Rect_list + You can pass the background too. If a background is already set, then the bgd argument has no effect. """ @@ -949,22 +1021,22 @@ return _ret def clear(self, surface, bgd): - """ - Only used to set background. + """used to set background + Group.clear(surface, bgd): return None """ self._bgd = bgd def repaint_rect(self, screen_rect): - """ - Repaints the given area. - screen_rect in screencoordinates. + """repaints the given area + LayeredDirty.repaint_rect(screen_rect): return None + + screen_rect is in screencoordinates. """ self.lostsprites.append(screen_rect.clip(self._clip)) def set_clip(self, screen_rect=None): - """ - clip the area where to draw. Just pass None (default) to - reset the clip. + """ clip the area where to draw. Just pass None (default) to reset the clip + LayeredDirty.set_clip(screen_rect=None): return None """ if screen_rect is None: self._clip = pygame.display.get_surface().get_rect() @@ -973,24 +1045,27 @@ self._use_update = False def get_clip(self): - """ - Returns the current clip. + """clip the area where to draw. Just pass None (default) to reset the clip + LayeredDirty.get_clip(): return Rect """ return self._clip def change_layer(self, sprite, new_layer): - """ - Changes the layer of the sprite. + """changes the layer of the sprite + change_layer(sprite, new_layer): return None + sprite must have been added to the renderer. It is not checked. """ - LayeredRenderGroup.change_layer(self, sprite, new_layer) + LayeredUpdates.change_layer(self, sprite, new_layer) if sprite.dirty == 0: sprite.dirty = 1 + def set_timing_treshold(self, time_ms): - """ - Sets the treshold in milliseconds. Default is 1000./80 where 80 is the - fps I want to switch to full screen mode. + """sets the treshold in milliseconds + set_timing_treshold(time_ms): return None + + Default is 1000./80 where 80 is the fps I want to switch to full screen mode. """ self._time_threshold = time_ms @@ -1056,67 +1131,208 @@ # some different collision detection functions that could be used. -def collide_rect( left, right ): - return left.rect.colliderect( right.rect ) +def collide_rect(left, right): + """collision detection between two sprites, using rects. + pygame.sprite.collide_rect(left, right): return bool + + Tests for collision between two sprites. Uses the + pygame rect colliderect function to calculate the + collision. Intended to be passed as a collided + callback function to the *collide functions. + Sprites must have a "rect" attributes. + + New in pygame 1.8.0 + """ + return left.rect.colliderect(right.rect) class collide_rect_ratio: + """A callable class that checks for collisions between + two sprites, using a scaled version of the sprites + rects. + + Is created with a ratio, the instance is then intended + to be passed as a collided callback function to the + *collide functions. + + New in pygame 1.8.1 + """ + def __init__( self, ratio ): - self.ratio = ratio + """Creates a new collide_rect_ratio callable. ratio is + expected to be a floating point value used to scale + the underlying sprite rect before checking for + collisions. + """ - def __inflate_by_ratio( self, rect ): - width = rect.width * self.ratio - height = rect.height * self.ratio - return rect.inflate( width - rect.width, height - rect.height ) + self.ratio = ratio def __call__( self, left, right ): - leftrect = self.__inflate_by_ratio( left.rect ) - rightrect = self.__inflate_by_ratio( right.rect ) + """pygame.sprite.collide_rect_ratio(ratio)(left, right): bool + collision detection between two sprites, using scaled rects. + + Tests for collision between two sprites. Uses the + pygame rect colliderect function to calculate the + collision, after scaling the rects by the stored ratio. + Sprites must have a "rect" attributes. + """ + + ratio = self.ratio + + leftrect = left.rect + width = leftrect.width + height = leftrect.height + leftrect = leftrect.inflate( width * ratio - width, height * ratio - height ) + + rightrect = right.rect + width = rightrect.width + height = rightrect.height + rightrect = rightrect.inflate( width * ratio - width, height * ratio - height ) + return leftrect.colliderect( rightrect ) def collide_circle( left, right ): - def get_radius_squared( sprite ): - try: - radiusSquared = sprite.radius ** 2 - except AttributeError: - rect = sprite.rect - radiusSquared = ( rect.width ** 2 + rect.height ** 2 ) / 4 - return radiusSquared - - xDistance = left.rect.centerx - right.rect.centerx - yDistance = left.rect.centery - right.rect.centery - distanceSquared = xDistance ** 2 + yDistance ** 2 - return distanceSquared < get_radius_squared( left ) + get_radius_squared( right ) - - -def collide_mask( left, right ): - - offset_x = left.rect[0] - right.rect[0] - offset_y = left.rect[1] - right.rect[1] - # See if the two masks at the offset are overlapping. - overlap = left.mask.overlap(right.mask, (offset_x, offset_y)) - return overlap + """collision detection between two sprites, using circles. + pygame.sprite.collide_circle(left, right): return bool + + Tests for collision between two sprites, by testing to + see if two circles centered on the sprites overlap. If + the sprites have a "radius" attribute, that is used to + create the circle, otherwise a circle is created that + is big enough to completely enclose the sprites rect as + given by the "rect" attribute. Intended to be passed as + a collided callback function to the *collide functions. + Sprites must have a "rect" and an optional "radius" + attribute. + + New in pygame 1.8.0 + """ + + xdistance = left.rect.centerx - right.rect.centerx + ydistance = left.rect.centery - right.rect.centery + distancesquared = xdistance ** 2 + ydistance ** 2 + try: + leftradiussquared = left.radius ** 2 + except AttributeError: + leftrect = left.rect + leftradiussquared = ( leftrect.width ** 2 + leftrect.height ** 2 ) / 4 + try: + rightradiussquared = right.radius ** 2 + except AttributeError: + rightrect = right.rect + rightradiussquared = ( rightrect.width ** 2 + rightrect.height ** 2 ) / 4 + return distancesquared < leftradiussquared + rightradiussquared + +class collide_circle_ratio( object ): + """A callable class that checks for collisions between + two sprites, using a scaled version of the sprites radius. + + Is created with a ratio, the instance is then intended + to be passed as a collided callback function to the + *collide functions. + + New in pygame 1.8.1 + """ + def __init__( self, ratio ): + """Creates a new collide_circle_ratio callable. ratio is + expected to be a floating point value used to scale + the underlying sprite radius before checking for + collisions. + """ + self.ratio = ratio + # Constant value that folds in division for diameter to radius, + # when calculating from a rect. + self.halfratio = ratio ** 2 / 4.0 + def __call__( self, left, right ): + """pygame.sprite.collide_circle_radio(ratio)(left, right): return bool + collision detection between two sprites, using scaled circles. + Tests for collision between two sprites, by testing to + see if two circles centered on the sprites overlap, after + scaling the circles radius by the stored ratio. If + the sprites have a "radius" attribute, that is used to + create the circle, otherwise a circle is created that + is big enough to completely enclose the sprites rect as + given by the "rect" attribute. Intended to be passed as + a collided callback function to the *collide functions. + Sprites must have a "rect" and an optional "radius" + attribute. + """ + + ratio = self.ratio + xdistance = left.rect.centerx - right.rect.centerx + ydistance = left.rect.centery - right.rect.centery + distancesquared = xdistance ** 2 + ydistance ** 2 + # Optimize for not containing radius attribute, as if radius was + # set consistently, would probably be using collide_circle instead. + if hasattr( left, "radius" ): + leftradiussquared = (left.radius * ratio) ** 2 + + if hasattr( right, "radius" ): + rightradiussquared = (right.radius * ratio) ** 2 + else: + halfratio = self.halfratio + rightrect = right.rect + rightradiussquared = (rightrect.width ** 2 + rightrect.height ** 2) * halfratio + else: + halfratio = self.halfratio + leftrect = left.rect + leftradiussquared = (leftrect.width ** 2 + leftrect.height ** 2) * halfratio + + if hasattr( right, "radius" ): + rightradiussquared = (right.radius * ratio) ** 2 + else: + rightrect = right.rect + rightradiussquared = (rightrect.width ** 2 + rightrect.height ** 2) * halfratio + return distancesquared < leftradiussquared + rightradiussquared + +def collide_mask(left, right): + """collision detection between two sprites, using masks. + pygame.sprite.collide_mask(SpriteLeft, SpriteRight): bool + + Tests for collision between two sprites, by testing if + thier bitmasks overlap. If the sprites have a "mask" + attribute, that is used as the mask, otherwise a mask is + created from the sprite image. Intended to be passed as + a collided callback function to the *collide functions. + Sprites must have a "rect" and an optional "mask" + attribute. + New in pygame 1.8.0 + """ + xoffset = right.rect[0] - left.rect[0] + yoffset = right.rect[1] - left.rect[1] + try: + leftmask = left.mask + except AttributeError: + leftmask = from_surface(left.image) + try: + rightmask = right.mask + except AttributeError: + rightmask = from_surface(right.image) + return leftmask.overlap(rightmask, (xoffset, yoffset)) def spritecollide(sprite, group, dokill, collided = None): - """pygame.sprite.spritecollide(sprite, group, dokill) -> list - collision detection between sprite and group + """find Sprites in a Group that intersect another Sprite + pygame.sprite.spritecollide(sprite, group, dokill, collided = None): return Sprite_list - given a sprite and a group of sprites, this will - return a list of all the sprites that intersect - the given sprite. - all sprites must have a "rect" value, which is a - rectangle of the sprite area. if the dokill argument - is true, the sprites that do collide will be - automatically removed from all groups.""" + Return a list containing all Sprites in a Group that intersect with another + Sprite. Intersection is determined by comparing the Sprite.rect attribute + of each Sprite. + + The dokill argument is a bool. If set to True, all Sprites that collide + will be removed from the Group. + + The collided argument is a callback function used to calculate if two sprites + are colliding. it should take two sprites as values, and return a bool + value indicating if they are colliding. If collided is not passed, all sprites + must have a "rect" value, which is a rectangle of the sprite area, which will + be used to calculate the collision. + """ crashed = [] - acollide = collided - - - if not collided: - # special case + if collided is None: + # Special case old behaviour for speed. spritecollide = sprite.rect.colliderect if dokill: for s in group.sprites(): @@ -1130,12 +1346,12 @@ else: if dokill: for s in group.sprites(): - if acollide( sprite, s ): + if collided(sprite, s): s.kill() crashed.append(s) else: for s in group: - if acollide( sprite, s ): + if collided(sprite, s): crashed.append(s) return crashed @@ -1150,12 +1366,16 @@ is a list of the sprites in the second group it collides with. the two dokill arguments control if the sprites from either group will be automatically - removed from all groups.""" + removed from all groups. + collided is a callback function used to calculate if + two sprites are colliding. it should take two sprites + as values, and return a bool value indicating if + they are colliding. if collided is not passed, all + sprites must have a "rect" value, which is a + rectangle of the sprite area, which will be used + to calculate the collision.""" crashed = {} SC = spritecollide - if not collided: - collided = collide_rect - if dokilla: for s in groupa.sprites(): c = SC(s, groupb, dokillb, collided) @@ -1182,18 +1402,21 @@ spritecollide function, this function will be a bit quicker. - all sprites must have a "rect" value, which is a - rectangle of the sprite area.""" - - if collided: + collided is a callback function used to calculate if + two sprites are colliding. it should take two sprites + as values, and return a bool value indicating if + they are colliding. if collided is not passed, all + sprites must have a "rect" value, which is a + rectangle of the sprite area, which will be used + to calculate the collision.""" + if collided is None: + # Special case old behaviour for speed. + spritecollide = sprite.rect.colliderect for s in group: - if collided( sprite, s ): + if spritecollide(s.rect): return s else: - spritecollide = sprite.rect.colliderect for s in group: - if spritecollide(s.rect): + if collided(sprite, s): return s - - return None diff -Nru pygame-1.8.0release/lib/threads/__init__.py pygame-1.8.1release/lib/threads/__init__.py --- pygame-1.8.0release/lib/threads/__init__.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/lib/threads/__init__.py 2008-07-10 06:48:13.000000000 -0400 @@ -0,0 +1,305 @@ +""" +* Experimental * + +Like the map function, but can use a pool of threads. + +Really easy to use threads. eg. tmap(f, alist) + +If you know how to use the map function, you can use threads. +""" + +__author__ = "Rene Dudfield" +__version__ = "0.3.0" +__license__ = 'Python license' + +import traceback, sys + +if (sys.version_info[0] == 2 and sys.version_info[1] < 5): + from Py25Queue import Queue + from Py25Queue import Empty +else: + # use up to date version + from Queue import Queue + from Queue import Empty + +import threading +Thread = threading.Thread + +STOP = object() +FINISH = object() + +# DONE_ONE = object() +# DONE_TWO = object() + +# a default worker queue. +_wq = None + +# if we are using threads or not. This is the number of workers. +_use_workers = 0 + +# Set this to the maximum for the amount of Cores/CPUs +# Note, that the tests early out. +# So it should only test the best number of workers +2 +MAX_WORKERS_TO_TEST = 64 + + + +def init(number_of_workers = 0): + """ Does a little test to see if threading is worth it. + Sets up a global worker queue if it's worth it. + + Calling init() is not required, but is generally better to do. + """ + global _wq, _use_workers + + if number_of_workers: + _use_workers = number_of_workers + else: + _use_workers = benchmark_workers() + + # if it is best to use zero workers, then use that. + _wq = WorkerQueue(_use_workers) + + + + +def quit(): + """ cleans up everything. + """ + global _wq, _use_workers + _wq.stop() + _wq = None + _use_workers = False + + +def benchmark_workers(a_bench_func = None, the_data = None): + """ does a little test to see if workers are at all faster. + Returns the number of workers which works best. + Takes a little bit of time to run, so you should only really call + it once. + You can pass in benchmark data, and functions if you want. + a_bench_func - f(data) + the_data - data to work on. + """ + global _use_workers + + #TODO: try and make this scale better with slower/faster cpus. + # first find some variables so that using 0 workers takes about 1.0 seconds. + # then go from there. + + + # note, this will only work with pygame 1.8rc3+ + # replace the doit() and the_data with something that releases the GIL + + + import pygame + import pygame.transform + import time + + if not a_bench_func: + def doit(x): + return pygame.transform.scale(x, (544, 576)) + else: + doit = a_bench_func + + if not the_data: + thedata = [] + for x in range(10): + thedata.append(pygame.Surface((155,155), 0, 32)) + else: + thedata = the_data + + best = time.time() + 100000000 + best_number = 0 + last_best = -1 + + for num_workers in range(0, MAX_WORKERS_TO_TEST): + + wq = WorkerQueue(num_workers) + t1 = time.time() + for xx in range(20): + print "active count:%s" % threading.activeCount() + results = tmap(doit, thedata, worker_queue = wq) + t2 = time.time() + + wq.stop() + + + total_time = t2 - t1 + print "total time num_workers:%s: time:%s:" % (num_workers, total_time) + + if total_time < best: + last_best = best_number + best_number =num_workers + best = total_time + + if num_workers - best_number > 1: + # We tried to add more, but it didn't like it. + # so we stop with testing at this number. + break + + + return best_number + + + + +class WorkerQueue(object): + + def __init__(self, num_workers = 20): + self.queue = Queue() + self.pool = [] + self._setup_workers(num_workers) + + def _setup_workers(self, num_workers): + """ Sets up the worker threads + NOTE: undefined behaviour if you call this again. + """ + self.pool = [] + + for _ in range(num_workers): + self.pool.append(Thread(target=self.threadloop)) + + for a_thread in self.pool: + a_thread.setDaemon(True) + a_thread.start() + + + def do(self, f, *args, **kwArgs): + """ puts a function on a queue for running later. + """ + self.queue.put((f, args, kwArgs)) + + + def stop(self): + """ Stops the WorkerQueue, waits for all of the threads to finish up. + """ + self.queue.put(STOP) + for thread in self.pool: + thread.join() + + + def threadloop(self): #, finish = False): + """ Loops until all of the tasks are finished. + """ + while True: + args = self.queue.get() + if args is STOP: + self.queue.put(STOP) + self.queue.task_done() + break + else: + try: + args[0](*args[1], **args[2]) + finally: + # clean up the queue, raise the exception. + self.queue.task_done() + #raise + + + def wait(self): + """ waits until all tasks are complete. + """ + self.queue.join() + +class FuncResult: + """ Used for wrapping up a function call so that the results are stored + inside the instances result attribute. + """ + def __init__(self, f, callback = None, errback = None): + """ f - is the function we that we call + callback(result) - this is called when the function(f) returns + errback(exception) - this is called when the function(f) raises + an exception. + """ + self.f = f + self.exception = None + self.callback = callback + self.errback = errback + + def __call__(self, *args, **kwargs): + + #we try to call the function here. If it fails we store the exception. + try: + self.result = self.f(*args, **kwargs) + if self.callback: + self.callback(self.result) + except Exception, e: + self.exception = e + if self.errback: + self.errback(self.exception) + + +def tmap(f, seq_args, num_workers = 20, worker_queue = None, wait = True, stop_on_error = True): + """ like map, but uses a thread pool to execute. + num_workers - the number of worker threads that will be used. If pool + is passed in, then the num_workers arg is ignored. + worker_queue - you can optionally pass in an existing WorkerQueue. + wait - True means that the results are returned when everything is finished. + False means that we return the [worker_queue, results] right away instead. + results, is returned as a list of FuncResult instances. + stop_on_error - + """ + + if worker_queue: + wq = worker_queue + else: + # see if we have a global queue to work with. + if _wq: + wq = _wq + else: + if num_workers == 0: + return map(f, seq_args) + + wq = WorkerQueue(num_workers) + + # we short cut it here if the number of workers is 0. + # normal map should be faster in this case. + if len(wq.pool) == 0: + return map(f, seq_args) + + #print "queue size:%s" % wq.queue.qsize() + + + #TODO: divide the data (seq_args) into even chunks and + # then pass each thread a map(f, equal_part(seq_args)) + # That way there should be less locking, and overhead. + + + + results = [] + for sa in seq_args: + results.append(FuncResult(f)) + wq.do(results[-1], sa) + + + #wq.stop() + + if wait: + #print "wait" + wq.wait() + #print "after wait" + #print "queue size:%s" % wq.queue.qsize() + if wq.queue.qsize(): + raise Exception("buggy threadmap") + # if we created a worker queue, we need to stop it. + if not worker_queue and not _wq: + #print "stoping" + wq.stop() + if wq.queue.qsize(): + um = wq.queue.get() + if not um is STOP: + raise Exception("buggy threadmap") + + + # see if there were any errors. If so raise the first one. This matches map behaviour. + # TODO: the traceback doesn't show up nicely. + # NOTE: TODO: we might want to return the results anyway? This should be an option. + if stop_on_error: + error_ones = filter(lambda x:x.exception, results) + if error_ones: + raise error_ones[0].exception + + return map(lambda x:x.result, results) + else: + return [wq, results] \ No newline at end of file diff -Nru pygame-1.8.0release/lib/threads/Py25Queue.py pygame-1.8.1release/lib/threads/Py25Queue.py --- pygame-1.8.0release/lib/threads/Py25Queue.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/lib/threads/Py25Queue.py 2008-07-07 01:58:04.000000000 -0400 @@ -0,0 +1,216 @@ +"""A multi-producer, multi-consumer queue.""" + +from time import time as _time + +from collections import deque + +__all__ = ['Empty', 'Full', 'Queue'] + +class Empty(Exception): + "Exception raised by Queue.get(block=0)/get_nowait()." + pass + +class Full(Exception): + "Exception raised by Queue.put(block=0)/put_nowait()." + pass + +class Queue: + """Create a queue object with a given maximum size. + + If maxsize is <= 0, the queue size is infinite. + """ + def __init__(self, maxsize=0): + try: + import threading + except ImportError: + import dummy_threading as threading + self._init(maxsize) + # mutex must be held whenever the queue is mutating. All methods + # that acquire mutex must release it before returning. mutex + # is shared between the three conditions, so acquiring and + # releasing the conditions also acquires and releases mutex. + self.mutex = threading.Lock() + # Notify not_empty whenever an item is added to the queue; a + # thread waiting to get is notified then. + self.not_empty = threading.Condition(self.mutex) + # Notify not_full whenever an item is removed from the queue; + # a thread waiting to put is notified then. + self.not_full = threading.Condition(self.mutex) + # Notify all_tasks_done whenever the number of unfinished tasks + # drops to zero; thread waiting to join() is notified to resume + self.all_tasks_done = threading.Condition(self.mutex) + self.unfinished_tasks = 0 + + def task_done(self): + """Indicate that a formerly enqueued task is complete. + + Used by Queue consumer threads. For each get() used to fetch a task, + a subsequent call to task_done() tells the queue that the processing + on the task is complete. + + If a join() is currently blocking, it will resume when all items + have been processed (meaning that a task_done() call was received + for every item that had been put() into the queue). + + Raises a ValueError if called more times than there were items + placed in the queue. + """ + self.all_tasks_done.acquire() + try: + unfinished = self.unfinished_tasks - 1 + if unfinished <= 0: + if unfinished < 0: + raise ValueError('task_done() called too many times') + self.all_tasks_done.notifyAll() + self.unfinished_tasks = unfinished + finally: + self.all_tasks_done.release() + + def join(self): + """Blocks until all items in the Queue have been gotten and processed. + + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer thread calls task_done() + to indicate the item was retrieved and all work on it is complete. + + When the count of unfinished tasks drops to zero, join() unblocks. + """ + self.all_tasks_done.acquire() + try: + while self.unfinished_tasks: + self.all_tasks_done.wait() + finally: + self.all_tasks_done.release() + + def qsize(self): + """Return the approximate size of the queue (not reliable!).""" + self.mutex.acquire() + n = self._qsize() + self.mutex.release() + return n + + def empty(self): + """Return True if the queue is empty, False otherwise (not reliable!).""" + self.mutex.acquire() + n = self._empty() + self.mutex.release() + return n + + def full(self): + """Return True if the queue is full, False otherwise (not reliable!).""" + self.mutex.acquire() + n = self._full() + self.mutex.release() + return n + + def put(self, item, block=True, timeout=None): + """Put an item into the queue. + + If optional args 'block' is true and 'timeout' is None (the default), + block if necessary until a free slot is available. If 'timeout' is + a positive number, it blocks at most 'timeout' seconds and raises + the Full exception if no free slot was available within that time. + Otherwise ('block' is false), put an item on the queue if a free slot + is immediately available, else raise the Full exception ('timeout' + is ignored in that case). + """ + self.not_full.acquire() + try: + if not block: + if self._full(): + raise Full + elif timeout is None: + while self._full(): + self.not_full.wait() + else: + if timeout < 0: + raise ValueError("'timeout' must be a positive number") + endtime = _time() + timeout + while self._full(): + remaining = endtime - _time() + if remaining <= 0.0: + raise Full + self.not_full.wait(remaining) + self._put(item) + self.unfinished_tasks += 1 + self.not_empty.notify() + finally: + self.not_full.release() + + def put_nowait(self, item): + """Put an item into the queue without blocking. + + Only enqueue the item if a free slot is immediately available. + Otherwise raise the Full exception. + """ + return self.put(item, False) + + def get(self, block=True, timeout=None): + """Remove and return an item from the queue. + + If optional args 'block' is true and 'timeout' is None (the default), + block if necessary until an item is available. If 'timeout' is + a positive number, it blocks at most 'timeout' seconds and raises + the Empty exception if no item was available within that time. + Otherwise ('block' is false), return an item if one is immediately + available, else raise the Empty exception ('timeout' is ignored + in that case). + """ + self.not_empty.acquire() + try: + if not block: + if self._empty(): + raise Empty + elif timeout is None: + while self._empty(): + self.not_empty.wait() + else: + if timeout < 0: + raise ValueError("'timeout' must be a positive number") + endtime = _time() + timeout + while self._empty(): + remaining = endtime - _time() + if remaining <= 0.0: + raise Empty + self.not_empty.wait(remaining) + item = self._get() + self.not_full.notify() + return item + finally: + self.not_empty.release() + + def get_nowait(self): + """Remove and return an item from the queue without blocking. + + Only get an item if one is immediately available. Otherwise + raise the Empty exception. + """ + return self.get(False) + + # Override these methods to implement other queue organizations + # (e.g. stack or priority queue). + # These will only be called with appropriate locks held + + # Initialize the queue representation + def _init(self, maxsize): + self.maxsize = maxsize + self.queue = deque() + + def _qsize(self): + return len(self.queue) + + # Check whether the queue is empty + def _empty(self): + return not self.queue + + # Check whether the queue is full + def _full(self): + return self.maxsize > 0 and len(self.queue) == self.maxsize + + # Put a new item in the queue + def _put(self, item): + self.queue.append(item) + + # Get an item from the queue + def _get(self): + return self.queue.popleft() diff -Nru pygame-1.8.0release/lib/version.py pygame-1.8.1release/lib/version.py --- pygame-1.8.0release/lib/version.py 2008-03-28 17:58:10.000000000 -0400 +++ pygame-1.8.1release/lib/version.py 2008-07-28 05:36:47.000000000 -0400 @@ -27,5 +27,5 @@ releases. (hmm, until we get to versions > 10) """ -ver = '1.8.0release' -vernum = 1,8,0 +ver = '1.8.1release' +vernum = 1,8,1 diff -Nru pygame-1.8.0release/msys_build_deps.py pygame-1.8.1release/msys_build_deps.py --- pygame-1.8.0release/msys_build_deps.py 2008-02-11 02:39:21.000000000 -0500 +++ pygame-1.8.1release/msys_build_deps.py 2008-07-07 01:58:41.000000000 -0400 @@ -1,4 +1,6 @@ -# Program build_deps.py +#!/usr/bin/env python +# -*- coding: ascii -*- +# Program msys_build_deps.py # Requires Python 2.4 or later and win32api. """Build Pygame dependencies using MinGW and MSYS @@ -255,6 +257,9 @@ parser.set_defaults(compile=True) parser.add_option('--no-install', action='store_false', dest='install', help="Do not install the libraries") + parser.add_option('--no-strip', action='store_false', dest='strip', + help="Do not strip the library") + parser.set_defaults(strip=True) parser.set_defaults(install=True) parser.add_option('--clean', action='store_true', dest='clean', help="Remove generated files (make clean)" @@ -289,6 +294,9 @@ environ['BDINST'] = as_flag(options.install and options.compile and not options.clean_only) + environ['BDSTRIP'] = as_flag(options.install and + options.strip and + not options.clean_only) environ['BDCLEAN'] = as_flag(options.clean or options.clean_only) environ.pop('INCLUDE', None) # INCLUDE causes problems with MIXER. if 'CFLAGS' not in environ: @@ -438,29 +446,6 @@ # # Build specific code # -# The basic configure/make steps. -basic_build_script = """ - -set -e -cd $BDWD - -if [ x$BDCONF == x1 ]; then - ./configure -fi - -if [ x$BDCOMP == x1 ]; then - make -fi - -if [ x$BDINST == x1 ]; then - make install -fi - -if [ x$BDCLEAN == x1 ]; then - set +e - make clean -fi -""" # This list includes the MSYS shell scripts to build each library. Each script # runs in an environment where MINGW_ROOT_DIRECTORY is defined and the MinGW @@ -500,6 +485,10 @@ make install fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/SDL.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -528,6 +517,10 @@ cp -fp zlib1.dll /usr/local/bin fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/zlib1.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -556,8 +549,32 @@ make clean fi """), - Dependency('FONT', ['SDL_ttf-[2-9].*'], ['SDL_ttf.dll'], - basic_build_script), + Dependency('FONT', ['SDL_ttf-[2-9].*'], ['SDL_ttf.dll'], """ + +set -e +cd $BDWD + +if [ x$BDCONF == x1 ]; then + ./configure +fi + +if [ x$BDCOMP == x1 ]; then + make +fi + +if [ x$BDINST == x1 ]; then + make install +fi + +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/SDL_ttf.dll +fi + +if [ x$BDCLEAN == x1 ]; then + set +e + make clean +fi +"""), Dependency('PNG', ['libpng-[1-9].*'], ['libpng13.dll'], """ set -e @@ -589,6 +606,10 @@ cp -fp libpng13.dll /usr/local/bin fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/libpng13.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -624,6 +645,10 @@ if [ x$? != x0 ]; then exit $?; fi fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/jpeg.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -665,6 +690,10 @@ cd .. fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/libtiff.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -691,6 +720,10 @@ make install fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/SDL_image.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -715,13 +748,41 @@ make install fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/smpeg.dll +fi + +if [ x$BDCLEAN == x1 ]; then + set +e + make clean +fi +"""), + Dependency('OGG', ['libogg-[1-9].*'], ['libogg-0.dll'], """ + +set -e +cd $BDWD + +if [ x$BDCONF == x1 ]; then + ./configure +fi + +if [ x$BDCOMP == x1 ]; then + make +fi + +if [ x$BDINST == x1 ]; then + make install +fi + +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/libogg-0.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean fi """), - Dependency('OGG', ['libogg-[1-9].*'], ['libogg-0.dll'], - basic_build_script), Dependency('VORBIS', ['libvorbis-[1-9].*'], ['libvorbis-0.dll', 'libvorbisfile-3.dll'], """ @@ -741,6 +802,11 @@ make install fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/libvorbis-0.dll + strip --strip-all /usr/local/bin/libvorbisfile-3.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean @@ -763,6 +829,10 @@ make install fi +if [ x$BDSTRIP == x1 ]; then + strip --strip-all /usr/local/bin/SDL_mixer.dll +fi + if [ x$BDCLEAN == x1 ]; then set +e make clean diff -Nru pygame-1.8.0release/PKG-INFO pygame-1.8.1release/PKG-INFO --- pygame-1.8.0release/PKG-INFO 2008-03-28 18:36:50.000000000 -0400 +++ pygame-1.8.1release/PKG-INFO 2008-07-28 05:40:00.000000000 -0400 @@ -1,13 +1,13 @@ -Metadata-Version: 1.0 -Name: pygame -Version: 1.8.0release -Summary: Python Game Development -Home-page: http://www.pygame.org -Author: Pete Shinners, Rene Dudfield, Marcus von Appen, Bob Pendleton, others... -Author-email: pygame@seul.org -License: LGPL -Description: Pygame is a Python wrapper module for the - SDL multimedia library. It contains python functions and classes - that will allow you to use SDL's support for playing cdroms, - audio and video output, and keyboard, mouse and joystick input. -Platform: UNKNOWN +Metadata-Version: 1.0 +Name: pygame +Version: 1.8.1release +Summary: Python Game Development +Home-page: http://www.pygame.org +Author: Pete Shinners, Rene Dudfield, Marcus von Appen, Bob Pendleton, others... +Author-email: pygame@seul.org +License: LGPL +Description: Pygame is a Python wrapper module for the + SDL multimedia library. It contains python functions and classes + that will allow you to use SDL's support for playing cdroms, + audio and video output, and keyboard, mouse and joystick input. +Platform: UNKNOWN diff -Nru pygame-1.8.0release/readme.txt pygame-1.8.1release/readme.txt --- pygame-1.8.0release/readme.txt 2008-03-28 17:58:10.000000000 -0400 +++ pygame-1.8.1release/readme.txt 1969-12-31 19:00:00.000000000 -0500 @@ -1,152 +0,0 @@ - - Pygame Readme - Version 1.8.0release Python Game Development - Originally by Pete Shinners, now an open source community project. - http://www.pygame.org - pete@shinners.org - - About - - Pygame is a cross-platfrom library designed to make it easy to - write multimedia software, such as games, in Python. Pygame - requires the Python language and SDL multimedia library. It can - also make use of several other popular libraries. - - Installation - - You should definitely begin by installing a binary package for your - system. The binary packages usually come with or give the - information needed for dependencies. Choose an appropriate - installer for your system and version of python from the pygame - downloads page. http://www.pygame.org/download.shtml - - Installing from source is fairly automated. The most work will - involve compiling and installing all the pygame dependencies. Once - that is done run the "setup.py" script which will attempt to - auto-configure, build, and install pygame. - - Much more information about installing and compiling is available - in the install.html file. - - Help - - If you are just getting started with pygame, you should be able to - get started fairly quickly. Pygame comes with many tutorials and - introductions. There is also full reference documentation for the - entire library. Browse the documentation from the documenantation - index. docs/index.html. - - On the pygame website, there is also an online copy of this - documentation. You should know that the online documentation stays - up to date with the development version of pygame in svn. This may - be a bit newer than the version of pygame you are using. - - Best of all the examples directory has many playable small programs - which can get started playing with the code right away. - - Credits - - Thanks to everyone who has helped contribute to this library. - Special thanks are also in order. - - - Marcus Von Appen - many changes, and fixes, 1.7.1+ freebsd maintainer. - - Lenard Lindstrom - the 1.8 windows maintainer. - - Brian Fisher - for svn auto builder, bug tracker and many contributions. - - Rene Dudfield - many changes, and fixes, 1.7+ release manager/maintainer. - - Phil Hassey - for his work on the pygame.org website. - - DR0ID for his work on the sprite module. - - Richard Goedeken for his smoothscale function. - - Ulf Ekström for his pixel perfect collision detection code. - - Pete Shinners - orginal author. - - - David Clark - for filling the right-hand-man position - - Ed Boraas and Francis Irving - Debian packages - - Maxim Sobolev - FreeBSD packaging - - Bob Ippolito - MacOS and OS X porting (much work!) - - Jan Ekhol, Ray Kelm, and Peter Nicolai - putting up with my early - design ideas - - Nat Pryce for starting our unit tests - - Dan Richter for documentation work - - TheCorruptor for his incredible logos and graphics - - Thanks to those sending in patches and fixes: Niki Spahiev, Gordon - Tyler, Nathaniel Pryce, Dave Wallace, John Popplewell, Michael Urman, - Andrew Straw, Michael Hudson, Ole Martin Bjoerndalen, Hervé Cauwelier, - James Mazer, Lalo Martins, Timothy Stranex, Chad Lester, Matthias - Spiller, Bo Jangeborg, Dmitry Borisov, Campbell Barton, Diego Essaya, - Eyal Lotem, Regis Desgroppes, Emmanuel Hainry, Randy Kaelber - Matthew L Daniel - - And our bug hunters above and beyond: Angus, Guillaume Proux, Frank - Raiser, Austin Henry, Kaweh Kazemi, Arturo Aldama, Mike Mulcheck, - Michael Benfield, David Lau - - There's many more folks out there who've submitted helpful ideas, kept - this project going, and basically made my life easer, Thanks! - - Many thank you's for people making documentation comments, and adding to the - pygame.org wiki. - - Also many thanks for people creating games and putting them on the - pygame.org website for others to learn from and enjoy. - - Also a big thanks to Roger Dingledine and the crew at SEUL.ORG for our - excellent hosting. - - Dependencies - - Pygame is obviously strongly dependent on SDL and Python. It also - links to and embeds several other smaller libraries. The font - module relies on SDL_tff, which is dependent on freetype. The mixer - (and mixer.music) modules depend on SDL_mixer. The image module - depends on SDL_image, which also can use libjpeg and libpng. The - transform module has an embedded version of SDL_rotozoom for its - own rotozoom function. The surfarray module requires the python - Numeric package for its multidimensional numeric arrays. - - Todo / Ideas (feel free to submit) - * transform.skew() function - * transform.scroll() function - * image filtering (colors,blurs,etc) - * quake-like console with python interpreter - * game lobby. client, simple server, and protocol - * surfarrays should be able to do RGBA along with RGB - * draw with transparancy - * draw large sets of primitives with a single call - * drawing offsets, perhaps as subsurfaces - * new scale2x, scale3x, and scale4x from hiend3d - * switch Numeric to numarray (see docs on how to do both) - * audio resampling - - License - - This library is distributed under GNU LGPL version 2.1, which can - be found in the file "doc/LGPL". I reserve the right to place - future versions of this library under a different license. - http://www.gnu.org/copyleft/lesser.html - - This basically means you can use pygame in any project you want, - but if you make any changes or additions to pygame itself, those - must be released with a compatible license. (preferably submitted - back to the pygame project). Closed source and commercial games are - fine. - - The programs in the "examples" subdirectory are in the public - domain. diff -Nru pygame-1.8.0release/README.txt pygame-1.8.1release/README.txt --- pygame-1.8.0release/README.txt 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/README.txt 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,157 @@ + + Pygame Readme + Version 1.8.1release Python Game Development + Originally by Pete Shinners, now an open source community project. + http://www.pygame.org + pete@shinners.org + + About + + Pygame is a cross-platfrom library designed to make it easy to + write multimedia software, such as games, in Python. Pygame + requires the Python language and SDL multimedia library. It can + also make use of several other popular libraries. + + Installation + + You should definitely begin by installing a binary package for your + system. The binary packages usually come with or give the + information needed for dependencies. Choose an appropriate + installer for your system and version of python from the pygame + downloads page. http://www.pygame.org/download.shtml + + Installing from source is fairly automated. The most work will + involve compiling and installing all the pygame dependencies. Once + that is done run the "setup.py" script which will attempt to + auto-configure, build, and install pygame. + + Much more information about installing and compiling is available + in the install.html file. + + Help + + If you are just getting started with pygame, you should be able to + get started fairly quickly. Pygame comes with many tutorials and + introductions. There is also full reference documentation for the + entire library. Browse the documentation from the documenantation + index. docs/index.html. + + On the pygame website, there is also an online copy of this + documentation. You should know that the online documentation stays + up to date with the development version of pygame in svn. This may + be a bit newer than the version of pygame you are using. + + Best of all the examples directory has many playable small programs + which can get started playing with the code right away. + + Credits + + Thanks to everyone who has helped contribute to this library. + Special thanks are also in order. + + + Marcus Von Appen - many changes, and fixes, 1.7.1+ freebsd maintainer. + + Lenard Lindstrom - the 1.8+ windows maintainer. + + Brian Fisher - for svn auto builder, bug tracker and many contributions. + + Rene Dudfield - many changes, and fixes, 1.7+ release manager/maintainer. + + Phil Hassey - for his work on the pygame.org website. + + DR0ID for his work on the sprite module. + + Richard Goedeken for his smoothscale function. + + Ulf Ekström for his pixel perfect collision detection code. + + Pete Shinners - orginal author. + + + David Clark - for filling the right-hand-man position + + Ed Boraas and Francis Irving - Debian packages + + Maxim Sobolev - FreeBSD packaging + + Bob Ippolito - MacOS and OS X porting (much work!) + + Jan Ekhol, Ray Kelm, and Peter Nicolai - putting up with my early + design ideas + + Nat Pryce for starting our unit tests + + Dan Richter for documentation work + + TheCorruptor for his incredible logos and graphics + + Nicholas Dudfield - many test improvements. + + Alex Folkner - for pygame-ctypes + + Thanks to those sending in patches and fixes: Niki Spahiev, Gordon + Tyler, Nathaniel Pryce, Dave Wallace, John Popplewell, Michael Urman, + Andrew Straw, Michael Hudson, Ole Martin Bjoerndalen, Hervé Cauwelier, + James Mazer, Lalo Martins, Timothy Stranex, Chad Lester, Matthias + Spiller, Bo Jangeborg, Dmitry Borisov, Campbell Barton, Diego Essaya, + Eyal Lotem, Regis Desgroppes, Emmanuel Hainry, Randy Kaelber + Matthew L Daniel, Nirav Patel, Forrest Voight, Charlie Nolan, + Frankie Robertson, John Krukoff, Lorenz Quack, Nick Irvine + + And our bug hunters above and beyond: Angus, Guillaume Proux, Frank + Raiser, Austin Henry, Kaweh Kazemi, Arturo Aldama, Mike Mulcheck, + Michael Benfield, David Lau + + There's many more folks out there who've submitted helpful ideas, kept + this project going, and basically made my life easer, Thanks! + + Many thank you's for people making documentation comments, and adding to the + pygame.org wiki. + + Also many thanks for people creating games and putting them on the + pygame.org website for others to learn from and enjoy. + + Also a big thanks to Roger Dingledine and the crew at SEUL.ORG for our + excellent hosting. + + Dependencies + + Pygame is obviously strongly dependent on SDL and Python. It also + links to and embeds several other smaller libraries. The font + module relies on SDL_tff, which is dependent on freetype. The mixer + (and mixer.music) modules depend on SDL_mixer. The image module + depends on SDL_image, which also can use libjpeg and libpng. The + transform module has an embedded version of SDL_rotozoom for its + own rotozoom function. The surfarray module requires the python + Numeric package for its multidimensional numeric arrays. + + Todo / Ideas (feel free to submit) + * transform.skew() function + * transform.scroll() function + * image filtering (colors,blurs,etc) + * quake-like console with python interpreter + * game lobby. client, simple server, and protocol + * surfarrays should be able to do RGBA along with RGB + * draw with transparancy + * draw large sets of primitives with a single call + * drawing offsets, perhaps as subsurfaces + * new scale2x, scale3x, and scale4x from hiend3d + * switch Numeric to numarray (see docs on how to do both) + * audio resampling + + License + + This library is distributed under GNU LGPL version 2.1, which can + be found in the file "doc/LGPL". I reserve the right to place + future versions of this library under a different license. + http://www.gnu.org/copyleft/lesser.html + + This basically means you can use pygame in any project you want, + but if you make any changes or additions to pygame itself, those + must be released with a compatible license. (preferably submitted + back to the pygame project). Closed source and commercial games are + fine. + + The programs in the "examples" subdirectory are in the public + domain. diff -Nru pygame-1.8.0release/run_tests.py pygame-1.8.1release/run_tests.py --- pygame-1.8.0release/run_tests.py 2008-01-19 21:26:49.000000000 -0500 +++ pygame-1.8.1release/run_tests.py 2008-07-28 05:36:49.000000000 -0400 @@ -1,27 +1,179 @@ -#!/usr/bin/env python -import sys, os, re, unittest +#################################### IMPORTS ################################### +# TODO: clean up imports -main_dir = os.path.split(os.path.abspath(sys.argv[0]))[0] -test_subdir = 'test' +import test.unittest as unittest -# Make sure we're in the correct directory -os.chdir( main_dir ) +import sys, os, re, subprocess, time, optparse +import pygame.threads, pygame -# Add the modules directory to the python path -sys.path.insert( 0, test_subdir ) - -# Load all the tests -suite = unittest.TestSuite() -test_module_re = re.compile('^(.+_test)\.py$') -for file in os.listdir(test_subdir): - for module in test_module_re.findall(file): - if module == "scrap_test": - continue - print 'loading ' + module - __import__( module ) - test = unittest.defaultTestLoader.loadTestsFromName( module ) - suite.addTest( test ) - -# Run the tests -runner = unittest.TextTestRunner() -runner.run( suite ) +from test_runner import prepare_test_env, run_test, combine_results, \ + test_failures, get_test_results, from_namespace, \ + TEST_RESULTS_START + +from pprint import pformat + +main_dir, test_subdir, fake_test_subdir = prepare_test_env() +test_runner_py = os.path.join(main_dir, "test_runner.py") + +import test_utils, unittest_patch + +################################### CONSTANTS ################################## +# Defaults: +# See optparse options below for more options (test_runner.py) +# + +# If an xxxx_test.py takes longer than TIME_OUT seconds it will be killed +# This is only the default, can be over-ridden on command line + +TIME_OUT = 30 + +# Any tests in IGNORE will not be ran +IGNORE = set ([ + "scrap_test", +]) + +# Subprocess has less of a need to worry about interference between tests +SUBPROCESS_IGNORE = set ([ + "scrap_test", +]) + +INTERACTIVE = set ([ + 'cdrom_test' +]) + +################################################################################ +# Set the command line options +# +# Defined in test_runner.py as it shares options, added to here + +from test_runner import opt_parser + +opt_parser.set_usage(""" + +Runs all or some of the test/xxxx_test.py tests. + +$ run_tests.py sprite threads -sd + +Runs the sprite and threads module tests isolated in subprocesses, dumping all +failing tests info in the form of a dict. + +""") + +opt_parser.set_defaults ( + python = sys.executable, + time_out = TIME_OUT, +) + +options, args = opt_parser.parse_args() + +################################################################################ +# Change to working directory and compile a list of test modules +# If options.fake, then compile list of fake xxxx_test.py from run_tests__tests + +TEST_MODULE_RE = re.compile('^(.+_test)\.py$') + +if options.fake: + test_subdir = os.path.join(fake_test_subdir, options.fake ) + sys.path.append(test_subdir) + working_dir = test_subdir +else: + working_dir = main_dir + +test_env = {"PYTHONPATH": test_subdir} #TODO: append to PYTHONPATH +try: + # Required by Python 2.6 on Windows. + test_env["SystemRoot"] = os.environ["SystemRoot"] +except KeyError: + pass +os.chdir(working_dir) + +if args: + test_modules = [ + m.endswith('_test') and m or ('%s_test' % m) for m in args + ] +else: + if options.subprocess: ignore = SUBPROCESS_IGNORE + else: ignore = IGNORE + + # TODO: add option to run only INTERACTIVE, or include them, etc + ignore = ignore | INTERACTIVE + + test_modules = [] + for f in sorted(os.listdir(test_subdir)): + for match in TEST_MODULE_RE.findall(f): + if match not in ignore: + test_modules.append(match) + +################################################################################ +# Single process mode + +if not options.subprocess: + results = {} + unittest_patch.patch(options) + + t = time.time() + for module in test_modules: + results.update(run_test(module, options = options)) + t = time.time() - t + +################################################################################ +# Subprocess mode +# + +if options.subprocess: + from async_sub import proc_in_time_or_kill + + def sub_test(module): + print 'loading', module + + pass_on_args = [a for a in sys.argv[1:] if a not in args] + cmd = [options.python, test_runner_py, module ] + pass_on_args + + return module, (cmd, test_env, working_dir), proc_in_time_or_kill ( + cmd, options.time_out, env = test_env, wd = working_dir, + ) + + if options.multi_thread: + def tmap(f, args): + return pygame.threads.tmap ( + f, args, stop_on_error = False, + num_workers = options.multi_thread + ) + else: tmap = map + + results = {} + t = time.time() + + for module, cmd, (return_code, raw_return) in tmap(sub_test, test_modules): + test_file = '%s.py' % os.path.join(test_subdir, module) + cmd, test_env, working_dir = cmd + + test_results = get_test_results(raw_return) + if test_results: results.update(test_results) + else: results[module] = {} + + add_to_results = [ + 'return_code', 'raw_return', 'cmd', 'test_file', + 'test_env', 'working_dir', 'module', + ] + + results[module].update(from_namespace(locals(), add_to_results)) + + t = time.time() -t + +################################################################################ +# Output Results +# + +untrusty_total, combined = combine_results(results, t) +total, fails = test_failures(results) + +if not options.subprocess: assert total == untrusty_total + +if not options.dump or (options.human and untrusty_total == total): + print combined +else: + print TEST_RESULTS_START + print pformat(options.all and results or fails) + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/search_and_replace.py pygame-1.8.1release/search_and_replace.py --- pygame-1.8.0release/search_and_replace.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/search_and_replace.py 2008-07-22 07:39:52.000000000 -0400 @@ -0,0 +1,54 @@ +#!/usr/bin/python + +import sys +import string + + +def useage(): + print "" + print "useage: search_and_replace.py searchword replaceword " + print "" + +if(__name__ == "__main__"): + if(len(sys.argv) <= 2): + useage() + + else: + + try: + searchword = sys.argv[1] + replaceword = sys.argv[2] + + + except: + print "Error: Could not read the number of spaces that you supplied." + useage() + sys.exit(-1) + + + for x in sys.argv[3:]: + + try: + f = open(x) + except: + print "could not open file:" + x + print "continuing with other files." + break + + file_contents = f.read() + new_contents = file_contents.replace(searchword, replaceword) + + f.close() + # try to write to the file. + + try: + f = open(x, "w") + except: + print "Could not write file:" +x + print "Continuing with other files." + break + f.write(new_contents) + f.close() + + + diff -Nru pygame-1.8.0release/Setup.in pygame-1.8.1release/Setup.in --- pygame-1.8.0release/Setup.in 2008-02-03 17:20:12.000000000 -0500 +++ pygame-1.8.1release/Setup.in 2008-07-07 01:58:40.000000000 -0400 @@ -1,77 +1,78 @@ -#This Setup file is used by the setup.py script to configure the -#python extensions. You will likely use the "config.py" which will -#build a correct Setup file for you based on your system settings. -#If not, the format is simple enough to edit by hand. First change -#the needed commandline flags for each dependency, then comment out -#any unavailable optional modules in the first optional section. - - -#--StartConfig -SDL = -I/usr/include/SDL -D_REENTRANT -lSDL -FONT = -lSDL_ttf -IMAGE = -lSDL_image -MIXER = -lSDL_mixer -SMPEG = -lsmpeg -PNG = -lpng -JPEG = -ljpeg -SCRAP = -lX11 -COPYLIB_SDL -lSDL -Lprebuilt/lib/SDL.dll -COPYLIB_FONT -lSDL_ttf -Lprebuilt/lib/SDL_ttf.dll -COPYLIB_IMAGE -lSDL_image -Lprebuilt/lib/SDL_image.dll -COPYLIB_MIXER -lSDL_mixer -Lprebuilt/lib/SDL_mixer.dll -COPYLIB_SMPEG -lsmpeg -Lprebuilt/lib/smpeg.dll -COPYLIB_TIFF -ltiff -Lprebuilt/lib/libtiff.dll -COPYLIB_PNG -lpng -Lprebuilt/lib/libpng13.dll -COPYLIB_JPEG -ljpeg -Lprebuilt/lib/jpeg.dll -COPYLIB_Z -lz -Lprebuilt/lib/zlib1.dll -COPYLIB_VORBISFILE -lvorbisfile -Lprebuilt/lib/libvorbisfile-3.dll -COPYLIB_VORBIS -lvorbis -Lprebuilt/lib/libvorbis-0.dll -COPYLIB_OGG -logg -Lprebuilt/lib/libogg-0.dll -#--EndConfig - -#DEBUG = -C-W -C-Wall -DEBUG = - -#the following modules are optional. you will want to compile -#everything you can, but you can ignore ones you don't have -#dependencies for, just comment them out - -imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) -font src/font.c $(SDL) $(FONT) $(DEBUG) -mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG) -mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG) -_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG) -_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG) -movie src/movie.c $(SDL) $(SMPEG) $(DEBUG) -scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG) - -#experimental new movie movie. requires libavcodec and libavformat. -#add any necessary compile flags to this line and uncomment. -#movieext src/movie.c src/ffmovie.c $(SDL) -lavcodec -lavformat - - -#these modules are required for pygame to run. they only require -#SDL as a dependency. these should not be altered - -base src/base.c $(SDL) $(DEBUG) -cdrom src/cdrom.c $(SDL) $(DEBUG) -constants src/constants.c $(SDL) $(DEBUG) -display src/display.c $(SDL) $(DEBUG) -event src/event.c $(SDL) $(DEBUG) -fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG) -key src/key.c $(SDL) $(DEBUG) -mouse src/mouse.c $(SDL) $(DEBUG) -rect src/rect.c $(SDL) $(DEBUG) -rwobject src/rwobject.c $(SDL) $(DEBUG) -surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG) -surflock src/surflock.c $(SDL) $(DEBUG) -time src/time.c $(SDL) $(DEBUG) -joystick src/joystick.c $(SDL) $(DEBUG) -draw src/draw.c $(SDL) $(DEBUG) -image src/image.c $(SDL) $(DEBUG) -overlay src/overlay.c $(SDL) $(DEBUG) -transform src/transform.c src/rotozoom.c src/scale2x.c $(SDL) $(DEBUG) -mask src/mask.c src/bitmask.c $(SDL) $(DEBUG) -bufferproxy src/bufferproxy.c $(SDL) $(DEBUG) -pixelarray src/pixelarray.c $(SDL) $(DEBUG) - +#This Setup file is used by the setup.py script to configure the +#python extensions. You will likely use the "config.py" which will +#build a correct Setup file for you based on your system settings. +#If not, the format is simple enough to edit by hand. First change +#the needed commandline flags for each dependency, then comment out +#any unavailable optional modules in the first optional section. + + +#--StartConfig +SDL = -I/usr/include/SDL -D_REENTRANT -lSDL +FONT = -lSDL_ttf +IMAGE = -lSDL_image +MIXER = -lSDL_mixer +SMPEG = -lsmpeg +PNG = -lpng +JPEG = -ljpeg +SCRAP = -lX11 +COPYLIB_SDL -lSDL -Lprebuilt/lib/SDL.dll +COPYLIB_FONT -lSDL_ttf -Lprebuilt/lib/SDL_ttf.dll +COPYLIB_IMAGE -lSDL_image -Lprebuilt/lib/SDL_image.dll +COPYLIB_MIXER -lSDL_mixer -Lprebuilt/lib/SDL_mixer.dll +COPYLIB_SMPEG -lsmpeg -Lprebuilt/lib/smpeg.dll +COPYLIB_TIFF -ltiff -Lprebuilt/lib/libtiff.dll +COPYLIB_PNG -lpng -Lprebuilt/lib/libpng13.dll +COPYLIB_JPEG -ljpeg -Lprebuilt/lib/jpeg.dll +COPYLIB_Z -lz -Lprebuilt/lib/zlib1.dll +COPYLIB_VORBISFILE -lvorbisfile -Lprebuilt/lib/libvorbisfile-3.dll +COPYLIB_VORBIS -lvorbis -Lprebuilt/lib/libvorbis-0.dll +COPYLIB_OGG -logg -Lprebuilt/lib/libogg-0.dll +#--EndConfig + +#DEBUG = -C-W -C-Wall +DEBUG = + +#the following modules are optional. you will want to compile +#everything you can, but you can ignore ones you don't have +#dependencies for, just comment them out + +imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) +font src/font.c $(SDL) $(FONT) $(DEBUG) +mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG) +mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG) +_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG) +_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG) +movie src/movie.c $(SDL) $(SMPEG) $(DEBUG) +scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG) + +#experimental new movie movie. requires libavcodec and libavformat. +#add any necessary compile flags to this line and uncomment. +#movieext src/movie.c src/ffmovie.c $(SDL) -lavcodec -lavformat + + +#these modules are required for pygame to run. they only require +#SDL as a dependency. these should not be altered + +base src/base.c $(SDL) $(DEBUG) +cdrom src/cdrom.c $(SDL) $(DEBUG) +color src/color.c $(SDL) $(DEBUG) +constants src/constants.c $(SDL) $(DEBUG) +display src/display.c $(SDL) $(DEBUG) +event src/event.c $(SDL) $(DEBUG) +fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG) +key src/key.c $(SDL) $(DEBUG) +mouse src/mouse.c $(SDL) $(DEBUG) +rect src/rect.c $(SDL) $(DEBUG) +rwobject src/rwobject.c $(SDL) $(DEBUG) +surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG) +surflock src/surflock.c $(SDL) $(DEBUG) +time src/time.c $(SDL) $(DEBUG) +joystick src/joystick.c $(SDL) $(DEBUG) +draw src/draw.c $(SDL) $(DEBUG) +image src/image.c $(SDL) $(DEBUG) +overlay src/overlay.c $(SDL) $(DEBUG) +transform src/transform.c src/rotozoom.c src/scale2x.c $(SDL) $(DEBUG) +mask src/mask.c src/bitmask.c $(SDL) $(DEBUG) +bufferproxy src/bufferproxy.c $(SDL) $(DEBUG) +pixelarray src/pixelarray.c $(SDL) $(DEBUG) + diff -Nru pygame-1.8.0release/setup.py pygame-1.8.1release/setup.py --- pygame-1.8.0release/setup.py 2008-03-28 17:58:10.000000000 -0400 +++ pygame-1.8.1release/setup.py 2008-07-28 05:36:49.000000000 -0400 @@ -14,7 +14,7 @@ METADATA = { "name": "pygame", - "version": "1.8.0release", + "version": "1.8.1release", "license": "LGPL", "url": "http://www.pygame.org", "author": "Pete Shinners, Rene Dudfield, Marcus von Appen, Bob Pendleton, others...", @@ -25,12 +25,15 @@ import sys -# hack the version name to a format msi doesn't have trouble with if "bdist_msi" in sys.argv: - METADATA["version"] = METADATA["version"].replace("rc", "b") + # hack the version name to a format msi doesn't have trouble with + METADATA["version"] = METADATA["version"].replace("pre", "a0") + METADATA["version"] = METADATA["version"].replace("rc", "b0") + METADATA["version"] = METADATA["version"].replace("release", "c0s") -if not hasattr(sys, 'version_info') or sys.version_info < (2,2): - raise SystemExit, "Pygame requires Python version 2.2 or above." + +if not hasattr(sys, 'version_info') or sys.version_info < (2,3): + raise SystemExit, "Pygame requires Python version 2.3 or above." #get us to the correct directory import os, sys @@ -52,7 +55,7 @@ "-Wnested-externs -Wshadow -Wredundant-decls" sys.argv.remove ("-warnings") -import os.path, glob +import os.path, glob, stat import distutils.sysconfig from distutils.core import setup, Extension from distutils.extension import read_setup_file @@ -91,6 +94,13 @@ print '\nContinuing With "setup.py"' +try: + s_mtime = os.stat("Setup")[stat.ST_MTIME] + sin_mtime = os.stat("Setup.in")[stat.ST_MTIME] + if sin_mtime > s_mtime: + print '\n\nWARNING, "Setup.in" newer than "Setup", you might need to modify Setup."' +except: + pass #get compile info for all extensions try: extensions = read_setup_file('Setup') @@ -185,12 +195,28 @@ path = os.environ['PATH'] os.environ['PATH'] = ';'.join([os.path.join(mingw_root, 'bin'), path]) - if sys.version_info >= (2, 4): - os.environ - # For an MinGW build requiring msvcr71.dll linkage overide the - # msvcrt.dll import libraries. - os.environ['LIBRARY_PATH'] = ( - os.path.join(self.__sdl_lib_dir, 'msvcr71')) + if sys.version_info >= (2, 6): + # The Visual Studio 2008 C library is msvcr90.dll. + c_runtime_path = os.path.join(self.__sdl_lib_dir, 'msvcr90') + elif sys.version_info >= (2, 4): + # The Visual Studio 2003 C library is msvcr71.dll. + c_runtime_path = os.path.join(self.__sdl_lib_dir, 'msvcr71') + else: + # The Visual Studio 6.0 C library is msvcrt.dll, + # the MinGW default. + c_runtime_path = '' + if c_runtime_path and os.path.isdir(c_runtime_path): + # Override the default msvcrt.dll linkage. + os.environ['LIBRARY_PATH'] = c_runtime_path + elif not (c_runtime_path or + glob.glob(os.path.join(self.__sdl_lib_dir, + 'msvcr*'))): + pass + else: + raise RuntimeError("The dependencies are linked to" + " the wrong C runtime for" + " Python %i.%i" % + sys.version_info[:2]) build_ext.run(self) cmdclass['build_ext'] = WinBuildExt @@ -216,12 +242,46 @@ cmdclass['install_data'] = smart_install_data + +if "bdist_msi" in sys.argv: + # if you are making an msi, we want it to overwrite files + from distutils.command import bdist_msi + import msilib + + class bdist_msi_overwrite_on_install(bdist_msi.bdist_msi): + def run(self): + bdist_msi.bdist_msi.run(self) + + # Remove obsolete files. + comp = "pygame1" # Pygame component + prop = comp # Directory property + records = [("surfarray.pyd", comp, + "SURFAR~1.PYD|surfarray.pyd", prop, 1), + ("sndarray.pyd", comp, + "SNDARRAY.PYD|sndarray.pyd", prop, 1), + ("color.py", comp, "COLOR.PY|color.py", prop, 1), + ("color.pyc", comp, "COLOR.PYC|color.pyc", prop, 1), + ("color.pyo", comp, "COLOR.PYO|color.pyo", prop, 1)] + msilib.add_data(self.db, "RemoveFile", records) + + # Overwrite outdated files. + fullname = self.distribution.get_fullname() + installer_name = self.get_installer_filename(fullname) + print "changing",installer_name,"to overwrite files on install" + + msilib.add_data(self.db, "Property", [("REINSTALLMODE", "amus")]) + self.db.Commit() + + cmdclass['bdist_msi'] = bdist_msi_overwrite_on_install + + #finally, #call distutils with all needed info PACKAGEDATA = { "cmdclass": cmdclass, - "packages": ['pygame', 'pygame.gp2x'], + "packages": ['pygame', 'pygame.gp2x', 'pygame.threads'], "package_dir": {'pygame': 'lib', + 'pygame.threads': 'lib/threads', 'pygame.gp2x': 'lib/gp2x'}, "headers": headers, "ext_modules": extensions, diff -Nru pygame-1.8.0release/src/alphablit.c pygame-1.8.1release/src/alphablit.c --- pygame-1.8.0release/src/alphablit.c 2007-05-29 19:43:35.000000000 -0400 +++ pygame-1.8.1release/src/alphablit.c 2008-07-07 01:57:32.000000000 -0400 @@ -50,6 +50,14 @@ static void blit_blend_min (SDL_BlitInfo * info); static void blit_blend_max (SDL_BlitInfo * info); +static void blit_blend_rgba_add (SDL_BlitInfo * info); +static void blit_blend_rgba_sub (SDL_BlitInfo * info); +static void blit_blend_rgba_mul (SDL_BlitInfo * info); +static void blit_blend_rgba_min (SDL_BlitInfo * info); +static void blit_blend_rgba_max (SDL_BlitInfo * info); + + + static int SoftBlitPyGame (SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, int the_args); @@ -144,6 +152,36 @@ blit_blend_max (&info); break; } + + case PYGAME_BLEND_RGBA_ADD: + { + blit_blend_rgba_add (&info); + break; + } + case PYGAME_BLEND_RGBA_SUB: + { + blit_blend_rgba_sub (&info); + break; + } + case PYGAME_BLEND_RGBA_MULT: + { + blit_blend_rgba_mul (&info); + break; + } + case PYGAME_BLEND_RGBA_MIN: + { + blit_blend_rgba_min (&info); + break; + } + case PYGAME_BLEND_RGBA_MAX: + { + blit_blend_rgba_max (&info); + break; + } + + + + default: { SDL_SetError ("Invalid argument passed to blit."); @@ -161,8 +199,18 @@ return (okay ? 0 : -1); } + + + + + + + +/* --------------------------------------------------------- */ + + static void -blit_blend_add (SDL_BlitInfo * info) +blit_blend_rgba_add (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -185,15 +233,13 @@ { LOOP_UNROLLED4( { - REPEAT_3( + REPEAT_4( { tmp = (*dst) + (*src); (*dst) = (tmp <= 255 ? tmp : 255); src++; dst++; }); - src++; - dst++; }, n, width); src += srcskip; dst += dstskip; @@ -209,9 +255,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -226,10 +272,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -249,8 +295,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -270,7 +316,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -283,7 +329,7 @@ } static void -blit_blend_sub (SDL_BlitInfo * info) +blit_blend_rgba_sub (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -306,15 +352,13 @@ { LOOP_UNROLLED4( { - REPEAT_3( + REPEAT_4( { tmp2 = (*dst) - (*src); (*dst) = (tmp2 >= 0 ? tmp2 : 0); src++; dst++; }); - src++; - dst++; }, n, width); src += srcskip; dst += dstskip; @@ -330,9 +374,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -347,10 +391,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -370,8 +414,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -391,7 +435,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -404,7 +448,7 @@ } static void -blit_blend_mul (SDL_BlitInfo * info) +blit_blend_rgba_mul (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -427,15 +471,13 @@ { LOOP_UNROLLED4( { - REPEAT_3( + REPEAT_4( { tmp = ((*dst) && (*src)) ? ((*dst) * (*src)) >> 8 : 0; (*dst) = (tmp <= 255 ? tmp : 255); src++; dst++; }); - src++; - dst++; }, n, width); src += srcskip; dst += dstskip; @@ -451,9 +493,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MULT (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -468,10 +510,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MULT (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -491,8 +533,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MULT (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -512,7 +554,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MULT (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -525,7 +567,7 @@ } static void -blit_blend_min (SDL_BlitInfo * info) +blit_blend_rgba_min (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -547,15 +589,13 @@ { LOOP_UNROLLED4( { - REPEAT_3( + REPEAT_4( { if ((*src) < (*dst)) (*dst) = (*src); src++; dst++; }); - src++; - dst++; }, n, width); src += srcskip; dst += dstskip; @@ -571,9 +611,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MIN (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -588,10 +628,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MIN (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -611,8 +651,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MIN (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -632,7 +672,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MIN (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -645,7 +685,7 @@ } static void -blit_blend_max (SDL_BlitInfo * info) +blit_blend_rgba_max (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -667,15 +707,13 @@ { LOOP_UNROLLED4( { - REPEAT_3( + REPEAT_4( { if ((*src) > (*dst)) (*dst) = (*src); src++; dst++; }); - src++; - dst++; }, n, width); src += srcskip; dst += dstskip; @@ -692,9 +730,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MAX (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -709,10 +747,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MAX (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -732,8 +770,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_RGBA_MAX (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -753,7 +791,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_RGBA_MAX (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -766,8 +804,23 @@ } -static void -alphablit_alpha (SDL_BlitInfo * info) + + + + + + + + + + + + +/* --------------------------------------------------------- */ + + +static void +blit_blend_add (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -780,12 +833,31 @@ SDL_PixelFormat *dstfmt = info->dst; int srcbpp = srcfmt->BytesPerPixel; int dstbpp = dstfmt->BytesPerPixel; - int dR, dG, dB, dA, sR, sG, sB, sA; + Uint8 dR, dG, dB, dA, sR, sG, sB, sA; Uint32 pixel; + Uint32 tmp; - /* - printf ("Alpha blit with %d and %d\n", srcbpp, dstbpp); - */ + if (srcbpp == 4 && dstbpp == 4) + { + while (height--) + { + LOOP_UNROLLED4( + { + REPEAT_3( + { + tmp = (*dst) + (*src); + (*dst) = (tmp <= 255 ? tmp : 255); + src++; + dst++; + }); + src++; + dst++; + }, n, width); + src += srcskip; + dst += dstskip; + } + return; + } if (srcbpp == 1) { @@ -795,9 +867,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -812,10 +884,10 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -835,8 +907,8 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -856,7 +928,7 @@ GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); - ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -868,8 +940,8 @@ } } -static void -alphablit_colorkey (SDL_BlitInfo * info) +static void +blit_blend_sub (SDL_BlitInfo * info) { int n; int width = info->d_width; @@ -882,14 +954,31 @@ SDL_PixelFormat *dstfmt = info->dst; int srcbpp = srcfmt->BytesPerPixel; int dstbpp = dstfmt->BytesPerPixel; - int dR, dG, dB, dA, sR, sG, sB, sA; - int alpha = srcfmt->alpha; - Uint32 colorkey = srcfmt->colorkey; + Uint8 dR, dG, dB, dA, sR, sG, sB, sA; Uint32 pixel; + Sint32 tmp2; - /* - printf ("Colorkey blit with %d and %d\n", srcbpp, dstbpp); - */ + if (srcbpp == 4 && dstbpp == 4) + { + while (height--) + { + LOOP_UNROLLED4( + { + REPEAT_3( + { + tmp2 = (*dst) - (*src); + (*dst) = (tmp2 >= 0 ? tmp2 : 0); + src++; + dst++; + }); + src++; + dst++; + }, n, width); + src += srcskip; + dst += dstskip; + } + return; + } if (srcbpp == 1) { @@ -899,10 +988,9 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - sA = (pixel == colorkey) ? 0 : alpha; - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); - ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; dst += dstbpp; @@ -917,8 +1005,610 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - sA = (pixel == colorkey) ? 0 : alpha; + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } + else /* srcbpp > 1 */ + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } +} + +static void +blit_blend_mul (SDL_BlitInfo * info) +{ + int n; + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + Uint8 dR, dG, dB, dA, sR, sG, sB, sA; + Uint32 pixel; + Uint32 tmp; + + if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4) + { + while (height--) + { + LOOP_UNROLLED4( + { + REPEAT_3( + { + tmp = ((*dst) && (*src)) ? ((*dst) * (*src)) >> 8 : 0; + (*dst) = (tmp <= 255 ? tmp : 255); + src++; + dst++; + }); + src++; + dst++; + }, n, width); + src += srcskip; + dst += dstskip; + } + return; + } + + if (srcbpp == 1) + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } + else /* srcbpp > 1 */ + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } +} + +static void +blit_blend_min (SDL_BlitInfo * info) +{ + int n; + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + Uint8 dR, dG, dB, dA, sR, sG, sB, sA; + Uint32 pixel; + + if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4) + { + while (height--) + { + LOOP_UNROLLED4( + { + REPEAT_3( + { + if ((*src) < (*dst)) + (*dst) = (*src); + src++; + dst++; + }); + src++; + dst++; + }, n, width); + src += srcskip; + dst += dstskip; + } + return; + } + + if (srcbpp == 1) + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } + else /* srcbpp > 1 */ + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } +} + +static void +blit_blend_max (SDL_BlitInfo * info) +{ + int n; + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + Uint8 dR, dG, dB, dA, sR, sG, sB, sA; + Uint32 pixel; + + if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4) + { + while (height--) + { + LOOP_UNROLLED4( + { + REPEAT_3( + { + if ((*src) > (*dst)) + (*dst) = (*src); + src++; + dst++; + }); + src++; + dst++; + }, n, width); + src += srcskip; + dst += dstskip; + } + return; + } + + + if (srcbpp == 1) + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } + else /* srcbpp > 1 */ + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } +} + + + + + +/* --------------------------------------------------------- */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +static void +alphablit_alpha (SDL_BlitInfo * info) +{ + int n; + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + int dR, dG, dB, dA, sR, sG, sB, sA; + Uint32 pixel; + + /* + printf ("Alpha blit with %d and %d\n", srcbpp, dstbpp); + */ + + if (srcbpp == 1) + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } + else /* srcbpp > 1 */ + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL(pixel, srcbpp, src); + GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); + GET_PIXEL (pixel, dstbpp, dst); + GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); + ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + } +} + +static void +alphablit_colorkey (SDL_BlitInfo * info) +{ + int n; + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + int dR, dG, dB, dA, sR, sG, sB, sA; + int alpha = srcfmt->alpha; + Uint32 colorkey = srcfmt->colorkey; + Uint32 pixel; + + /* + printf ("Colorkey blit with %d and %d\n", srcbpp, dstbpp); + */ + + if (srcbpp == 1) + { + if (dstbpp == 1) + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + sA = (*src == colorkey) ? 0 : alpha; + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); + ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); + CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); + src += srcbpp; + dst += dstbpp; + }, n, width); + src += srcskip; + dst += dstskip; + } + } + else /* dstbpp > 1 */ + { + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + sA = (*src == colorkey) ? 0 : alpha; GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); @@ -942,7 +1632,7 @@ GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); sA = (pixel == colorkey) ? 0 : alpha; - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; @@ -1006,8 +1696,8 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; @@ -1023,7 +1713,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt); + GET_PIXELVALS_1(sR, sG, sB, sA, src, srcfmt); GET_PIXEL (pixel, dstbpp, dst); GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt); ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA); @@ -1046,7 +1736,7 @@ { GET_PIXEL(pixel, srcbpp, src); GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt); - GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt); + GET_PIXELVALS_1(dR, dG, dB, dA, dst, dstfmt); ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA); CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt); src += srcbpp; @@ -1187,7 +1877,7 @@ int pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) + SDL_Surface * dst, SDL_Rect * dstrect, int the_args) { - return pygame_Blit (src, srcrect, dst, dstrect, 0); + return pygame_Blit (src, srcrect, dst, dstrect, the_args); } diff -Nru pygame-1.8.0release/src/bufferproxy.c pygame-1.8.1release/src/bufferproxy.c --- pygame-1.8.0release/src/bufferproxy.c 2008-02-11 02:39:20.000000000 -0500 +++ pygame-1.8.1release/src/bufferproxy.c 2008-07-07 01:57:33.000000000 -0400 @@ -23,18 +23,6 @@ #include "pygame.h" #include "pygamedocs.h" -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; - static PyObject* _bufferproxy_new (PyTypeObject *type, PyObject *args, PyObject *kwds); static void _bufferproxy_dealloc (PyBufferProxy *self); @@ -178,10 +166,8 @@ { if (self->weakrefs) PyObject_ClearWeakRefs ((PyObject *) self); - if (self->lock) - { - Py_DECREF (self->lock); - } + + Py_XDECREF (self->lock); Py_XDECREF (self->dict); self->ob_type->tp_free ((PyObject *) self); } diff -Nru pygame-1.8.0release/src/cdrom.doc pygame-1.8.1release/src/cdrom.doc --- pygame-1.8.0release/src/cdrom.doc 2006-11-03 21:02:19.000000000 -0500 +++ pygame-1.8.1release/src/cdrom.doc 2008-07-07 01:57:33.000000000 -0400 @@ -219,10 +219,10 @@ get_empty False if a cdrom is in the drive -CD.get_empty(): return True +CD.get_empty(): return bool -Return False if there is a cdrom currently in the drive. If the drive is open -this will return True. +Return False if there is a cdrom currently in the drive. If the drive is +empty this will return True. diff -Nru pygame-1.8.0release/src/color.c pygame-1.8.1release/src/color.c --- pygame-1.8.0release/src/color.c 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/src/color.c 2008-07-07 01:57:32.000000000 -0400 @@ -0,0 +1,1393 @@ +/* + pygame - Python Game Library + Copyright (C) 2008 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#define PYGAMEAPI_COLOR_INTERNAL + +#include "pygamedocs.h" +#include "pygame.h" + +typedef struct +{ + PyObject_HEAD + /* RGBA */ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} PyColor; + +static PyObject *_COLORDICT = NULL; + +static int _get_double (PyObject *obj, double *val); +static int _get_color (PyObject *val, Uint32 *color); +static int _hextoint (char *hex, Uint8 *val); +static int _hexcolor (PyObject *color, Uint8 rgba[]); + +static PyColor* _color_new_internal (PyTypeObject *type, Uint8 rgba[]); +static PyObject* _color_new (PyTypeObject *type, PyObject *args, + PyObject *kwds); +static void _color_dealloc (PyColor *color); +static PyObject* _color_repr (PyColor *color); +static PyObject* _color_normalize (PyColor *color); +static PyObject* _color_correct_gamma (PyColor *color, PyObject *args); + +/* Getters/setters */ +static PyObject* _color_get_r (PyColor *color, void *closure); +static int _color_set_r (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_g (PyColor *color, void *closure); +static int _color_set_g (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_b (PyColor *color, void *closure); +static int _color_set_b (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_a (PyColor *color, void *closure); +static int _color_set_a (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_hsva (PyColor *color, void *closure); +static int _color_set_hsva (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_hsla (PyColor *color, void *closure); +static int _color_set_hsla (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_i1i2i3 (PyColor *color, void *closure); +static int _color_set_i1i2i3 (PyColor *color, PyObject *value, void *closure); +static PyObject* _color_get_cmy (PyColor *color, void *closure); +static int _color_set_cmy (PyColor *color, PyObject *value, void *closure); + +/* Number protocol methods */ +static PyObject* _color_add (PyColor *color1, PyColor *color2); +static PyObject* _color_sub (PyColor *color1, PyColor *color2); +static PyObject* _color_mul (PyColor *color1, PyColor *color2); +static PyObject* _color_div (PyColor *color1, PyColor *color2); +static PyObject* _color_mod (PyColor *color1, PyColor *color2); +static PyObject* _color_inv (PyColor *color); +static int _color_coerce (PyObject **pv, PyObject **pw); +static PyObject* _color_int (PyColor *color); +static PyObject* _color_long (PyColor *color); +static PyObject* _color_float (PyColor *color); +static PyObject* _color_oct (PyColor *color); +static PyObject* _color_hex (PyColor *color); + +/* Sequence protocol methods */ +static Py_ssize_t _color_length (PyColor *color); +static PyObject* _color_item (PyColor *color, Py_ssize_t _index); +static int _color_ass_item (PyColor *color, Py_ssize_t _index, PyObject *value); + +/* C API interfaces */ +static PyObject* PyColor_New (Uint8 rgba[]); +static int RGBAFromColorObj (PyObject *color, Uint8 rgba[]); + +/** + * Methods, which are bound to the PyColor type. + */ +static PyMethodDef _color_methods[] = +{ + { "normalize", (PyCFunction) _color_normalize, METH_NOARGS, + DOC_COLORNORMALIZE }, + { "correct_gamma", (PyCFunction) _color_correct_gamma, METH_VARARGS, + DOC_COLORCORRECTGAMMA }, + { NULL, NULL, 0, NULL } +}; + +/** + * Getters and setters for the PyColor. + */ +static PyGetSetDef _color_getsets[] = +{ + { "r", (getter) _color_get_r, (setter) _color_set_r, DOC_COLORR, NULL }, + { "g", (getter) _color_get_g, (setter) _color_set_g, DOC_COLORG, NULL }, + { "b", (getter) _color_get_b, (setter) _color_set_b, DOC_COLORB, NULL }, + { "a", (getter) _color_get_a, (setter) _color_set_a, DOC_COLORA, NULL }, + { "hsva", (getter) _color_get_hsva, (setter) _color_set_hsva, DOC_COLORHSVA, + NULL }, + { "hsla", (getter) _color_get_hsla, (setter) _color_set_hsla, DOC_COLORHSLA, + NULL }, + { "i1i2i3", (getter) _color_get_i1i2i3, (setter) _color_set_i1i2i3, + DOC_COLORI1I2I3, NULL }, + { "cmy", (getter) _color_get_cmy, (setter) _color_set_cmy, DOC_COLORCMY, + NULL }, + { NULL, NULL, NULL, NULL, NULL } +}; + + +static PyNumberMethods _color_as_number = +{ + (binaryfunc) _color_add, /* nb_add */ + (binaryfunc) _color_sub, /* nb_subtract */ + (binaryfunc) _color_mul, /* nb_multiply */ + (binaryfunc) _color_div, /* nb_divide */ + (binaryfunc) _color_mod, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_nonzero */ + (unaryfunc) _color_inv, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + _color_coerce, /* nb_coerce */ + (unaryfunc) _color_int, /* nb_int */ + (unaryfunc) _color_long, /* nb_long */ + (unaryfunc) _color_float,/* nb_float */ + (unaryfunc) _color_oct, /* nb_oct */ + (unaryfunc) _color_hex, /* nb_hex */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_divide */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + (binaryfunc) _color_div, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ +#if PY_VERSION_HEX >= 0x02050000 + (unaryfunc) _color_int, /* nb_index */ +#endif +}; + +/** + * Sequence interface support for PyColor. + */ +static PySequenceMethods _color_as_sequence = +{ + (lenfunc) _color_length, /* sq_length */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + (ssizeargfunc) _color_item, /* sq_item */ + NULL, /* sq_slice */ + (ssizeobjargproc) _color_ass_item, /* sq_ass_item */ + NULL, /* sq_ass_slice */ + NULL, /* sq_contains */ + NULL, /* sq_inplace_concat */ + NULL, /* sq_inplace_repeat */ +}; + +static PyTypeObject PyColor_Type = +{ + PyObject_HEAD_INIT(NULL) + 0, + "pygame.Color", /* tp_name */ + sizeof (PyColor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) _color_dealloc,/* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc) _color_repr, /* tp_repr */ + &_color_as_number, /* tp_as_number */ + &_color_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + DOC_PYGAMECOLOR, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + _color_methods, /* tp_methods */ + 0, /* tp_members */ + _color_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + _color_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0 /* tp_del */ +}; + +#define PyColor_Check(o) \ + ((o)->ob_type == (PyTypeObject *) &PyColor_Type) + +#define RGB_EQUALS(x,y) \ + ((((PyColor *)x)->r == ((PyColor *)y)->r) && \ + (((PyColor *)x)->g == ((PyColor *)y)->g) && \ + (((PyColor *)x)->b == ((PyColor *)y)->b) && \ + (((PyColor *)x)->a == ((PyColor *)y)->a)) + +static int +_get_double (PyObject *obj, double *val) +{ + PyObject *floatobj; + if (!(floatobj = PyNumber_Float (obj))) + return 0; + *val = PyFloat_AsDouble (floatobj); + Py_DECREF (floatobj); + return 1; +} + +static int +_get_color (PyObject *val, Uint32 *color) +{ + if (!val || !color) + return 0; + + if (PyInt_Check (val)) + { + long intval = PyInt_AsLong (val); + if (intval == -1 && PyErr_Occurred ()) + { + PyErr_SetString (PyExc_ValueError, "invalid color argument"); + return 0; + } + *color = (Uint32) intval; + return 1; + } + else if (PyLong_Check (val)) + { + unsigned long longval = PyLong_AsUnsignedLong (val); + if (PyErr_Occurred ()) + { + PyErr_SetString (PyExc_ValueError, "invalid color argument"); + return 0; + } + *color = (Uint32) longval; + return 1; + } + else + PyErr_SetString (PyExc_ValueError, "invalid color argument"); + return 0; +} + +static int +_hextoint (char *hex, Uint8 *val) +{ + char part[3] = { '\0' }; + char *eptr; + part[0] = hex[0]; + part[1] = hex[1]; + + *val = strtol (part, &eptr, 16); + if (eptr == part) /* Failure */ + return 0; + return 1; +} + +static int +_hexcolor (PyObject *color, Uint8 rgba[]) +{ + size_t len; + char *name = PyString_AsString (color); + if (!name) + return 0; + + len = strlen (name); + /* hex colors can be + * #RRGGBB + * #RRGGBBAA + * 0xRRGGBB + * 0xRRGGBBAA + */ + if (len < 7) + return 0; + + if (name[0] == '#') + { + if (len != 7 && len != 9) + return 0; + if (!_hextoint (name + 1, &rgba[0])) + return 0; + if (!_hextoint (name + 3, &rgba[1])) + return 0; + if (!_hextoint (name + 5, &rgba[2])) + return 0; + rgba[3] = 0; + if (len == 9 && !_hextoint (name + 7, &rgba[3])) + return 0; + return 1; + } + else if (name[0] == '0' && name[1] == 'x') + { + if (len != 8 && len != 10) + return 0; + if (!_hextoint (name + 2, &rgba[0])) + return 0; + if (!_hextoint (name + 4, &rgba[1])) + return 0; + if (!_hextoint (name + 6, &rgba[2])) + return 0; + rgba[3] = 0; + if (len == 10 && !_hextoint (name + 8, &rgba[3])) + return 0; + return 1; + } + return 0; +} + +static PyColor* +_color_new_internal (PyTypeObject *type, Uint8 rgba[]) +{ + PyColor *color = (PyColor *) type->tp_alloc (type, 0); + if (!color) + return NULL; + + color->r = rgba[0]; + color->g = rgba[1]; + color->b = rgba[2]; + color->a = rgba[3]; + + return color; +} + +/** + * Creates a new PyColor. + */ +static PyObject* +_color_new (PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *obj = NULL, *obj1 = NULL, *obj2 = NULL, *obj3 = NULL; + Uint8 rgba[4]; + + if (!PyArg_ParseTuple (args, "O|OOO", &obj, &obj1, &obj2, &obj3)) + return NULL; + + if (PyString_Check (obj)) + { + /* Named color */ + PyObject *color = NULL; + if (obj1 || obj2 || obj3) + return RAISE (PyExc_ValueError, "invalid arguments"); + + color = PyDict_GetItem (_COLORDICT, obj); + if (!color) + { + if (!_hexcolor (obj, rgba)) + return RAISE (PyExc_ValueError, "invalid color name"); + } + else if (!RGBAFromObj (color, rgba)) + return RAISE (PyExc_ValueError, "invalid color"); + + return (PyObject *) _color_new_internal (type, rgba); + } + else if (!obj1) + { + /* Single integer color value or tuple */ + Uint32 color; + if (_get_color (obj, &color)) + { + rgba[0] = (Uint8) (color >> 24); + rgba[1] = (Uint8) (color >> 16); + rgba[2] = (Uint8) (color >> 8); + rgba[3] = (Uint8) color; + } + else if (!RGBAFromObj (obj, rgba)) + return RAISE (PyExc_ValueError, "invalid argument"); + else + return RAISE (PyExc_ValueError, "invalid argument"); + return (PyObject *) _color_new_internal (type, rgba); + } + else + { + Uint32 color = 0; + + /* Color (R,G,B[,A]) */ + if (!_get_color (obj, &color) || color > 255) + return RAISE (PyExc_ValueError, "invalid color argument"); + rgba[0] = (Uint8) color; + if (!_get_color (obj1, &color) || color > 255) + return RAISE (PyExc_ValueError, "invalid color argument"); + rgba[1] = (Uint8) color; + if (!obj2 || !_get_color (obj2, &color) || color > 255) + return RAISE (PyExc_ValueError, "invalid color argument"); + rgba[2] = (Uint8) color; + + if (obj3) + { + if (!_get_color (obj3, &color) || color > 255) + return RAISE (PyExc_ValueError, "invalid color argument"); + rgba[3] = (Uint8) color; + } + else /* No alpha */ + rgba[3] = 255; + return (PyObject *) _color_new_internal (type, rgba); + } +} + +/** + * Deallocates the PyColor. + */ +static void +_color_dealloc (PyColor *color) +{ + color->ob_type->tp_free ((PyObject *) color); +} + +/** + * repr(color) + */ +static PyObject* +_color_repr (PyColor *color) +{ + /* Max. would be (255, 255, 255, 255) */ + char buf[21]; + PyOS_snprintf (buf, sizeof (buf), "(%d, %d, %d, %d)", + color->r, color->g, color->b, color->a); + return PyString_FromString (buf); +} + +/** + * color.normalize () + */ +static PyObject* +_color_normalize (PyColor *color) +{ + double rgba[4]; + rgba[0] = color->r / 255.0; + rgba[1] = color->g / 255.0; + rgba[2] = color->b / 255.0; + rgba[3] = color->a / 255.0; + return Py_BuildValue ("(ffff)", rgba[0], rgba[1], rgba[2], rgba[3]); +} + +/** + * color.correct_gamma (x) + */ +static PyObject* +_color_correct_gamma (PyColor *color, PyObject *args) +{ + double frgba[4]; + Uint8 rgba[4]; + double _gamma; + + if (!PyArg_ParseTuple (args, "d", &_gamma)) + return NULL; + + frgba[0] = pow (color->r / 255.0, _gamma); + frgba[1] = pow (color->g / 255.0, _gamma); + frgba[2] = pow (color->b / 255.0, _gamma); + frgba[3] = pow (color->a / 255.0, _gamma); + + /* visual studio doesn't have a round func, so doing it with +.5 and + * truncaction */ + rgba[0] = (frgba[0] > 1.0) ? 255 : ((frgba[0] < 0.0) ? 0 : + (Uint8) (frgba[0] * 255 + .5)); + rgba[1] = (frgba[1] > 1.0) ? 255 : ((frgba[1] < 0.0) ? 0 : + (Uint8) (frgba[1] * 255 + .5)); + rgba[2] = (frgba[2] > 1.0) ? 255 : ((frgba[2] < 0.0) ? 0 : + (Uint8) (frgba[2] * 255 + .5)); + rgba[3] = (frgba[3] > 1.0) ? 255 : ((frgba[3] < 0.0) ? 0 : + (Uint8) (frgba[3] * 255 + .5)); + return (PyObject *) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * color.r + */ +static PyObject* +_color_get_r (PyColor *color, void *closure) +{ + return PyInt_FromLong (color->r); +} + +/** + * color.r = x + */ +static int +_color_set_r (PyColor *color, PyObject *value, void *closure) +{ + Uint32 c; + if (!_get_color (value, &c)) + return -1; + if (c > 255) + { + PyErr_SetString (PyExc_ValueError, "color exceeds allowed range"); + return -1; + } + color->r = c; + return 0; +} + +/** + * color.g + */ +static PyObject* +_color_get_g (PyColor *color, void *closure) +{ + return PyInt_FromLong (color->g); +} + +/** + * color.g = x + */ +static int +_color_set_g (PyColor *color, PyObject *value, void *closure) +{ + Uint32 c; + if (!_get_color (value, &c)) + return -1; + if (c > 255) + { + PyErr_SetString (PyExc_ValueError, "color exceeds allowed range"); + return -1; + } + color->g = c; + return 0; +} + +/** + * color.b + */ +static PyObject* +_color_get_b (PyColor *color, void *closure) +{ + return PyInt_FromLong (color->b); +} + +/** + * color.b = x + */ +static int +_color_set_b (PyColor *color, PyObject *value, void *closure) +{ + Uint32 c; + if (!_get_color (value, &c)) + return -1; + if (c > 255) + { + PyErr_SetString (PyExc_ValueError, "color exceeds allowed range"); + return -1; + } + color->b = c; + return 0; +} + +/** + * color.a + */ +static PyObject* +_color_get_a (PyColor *color, void *closure) +{ + return PyInt_FromLong (color->a); +} + +/** + * color.a = x + */ +static int +_color_set_a (PyColor *color, PyObject *value, void *closure) +{ + Uint32 c; + if (!_get_color (value, &c)) + return -1; + if (c > 255) + { + PyErr_SetString (PyExc_ValueError, "color exceeds allowed range"); + return -1; + } + color->a = c; + return 0; +} + +/** + * color.hsva + */ +static PyObject* +_color_get_hsva (PyColor *color, void *closure) +{ + double hsv[3] = { 0, 0, 0 }; + double frgb[4]; + double minv, maxv, diff; + + /* Normalize */ + frgb[0] = color->r / 255.0; + frgb[1] = color->g / 255.0; + frgb[2] = color->b / 255.0; + frgb[3] = color->a / 255.0; + + maxv = MAX (MAX (frgb[0], frgb[1]), frgb[2]); + minv = MIN (MIN (frgb[0], frgb[1]), frgb[2]); + diff = maxv - minv; + + /* Calculate V */ + hsv[2] = 100. * maxv; + + if (maxv == minv) + { + hsv[0] = 0; + hsv[1] = 0; + return Py_BuildValue ("(ffff)", hsv[0], hsv[1], hsv[2], frgb[3] * 100); + } + /* Calculate S */ + hsv[1] = 100. * (maxv - minv) / maxv; + + /* Calculate H */ + if (maxv == frgb[0]) + hsv[0] = fmod ((60 * ((frgb[1] - frgb[2]) / diff)), 360.f); + else if (maxv == frgb[1]) + hsv[0] = (60 * ((frgb[2] - frgb[0]) / diff)) + 120.f; + else + hsv[0] = (60 * ((frgb[0] - frgb[1]) / diff)) + 240.f; + + if (hsv[0] < 0) + hsv[0] += 360.f; + + /* H,S,V,A */ + return Py_BuildValue ("(ffff)", hsv[0], hsv[1], hsv[2], frgb[3] * 100); +} + +static int +_color_set_hsva (PyColor *color, PyObject *value, void *closure) +{ + PyObject *item; + double hsva[4] = { 0, 0, 0, 0 }; + double f, p, q, t, v, s; + int hi; + + if (!PySequence_Check (value) || PySequence_Size (value) < 3) + { + PyErr_SetString (PyExc_ValueError, "invalid HSVA value"); + return -1; + } + + /* H */ + item = PySequence_GetItem (value, 0); + if (!item || !_get_double (item, &(hsva[0])) || + hsva[0] < 0 || hsva[0] > 360) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSVA value"); + return -1; + } + Py_DECREF (item); + + /* S */ + item = PySequence_GetItem (value, 1); + if (!item || !_get_double (item, &(hsva[1])) || + hsva[1] < 0 || hsva[1] > 100) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSVA value"); + return -1; + } + Py_DECREF (item); + + /* V */ + item = PySequence_GetItem (value, 2); + if (!item || !_get_double (item, &(hsva[2])) || + hsva[2] < 0 || hsva[2] > 100) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSVA value"); + return -1; + } + Py_DECREF (item); + + /* A */ + if (PySequence_Size (value) > 3) + { + item = PySequence_GetItem (value, 3); + if (!item || !_get_double (item, &(hsva[3])) || + hsva[3] < 0 || hsva[3] > 100) + { + Py_DECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSVA value"); + return -1; + } + Py_DECREF (item); + } + + color->a = (Uint8) ((hsva[3] / 100.0f) * 255); + + s = hsva[1] / 100.f; + v = hsva[2] / 100.f; + + hi = (int) floor (hsva[0] / 60.f); + f = (hsva[0] / 60.f) - hi; + p = v * (1 - s); + q = v * (1 - s * f); + t = v * (1 - s * (1 - f)); + + switch (hi) + { + case 0: + color->r = (Uint8) (v * 255); + color->g = (Uint8) (t * 255); + color->b = (Uint8) (p * 255); + break; + case 1: + color->r = (Uint8) (q * 255); + color->g = (Uint8) (v * 255); + color->b = (Uint8) (p * 255); + break; + case 2: + color->r = (Uint8) (p * 255); + color->g = (Uint8) (v * 255); + color->b = (Uint8) (t * 255); + break; + case 3: + color->r = (Uint8) (p * 255); + color->g = (Uint8) (q * 255); + color->b = (Uint8) (v * 255); + break; + case 4: + color->r = (Uint8) (t * 255); + color->g = (Uint8) (p * 255); + color->b = (Uint8) (v * 255); + break; + case 5: + color->r = (Uint8) (v * 255); + color->g = (Uint8) (p * 255); + color->b = (Uint8) (q * 255); + break; + default: + PyErr_SetString (PyExc_OverflowError, + "this is not allowed to happen ever"); + return -1; + } + + return 0; +} + +/** + * color.hsla + */ +static PyObject* +_color_get_hsla (PyColor *color, void *closure) +{ + double hsl[3] = { 0, 0, 0 }; + double frgb[4]; + double minv, maxv, diff; + + /* Normalize */ + frgb[0] = color->r / 255.0; + frgb[1] = color->g / 255.0; + frgb[2] = color->b / 255.0; + frgb[3] = color->a / 255.0; + + maxv = MAX (MAX (frgb[0], frgb[1]), frgb[2]); + minv = MIN (MIN (frgb[0], frgb[1]), frgb[2]); + + diff = maxv - minv; + + /* Calculate L */ + hsl[2] = 50.f * (maxv + minv); /* 1/2 (max + min) */ + + if (maxv == minv) + { + hsl[1] = 0; + hsl[0] = 0; + return Py_BuildValue ("(ffff)", hsl[0], hsl[1], hsl[2], frgb[3] * 100); + } + + /* Calculate S */ + if (hsl[2] <= 50) + hsl[1] = diff / (maxv + minv); + else + hsl[1] = diff / (2 - maxv - minv); + hsl[1] *= 100.f; + + /* Calculate H */ + if (maxv == frgb[0]) + hsl[0] = fmod ((60 * ((frgb[1] - frgb[2]) / diff)), 360.f); + else if (maxv == frgb[1]) + hsl[0] = (60 * ((frgb[2] - frgb[0]) / diff)) + 120.f; + else + hsl[0] = (60 * ((frgb[0] - frgb[1]) / diff)) + 240.f; + if (hsl[0] < 0) + hsl[0] += 360.f; + + /* H,S,L,A */ + return Py_BuildValue ("(ffff)", hsl[0], hsl[1], hsl[2], frgb[3] * 100); +} + +/** + * color.hsla = x + */ +static int +_color_set_hsla (PyColor *color, PyObject *value, void *closure) +{ + PyObject *item; + double hsla[4] = { 0, 0, 0, 0 }; + double ht, h, q, p = 0, s, l = 0; + static double onethird = 1.0 / 3.0f; + + if (!PySequence_Check (value) || PySequence_Size (value) < 3) + { + PyErr_SetString (PyExc_ValueError, "invalid HSLA value"); + return -1; + } + + /* H */ + item = PySequence_GetItem (value, 0); + if (!item || !_get_double (item, &(hsla[0])) || + hsla[0] < 0 || hsla[0] > 360) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSLA value"); + return -1; + } + Py_DECREF (item); + + /* S */ + item = PySequence_GetItem (value, 1); + if (!item || !_get_double (item, &(hsla[1])) || + hsla[1] < 0 || hsla[1] > 100) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSLA value"); + return -1; + } + Py_DECREF (item); + + /* L */ + item = PySequence_GetItem (value, 2); + if (!item || !_get_double (item, &(hsla[2])) || + hsla[2] < 0 || hsla[2] > 100) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSLA value"); + return -1; + } + Py_DECREF (item); + + /* A */ + if (PySequence_Size (value) > 3) + { + item = PySequence_GetItem (value, 3); + if (!item || !_get_double (item, &(hsla[3])) || + hsla[3] < 0 || hsla[3] > 100) + { + Py_DECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid HSLA value"); + return -1; + } + Py_DECREF (item); + } + + color->a = (Uint8) ((hsla[3] / 100.f) * 255); + + s = hsla[1] / 100.f; + l = hsla[2] / 100.f; + + if (s == 0) + { + color->r = (Uint8) (l * 255); + color->g = (Uint8) (l * 255); + color->b = (Uint8) (l * 255); + return 0; + } + + if (l < 0.5f) + q = l * (1 + s); + else + q = l + s - (l * s); + p = 2 * l - q; + + ht = hsla[0] / 360.f; + + /* Calulate R */ + h = ht + onethird; + if (h < 0) + h += 1; + else if (h > 1) + h -= 1; + + if (h < 1./6.f) + color->r = (Uint8) ((p + ((q - p) * 6 * h)) * 255); + else if (h < 0.5f) + color->r = (Uint8) (q * 255); + else if (h < 2./3.f) + color->r = (Uint8) ((p + ((q - p) * 6 * (2./3.f - h))) * 255); + else + color->r = (Uint8) (p * 255); + + /* Calculate G */ + h = ht; + if (h < 0) + h += 1; + else if (h > 1) + h -= 1; + + if (h < 1./6.f) + color->g = (Uint8) ((p + ((q - p) * 6 * h)) * 255); + else if (h < 0.5f) + color->g = (Uint8) (q * 255); + else if (h < 2./3.f) + color->g = (Uint8) ((p + ((q - p) * 6 * (2./3.f - h))) * 255); + else + color->g = (Uint8) (p * 255); + + /* Calculate B */ + h = ht - onethird; + if (h < 0) + h += 1; + else if (h > 1) + h -= 1; + + if (h < 1./6.f) + color->b = (Uint8) ((p + ((q - p) * 6 * h)) * 255); + else if (h < 0.5f) + color->b = (Uint8) (q * 255); + else if (h < 2./3.f) + color->b = (Uint8) ((p + ((q - p) * 6 * (2./3.f - h))) * 255); + else + color->b = (Uint8) (p * 255); + + return 0; +} + +static PyObject* +_color_get_i1i2i3 (PyColor *color, void *closure) +{ + double i1i2i3[3] = { 0, 0, 0 }; + double frgb[3]; + + /* Normalize */ + frgb[0] = color->r / 255.0; + frgb[1] = color->g / 255.0; + frgb[2] = color->b / 255.0; + + i1i2i3[0] = (frgb[0] + frgb[1] + frgb[2]) / 3.0f; + i1i2i3[1] = (frgb[0] - frgb[2]) / 2.0f; + i1i2i3[2] = (2 * frgb[1] - frgb[0] - frgb[2]) / 4.0f; + + return Py_BuildValue ("(fff)", i1i2i3[0], i1i2i3[1], i1i2i3[2]); +} + +static int +_color_set_i1i2i3 (PyColor *color, PyObject *value, void *closure) +{ + PyObject *item; + double i1i2i3[3] = { 0, 0, 0 }; + double ar, ag, ab; + + /* I1 */ + item = PySequence_GetItem (value, 0); + if (!item || !_get_double (item, &(i1i2i3[0])) || + i1i2i3[0] < 0 || i1i2i3[0] > 1) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid I1I2I3 value"); + return -1; + } + Py_DECREF (item); + + /* I2 */ + item = PySequence_GetItem (value, 1); + if (!item || !_get_double (item, &(i1i2i3[1])) || + i1i2i3[1] < -0.5f || i1i2i3[1] > 0.5f) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid I1I2I3 value"); + return -1; + } + Py_DECREF (item); + + /* I3 */ + item = PySequence_GetItem (value, 2); + if (!item || !_get_double (item, &(i1i2i3[2])) || + i1i2i3[2] < -0.5f || i1i2i3[2] > 0.5f) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid I1I2I3 value"); + return -1; + } + Py_DECREF (item); + + ab = i1i2i3[0] - i1i2i3[1] - 2 * i1i2i3[2] / 3.f; + ar = 2 * i1i2i3[1] + ab; + ag = 3 * i1i2i3[0] - ar - ab; + + color->r = (Uint8) (ar * 255); + color->g = (Uint8) (ag * 255); + color->b = (Uint8) (ab * 255); + + return 0; +} + +static PyObject* +_color_get_cmy (PyColor *color, void *closure) +{ + double cmy[3] = { 0, 0, 0 }; + double frgb[3]; + + /* Normalize */ + frgb[0] = color->r / 255.0; + frgb[1] = color->g / 255.0; + frgb[2] = color->b / 255.0; + + cmy[0] = 1.0 - frgb[0]; + cmy[1] = 1.0 - frgb[1]; + cmy[2] = 1.0 - frgb[2]; + + return Py_BuildValue ("(fff)", cmy[0], cmy[1], cmy[2]); +} + +static int +_color_set_cmy (PyColor *color, PyObject *value, void *closure) +{ + PyObject *item; + double cmy[3] = { 0, 0, 0 }; + + /* I1 */ + item = PySequence_GetItem (value, 0); + if (!item || !_get_double (item, &(cmy[0])) || cmy[0] < 0 || cmy[0] > 1) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid CMY value"); + return -1; + } + Py_DECREF (item); + + /* I2 */ + item = PySequence_GetItem (value, 1); + if (!item || !_get_double (item, &(cmy[1])) || cmy[1] < 0 || cmy[1] > 1) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid CMY value"); + return -1; + } + Py_DECREF (item); + + /* I2 */ + item = PySequence_GetItem (value, 2); + if (!item || !_get_double (item, &(cmy[2])) || cmy[2] < 0 || cmy[2] > 1) + { + Py_XDECREF (item); + PyErr_SetString (PyExc_ValueError, "invalid CMY value"); + return -1; + } + Py_DECREF (item); + + color->r = (Uint8) ((1.0 - cmy[0]) * 255); + color->g = (Uint8) ((1.0 - cmy[1]) * 255); + color->b = (Uint8) ((1.0 - cmy[2]) * 255); + + return 0; +} + +/* Number protocol methods */ + +/** + * color1 + color2 + */ +static PyObject* +_color_add (PyColor *color1, PyColor *color2) +{ + Uint8 rgba[4]; + rgba[0] = MIN (color1->r + color2->r, 255); + rgba[1] = MIN (color1->g + color2->g, 255); + rgba[2] = MIN (color1->b + color2->b, 255); + rgba[3] = MIN (color1->a + color2->a, 255); + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * color1 - color2 + */ +static PyObject* +_color_sub (PyColor *color1, PyColor *color2) +{ + Uint8 rgba[4]; + rgba[0] = MAX (color1->r - color2->r, 0); + rgba[1] = MAX (color1->g - color2->g, 0); + rgba[2] = MAX (color1->b - color2->b, 0); + rgba[3] = MAX (color1->a - color2->a, 0); + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * color1 * color2 + */ +static PyObject* +_color_mul (PyColor *color1, PyColor *color2) +{ + Uint8 rgba[4]; + rgba[0] = MIN (color1->r * color2->r, 255); + rgba[1] = MIN (color1->g * color2->g, 255); + rgba[2] = MIN (color1->b * color2->b, 255); + rgba[3] = MIN (color1->a * color2->a, 255); + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * color1 / color2 + */ +static PyObject* +_color_div (PyColor *color1, PyColor *color2) +{ + Uint8 rgba[4] = { 0, 0, 0, 0 }; + if (color2->r != 0) + rgba[0] = color1->r / color2->r; + if (color2->g != 0) + rgba[1] = color1->g / color2->g; + if (color2->b) + rgba[2] = color1->b / color2->b; + if (color2->a) + rgba[3] = color1->a / color2->a; + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * color1 % color2 + */ +static PyObject* +_color_mod (PyColor *color1, PyColor *color2) +{ + Uint8 rgba[4]; + rgba[0] = color1->r % color2->r; + rgba[1] = color1->g % color2->g; + rgba[2] = color1->b % color2->b; + rgba[3] = color1->a % color2->a; + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * ~color + */ +static PyObject* +_color_inv (PyColor *color) +{ + Uint8 rgba[4]; + rgba[0] = 255 - color->r; + rgba[1] = 255 - color->g; + rgba[2] = 255 - color->b; + rgba[3] = 255 - color->a; + return (PyObject*) _color_new_internal (&PyColor_Type, rgba); +} + +/** + * coerce (color1, color2) + */ +static int +_color_coerce (PyObject **pv, PyObject **pw) +{ + if (PyColor_Check (*pw)) + { + Py_INCREF (*pv); + Py_INCREF (*pw); + return 0; + } + return 1; +} + +/** + * int(color) + */ +static PyObject* +_color_int (PyColor *color) +{ + unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) + + color->a; + if (tmp < INT_MAX) + return PyInt_FromLong ((long) tmp); + return PyLong_FromUnsignedLong (tmp); +} + +/** + * long(color) + */ +static PyObject* +_color_long (PyColor *color) +{ + unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) + + color->a; + return PyLong_FromUnsignedLong (tmp); +} + +/** + * float(color) + */ +static PyObject* +_color_float (PyColor *color) +{ + unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) + + color->a; + return PyFloat_FromDouble ((double) tmp); +} + +/** + * oct(color) + */ +static PyObject* +_color_oct (PyColor *color) +{ + char buf[100]; + unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) + + color->a; + if (tmp < INT_MAX) + PyOS_snprintf (buf, sizeof (buf), "0%lo", tmp); + else + PyOS_snprintf (buf, sizeof (buf), "0%loL", tmp); + return PyString_FromString (buf); +} + +/** + * hex(color) + */ +static PyObject* +_color_hex (PyColor *color) +{ + char buf[100]; + unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) + + color->a; + if (tmp < INT_MAX) + PyOS_snprintf (buf, sizeof (buf), "0x%lx", tmp); + else + { +#if PY_VERSION_HEX >= 0x02050000 + PyOS_snprintf (buf, sizeof (buf), "0x%lxL", tmp); +#else + /* <= 2.4 uses capitalised hex chars. */ + PyOS_snprintf (buf, sizeof (buf), "0x%lXL", tmp); +#endif + } + return PyString_FromString (buf); +} + +/* Sequence protocol methods */ + +/** + * len (color) + */ +static Py_ssize_t +_color_length (PyColor *color) +{ + return 4; +} + +/** + * color[x] + */ +static PyObject* +_color_item (PyColor *color, Py_ssize_t _index) +{ + switch (_index) + { + case 0: + return PyInt_FromLong (color->r); + case 1: + return PyInt_FromLong (color->g); + case 2: + return PyInt_FromLong (color->b); + case 3: + return PyInt_FromLong (color->a); + default: + return RAISE (PyExc_IndexError, "invalid index"); + } +} + +/** + * color[x] = y + */ +static int +_color_ass_item (PyColor *color, Py_ssize_t _index, PyObject *value) +{ + switch (_index) + { + case 0: + return _color_set_r (color, value, NULL); + case 1: + return _color_set_g (color, value, NULL); + case 2: + return _color_set_b (color, value, NULL); + case 3: + return _color_set_a (color, value, NULL); + default: + PyErr_SetString (PyExc_IndexError, "invalid index"); + break; + } + return -1; +} + +/**** C API interfaces ****/ +static PyObject* +PyColor_New (Uint8 rgba[]) +{ + return (PyObject *) _color_new_internal (&PyColor_Type, rgba); +} + +static int +RGBAFromColorObj (PyObject *color, Uint8 rgba[]) +{ + if (PyColor_Check (color)) + { + rgba[0] = ((PyColor *) color)->r; + rgba[1] = ((PyColor *) color)->g; + rgba[2] = ((PyColor *) color)->b; + rgba[3] = ((PyColor *) color)->a; + return 1; + } + else + return RGBAFromObj (color, rgba); +} + +PYGAME_EXPORT +void initcolor (void) +{ + PyObject *colordict; + PyObject *module; + PyObject *dict; + PyObject *apiobj; + static void* c_api[PYGAMEAPI_COLOR_NUMSLOTS]; + + if (PyType_Ready (&PyColor_Type) < 0) + return; + + /* create the module */ + module = Py_InitModule3 ("color", NULL, "color module for pygame"); + PyColor_Type.tp_getattro = PyObject_GenericGetAttr; + Py_INCREF (&PyColor_Type); + PyModule_AddObject (module, "Color", (PyObject *) &PyColor_Type); + dict = PyModule_GetDict (module); + + colordict = PyImport_ImportModule ("pygame.colordict"); + if (colordict) + { + PyObject *_dict = PyModule_GetDict (colordict); + PyObject *colors = PyDict_GetItemString (_dict, "THECOLORS"); + Py_INCREF (colors); + Py_INCREF (colors); /* Needed for the _AddObject call beneath */ + _COLORDICT = colors; + PyModule_AddObject (module, "THECOLORS", colors); + Py_DECREF (colordict); + } + + import_pygame_base (); + + c_api[0] = &PyColor_Type; + c_api[1] = PyColor_New; + c_api[2] = RGBAFromColorObj; + + apiobj = PyCObject_FromVoidPtr (c_api, NULL); + PyDict_SetItemString (dict, PYGAMEAPI_LOCAL_ENTRY, apiobj); + Py_DECREF (apiobj); +} diff -Nru pygame-1.8.0release/src/color.doc pygame-1.8.1release/src/color.doc --- pygame-1.8.0release/src/color.doc 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/src/color.doc 2008-07-07 01:57:32.000000000 -0400 @@ -0,0 +1,105 @@ +pygame.Color +pygame object for color representations +pygame.Color(name): Return Color +pygame.Color(r, g, b, a): Return Color +pygame.Color(rgbvalue): Return Color + +The Color class represents RGBA color values using a value range of +0-255. It allows basic arithmetic operations to create new colors, +supports conversions to other color spaces such as HSV or HSL and lets +you adjust single color channels. + +New in pygame 1.8.1. +
        + +r +Gets or sets the red value of the Color. +Color.r: Return int + +The red value of the Color. + + +g +Gets or sets the green value of the Color. +Color.g: Return int + +The green value of the Color. + + +b +Gets or sets the blue value of the Color. +Color.b: Return int + +The blue value of the Color. + + +a +Gets or sets the alpha value of the Color. +Color.a: Return int + +The alpha value of the Color. + + +cmy +Gets or sets the CMY representation of the Color. +Color.cmy: Return tuple + +The CMY representation of the Color. The CMY components are in the +ranges C = [0, 1], M = [0, 1], Y = [0, 1]. Note that this will not +return the absolutely exact CMY values for the set RGB values in all +cases. Due to the RGB mapping from 0-255 and the CMY mapping from 0-1 +rounding errors may cause the CMY values to differ slightly from what +you might expect. + + +hsva +Gets or sets the HSVA representation of the Color. +Color.hsva: Return tuple + +The HSVA representation of the Color. The HSVA components are in the +ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100]. Note that +this will not return the absolutely exact HSV values for the set RGB +values in all cases. Due to the RGB mapping from 0-255 and the HSV +mapping from 0-100 and 0-360 rounding errors may cause the HSV values to +differ slightly from what you might expect. + + +hsla +Gets or sets the HSLA representation of the Color. +Color.hsla: Return tuple + +The HSLA representation of the Color. The HSLA components are in the +ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100]. Note that +this will not return the absolutely exact HSL values for the set RGB +values in all cases. Due to the RGB mapping from 0-255 and the HSL +mapping from 0-100 and 0-360 rounding errors may cause the HSL values to +differ slightly from what you might expect. + + +i1i2i3 +Gets or sets the I1I2I3 representation of the Color. +Color.i1i2i3: Return tuple + +The I1I2I3 representation of the Color. The I1I2I3 components are in the +ranges I1 = [0, 1], I2 = [-0.5, 0.5], I3 = [-0.5, 0.5]. Note that this +will not return the absolutely exact I1I2I3 values for the set RGB +values in all cases. Due to the RGB mapping from 0-255 and the I1I2I3 +mapping from 0-1 rounding errors may cause the I1I2I3 values to differ +slightly from what you might expect. + + +normalize +Returns the normalized RGBA values of the Color. +Color.normalize(): Return tuple + +Returns the normalized RGBA values of the Color as floating point +values. + + +correct_gamma +Applies a certain gamma value to the Color. +Color.correct_gamma (gamma): Return Color + +Applies a certain gamma value to the Color and returns a new Color with +the adjusted RGBA values. + diff -Nru pygame-1.8.0release/src/constants.c pygame-1.8.1release/src/constants.c --- pygame-1.8.0release/src/constants.c 2008-02-13 14:48:58.000000000 -0500 +++ pygame-1.8.1release/src/constants.c 2008-07-07 01:57:33.000000000 -0400 @@ -145,11 +145,28 @@ PyModule_AddIntConstant(module, "SCRAP_CLIPBOARD", 0); PyModule_AddIntConstant(module, "SCRAP_SELECTION", 1); -#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 +/* BLEND_ADD is an alias for BLEND_RGB_ADD +*/ + +#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_ADD PYGAME_BLEND_RGB_ADD +#define PYGAME_BLEND_SUB PYGAME_BLEND_RGB_SUB +#define PYGAME_BLEND_MULT PYGAME_BLEND_RGB_MULT +#define PYGAME_BLEND_MIN PYGAME_BLEND_RGB_MIN +#define PYGAME_BLEND_MAX PYGAME_BLEND_RGB_MAX + +#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 + + DEC_CONSTS(BLEND_ADD, PYGAME_BLEND_ADD); DEC_CONSTS(BLEND_SUB, PYGAME_BLEND_SUB); @@ -157,6 +174,20 @@ DEC_CONSTS(BLEND_MIN, PYGAME_BLEND_MIN); DEC_CONSTS(BLEND_MAX, PYGAME_BLEND_MAX); + DEC_CONSTS(BLEND_RGB_ADD, PYGAME_BLEND_RGB_ADD); + DEC_CONSTS(BLEND_RGB_SUB, PYGAME_BLEND_RGB_SUB); + DEC_CONSTS(BLEND_RGB_MULT, PYGAME_BLEND_RGB_MULT); + DEC_CONSTS(BLEND_RGB_MIN, PYGAME_BLEND_RGB_MIN); + DEC_CONSTS(BLEND_RGB_MAX, PYGAME_BLEND_RGB_MAX); + + DEC_CONSTS(BLEND_RGBA_ADD, PYGAME_BLEND_RGBA_ADD); + DEC_CONSTS(BLEND_RGBA_SUB, PYGAME_BLEND_RGBA_SUB); + DEC_CONSTS(BLEND_RGBA_MULT, PYGAME_BLEND_RGBA_MULT); + DEC_CONSTS(BLEND_RGBA_MIN, PYGAME_BLEND_RGBA_MIN); + DEC_CONSTS(BLEND_RGBA_MAX, PYGAME_BLEND_RGBA_MAX); + + + DEC_CONST(NOEVENT); DEC_CONST(ACTIVEEVENT); DEC_CONST(KEYDOWN); diff -Nru pygame-1.8.0release/src/display.doc pygame-1.8.1release/src/display.doc --- pygame-1.8.0release/src/display.doc 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/display.doc 2008-07-07 01:57:32.000000000 -0400 @@ -124,7 +124,7 @@ pygame.FULLSCREEN create a fullscreen display pygame.DOUBLEBUF recommended for HWSURFACE or OPENGL - pygame.HWSURFACE hardware accelereated, only in FULLSCREEN + pygame.HWSURFACE hardware accelerated, only in FULLSCREEN pygame.OPENGL create an opengl renderable display pygame.RESIZABLE display window should be sizeable pygame.NOFRAME display window will have no border or controls @@ -280,7 +280,7 @@ After calling pygame.display.set_mode() with the pygame.OPENGL flag, it is a good idea to check the value of any requested OpenGL attributes. See -pygame.display.get_set_attribute() for a list of valid flags. +pygame.display.gl_set_attribute() for a list of valid flags. diff -Nru pygame-1.8.0release/src/draw.c pygame-1.8.1release/src/draw.c --- pygame-1.8.0release/src/draw.c 2007-06-26 19:13:00.000000000 -0400 +++ pygame-1.8.1release/src/draw.c 2008-07-07 01:57:32.000000000 -0400 @@ -69,7 +69,7 @@ if(surf->format->BytesPerPixel !=3 && surf->format->BytesPerPixel != 4) return RAISE(PyExc_ValueError, "unsupported bit depth for aaline draw (supports 32 & 24 bit)"); - if(RGBAFromObj(colorobj, rgba)) + if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -136,7 +136,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -208,7 +208,7 @@ if(surf->format->BytesPerPixel !=3 && surf->format->BytesPerPixel != 4) return RAISE(PyExc_ValueError, "unsupported bit depth for aaline draw (supports 32 & 24 bit)"); - if(RGBAFromObj(colorobj, rgba)) + if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -298,7 +298,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -391,7 +391,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -445,7 +445,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -499,7 +499,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -563,7 +563,7 @@ if(PyInt_Check(colorobj)) color = (Uint32)PyInt_AsLong(colorobj); - else if(RGBAFromObj(colorobj, rgba)) + else if(RGBAFromColorObj(colorobj, rgba)) color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE(PyExc_TypeError, "invalid color argument"); @@ -962,6 +962,15 @@ xd = x2-x1; yd = y2-y1; + + if (xd == 0 && yd == 0) + { + /* Single point. Due to the nature of the aaline clipping, this + * is less exact than the normal line. */ + set_at (surf, x1, y1, color); + return; + } + if(fabs(xd)>fabs(yd)) { if(x1>x2) { swaptmp=x1; x1=x2; x2=swaptmp; @@ -1569,6 +1578,7 @@ /*imported needed apis*/ import_pygame_base(); + import_pygame_color(); import_pygame_rect(); import_pygame_surface(); } diff -Nru pygame-1.8.0release/src/font.c pygame-1.8.1release/src/font.c --- pygame-1.8.0release/src/font.c 2007-06-26 19:13:00.000000000 -0400 +++ pygame-1.8.1release/src/font.c 2008-07-07 01:57:32.000000000 -0400 @@ -257,14 +257,14 @@ &bg_rgba_obj)) return NULL; - if (!RGBAFromObj (fg_rgba_obj, rgba)) + if (!RGBAFromColorObj (fg_rgba_obj, rgba)) return RAISE (PyExc_TypeError, "Invalid foreground RGBA argument"); foreg.r = rgba[0]; foreg.g = rgba[1]; foreg.b = rgba[2]; if (bg_rgba_obj) { - if (!RGBAFromObj (bg_rgba_obj, rgba)) + if (!RGBAFromColorObj (bg_rgba_obj, rgba)) return RAISE (PyExc_TypeError, "Invalid background RGBA argument"); backg.r = rgba[0]; backg.g = rgba[1]; @@ -718,6 +718,7 @@ /*imported needed apis*/ import_pygame_base (); + import_pygame_color (); import_pygame_surface (); import_pygame_rwobject (); } diff -Nru pygame-1.8.0release/src/image.c pygame-1.8.1release/src/image.c --- pygame-1.8.0release/src/image.c 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/src/image.c 2008-07-07 01:57:32.000000000 -0400 @@ -26,6 +26,7 @@ */ #include "pygame.h" #include "pygamedocs.h" +#include "pgopengl.h" static int is_extended = 0; static int SaveTGA (SDL_Surface *surface, char *file, int rle); @@ -79,6 +80,7 @@ return final; } + static SDL_Surface* opengltosdl () { @@ -90,81 +92,65 @@ Uint32 rmask, gmask, bmask; int i; unsigned char *pixels; - PyObject *data; + + GL_glReadPixels_Func p_glReadPixels= NULL; + pixels = NULL; + surf = NULL; + + p_glReadPixels = (GL_glReadPixels_Func) SDL_GL_GetProcAddress("glReadPixels"); surf = SDL_GetVideoSurface (); - pyopengl = PyImport_ImportModule ("OpenGL.GL"); - if (pyopengl) - { - PyObject* dict = PyModule_GetDict (pyopengl); - if (dict) - { - PyObject *o; - o = PyDict_GetItemString (dict, "GL_RGB"); - if (!o) - { - Py_DECREF (pyopengl); - return NULL; - } - formatflag = PyInt_AsLong (o); - o = PyDict_GetItemString (dict, "GL_UNSIGNED_BYTE"); - if (!o) - { - Py_DECREF (pyopengl); - return NULL; - } - typeflag = PyInt_AsLong (o); - readpixels = PyDict_GetItemString (dict, "glReadPixels"); - if (!readpixels) - { - Py_DECREF (pyopengl); - return NULL; - } - } - Py_DECREF (pyopengl); + if(!surf) { + RAISE (PyExc_RuntimeError, "Cannot get video surface."); + return NULL; } - else - { - RAISE (PyExc_ImportError, "Cannot import PyOpenGL"); + + + if(!p_glReadPixels) { + RAISE (PyExc_RuntimeError, "Cannot find glReadPixels function."); return NULL; } - data = PyObject_CallFunction (readpixels, "iiiiii", - 0, 0, surf->w, surf->h, formatflag, typeflag); - if (!data) - { - RAISE (PyExc_SDLError, "glReadPixels returned NULL"); + /* + GL_UNSIGNED_BYTE = 5121 + GL_RGB = 6407 + */ + + pixels = (unsigned char*) malloc(surf->w * surf->h * 3); + + if(!pixels) { + RAISE (PyExc_MemoryError, "Cannot allocate enough memory for pixels."); return NULL; } - pixels = (unsigned char*) PyString_AsString (data); + //p_glReadPixels(0, 0, surf->w, surf->h, 6407, 5121, pixels); + //glReadPixels(0, 0, surf->w, surf->h, 0x1907, 0x1401, pixels); + p_glReadPixels(0, 0, surf->w, surf->h, 0x1907, 0x1401, pixels); - if (SDL_BYTEORDER == SDL_LIL_ENDIAN) - { + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { rmask=0x000000FF; gmask=0x0000FF00; bmask=0x00FF0000; - } - else - { + } else { rmask=0x00FF0000; gmask=0x0000FF00; bmask=0x000000FF; } surf = SDL_CreateRGBSurface (SDL_SWSURFACE, surf->w, surf->h, 24, rmask, gmask, bmask, 0); - if (!surf) - { - Py_DECREF (data); + if (!surf) { + free(pixels); RAISE (PyExc_SDLError, SDL_GetError ()); return NULL; } - for (i = 0; i < surf->h; ++i) + for (i = 0; i < surf->h; ++i) { memcpy (((char *) surf->pixels) + surf->pitch * i, pixels + 3 * surf->w * (surf->h - i - 1), surf->w * 3); + } + - Py_DECREF (data); + free(pixels); return surf; } @@ -212,11 +198,11 @@ } else if (((name[namelen - 1]=='g' || name[namelen - 1]=='G') && (name[namelen - 2]=='n' || name[namelen - 2]=='N') && - (name[namelen - 3]=='p' || name[namelen - 2]=='P')) || + (name[namelen - 3]=='p' || name[namelen - 3]=='P')) || ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && (name[namelen - 2]=='e' || name[namelen - 2]=='E') && (name[namelen - 3]=='p' || name[namelen - 3]=='P') && - (name[namelen - 4]=='j' || name[namelen - 3]=='J')) || + (name[namelen - 4]=='j' || name[namelen - 4]=='J')) || ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && (name[namelen - 2]=='p' || name[namelen - 2]=='P') && (name[namelen - 3]=='j' || name[namelen - 3]=='J'))) @@ -234,7 +220,8 @@ result = -1; Py_DECREF (imgext); /* Data must be decremented here, not? */ - Py_DECREF (data); + if (data) + Py_DECREF (data); } else result = -2; diff -Nru pygame-1.8.0release/src/imageext.c pygame-1.8.1release/src/imageext.c --- pygame-1.8.0release/src/imageext.c 2008-03-05 04:00:00.000000000 -0500 +++ pygame-1.8.1release/src/imageext.c 2008-07-07 01:57:32.000000000 -0400 @@ -30,6 +30,7 @@ #include #include "pygame.h" #include "pygamedocs.h" +#include "pgopengl.h" #include static char* @@ -346,7 +347,9 @@ need to share it between both. */ -static SDL_Surface* opengltosdl (void) + +static SDL_Surface* +opengltosdl () { /*we need to get ahold of the pyopengl glReadPixels function*/ /*we use pyopengl's so we don't need to link with opengl at compiletime*/ @@ -356,84 +359,62 @@ Uint32 rmask, gmask, bmask; int i; unsigned char *pixels; - PyObject *data; + + GL_glReadPixels_Func p_glReadPixels= NULL; + pixels = NULL; + surf = NULL; + + p_glReadPixels = (GL_glReadPixels_Func) SDL_GL_GetProcAddress("glReadPixels"); surf = SDL_GetVideoSurface (); - pyopengl = PyImport_ImportModule ("OpenGL.GL"); - if (pyopengl) - { - PyObject* dict = PyModule_GetDict (pyopengl); - if (dict) - { - PyObject *o; - o = PyDict_GetItemString (dict, "GL_RGB"); - if (!o) - { - Py_DECREF (pyopengl); - return NULL; - } - formatflag = PyInt_AsLong (o); - o = PyDict_GetItemString (dict, "GL_UNSIGNED_BYTE"); - if (!o) - { - Py_DECREF (pyopengl); - return NULL; - } - typeflag = PyInt_AsLong (o); - readpixels = PyDict_GetItemString (dict, "glReadPixels"); - if (!readpixels) - { - Py_DECREF (pyopengl); - return NULL; - } - } - Py_DECREF (pyopengl); + if(!surf) { + RAISE (PyExc_RuntimeError, "Cannot get video surface."); + return NULL; } - else - { - RAISE (PyExc_ImportError, "Cannot import PyOpenGL"); + if(!p_glReadPixels) { + RAISE (PyExc_RuntimeError, "Cannot find glReadPixels function."); return NULL; } - data = PyObject_CallFunction (readpixels, "iiiiii", - 0, 0, surf->w, surf->h, formatflag, typeflag); - if (!data) - { - RAISE (PyExc_SDLError, "glReadPixels returned NULL"); + pixels = (unsigned char*) malloc(surf->w * surf->h * 3); + + if(!pixels) { + RAISE (PyExc_MemoryError, "Cannot allocate enough memory for pixels."); return NULL; } - pixels = (unsigned char*) PyString_AsString (data); - if(SDL_BYTEORDER == SDL_LIL_ENDIAN) - { + /* GL_RGB, GL_UNSIGNED_BYTE */ + p_glReadPixels(0, 0, surf->w, surf->h, 0x1907, 0x1401, pixels); + + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { rmask=0x000000FF; gmask=0x0000FF00; bmask=0x00FF0000; - } - else - { + } else { rmask=0x00FF0000; gmask=0x0000FF00; bmask=0x000000FF; } surf = SDL_CreateRGBSurface (SDL_SWSURFACE, surf->w, surf->h, 24, rmask, gmask, bmask, 0); - if (!surf) - { - Py_DECREF (data); + if (!surf) { + free(pixels); RAISE (PyExc_SDLError, SDL_GetError ()); return NULL; } - for (i=0; ih; ++i) + for (i = 0; i < surf->h; ++i) { memcpy (((char *) surf->pixels) + surf->pitch * i, - pixels + 3 * surf->w * (surf->h - i - 1), (size_t) surf->w * 3); + pixels + 3 * surf->w * (surf->h - i - 1), surf->w * 3); + } + - Py_DECREF (data); + free(pixels); return surf; } + static PyObject* image_save_ext (PyObject* self, PyObject* arg) { @@ -462,30 +443,29 @@ if (!PyArg_ParseTuple (arg, "O|s", &file, &name)) return NULL; namelen = strlen (name); - if ((namelen > 3) && + if ((namelen >= 4) && (((name[namelen - 1]=='g' || name[namelen - 1]=='G') && - (name[namelen - 2]=='n' || name[namelen - 2]=='N') && - (name[namelen - 3]=='p' || name[namelen - 2]=='P')) || - ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && - (name[namelen - 2]=='e' || name[namelen - 2]=='E') && - (name[namelen - 3]=='p' || name[namelen - 3]=='P') && - (name[namelen - 4]=='j' || name[namelen - 3]=='J')) || - ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && - (name[namelen - 2]=='p' || name[namelen - 2]=='P') && - (name[namelen - 3]=='j' || name[namelen - 3]=='J')))) + (name[namelen - 2]=='e' || name[namelen - 2]=='E') && + (name[namelen - 3]=='p' || name[namelen - 3]=='P') && + (name[namelen - 4]=='j' || name[namelen - 4]=='J')) || + ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && + (name[namelen - 2]=='p' || name[namelen - 2]=='P') && + (name[namelen - 3]=='j' || name[namelen - 3]=='J')))) { #ifdef JPEGLIB_H /* Png, and jpg save functions are not thread safe. */ /*Py_BEGIN_ALLOW_THREADS; */ result = SaveJPEG (surf, name); /*Py_END_ALLOW_THREADS; */ - #else return RAISE (PyExc_SDLError, "No support for jpg compiled in."); #endif } - else if (name[namelen-1]=='g' || name[namelen-1]=='G') + else if ((namelen >= 3) && + ((name[namelen - 1]=='g' || name[namelen - 1]=='G') && + (name[namelen - 2]=='n' || name[namelen - 2]=='N') && + (name[namelen - 3]=='p' || name[namelen - 3]=='P'))) { #ifdef PNG_H /*Py_BEGIN_ALLOW_THREADS; */ diff -Nru pygame-1.8.0release/src/mask.c pygame-1.8.1release/src/mask.c --- pygame-1.8.0release/src/mask.c 2008-03-03 06:45:10.000000000 -0500 +++ pygame-1.8.1release/src/mask.c 2008-07-15 09:55:07.000000000 -0400 @@ -502,14 +502,14 @@ static PyMethodDef maskobj_builtins[] = { - { "get_size", mask_get_size, METH_VARARGS, DOC_PYGAMEMASKGETSIZE}, - { "get_at", mask_get_at, METH_VARARGS, DOC_PYGAMEMASKGETAT }, - { "set_at", mask_set_at, METH_VARARGS, DOC_PYGAMEMASKSETAT }, - { "overlap", mask_overlap, METH_VARARGS, DOC_PYGAMEMASKOVERLAP }, + { "get_size", mask_get_size, METH_VARARGS, DOC_MASKGETSIZE}, + { "get_at", mask_get_at, METH_VARARGS, DOC_MASKGETAT }, + { "set_at", mask_set_at, METH_VARARGS, DOC_MASKSETAT }, + { "overlap", mask_overlap, METH_VARARGS, DOC_MASKOVERLAP }, { "overlap_area", mask_overlap_area, METH_VARARGS, - DOC_PYGAMEMASKOVERLAPAREA }, + DOC_MASKOVERLAPAREA }, { "get_bounding_rects", mask_get_bounding_rects, METH_VARARGS, - DOC_PYGAMEMASKGETBOUNDINGRECTS }, + DOC_MASKGETBOUNDINGRECTS }, { NULL, NULL, 0, NULL } }; @@ -536,7 +536,7 @@ { PyObject_HEAD_INIT(NULL) 0, - "Mask", + "pygame.mask.Mask", sizeof(PyMaskObject), 0, mask_dealloc, @@ -552,7 +552,7 @@ (ternaryfunc)NULL, (reprfunc)NULL, 0L,0L,0L,0L, - DOC_PYGAMEMASK /* Documentation string */ + DOC_PYGAMEMASKMASK /* Documentation string */ }; @@ -581,9 +581,9 @@ static PyMethodDef mask_builtins[] = { - { "Mask", Mask, METH_VARARGS, DOC_PYGAMEMASK }, + { "Mask", Mask, METH_VARARGS, DOC_PYGAMEMASKMASK }, { "from_surface", mask_from_surface, METH_VARARGS, - DOC_PYGAMEMASKPYGAMEMASKFROMSURFACE}, + DOC_PYGAMEMASKFROMSURFACE}, { NULL, NULL, 0, NULL } }; diff -Nru pygame-1.8.0release/src/mask.doc pygame-1.8.1release/src/mask.doc --- pygame-1.8.0release/src/mask.doc 2008-01-29 02:48:04.000000000 -0500 +++ pygame-1.8.1release/src/mask.doc 2008-07-07 01:57:32.000000000 -0400 @@ -7,7 +7,7 @@ New in pygame 1.8.
        -pygame.mask.from_surface +from_surface Returns a Mask from the given surface. pygame.mask.from_surface(Surface, threshold = 127) -> Mask @@ -19,10 +19,10 @@ If the Surface is color keyed, then threshold is not used. -pygame.Mask +Mask pygame object for representing 2d bitmasks pygame.Mask((width, height): return Mask - +
        get_size Returns the size of the mask. diff -Nru pygame-1.8.0release/src/mixer.c pygame-1.8.1release/src/mixer.c --- pygame-1.8.0release/src/mixer.c 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/mixer.c 2008-07-07 01:57:32.000000000 -0400 @@ -174,9 +174,8 @@ /*make chunk a power of 2*/ - for (i = 0; 1 << i < chunk; ++i) { - chunk = MAX (1 << i, 256); - } + for (i = 0; 1 << i < chunk; ++i); //yes, semicolon on for loop + chunk = MAX (1 << i, 256); if (!SDL_WasInit (SDL_INIT_AUDIO)) { @@ -268,8 +267,9 @@ Py_RETURN_NONE; //create a signed or unsigned number of bits per sample + // XXX: When mixer is init'd with a format of -8, this returns +8 realform = format&~0xff ? - (format&0xff) : format&0xff; - return Py_BuildValue ("(iii)", freq, realform, channels > 1); + return Py_BuildValue ("(iii)", freq, realform, channels); } static PyObject* diff -Nru pygame-1.8.0release/src/movie.c pygame-1.8.1release/src/movie.c --- pygame-1.8.0release/src/movie.c 2007-09-01 01:21:55.000000000 -0400 +++ pygame-1.8.1release/src/movie.c 2008-07-18 18:18:45.000000000 -0400 @@ -46,6 +46,11 @@ { SMPEG* movie = PyMovie_AsSMPEG (self); int loops = 0; + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_loop (movie, loops); SMPEG_play (movie); @@ -57,6 +62,11 @@ movie_stop (PyObject* self) { SMPEG* movie = PyMovie_AsSMPEG (self); + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_stop (movie); Py_END_ALLOW_THREADS; @@ -64,9 +74,14 @@ } static PyObject* -movie_pause (PyObject* self) -{ +movie_pause (PyObject* self) { SMPEG* movie = PyMovie_AsSMPEG (self); + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + Py_BEGIN_ALLOW_THREADS; SMPEG_pause (movie); Py_END_ALLOW_THREADS; @@ -77,6 +92,11 @@ movie_rewind (PyObject* self) { SMPEG* movie = PyMovie_AsSMPEG (self); + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_rewind (movie); Py_END_ALLOW_THREADS; @@ -88,7 +108,13 @@ { SMPEG* movie = PyMovie_AsSMPEG (self); float seconds; - if (!PyArg_ParseTuple (args, "f", &seconds)) + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + + if (!PyArg_ParseTuple (args, "f", &seconds)) return NULL; Py_BEGIN_ALLOW_THREADS; SMPEG_skip (movie, seconds); @@ -105,6 +131,11 @@ if (!PyArg_ParseTuple (args, "f", &value)) return NULL; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + Py_BEGIN_ALLOW_THREADS; volume = (int) (value * 100); if (volume < 0) @@ -126,6 +157,12 @@ if (!PyArg_ParseTuple (args, "O|O", &surfobj, &posobj)) return NULL; + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + Py_XDECREF (((PyMovieObject*) self)->surftarget); ((PyMovieObject*) self)->surftarget = NULL; @@ -187,6 +224,10 @@ SMPEG* movie = PyMovie_AsSMPEG (self); SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -199,6 +240,11 @@ SMPEG* movie = PyMovie_AsSMPEG (self); SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -211,6 +257,10 @@ SMPEG* movie = PyMovie_AsSMPEG (self); SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -223,6 +273,10 @@ SMPEG* movie = PyMovie_AsSMPEG (self); SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -235,6 +289,10 @@ SMPEG* movie = PyMovie_AsSMPEG (self); SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -244,9 +302,15 @@ static PyObject* movie_get_length (PyObject* self) { - SMPEG* movie = PyMovie_AsSMPEG (self); + SMPEG* movie; SMPEG_Info info; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + movie = PyMovie_AsSMPEG (self); + Py_BEGIN_ALLOW_THREADS; SMPEG_getinfo (movie, &info); Py_END_ALLOW_THREADS; @@ -256,7 +320,14 @@ static PyObject* movie_get_busy (PyObject* self) { - SMPEG* movie = PyMovie_AsSMPEG (self); + SMPEG* movie; + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + + movie = PyMovie_AsSMPEG (self); + return PyInt_FromLong (SMPEG_status (movie) == SMPEG_PLAYING); } @@ -267,6 +338,10 @@ SMPEG_Info info; int framenum; + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + if (!PyArg_ParseTuple (args, "i", &framenum)) return NULL; Py_BEGIN_ALLOW_THREADS; @@ -357,6 +432,11 @@ SDL_Surface* screen; char* error; int audioavail = 0; + + if (!SDL_WasInit (SDL_INIT_VIDEO)) + return RAISE (PyExc_SDLError, + "cannot convert without pygame.display initialized"); + if (!PyArg_ParseTuple (arg, "O", &file)) return NULL; diff -Nru pygame-1.8.0release/src/music.c pygame-1.8.1release/src/music.c --- pygame-1.8.0release/src/music.c 2007-06-26 19:13:00.000000000 -0400 +++ pygame-1.8.1release/src/music.c 2008-07-22 07:32:57.000000000 -0400 @@ -96,14 +96,18 @@ music_pos_time = SDL_GetTicks (); #if MIX_MAJOR_VERSION>=1 && MIX_MINOR_VERSION>=2 && MIX_PATCHLEVEL>=3 + Py_BEGIN_ALLOW_THREADS volume = Mix_VolumeMusic (-1); val = Mix_FadeInMusicPos (current_music, loops, 0, startpos); Mix_VolumeMusic (volume); + Py_END_ALLOW_THREADS #else if (startpos) return RAISE (PyExc_NotImplementedError, "music start position requires SDL_mixer-1.2.4"); + Py_BEGIN_ALLOW_THREADS val = Mix_PlayMusic (current_music, loops); + Py_END_ALLOW_THREADS #endif if (val == -1) return RAISE (PyExc_SDLError, SDL_GetError ()); @@ -240,55 +244,98 @@ static PyObject* music_load (PyObject* self, PyObject* args) { - char* filename; - if (!PyArg_ParseTuple (args, "s", &filename)) + char* name = NULL; + PyObject* file; + Mix_Music* new_music; + SDL_RWops *rw; + if(!PyArg_ParseTuple(args, "O", &file)) return NULL; MIXER_INIT_CHECK (); - if (current_music) + #if (MIX_MAJOR_VERSION*100*100 + MIX_MINOR_VERSION*100 + MIX_PATCHLEVEL) >= 10208 + if(!PyString_Check(file) && !PyUnicode_Check(file)) { - Mix_FreeMusic (current_music); - current_music = NULL; + rw = RWopsFromPythonThreaded(file); + if(!rw) + return NULL; + Py_BEGIN_ALLOW_THREADS + new_music = Mix_LoadMUS_RW(rw); + Py_END_ALLOW_THREADS + } + else + #endif + { + if(!PyArg_ParseTuple(args, "s", &name)) + return NULL; + Py_BEGIN_ALLOW_THREADS + new_music = Mix_LoadMUS(name); + Py_END_ALLOW_THREADS } - Py_BEGIN_ALLOW_THREADS; - current_music = Mix_LoadMUS (filename); - Py_END_ALLOW_THREADS; - if (!current_music) + if (!new_music) return RAISE (PyExc_SDLError, SDL_GetError ()); + Py_BEGIN_ALLOW_THREADS + if (current_music) + { + Mix_FreeMusic (current_music); + current_music = NULL; + } if (queue_music) { Mix_FreeMusic (queue_music); queue_music = NULL; } + Py_END_ALLOW_THREADS + current_music = new_music; Py_RETURN_NONE; } static PyObject* music_queue (PyObject* self, PyObject* args) { - char* filename; + char* name = NULL; + PyObject* file; Mix_Music* new_music; - if (!PyArg_ParseTuple (args, "s", &filename)) + SDL_RWops *rw; + if (!PyArg_ParseTuple (args, "O", &file)) return NULL; MIXER_INIT_CHECK (); - Py_BEGIN_ALLOW_THREADS; - new_music = Mix_LoadMUS (filename); - Py_END_ALLOW_THREADS; + #if MIX_MAJOR_VERSION*100*100 + MIX_MINOR_VERSION*100 + MIX_PATCHLEVEL >= 10208 + if(!PyString_Check(file) && !PyUnicode_Check(file)) + { + rw = RWopsFromPythonThreaded(file); + if(!rw) + return NULL; + Py_BEGIN_ALLOW_THREADS + new_music = Mix_LoadMUS_RW(rw); + Py_END_ALLOW_THREADS + } + else + #endif + { + if(!PyArg_ParseTuple(args, "s", &name)) + return NULL; + Py_BEGIN_ALLOW_THREADS + new_music = Mix_LoadMUS(name); + Py_END_ALLOW_THREADS + } if (!new_music) return RAISE (PyExc_SDLError, SDL_GetError ()); + Py_BEGIN_ALLOW_THREADS if (queue_music) { Mix_FreeMusic (queue_music); queue_music = NULL; } + Py_END_ALLOW_THREADS + queue_music = new_music; Py_RETURN_NONE; } @@ -340,4 +387,5 @@ /*imported needed apis*/ import_pygame_base (); + import_pygame_rwobject (); } diff -Nru pygame-1.8.0release/src/_numericsurfarray.c pygame-1.8.1release/src/_numericsurfarray.c --- pygame-1.8.0release/src/_numericsurfarray.c 2008-01-19 21:26:20.000000000 -0500 +++ pygame-1.8.1release/src/_numericsurfarray.c 2008-07-07 01:57:33.000000000 -0400 @@ -35,6 +35,7 @@ int pixelstep; const int lilendian = (SDL_BYTEORDER == SDL_LIL_ENDIAN); PyObject* lifelock; + int rgb = 0; if (!PyArg_ParseTuple (arg, "O!", &PySurface_Type, &surfobj)) return NULL; @@ -43,44 +44,55 @@ if (surf->format->BytesPerPixel <= 2 || surf->format->BytesPerPixel > 4) return RAISE (PyExc_ValueError, "unsupport bit depth for 3D reference array"); - - lifelock = PySurface_LockLifetime (surfobj); - if (!lifelock) - return NULL; - + /*must discover information about how data is packed*/ if (surf->format->Rmask == 0xff<<16 && surf->format->Gmask == 0xff<<8 && surf->format->Bmask == 0xff) { pixelstep = (lilendian ? -1 : 1); - startpixel = ((char*) surf->pixels) + (lilendian ? 2 : 0); + rgb = 1; } else if (surf->format->Bmask == 0xff<<16 && surf->format->Gmask == 0xff<<8 && surf->format->Rmask == 0xff) { pixelstep = (lilendian ? 1 : -1); - startpixel = ((char*) surf->pixels) + (lilendian ? 0 : 2); + rgb = 0; } else return RAISE (PyExc_ValueError, "unsupport colormasks for 3D reference array"); - if (!lilendian && surf->format->BytesPerPixel == 4) - ++startpixel; - + /*create the referenced array*/ dim[0] = surf->w; dim[1] = surf->h; dim[2] = 3; /*could be 4 if alpha in the house*/ - array = PyArray_FromDimsAndData (3, dim, PyArray_UBYTE, startpixel); + + /* Pass a dummy string and set it correctly later */ + array = PyArray_FromDimsAndData (3, dim, PyArray_UBYTE, ""); if (array) { + lifelock = PySurface_LockLifetime (surfobj, array); + if (!lifelock) + { + Py_DECREF (array); + return NULL; + } + + if (rgb) + startpixel = ((char*) surf->pixels) + (lilendian ? 2 : 0); + else + startpixel = ((char*) surf->pixels) + (lilendian ? 0 : 2); + if (!lilendian && surf->format->BytesPerPixel == 4) + ++startpixel; + ((PyArrayObject*) array)->flags = OWN_DIMENSIONS|OWN_STRIDES|SAVESPACE; ((PyArrayObject*) array)->strides[2] = pixelstep; ((PyArrayObject*) array)->strides[1] = surf->pitch; ((PyArrayObject*) array)->strides[0] = surf->format->BytesPerPixel; ((PyArrayObject*) array)->base = lifelock; + ((PyArrayObject*) array)->data = startpixel; } return array; } @@ -104,20 +116,23 @@ return RAISE (PyExc_ValueError, "unsupport bit depth for 2D reference array"); - lifelock = PySurface_LockLifetime (surfobj); - if (!lifelock) - return NULL; - dim[0] = surf->w; dim[1] = surf->h; type = types[surf->format->BytesPerPixel-1]; - array = PyArray_FromDimsAndData (2, dim, type, (char*) surf->pixels); + array = PyArray_FromDimsAndData (2, dim, type, ""); if (array) { + lifelock = PySurface_LockLifetime (surfobj, array); + if (!lifelock) + { + Py_DECREF (array); + return NULL; + } ((PyArrayObject*) array)->strides[1] = surf->pitch; ((PyArrayObject*) array)->strides[0] = surf->format->BytesPerPixel; ((PyArrayObject*) array)->flags = OWN_DIMENSIONS|OWN_STRIDES; ((PyArrayObject*) array)->base = lifelock; + ((PyArrayObject*) array)->data = (char*) surf->pixels; } return array; } @@ -130,6 +145,8 @@ PyObject* lifelock; SDL_Surface* surf; char* startpixel; + int startoffset; + const int lilendian = (SDL_BYTEORDER == SDL_LIL_ENDIAN); if (!PyArg_ParseTuple(arg, "O!", &PySurface_Type, &surfobj)) @@ -139,28 +156,32 @@ if (surf->format->BytesPerPixel != 4) return RAISE (PyExc_ValueError, "unsupport bit depth for alpha array"); - lifelock = PySurface_LockLifetime (surfobj); - if (!lifelock) - return NULL; - /*must discover information about how data is packed*/ if (surf->format->Amask == 0xff << 24) - startpixel = ((char*) surf->pixels) + (lilendian ? 3 : 0); + startoffset = (lilendian ? 3 : 0); else if (surf->format->Amask == 0xff) - startpixel = ((char*) surf->pixels) + (lilendian ? 0 : 3); + startoffset = (lilendian ? 0 : 3); else return RAISE (PyExc_ValueError, "unsupport colormasks for alpha reference array"); dim[0] = surf->w; dim[1] = surf->h; - array = PyArray_FromDimsAndData (2, dim, PyArray_UBYTE, startpixel); + array = PyArray_FromDimsAndData (2, dim, PyArray_UBYTE, ""); if(array) { + lifelock = PySurface_LockLifetime (surfobj, array); + if (!lifelock) + { + Py_DECREF (array); + return NULL; + } + startpixel = ((char*) surf->pixels) + startoffset; ((PyArrayObject*) array)->strides[1] = surf->pitch; ((PyArrayObject*) array)->strides[0] = surf->format->BytesPerPixel; ((PyArrayObject*) array)->flags = OWN_DIMENSIONS|OWN_STRIDES; ((PyArrayObject*) array)->base = lifelock; + ((PyArrayObject*) array)->data = startpixel; } return array; } @@ -191,8 +212,11 @@ stridex = ((PyArrayObject*) array)->strides[0]; stridey = ((PyArrayObject*) array)->strides[1]; - if (!PySurface_Lock (surfobj)) + if (!PySurface_LockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } switch (surf->format->BytesPerPixel) { @@ -255,8 +279,11 @@ break; } - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } return array; } @@ -301,15 +328,19 @@ stridex = ((PyArrayObject*) array)->strides[0]; stridey = ((PyArrayObject*) array)->strides[1]; - if (!PySurface_Lock (surfobj)) + if (!PySurface_LockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } switch (surf->format->BytesPerPixel) { case 1: if (!format->palette) { - if (!PySurface_Unlock (surfobj)) + Py_DECREF (array); + if (!PySurface_UnlockBy (surfobj, array)) return NULL; return RAISE (PyExc_RuntimeError, "8bit surface has no palette"); } @@ -389,8 +420,11 @@ break; } - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } return array; } @@ -433,9 +467,12 @@ stridex = ((PyArrayObject*) array)->strides[0]; stridey = ((PyArrayObject*) array)->strides[1]; - if (!PySurface_Lock (surfobj)) + if (!PySurface_LockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; - + } + switch (surf->format->BytesPerPixel) { case 2: @@ -488,8 +525,11 @@ break; } - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } return array; } @@ -529,9 +569,12 @@ stridex = ((PyArrayObject*) array)->strides[0]; stridey = ((PyArrayObject*) array)->strides[1]; - if (!PySurface_Lock (surfobj)) + if (!PySurface_LockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; - + } + switch (surf->format->BytesPerPixel) { case 1: @@ -597,8 +640,11 @@ break; } - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, array)) + { + Py_DECREF (array); return NULL; + } return array; } @@ -824,7 +870,7 @@ if (sizex != surf->w || sizey != surf->h) return RAISE (PyExc_ValueError, "array must match surface dimensions"); - if (!PySurface_Lock (surfobj)) + if (!PySurface_LockBy (surfobj, (PyObject *) array)) return NULL; switch (surf->format->BytesPerPixel) @@ -847,7 +893,7 @@ COPYMACRO_2D(Uint8, Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -872,7 +918,7 @@ COPYMACRO_2D(Uint16, Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -895,7 +941,7 @@ COPYMACRO_3D(Uint16, Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -920,7 +966,7 @@ COPYMACRO_2D_24(Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -943,7 +989,7 @@ COPYMACRO_3D_24(Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -968,7 +1014,7 @@ COPYMACRO_2D(Uint32, Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -991,7 +1037,7 @@ COPYMACRO_3D(Uint32, Uint64); break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_ValueError, "unsupported datatype for array\n"); @@ -999,12 +1045,12 @@ } break; default: - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; return RAISE (PyExc_RuntimeError, "unsupported bit depth for image"); } - if (!PySurface_Unlock (surfobj)) + if (!PySurface_UnlockBy (surfobj, (PyObject *) array)) return NULL; Py_RETURN_NONE; } @@ -1030,7 +1076,9 @@ if (array->nd == 2) { bitsperpixel = 8; - rmask = gmask = bmask = 0; + rmask = 0xFF >> 6 << 5; + gmask = 0xFF >> 5 << 2; + bmask = 0xFF >> 6; } else { @@ -1094,17 +1142,18 @@ PYGAME_EXPORT void init_numericsurfarray (void) { - PyObject *module, *dict; + PyObject *module; + PyObject* numeric_module; - /* create the module */ - module = Py_InitModule3 ("_numericsurfarray", surfarray_builtins, - DOC_PYGAMESURFARRAY); - dict = PyModule_GetDict (module); - - /*imported needed apis*/ - import_pygame_base (); - import_pygame_surface (); - import_array (); - /*needed for Numeric in python2.3*/ - PyImport_ImportModule ("Numeric"); + numeric_module = PyImport_ImportModule ("Numeric"); + if (numeric_module != 0) + { + /* create the module */ + module = Py_InitModule3 ("_numericsurfarray", surfarray_builtins, + DOC_PYGAMESURFARRAY); + + import_pygame_base (); + import_pygame_surface (); + import_array (); + } } diff -Nru pygame-1.8.0release/src/pgopengl.h pygame-1.8.1release/src/pgopengl.h --- pygame-1.8.0release/src/pgopengl.h 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/src/pgopengl.h 2008-07-07 01:57:32.000000000 -0400 @@ -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 -Nru pygame-1.8.0release/src/pixelarray.c pygame-1.8.1release/src/pixelarray.c --- pygame-1.8.0release/src/pixelarray.c 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/pixelarray.c 2008-07-07 01:57:33.000000000 -0400 @@ -1,6 +1,6 @@ /* pygame - Python Game Library - Copyright (C) 2007 Marcus von Appen + Copyright (C) 2007-2008 Marcus von Appen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,7 +19,7 @@ */ #define PYGAMEAPI_PIXELARRAY_INTERNAL - + #include "pygame.h" #include "pygamedocs.h" #include "surface.h" @@ -28,7 +28,6 @@ #define PyIndex_Check(op) 0 #endif - typedef struct { PyObject_HEAD @@ -56,22 +55,13 @@ static PyObject* _pxarray_get_dict (PyPixelArray *self, void *closure); static PyObject* _pxarray_get_surface (PyPixelArray *self, void *closure); - static PyObject* _pxarray_repr (PyPixelArray *array); -static int _get_color_from_object (PyObject *val, SDL_PixelFormat *format, - Uint32 *color); -static PyObject* _get_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, - Uint32 row); -static void _set_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, - Uint32 row, SDL_PixelFormat *format, Uint32 color); static PyObject* _array_slice_internal (PyPixelArray *array, Sint32 _start, Sint32 _end, Sint32 _step); /* Sequence methods */ static Py_ssize_t _pxarray_length (PyPixelArray *array); -static PyObject* _pxarray_concat (PyPixelArray *array, PyObject *value); -static PyObject* _pxarray_repeat (PyPixelArray *a, Py_ssize_t n); static PyObject* _pxarray_item (PyPixelArray *array, Py_ssize_t _index); static PyObject* _pxarray_slice (PyPixelArray *array, Py_ssize_t low, Py_ssize_t high); @@ -79,17 +69,18 @@ Py_ssize_t high, PyPixelArray *val); static int _array_assign_sequence (PyPixelArray *array, Py_ssize_t low, Py_ssize_t high, PyObject *val); +static int _array_assign_slice (PyPixelArray *array, Py_ssize_t low, + Py_ssize_t high, Uint32 color); static int _pxarray_ass_item (PyPixelArray *array, Py_ssize_t _index, PyObject *value); static int _pxarray_ass_slice (PyPixelArray *array, Py_ssize_t low, Py_ssize_t high, PyObject *value); static int _pxarray_contains (PyPixelArray *array, PyObject *value); -static PyObject* _pxarray_inplace_concat (PyPixelArray *array, PyObject *seq); -static PyObject* _pxarray_inplace_repeat (PyPixelArray *array, Py_ssize_t n); +static PyObject* _pxarray_iter (PyPixelArray *array); /* Mapping methods */ -static int _get_subslice (PyPixelArray *array, PyObject *op, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +static int _get_subslice (PyObject *op, Py_ssize_t length, Py_ssize_t *start, + Py_ssize_t *stop, Py_ssize_t *step); static PyObject* _pxarray_subscript (PyPixelArray *array, PyObject *op); static int _pxarray_ass_subscript (PyPixelArray *array, PyObject* op, PyObject* value); @@ -97,11 +88,31 @@ /* C API interfaces */ static PyObject* PyPixelArray_New (PyObject *surfobj); +/* Incomplete forward declaration so we can use it in the methods included + * below. + */ +staticforward PyTypeObject PyPixelArray_Type; +#define PyPixelArray_Check(o) \ + ((o)->ob_type == (PyTypeObject *) &PyPixelArray_Type) + +#define SURFACE_EQUALS(x,y) \ + (((PyPixelArray *)x)->surface == ((PyPixelArray *)y)->surface) + +#include "pixelarray_methods.c" + /** * Methods, which are bound to the PyPixelArray type. */ static PyMethodDef _pxarray_methods[] = { + { "compare", (PyCFunction) _compare, METH_KEYWORDS, + DOC_PIXELARRAYCOMPARE }, + { "extract", (PyCFunction) _extract_color, METH_KEYWORDS, + DOC_PIXELARRAYEXTRACT }, + { "make_surface", (PyCFunction) _make_surface, METH_NOARGS, + DOC_PIXELARRAYMAKESURFACE }, + { "replace", (PyCFunction) _replace_color, METH_KEYWORDS, + DOC_PIXELARRAYREPLACE }, { NULL, NULL, 0, NULL } }; @@ -112,25 +123,27 @@ { { "__dict__", (getter) _pxarray_get_dict, NULL, NULL, NULL }, { "surface", (getter) _pxarray_get_surface, NULL, DOC_PIXELARRAYSURFACE, - NULL }, + NULL }, { NULL, NULL, NULL, NULL, NULL } }; /** * Sequence interface support for the PyPixelArray. + * concat and repeat are not implemented due to the possible confusion + * of their behaviour (see lists numpy array). */ static PySequenceMethods _pxarray_sequence = { (lenfunc) _pxarray_length, /*sq_length*/ - NULL, /*(binaryfunc) _pxarray_concat,*/ /*sq_concat*/ - (ssizeargfunc) _pxarray_repeat, /*sq_repeat*/ + NULL, /*sq_concat*/ + NULL, /*sq_repeat*/ (ssizeargfunc) _pxarray_item, /*sq_item*/ (ssizessizeargfunc) _pxarray_slice, /*sq_slice*/ (ssizeobjargproc) _pxarray_ass_item, /*sq_ass_item*/ (ssizessizeobjargproc) _pxarray_ass_slice, /*sq_ass_slice*/ (objobjproc) _pxarray_contains, /*sq_contains*/ - NULL, /*(binaryfunc) _pxarray_inplace_concat,*/ /*sq_inplace_concat*/ - NULL, /*(ssizeargfunc) _pxarray_inplace_repeat*/ /*sq_inplace_repeat*/ + NULL, /*sq_inplace_concat*/ + NULL, /*sq_inplace_repeat*/ }; /** @@ -155,10 +168,10 @@ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc) &_pxarray_repr, /* tp_repr */ + (reprfunc) _pxarray_repr, /* tp_repr */ 0, /* tp_as_number */ &_pxarray_sequence, /* tp_as_sequence */ - 0, /*&_pxarray_mapping,*/ /* tp_as_mapping */ + &_pxarray_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ @@ -171,7 +184,7 @@ 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof (PyPixelArray, weakrefs), /* tp_weaklistoffset */ - 0, /* tp_iter */ + (getiterfunc) _pxarray_iter, /* tp_iter */ 0, /* tp_iternext */ _pxarray_methods, /* tp_methods */ 0, /* tp_members */ @@ -194,9 +207,6 @@ 0 /* tp_del */ }; -#define PyPixelArray_Check(o) \ - ((o)->ob_type == (PyTypeObject *) &PyPixelArray_Type) - static PyPixelArray* _pxarray_new_internal (PyTypeObject *type, PyObject *surface, Uint32 xstart, Uint32 ystart, Uint32 xlen, Uint32 ylen, @@ -216,7 +226,7 @@ /* Initial PixelArray */ if (surface) { - self->lock = PySurface_LockLifetime (surface); + self->lock = PySurface_LockLifetime (surface, (PyObject *) self); if (!self->lock) { Py_DECREF (surface); @@ -229,7 +239,7 @@ { self->parent = parent; Py_INCREF (parent); - self->lock = ((PyPixelArray*) parent)->lock; + self->lock = ((PyPixelArray *)parent)->lock; Py_INCREF (self->lock); } @@ -276,11 +286,10 @@ { if (self->weakrefs) PyObject_ClearWeakRefs ((PyObject *) self); - Py_DECREF (self->lock); - Py_DECREF (self->surface); + Py_XDECREF (self->lock); Py_XDECREF (self->parent); Py_XDECREF (self->dict); - + Py_DECREF (self->surface); self->ob_type->tp_free ((PyObject *) self); } @@ -340,8 +349,8 @@ pixels = (Uint8 *) surface->pixels; /* - printf ("ARRAY: %d:%d, %d:%d %d:%d %d\n", - array->start, array->end, array->xlen, array->xstep, + printf ("::ARRAY: %d:%d:%d, %d:%d:%d %d\n", + array->xstart, array->xlen, array->xstep, array->ystart, array->ylen, array->ystep, array->padding); */ string = PyString_FromString ("PixelArray("); @@ -355,60 +364,60 @@ switch (bpp) { case 1: - while (posy != array->ylen) + while (posy < array->ylen) { /* Construct the rows */ PyString_ConcatAndDel (&string, PyString_FromString ("\n [")); posx = 0; x = array->xstart; - while (posx != (Uint32)xlen) + while (posx < (Uint32)xlen) { /* Construct the columns */ pixel = (Uint32) *((Uint8 *) pixels + x + y * array->padding); PyString_ConcatAndDel (&string, PyString_FromFormat - ("%d, ", pixel)); + ("%ld, ", (long)pixel)); x += array->xstep; posx += absxstep; } pixel = (Uint32) *((Uint8 *) pixels + x + y * array->padding); PyString_ConcatAndDel (&string, - PyString_FromFormat ("%d]", pixel)); + PyString_FromFormat ("%ld]", (long)pixel)); y += array->ystep; posy += absystep; } break; case 2: - while (posy != array->ylen) + while (posy < array->ylen) { /* Construct the rows */ PyString_ConcatAndDel (&string, PyString_FromString ("\n [")); posx = 0; x = array->xstart; - while (posx != (Uint32)xlen) + while (posx < (Uint32)xlen) { /* Construct the columns */ pixel = (Uint32) *((Uint16 *) (pixels + y * array->padding) + x); PyString_ConcatAndDel (&string, PyString_FromFormat - ("%d, ", pixel)); + ("%ld, ", (long)pixel)); x += array->xstep; posx += absxstep; } pixel = (Uint32) *((Uint16 *) (pixels + y * array->padding) + x); PyString_ConcatAndDel (&string, - PyString_FromFormat ("%d]", pixel)); + PyString_FromFormat ("%ld]", (long)pixel)); y += array->ystep; posy += absystep; } break; case 3: - while (posy != array->ylen) + while (posy < array->ylen) { /* Construct the rows */ PyString_ConcatAndDel (&string, PyString_FromString ("\n [")); posx = 0; x = array->xstart; - while (posx != (Uint32)xlen) + while (posx < (Uint32)xlen) { /* Construct the columns */ px24 = ((Uint8 *) (pixels + y * array->padding) + x * 3); @@ -418,7 +427,7 @@ pixel = (px24[2]) + (px24[1] << 8) + (px24[0] << 16); #endif PyString_ConcatAndDel (&string, PyString_FromFormat - ("%d, ", pixel)); + ("%ld, ", (long)pixel)); x += array->xstep; posx += absxstep; } @@ -429,30 +438,30 @@ pixel = (px24[2]) + (px24[1] << 8) + (px24[0] << 16); #endif PyString_ConcatAndDel (&string, - PyString_FromFormat ("%d]", pixel)); + PyString_FromFormat ("%ld]", (long)pixel)); y += array->ystep; posy += absystep; } break; default: /* 4bpp */ - while (posy != array->ylen) + while (posy < array->ylen) { /* Construct the rows */ PyString_ConcatAndDel (&string, PyString_FromString ("\n [")); posx = 0; x = array->xstart; - while (posx != (Uint32)xlen) + while (posx < (Uint32)xlen) { /* Construct the columns */ pixel = *((Uint32 *) (pixels + y * array->padding) + x); PyString_ConcatAndDel (&string, PyString_FromFormat - ("%d, ", pixel)); + ("%ld, ", (long)pixel)); x += array->xstep; posx += absxstep; } pixel = *((Uint32 *) (pixels + y * array->padding) + x); PyString_ConcatAndDel (&string, - PyString_FromFormat ("%d]", pixel)); + PyString_FromFormat ("%ld]", (long)pixel)); y += array->ystep; posy += absystep; } @@ -462,124 +471,6 @@ return string; } -/** - * Tries to retrieve a valid color for a Surface. - */ -static int -_get_color_from_object (PyObject *val, SDL_PixelFormat *format, Uint32 *color) -{ - Uint8 rgba[4]; - - if (PyInt_Check (val)) - { - int intval = PyInt_AsLong (val); - if (intval < 0) - { - if (!PyErr_Occurred ()) - PyErr_SetString (PyExc_ValueError, "invalid color argument"); - return 0; - } - *color = (Uint32) intval; - return 1; - } - else if (PyLong_Check (val)) - { - long long longval = -1; - /* Plain index: array[x, */ - - longval = PyLong_AsLong (val); - if ((longval < INT_MIN) || (longval > INT_MAX)) - { - PyErr_SetString(PyExc_ValueError, - "index too big for array access"); - return 0; - } - *color = (Uint32) longval; - return 1; - } - else if (RGBAFromObj (val, rgba)) - { - *color = (Uint32) SDL_MapRGBA - (format, rgba[0], rgba[1], rgba[2], rgba[3]); - return 1; - } - else - PyErr_SetString (PyExc_ValueError, "invalid color argument"); - return 0; -} - -/** - * Retrieves a single pixel located at index from the surface pixel - * array. - */ -static PyObject* -_get_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row) -{ - Uint32 pixel; - - switch (bpp) - { - case 1: - pixel = (Uint32)*((Uint8 *) pixels + row + _index); - break; - case 2: - pixel = (Uint32)*((Uint16 *) (pixels + row) + _index); - break; - case 3: - { - Uint8 *px = ((Uint8 *) (pixels + row) + _index * 3); -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - pixel = (px[0]) + (px[1] << 8) + (px[2] << 16); -#else - pixel = (px[2]) + (px[1] << 8) + (px[0] << 16); -#endif - break; - } - default: /* 4 bpp */ - pixel = *((Uint32 *) (pixels + row) + _index); - break; - } - - return PyInt_FromLong ((long)pixel); -} - -/** - * Sets a single pixel located at index from the surface pixel array. - */ -static void -_set_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row, - SDL_PixelFormat *format, Uint32 color) -{ - switch (bpp) - { - case 1: - *((Uint8 *) pixels + row + _index) = (Uint8) color; - break; - case 2: - *((Uint16 *) (pixels + row) + _index) = (Uint16) color; - break; - case 3: -#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) - *((Uint8 *) (pixels + row) + _index * 3 + (format->Rshift >> 3)) = - (Uint8) (color >> 16); - *((Uint8 *) (pixels + row) + _index * 3 + (format->Gshift >> 3)) = - (Uint8) (color >> 8); - *((Uint8 *) (pixels + row) + _index * 3 + (format->Bshift >> 3)) = - (Uint8) color; -#else - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Rshift >> 3)) = - (Uint8) (color >> 16); - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Gshift >> 3)) = - (Uint8) (color >> 8); - *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Bshift >> 3)) = - (Uint8) color; -#endif - break; - default: /* 4 bpp */ - *((Uint32 *) (pixels + row) + _index) = color; - break; - } -} /** * Creates a 2D slice of the array. @@ -608,6 +499,10 @@ ystep = _step; xstep = array->xstep; padding = array->padding; + + /* Out of bounds? */ + if (_start >= (Sint32) array->ylen && ystep > 0) + return RAISE (PyExc_IndexError, "array index out of range"); } else { @@ -618,6 +513,10 @@ xstep = _step; ystep = array->ystep; padding = array->padding; + + /* Out of bounds? */ + if (_start >= (Sint32) array->xlen && xstep > 0) + return RAISE (PyExc_IndexError, "array index out of range"); } /* @@ -629,6 +528,7 @@ xstep, ystep, padding, (PyObject *) array); } + /**** Sequence interfaces ****/ /** @@ -643,77 +543,6 @@ } /** - * array + value -> new array with new surface. - */ -static PyObject* -_pxarray_concat (PyPixelArray *array, PyObject *value) -{ - /* TODO */ - return RAISE (PyExc_NotImplementedError, "method not implemented"); -} - -/** - * array * x -> new array with new surface. - */ -static PyObject* -_pxarray_repeat (PyPixelArray *array, Py_ssize_t n) -{ - /* TODO */ - return RAISE (PyExc_NotImplementedError, "method not implemented"); -/* PyObject *newsf; */ -/* SDL_Surface *tmpsf; */ -/* SDL_Surface *newsurf; */ -/* PyPixelArray *newarray; */ - -/* SDL_Surface *surface; */ -/* int bpp; */ -/* Uint8 *pixels; */ -/* Uint32 x = 0; */ -/* Uint32 y = 0; */ -/* Uint32 vx = 0; */ -/* Uint32 vy = 0; */ -/* Uint32 posx = 0; */ -/* Uint32 posy = 0; */ - -/* Uint32 maxcolor; */ - -/* surface = PySurface_AsSurface (array->surface); */ -/* bpp = surface->format->BytesPerPixel; */ -/* maxcolor = SDL_MapRGB (surface->format, 255, 255, 255); */ - -/* /\* Check the factor bounds. *\/ */ -/* if (n < 0) */ -/* return RAISE (PyExc_TypeError, "negative factors are not allowed"); */ -/* if ((Uint32) n > maxcolor) */ -/* return RAISE (PyExc_ArithmeticError, "integer overflow for factor"); */ - -/* /\* Anything's fine, create the second surface. *\/ */ -/* tmpsf = SDL_CreateRGBSurface (surface->flags, */ -/* (int) (array->xlen / array->xstep), */ -/* (int) (array->ylen / array->ystep), bpp, surface->format->Rmask, */ -/* surface->format->Gmask, surface->format->Bmask, surface->format->Amask); */ -/* if (!tmpsf) */ -/* return RAISE (PyExc_SDLError, SDL_GetError ()); */ -/* /\* Guarantee an identical format. *\/ */ -/* newsurf = SDL_ConvertSurface (tmpsf, surface->format, surface->flags); */ -/* if (!newsurf) */ -/* { */ -/* SDL_FreeSurface (tmpsf); */ -/* return RAISE (PyExc_SDLError, SDL_GetError ()); */ -/* } */ -/* SDL_FreeSurface (tmpsf); */ - -/* newsf = PySurface_New (newsurf); */ -/* if (!newsf) */ -/* return NULL; */ -/* newarray = _pxarray_new_internal (&PyPixelArray_Type, newsf, 0, 0, */ -/* (Uint32) newsurf->w, (Uint32) newsurf->h, 1, 1, (Uint32) newsurf->pitch, */ -/* NULL); */ -/* if (!newarray) */ -/* return NULL; */ -} - -/** * array[x] */ static PyObject* @@ -731,15 +560,22 @@ /* Access of a single column. */ if (array->xlen == 1) { + if ((Uint32) _index >= array->ystart + array->ylen) + return RAISE (PyExc_IndexError, "array index out of range"); + return _get_single_pixel ((Uint8 *) surface->pixels, bpp, array->xstart, _index * array->padding * array->ystep); } if (array->ylen == 1) { + if ((Uint32) _index >= array->xstart + array->xlen) + return RAISE (PyExc_IndexError, "array index out of range"); + return _get_single_pixel ((Uint8 *) surface->pixels, bpp, array->xstart + _index * array->xstep, array->ystart * array->padding * array->ystep); } + return _array_slice_internal (array, _index, _index + 1, 1); } @@ -778,6 +614,8 @@ int bpp; int valbpp; Uint8 *pixels; + Uint8 *valpixels; + int copied = 0; Uint32 xstart = 0; Uint32 ystart = 0; @@ -800,7 +638,7 @@ ystart = array->ystart + low * array->ystep; xlen = array->xlen; ylen = ABS (high - low); - ystep = 1; + ystep = array->ystep; xstep = array->xstep; padding = array->padding; } @@ -810,13 +648,19 @@ ystart = array->ystart; xlen = ABS (high - low); ylen = array->ylen; - xstep = 1; + xstep = array->xstep; ystep = array->ystep; padding = array->padding; } - if (val->ylen / val->ystep != ylen / ystep || - val->xlen / val->xstep != xlen / xstep) +/* + printf ("ARRAY: %d:%d:%d, %d:%d:%d -- VAL: %d:%d:%d, %d:%d:%d\n", + xstart, xlen, xstep, ystart, ylen, ystep, + val->xstart, val->xlen, val->xstep, + val->ystart, val->ylen, val->ystep); +*/ + if (val->ylen / ABS (val->ystep) != ylen / ABS (ystep) || + val->xlen / ABS (val->xstep) != xlen / ABS (xstep)) { /* Bounds do not match. */ PyErr_SetString (PyExc_ValueError, "array sizes do not match"); @@ -827,6 +671,7 @@ bpp = surface->format->BytesPerPixel; valbpp = valsf->format->BytesPerPixel; pixels = (Uint8 *) surface->pixels; + valpixels = valsf->pixels; if (bpp != valbpp) { @@ -836,24 +681,42 @@ return -1; } + /* If we reassign the same array, we need to copy the pixels + * first. */ + if (SURFACE_EQUALS (array, val)) + { + /* We assign a different view or so. Copy the source buffer. */ + valpixels = malloc ((size_t) (surface->pitch * surface->h)); + if (!valpixels) + { + PyErr_SetString (PyExc_ValueError, "could not copy pixels"); + return -1; + } + valpixels = memcpy (valpixels, pixels, + (size_t) (surface->pitch * surface->h)); + copied = 1; + } + absxstep = ABS (xstep); absystep = ABS (ystep); y = ystart; + vy = val->ystart; + Py_BEGIN_ALLOW_THREADS; /* Single value assignment. */ switch (bpp) { case 1: - while (posy != ylen) + while (posy < ylen) { vx = val->xstart; posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint8 *) pixels + y * padding + x) = - (Uint8)*((Uint8 *) valsf->pixels + vy * val->padding + vx); + (Uint8)*((Uint8 *) valpixels + vy * val->padding + vx); vx += val->xstep; x += xstep; posx += absxstep; @@ -864,16 +727,15 @@ } break; case 2: - while (posy != ylen) + while (posy < ylen) { vx = val->xstart; posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint16 *) (pixels + y * padding) + x) = - (Uint16)*((Uint16 *) - ((Uint8*)valsf->pixels + vy * val->padding) + vx); + (Uint16)*((Uint16 *) (valpixels + vy * val->padding) + vx); vx += val->xstep; x += xstep; posx += absxstep; @@ -890,16 +752,15 @@ SDL_PixelFormat *format = surface->format; SDL_PixelFormat *vformat = valsf->format; - while (posy != ylen) + while (posy < ylen) { vx = val->xstart; posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - px = (Uint8 *) (pixels + y * padding) + x * 3; - vpx = (Uint8 *) ((Uint8*)valsf->pixels + y * val->padding) + - vx * 3; + px = ((Uint8 *) (pixels + y * padding) + x * 3); + vpx = ((Uint8 *) (valpixels + vy * val->padding) + vx * 3); #if (SDL_BYTEORDER == SDL_LIL_ENDIAN) *(px + (format->Rshift >> 3)) = @@ -927,16 +788,15 @@ break; } default: - while (posy != ylen) + while (posy < ylen) { vx = val->xstart; posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint32 *) (pixels + y * padding) + x) = - *((Uint32 *) - ((Uint8*)valsf->pixels + y * val->padding) + vx); + (Uint32)*((Uint32 *) (valpixels + vy * val->padding) + vx); vx += val->xstep; x += xstep; posx += absxstep; @@ -947,6 +807,12 @@ } break; } + Py_END_ALLOW_THREADS; + + if (copied) + { + free (valpixels); + } return 0; } @@ -958,9 +824,11 @@ Uint32 x = 0; Uint32 y = 0; int bpp; + int gooverx = 0; Uint8 *pixels; Uint32 color = 0; Uint32 *colorvals = NULL; + Uint32 *nextcolor = NULL; Py_ssize_t offset = 0; Py_ssize_t seqsize = PySequence_Size (val); @@ -987,7 +855,7 @@ ystart = array->ystart + low * array->ystep; xlen = array->xlen; ylen = ABS (high - low); - ystep = 1; + ystep = array->ystep; xstep = array->xstep; padding = array->padding; } @@ -997,27 +865,25 @@ ystart = array->ystart; xlen = ABS (high - low); ylen = array->ylen; - xstep = 1; + xstep = array->xstep; ystep = array->ystep; padding = array->padding; } -/* - printf ("LEN: %d:%d - %d\n", xlen / xstep, ylen / ystep, seqsize); -*/ - if ((Uint32)seqsize != ylen / ystep) + if ((Uint32)seqsize != ylen / ABS (ystep)) { - if ((Uint32)seqsize != xlen / xstep) + if ((Uint32)seqsize != xlen / ABS (xstep)) { PyErr_SetString(PyExc_ValueError, "sequence size mismatch"); return -1; } + gooverx = 1; /* We have to iterate over the x axis. */ } - + if (seqsize == 1) { /* Single value assignment. */ - _set_single_pixel (pixels, bpp, xstart, x * padding * ystep, + _set_single_pixel (pixels, bpp, xstart, ystart + padding * ystep, surface->format, color); return 0; } @@ -1026,7 +892,7 @@ colorvals = malloc (sizeof (Uint32) * seqsize); if (!colorvals) { - PyErr_SetString(PyExc_ValueError, "could not copy colors"); + PyErr_SetString (PyExc_ValueError, "could not copy colors"); return -1; } @@ -1044,17 +910,251 @@ absxstep = ABS (xstep); absystep = ABS (ystep); y = ystart; + nextcolor = colorvals; + + Py_BEGIN_ALLOW_THREADS; + switch (bpp) + { + case 1: + if (gooverx) + { + while (posy < ylen) + { + posx = 0; + x = xstart; + nextcolor = colorvals; + while (posx < xlen) + { + color = *nextcolor++; + *((Uint8 *) pixels + y * padding + x) = (Uint8) color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + else + { + while (posy < ylen) + { + posx = 0; + x = xstart; + color = *nextcolor++; + while (posx < xlen) + { + *((Uint8 *) pixels + y * padding + x) = (Uint8) color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + break; + case 2: + if (gooverx) + { + while (posy < ylen) + { + posx = 0; + x = xstart; + nextcolor = colorvals; + while (posx < xlen) + { + color = *nextcolor++; + *((Uint16 *) (pixels + y * padding) + x) = (Uint16) color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + else + { + while (posy < ylen) + { + posx = 0; + x = xstart; + color = *nextcolor++; + while (posx < xlen) + { + *((Uint16 *) (pixels + y * padding) + x) = (Uint16) color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + break; + case 3: + { + Uint8 *px; + SDL_PixelFormat *format = surface->format; + + if (gooverx) + { + while (posy < ylen) + { + posx = 0; + x = xstart; + nextcolor = colorvals; + while (posx < xlen) + { + color = *nextcolor++; + px = ((Uint8 *) (pixels + y * padding) + x * 3); +#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) + *(px + (format->Rshift >> 3)) = (Uint8) (color >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (color >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) color; +#else + *(px + 2 - (format->Rshift >> 3)) = (Uint8) (color >> 16); + *(px + 2 - (format->Gshift >> 3)) = (Uint8) (color >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) color; +#endif + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + else + { + while (posy < ylen) + { + posx = 0; + x = xstart; + color = *nextcolor++; + while (posx < xlen) + { + px = ((Uint8 *) (pixels + y * padding) + x * 3); +#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) + *(px + (format->Rshift >> 3)) = (Uint8) (color >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (color >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) color; +#else + *(px + 2 - (format->Rshift >> 3)) = (Uint8) (color >> 16); + *(px + 2 - (format->Gshift >> 3)) = (Uint8) (color >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) color; +#endif + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + break; + } + default: + if (gooverx) + { + while (posy < ylen) + { + posx = 0; + x = xstart; + nextcolor = colorvals; + while (posx < xlen) + { + color = *nextcolor++; + *((Uint32 *) (pixels + y * padding) + x) = color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + else + { + while (posy < ylen) + { + posx = 0; + x = xstart; + color = *nextcolor++; + while (posx < xlen) + { + *((Uint32 *) (pixels + y * padding) + x) = color; + x += xstep; + posx += absxstep; + } + y += ystep; + posy += absystep; + } + } + break; + } + free (colorvals); + Py_END_ALLOW_THREADS; + return 0; +} + +static int +_array_assign_slice (PyPixelArray *array, Py_ssize_t low, Py_ssize_t high, + Uint32 color) +{ + SDL_Surface *surface; + Uint32 x = 0; + Uint32 y = 0; + int bpp; + Uint8 *pixels; + + Uint32 xstart = 0; + Uint32 ystart = 0; + Uint32 xlen; + Uint32 ylen; + Sint32 xstep; + Sint32 ystep; + Uint32 padding; + Uint32 posx = 0; + Uint32 posy = 0; + Sint32 absxstep; + Sint32 absystep; + + surface = PySurface_AsSurface (array->surface); + bpp = surface->format->BytesPerPixel; + pixels = (Uint8 *) surface->pixels; + + /* Set the correct slice indices */ + if (array->xlen == 1) + { + xstart = array->xstart; + ystart = array->ystart + low * array->ystep; + xlen = array->xlen; + ylen = ABS (high - low); + ystep = array->ystep; + xstep = array->xstep; + padding = array->padding; + } + else + { + xstart = array->xstart + low * array->xstep; + ystart = array->ystart; + xlen = ABS (high - low); + ylen = array->ylen; + xstep = array->xstep; + ystep = array->ystep; + padding = array->padding; + } + + absxstep = ABS (xstep); + absystep = ABS (ystep); + y = ystart; + Py_BEGIN_ALLOW_THREADS; + /* Single value assignment. */ switch (bpp) { case 1: - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - color = *colorvals++; *((Uint8 *) pixels + y * padding + x) = (Uint8) color; x += xstep; posx += absxstep; @@ -1064,13 +1164,12 @@ } break; case 2: - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - color = *colorvals++; *((Uint16 *) (pixels + y * padding) + x) = (Uint16) color; x += xstep; posx += absxstep; @@ -1084,14 +1183,13 @@ Uint8 *px; SDL_PixelFormat *format = surface->format; - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - color = *colorvals++; - px = (Uint8 *) (pixels + y * padding) + x * 3; + px = ((Uint8 *) (pixels + y * padding) + x * 3); #if (SDL_BYTEORDER == SDL_LIL_ENDIAN) *(px + (format->Rshift >> 3)) = (Uint8) (color >> 16); *(px + (format->Gshift >> 3)) = (Uint8) (color >> 8); @@ -1099,7 +1197,7 @@ #else *(px + 2 - (format->Rshift >> 3)) = (Uint8) (color >> 16); *(px + 2 - (format->Gshift >> 3)) = (Uint8) (color >> 8); - *(px - (format->Bshift >> 3)) = (Uint8) color; + *(px + 2 - (format->Bshift >> 3)) = (Uint8) color; #endif x += xstep; posx += absxstep; @@ -1109,14 +1207,13 @@ } break; } - default: - while (posy != ylen) + default: /* 4 bpp */ + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - color = *colorvals++; *((Uint32 *) (pixels + y * padding) + x) = color; x += xstep; posx += absxstep; @@ -1126,6 +1223,7 @@ } break; } + Py_END_ALLOW_THREADS; return 0; } @@ -1200,20 +1298,21 @@ /* printf ("ITEM: %d:%d, %d:%d %d:%d %d\n", xstart, ystart, xlen, xstep, ylen, ystep, padding); -*/ +*/ absxstep = ABS (xstep); absystep = ABS (ystep); y = ystart; + Py_BEGIN_ALLOW_THREADS; /* Single value assignment. */ switch (bpp) { case 1: - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint8 *) pixels + y * padding + x) = (Uint8) color; x += xstep; @@ -1224,11 +1323,11 @@ } break; case 2: - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint16 *) (pixels + y * padding) + x) = (Uint16) color; x += xstep; @@ -1243,13 +1342,13 @@ Uint8 *px; SDL_PixelFormat *format = surface->format; - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { - px = (Uint8 *) (pixels + y * padding) + x * 3; + px = ((Uint8 *) (pixels + y * padding) + x * 3); #if (SDL_BYTEORDER == SDL_LIL_ENDIAN) *(px + (format->Rshift >> 3)) = (Uint8) (color >> 16); *(px + (format->Gshift >> 3)) = (Uint8) (color >> 8); @@ -1257,7 +1356,7 @@ #else *(px + 2 - (format->Rshift >> 3)) = (Uint8) (color >> 16); *(px + 2 - (format->Gshift >> 3)) = (Uint8) (color >> 8); - *(px - (format->Bshift >> 3)) = (Uint8) color; + *(px + 2 - (format->Bshift >> 3)) = (Uint8) color; #endif x += xstep; posx += absxstep; @@ -1268,11 +1367,11 @@ break; } default: /* 4 bpp */ - while (posy != ylen) + while (posy < ylen) { posx = 0; x = xstart; - while (posx != xlen) + while (posx < xlen) { *((Uint32 *) (pixels + y * padding) + x) = color; x += xstep; @@ -1283,6 +1382,7 @@ } break; } + Py_END_ALLOW_THREADS; return 0; } @@ -1295,7 +1395,6 @@ { SDL_Surface *surface; Uint32 color; - int i = 0; if (array->xlen != 1) { @@ -1332,41 +1431,7 @@ } else if (_get_color_from_object (value, surface->format, &color)) { - if (array->xlen == 1) - { - for (i = low; i < high; i++) - { - _set_single_pixel ((Uint8*) surface->pixels, - surface->format->BytesPerPixel, - array->xstart, i * array->padding * array->ystep, - surface->format, color); - } - } - else if (array->ylen == 1) - { - for (i = low; i < high; i++) - { - _set_single_pixel ((Uint8*) surface->pixels, - surface->format->BytesPerPixel, - array->xstart + i * array->xstep, - array->ystart * array->padding, - surface->format, color); - } - } - else - { - Uint32 y; - for (y = array->ystart; y < array->ylen; y += array->ystep) - { - for (i = low; i < high; i++) - { - _set_single_pixel ((Uint8*) surface->pixels, - surface->format->BytesPerPixel, - array->xstart + i * array->xstep, y * array->padding, - surface->format, color); - } - } - } + return _array_assign_slice (array, low, high, color); } else if (PySequence_Check (value)) { @@ -1393,6 +1458,7 @@ Uint32 posy = 0; Sint32 absxstep; Sint32 absystep; + int found = 0; surface = PySurface_AsSurface (array->surface); bpp = surface->format->BytesPerPixel; @@ -1405,18 +1471,22 @@ absystep = ABS (array->ystep); y = array->ystart; + Py_BEGIN_ALLOW_THREADS; switch (bpp) { case 1: - while (posy != array->ylen) + while (posy < array->ylen && !found) { posx = 0; x = array->xstart; - while (posx != array->xlen) + while (posx < array->xlen) { if (*((Uint8 *) pixels + y * array->padding + x) == (Uint8) color) - return 1; + { + found = 1; + break; + } x += array->xstep; posx += absxstep; } @@ -1425,15 +1495,18 @@ } break; case 2: - while (posy != array->ylen) + while (posy < array->ylen && !found) { posx = 0; x = array->xstart; - while (posx != array->xlen) + while (posx < array->xlen) { if (*((Uint16 *) (pixels + y * array->padding) + x) == (Uint16) color) - return 1; + { + found = 1; + break; + } x += array->xstep; posx += absxstep; } @@ -1446,11 +1519,11 @@ Uint32 pxcolor; Uint8 *pix; - while (posy != array->ylen) + while (posy < array->ylen && !found) { posx = 0; x = array->xstart; - while (posx != array->xlen) + while (posx < array->xlen) { pix = ((Uint8 *) (pixels + y * array->padding) + x * 3); #if SDL_BYTEORDER == SDL_LIL_ENDIAN @@ -1459,7 +1532,10 @@ pxcolor = (pix[2]) + (pix[1] << 8) + (pix[0] << 16); #endif if (pxcolor == color) - return 1; + { + found = 1; + break; + } x += array->xstep; posx += absxstep; } @@ -1469,15 +1545,18 @@ break; } default: /* 4 bpp */ - while (posy != array->ylen) + while (posy < array->ylen && !found) { posx = 0; x = array->xstart; - while (posx != array->xlen) + while (posx < array->xlen) { if (*((Uint32 *) (pixels + y * array->padding) + x) == color) - return 1; + { + found = 1; + break; + } x += array->xstep; posx += absxstep; } @@ -1486,121 +1565,23 @@ } break; } - return 0; -} -/** - * array += .... - */ -static PyObject* -_pxarray_inplace_concat (PyPixelArray *array, PyObject *seq) -{ - /* TODO */ - return RAISE (PyExc_NotImplementedError, "method not implemented"); + Py_END_ALLOW_THREADS; + return found; } /** - * array *= ... + * iter (arrray), for x in array */ static PyObject* -_pxarray_inplace_repeat (PyPixelArray *array, Py_ssize_t n) +_pxarray_iter (PyPixelArray *array) { - /* TODO */ - return RAISE (PyExc_NotImplementedError, "method not implemented"); -/* SDL_Surface *surface; */ -/* int bpp; */ -/* Uint8 *pixels; */ -/* Uint32 x = 0; */ -/* Uint32 y = 0; */ -/* Uint32 posx = 0; */ -/* Uint32 posy = 0; */ -/* Sint32 absxstep; */ -/* Sint32 absystep; */ -/* Uint32 maxcolor; */ - -/* surface = PySurface_AsSurface (array->surface); */ -/* bpp = surface->format->BytesPerPixel; */ -/* maxcolor = SDL_MapRGB (surface->format, 255, 255, 255); */ - -/* /\* Check the factor bounds. *\/ */ -/* if (n < 0) */ -/* return RAISE (PyExc_TypeError, "negative factors are not allowed"); */ -/* if ((Uint32) n > maxcolor) */ -/* return RAISE (PyExc_ArithmeticError, "integer overflow for factor"); */ - -/* pixels = (Uint8 *) surface->pixels; */ -/* absxstep = ABS (array->xstep); */ -/* absystep = ABS (array->ystep); */ -/* y = array->ystart; */ - -/* switch (bpp) */ -/* { */ -/* case 1: */ -/* while (posy != array->ylen) */ -/* { */ -/* x = array->xstart; */ -/* posx = 0; */ -/* while (posx != array->xlen) */ -/* { */ -/* *((Uint8 *) pixels + y * array->padding + x) *= n; */ -/* x += array->xstep; */ -/* posx += absxstep; */ -/* } */ -/* y += array->ystep; */ -/* posy += absystep; */ -/* } */ -/* break; */ -/* case 2: */ -/* while (posy != array->ylen) */ -/* { */ -/* x = array->xstart; */ -/* posx = 0; */ -/* while (posx != array->xlen) */ -/* { */ -/* *((Uint16 *) (pixels + y * array->padding) + x) *= n; */ -/* x += array->xstep; */ -/* posx += absxstep; */ -/* } */ -/* y += array->ystep; */ -/* posy += absystep; */ -/* } */ -/* break; */ -/* case 3: */ -/* { */ -/* Uint8 *px; */ - -/* while (posy != array->ylen) */ -/* { */ -/* x = array->xstart; */ -/* posx = 0; */ -/* while (posx != array->xlen) */ -/* { */ -/* px = (Uint8 *) (pixels + y * array->padding) + x * 3; */ -/* x += array->xstep; */ -/* posx += absxstep; */ -/* } */ -/* y += array->ystep; */ -/* posy += absystep; */ -/* } */ -/* break; */ -/* } */ -/* default: */ -/* while (posy != array->ylen) */ -/* { */ -/* x = array->xstart; */ -/* posx = 0; */ -/* while (posx != array->xlen) */ -/* { */ -/* *((Uint32 *) (pixels + y * array->padding) + x) *= n; */ -/* x += array->xstep; */ -/* posx += absxstep; */ -/* } */ -/* y += array->ystep; */ -/* posy += absystep; */ -/* } */ -/* break; */ -/* } */ -/* return (PyObject *)array; */ +/* + printf ("Iter ARRAY: %d:%d:%d %d:%d:%d\n", + array->xstart, array->xlen, array->xstep, + array->ystart, array->ylen, array->ystep); +*/ + return PySeqIter_New ((PyObject *) array); } /**** Mapping interfaces ****/ @@ -1610,17 +1591,35 @@ * array[x,y], array[:,:], ... */ static int -_get_subslice (PyPixelArray *array, PyObject *op, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) +_get_subslice (PyObject *op, Py_ssize_t length, Py_ssize_t *start, + Py_ssize_t *stop, Py_ssize_t *step) { *start = -1; *stop = -1; *step = -1; - if (PyInt_Check (op)) + if (PySlice_Check (op)) + { + Py_ssize_t slicelen; + + /* Operator is a slice: array[x::, */ + if (PySlice_GetIndicesEx ((PySliceObject *) op, length, + start, stop, step, &slicelen) < 0) + { + return 0; + } + } + else if (PyInt_Check (op)) { /* Plain index: array[x, */ *start = PyInt_AsLong (op); + if (*start < 0) + *start += length; + if (*start >= length || *start < 0) + { + PyErr_SetString(PyExc_IndexError, "invalid index"); + return 0; + } *stop = (*start) + 1; *step = 1; } @@ -1637,19 +1636,15 @@ return 0; } *start = (int) val; - *stop = *start + 1; - *step = 1; - } - else if (PySlice_Check (op)) - { - Py_ssize_t slicelen; - - /* Operator is a slice: array[x::, */ - if (PySlice_GetIndicesEx ((PySliceObject *) op, length, - start, stop, step, &slicelen) < 0) + if (*start < 0) + *start += length; + if (*start >= length || *start < 0) { + PyErr_SetString(PyExc_IndexError, "invalid index"); return 0; - } + } + *stop = (*start) + 1; + *step = 1; } return 1; } @@ -1684,8 +1679,8 @@ if (size > 2 || (size == 2 && array->xlen == 1)) return RAISE (PyExc_IndexError, "too many indices for the array"); - lenx = (array->xlen > 1) ? array->xlen / array->xstep : 0; - leny = array->ylen / array->ystep; + lenx = (array->xlen > 1) ? array->xlen / ABS (array->xstep) : 0; + leny = array->ylen / ABS (array->ystep); obj = PySequence_Fast_GET_ITEM (op, 0); if (obj == Py_Ellipsis || obj == Py_None) @@ -1697,7 +1692,7 @@ xstop = array->xlen; xstep = array->xstep; } - else if (!_get_subslice (array, obj, lenx, &xstart, &xstop, &xstep)) + else if (!_get_subslice (obj, lenx, &xstart, &xstop, &xstep)) { /* Error on retrieving the subslice. */ return NULL; @@ -1715,7 +1710,7 @@ ystop = array->ylen; ystep = array->ystep; } - else if (!_get_subslice (array, obj, leny, &ystart, &ystop, &ystep)) + else if (!_get_subslice (obj, leny, &ystart, &ystop, &ystep)) { /* Error on retrieving the subslice. */ return NULL; @@ -1731,63 +1726,29 @@ /* Null value? */ if (xstart == xstop || ystart == ystop) Py_RETURN_NONE; - - /* Check boundaries. */ - if (xstart + xstep >= xstop) - { - xstop = xstart + 1; - xstep = 1; - } - - if (ystart + ystep >= ystop) - { - ystop = ystart + 1; - ystep = 1; - } - - /* Move to the correct offsets. */ - if (xstart < 0) - xstart += array->xstart + array->xlen; - if (ystart < 0) - ystart += array->ystart + array->ylen; - if (xstop < 0) - xstop += array->xstart + array->xlen; - if (ystop < 0) - ystop += array->ystart + array->ylen; - +/* + printf ("X: %d:%d:%d Y: %d:%d:%d\n", xstart, xstop, xstep, + ystart, ystop, ystep); +*/ /* Single value? */ - if (xstart + xstep >= xstop && ystart + ystep >= ystop) + if (ABS (xstop - xstart) == 1 && ABS (ystop - ystart) == 1) { return _get_single_pixel ((Uint8 *) surface->pixels, surface->format->BytesPerPixel, array->xstart + xstart, ystart * array->padding * array->ystep); } -/* - printf ("X: %d:%d:%d Y: %d:%d:%d\n", xstart, xstop, xstep, - ystart, ystop, ystep); -*/ -/* - printf ("NEW ARRAY: %d:%d %d:%d:%d %d:%d:%d %d\n", - array->xstart + xstart, array->ystart + ystart, - xstart, xstop, xstep, ystart, ystop, ystep, array->padding); -*/ -/* - lenx = MAX((xstop - xstart) / xstep, 1); - leny = MAX((ystop - ystart) / ystep, 1); -*/ /* -static PyPixelArray* _pxarray_new_internal (PyTypeObject *type, - PyObject *surface, Uint32 start, Uint32 end, Uint32 xlen, Uint32 ylen, - Uint32 xstep, Uint32 ystep, Uint32 padding, PyObject *parent); + printf ("NEW ARRAY: %d:%d:%d %d:%d:%d\n", + array->xstart + xstart, ABS (xstop - xstart), xstep, + array->ystart + ystart, ABS (ystop - ystart), ystep); */ - return (PyObject *) _pxarray_new_internal (&PyPixelArray_Type, array->surface, (Uint32) array->xstart + xstart, (Uint32) array->ystart + ystart, - (Uint32) xstop - xstart, - (Uint32) ystop - ystart, + (Uint32) ABS (xstop - xstart), + (Uint32) ABS (ystop - ystart), (Sint32) xstep, (Sint32) ystep, (Uint32) array->padding, (PyObject *) array); @@ -1805,25 +1766,24 @@ { /* 2D array - slice along the x axis */ retval = PySlice_GetIndicesEx ((PySliceObject *) op, - (Py_ssize_t) (array->xlen / array->xstep), &start, &stop, &step, - &slicelen); + (Py_ssize_t) (array->xlen / ABS (array->xstep)), &start, &stop, + &step, &slicelen); } else { /* 1D array - use the y axis. */ retval = PySlice_GetIndicesEx ((PySliceObject *) op, - (Py_ssize_t) (array->ylen / array->ystep), &start, &stop, &step, - &slicelen); + (Py_ssize_t) (array->ylen / ABS (array->ystep)), &start, &stop, + &step, &slicelen); } if (retval < 0 || slicelen < 0) return NULL; if (slicelen == 0) Py_RETURN_NONE; - /* printf ("start: %d, stop: %d, step: %d, len: %d\n", start, stop, step, slicelen); -*/ +*/ return (PyObject *) _array_slice_internal (array, start, stop, step); } else if (PyIndex_Check (op) || PyInt_Check (op) || PyLong_Check (op)) @@ -1857,9 +1817,168 @@ static int _pxarray_ass_subscript (PyPixelArray *array, PyObject* op, PyObject* value) { - SDL_Surface *surface = PySurface_AsSurface (array->surface); + /* TODO: by time we can make this faster by avoiding the creation of + * temporary subarrays. + */ - if (PyIndex_Check (op) || PyInt_Check (op) || PyLong_Check (op)) + /* Note: order matters here. + * First check array[x,y], then array[x:y:z], then array[x] + * Otherwise it'll fail. + */ + if (PySequence_Check (op)) + { + PyPixelArray *tmparray; + PyObject *obj; + Py_ssize_t size = PySequence_Size (op); + Py_ssize_t xstart, xstop, xstep; + Py_ssize_t ystart, ystop, ystep; + Py_ssize_t lenx, leny; + int retval; + + if (size == 0) + { + /* array[,], array[()] ... */ + if (array->xlen == 1) + return _pxarray_ass_slice (array, 0, (Py_ssize_t) array->ylen, + value); + else + return _pxarray_ass_slice (array, 0, (Py_ssize_t) array->xlen, + value); + } + if (size > 2 || (size == 2 && array->xlen == 1)) + { + PyErr_SetString (PyExc_IndexError, + "too many indices for the array"); + return -1; + } + + lenx = (array->xlen > 1) ? array->xlen / ABS (array->xstep) : 0; + leny = array->ylen / ABS (array->ystep); + + obj = PySequence_Fast_GET_ITEM (op, 0); + if (obj == Py_Ellipsis || obj == Py_None) + { + /* Operator is the ellipsis or None + * array[...,XXX], array[None,XXX] + */ + xstart = 0; + xstop = array->xlen; + xstep = array->xstep; + } + else if (!_get_subslice (obj, lenx, &xstart, &xstop, &xstep)) + { + /* Error on retrieving the subslice. */ + return -1; + } + + if (size == 2) + { + obj = PySequence_Fast_GET_ITEM (op, 1); + if (obj == Py_Ellipsis || obj == Py_None) + { + /* Operator is the ellipsis or None + * array[XXX,...], array[XXX,None] + */ + ystart = array->ystart; + ystop = array->ylen; + ystep = array->ystep; + } + else if (!_get_subslice (obj, leny, &ystart, &ystop, &ystep)) + { + /* Error on retrieving the subslice. */ + return -1; + } + } + else + { + ystart = array->ystart; + ystop = array->ylen; + ystep = array->ystep; + } + + /* Null value? Do nothing then. */ + if (xstart == xstop || ystart == ystop) + return 0; + + /* Single value? */ + if (ABS (xstop - xstart) == 1 && ABS (ystop - ystart) == 1) + { + tmparray = _pxarray_new_internal (&PyPixelArray_Type, + array->surface, + (Uint32) array->xstart + xstart, + (Uint32) array->ystart + ystart, + 1, 1, 1, 1, (Uint32) array->padding, (PyObject *) array); + if (!tmparray) + return -1; + retval = _pxarray_ass_item (tmparray, 0, value); + Py_DECREF (tmparray); + return retval; + } + tmparray =_pxarray_new_internal (&PyPixelArray_Type, + array->surface, + (Uint32) array->xstart + xstart, (Uint32) array->ystart + ystart, + (Uint32) ABS (xstop - xstart), (Uint32) ABS (ystop - ystart), + (Sint32) xstep, (Sint32) ystep, + (Uint32) array->padding, (PyObject *) array); + if (!tmparray) + return -1; + + if (tmparray->xlen == 1) + retval = _pxarray_ass_slice (tmparray, 0, + (Py_ssize_t) tmparray->ylen, value); + else + retval = _pxarray_ass_slice (tmparray, 0, + (Py_ssize_t) tmparray->xlen, value); + Py_DECREF (tmparray); + return retval; + } + else if (PySlice_Check (op)) + { + /* A slice */ + PyPixelArray *tmparray; + Py_ssize_t slicelen; + Py_ssize_t step; + Py_ssize_t start; + Py_ssize_t stop; + int retval; + + if (array->xlen > 1) + { + /* 2D array - slice along the x axis */ + retval = PySlice_GetIndicesEx ((PySliceObject *) op, + (Py_ssize_t) (array->xlen / ABS (array->xstep)), &start, &stop, + &step, &slicelen); + } + else + { + /* 1D array - use the y axis. */ + retval = PySlice_GetIndicesEx ((PySliceObject *) op, + (Py_ssize_t) (array->ylen / ABS (array->ystep)), &start, &stop, + &step, &slicelen); + } + if (retval < 0 || slicelen < 0) + return -1; + if (slicelen == 0) + return 0; + +/* + printf ("start: %d, stop: %d, step: %d, len: %d\n", start, stop, + step, slicelen); +*/ + tmparray = (PyPixelArray *) _array_slice_internal (array, start, stop, + step); + if (!tmparray) + return -1; + if (tmparray->xlen == 1) + retval = _pxarray_ass_slice (tmparray, 0, + (Py_ssize_t) tmparray->ylen, value); + else + retval = _pxarray_ass_slice (tmparray, 0, + (Py_ssize_t) tmparray->xlen, value); + Py_DECREF (tmparray); + return retval; + } + else if (PyIndex_Check (op) || PyInt_Check (op) || PyLong_Check (op)) { Py_ssize_t i; #if PY_VERSION_HEX >= 0x02050000 @@ -1876,14 +1995,15 @@ #endif if (i == -1 && PyErr_Occurred ()) return -1; - if (i < 0) - i += (array->xlen > 1) ? array->xlen / array->xstep : - array->ylen / array->ystep; + i += (array->xlen > 1) ? array->xlen / ABS (array->xstep) : + array->ylen / ABS (array->ystep); return _pxarray_ass_item (array, i, value); } - PyErr_SetString (PyExc_NotImplementedError, "method not implemented"); + + PyErr_SetString (PyExc_TypeError, + "index must be an integer, sequence or slice"); return -1; } @@ -1899,7 +2019,7 @@ if (surface->format->BytesPerPixel < 1 || surface->format->BytesPerPixel > 4) return RAISE (PyExc_ValueError, - "unsupport bit depth for reference array"); + "unsupported bit depth for reference array"); return (PyObject *) _pxarray_new_internal (&PyPixelArray_Type, surfobj, 0, 0, @@ -1920,10 +2040,9 @@ /* create the module */ module = Py_InitModule3 ("pixelarray", NULL, NULL); - PyPixelArray_Type.tp_getattro = PyObject_GenericGetAttr; Py_INCREF (&PyPixelArray_Type); PyModule_AddObject (module, "PixelArray", (PyObject *) &PyPixelArray_Type); - + PyPixelArray_Type.tp_getattro = PyObject_GenericGetAttr; dict = PyModule_GetDict (module); c_api[0] = &PyPixelArray_Type; @@ -1934,5 +2053,6 @@ /*imported needed apis*/ import_pygame_base (); + import_pygame_color(); import_pygame_surface (); } diff -Nru pygame-1.8.0release/src/pixelarray.doc pygame-1.8.1release/src/pixelarray.doc --- pygame-1.8.0release/src/pixelarray.doc 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/pixelarray.doc 2008-07-07 01:57:33.000000000 -0400 @@ -1,15 +1,12 @@ pygame.PixelArray -pygame Object for direct pixel access of surfaces +pygame object for direct pixel access of surfaces pygame.PixelArray(Surface): return PixelArray -NOTE: This is an EXPERIMENTAL module and subject to CHANGE in future -versions. - The PixelArray wraps up a Surface and provides a direct 2D array access to its pixels using the surface its rows as first and its columns as -second axis. It supports slicing and row and pixel manipluation while -inplace operations such as addition, subtraction, multiplication, -division and slice assignments are not allowed. +second axis. It supports slicing, row and pixel manipluation, slicing +and slice assignments while inplace operations such as addition, +subtraction, multiplication, division and so forth are not allowed. While it is possible to assign both, integer color values and RGB(A) color tuples, the PixelArray will only use integers for the color @@ -39,7 +36,7 @@ pxarray[a:b] = ((255, 0, 255), 0xAACCEE, ...) # same as above pxarray[a:b] = otherarray[x:y] # slice sizes must match - + Note, that something like pxarray[2:4][3:5] = ... @@ -53,11 +50,26 @@ pxarray[2][3:5] = ... pxarray[3][3:5] = ... +If you want to make a rectangular manipulation or create a view of a +part of the PixelArray, you also can use the subscript abilities. You +can easily create different view by creating 'subarrays' using the +subscripts. + + # Create some new PixelArray objects providing a different view + # of the original array/surface. + newarray = pxarray[2:4,3:5] + otherarray = pxarray[::2,::2] + +Subscripts also can be used to do fast rectangular pixel manipulations +instead of iterating over the x or y axis as above. + + pxarray[::2,:] = (0, 0, 0) # Make each second column black. + During its lifetime, the PixelArray locks the surface, thus you explicitly have to delete it once its not used anymore and the surface should perform operations in the same scope. -New in pygame 1.8. +New in pygame 1.8. Subscript support is new in pygame 1.8.1.
        surface @@ -66,3 +78,72 @@ The Surface, the PixelArray was created for. + +make_surface +Creates a new Surface from the current PixelArray. +PixelArray.make_surface (): Return Surface + +Creates a new Surface from the current PixelArray. Depending on the +current PixelArray the size, pixel order etc. will be different from the +original Surface. + + # Create a new surface flipped around the vertical axis. + sf = pxarray[:,::-1].make_surface () + +New in pygame 1.8.1. + + +replace +Replaces the passed color in the PixelArray with another one. +PixelArray.replace (color, repcolor, distance=0, weights=(0.299, 0.587, 0.114)): Return None + +Replaces the pixels with the passed color in the PixelArray by changing +them them to the passed replacement color. + +It uses a simple weighted euclidian distance formula to calculate the +distance between the colors. The distance space ranges from 0.0 to 1.0 +and is used as threshold for the color detection. This causes the +replacement to take pixels with a similar, but not exactly identical +color, into account as well. + +This is an in place operation that directly affects the pixels of the +PixelArray. + +New in pygame 1.8.1. + + +extract +Extracts the passed color from the PixelArray. +PixelArray.extract (color, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray + +Extracts the passed color by changing all matching pixels to white, +while non-matching pixels are changed to black. This returns a new +PixelArray with the black/white color mask. + +It uses a simple weighted euclidian distance formula to calculate the +distance between the colors. The distance space ranges from 0.0 to +1.0 and is used as threshold for the color detection. This causes the +extraction to take pixels with a similar, but not exactly identical +color, into account as well. + +New in pygame 1.8.1. + + +compare +Compares the PixelArray with another one. +PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray + +Compares the contents of the PixelArray with those from the passed PixelArray. +It returns a new PixelArray with a black/white color mask that indicates the +differences (white) of both arrays. Both PixelArray objects must have indentical +bit depths and dimensions. + +It uses a simple weighted euclidian distance formula to calculate the +distance between the colors. The distance space ranges from 0.0 to +1.0 and is used as threshold for the color detection. This causes the +comparision to mark pixels with a similar, but not exactly identical +color, as black. + +New in pygame 1.8.1. + + diff -Nru pygame-1.8.0release/src/pixelarray_methods.c pygame-1.8.1release/src/pixelarray_methods.c --- pygame-1.8.0release/src/pixelarray_methods.c 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/src/pixelarray_methods.c 2008-07-07 01:57:33.000000000 -0400 @@ -0,0 +1,1145 @@ +/* + pygame - Python Game Library + Copyright (C) 2007-2008 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* Simple weighted euclidian distance, which tries to get near to the + * human eye reception using the weights. + * It receives RGB values in the range 0-255 and returns a distance + * value between 0.0 and 1.0. + */ +#define COLOR_DIFF_RGB(wr,wg,wb,r1,g1,b1,r2,g2,b2) \ + (sqrt (wr * (r1 - r2) * (r1 - r2) + \ + wg * (g1 - g2) * (g1 - g2) + \ + wb * (b1 - b2) * (b1 - b2)) / 255.0) + +#define WR_NTSC 0.299 +#define WG_NTSC 0.587 +#define WB_NTSC 0.114 + +/** + * Tries to retrieve a valid color for a Surface. + */ +static int +_get_color_from_object (PyObject *val, SDL_PixelFormat *format, Uint32 *color) +{ + Uint8 rgba[4]; + + if (!val) + return 0; + + if (PyInt_Check (val)) + { + long intval = PyInt_AsLong (val); + if (intval == -1 && PyErr_Occurred ()) + { + PyErr_SetString (PyExc_ValueError, "invalid color argument"); + return 0; + } + *color = (Uint32) intval; + return 1; + } + else if (PyLong_Check (val)) + { + unsigned long longval = PyLong_AsUnsignedLong (val); + if (PyErr_Occurred ()) + { + PyErr_SetString(PyExc_ValueError, "invalid color argument"); + return 0; + } + *color = (Uint32) longval; + return 1; + } + else if (RGBAFromColorObj (val, rgba)) + { + *color = (Uint32) SDL_MapRGBA + (format, rgba[0], rgba[1], rgba[2], rgba[3]); + return 1; + } + else + PyErr_SetString (PyExc_ValueError, "invalid color argument"); + return 0; +} + +/** + * Retrieves a single pixel located at index from the surface pixel + * array. + */ +static PyObject* +_get_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row) +{ + Uint32 pixel; + + switch (bpp) + { + case 1: + pixel = (Uint32)*((Uint8 *) pixels + row + _index); + break; + case 2: + pixel = (Uint32)*((Uint16 *) (pixels + row) + _index); + break; + case 3: + { + Uint8 *px = ((Uint8 *) (pixels + row) + _index * 3); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + pixel = (px[0]) + (px[1] << 8) + (px[2] << 16); +#else + pixel = (px[2]) + (px[1] << 8) + (px[0] << 16); +#endif + break; + } + default: /* 4 bpp */ + pixel = *((Uint32 *) (pixels + row) + _index); + break; + } + + return PyInt_FromLong ((long)pixel); +} + +/** + * Sets a single pixel located at index from the surface pixel array. + */ +static void +_set_single_pixel (Uint8 *pixels, int bpp, Uint32 _index, Uint32 row, + SDL_PixelFormat *format, Uint32 color) +{ + switch (bpp) + { + case 1: + *((Uint8 *) pixels + row + _index) = (Uint8) color; + break; + case 2: + *((Uint16 *) (pixels + row) + _index) = (Uint16) color; + break; + case 3: +#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) + *((Uint8 *) (pixels + row) + _index * 3 + (format->Rshift >> 3)) = + (Uint8) (color >> 16); + *((Uint8 *) (pixels + row) + _index * 3 + (format->Gshift >> 3)) = + (Uint8) (color >> 8); + *((Uint8 *) (pixels + row) + _index * 3 + (format->Bshift >> 3)) = + (Uint8) color; +#else + *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Rshift >> 3)) = + (Uint8) (color >> 16); + *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Gshift >> 3)) = + (Uint8) (color >> 8); + *((Uint8 *) (pixels + row) + _index * 3 + 2 - (format->Bshift >> 3)) = + (Uint8) color; +#endif + break; + default: /* 4 bpp */ + *((Uint32 *) (pixels + row) + _index) = color; + break; + } +} + +/** + * Creates a new surface using the currently applied dimensions, step + * size, etc. + */ +static PyObject* +_make_surface(PyPixelArray *array) +{ + PyObject *newsf; + SDL_Surface *tmpsf; + SDL_Surface *newsurf; + Uint8 *pixels; + Uint8 *origpixels; + + SDL_Surface *surface; + int bpp; + Uint32 x = 0; + Uint32 y = 0; + Uint32 vx = 0; + Uint32 vy = 0; + Uint32 posx = 0; + Uint32 posy = 0; + Uint32 absxstep; + Uint32 absystep; + + surface = PySurface_AsSurface (array->surface); + bpp = surface->format->BytesPerPixel; + + /* Create the second surface. */ + tmpsf = SDL_CreateRGBSurface (surface->flags, + (int) (array->xlen / ABS (array->xstep)), + (int) (array->ylen / ABS (array->ystep)), bpp, surface->format->Rmask, + surface->format->Gmask, surface->format->Bmask, surface->format->Amask); + if (!tmpsf) + return RAISE (PyExc_SDLError, SDL_GetError ()); + + /* Guarantee an identical format. */ + newsurf = SDL_ConvertSurface (tmpsf, surface->format, surface->flags); + if (!newsurf) + { + SDL_FreeSurface (tmpsf); + return RAISE (PyExc_SDLError, SDL_GetError ()); + } + SDL_FreeSurface (tmpsf); + + newsf = PySurface_New (newsurf); + if (!newsf) + { + SDL_FreeSurface (newsurf); + return NULL; + } + + /* Acquire a temporary lock. */ + if (SDL_MUSTLOCK (newsurf) == 0) + SDL_LockSurface (newsurf); + + pixels = (Uint8 *) newsurf->pixels; + origpixels = (Uint8 *) surface->pixels; + + absxstep = ABS (array->xstep); + absystep = ABS (array->ystep); + y = array->ystart; + + Py_BEGIN_ALLOW_THREADS; + /* Single value assignment. */ + switch (bpp) + { + case 1: + while (posy < array->ylen) + { + vx = 0; + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + *((Uint8 *) pixels + vy * newsurf->pitch + vx) = + (Uint8)*((Uint8 *) origpixels + y * array->padding + x); + vx++; + x += array->xstep; + posx += absxstep; + } + vy++; + y += array->ystep; + posy += absystep; + } + break; + case 2: + while (posy < array->ylen) + { + vx = 0; + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + *((Uint16 *) (pixels + vy * newsurf->pitch) + vx) = + (Uint16)*((Uint16 *) (origpixels + y * array->padding) + x); + vx++; + x += array->xstep; + posx += absxstep; + } + vy++; + y += array->ystep; + posy += absystep; + } + break; + case 3: + { + Uint8 *px; + Uint8 *vpx; + SDL_PixelFormat *format = newsurf->format; + SDL_PixelFormat *vformat = surface->format; + + while (posy < array->ylen) + { + vx = 0; + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + px = ((Uint8 *) (pixels + vy * newsurf->pitch) + vx * 3); + vpx = ((Uint8 *) (origpixels + y * array->padding) + x * 3); + +#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) + *(px + (format->Rshift >> 3)) = + *(vpx + (vformat->Rshift >> 3)); + *(px + (format->Gshift >> 3)) = + *(vpx + (vformat->Gshift >> 3)); + *(px + (format->Bshift >> 3)) = + *(vpx + (vformat->Bshift >> 3)); +#else + *(px + 2 - (format->Rshift >> 3)) = + *(vpx + 2 - (vformat->Rshift >> 3)); + *(px + 2 - (format->Gshift >> 3)) = + *(vpx + 2 - (vformat->Gshift >> 3)); + *(px + 2 - (format->Bshift >> 3)) = + *(vpx + 2 - (vformat->Bshift >> 3)); +#endif + vx++; + x += array->xstep; + posx += absxstep; + } + vy++; + y += array->ystep; + posy += absystep; + } + break; + } + default: + while (posy < array->ylen) + { + vx = 0; + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + *((Uint32 *) (pixels + vy * newsurf->pitch) + vx) = + (Uint32)*((Uint32 *) (origpixels + y * array->padding) + x); + vx++; + x += array->xstep; + posx += absxstep; + } + vy++; + y += array->ystep; + posy += absystep; + } + break; + } + Py_END_ALLOW_THREADS; + + if (SDL_MUSTLOCK (newsurf) == 0) + SDL_UnlockSurface (newsurf); + return newsf; +} + +static int +_get_weights (PyObject *weights, float *wr, float *wg, float *wb) +{ + int success = 1; + float rgb[3] = { 0 }; + + if (!weights) + { + *wr = WR_NTSC; + *wg = WG_NTSC; + *wb = WB_NTSC; + return 1; + } + + if (!PySequence_Check (weights)) + { + PyErr_SetString (PyExc_TypeError, "weights must be a sequence"); + success = 0; + } + else if (PySequence_Size (weights) < 3) + { + PyErr_SetString (PyExc_TypeError, + "weights must contain at least 3 values"); + success = 0; + } + else + { + PyObject *item; + int i; + + for (i = 0; i < 3; i++) + { + item = PySequence_GetItem (weights, i); + if (PyNumber_Check (item)) + { + PyObject *num = NULL; + if ((num = PyNumber_Float (item)) != NULL) + { + rgb[i] = (float) PyFloat_AsDouble (num); + Py_DECREF (num); + } + else if ((num = PyNumber_Int (item)) != NULL) + { + rgb[i] = (float) PyInt_AsLong (num); + if (rgb[i] == -1 && PyErr_Occurred ()) + success = 0; + Py_DECREF (num); + } + else if ((num = PyNumber_Long (item)) != NULL) + { + rgb[i] = (float) PyLong_AsLong (num); + if (PyErr_Occurred () && + PyErr_ExceptionMatches (PyExc_OverflowError)) + success = 0; + Py_DECREF (num); + } + } + else + { + PyErr_SetString (PyExc_TypeError, "invalid weights"); + success = 0; + } + Py_XDECREF (item); + if (!success) + break; + } + } + + if (success) + { + float sum = 0; + + *wr = rgb[0]; + *wg = rgb[1]; + *wb = rgb[2]; + if ((*wr < 0 || *wg < 0 || *wb < 0) || + (*wr == 0 && *wg == 0 && *wb == 0)) + { + PyErr_SetString (PyExc_ValueError, + "weights must be positive and greater than 0"); + return 0; + } + /* Build the average weight values. */ + sum = *wr + *wg + *wb; + *wr = *wr / sum; + *wg = *wg / sum; + *wb = *wb / sum; + + return success; + } + return 0; +} + +static PyObject* +_replace_color (PyPixelArray *array, PyObject *args, PyObject *kwds) +{ + PyObject *weights = NULL; + PyObject *delcolor = NULL; + PyObject *replcolor = NULL; + Uint32 dcolor; + Uint32 rcolor; + Uint8 r1, g1, b1, r2, g2, b2, a2; + SDL_Surface *surface; + float distance = 0; + float wr, wg, wb; + + Uint32 x = 0; + Uint32 y = 0; + Uint32 posx = 0; + Uint32 posy = 0; + Sint32 absxstep; + Sint32 absystep; + Uint8 *pixels; + + static char *keys[] = { "color", "repcolor", "distance", "weights", NULL }; + + if (!PyArg_ParseTupleAndKeywords (args, kwds, "OO|fO", keys, &delcolor, + &replcolor, &distance, &weights)) + return NULL; + + if (distance < 0 || distance > 1) + return RAISE (PyExc_ValueError, + "distance must be in the range from 0.0 to 1.0"); + + surface = PySurface_AsSurface (array->surface); + if (!_get_color_from_object (delcolor, surface->format, &dcolor) || + !_get_color_from_object (replcolor, surface->format, &rcolor)) + return NULL; + + if (!_get_weights (weights, &wr, &wg, &wb)) + return NULL; + + surface = PySurface_AsSurface (array->surface); + pixels = surface->pixels; + absxstep = ABS (array->xstep); + absystep = ABS (array->ystep); + y = array->ystart; + + if (distance) + SDL_GetRGB (dcolor, surface->format, &r1, &g1, &b1); + + Py_BEGIN_ALLOW_THREADS; + switch (surface->format->BytesPerPixel) + { + case 1: + { + Uint8 *pixel; + while (posy < array->ylen) + { + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + pixel = ((Uint8 *) pixels + y * surface->pitch + x); + if (distance) + { + GET_PIXELVALS_1 (r2, g2, b2, a2, pixel, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = (Uint8) rcolor; + } + else if (*pixel == dcolor) + *pixel = (Uint8) rcolor; + x += array->xstep; + posx += absxstep; + } + y += array->ystep; + posy += absystep; + } + break; + } + case 2: + { + Uint16 *pixel; + while (posy < array->ylen) + { + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + pixel = ((Uint16 *) (pixels + y * surface->pitch) + x); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, (Uint32) *pixel, + surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = (Uint16) rcolor; + } + else if (*pixel == dcolor) + *pixel = (Uint16) rcolor; + x += array->xstep; + posx += absxstep; + } + y += array->ystep; + posy += absystep; + } + break; + } + case 3: + { + Uint8 *px; + Uint32 pxcolor; + SDL_PixelFormat *format = surface->format; + while (posy < array->ylen) + { + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + px = ((Uint8 *) (pixels + y * surface->pitch) + x * 3); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + pxcolor = (px[0]) + (px[1] << 8) + (px[2] << 16); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, pxcolor, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + { + *(px + (format->Rshift >> 3)) = (Uint8) (rcolor >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (rcolor >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) rcolor; + } + } + else if (pxcolor == dcolor) + { + *(px + (format->Rshift >> 3)) = (Uint8) (rcolor >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (rcolor >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) rcolor; + } +#else + pxcolor = (px[2]) + (px[1] << 8) + (px[0] << 16); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, pxcolor, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + { + *(px + 2 - (format->Rshift >> 3)) = + (Uint8) (rcolor >> 16); + *(px + 2 - (format->Gshift >> 3)) = + (Uint8) (rcolor >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) rcolor; + } + } + else if (pxcolor == dcolor) + { + *(px + 2 - (format->Rshift >> 3)) = (Uint8) (rcolor >> 16); + *(px + 2 - (format->Gshift >> 3)) = (Uint8) (rcolor >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) rcolor; + } +#endif + x += array->xstep; + posx += absxstep; + } + y += array->ystep; + posy += absystep; + } + break; + } + default: + { + Uint32 *pixel; + while (posy < array->ylen) + { + x = array->xstart; + posx = 0; + while (posx < array->xlen) + { + pixel = ((Uint32 *) (pixels + y * surface->pitch) + x); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, *pixel, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = rcolor; + } + else if (*pixel == dcolor) + *pixel = rcolor; + x += array->xstep; + posx += absxstep; + } + y += array->ystep; + posy += absystep; + } + break; + } + } + Py_END_ALLOW_THREADS; + Py_RETURN_NONE; +} + +static PyObject* +_extract_color (PyPixelArray *array, PyObject *args, PyObject *kwds) +{ + PyObject *weights = NULL; + PyObject *sf = NULL; + PyObject *excolor = NULL; + PyPixelArray *newarray = NULL; + Uint32 color; + Uint32 white; + Uint32 black; + SDL_Surface *surface; + float distance = 0; + float wr, wg, wb; + Uint8 r1, g1, b1, r2, g2, b2, a2; + + Uint32 x = 0; + Uint32 y = 0; + Uint32 posx = 0; + Uint32 posy = 0; + Sint32 absxstep; + Sint32 absystep; + Uint8 *pixels; + + static char *keys[] = { "color", "distance", "weights", NULL }; + + if (!PyArg_ParseTupleAndKeywords (args, kwds, "O|fO", keys, &excolor, + &distance, &weights)) + return NULL; + + if (distance < 0 || distance > 1) + return RAISE (PyExc_ValueError, + "distance must be in the range from 0.0 to 1.0"); + if (!_get_weights (weights, &wr, &wg, &wb)) + return NULL; + + surface = PySurface_AsSurface (array->surface); + if (!_get_color_from_object (excolor, surface->format, &color)) + return NULL; + + /* Create the b/w mask surface. */ + sf = _make_surface (array); + if (!sf) + return NULL; + newarray = (PyPixelArray *) PyPixelArray_New (sf); + if (!newarray) + { + Py_DECREF (sf); + return NULL; + } + surface = PySurface_AsSurface (newarray->surface); + + black = SDL_MapRGBA (surface->format, 0, 0, 0, 255); + white = SDL_MapRGBA (surface->format, 255, 255, 255, 255); + if (distance) + SDL_GetRGB (color, surface->format, &r1, &g1, &b1); + + pixels = surface->pixels; + absxstep = ABS (newarray->xstep); + absystep = ABS (newarray->ystep); + y = newarray->ystart; + + Py_BEGIN_ALLOW_THREADS; + switch (surface->format->BytesPerPixel) + { + case 1: + { + Uint8 *pixel; + while (posy < newarray->ylen) + { + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel = ((Uint8 *) pixels + y * surface->pitch + x); + if (distance) + { + GET_PIXELVALS_1 (r2, g2, b2, a2, pixel, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = (Uint8) white; + else + *pixel = (Uint8) black; + } + else + *pixel = (*pixel == color) ? (Uint8) white : (Uint8) black; + x += newarray->xstep; + posx += absxstep; + } + y += newarray->ystep; + posy += absystep; + } + break; + } + case 2: + { + Uint16 *pixel; + while (posy < newarray->ylen) + { + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel = ((Uint16 *) (pixels + y * surface->pitch) + x); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, (Uint32) *pixel, + surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = (Uint16) white; + else + *pixel = (Uint16) black; + } + else + *pixel = (*pixel == color) ? (Uint16) white : + (Uint16) black; + x += newarray->xstep; + posx += absxstep; + } + y += newarray->ystep; + posy += absystep; + } + break; + } + case 3: + { + Uint8 *px; + Uint32 pxcolor; + SDL_PixelFormat *format = surface->format; + while (posy < newarray->ylen) + { + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + px = ((Uint8 *) (pixels + y * surface->pitch) + x * 3); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + pxcolor = (px[0]) + (px[1] << 8) + (px[2] << 16); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, pxcolor, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + { + *(px + (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px + (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) black; + } + } + else if (pxcolor == color) + { + *(px + (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px + (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px + (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px + (format->Bshift >> 3)) = (Uint8) black; + } +#else + pxcolor = (px[2]) + (px[1] << 8) + (px[0] << 16); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, pxcolor, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + { + *(px + 2 - (format->Rshift >> 3)) = + (Uint8) (white >> 16); + *(px + 2 - (format->Gshift >> 3)) = + (Uint8) (white >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px + 2 - (format->Rshift >> 3)) = + (Uint8) (black >> 16); + *(px + 2 - (format->Gshift >> 3)) = + (Uint8) (black >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) black; + } + } + else if (pxcolor == color) + { + *(px + 2 - (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px + 2 - (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px + 2 - (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px + 2 - (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px + 2 - (format->Bshift >> 3)) = (Uint8) black; + } +#endif + x += newarray->xstep; + posx += absxstep; + } + y += newarray->ystep; + posy += absystep; + } + break; + } + default: + { + Uint32 *pixel; + while (posy < newarray->ylen) + { + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel = ((Uint32 *) (pixels + y * surface->pitch) + x); + if (distance) + { + GET_PIXELVALS (r2, g2, b2, a2, *pixel, surface->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) <= + distance) + *pixel = white; + else + *pixel = black; + } + else + *pixel = (*pixel == color) ? white : black; + x += newarray->xstep; + posx += absxstep; + } + y += newarray->ystep; + posy += absystep; + } + break; + } + } + Py_END_ALLOW_THREADS; + return (PyObject *) newarray; +} + +static PyObject* +_compare (PyPixelArray *array, PyObject *args, PyObject *kwds) +{ + PyPixelArray *array2 = NULL; + PyPixelArray *newarray = NULL; + PyObject *weights = NULL; + PyObject *sf = NULL; + SDL_Surface *surface1 = NULL; + SDL_Surface *surface2 = NULL; + Uint32 black; + Uint32 white; + float distance = 0; + Uint8 r1, g1, b1, a1, r2, g2, b2, a2; + float wr, wg, wb; + + Uint32 x = 0; + Uint32 y = 0; + Uint32 vx = 0; + Uint32 vy = 0; + Uint32 posx = 0; + Uint32 posy = 0; + Sint32 absxstep; + Sint32 absystep; + Uint8 *pixels1; + Uint8 *pixels2; + + static char *keys[] = { "array", "distance", "weights", NULL }; + + if (!PyArg_ParseTupleAndKeywords (args, kwds, "O|fO", keys, &newarray, + &distance, &weights)) + return NULL; + + if (!PyPixelArray_Check (newarray)) + return RAISE (PyExc_TypeError, "invalid array type"); + array2 = (PyPixelArray *) newarray; + newarray = NULL; + if (distance < 0 || distance > 1) + return RAISE (PyExc_ValueError, + "distance must be in the range from 0.0 to 1.0"); + if (!_get_weights (weights, &wr, &wg, &wb)) + return NULL; + + if (array->ylen / ABS (array->ystep) != array2->ylen / ABS (array2->ystep) + || array->xlen / ABS (array->xstep) != array2->xlen / ABS (array2->xstep)) + { + /* Bounds do not match. */ + PyErr_SetString (PyExc_ValueError, "array sizes do not match"); + return NULL; + } + + surface1 = PySurface_AsSurface (array->surface); + surface2 = PySurface_AsSurface (array2->surface); + if (surface2->format->BytesPerPixel != surface1->format->BytesPerPixel) + return RAISE (PyExc_ValueError, "bit depths do not match"); + + /* Create the b/w mask surface. */ + sf = _make_surface (array); + if (!sf) + return NULL; + newarray = (PyPixelArray *) PyPixelArray_New (sf); + if (!newarray) + { + Py_DECREF (sf); + return NULL; + } + surface1 = PySurface_AsSurface (newarray->surface); + + black = SDL_MapRGBA (surface1->format, 0, 0, 0, 255); + white = SDL_MapRGBA (surface1->format, 255, 255, 255, 255); + + pixels1 = surface1->pixels; + pixels2 = surface2->pixels; + absxstep = ABS (array2->xstep); + absystep = ABS (array2->ystep); + y = array2->ystart; + + Py_BEGIN_ALLOW_THREADS; + switch (surface1->format->BytesPerPixel) + { + case 1: + { + Uint8 *pixel1, *pixel2; + while (posy < newarray->ylen) + { + vx = array2->xstart; + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel1 = ((Uint8 *) pixels1 + y * surface1->pitch + x); + pixel2 = ((Uint8 *) pixels2 + vy * surface2->pitch + vx); + if (distance) + { + GET_PIXELVALS_1 (r1, g1, b1, a1, pixel1, surface1->format); + GET_PIXELVALS_1 (r2, g2, b2, a2, pixel2, surface2->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) > + distance) + *pixel1 = (Uint8) white; + else + *pixel1 = (Uint8) black; + } + else + *pixel1 = (*pixel1 == *pixel2) ? (Uint8) white : + (Uint8) black; + vx += array2->xstep; + x += newarray->xstep; + posx += absxstep; + } + vy += array2->ystep; + y += newarray->ystep; + posy += absystep; + } + break; + } + case 2: + { + Uint16 *pixel1, *pixel2; + while (posy < newarray->ylen) + { + vx = array2->xstart; + x = array->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel1 = ((Uint16 *) (pixels1 + y * surface1->pitch) + x); + pixel2 = ((Uint16 *) (pixels2 + vy * surface2->pitch) + vx); + if (distance) + { + GET_PIXELVALS (r1, g1, b1, a1, (Uint32) *pixel1, + surface1->format); + GET_PIXELVALS (r2, g2, b2, a2, (Uint32) *pixel2, + surface1->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) > + distance) + *pixel1 = (Uint16) white; + else + *pixel1 = (Uint16) black; + } + else + *pixel1 = (*pixel1 == *pixel2) ? (Uint16) white : + (Uint16) black; + vx += array2->xstep; + x += newarray->xstep; + posx += absxstep; + } + vy += array2->ystep; + y += newarray->ystep; + posy += absystep; + } + break; + } + case 3: + { + Uint8 *px1, *px2; + Uint32 pxcolor1, pxcolor2; + SDL_PixelFormat *format = surface1->format; + while (posy < newarray->ylen) + { + vx = array2->xstart; + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + px1 = ((Uint8 *) (pixels1 + y * surface1->pitch) + x * 3); + px2 = ((Uint8 *) (pixels2 + vy * surface2->pitch) + vx * 3); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + pxcolor1 = (px1[0]) + (px1[1] << 8) + (px1[2] << 16); + pxcolor2 = (px2[0]) + (px2[1] << 8) + (px2[2] << 16); + if (distance) + { + GET_PIXELVALS (r1, g1, b1, a1, pxcolor1, surface1->format); + GET_PIXELVALS (r2, g2, b2, a2, pxcolor2, surface2->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) > + distance) + { + *(px1 + (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px1 + (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px1 + (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px1 + (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px1 + (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px1 + (format->Bshift >> 3)) = (Uint8) black; + } + } + else if (pxcolor1 != pxcolor2) + { + *(px1 + (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px1 + (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px1 + (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px1 + (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px1 + (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px1 + (format->Bshift >> 3)) = (Uint8) black; + } +#else + pxcolor1 = (px1[2]) + (px1[1] << 8) + (px1[0] << 16); + pxcolor2 = (px2[2]) + (px2[1] << 8) + (px2[0] << 16); + if (distance) + { + GET_PIXELVALS (r1, g1, b1, a1, pxcolor1, surface1->format); + GET_PIXELVALS (r2, g2, b2, a2, pxcolor2, surface2->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) > + distance) + { + *(px1 + 2 - (format->Rshift >> 3)) = + (Uint8) (white >> 16); + *(px1 + 2 - (format->Gshift >> 3)) = + (Uint8) (white >> 8); + *(px1 + 2 - (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px1 + 2 - (format->Rshift >> 3)) = + (Uint8) (black >> 16); + *(px1 + 2 - (format->Gshift >> 3)) = + (Uint8) (black >> 8); + *(px1 + 2 - (format->Bshift >> 3)) = (Uint8) black; + } + } + else if (pxcolor1 != pxcolor2) + { + *(px1 + 2 - (format->Rshift >> 3)) = (Uint8) (white >> 16); + *(px1 + 2 - (format->Gshift >> 3)) = (Uint8) (white >> 8); + *(px1 + 2 - (format->Bshift >> 3)) = (Uint8) white; + } + else + { + *(px1 + 2 - (format->Rshift >> 3)) = (Uint8) (black >> 16); + *(px1 + 2 - (format->Gshift >> 3)) = (Uint8) (black >> 8); + *(px1 + 2 - (format->Bshift >> 3)) = (Uint8) black; + } +#endif + vx += array2->xstep; + x += newarray->xstep; + posx += absxstep; + } + vy += array2->ystep; + y += newarray->ystep; + posy += absystep; + } + break; + } + default: + { + Uint32 *pixel1, *pixel2; + while (posy < newarray->ylen) + { + vx = array2->xstart; + x = newarray->xstart; + posx = 0; + while (posx < newarray->xlen) + { + pixel1 = ((Uint32 *) (pixels1 + y * surface1->pitch) + x); + pixel2 = ((Uint32 *) (pixels2 + vy * surface2->pitch) + vx); + if (distance) + { + GET_PIXELVALS (r1, g1, b1, a1, *pixel1, surface1->format); + GET_PIXELVALS (r2, g2, b2, a2, *pixel2, surface2->format); + if (COLOR_DIFF_RGB (wr, wg, wb, r1, g1, b1, r2, g2, b2) > + distance) + *pixel1 = white; + else + *pixel1 = black; + } + else + *pixel1 = (*pixel1 == *pixel2) ? white : black; + vx += array2->xstep; + x += newarray->xstep; + posx += absxstep; + } + vy += array2->ystep; + y += newarray->ystep; + posy += absystep; + } + break; + } + } + Py_END_ALLOW_THREADS; + return (PyObject *) newarray; +} diff -Nru pygame-1.8.0release/src/pygamedocs.h pygame-1.8.1release/src/pygamedocs.h --- pygame-1.8.0release/src/pygamedocs.h 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/pygamedocs.h 2008-07-17 17:27:38.000000000 -0400 @@ -59,7 +59,7 @@ #define DOC_CDGETCURRENT "CD.get_current(): return track, seconds\nthe current audio playback position" -#define DOC_CDGETEMPTY "CD.get_empty(): return True\nFalse if a cdrom is in the drive" +#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" @@ -71,6 +71,28 @@ #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" @@ -289,21 +311,21 @@ #define DOC_PYGAMEMASK "pygame module for image masks." -#define DOC_PYGAMEMASKPYGAMEMASKFROMSURFACE "pygame.mask.from_surface(Surface, threshold = 127) -> Mask\nReturns a Mask from the given surface." +#define DOC_PYGAMEMASKFROMSURFACE "pygame.mask.from_surface(Surface, threshold = 127) -> Mask\nReturns a Mask from the given surface." -#define DOC_PYGAMEMASKPYGAMEMASK "pygame.Mask((width, height): return Mask\npygame object for representing 2d bitmasks" +#define DOC_PYGAMEMASKMASK "pygame.Mask((width, height): return Mask\npygame object for representing 2d bitmasks" -#define DOC_PYGAMEMASKGETSIZE "Mask.get_size() -> width,height\nReturns the size of the mask." +#define DOC_MASKGETSIZE "Mask.get_size() -> width,height\nReturns the size of the mask." -#define DOC_PYGAMEMASKGETAT "Mask.get_at((x,y)) -> int\nReturns nonzero if the bit at (x,y) is set." +#define DOC_MASKGETAT "Mask.get_at((x,y)) -> int\nReturns nonzero if the bit at (x,y) is set." -#define DOC_PYGAMEMASKSETAT "Mask.set_at((x,y),value)\nSets the position in the mask given by x and y." +#define DOC_MASKSETAT "Mask.set_at((x,y),value)\nSets the position in the mask given by x and y." -#define DOC_PYGAMEMASKOVERLAP "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_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_PYGAMEMASKOVERLAPAREA "Mask.overlap_area(othermask, offset) -> numpixels\nReturns the number of overlapping 'pixels'." +#define DOC_MASKOVERLAPAREA "Mask.overlap_area(othermask, offset) -> numpixels\nReturns the number of overlapping 'pixels'." -#define DOC_PYGAMEMASKGETBOUNDINGRECTS "Mask.get_bounding_rects() -> Rects\nReturns a list of bounding rects of regions of set 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" @@ -469,10 +491,18 @@ #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_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" @@ -489,8 +519,6 @@ #define DOC_RECTCLIP "Rect.clip(Rect): return Rect\ncrops a rectangle inside another" -#define DOC_RECTCLIPIP "Rect.clip_ip(Rect): return None\ncrops a rectangle inside another, in place" - #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" @@ -517,7 +545,7 @@ #define DOC_RECTCOLLIDEDICTALL "Rect.collidedictall(dict): return [(key, value), ...]\ntest if all rectangles in a dictionary intersect" -#define DOC_PYGAMESCRAP "" +#define DOC_PYGAMESCRAP "pygame module for clipboard support." #define DOC_PYGAMESCRAPINIT "scrap.init () -> None\nInitializes the scrap module." @@ -563,6 +591,10 @@ #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" @@ -589,14 +621,76 @@ #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): return Sprite_list\nfind Sprites in a Group that intersect another 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" @@ -625,6 +719,8 @@ #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" @@ -643,7 +739,7 @@ #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 are 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" @@ -673,8 +769,12 @@ #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" @@ -751,5 +851,5 @@ #define DOC_PYGAMETRANSFORMAVERAGESURFACES "pygame.transform.average_surfaces(Surfaces, DestSurface = None): return Surface\nfind the average surface from many surfaces." -#define DOC_PYGAMETRANSFORMTHRESHOLD "pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = True): return num_threshold_pixels\nfinds which, and how many pixels in a surface are within a threshold of a color." +#define DOC_PYGAMETRANSFORMTHRESHOLD "finds which, and how many pixels in a surface are within a threshold of a color." diff -Nru pygame-1.8.0release/src/pygame.h pygame-1.8.1release/src/pygame.h --- pygame-1.8.0release/src/pygame.h 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/pygame.h 2008-07-07 01:57:32.000000000 -0400 @@ -350,7 +350,8 @@ SDL_Surface* surf; struct SubSurface_Data* subsurface; /*ptr to subsurface data (if a * subsurface)*/ - PyObject* weakreflist; + PyObject *weakreflist; + PyObject *locklist; PyObject *dependency; } PySurfaceObject; #define PySurface_AsSurface(x) (((PySurfaceObject*)x)->surf) @@ -401,7 +402,7 @@ /* SURFLOCK */ /*auto import/init by surface*/ #define PYGAMEAPI_SURFLOCK_FIRSTSLOT \ (PYGAMEAPI_SURFACE_FIRSTSLOT + PYGAMEAPI_SURFACE_NUMSLOTS) -#define PYGAMEAPI_SURFLOCK_NUMSLOTS 5 +#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8 struct SubSurface_Data { PyObject* owner; @@ -409,23 +410,41 @@ 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 + 0]))(x) + PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 1]))(x) #define PySurface_Unprep(x) \ if(((PySurfaceObject*)x)->subsurface) \ (*(*(void(*)(PyObject*)) \ - PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 1]))(x) + PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 2]))(x) #define PySurface_Lock \ - (*(int(*)(PyObject*))PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 2]) -#define PySurface_Unlock \ (*(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*))PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 4]) + (*(PyObject*(*)(PyObject*,PyObject*)) \ + PyGAME_C_API[PYGAMEAPI_SURFLOCK_FIRSTSLOT + 7]) #endif @@ -501,6 +520,18 @@ #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 @@ -563,9 +594,42 @@ } #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_PIXELARRAY_FIRSTSLOT + PYGAMEAPI_PIXELARRAY_NUMSLOTS) + (PYGAMEAPI_COLOR_FIRSTSLOT + PYGAMEAPI_COLOR_NUMSLOTS) static void* PyGAME_C_API[PYGAMEAPI_TOTALSLOTS] = { NULL }; #endif diff -Nru pygame-1.8.0release/src/rect.doc pygame-1.8.1release/src/rect.doc --- pygame-1.8.0release/src/rect.doc 2006-11-03 21:13:48.000000000 -0500 +++ pygame-1.8.1release/src/rect.doc 2008-07-07 01:57:32.000000000 -0400 @@ -124,16 +124,6 @@ - -clip_ip -crops a rectangle inside another, in place -Rect.clip_ip(Rect): return None - -Same as the Rect.clip() method, but operates in place. - - - - union joins two rectangles into one Rect.union(Rect): return Rect diff -Nru pygame-1.8.0release/src/rwobject.c pygame-1.8.1release/src/rwobject.c --- pygame-1.8.0release/src/rwobject.c 2007-07-03 18:36:05.000000000 -0400 +++ pygame-1.8.1release/src/rwobject.c 2008-07-22 07:32:57.000000000 -0400 @@ -269,10 +269,6 @@ if (!obj) return (SDL_RWops*) RAISE (PyExc_TypeError, "Invalid filetype object"); - rw = get_standard_rwop (obj); - if (rw) - return rw; - #ifndef WITH_THREAD return (SDL_RWops*) RAISE (PyExc_NotImplementedError, "Python built without thread support"); @@ -321,21 +317,30 @@ PyEval_AcquireLock (); oldstate = PyThreadState_Swap (helper->thread); - if (!(offset == 0 && whence == SEEK_CUR)) /*being called only for 'tell'*/ + if (!(offset == 0 && whence == SEEK_CUR)) /* being seek'd, not just tell'd */ { result = PyObject_CallFunction (helper->seek, "ii", offset, whence); if(!result) - return -1; + { + PyErr_Print(); + retval = -1; + goto end; + } Py_DECREF (result); } result = PyObject_CallFunction (helper->tell, NULL); if (!result) - return -1; + { + PyErr_Print(); + retval = -1; + goto end; + } retval = PyInt_AsLong (result); Py_DECREF (result); +end: PyThreadState_Swap (oldstate); PyEval_ReleaseLock (); @@ -358,12 +363,18 @@ result = PyObject_CallFunction (helper->read, "i", size * maxnum); if (!result) - return -1; + { + PyErr_Print(); + retval = -1; + goto end; + } if (!PyString_Check (result)) { Py_DECREF (result); - return -1; + PyErr_Print(); + retval = -1; + goto end; } retval = PyString_GET_SIZE (result); @@ -372,6 +383,7 @@ Py_DECREF (result); +end: PyThreadState_Swap (oldstate); PyEval_ReleaseLock (); @@ -383,6 +395,7 @@ { RWHelper* helper = (RWHelper*) context->hidden.unknown.data1; PyObject* result; + int retval; PyThreadState* oldstate; if (!helper->write) @@ -393,14 +406,20 @@ result = PyObject_CallFunction (helper->write, "s#", ptr, size * num); if (!result) - return -1; + { + PyErr_Print(); + retval = -1; + goto end; + } Py_DECREF (result); + retval = num; +end: PyThreadState_Swap (oldstate); PyEval_ReleaseLock (); - return num; + return retval; } static int @@ -417,8 +436,11 @@ if (helper->close) { result = PyObject_CallFunction (helper->close, NULL); - if (result) + if (!result) + { + PyErr_Print(); retval = -1; + } Py_XDECREF (result); } diff -Nru pygame-1.8.0release/src/scrap.c pygame-1.8.1release/src/scrap.c --- pygame-1.8.0release/src/scrap.c 2008-01-19 21:26:20.000000000 -0500 +++ pygame-1.8.1release/src/scrap.c 2008-07-07 01:57:33.000000000 -0400 @@ -96,9 +96,14 @@ _clipdata = PyDict_New (); _selectiondata = PyDict_New (); + /* In case we've got not video surface, we won't initialize + * anything. + */ + if (!SDL_GetVideoSurface()) + return RAISE (PyExc_SDLError, "No display mode is set"); if (!pygame_scrap_init ()) return RAISE (PyExc_SDLError, SDL_GetError ()); - + Py_RETURN_NONE; } #endif diff -Nru pygame-1.8.0release/src/scrap.doc pygame-1.8.1release/src/scrap.doc --- pygame-1.8.0release/src/scrap.doc 2008-03-28 17:45:42.000000000 -0400 +++ pygame-1.8.1release/src/scrap.doc 2008-07-07 01:57:33.000000000 -0400 @@ -1,4 +1,5 @@ pygame.scrap +pygame module for clipboard support. The scrap module is for getting and putting stuff from the clipboard. So you can copy and paste things between pygame, and other application @@ -51,7 +52,9 @@ EXPERIMENTAL! -New in pygame 1.8. Only works for Windows, X11 and Mac OS X so far. On Mac OSX only text works at the moment - other types will be supported in the next release. +New in pygame 1.8. Only works for Windows, X11 and Mac OS X so far. On +Mac OSX only text works at the moment - other types will be supported in +the next release.
        init @@ -59,7 +62,8 @@ scrap.init () -> None Tries to initialize the scrap module and raises an exception, if it -fails. +fails. Note that this module requires a set display surface, so you have +to make sure, you acquired one earlier using pygame.display.set_mode(). get diff -Nru pygame-1.8.0release/src/scrap_x11.c pygame-1.8.1release/src/scrap_x11.c --- pygame-1.8.0release/src/scrap_x11.c 2007-06-26 19:13:00.000000000 -0400 +++ pygame-1.8.1release/src/scrap_x11.c 2008-07-07 01:57:32.000000000 -0400 @@ -525,7 +525,7 @@ { unsigned long boffset = 0; chunk = MAX_CHUNK_SIZE(SDL_Display); - memset (retval, 0, *length + 1); + memset (retval, 0, (size_t) (*length + 1)); /* Read as long as there is data. */ while (overflow) @@ -821,7 +821,7 @@ if (!types) return NULL; - memset (types, 0, (PyDict_Size (dict) + 1)); + memset (types, 0, (size_t) (PyDict_Size (dict) + 1)); while (PyDict_Next (dict, &pos, &key, NULL)) { types[i] = strdup (PyString_AsString (key)); diff -Nru pygame-1.8.0release/src/surface.c pygame-1.8.1release/src/surface.c --- pygame-1.8.0release/src/surface.c 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/src/surface.c 2008-07-17 17:27:38.000000000 -0400 @@ -49,6 +49,7 @@ static PyObject *surf_unlock (PyObject *self); static PyObject *surf_mustlock (PyObject *self); static PyObject *surf_get_locked (PyObject *self); +static PyObject *surf_get_locks (PyObject *self); static PyObject *surf_get_palette (PyObject *self); static PyObject *surf_get_palette_at (PyObject *self, PyObject *args); static PyObject *surf_set_palette (PyObject *self, PyObject *args); @@ -75,9 +76,11 @@ PyObject *kwargs); static PyObject *surf_get_width (PyObject *self); static PyObject *surf_get_shifts (PyObject *self); +static PyObject *surf_set_shifts (PyObject *self, PyObject *args); static PyObject *surf_get_size (PyObject *self); static PyObject *surf_get_losses (PyObject *self); static PyObject *surf_get_masks (PyObject *self); +static PyObject *surf_set_masks (PyObject *self, PyObject *args); static PyObject *surf_get_offset (PyObject *self); static PyObject *surf_get_parent (PyObject *self); static PyObject *surf_subsurface (PyObject *self, PyObject *args); @@ -106,6 +109,8 @@ DOC_SURFACEMUSTLOCK }, { "get_locked", (PyCFunction) surf_get_locked, METH_NOARGS, DOC_SURFACEGETLOCKED }, + { "get_locks", (PyCFunction) surf_get_locks, METH_NOARGS, + DOC_SURFACEGETLOCKS }, { "set_colorkey", surf_set_colorkey, METH_VARARGS, DOC_SURFACESETCOLORKEY }, { "get_colorkey", (PyCFunction) surf_get_colorkey, METH_NOARGS, @@ -147,6 +152,11 @@ DOC_SURFACEGETMASKS }, { "get_shifts", (PyCFunction) surf_get_shifts, METH_NOARGS, DOC_SURFACEGETSHIFTS }, + { "set_masks", (PyCFunction) surf_set_masks, METH_VARARGS, + DOC_SURFACESETMASKS }, + { "set_shifts", (PyCFunction) surf_set_shifts, METH_VARARGS, + DOC_SURFACESETSHIFTS }, + { "get_losses", (PyCFunction) surf_get_losses, METH_NOARGS, DOC_SURFACEGETLOSSES }, @@ -239,6 +249,8 @@ self->surf = NULL; self->subsurface = NULL; self->weakreflist = NULL; + self->dependency = NULL; + self->locklist = NULL; } return (PyObject *) self; } @@ -269,6 +281,12 @@ Py_DECREF (self->dependency); self->dependency = NULL; } + + if (self->locklist) + { + Py_DECREF (self->locklist); + self->locklist = NULL; + } } static void @@ -561,7 +579,7 @@ int x, y; Uint32 color; Uint8 rgba[4] = {0, 0, 0, 0 }; - PyObject *rgba_obj; + PyObject *rgba_obj, *intobj; Uint8 *byte_buf; if (!PyArg_ParseTuple (args, "(ii)O", &x, &y, &rgba_obj)) @@ -583,8 +601,18 @@ } if (PyInt_Check (rgba_obj)) + { color = (Uint32) PyInt_AsLong (rgba_obj); - else if (RGBAFromObj (rgba_obj, rgba)) + if (PyErr_Occurred () && (Sint32) color == -1) + return RAISE (PyExc_TypeError, "invalid color argument"); + } + else if (PyLong_Check (rgba_obj)) + { + color = (Uint32) PyLong_AsUnsignedLong (rgba_obj); + if (PyErr_Occurred () && (Sint32) color == -1) + return RAISE (PyExc_TypeError, "invalid color argument"); + } + else if (RGBAFromColorObj (rgba_obj, rgba)) color = SDL_MapRGBA (surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE (PyExc_TypeError, "invalid color argument"); @@ -630,7 +658,7 @@ Uint8 rgba[4]; int color; - if (!RGBAFromObj (args, rgba)) + if (!RGBAFromColorObj (args, rgba)) return RAISE (PyExc_TypeError, "Invalid RGBA argument"); if (!surf) return RAISE (PyExc_SDLError, "display Surface quit"); @@ -667,8 +695,7 @@ static PyObject* surf_unlock (PyObject *self) { - if (!PySurface_Unlock (self)) - return NULL; + PySurface_Unlock (self); Py_RETURN_NONE; } @@ -677,19 +704,43 @@ { SDL_Surface *surf = PySurface_AsSurface (self); return PyInt_FromLong (SDL_MUSTLOCK (surf) || - ((PySurfaceObject *) self)->subsurface); + ((PySurfaceObject *) self)->subsurface); } static PyObject* surf_get_locked (PyObject *self) { PySurfaceObject *surf = (PySurfaceObject *) self; - if (surf->surf->pixels != NULL) + + if (surf->locklist && PyList_Size (surf->locklist) > 0) Py_RETURN_TRUE; Py_RETURN_FALSE; } static PyObject* +surf_get_locks (PyObject *self) +{ + PySurfaceObject *surf = (PySurfaceObject *) self; + Py_ssize_t len, i = 0; + PyObject *tuple, *tmp; + if (!surf->locklist) + return PyTuple_New (0); + + len = PyList_Size (surf->locklist); + tuple = PyTuple_New (len); + if (!tuple) + return NULL; + + for (i = 0; i < len; i++) + { + tmp = PyWeakref_GetObject (PyList_GetItem (surf->locklist, i)); + Py_INCREF (tmp); + PyTuple_SetItem (tuple, i, tmp); + } + return tuple; +} + +static PyObject* surf_get_palette (PyObject *self) { SDL_Surface *surf = PySurface_AsSurface (self); @@ -850,7 +901,7 @@ { SDL_Surface *surf = PySurface_AsSurface (self); Uint32 flags = 0, color = 0; - PyObject *rgba_obj = NULL, *intobj = NULL; + PyObject *rgba_obj = NULL; Uint8 rgba[4]; int result, hascolor = 0; @@ -864,14 +915,23 @@ if (rgba_obj && rgba_obj != Py_None) { - if (PyNumber_Check (rgba_obj) && (intobj = PyNumber_Int (rgba_obj))) + if (PyInt_Check (rgba_obj)) + { + color = (Uint32) PyInt_AsLong (rgba_obj); + if (PyErr_Occurred () && (Sint32) color == -1) + return RAISE (PyExc_TypeError, "invalid color argument"); + } + else if (PyLong_Check (rgba_obj)) { - color = (Uint32) PyInt_AsLong (intobj); - Py_DECREF (intobj); + color = (Uint32) PyLong_AsUnsignedLong (rgba_obj); + if (PyErr_Occurred () && (Sint32) color == -1) + return RAISE (PyExc_TypeError, "invalid color argument"); } - else if (RGBAFromObj (rgba_obj, rgba)) + else if (RGBAFromColorObj (rgba_obj, rgba)) + { color = SDL_MapRGBA (surf->format, rgba[0], rgba[1], rgba[2], - rgba[3]); + rgba[3]); + } else return RAISE (PyExc_TypeError, "invalid color argument"); hascolor = 1; @@ -929,8 +989,13 @@ { if (PyNumber_Check (alpha_obj) && (intobj = PyNumber_Int (alpha_obj))) { - alphaval = (int)PyInt_AsLong (intobj); - Py_DECREF (intobj); + if (PyInt_Check (intobj)) + { + alphaval = (int) PyInt_AsLong (intobj); + Py_DECREF (intobj); + } + else + return RAISE (PyExc_TypeError, "invalid alpha argument"); } else return RAISE (PyExc_TypeError, "invalid alpha argument"); @@ -1261,7 +1326,9 @@ if (PyInt_Check (rgba_obj)) color = (Uint32) PyInt_AsLong (rgba_obj); - else if (RGBAFromObj (rgba_obj, rgba)) + else if (PyLong_Check (rgba_obj)) + color = (Uint32) PyLong_AsUnsignedLong (rgba_obj); + else if (RGBAFromColorObj (rgba_obj, rgba)) color = SDL_MapRGBA (surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); else return RAISE (PyExc_TypeError, "invalid color argument"); @@ -1494,6 +1561,30 @@ surf->format->Bmask, surf->format->Amask); } + +static PyObject* +surf_set_masks (PyObject *self, PyObject *args) +{ + SDL_Surface *surf = PySurface_AsSurface (self); + Uint32 r, g, b, a; + + if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a)) + return NULL; + if (!surf) + return RAISE (PyExc_SDLError, "display Surface quit"); + + surf->format->Rmask = r; + surf->format->Gmask = g; + surf->format->Bmask = b; + surf->format->Amask = a; + + Py_RETURN_NONE; +} + + + + + static PyObject* surf_get_shifts (PyObject *self) { @@ -1505,6 +1596,32 @@ surf->format->Bshift, surf->format->Ashift); } + +static PyObject* +surf_set_shifts (PyObject *self, PyObject *args) +{ + SDL_Surface *surf = PySurface_AsSurface (self); + Uint32 r, g, b, a; + + if (!PyArg_ParseTuple (args, "(kkkk)", &r, &g, &b, &a)) + return NULL; + if (!surf) + return RAISE (PyExc_SDLError, "display Surface quit"); + + surf->format->Rshift = r; + surf->format->Gshift = g; + surf->format->Bshift = b; + surf->format->Ashift = a; + + Py_RETURN_NONE; +} + + + + + + + static PyObject* surf_get_losses (PyObject *self) { @@ -1787,7 +1904,8 @@ return rect; } -static PyObject *surf_get_buffer (PyObject *self) +static PyObject +*surf_get_buffer (PyObject *self) { PyObject *buffer; PyObject *lock; @@ -1796,23 +1914,26 @@ Py_ssize_t length; length = (Py_ssize_t) surface->pitch * surface->h; - lock = PySurface_LockLifetime (self); - if (!lock) - { - return RAISE (PyExc_SDLError, "could not lock surface"); - } - buffer = PyBufferProxy_New (self, surface->pixels, length, lock); + buffer = PyBufferProxy_New (self, NULL, length, NULL); if (!buffer) { - Py_DECREF (lock); return RAISE (PyExc_SDLError, - "could not acquire a buffer for the surface"); + "could not acquire a buffer for the surface"); + } + + lock = PySurface_LockLifetime (self, buffer); + if (!lock) + { + Py_DECREF (buffer); + return RAISE (PyExc_SDLError, "could not lock surface"); } + ((PyBufferProxy *) buffer)->buffer = surface->pixels; + ((PyBufferProxy *) buffer)->lock = lock; + return buffer; } - /*this internal blit function is accessable through the C api*/ int PySurface_Blit (PyObject * dstobj, PyObject * srcobj, SDL_Rect * dstrect, @@ -1878,7 +1999,7 @@ /* special case, SDL works */ (dst->format->BytesPerPixel == 2 || dst->format->BytesPerPixel == 4)) { - result = pygame_AlphaBlit (src, srcrect, dst, dstrect); + result = pygame_AlphaBlit (src, srcrect, dst, dstrect, the_args); } else if (the_args != 0) { @@ -1944,6 +2065,7 @@ /* imported needed apis */ import_pygame_base (); + import_pygame_color (); import_pygame_rect (); import_pygame_bufferproxy(); diff -Nru pygame-1.8.0release/src/surface.doc pygame-1.8.1release/src/surface.doc --- pygame-1.8.0release/src/surface.doc 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/src/surface.doc 2008-07-17 17:27:38.000000000 -0400 @@ -91,7 +91,11 @@ portion of the source Surface to draw. An optional special flags is for passing in +new in 1.8.0: BLEND_ADD, BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX +new in 1.8.1: +BLEND_RGBA_ADD, BLEND_RGBA_SUB, BLEND_RGBA_MULT, BLEND_RGBA_MIN, BLEND_RGBA_MAX +BLEND_RGB_ADD, BLEND_RGB_SUB, BLEND_RGB_MULT, BLEND_RGB_MIN, BLEND_RGB_MAX With other special blitting flags perhaps added in the future. The return rectangle is the area of the affected pixels, excluding any pixels @@ -136,7 +140,7 @@ Creates a new copy of the surface with the desired pixel format. The new surface will be in a format suited for quick blitting to the given format with per pixel alpha. If no surface is given, the new surface will be -optimized for blittint to the current display. +optimized for blitting to the current display. Unlike the Surface.convert() method, the pixel format for the new image will not be exactly the same as the requested source, but it will be optimized for @@ -168,7 +172,11 @@ unless the surface uses per pixel alpha (Surface has the SRCALPHA flag). An optional special_flags is for passing in +new in 1.8.0: BLEND_ADD, BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX +new in 1.8.1: +BLEND_RGBA_ADD, BLEND_RGBA_SUB, BLEND_RGBA_MULT, BLEND_RGBA_MIN, BLEND_RGBA_MAX +BLEND_RGB_ADD, BLEND_RGB_SUB, BLEND_RGB_MULT, BLEND_RGB_MIN, BLEND_RGB_MAX With other special blitting flags perhaps added in the future. This will return the affected Surface area. @@ -306,8 +314,15 @@ Surface.get_locked(): return bool Returns True when the Surface is locked. It doesn't matter how many times -the Surface is locked. Surfaces that do not need locking (see -mustlock()) will always return True. +the Surface is locked. + + + +get_locks +Gets the locks for the Surface +Surface.get_locks(): return tuple + +Returns the currently existing locks for the Surface. @@ -433,7 +448,7 @@ get_clip -get the current clipping are of the Surface +get the current clipping area of the Surface Surface.get_clip(): return Rect Return a rectangle of the current clipping area. The Surface will always @@ -626,6 +641,16 @@ +set_masks +set the bitmasks needed to convert between a color and a mapped integer +Surface.set_masks((r,g,b,a)): return None + +This is not needed for normal Pygame usage. +New in pygame 1.8.1 + + + + get_shifts the bit shifts needed to convert between a color and a mapped integer Surface.get_shifts(): return (R, G, B, A) @@ -638,6 +663,15 @@ +set_shifts +sets the bit shifts needed to convert between a color and a mapped integer +Surface.get_shifts((r,g,b,a)): return None + +This is not needed for normal Pygame usage. +New in pygame 1.8.1 + + + get_losses the significant bits used to convert between a color and a mapped integer Surface.get_losses(): return (R, G, B, A) diff -Nru pygame-1.8.0release/src/surface_fill.c pygame-1.8.1release/src/surface_fill.c --- pygame-1.8.0release/src/surface_fill.c 2007-05-29 19:43:01.000000000 -0400 +++ pygame-1.8.1release/src/surface_fill.c 2008-07-07 01:57:33.000000000 -0400 @@ -19,6 +19,360 @@ #include "surface.h" + + +static int +surface_fill_blend_rgba_add (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) +{ + Uint8 *pixels; + int width = rect->w; + int height = rect->h; + int skip; + int bpp; + int n; + SDL_PixelFormat *fmt; + Uint8 sR, sG, sB, sA, cR, cG, cB, cA; + Uint32 pixel; + Uint32 tmp; + int result = -1; + + bpp = surface->format->BytesPerPixel; + fmt = surface->format; + pixels = (Uint8 *) surface->pixels + surface->offset + + (Uint16) rect->y * surface->pitch + (Uint16) rect->x * bpp; + skip = surface->pitch - width * bpp; + + switch (bpp) + { + case 1: + { + SDL_GetRGBA (color, fmt, &cR, &cG, &cB, &cA); + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); + BLEND_RGBA_ADD (tmp, cR, cG, cB, cA, sR, sG, sB, sA); + *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + default: + { + GET_PIXELVALS (cR, cG, cB, cA, color, fmt); + /* + printf ("Color: %d, %d, %d, %d, BPP is: %d\n", cR, cG, cB, cA, bpp); + */ + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL (pixel, bpp, pixels); + GET_PIXELVALS (sR, sG, sB, sA, pixel, fmt); + BLEND_RGBA_ADD (tmp, cR, cG, cB, cA, sR, sG, sB, sA); + CREATE_PIXEL(pixels, sR, sG, sB, sA, bpp, fmt); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + } + return result; +} + +static int +surface_fill_blend_rgba_sub (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) +{ + Uint8 *pixels; + int width = rect->w; + int height = rect->h; + int skip; + int bpp; + int n; + SDL_PixelFormat *fmt; + Uint8 sR, sG, sB, sA, cR, cG, cB, cA; + Uint32 pixel; + Uint32 tmp; + int result = -1; + + bpp = surface->format->BytesPerPixel; + fmt = surface->format; + pixels = (Uint8 *) surface->pixels + surface->offset + + (Uint16) rect->y * surface->pitch + (Uint16) rect->x * bpp; + skip = surface->pitch - width * bpp; + + switch (bpp) + { + case 1: + { + SDL_GetRGBA (color, fmt, &cR, &cG, &cB, &cA); + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); + BLEND_RGBA_SUB (tmp, cR, cG, cB, cA, sR, sG, sB, sA); + *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + default: + { + GET_PIXELVALS (cR, cG, cB, cA, color, fmt); + /* + printf ("Color: %d, %d, %d, %d, BPP is: %d\n", cR, cG, cB, cA, bpp); + */ + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL (pixel, bpp, pixels); + GET_PIXELVALS (sR, sG, sB, sA, pixel, fmt); + BLEND_RGBA_SUB (tmp, cR, cG, cB, cA, sR, sG, sB, sA); + CREATE_PIXEL(pixels, sR, sG, sB, sA, bpp, fmt); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + } + return result; +} + +static int +surface_fill_blend_rgba_mult (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) +{ + Uint8 *pixels; + int width = rect->w; + int height = rect->h; + int skip; + int bpp; + int n; + SDL_PixelFormat *fmt; + Uint8 sR, sG, sB, sA, cR, cG, cB, cA; + Uint32 pixel; + int result = -1; + + bpp = surface->format->BytesPerPixel; + fmt = surface->format; + pixels = (Uint8 *) surface->pixels + surface->offset + + (Uint16) rect->y * surface->pitch + (Uint16) rect->x * bpp; + skip = surface->pitch - width * bpp; + + switch (bpp) + { + case 1: + { + SDL_GetRGBA (color, fmt, &cR, &cG, &cB, &cA); + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); + BLEND_RGBA_MULT (cR, cG, cB, cA, sR, sG, sB, sA); + *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + default: + { + GET_PIXELVALS (cR, cG, cB, cA, color, fmt); + /* + printf ("Color: %d, %d, %d, %d, BPP is: %d\n", cR, cG, cB, cA, bpp); + */ + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL (pixel, bpp, pixels); + GET_PIXELVALS (sR, sG, sB, sA, pixel, fmt); + BLEND_RGBA_MULT (cR, cG, cB, cA, sR, sG, sB, sA); + CREATE_PIXEL(pixels, sR, sG, sB, sA, bpp, fmt); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + } + return result; +} + +static int +surface_fill_blend_rgba_min (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) +{ + Uint8 *pixels; + int width = rect->w; + int height = rect->h; + int skip; + int bpp; + int n; + SDL_PixelFormat *fmt; + Uint8 sR, sG, sB, sA, cR, cG, cB, cA; + Uint32 pixel; + int result = -1; + + bpp = surface->format->BytesPerPixel; + fmt = surface->format; + pixels = (Uint8 *) surface->pixels + surface->offset + + (Uint16) rect->y * surface->pitch + (Uint16) rect->x * bpp; + skip = surface->pitch - width * bpp; + + switch (bpp) + { + case 1: + { + SDL_GetRGBA (color, fmt, &cR, &cG, &cB, &cA); + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); + BLEND_RGBA_MIN (cR, cG, cB, cA, sR, sG, sB, sA); + *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + default: + { + GET_PIXELVALS (cR, cG, cB, cA, color, fmt); + /* + printf ("Color: %d, %d, %d, %d, BPP is: %d\n", cR, cG, cB, cA, bpp); + */ + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL (pixel, bpp, pixels); + GET_PIXELVALS (sR, sG, sB, sA, pixel, fmt); + BLEND_RGBA_MIN (cR, cG, cB, cA, sR, sG, sB, sA); + CREATE_PIXEL(pixels, sR, sG, sB, sA, bpp, fmt); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + } + return result; +} + +static int +surface_fill_blend_rgba_max (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) +{ + Uint8 *pixels; + int width = rect->w; + int height = rect->h; + int skip; + int bpp; + int n; + SDL_PixelFormat *fmt; + Uint8 sR, sG, sB, sA, cR, cG, cB, cA; + Uint32 pixel; + int result = -1; + + bpp = surface->format->BytesPerPixel; + fmt = surface->format; + pixels = (Uint8 *) surface->pixels + surface->offset + + (Uint16) rect->y * surface->pitch + (Uint16) rect->x * bpp; + skip = surface->pitch - width * bpp; + + switch (bpp) + { + case 1: + { + SDL_GetRGBA (color, fmt, &cR, &cG, &cB, &cA); + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); + BLEND_RGBA_MAX (cR, cG, cB, cA, sR, sG, sB, sA); + *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + default: + { + GET_PIXELVALS (cR, cG, cB, cA, color, fmt); + /* + printf ("Color: %d, %d, %d, %d, BPP is: %d\n", cR, cG, cB, cA, bpp); + */ + while (height--) + { + LOOP_UNROLLED4( + { + GET_PIXEL (pixel, bpp, pixels); + GET_PIXELVALS (sR, sG, sB, sA, pixel, fmt); + BLEND_RGBA_MAX (cR, cG, cB, cA, sR, sG, sB, sA); + CREATE_PIXEL(pixels, sR, sG, sB, sA, bpp, fmt); + pixels += bpp; + }, n, width); + pixels += skip; + } + result = 0; + break; + } + } + return result; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +// ------------------------- + + + static int surface_fill_blend_add (SDL_Surface *surface, SDL_Rect *rect, Uint32 color) { @@ -49,7 +403,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1 (sR, sG, sB, sA, pixel, pixels, fmt); + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); BLEND_ADD (tmp, cR, cG, cB, cA, sR, sG, sB, sA); *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); pixels += bpp; @@ -114,7 +468,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1 (sR, sG, sB, sA, pixel, pixels, fmt); + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); BLEND_SUB (tmp, cR, cG, cB, cA, sR, sG, sB, sA); *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); pixels += bpp; @@ -161,7 +515,6 @@ SDL_PixelFormat *fmt; Uint8 sR, sG, sB, sA, cR, cG, cB, cA; Uint32 pixel; - Uint32 tmp; int result = -1; bpp = surface->format->BytesPerPixel; @@ -179,7 +532,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1 (sR, sG, sB, sA, pixel, pixels, fmt); + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); BLEND_MULT (cR, cG, cB, cA, sR, sG, sB, sA); *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); pixels += bpp; @@ -226,7 +579,6 @@ SDL_PixelFormat *fmt; Uint8 sR, sG, sB, sA, cR, cG, cB, cA; Uint32 pixel; - Uint32 tmp; int result = -1; bpp = surface->format->BytesPerPixel; @@ -244,7 +596,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1 (sR, sG, sB, sA, pixel, pixels, fmt); + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); BLEND_MIN (cR, cG, cB, cA, sR, sG, sB, sA); *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); pixels += bpp; @@ -291,7 +643,6 @@ SDL_PixelFormat *fmt; Uint8 sR, sG, sB, sA, cR, cG, cB, cA; Uint32 pixel; - Uint32 tmp; int result = -1; bpp = surface->format->BytesPerPixel; @@ -309,7 +660,7 @@ { LOOP_UNROLLED4( { - GET_PIXELVALS_1 (sR, sG, sB, sA, pixel, pixels, fmt); + GET_PIXELVALS_1 (sR, sG, sB, sA, pixels, fmt); BLEND_MAX (cR, cG, cB, cA, sR, sG, sB, sA); *pixels = SDL_MapRGBA (fmt, sR, sG, sB, sA); pixels += bpp; @@ -386,6 +737,38 @@ result = surface_fill_blend_max (surface, rect, color); break; } + + + + case PYGAME_BLEND_RGBA_ADD: + { + result = surface_fill_blend_rgba_add (surface, rect, color); + break; + } + case PYGAME_BLEND_RGBA_SUB: + { + result = surface_fill_blend_rgba_sub (surface, rect, color); + break; + } + case PYGAME_BLEND_RGBA_MULT: + { + result = surface_fill_blend_rgba_mult (surface, rect, color); + break; + } + case PYGAME_BLEND_RGBA_MIN: + { + result = surface_fill_blend_rgba_min (surface, rect, color); + break; + } + case PYGAME_BLEND_RGBA_MAX: + { + result = surface_fill_blend_rgba_max (surface, rect, color); + break; + } + + + + default: { result = -1; diff -Nru pygame-1.8.0release/src/surface.h pygame-1.8.1release/src/surface.h --- pygame-1.8.0release/src/surface.h 2007-05-29 17:40:35.000000000 -0400 +++ pygame-1.8.1release/src/surface.h 2008-07-07 01:57:33.000000000 -0400 @@ -33,6 +33,22 @@ #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) \ { \ @@ -52,19 +68,35 @@ break; \ } -#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt) \ - _sR = ((px & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; \ - _sG = ((px & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; \ - _sB = ((px & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; \ - _sA = ((px & fmt->Amask) >> fmt->Ashift) << fmt->Aloss; - -#define GET_PIXELVALS_1(sr, sg, sb, sa, p, _src, _fmt) \ - p = *((Uint8 *) (_src)); \ - sr = _fmt->palette->colors[p].r; \ - sg = _fmt->palette->colors[p].g; \ - sb = _fmt->palette->colors[p].b; \ +#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) \ { \ @@ -102,10 +134,17 @@ code; \ code; -#define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ +#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); + 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); \ @@ -127,6 +166,51 @@ 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 #define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \ do { \ @@ -171,7 +255,7 @@ int pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); + SDL_Surface * dst, SDL_Rect * dstrect, int the_args); int pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect, diff -Nru pygame-1.8.0release/src/surflock.c pygame-1.8.1release/src/surflock.c --- pygame-1.8.0release/src/surflock.c 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/src/surflock.c 2008-07-07 01:57:32.000000000 -0400 @@ -1,6 +1,7 @@ /* pygame - Python Game Library Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2008 Marcus von Appen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -28,6 +29,10 @@ static int PySurface_Lock (PyObject* surfobj); static int PySurface_Unlock (PyObject* surfobj); +static int PySurface_LockBy (PyObject* surfobj, PyObject* lockobj); +static int PySurface_UnlockBy (PyObject* surfobj, PyObject* lockobj); + +static void _lifelock_dealloc (PyObject* self); static void PySurface_Prep (PyObject* surfobj) @@ -37,7 +42,7 @@ { SDL_Surface* surf = PySurface_AsSurface (surfobj); SDL_Surface* owner = PySurface_AsSurface (data->owner); - PySurface_Lock (data->owner); + PySurface_LockBy (data->owner, surfobj); surf->pixels = ((char*) owner->pixels) + data->pixeloffset; } } @@ -47,13 +52,43 @@ { struct SubSurface_Data* data = ((PySurfaceObject*) surfobj)->subsurface; if (data) - PySurface_Unlock (data->owner); + PySurface_UnlockBy (data->owner, surfobj); } static int PySurface_Lock (PyObject* surfobj) { + return PySurface_LockBy (surfobj, surfobj); +} + +static int +PySurface_Unlock (PyObject* surfobj) +{ + return PySurface_UnlockBy (surfobj, surfobj); +} + +static int +PySurface_LockBy (PyObject* surfobj, PyObject* lockobj) +{ + PyObject *ref; PySurfaceObject* surf = (PySurfaceObject*) surfobj; + + if (!surf->locklist) + { + surf->locklist = PyList_New (0); + if (!surf->locklist) + return 0; + } + ref = PyWeakref_NewRef (lockobj, NULL); + if (!ref) + return 0; + if (ref == Py_None) + { + Py_DECREF (ref); + return 0; + } + PyList_Append (surf->locklist, ref); + if (surf->subsurface) PySurface_Prep (surfobj); if (SDL_LockSurface (surf->surf) == -1) @@ -65,59 +100,143 @@ } static int -PySurface_Unlock (PyObject* surfobj) +PySurface_UnlockBy (PyObject* surfobj, PyObject* lockobj) { PySurfaceObject* surf = (PySurfaceObject*) surfobj; - if (surf->surf != NULL) - SDL_UnlockSurface (surf->surf); - if (surf->subsurface) - PySurface_Unprep (surfobj); - return 1; + int found = 0; + int noerror = 1; + + if (surf->locklist) + { + PyObject *item, *ref; + Py_ssize_t len = PyList_Size (surf->locklist); + while (--len >= 0 && !found) + { + item = PyList_GetItem (surf->locklist, len); + ref = PyWeakref_GetObject (item); + if (ref == lockobj) + { + if (PySequence_DelItem (surf->locklist, len) == -1) + return 0; + else + found = 1; + } + } + + /* Clear dead references */ + len = PyList_Size (surf->locklist); + while (--len >= 0) + { + item = PyList_GetItem (surf->locklist, len); + ref = PyWeakref_GetObject (item); + if (ref == Py_None) + { + if (PySequence_DelItem (surf->locklist, len) == -1) + noerror = 0; + else + found++; + } + } + } + + if (!found) + return noerror; + + /* Release all found locks. */ + while (found > 0) + { + if (surf->surf != NULL) + SDL_UnlockSurface (surf->surf); + if (surf->subsurface) + PySurface_Unprep (surfobj); + found--; + } + + return noerror; } -/* lifetimelock object internals */ -typedef struct + +static PyTypeObject PyLifetimeLock_Type = { - PyObject_HEAD - PyObject* surface; -} PyLifetimeLockObject; + PyObject_HEAD_INIT(NULL) + 0, /*size*/ + "SurfLifeLock", /*name*/ + sizeof(PyLifetimeLock), /*basic size*/ + 0, /* tp_itemsize */ + _lifelock_dealloc, /* tp_dealloc*/ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof (PyLifetimeLock, weakrefs), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0 /* tp_del */ +}; +/* lifetimelock object internals */ static void -lifelock_dealloc (PyObject* self) +_lifelock_dealloc (PyObject* self) { - PyLifetimeLockObject* lifelock = (PyLifetimeLockObject*) self; - - PySurface_Unlock (lifelock->surface); + PyLifetimeLock* lifelock = (PyLifetimeLock*) self; + + if (lifelock->weakrefs) + PyObject_ClearWeakRefs (self); + + PySurface_UnlockBy (lifelock->surface, lifelock->lockobj); Py_DECREF (lifelock->surface); - PyObject_DEL (self); } -static PyTypeObject PyLifetimeLock_Type = -{ - PyObject_HEAD_INIT(NULL) - 0, /*size*/ - "SurfLifeLock", /*name*/ - sizeof(PyLifetimeLockObject),/*basic size*/ - 0, /*itemsize*/ - lifelock_dealloc, /*dealloc*/ -}; - static PyObject* -PySurface_LockLifetime (PyObject* surf) +PySurface_LockLifetime (PyObject* surfobj, PyObject *lockobj) { - PyLifetimeLockObject* life; - if (!surf) + PyLifetimeLock* life; + if (!surfobj) return RAISE (PyExc_SDLError, SDL_GetError ()); - if (!PySurface_Lock (surf)) - return NULL; - - life = PyObject_NEW (PyLifetimeLockObject, &PyLifetimeLock_Type); + life = PyObject_NEW (PyLifetimeLock, &PyLifetimeLock_Type); if (life) { - life->surface = surf; - Py_INCREF (surf); + life->surface = surfobj; + life->lockobj = lockobj; + life->weakrefs = NULL; + Py_INCREF (surfobj); + if (!PySurface_LockBy (surfobj, lockobj)) + return NULL; } return (PyObject*) life; } @@ -141,11 +260,14 @@ dict = PyModule_GetDict (module); /* export the c api */ - c_api[0] = PySurface_Prep; - c_api[1] = PySurface_Unprep; - c_api[2] = PySurface_Lock; - c_api[3] = PySurface_Unlock; - c_api[4] = PySurface_LockLifetime; + c_api[0] = &PyLifetimeLock_Type; + c_api[1] = PySurface_Prep; + c_api[2] = PySurface_Unprep; + c_api[3] = PySurface_Lock; + c_api[4] = PySurface_Unlock; + c_api[5] = PySurface_LockBy; + c_api[6] = PySurface_UnlockBy; + c_api[7] = PySurface_LockLifetime; apiobj = PyCObject_FromVoidPtr (c_api, NULL); PyDict_SetItemString (dict, PYGAMEAPI_LOCAL_ENTRY, apiobj); Py_DECREF (apiobj); diff -Nru pygame-1.8.0release/src/time.c pygame-1.8.1release/src/time.c --- pygame-1.8.0release/src/time.c 2007-06-26 19:13:00.000000000 -0400 +++ pygame-1.8.1release/src/time.c 2008-07-07 01:57:32.000000000 -0400 @@ -299,7 +299,8 @@ { "get_time", (PyCFunction) clock_get_time, METH_NOARGS, DOC_CLOCKGETTIME }, { "get_rawtime", (PyCFunction) clock_get_rawtime, METH_NOARGS, DOC_CLOCKGETRAWTIME }, - { "tick_busy_loop", clock_tick_busy_loop, METH_VARARGS, DOC_CLOCKTICK }, + { "tick_busy_loop", clock_tick_busy_loop, METH_VARARGS, + DOC_CLOCKTICKBUSYLOOP }, { NULL, NULL, 0, NULL} }; diff -Nru pygame-1.8.0release/src/time.doc pygame-1.8.1release/src/time.doc --- pygame-1.8.0release/src/time.doc 2006-06-08 03:13:22.000000000 -0400 +++ pygame-1.8.1release/src/time.doc 2008-07-07 01:57:32.000000000 -0400 @@ -102,6 +102,8 @@ Note that this function uses pygame.time.delay, which uses lots of cpu in a busy loop to make sure that timing is more acurate. + +New in pygame 1.8.0. diff -Nru pygame-1.8.0release/src/transform.c pygame-1.8.1release/src/transform.c --- pygame-1.8.0release/src/transform.c 2008-01-19 21:26:20.000000000 -0500 +++ pygame-1.8.1release/src/transform.c 2008-07-28 05:36:47.000000000 -0400 @@ -571,8 +571,9 @@ return RAISE (PyExc_ValueError, "unsupport Surface bit depth for transform"); - if (!(((int) angle) % 90)) - { + + + if ( !( fmod((double)angle, (double)90.0f) ) ) { PySurface_Lock (surfobj); Py_BEGIN_ALLOW_THREADS; @@ -1738,15 +1739,15 @@ static void scalesmooth(SDL_Surface *src, SDL_Surface *dst) { - Uint8* srcpix = (Uint8*)src->pixels; - Uint8* dstpix = (Uint8*)dst->pixels; + Uint8* srcpix = (Uint8*)src->pixels; + Uint8* dstpix = (Uint8*)dst->pixels; Uint8* dst32 = NULL; - int srcpitch = src->pitch; - int dstpitch = dst->pitch; + int srcpitch = src->pitch; + int dstpitch = dst->pitch; - int srcwidth = src->w; - int srcheight = src->h; - int dstwidth = dst->w; + int srcwidth = src->w; + int srcheight = src->h; + int dstwidth = dst->w; int dstheight = dst->h; int bpp = src->format->BytesPerPixel; @@ -1759,7 +1760,8 @@ { int newpitch = srcwidth * 4; Uint8 *newsrc = (Uint8 *) malloc(newpitch * srcheight); - if (!newsrc) return; + if (!newsrc) + return; convert_24_32(srcpix, srcpitch, newsrc, newpitch, srcwidth, srcheight); srcpix = newsrc; srcpitch = newpitch; @@ -1768,7 +1770,7 @@ dst32 = (Uint8 *) malloc(dstpitch * dstheight); if (dst32 == NULL) { - free(dst32); + free(srcpix); return; } dstpix = dst32; @@ -1871,7 +1873,8 @@ srcpix = NULL; } /* free temporary buffer if necessary */ - if (temppix != NULL) free(temppix); + if (temppix != NULL) + free(temppix); } @@ -2197,9 +2200,8 @@ break; } - - similar++; } + similar++; @@ -2251,8 +2253,8 @@ num_threshold_pixels = 0; change_return = 1; - rgba_threshold[0] = 0; rgba_threshold[1] = 0; rgba_threshold[2] = 0; rgba_threshold[4] = 255; - rgba_diff_color[0] = 0; rgba_diff_color[1] = 0; rgba_diff_color[2] = 0; rgba_diff_color[4] = 255; + rgba_threshold[0] = 0; rgba_threshold[1] = 0; rgba_threshold[2] = 0; rgba_threshold[3] = 255; + rgba_diff_color[0] = 0; rgba_diff_color[1] = 0; rgba_diff_color[2] = 0; rgba_diff_color[3] = 255; /*get all the arguments*/ @@ -2272,14 +2274,24 @@ - if (PyInt_Check (rgba_obj_color)) { + if (PyInt_Check (rgba_obj_color)) + { color = (Uint32) PyInt_AsLong (rgba_obj_color); - } else if (RGBAFromObj (rgba_obj_color, rgba_color)) { - color = SDL_MapRGBA (surf->format, rgba_color[0], rgba_color[1], rgba_color[2], rgba_color[3]); + } + else if (PyLong_Check (rgba_obj_color)) + { + color = (Uint32) PyLong_AsUnsignedLong (rgba_obj_color); + } + else if (RGBAFromColorObj (rgba_obj_color, rgba_color)) + { + color = SDL_MapRGBA (surf->format, rgba_color[0], rgba_color[1], + rgba_color[2], rgba_color[3]); /*printf("here I am! :%d: %d, %d, %d, %d\n", color, rgba_color[0], rgba_color[1], rgba_color[2], rgba_color[3]); */ - } else { + } + else + { return RAISE (PyExc_TypeError, "invalid color argument"); } @@ -2289,7 +2301,10 @@ if (PyInt_Check (rgba_obj_threshold)) color_threshold = (Uint32) PyInt_AsLong (rgba_obj_threshold); - else if (RGBAFromObj (rgba_obj_threshold, rgba_threshold)) + else if (PyLong_Check (rgba_obj_threshold)) + color_threshold = (Uint32) PyLong_AsUnsignedLong + (rgba_obj_threshold); + else if (RGBAFromColorObj (rgba_obj_threshold, rgba_threshold)) color_threshold = SDL_MapRGBA (surf->format, rgba_threshold[0], rgba_threshold[1], rgba_threshold[2], rgba_threshold[3]); else return RAISE (PyExc_TypeError, "invalid threshold argument"); @@ -2302,7 +2317,10 @@ if (PyInt_Check (rgba_obj_diff_color)) color_diff_color = (Uint32) PyInt_AsLong (rgba_obj_diff_color); - else if (RGBAFromObj (rgba_obj_diff_color, rgba_diff_color)) + else if (PyLong_Check (rgba_obj_threshold)) + color_diff_color = (Uint32) PyLong_AsUnsignedLong + (rgba_obj_diff_color); + else if (RGBAFromColorObj (rgba_obj_diff_color, rgba_diff_color)) color_diff_color = SDL_MapRGBA (surf->format, rgba_diff_color[0], rgba_diff_color[1], rgba_diff_color[2], rgba_diff_color[3]); else return RAISE (PyExc_TypeError, "invalid diff_color argument"); @@ -3030,6 +3048,7 @@ /*imported needed apis*/ import_pygame_base (); + import_pygame_color (); import_pygame_rect (); import_pygame_surface (); } diff -Nru pygame-1.8.0release/src/transform.doc pygame-1.8.1release/src/transform.doc --- pygame-1.8.0release/src/transform.doc 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/src/transform.doc 2008-07-15 09:42:39.000000000 -0400 @@ -150,9 +150,8 @@ threshold finds which, and how many pixels in a surface are within a threshold of a color. -pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = True): return num_threshold_pixels -Finds which, and how many pixels in a surface are within a threshold of a color. +pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = True, Surface =None): return num_threshold_pixels It can set the destination surface where all of the pixels not within the threshold are changed to diff_color. @@ -160,6 +159,9 @@ Or it can be used to just count the number of pixels within the threshold if you set change_return to False. +When given the optional third surface, it will use the colors in that rather +than the 3rd position "color" arg. + You can use a threshold of (r,g,b,a) where the r,g,b can have different thresholds. So you could use an r threshold of 40 and a blue threshold of 2 if you like. diff -Nru pygame-1.8.0release/test/base_test.py pygame-1.8.1release/test/base_test.py --- pygame-1.8.0release/test/base_test.py 2006-06-08 03:13:20.000000000 -0400 +++ pygame-1.8.1release/test/base_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,6 +1,7 @@ - -import unittest, pygame - +import test_utils +import test.unittest as unittest +import pygame +from test_utils import test_not_implemented init_called = quit_called = 0 def __PYGAMEinit__(): #called automatically by pygame.init() @@ -12,15 +13,115 @@ quit_called = quit_called + 1 +quit_hook_ran = 0 +def quit_hook(): + global quit_hook_ran + quit_hook_ran = 1 -class BaseTest(unittest.TestCase): +class BaseModuleTest(unittest.TestCase): def testAutoInit(self): pygame.init() pygame.quit() self.assertEqual(init_called, 1) self.assertEqual(quit_called, 1) + def test_get_error(self): + + # __doc__ (as of 2008-06-25) for pygame.base.get_error: + + # pygame.get_error(): return errorstr + # get the current error message + + self.assert_(test_not_implemented()) + + def test_get_sdl_byteorder(self): + + # __doc__ (as of 2008-06-25) for pygame.base.get_sdl_byteorder: + + # pygame.get_sdl_byteorder(): return int + # get the byte order of SDL + + self.assert_(pygame.get_sdl_byteorder() + 1) + + def test_get_sdl_version(self): + + # __doc__ (as of 2008-06-25) for pygame.base.get_sdl_version: + + # pygame.get_sdl_version(): return major, minor, patch + # get the version number of SDL + + self.assert_( len(pygame.get_sdl_version()) == 3) + + def test_init(self): + return + + # __doc__ (as of 2008-06-25) for pygame.base.init: + + # pygame.init(): return (numpass, numfail) + # initialize all imported pygame modules + + self.assert_(test_not_implemented()) + + def not_init_assertions(self): + self.assert_(not pygame.display.get_init(), "display shouldn't be initialized" ) + self.assert_(not pygame.mixer.get_init(), "mixer shouldn't be initialized" ) + self.assert_(not pygame.font.get_init(), "init shouldn't be initialized" ) + + self.assertRaises(pygame.error, pygame.scrap.get) + + # pygame.cdrom + # pygame.joystick + + def init_assertions(self): + self.assert_(pygame.display.get_init()) + self.assert_(pygame.mixer.get_init()) + self.assert_(pygame.font.get_init()) + + def test_quit__and_init(self): + return # TODO + + # __doc__ (as of 2008-06-25) for pygame.base.quit: + + # pygame.quit(): return None + # uninitialize all pygame modules + + # Make sure everything is not init + self.not_init_assertions() + + # Initiate it + pygame.init() + + # Check + self.init_assertions() + + # Quit + pygame.quit() + + # All modules have quit + self.not_init_assertions() + + def test_register_quit(self): + + # __doc__ (as of 2008-06-25) for pygame.base.register_quit: + + # register_quit(callable): return None + # register a function to be called when pygame quits + + self.assert_(not quit_hook_ran) + + pygame.init() + pygame.register_quit(quit_hook) + pygame.quit() + + self.assert_(quit_hook_ran) + + def test_segfault(self): + + # __doc__ (as of 2008-06-25) for pygame.base.segfault: + + # crash + self.assert_(test_not_implemented()) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/base_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/base_test.pyc differ diff -Nru pygame-1.8.0release/test/blit_test.py pygame-1.8.1release/test/blit_test.py --- pygame-1.8.0release/test/blit_test.py 2006-06-08 03:13:20.000000000 -0400 +++ pygame-1.8.1release/test/blit_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,4 +1,6 @@ -import unittest +import test_utils +import test.unittest as unittest +import test_utils import pygame from pygame.locals import * @@ -6,7 +8,6 @@ def test_SRCALPHA( self ): """ SRCALPHA tests. """ - #blend(s, 0, d) = d s = pygame.Surface((1,1), SRCALPHA, 32) s.fill((255, 255,255, 0)) @@ -17,8 +18,6 @@ s.blit(d, (0,0)) self.assertEqual(s.get_at((0,0)), d.get_at((0,0)) ) - - #blend(s, 255, d) = s s = pygame.Surface((1,1), SRCALPHA, 32) s.fill((123, 0, 0, 255)) @@ -29,26 +28,35 @@ s.blit(d, (0,0)) self.assertEqual(s.get_at((0,0)), s1.get_at((0,0)) ) - #TODO: these should be true too. #blend(0, sA, 0) = 0 #blend(255, sA, 255) = 255 #blend(s, sA, d) <= 255 - def test_BLEND( self ): """ BLEND_ tests. """ #test that it doesn't overflow, and that it is saturated. - s = pygame.Surface((1,1)) + s = pygame.Surface((1,1), SRCALPHA, 32) s.fill((255, 255,255, 0)) - d = pygame.Surface((1,1)) + d = pygame.Surface((1,1), SRCALPHA, 32) d.fill((0, 0,255, 255)) s.blit(d, (0,0), None, BLEND_ADD) - self.assertEqual(s.get_at((0,0))[2], 255 ) + + #print "d %s" % (d.get_at((0,0)),) + #print s.get_at((0,0)) + #self.assertEqual(s.get_at((0,0))[2], 255 ) + #self.assertEqual(s.get_at((0,0))[3], 0 ) + + + + s.blit(d, (0,0), None, BLEND_RGBA_ADD) + #print s.get_at((0,0)) + self.assertEqual(s.get_at((0,0))[3], 255 ) + # test adding works. s.fill((20, 255,255, 0)) Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/blit_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/blit_test.pyc differ diff -Nru pygame-1.8.0release/test/bufferproxy_test.py pygame-1.8.1release/test/bufferproxy_test.py --- pygame-1.8.0release/test/bufferproxy_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/bufferproxy_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,29 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class BufferProxyTypeTest(unittest.TestCase): + def test_write(self): + + # __doc__ (as of 2008-06-25) for pygame.bufferproxy.BufferProxy.write: + + # B.write (bufferproxy, buffer, offset) -> None + # + # Writes raw data to the bufferproxy. + # + # Writes the raw data from buffer to the BufferProxy object, starting + # at the specified offset within the BufferProxy. + # If the length of the passed buffer exceeds the length of the + # BufferProxy (reduced by the offset), an IndexError will be raised. + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/bufferproxy_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/bufferproxy_test.pyc differ diff -Nru pygame-1.8.0release/test/cdrom_test.py pygame-1.8.1release/test/cdrom_test.py --- pygame-1.8.0release/test/cdrom_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/cdrom_test.py 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,279 @@ +#################################### IMPORTS ################################### + +__tags__ = ['interactive'] + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented, question, prompt + +import pygame + +################################################################################ + +class CdromModuleTest(unittest.TestCase): + def todo_test_CD(self): + + # __doc__ (as of 2008-06-25) for pygame.cdrom.CD: + + # pygame.cdrom.CD(id): return CD + # class to manage a cdrom drive + + self.fail() + + def todo_test_get_count(self): + + + # __doc__ (as of 2008-06-25) for pygame.cdrom.get_count: + + # pygame.cdrom.get_count(): return count + # number of cd drives on the system + + self.fail() + + def todo_test_get_init(self): + + + # __doc__ (as of 2008-06-25) for pygame.cdrom.get_init: + + # pygame.cdrom.get_init(): return bool + # true if the cdrom module is initialized + + self.fail() + + def todo_test_init(self): + + + # __doc__ (as of 2008-06-25) for pygame.cdrom.init: + + # pygame.cdrom.init(): return None + # initialize the cdrom module + + self.fail() + + def todo_test_quit(self): + + + # __doc__ (as of 2008-06-25) for pygame.cdrom.quit: + + # pygame.cdrom.quit(): return None + # uninitialize the cdrom module + + self.fail() + +class CDTypeTest(unittest.TestCase): + def setUp(self): + pygame.cdrom.init() + + try: + self.cd = pygame.cdrom.CD(0) + except pygame.error: + self.cd = None + + def tearDown(self): + pygame.cdrom.quit() + + def test_1_eject(self): + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.eject: + + # CD.eject(): return None + # eject or open the cdrom drive + + # should raise if cd object not initialized + if self.cd: + self.cd.init() + self.cd.eject() + + self.assert_(question('Did the cd eject?')) + + prompt("Please close the cd drive") + + # self.assert_(test_not_implemented()) + + def todo_test_get_all(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_all: + + # CD.get_all(): return [(audio, start, end, lenth), ...] + # get all track information + + # self.cd.init() + + self.fail() + + def todo_test_get_busy(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_busy: + + # CD.get_busy(): return bool + # true if the drive is playing audio + + self.fail() + + def todo_test_get_current(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_current: + + # CD.get_current(): return track, seconds + # the current audio playback position + + self.fail() + + def todo_test_get_empty(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_empty: + + # CD.get_empty(): return bool + # False if a cdrom is in the drive + + self.fail() + + def todo_test_get_id(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_id: + + # CD.get_init(): return bool + # true if this cd device initialized + + self.fail() + + def todo_test_get_init(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_init: + + # CD.get_init(): return bool + # true if this cd device initialized + + self.fail() + + def test_2_get_name(self): + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_name: + + # CD.get_name(): return name + # the system name of the cdrom drive + + if self.cd: + cd_name = self.cd.get_name() + + self.assert_ ( + question('Is %s the correct name for the cd drive?' % cd_name) + ) + + def todo_test_get_numtracks(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_numtracks: + + # CD.get_numtracks(): return count + # the number of tracks on the cdrom + + self.fail() + + def todo_test_get_paused(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_paused: + + # CD.get_paused(): return bool + # true if the drive is paused + + self.fail() + + def todo_test_get_track_audio(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_track_audio: + + # CD.get_track_audio(track): return bool + # true if the cdrom track has audio data + + self.fail() + + def todo_test_get_track_length(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_track_length: + + # CD.get_track_length(track): return seconds + # length of a cdrom track + + self.fail() + + def todo_test_get_track_start(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.get_track_start: + + # CD.get_track_start(track): return seconds + # start time of a cdrom track + + self.fail() + + def todo_test_init(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.init: + + # CD.init(): return None + # initialize a cdrom drive for use + + self.fail() + + def todo_test_pause(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.pause: + + # CD.pause(): return None + # temporarily stop audio playback + + self.fail() + + def todo_test_play(self): + + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.play: + + # CD.init(): return None + # initialize a cdrom drive for use + + self.fail() + + def todo_test_quit(self): + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.quit: + + # CD.quit(): return None + # uninitialize a cdrom drive for use + + self.fail() + + def todo_test_resume(self): + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.resume: + + # CD.resume(): return None + # unpause audio playback + + self.fail() + + def todo_test_stop(self): + + # __doc__ (as of 2008-07-02) for pygame.cdrom.CD.stop: + + # CD.stop(): return None + # stop audio playback + + self.fail() + +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/cdrom_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/cdrom_test.pyc differ diff -Nru pygame-1.8.0release/test/color_test.py pygame-1.8.1release/test/color_test.py --- pygame-1.8.0release/test/color_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/color_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,540 @@ +#################################### IMPORTS ################################### + +from __future__ import generators + +import test_utils +import test.unittest as unittest + +import pygame +import math + +from test_utils import test_not_implemented + +################################### CONSTANTS ################################## + +rgba_vals = [0, 1, 62, 63, 126, 127, 255] + +rgba_combinations = [ (r,g,b,a) for r in rgba_vals + for g in rgba_vals + for b in rgba_vals + for a in rgba_vals ] + +################################################################################ + +def rgba_combos_Color_generator (): + for rgba in rgba_combinations: + yield pygame.Color(*rgba) + +# Python gamma correct +def gamma_correct (rgba_0_255, gamma): + corrected = round(255.0 * math.pow(rgba_0_255/255.0, gamma)) + return max(min( int(corrected), 255), 0) + +################################################################################ + +# TODO: add tests for +# correct_gamma() -- test against statically defined verified correct values +# coerce () -- ?? + +def _assignr (x, y): + x.r = y + +def _assigng (x, y): + x.g = y + +def _assignb (x, y): + x.b = y + +def _assigna (x, y): + x.a = y + +def _assign_item (x, p, y): + x[p] = y + +class ColorTypeTest (unittest.TestCase): + def test_color (self): + c = pygame.Color (10, 20, 30, 40) + self.assertEquals (c.r, 10) + self.assertEquals (c.g, 20) + self.assertEquals (c.b, 30) + self.assertEquals (c.a, 40) + + c = pygame.Color ("indianred3") + self.assertEquals (c.r, 205) + self.assertEquals (c.g, 85) + self.assertEquals (c.b, 85) + self.assertEquals (c.a, 255) + + c = pygame.Color (0xAABBCCDD) + self.assertEquals (c.r, 0xAA) + self.assertEquals (c.g, 0xBB) + self.assertEquals (c.b, 0xCC) + self.assertEquals (c.a, 0xDD) + + self.assertRaises (ValueError, pygame.Color, 257, 10, 105, 44) + self.assertRaises (ValueError, pygame.Color, 10, 257, 105, 44) + self.assertRaises (ValueError, pygame.Color, 10, 105, 257, 44) + self.assertRaises (ValueError, pygame.Color, 10, 105, 44, 257) + + def test_rgba (self): + c = pygame.Color (0) + self.assertEquals (c.r, 0) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 0) + self.assertEquals (c.a, 0) + + # Test simple assignments + c.r = 123 + self.assertEquals (c.r, 123) + self.assertRaises (ValueError, _assignr, c, 537) + self.assertEquals (c.r, 123) + self.assertRaises (ValueError, _assignr, c, -3) + self.assertEquals (c.r, 123) + + c.g = 55 + self.assertEquals (c.g, 55) + self.assertRaises (ValueError, _assigng, c, 348) + self.assertEquals (c.g, 55) + self.assertRaises (ValueError, _assigng, c, -44) + self.assertEquals (c.g, 55) + + c.b = 77 + self.assertEquals (c.b, 77) + self.assertRaises (ValueError, _assignb, c, 256) + self.assertEquals (c.b, 77) + self.assertRaises (ValueError, _assignb, c, -12) + self.assertEquals (c.b, 77) + + c.a = 255 + self.assertEquals (c.a, 255) + self.assertRaises (ValueError, _assigna, c, 312) + self.assertEquals (c.a, 255) + self.assertRaises (ValueError, _assigna, c, -10) + self.assertEquals (c.a, 255) + + def test_repr (self): + c = pygame.Color (68, 38, 26, 69) + t = "(68, 38, 26, 69)" + self.assertEquals (repr (c), t) + + def test_add (self): + c1 = pygame.Color (0) + self.assertEquals (c1.r, 0) + self.assertEquals (c1.g, 0) + self.assertEquals (c1.b, 0) + self.assertEquals (c1.a, 0) + + c2 = pygame.Color (20, 33, 82, 193) + self.assertEquals (c2.r, 20) + self.assertEquals (c2.g, 33) + self.assertEquals (c2.b, 82) + self.assertEquals (c2.a, 193) + + c3 = c1 + c2 + self.assertEquals (c3.r, 20) + self.assertEquals (c3.g, 33) + self.assertEquals (c3.b, 82) + self.assertEquals (c3.a, 193) + + c3 = c3 + c2 + self.assertEquals (c3.r, 40) + self.assertEquals (c3.g, 66) + self.assertEquals (c3.b, 164) + self.assertEquals (c3.a, 255) + + def test_sub (self): + c1 = pygame.Color (0xFFFFFFFF) + self.assertEquals (c1.r, 255) + self.assertEquals (c1.g, 255) + self.assertEquals (c1.b, 255) + self.assertEquals (c1.a, 255) + + c2 = pygame.Color (20, 33, 82, 193) + self.assertEquals (c2.r, 20) + self.assertEquals (c2.g, 33) + self.assertEquals (c2.b, 82) + self.assertEquals (c2.a, 193) + + c3 = c1 - c2 + self.assertEquals (c3.r, 235) + self.assertEquals (c3.g, 222) + self.assertEquals (c3.b, 173) + self.assertEquals (c3.a, 62) + + c3 = c3 - c2 + self.assertEquals (c3.r, 215) + self.assertEquals (c3.g, 189) + self.assertEquals (c3.b, 91) + self.assertEquals (c3.a, 0) + + def test_mul (self): + c1 = pygame.Color (0x01010101) + self.assertEquals (c1.r, 1) + self.assertEquals (c1.g, 1) + self.assertEquals (c1.b, 1) + self.assertEquals (c1.a, 1) + + c2 = pygame.Color (2, 5, 3, 22) + self.assertEquals (c2.r, 2) + self.assertEquals (c2.g, 5) + self.assertEquals (c2.b, 3) + self.assertEquals (c2.a, 22) + + c3 = c1 * c2 + self.assertEquals (c3.r, 2) + self.assertEquals (c3.g, 5) + self.assertEquals (c3.b, 3) + self.assertEquals (c3.a, 22) + + c3 = c3 * c2 + self.assertEquals (c3.r, 4) + self.assertEquals (c3.g, 25) + self.assertEquals (c3.b, 9) + self.assertEquals (c3.a, 255) + + def test_div (self): + c1 = pygame.Color (0x80808080) + self.assertEquals (c1.r, 128) + self.assertEquals (c1.g, 128) + self.assertEquals (c1.b, 128) + self.assertEquals (c1.a, 128) + + c2 = pygame.Color (2, 4, 8, 16) + self.assertEquals (c2.r, 2) + self.assertEquals (c2.g, 4) + self.assertEquals (c2.b, 8) + self.assertEquals (c2.a, 16) + + c3 = c1 / c2 + self.assertEquals (c3.r, 64) + self.assertEquals (c3.g, 32) + self.assertEquals (c3.b, 16) + self.assertEquals (c3.a, 8) + + c3 = c3 / c2 + self.assertEquals (c3.r, 32) + self.assertEquals (c3.g, 8) + self.assertEquals (c3.b, 2) + self.assertEquals (c3.a, 0) + + def test_mod (self): + c1 = pygame.Color (0xFFFFFFFF) + self.assertEquals (c1.r, 255) + self.assertEquals (c1.g, 255) + self.assertEquals (c1.b, 255) + self.assertEquals (c1.a, 255) + + c2 = pygame.Color (2, 4, 8, 16) + self.assertEquals (c2.r, 2) + self.assertEquals (c2.g, 4) + self.assertEquals (c2.b, 8) + self.assertEquals (c2.a, 16) + + c3 = c1 % c2 + self.assertEquals (c3.r, 1) + self.assertEquals (c3.g, 3) + self.assertEquals (c3.b, 7) + self.assertEquals (c3.a, 15) + + def test_float (self): + c = pygame.Color (0xCC00CC00) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (float (c), float (0xCC00CC00)) + + c = pygame.Color (0x33727592) + self.assertEquals (c.r, 51) + self.assertEquals (c.g, 114) + self.assertEquals (c.b, 117) + self.assertEquals (c.a, 146) + self.assertEquals (float (c), float (0x33727592)) + + def test_oct (self): + c = pygame.Color (0xCC00CC00) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (oct (c), oct (0xCC00CC00)) + + c = pygame.Color (0x33727592) + self.assertEquals (c.r, 51) + self.assertEquals (c.g, 114) + self.assertEquals (c.b, 117) + self.assertEquals (c.a, 146) + self.assertEquals (oct (c), oct (0x33727592)) + + def test_hex (self): + c = pygame.Color (0xCC00CC00) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (hex (c), hex (0xCC00CC00)) + + c = pygame.Color (0x33727592) + self.assertEquals (c.r, 51) + self.assertEquals (c.g, 114) + self.assertEquals (c.b, 117) + self.assertEquals (c.a, 146) + self.assertEquals (hex (c), hex (0x33727592)) + + + def test_webstyle(self): + c = pygame.Color ("#CC00CC11") + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 17) + self.assertEquals (hex (c), hex (0xCC00CC11)) + + c = pygame.Color ("#CC00CC") + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (hex (c), hex (0xCC00CC00)) + + c = pygame.Color ("0xCC00CC11") + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 17) + self.assertEquals (hex (c), hex (0xCC00CC11)) + + c = pygame.Color ("0xCC00CC") + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (hex (c), hex (0xCC00CC00)) + + self.assertRaises (ValueError, pygame.Color, "#cc00qq") + self.assertRaises (ValueError, pygame.Color, "0xcc00qq") + self.assertRaises (ValueError, pygame.Color, "09abcdef") + self.assertRaises (ValueError, pygame.Color, "09abcde") + self.assertRaises (ValueError, pygame.Color, "quarky") + + def test_int (self): + # This will be a long + c = pygame.Color (0xCC00CC00) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (int (c), int (0xCC00CC00)) + + # This will be an int + c = pygame.Color (0x33727592) + self.assertEquals (c.r, 51) + self.assertEquals (c.g, 114) + self.assertEquals (c.b, 117) + self.assertEquals (c.a, 146) + self.assertEquals (int (c), int (0x33727592)) + + def test_long (self): + # This will be a long + c = pygame.Color (0xCC00CC00) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 0) + self.assertEquals (c.b, 204) + self.assertEquals (c.a, 0) + self.assertEquals (long (c), long (0xCC00CC00)) + + # This will be an int + c = pygame.Color (0x33727592) + self.assertEquals (c.r, 51) + self.assertEquals (c.g, 114) + self.assertEquals (c.b, 117) + self.assertEquals (c.a, 146) + self.assertEquals (long (c), long (0x33727592)) + + def test_normalize (self): + c = pygame.Color (204, 38, 194, 55) + self.assertEquals (c.r, 204) + self.assertEquals (c.g, 38) + self.assertEquals (c.b, 194) + self.assertEquals (c.a, 55) + + t = c.normalize () + + self.assertAlmostEquals (t[0], 0.800000, 5) + self.assertAlmostEquals (t[1], 0.149016, 5) + self.assertAlmostEquals (t[2], 0.760784, 5) + self.assertAlmostEquals (t[3], 0.215686, 5) + + def test_len (self): + c = pygame.Color (204, 38, 194, 55) + self.assertEquals (len (c), 4) + + def test_get_item (self): + c = pygame.Color (204, 38, 194, 55) + self.assertEquals (c[0], 204) + self.assertEquals (c[1], 38) + self.assertEquals (c[2], 194) + self.assertEquals (c[3], 55) + + def test_set_item (self): + c = pygame.Color (204, 38, 194, 55) + self.assertEquals (c[0], 204) + self.assertEquals (c[1], 38) + self.assertEquals (c[2], 194) + self.assertEquals (c[3], 55) + + c[0] = 33 + self.assertEquals (c[0], 33) + c[1] = 48 + self.assertEquals (c[1], 48) + c[2] = 173 + self.assertEquals (c[2], 173) + c[3] = 213 + self.assertEquals (c[3], 213) + + # Now try some 'invalid' ones + self.assertRaises (ValueError, _assign_item, c, 0, 95.485) + self.assertEquals (c[0], 33) + self.assertRaises (ValueError, _assign_item, c, 1, -83) + self.assertEquals (c[1], 48) + self.assertRaises (ValueError, _assign_item, c, 2, "Hello") + self.assertEquals (c[2], 173) + + def test_Color_type_works_for_Surface_get_and_set_colorkey(self): + s = pygame.Surface((32, 32)) + + c = pygame.Color(33, 22, 11, 255) + s.set_colorkey(c) + + get_r, get_g, get_b, get_a = s.get_colorkey() + + self.assert_(get_r == c.r) + self.assert_(get_g == c.g) + self.assert_(get_b == c.b) + self.assert_(get_a == c.a) + +########## HSLA, HSVA, CMY, I1I2I3 ALL ELEMENTS WITHIN SPECIFIED RANGE ######### + + def test_hsla__all_elements_within_limits (self): + for c in rgba_combos_Color_generator(): + h, s, l, a = c.hsla + self.assert_(0 <= h <= 360) + self.assert_(0 <= s <= 100) + self.assert_(0 <= l <= 100) + self.assert_(0 <= a <= 100) + + def test_hsva__all_elements_within_limits (self): + for c in rgba_combos_Color_generator(): + h, s, v, a = c.hsva + self.assert_(0 <= h <= 360) + self.assert_(0 <= s <= 100) + self.assert_(0 <= v <= 100) + self.assert_(0 <= a <= 100) + + def test_cmy__all_elements_within_limits (self): + for c in rgba_combos_Color_generator(): + c, m, y = c.cmy + self.assert_(0 <= c <= 1) + self.assert_(0 <= m <= 1) + self.assert_(0 <= y <= 1) + + def test_i1i2i3__all_elements_within_limits (self): + for c in rgba_combos_Color_generator(): + i1, i2, i3 = c.i1i2i3 + self.assert_( 0 <= i1 <= 1) + self.assert_( -0.5 <= i2 <= 0.5) + self.assert_( -0.5 <= i3 <= 0.5) + +####################### COLORSPACE PROPERTY SANITY TESTS ####################### + + def colorspaces_converted_should_not_raise (self, prop): + fails = 0 + + x = 0 + for c in rgba_combos_Color_generator(): + x += 1 + + other = pygame.Color(0) + + try: + setattr(other, prop, getattr(c, prop)) + #eg other.hsla = c.hsla + + except ValueError: + fails += 1 + + self.assert_(x > 0, "x is combination counter, 0 means no tests!") + self.assert_((fails, x) == (0, x)) + + def test_hsla__sanity_testing_converted_should_not_raise (self): + self.colorspaces_converted_should_not_raise('hsla') + + def test_hsva__sanity_testing_converted_should_not_raise (self): + self.colorspaces_converted_should_not_raise('hsva') + + def test_cmy__sanity_testing_converted_should_not_raise (self): + self.colorspaces_converted_should_not_raise('cmy') + + def test_i1i2i3__sanity_testing_converted_should_not_raise (self): + self.colorspaces_converted_should_not_raise('i1i2i3') + +################################################################################ + + def colorspaces_converted_should_equate_bar_rounding (self, prop): + for c in rgba_combos_Color_generator(): + other = pygame.Color(0) + + try: + setattr(other, prop, getattr(c, prop)) + #eg other.hsla = c.hsla + + self.assert_(abs(other.r - c.r) <= 1) + self.assert_(abs(other.b - c.b) <= 1) + self.assert_(abs(other.g - c.g) <= 1) + # CMY and I1I2I3 do not care about the alpha + if not prop in ("cmy", "i1i2i3"): + self.assert_(abs(other.a - c.a) <= 1) + + except ValueError: + pass # other tests will notify, this tests equation + + def test_hsla__sanity_testing_converted_should_equate_bar_rounding(self): + self.colorspaces_converted_should_equate_bar_rounding('hsla') + + def test_hsva__sanity_testing_converted_should_equate_bar_rounding(self): + self.colorspaces_converted_should_equate_bar_rounding('hsva') + + def test_cmy__sanity_testing_converted_should_equate_bar_rounding(self): + self.colorspaces_converted_should_equate_bar_rounding('cmy') + + def test_i1i2i3__sanity_testing_converted_should_equate_bar_rounding(self): + self.colorspaces_converted_should_equate_bar_rounding('i1i2i3') + +################################################################################ + + def test_correct_gamma__verified_against_python_implementation(self): + "|tags:slow|" + # gamma_correct defined at top of page + + gammas = map(lambda i: i / 10.0, range(1, 31)) # [0.1 .. 3.0] + gammas_len = len(gammas) + + for i, c in enumerate(rgba_combos_Color_generator()): + gamma = gammas[i % gammas_len] + + corrected = pygame.Color(*[gamma_correct(x, gamma) + for x in tuple(c)]) + lib_corrected = c.correct_gamma(gamma) + + self.assert_(corrected.r == lib_corrected.r) + self.assert_(corrected.g == lib_corrected.g) + self.assert_(corrected.b == lib_corrected.b) + self.assert_(corrected.a == lib_corrected.a) + + # TODO: test against statically defined verified _correct_ values + # assert corrected.r == 125 etc. + +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/color_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/color_test.pyc differ diff -Nru pygame-1.8.0release/test/cursors_test.py pygame-1.8.1release/test/cursors_test.py --- pygame-1.8.0release/test/cursors_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/cursors_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,49 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class CursorsModuleTest(unittest.TestCase): + def test_compile(self): + + # __doc__ (as of 2008-06-25) for pygame.cursors.compile: + + # pygame.cursors.compile(strings, black, white,xor) -> data, mask + # compile cursor strings into cursor data + # + # This takes a set of strings with equal length and computes + # the binary data for that cursor. The string widths must be + # divisible by 8. + # + # The black and white arguments are single letter strings that + # tells which characters will represent black pixels, and which + # characters represent white pixels. All other characters are + # considered clear. + # + # This returns a tuple containing the cursor data and cursor mask + # data. Both these arguments are used when setting a cursor with + # pygame.mouse.set_cursor(). + + self.assert_(test_not_implemented()) + + def test_load_xbm(self): + + # __doc__ (as of 2008-06-25) for pygame.cursors.load_xbm: + + # pygame.cursors.load_xbm(cursorfile, maskfile) -> cursor_args + # reads a pair of XBM files into set_cursor arguments + # + # Arguments can either be filenames or filelike objects + # with the readlines method. Not largely tested, but + # should work with typical XBM files. + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/cursors_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/cursors_test.pyc differ diff -Nru pygame-1.8.0release/test/display_test.py pygame-1.8.1release/test/display_test.py --- pygame-1.8.0release/test/display_test.py 2006-12-23 22:26:19.000000000 -0500 +++ pygame-1.8.1release/test/display_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,14 +1,16 @@ -import unittest +import test_utils +import test.unittest as unittest import pygame, pygame.transform +from test_utils import test_not_implemented -class DisplayTest( unittest.TestCase ): - +class DisplayModuleTest( unittest.TestCase ): def test_update( self ): """ see if pygame.display.update takes rects with negative values. + "|Tags:display|" """ - if 0: + if 1: pygame.init() screen = pygame.display.set_mode((100,100)) screen.fill((55,55,55)) @@ -26,6 +28,12 @@ pygame.quit() # I think it's because unittest runs stuff in threads # here's a stack trace... + + # NOTE to author of above: + # unittest doesn't run tests in threads + # segfault was probably caused by another tests need + # for a "clean slate" + """ #0 0x08103b7c in PyFrame_New () #1 0x080bd666 in PyEval_EvalCodeEx () @@ -40,23 +48,212 @@ #10 0x08054e31 in _start () """ - - - - def test_init_quit( self ): - """ see if initing, and quiting works. - """ - - if 0: - pygame.init() - screen = pygame.display.set_mode((100,100)) - #pygame.quit() - + def test_Info(self): + + # __doc__ (as of 2008-06-25) for pygame.display.Info: + + # pygame.display.Info(): return VideoInfo + # Create a video display information object + + self.assert_(test_not_implemented()) + + def test_flip(self): + + # __doc__ (as of 2008-06-25) for pygame.display.flip: + + # pygame.display.flip(): return None + # update the full display Surface to the screen + + self.assert_(test_not_implemented()) + + def test_get_active(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_active: + + # pygame.display.get_active(): return bool + # true when the display is active on the display + + self.assert_(test_not_implemented()) + + def test_get_caption(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_caption: + + # pygame.display.get_caption(): return (title, icontitle) + # get the current window caption + + self.assert_(test_not_implemented()) + + def test_get_driver(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_driver: + + # pygame.display.get_driver(): return name + # get the name of the pygame display backend + + self.assert_(test_not_implemented()) + + def test_get_init(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_init: + + # pygame.display.get_init(): return bool + # true if the display module is initialized + + self.assert_(test_not_implemented()) + + def test_get_surface(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_surface: + + # pygame.display.get_surface(): return Surface + # get a reference to the currently set display surface + + self.assert_(test_not_implemented()) + + def test_get_wm_info(self): + + # __doc__ (as of 2008-06-25) for pygame.display.get_wm_info: + + # pygame.display.get_wm_info(): return dict + # Get information about the current windowing system + + self.assert_(test_not_implemented()) + + def test_gl_get_attribute(self): + + # __doc__ (as of 2008-06-25) for pygame.display.gl_get_attribute: + + # pygame.display.gl_get_attribute(flag): return value + # get the value for an opengl flag for the current display + + self.assert_(test_not_implemented()) + + def test_gl_set_attribute(self): + + # __doc__ (as of 2008-06-25) for pygame.display.gl_set_attribute: + + # pygame.display.gl_set_attribute(flag, value): return None + # request an opengl display attribute for the display mode + + self.assert_(test_not_implemented()) + + def test_iconify(self): + + # __doc__ (as of 2008-06-25) for pygame.display.iconify: + + # pygame.display.iconify(): return bool + # iconify the display surface + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-25) for pygame.display.init: + + # pygame.display.init(): return None + # initialize the display module + + self.assert_(test_not_implemented()) + + def test_list_modes(self): + + # __doc__ (as of 2008-06-25) for pygame.display.list_modes: + + # pygame.display.list_modes(depth=0, flags=pygame.FULLSCREEN): return list + # get list of available fullscreen modes + + self.assert_(test_not_implemented()) + + def test_mode_ok(self): + + # __doc__ (as of 2008-06-25) for pygame.display.mode_ok: + + # pygame.display.mode_ok(size, flags=0, depth=0): return depth + # pick the best color depth for a display mode + + self.assert_(test_not_implemented()) + + def test_quit(self): + + # __doc__ (as of 2008-06-25) for pygame.display.quit: + + # pygame.display.quit(): return None + # uninitialize the display module + + self.assert_(test_not_implemented()) + + def test_set_caption(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_caption: + + # pygame.display.set_caption(title, icontitle=None): return None + # set the current window caption + + self.assert_(test_not_implemented()) + + def test_set_gamma(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_gamma: + + # pygame.display.set_gamma(red, green=None, blue=None): return bool + # change the hardware gamma ramps + + self.assert_(test_not_implemented()) + + def test_set_gamma_ramp(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_gamma_ramp: + + # change the hardware gamma ramps with a custom lookup + # pygame.display.set_gamma_ramp(red, green, blue): return bool + # set_gamma_ramp(red, green, blue): return bool + + self.assert_(test_not_implemented()) + + def test_set_icon(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_icon: + + # pygame.display.set_icon(Surface): return None + # change the system image for the display window + + self.assert_(test_not_implemented()) + + def test_set_mode(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_mode: + + # pygame.display.set_mode(resolution=(0,0), flags=0, depth=0): return Surface + # initialize a window or screen for display + + self.assert_(test_not_implemented()) + + def test_set_palette(self): + + # __doc__ (as of 2008-06-25) for pygame.display.set_palette: + + # pygame.display.set_palette(palette=None): return None + # set the display color palette for indexed displays + + self.assert_(test_not_implemented()) + + def test_toggle_fullscreen(self): + + # __doc__ (as of 2008-06-25) for pygame.display.toggle_fullscreen: + + # pygame.display.toggle_fullscreen(): return bool + # switch between fullscreen and windowed displays + + self.assert_(test_not_implemented()) def test_vid_info( self ): """ """ - + + # old test, was disabled so placing reminder + self.assert_(test_not_implemented()) + if 0: pygame.init() @@ -77,10 +274,5 @@ #pygame.quit() - - - - - if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/display_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/display_test.pyc differ diff -Nru pygame-1.8.0release/test/draw_test.py pygame-1.8.1release/test/draw_test.py --- pygame-1.8.0release/test/draw_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/draw_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,142 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented, unordered_equality + +import pygame +import pygame.draw as draw + +################################################################################ + +class DrawModuleTest(unittest.TestCase): + def setUp(self): + (self.surf_w, self.surf_h) = self.surf_size = (320, 200) + self.surf = pygame.Surface(self.surf_size, pygame.SRCALPHA) + self.color = (1, 13, 24, 205) + + def test_rect__fill(self): + # __doc__ (as of 2008-06-25) for pygame.draw.rect: + + # pygame.draw.rect(Surface, color, Rect, width=0): return Rect + # draw a rectangle shape + + rect = pygame.Rect(10, 10, 25, 20) + drawn = draw.rect(self.surf, self.color, rect, 0) + + self.assert_(drawn == rect) + + #Should be colored where it's supposed to be + for pt in test_utils.rect_area_pts(rect): + color_at_pt = self.surf.get_at(pt) + self.assert_(color_at_pt == self.color) + + #And not where it shouldn't + for pt in test_utils.rect_outer_bounds(rect): + color_at_pt = self.surf.get_at(pt) + self.assert_(color_at_pt != self.color) + + def test_rect__one_pixel_lines(self): + # __doc__ (as of 2008-06-25) for pygame.draw.rect: + + # pygame.draw.rect(Surface, color, Rect, width=0): return Rect + # draw a rectangle shape + rect = pygame.Rect(10, 10, 56, 20) + + drawn = draw.rect(self.surf, self.color, rect, 1) + self.assert_(drawn == rect) + + #Should be colored where it's supposed to be + for pt in test_utils.rect_perimeter_pts(drawn): + color_at_pt = self.surf.get_at(pt) + self.assert_(color_at_pt == self.color) + + #And not where it shouldn't + for pt in test_utils.rect_outer_bounds(drawn): + color_at_pt = self.surf.get_at(pt) + self.assert_(color_at_pt != self.color) + + def test_line(self): + + # __doc__ (as of 2008-06-25) for pygame.draw.line: + + # pygame.draw.line(Surface, color, start_pos, end_pos, width=1): return Rect + # draw a straight line segment + + drawn = draw.line(self.surf, self.color, (1, 0), (200, 0)) #(l, t), (l, t) + self.assert_(drawn.right == 201, + "end point arg should be (or at least was) inclusive" + ) + + #Should be colored where it's supposed to be + for pt in test_utils.rect_area_pts(drawn): + self.assert_(self.surf.get_at(pt) == self.color) + + #And not where it shouldn't + for pt in test_utils.rect_outer_bounds(drawn): + self.assert_(self.surf.get_at(pt) != self.color) + + + def test_aaline(self): + # __doc__ (as of 2008-06-25) for pygame.draw.aaline: + + # pygame.draw.aaline(Surface, color, startpos, endpos, blend=1): return Rect + # draw fine antialiased lines + + self.assert_(test_not_implemented()) + + def test_aalines(self): + + # __doc__ (as of 2008-06-25) for pygame.draw.aalines: + + # pygame.draw.aalines(Surface, color, closed, pointlist, blend=1): return Rect + + self.assert_(test_not_implemented()) + + def test_arc(self): + + # __doc__ (as of 2008-06-25) for pygame.draw.arc: + + # pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1): return Rect + # draw a partial section of an ellipse + + self.assert_(test_not_implemented()) + + def test_circle(self): + # __doc__ (as of 2008-06-25) for pygame.draw.circle: + + # pygame.draw.circle(Surface, color, pos, radius, width=0): return Rect + # draw a circle around a point + + self.assert_(test_not_implemented()) + + def test_ellipse(self): + + # __doc__ (as of 2008-06-25) for pygame.draw.ellipse: + + # pygame.draw.ellipse(Surface, color, Rect, width=0): return Rect + # draw a round shape inside a rectangle + + self.assert_(test_not_implemented()) + + def test_lines(self): + + # __doc__ (as of 2008-06-25) for pygame.draw.lines: + + # pygame.draw.lines(Surface, color, closed, pointlist, width=1): return Rect + # draw multiple contiguous line segments + + self.assert_(test_not_implemented()) + + def test_polygon(self): + # __doc__ (as of 2008-06-25) for pygame.draw.polygon: + + # pygame.draw.polygon(Surface, color, pointlist, width=0): return Rect + # draw a shape with any number of sides + + self.assert_(test_not_implemented()) + +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/draw_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/draw_test.pyc differ diff -Nru pygame-1.8.0release/test/event_test.py pygame-1.8.1release/test/event_test.py --- pygame-1.8.0release/test/event_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/event_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,151 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class EventTypeTest(unittest.TestCase): + def test_Event(self): + + # __doc__ (as of 2008-06-25) for pygame.event.Event: + + # pygame.event.Event(type, dict): return Event + # pygame.event.Event(type, **attributes): return Event + # create a new event object + + self.assert_(test_not_implemented()) + +class EventModuleTest(unittest.TestCase): + def test_clear(self): + + # __doc__ (as of 2008-06-25) for pygame.event.clear: + + # pygame.event.clear(): return None + # pygame.event.clear(type): return None + # pygame.event.clear(typelist): return None + # remove all events from the queue + + self.assert_(test_not_implemented()) + + def test_event_name(self): + + # __doc__ (as of 2008-06-25) for pygame.event.event_name: + + # pygame.event.event_name(type): return string + # get the string name from and event id + + self.assert_(test_not_implemented()) + + def test_get(self): + + # __doc__ (as of 2008-06-25) for pygame.event.get: + + # pygame.event.get(): return Eventlist + # pygame.event.get(type): return Eventlist + # pygame.event.get(typelist): return Eventlist + # get events from the queue + + self.assert_(test_not_implemented()) + + def test_get_blocked(self): + + # __doc__ (as of 2008-06-25) for pygame.event.get_blocked: + + # pygame.event.get_blocked(type): return bool + # test if a type of event is blocked from the queue + + self.assert_(test_not_implemented()) + + def test_get_grab(self): + + # __doc__ (as of 2008-06-25) for pygame.event.get_grab: + + # pygame.event.get_grab(): return bool + # test if the program is sharing input devices + + self.assert_(test_not_implemented()) + + def test_peek(self): + + # __doc__ (as of 2008-06-25) for pygame.event.peek: + + # pygame.event.peek(type): return bool + # pygame.event.peek(typelist): return bool + # test if event types are waiting on the queue + + self.assert_(test_not_implemented()) + + def test_poll(self): + + # __doc__ (as of 2008-06-25) for pygame.event.poll: + + # pygame.event.poll(): return Event + # get a single event from the queue + + self.assert_(test_not_implemented()) + + def test_post(self): + + # __doc__ (as of 2008-06-25) for pygame.event.post: + + # pygame.event.post(Event): return None + # place a new event on the queue + + self.assert_(test_not_implemented()) + + def test_pump(self): + + # __doc__ (as of 2008-06-25) for pygame.event.pump: + + # pygame.event.pump(): return None + # internally process pygame event handlers + + self.assert_(test_not_implemented()) + + def test_set_allowed(self): + + # __doc__ (as of 2008-06-25) for pygame.event.set_allowed: + + # pygame.event.set_allowed(type): return None + # pygame.event.set_allowed(typelist): return None + # pygame.event.set_allowed(None): return None + # control which events are allowed on the queue + + self.assert_(test_not_implemented()) + + def test_set_blocked(self): + + # __doc__ (as of 2008-06-25) for pygame.event.set_blocked: + + # pygame.event.set_blocked(type): return None + # pygame.event.set_blocked(typelist): return None + # pygame.event.set_blocked(None): return None + # control which events are allowed on the queue + + self.assert_(test_not_implemented()) + + def test_set_grab(self): + + # __doc__ (as of 2008-06-25) for pygame.event.set_grab: + + # pygame.event.set_grab(bool): return None + # control the sharing of input devices with other applications + + self.assert_(test_not_implemented()) + + def test_wait(self): + + # __doc__ (as of 2008-06-25) for pygame.event.wait: + + # pygame.event.wait(): return Event + # wait for a single event from the queue + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/event_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/event_test.pyc differ diff -Nru pygame-1.8.0release/test/fastevent_test.py pygame-1.8.1release/test/fastevent_test.py --- pygame-1.8.0release/test/fastevent_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/fastevent_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,101 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class FasteventModuleTest(unittest.TestCase): + def test_get(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.get: + + # pygame.fastevent.get() -> list of Events + # get all events from the queue + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.init: + + # pygame.fastevent.init() -> None + # initialize pygame.fastevent. + + self.assert_(test_not_implemented()) + + def test_poll(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.poll: + + # pygame.fastevent.poll() -> Event + # get an available event + # + # Returns next event on queue. If there is no event waiting on the + # queue, this will return an event with type NOEVENT. + + self.assert_(test_not_implemented()) + + def test_post(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.post: + + # pygame.fastevent.post(Event) -> None + # place an event on the queue + # + # This will post your own event objects onto the event queue. + # You can past any event type you want, but some care must be + # taken. For example, if you post a MOUSEBUTTONDOWN event to the + # queue, it is likely any code receiving the event will expect + # the standard MOUSEBUTTONDOWN attributes to be available, like + # 'pos' and 'button'. + # + # Because pygame.fastevent.post() may have to wait for the queue + # to empty, you can get into a dead lock if you try to append an + # event on to a full queue from the thread that processes events. + # For that reason I do not recommend using this function in the + # main thread of an SDL program. + + self.assert_(test_not_implemented()) + + def test_pump(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.pump: + + # pygame.fastevent.pump() -> None + # update the internal messages + # + # For each frame of your game, you will need to make some sort + # of call to the event queue. This ensures your program can internally + # interact with the rest of the operating system. If you are not using + # other event functions in your game, you should call pump() to allow + # pygame to handle internal actions. + # + # There are important things that must be dealt with internally in the + # event queue. The main window may need to be repainted. Certain joysticks + # must be polled for their values. If you fail to make a call to the event + # queue for too long, the system may decide your program has locked up. + + self.assert_(test_not_implemented()) + + def test_wait(self): + + # __doc__ (as of 2008-06-25) for pygame.fastevent.wait: + + # pygame.fastevent.wait() -> Event + # wait for an event + # + # Returns the current event on the queue. If there are no messages + # waiting on the queue, this will not return until one is + # available. Sometimes it is important to use this wait to get + # events from the queue, it will allow your application to idle + # when the user isn't doing anything with it. + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/fastevent_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/fastevent_test.pyc differ diff -Nru pygame-1.8.0release/test/font_test.py pygame-1.8.1release/test/font_test.py --- pygame-1.8.0release/test/font_test.py 2007-09-01 01:22:30.000000000 -0400 +++ pygame-1.8.1release/test/font_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,27 +1,237 @@ -import unittest -import pygame - -class FontTest( unittest.TestCase ): - def testFontRendering( self ): - """ - """ - return - print __file__ - #pygame.font.init () - f = pygame.font.Font(None, 20) - s = f.render("foo", True, [0, 0, 0], [255, 255, 255]) - s = f.render("xxx", True, [0, 0, 0], [255, 255, 255]) - s = f.render("", True, [0, 0, 0], [255, 255, 255]) - s = f.render("foo", False, [0, 0, 0], [255, 255, 255]) - s = f.render("xxx", False, [0, 0, 0], [255, 255, 255]) - s = f.render("xxx", False, [0, 0, 0]) - s = f.render(" ", False, [0, 0, 0]) - s = f.render(" ", False, [0, 0, 0], [255, 255, 255]) - # null text should be 1 pixel wide. - s = f.render("", False, [0, 0, 0], [255, 255, 255]) - self.assertEqual(s.get_size()[0], 1) - print "fonttest done" - #pygame.font.quit () - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented + +import pygame + +class FontModuleTest( unittest.TestCase ): + def testFontRendering( self ): + """ + """ + #print __file__ + pygame.font.init () + f = pygame.font.Font(None, 20) + s = f.render("foo", True, [0, 0, 0], [255, 255, 255]) + s = f.render("xxx", True, [0, 0, 0], [255, 255, 255]) + s = f.render("", True, [0, 0, 0], [255, 255, 255]) + s = f.render("foo", False, [0, 0, 0], [255, 255, 255]) + s = f.render("xxx", False, [0, 0, 0], [255, 255, 255]) + s = f.render("xxx", False, [0, 0, 0]) + s = f.render(" ", False, [0, 0, 0]) + s = f.render(" ", False, [0, 0, 0], [255, 255, 255]) + # null text should be 1 pixel wide. + s = f.render("", False, [0, 0, 0], [255, 255, 255]) + self.assertEqual(s.get_size()[0], 1) + #print "fonttest done" + #pygame.font.quit () + + def test_SysFont(self): + + # __doc__ (as of 2008-06-25) for pygame.font.SysFont: + + # 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. + + self.assert_(test_not_implemented()) + + def test_get_default_font(self): + + # __doc__ (as of 2008-06-25) for pygame.font.get_default_font: + + # pygame.font.get_default_font(): return string + # get the filename of the default font + + self.assert_(test_not_implemented()) + + def test_get_fonts(self): + + # __doc__ (as of 2008-06-25) for pygame.font.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. + + self.assert_(test_not_implemented()) + + def test_get_init(self): + + # __doc__ (as of 2008-06-25) for pygame.font.get_init: + + # pygame.font.get_init(): return bool + # true if the font module is initialized + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-25) for pygame.font.init: + + # pygame.font.init(): return None + # initialize the font module + + self.assert_(test_not_implemented()) + + def test_match_font(self): + + # __doc__ (as of 2008-06-25) for pygame.font.match_font: + + # 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. + + self.assert_(test_not_implemented()) + + def test_quit(self): + + # __doc__ (as of 2008-06-25) for pygame.font.quit: + + # pygame.font.quit(): return None + # uninitialize the font module + + self.assert_(test_not_implemented()) + +class FontTypeTest( unittest.TestCase ): + def test_get_ascent(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_ascent: + + # Font.get_ascent(): return int + # get the ascent of the font + + self.assert_(test_not_implemented()) + + def test_get_bold(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_bold: + + # Font.get_bold(): return bool + # check if text will be rendered bold + + self.assert_(test_not_implemented()) + + def test_get_descent(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_descent: + + # Font.get_descent(): return int + # get the descent of the font + + self.assert_(test_not_implemented()) + + def test_get_height(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_height: + + # Font.get_height(): return int + # get the height of the font + + self.assert_(test_not_implemented()) + + def test_get_italic(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_italic: + + # Font.get_italic(): return bool + # check if the text will be rendered italic + + self.assert_(test_not_implemented()) + + def test_get_linesize(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_linesize: + + # Font.get_linesize(): return int + # get the line space of the font text + + self.assert_(test_not_implemented()) + + def test_get_underline(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.get_underline: + + # Font.get_underline(): return bool + # check if text will be rendered with an underline + + self.assert_(test_not_implemented()) + + def test_metrics(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.metrics: + + # Font.metrics(text): return list + # Gets the metrics for each character in the pased string. + + self.assert_(test_not_implemented()) + + def test_render(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.render: + + # Font.render(text, antialias, color, background=None): return Surface + # draw text on a new Surface + + self.assert_(test_not_implemented()) + + def test_set_bold(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.set_bold: + + # Font.set_bold(bool): return None + # enable fake rendering of bold text + + self.assert_(test_not_implemented()) + + def test_set_italic(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.set_italic: + + # Font.set_bold(bool): return None + # enable fake rendering of italic text + + self.assert_(test_not_implemented()) + + def test_set_underline(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.set_underline: + + # Font.set_underline(bool): return None + # control if text is rendered with an underline + + self.assert_(test_not_implemented()) + + def test_size(self): + + # __doc__ (as of 2008-06-25) for pygame.font.Font.size: + + # Font.size(text): return (width, height) + # determine the amount of space needed to render text + + self.assert_(test_not_implemented()) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/font_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/font_test.pyc differ diff -Nru pygame-1.8.0release/test/image__save_gl_surface_test.py pygame-1.8.1release/test/image__save_gl_surface_test.py --- pygame-1.8.0release/test/image__save_gl_surface_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/image__save_gl_surface_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,41 @@ +import test_utils +import test.unittest as unittest + +import pygame, os +from pygame.locals import * + +class GL_ImageSave(unittest.TestCase): + def test_image_save_works_with_opengl_surfaces(self): + "|tags:display,slow|" + + pygame.display.init() + + + screen = pygame.display.set_mode((640,480), OPENGL|DOUBLEBUF) + + pygame.display.flip() + + tmp_dir = test_utils.get_tmp_dir() + # Try the imageext module. + tmp_file = os.path.join(tmp_dir, "opengl_save_surface_test.png") + + pygame.image.save(screen, tmp_file) + + self.assert_(os.path.exists(tmp_file)) + + os.remove(tmp_file) + + # Only test the image module. + tmp_file = os.path.join(tmp_dir, "opengl_save_surface_test.bmp") + + pygame.image.save(screen, tmp_file) + + self.assert_(os.path.exists(tmp_file)) + + os.remove(tmp_file) + # os.rmdir(tmp_dir) + + + pygame.display.quit() +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/image__save_gl_surface_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/image__save_gl_surface_test.pyc differ diff -Nru pygame-1.8.0release/test/image_test.py pygame-1.8.1release/test/image_test.py --- pygame-1.8.0release/test/image_test.py 2007-09-01 01:21:52.000000000 -0400 +++ pygame-1.8.1release/test/image_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,15 +1,29 @@ +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented - -import unittest import pygame, pygame.image, pygame.pkgdata import os import array - -class ImageTest( unittest.TestCase ): +def test_magic(f, magic_hex): + """ tests a given file to see if the magic hex matches. + """ + data = f.read(len(magic_hex)) + + if len(data) != len(magic_hex): + return 0 + + for i in range(len(magic_hex)): + if magic_hex[i] != ord(data[i]): + return 0 + return 1 + + +class ImageModuleTest( unittest.TestCase ): def testLoadIcon(self): """ see if we can load the pygame icon. """ @@ -22,7 +36,6 @@ self.assertEqual(surf.get_height(),32) self.assertEqual(surf.get_width(),32) - def testLoadPNG(self): """ see if we can load a png. """ @@ -44,6 +57,43 @@ surf = pygame.image.load(open(os.path.join("examples", "data", "alien1.jpg"), "rb")) + + def test_save(self): + + s = pygame.Surface((10,10)) + s.fill((23,23,23)) + magic_hex = {} + magic_hex['jpg'] = [0xff, 0xd8, 0xff, 0xe0] + magic_hex['png'] = [0x89 ,0x50 ,0x4e ,0x47] + magic_hex['tga'] = [0x0, 0x0, 0xa] + magic_hex['bmp'] = [0x42, 0x4d] + + + formats = ["jpg", "png", "tga", "bmp"] + # uppercase too... JPG + formats = formats + map(lambda x:x.upper(), formats) + + for fmt in formats: + try: + temp_filename = "%s.%s" % ("tmpimg", fmt) + pygame.image.save(s, temp_filename) + # test the magic numbers at the start of the file to ensure they are saved + # as the correct file type. + self.assertEqual((1, fmt), (test_magic(open(temp_filename, "rb"), magic_hex[fmt.lower()]), fmt)) + # load the file to make sure it was saved correctly. + # Note load can load a jpg saved with a .png file name. + s2 = pygame.image.load(temp_filename) + #compare contents, might only work reliably for png... + # but because it's all one color it seems to work with jpg. + self.assertEquals(s2.get_at((0,0)), s.get_at((0,0))) + finally: + #clean up the temp file, comment out to leave tmp file after run. + os.remove(temp_filename) + pass + + + + def assertPremultipliedAreEqual(self, string1, string2, source_string): self.assertEqual(len(string1), len(string2)) block_size = 20 @@ -89,7 +139,7 @@ self.assertRaises(ValueError, pygame.image.tostring, no_alpha_surface, "RGBA_PREMULT") - def test_from_to_string(self): + def test_fromstring__and_tostring(self): """ see if fromstring, and tostring methods are symmetric. """ @@ -165,10 +215,52 @@ self.assert_(AreSurfacesIdentical(test_surface, test_to_from_argb_string)) #"ERROR: image.fromstring and image.tostring with ARGB are not symmetric" + + test_tostring = test_fromstring__and_tostring # for gen_stubs.py + + def test_frombuffer(self): + + # __doc__ (as of 2008-06-25) for pygame.image.frombuffer: + + # pygame.image.frombuffer(string, size, format): return Surface + # create a new Surface that shares data inside a string buffer + + self.assert_(test_not_implemented()) + + def test_get_extended(self): + + # __doc__ (as of 2008-06-25) for pygame.image.get_extended: + + # pygame.image.get_extended(): return bool + # test if extended image formats can be loaded + + self.assert_(test_not_implemented()) + + def test_load_basic(self): + + # __doc__ (as of 2008-06-25) for pygame.image.load_basic: + + # pygame.image.load(filename): return Surface + # pygame.image.load(fileobj, namehint=): return Surface + # load new image from a file + + self.assert_(test_not_implemented()) + + def test_load_extended(self): + + # __doc__ (as of 2008-06-25) for pygame.image.load_extended: + + # pygame module for image transfer + + self.assert_(test_not_implemented()) + def test_save_extended(self): + # __doc__ (as of 2008-06-25) for pygame.image.save_extended: + # pygame module for image transfer + self.assert_(test_not_implemented()) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/image_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/image_test.pyc differ Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/__init__.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/__init__.pyc differ diff -Nru pygame-1.8.0release/test/joystick_test.py pygame-1.8.1release/test/joystick_test.py --- pygame-1.8.0release/test/joystick_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/joystick_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,59 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class JoystickTypeTest(unittest.TestCase): + def test_Joystick(self): + # __doc__ (as of 2008-06-25) for pygame.joystick.Joystick: + + # pygame.joystick.Joystick(id): return Joystick + # create a new Joystick object + + self.assert_(test_not_implemented()) + +class JoytickModuleTest(unittest.TestCase): + def test_get_count(self): + + # __doc__ (as of 2008-06-25) for pygame.joystick.get_count: + + # pygame.joystick.get_count(): return count + # number of joysticks on the system + + self.assert_(test_not_implemented()) + + def test_get_init(self): + + # __doc__ (as of 2008-06-25) for pygame.joystick.get_init: + + # pygame.joystick.get_init(): return bool + # true if the joystick module is initialized + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-25) for pygame.joystick.init: + + # pygame.joystick.init(): return None + # initialize the joystick module + + self.assert_(test_not_implemented()) + + def test_quit(self): + + # __doc__ (as of 2008-06-25) for pygame.joystick.quit: + + # pygame.joystick.quit(): return None + # uninitialize the joystick module + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/joystick_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/joystick_test.pyc differ diff -Nru pygame-1.8.0release/test/key_test.py pygame-1.8.1release/test/key_test.py --- pygame-1.8.0release/test/key_test.py 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/test/key_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,25 +1,70 @@ -import unittest -import pygame -import pygame.display - - -class KeyTest (unittest.TestCase): - - def test_import(self): - 'does it import' - import pygame.key - - def test_get_repeat(self): - pass - # the line below won't work because you need a window - #delay, interval = pygame.key.get_repeat() - - def test_add_more_tests(self): - 'we need to add more tests' - pass - #raise NotImplementedError("TODO: key tests need improving.") - - - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest +import os + +from test_utils import test_not_implemented + +import pygame + +class KeyModuleTest(unittest.TestCase): + def test_import(self): + 'does it import' + import pygame.key + + def test_get_focused(self): + # __doc__ (as of 2008-06-25) for pygame.key.get_focused: + + # pygame.key.get_focused(): return bool + # true if the display is receiving keyboard input from the system + + self.assert_(test_not_implemented()) + + def test_get_mods(self): + + # __doc__ (as of 2008-06-25) for pygame.key.get_mods: + + # pygame.key.get_mods(): return int + # determine which modifier keys are being held + + self.assert_(test_not_implemented()) + + def test_get_pressed(self): + + # __doc__ (as of 2008-06-25) for pygame.key.get_pressed: + + # pygame.key.get_pressed(): return bools + # get the state of all keyboard buttons + + self.assert_(test_not_implemented()) + + def test_name(self): + + # __doc__ (as of 2008-06-25) for pygame.key.name: + + # pygame.key.name(key): return string + # get the name of a key identifier + + self.assert_(test_not_implemented()) + + def test_set_mods(self): + + # __doc__ (as of 2008-06-25) for pygame.key.set_mods: + + # pygame.key.set_mods(int): return None + # temporarily set which modifier keys are pressed + + self.assert_(test_not_implemented()) + + def test_set_repeat(self): + + # __doc__ (as of 2008-06-25) for pygame.key.set_repeat: + + # pygame.key.set_repeat(): return None + # pygame.key.set_repeat(delay, interval): return None + # control how held keys are repeated + + self.assert_(test_not_implemented()) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/key_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/key_test.pyc differ diff -Nru pygame-1.8.0release/test/mask_test.py pygame-1.8.1release/test/mask_test.py --- pygame-1.8.0release/test/mask_test.py 2008-03-03 05:49:22.000000000 -0500 +++ pygame-1.8.1release/test/mask_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,5 +1,8 @@ +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented -import unittest import pygame import pygame.mask @@ -23,9 +26,23 @@ #pygame.init() #pygame.display.set_mode((10,10)) - -class MaskTest( unittest.TestCase ): +class MaskTypeTest( unittest.TestCase ): + # get_at + # get_size + # overlap_area + # get_bounding_rects + # overlap + # set_at + + def test_Mask(self): + + # __doc__ (as of 2008-06-25) for pygame.mask.Mask: + + # pygame.Mask((width, height): return Mask + # pygame object for representing 2d bitmasks + self.assert_(test_not_implemented()) + def test_mask_access( self ): """ do the set_at, and get_at parts work correctly? """ @@ -40,17 +57,130 @@ #self.assertEqual(s.get_at((1,0)), (0, 0, 1, 255)) #s.set_at((-1,0), (0, 0, 1, 255)) - - # out of bounds, should get IndexError self.assertRaises(IndexError, lambda : m.get_at((-1,0)) ) self.assertRaises(IndexError, lambda : m.set_at((-1,0), 1) ) self.assertRaises(IndexError, lambda : m.set_at((10,0), 1) ) self.assertRaises(IndexError, lambda : m.set_at((0,10), 1) ) + def test_get_bounding_rects(self): + """ + """ + + m = pygame.Mask((10,10)) + m.set_at((0,0), 1) + m.set_at((1,0), 1) + + m.set_at((0,1), 1) + + m.set_at((0,3), 1) + m.set_at((3,3), 1) + + r = m.get_bounding_rects() + + self.assertEquals(repr(r), "[, , ]") + + + + + + #1100 + #1111 + m = pygame.Mask((4,2)) + m.set_at((0,0), 1) + m.set_at((1,0), 1) + m.set_at((2,0), 0) + m.set_at((3,0), 0) + + m.set_at((0,1), 1) + m.set_at((1,1), 1) + m.set_at((2,1), 1) + m.set_at((3,1), 1) + + r = m.get_bounding_rects() + self.assertEquals(repr(r), "[]") + + + #00100 + #01110 + #00100 + m = pygame.Mask((5,3)) + m.set_at((0,0), 0) + m.set_at((1,0), 0) + m.set_at((2,0), 1) + m.set_at((3,0), 0) + m.set_at((4,0), 0) + + m.set_at((0,1), 0) + m.set_at((1,1), 1) + m.set_at((2,1), 1) + m.set_at((3,1), 1) + m.set_at((4,1), 0) + + m.set_at((0,2), 0) + m.set_at((1,2), 0) + m.set_at((2,2), 1) + m.set_at((3,2), 0) + m.set_at((4,2), 0) + + r = m.get_bounding_rects() + self.assertEquals(repr(r), "[]") + - def test_mask_from_surface(self): + #00010 + #00100 + #01000 + m = pygame.Mask((5,3)) + m.set_at((0,0), 0) + m.set_at((1,0), 0) + m.set_at((2,0), 0) + m.set_at((3,0), 1) + m.set_at((4,0), 0) + + m.set_at((0,1), 0) + m.set_at((1,1), 0) + m.set_at((2,1), 1) + m.set_at((3,1), 0) + m.set_at((4,1), 0) + + m.set_at((0,2), 0) + m.set_at((1,2), 1) + m.set_at((2,2), 0) + m.set_at((3,2), 0) + m.set_at((4,2), 0) + + r = m.get_bounding_rects() + self.assertEquals(repr(r), "[]") + + + + + #00011 + #11111 + m = pygame.Mask((5,2)) + m.set_at((0,0), 0) + m.set_at((1,0), 0) + m.set_at((2,0), 0) + m.set_at((3,0), 1) + m.set_at((4,0), 1) + + m.set_at((0,1), 1) + m.set_at((1,1), 1) + m.set_at((2,1), 1) + m.set_at((3,1), 1) + m.set_at((3,1), 1) + + r = m.get_bounding_rects() + #TODO: this should really make one bounding rect. + #self.assertEquals(repr(r), "[]") + + + + + +class MaskModuleTest(unittest.TestCase): + def test_from_surface(self): """ Does the mask.from_surface() work correctly? """ @@ -84,35 +214,11 @@ #TODO: test a color key surface. - - - def test_get_bounding_rects(self): - """ - """ - - m = pygame.Mask((10,10)) - m.set_at((0,0), 1) - m.set_at((1,0), 1) - - m.set_at((0,1), 1) - - m.set_at((0,3), 1) - m.set_at((3,3), 1) - - r = m.get_bounding_rects() - - self.assertEquals(repr(r), "[, , ]") - - - - - if __name__ == '__main__': if 1: unittest.main() else: - mask_from_surface = maskFromSurface surf = pygame.Surface((70,70), SRCALPHA, 32) @@ -122,4 +228,3 @@ print "asdf" print surf - Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/mask_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/mask_test.pyc differ diff -Nru pygame-1.8.0release/test/mixer_music_test.py pygame-1.8.1release/test/mixer_music_test.py --- pygame-1.8.0release/test/mixer_music_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/mixer_music_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,150 @@ +import test_utils +import test.unittest as unittest +import os, pygame +from test_utils import test_not_implemented + +class MixerMusicModuleTest(unittest.TestCase): + def test_load(self): + # __doc__ (as of 2008-07-13) for pygame.mixer_music.load: + + # pygame.mixer.music.load(filename): return None + # Load a music file for playback + + + data_fname = os.path.join('examples', 'data') + pygame.mixer.init() + + formats = ['mp3', 'ogg', 'wav'] + + for f in formats: + musfn = os.path.join(data_fname, 'house_lo.%s' % f) + + pygame.mixer.music.load(musfn) + + #NOTE: TODO: loading from filelikes are disabled... + # because as of writing it only works in SDL_mixer svn. + #pygame.mixer.music.load(open(musfn)) + #musf = open(musfn) + #pygame.mixer.music.load(musf) + pygame.mixer.quit() + + def test_queue(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.queue: + + # pygame.mixer.music.queue(filename): return None + # queue a music file to follow the current + + self.assert_(test_not_implemented()) + + def test_stop(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.stop: + + # pygame.mixer.music.stop(): return None + # stop the music playback + + self.assert_(test_not_implemented()) + + def test_rewind(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.rewind: + + # pygame.mixer.music.rewind(): return None + # restart music + + self.assert_(test_not_implemented()) + + def test_get_pos(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.get_pos: + + # pygame.mixer.music.get_pos(): return time + # get the music play time + + self.assert_(test_not_implemented()) + + def test_fadeout(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.fadeout: + + # pygame.mixer.music.fadeout(time): return None + # stop music playback after fading out + + self.assert_(test_not_implemented()) + + def test_play(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.play: + + # pygame.mixer.music.play(loops=0, start=0.0): return None + # Start the playback of the music stream + + self.assert_(test_not_implemented()) + + def test_get_volume(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.get_volume: + + # pygame.mixer.music.get_volume(): return value + # get the music volume + + self.assert_(test_not_implemented()) + + def test_set_endevent(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.set_endevent: + + # pygame.mixer.music.set_endevent(): return None + # pygame.mixer.music.set_endevent(type): return None + # have the music send an event when playback stops + + self.assert_(test_not_implemented()) + + def test_pause(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.pause: + + # pygame.mixer.music.pause(): return None + # temporarily stop music playback + + self.assert_(test_not_implemented()) + + def test_get_busy(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.get_busy: + + # pygame.mixer.music.get_busy(): return bool + # check if the music stream is playing + + self.assert_(test_not_implemented()) + + def test_get_endevent(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.get_endevent: + + # pygame.mixer.music.get_endevent(): return type + # get the event a channel sends when playback stops + + self.assert_(test_not_implemented()) + + def test_unpause(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.unpause: + + # pygame.mixer.music.unpause(): return None + # resume paused music + + self.assert_(test_not_implemented()) + + def test_set_volume(self): + + # __doc__ (as of 2008-07-13) for pygame.mixer_music.set_volume: + + # pygame.mixer.music.set_volume(value): return None + # set the music volume + + self.assert_(test_not_implemented()) + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/mixer_music_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/mixer_music_test.pyc differ diff -Nru pygame-1.8.0release/test/mixer_test.py pygame-1.8.1release/test/mixer_test.py --- pygame-1.8.0release/test/mixer_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/mixer_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,397 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest + +import pygame + +from pygame import mixer +import os + +from test_utils import test_not_implemented + +################################### CONSTANTS ################################## + +FREQUENCIES = [11025, 22050, 44100, 48000] +SIZES = [-16, -8, 8, 16] +CHANNELS = [1, 2] +BUFFERS = [3024] + +############################## MODULE LEVEL TESTS ############################## + +class MixerModuleTest(unittest.TestCase): + # def test_init__keyword_args(self): + # configs = ( {'frequency' : f, 'size' : s, 'channels': c } + # for f in FREQUENCIES + # for s in SIZES + # for c in CHANNELS ) + + # for kw_conf in configs: + # mixer.init(*kw_conf) + + # mixer_conf = mixer.get_init() + + # self.assertEquals( + # mixer_conf, + # (kw_conf['frequency'], kw_conf['size'] , kw_conf['channels']) + # ) + + # mixer.quit() + + # Documentation makes it seem as though init() takes kw args + # TypeError: init() takes no keyword arguments + + def test_get_init__returns_exact_values_used_for_init(self): + return + # fix in 1.9 - I think it's a SDL_mixer bug. + + # TODO: When this bug is fixed, testing through every combination + # will be too slow so adjust as necessary, at the moment it + # breaks the loop after first failure + + configs = [] + for f in FREQUENCIES: + for s in SIZES: + for c in CHANNELS: + configs.append ((f,s,c)) + + print configs + + + for init_conf in configs: + print init_conf + f,s,c = init_conf + if (f,s) == (22050,16):continue + mixer.init(f,s,c) + + mixer_conf = mixer.get_init() + import time + time.sleep(0.1) + + mixer.quit() + time.sleep(0.1) + + if init_conf != mixer_conf: + continue + self.assertEquals(init_conf, mixer_conf) + + def test_get_init__returns_None_if_mixer_not_initialized(self): + self.assert_(mixer.get_init() is None) + + def test_get_num_channels__defaults_eight_after_init(self): + mixer.init() + + num_channels = mixer.get_num_channels() + + self.assert_(num_channels == 8) + + mixer.quit() + + def test_set_num_channels(self): + mixer.init() + + for i in xrange(1, mixer.get_num_channels() + 1): + mixer.set_num_channels(i) + self.assert_(mixer.get_num_channels() == i) + + mixer.quit() + + def test_quit(self): + """ get_num_channels() Should throw pygame.error if uninitialized + after mixer.quit() """ + + mixer.init() + mixer.quit() + + self.assertRaises ( + pygame.error, mixer.get_num_channels, + ) + + def test_pre_init(self): + + # Doc string for pygame.mixer.pre_init: + + # pygame.mixer.pre_init(frequency=0, size=0, channels=0, buffersize=0): return None + # preset the mixer init arguments + + self.assert_(test_not_implemented()) + + + def test_fadeout(self): + + # Doc string for pygame.mixer.fadeout: + + # pygame.mixer.fadeout(time): return None + # fade out the volume on all sounds before stopping + + self.assert_(test_not_implemented()) + + def test_find_channel(self): + + # Doc string for pygame.mixer.find_channel: + + # pygame.mixer.find_channel(force=False): return Channel + # find an unused channel + + self.assert_(test_not_implemented()) + + def test_get_busy(self): + + # Doc string for pygame.mixer.get_busy: + + # pygame.mixer.get_busy(): return bool + # test if any sound is being mixed + + self.assert_(test_not_implemented()) + + def test_init(self): + + # Doc string for pygame.mixer.init: + + # pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=3072): return None + # initialize the mixer module + + self.assert_(test_not_implemented()) + + def test_pause(self): + + # Doc string for pygame.mixer.pause: + + # pygame.mixer.pause(): return None + # temporarily stop playback of all sound channels + + self.assert_(test_not_implemented()) + + def test_unpause(self): + + # Doc string for pygame.mixer.unpause: + + # pygame.mixer.unpause(): return None + # resume paused playback of sound channels + + self.assert_(test_not_implemented()) + + + def test_set_reserved(self): + + # Doc string for pygame.mixer.set_reserved: + + # pygame.mixer.set_reserved(count): return None + # reserve channels from being automatically used + + self.assert_(test_not_implemented()) + + def test_stop(self): + # Doc string for pygame.mixer.stop: + + # pygame.mixer.stop(): return None + # stop playback of all sound channels + + self.assert_(test_not_implemented()) + +############################## CHANNEL CLASS TESTS ############################# + +class ChannelTypeTest(unittest.TestCase): + + def test_Channel(self): + self.assert_(test_not_implemented()) + + def test_fadeout(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.fadeout: + + # Channel.fadeout(time): return None + # stop playback after fading channel out + + self.assert_(test_not_implemented()) + + def test_get_busy(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.get_busy: + + # Channel.get_busy(): return bool + # check if the channel is active + + self.assert_(test_not_implemented()) + + def test_get_endevent(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.get_endevent: + + # Channel.get_endevent(): return type + # get the event a channel sends when playback stops + + self.assert_(test_not_implemented()) + + def test_get_queue(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.get_queue: + + # Channel.get_queue(): return Sound + # return any Sound that is queued + + self.assert_(test_not_implemented()) + + def test_get_sound(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.get_sound: + + # Channel.get_sound(): return Sound + # get the currently playing Sound + + self.assert_(test_not_implemented()) + + def test_get_volume(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.get_volume: + + # Channel.get_volume(): return value + # get the volume of the playing channel + + self.assert_(test_not_implemented()) + + def test_pause(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.pause: + + # Channel.pause(): return None + # temporarily stop playback of a channel + + self.assert_(test_not_implemented()) + + def test_play(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.play: + + # Channel.play(Sound, loops=0, maxtime=0, fade_ms=0): return None + # play a Sound on a specific Channel + + self.assert_(test_not_implemented()) + + def test_queue(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.queue: + + # Channel.queue(Sound): return None + # queue a Sound object to follow the current + + self.assert_(test_not_implemented()) + + def test_set_endevent(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.set_endevent: + + # Channel.set_endevent(): return None + # Channel.set_endevent(type): return None + # have the channel send an event when playback stops + + self.assert_(test_not_implemented()) + + def test_set_volume(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.set_volume: + + # Channel.set_volume(value): return None + # Channel.set_volume(left, right): return None + # set the volume of a playing channel + + self.assert_(test_not_implemented()) + + def test_stop(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.stop: + + # Channel.stop(): return None + # stop playback on a Channel + + self.assert_(test_not_implemented()) + + def test_unpause(self): + + # __doc__ (as of 2008-07-02) for pygame.mixer.Channel.unpause: + + # Channel.unpause(): return None + # resume pause playback of a channel + + self.assert_(test_not_implemented()) + + +############################### SOUND CLASS TESTS ############################## + +class SoundTypeTest(unittest.TestCase): + def test_fadeout(self): + + # Doc string for pygame.mixer.Sound.fadeout: + + # Sound.fadeout(time): return None + # stop sound playback after fading out + + self.assert_(test_not_implemented()) + + def test_get_buffer(self): + + # Doc string for pygame.mixer.Sound.get_buffer: + + # Sound.get_buffer(): return BufferProxy + # acquires a buffer object for the sameples of the Sound. + + self.assert_(test_not_implemented()) + + def test_get_length(self): + + # Doc string for pygame.mixer.Sound.get_length: + + # Sound.get_length(): return seconds + # get the length of the Sound + + self.assert_(test_not_implemented()) + + def test_get_num_channels(self): + + # Doc string for pygame.mixer.Sound.get_num_channels: + + # Sound.get_num_channels(): return count + # count how many times this Sound is playing + + self.assert_(test_not_implemented()) + + def test_get_volume(self): + + # Doc string for pygame.mixer.Sound.get_volume: + + # Sound.get_volume(): return value + # get the playback volume + + self.assert_(test_not_implemented()) + + def test_play(self): + + # Doc string for pygame.mixer.Sound.play: + + # Sound.play(loops=0, maxtime=0, fade_ms=0): return Channel + # begin sound playback + + self.assert_(test_not_implemented()) + + def test_set_volume(self): + + # Doc string for pygame.mixer.Sound.set_volume: + + # Sound.set_volume(value): return None + # set the playback volume for this Sound + + self.assert_(test_not_implemented()) + + def test_stop(self): + + # Doc string for pygame.mixer.Sound.stop: + + # Sound.stop(): return None + # stop sound playback + + self.assert_(test_not_implemented()) + +##################################### MAIN ##################################### + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/mixer_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/mixer_test.pyc differ diff -Nru pygame-1.8.0release/test/mouse_test.py pygame-1.8.1release/test/mouse_test.py --- pygame-1.8.0release/test/mouse_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/mouse_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,85 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class MouseModuleTest(unittest.TestCase): + def test_get_cursor(self): + # __doc__ (as of 2008-06-25) for pygame.mouse.get_cursor: + + # pygame.mouse.get_cursor(): return (size, hotspot, xormasks, andmasks) + # get the image for the system mouse cursor + + self.assert_(test_not_implemented()) + + def test_get_focused(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.get_focused: + + # pygame.mouse.get_focused(): return bool + # check if the display is receiving mouse input + + self.assert_(test_not_implemented()) + + def test_get_pos(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.get_pos: + + # pygame.mouse.get_pos(): return (x, y) + # get the mouse cursor position + + self.assert_(test_not_implemented()) + + def test_get_pressed(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.get_pressed: + + # pygame.moouse.get_pressed(): return (button1, button2, button3) + # get the state of the mouse buttons + + self.assert_(test_not_implemented()) + + def test_get_rel(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.get_rel: + + # pygame.mouse.get_rel(): return (x, y) + # get the amount of mouse movement + + self.assert_(test_not_implemented()) + + def test_set_cursor(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.set_cursor: + + # pygame.mouse.set_cursor(size, hotspot, xormasks, andmasks): return None + # set the image for the system mouse cursor + + self.assert_(test_not_implemented()) + + def test_set_pos(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.set_pos: + + # pygame.mouse.set_pos([x, y]): return None + # set the mouse cursor position + + self.assert_(test_not_implemented()) + + def test_set_visible(self): + + # __doc__ (as of 2008-06-25) for pygame.mouse.set_visible: + + # pygame.mouse.set_visible(bool): return bool + # hide or show the mouse cursor + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/mouse_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/mouse_test.pyc differ diff -Nru pygame-1.8.0release/test/movie_test.py pygame-1.8.1release/test/movie_test.py --- pygame-1.8.0release/test/movie_test.py 2008-02-13 15:55:26.000000000 -0500 +++ pygame-1.8.1release/test/movie_test.py 2008-07-19 18:43:10.000000000 -0400 @@ -1,23 +1,226 @@ - -import unittest -import pygame, pygame.movie - - -class MovieTest( unittest.TestCase ): - - def test_load_movie( self ): - """ - """ - - - def test_import(self): - 'does it import' - import pygame.movie - - def test_add_more_tests(self): - 'we need to add more tests' - pass - #raise NotImplementedError("TODO: movie tests need improving.") - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest +import os, sys + +from test_utils import test_not_implemented + +import pygame, pygame.movie, time + +from pygame.locals import * + +# TODO fix bugs: checking to avoid segfaults + + + +def within(a,b, error_range): + return abs(a - b) < error_range + +def within_seq(a,b,error_range): + for x,y in zip(a,b): + #print x,y + if not within(x,y,error_range): + return 0 + return 1 + + + +class MovieTypeTest( unittest.TestCase ): + def test_render_frame__off_screen(self): + # __doc__ (as of 2008-06-25) for pygame.movie.Movie: + + # pygame.movie.Movie(filename): return Movie + # pygame.movie.Movie(object): return Movie + # load an mpeg movie file + + # pygame accepts only MPEG program stream containers, + # with MPEG1 video and MPEG2 audio. I found + # that the command + + # mencoder -of mpeg -ovc lavc -oac lavc -lavcopts \ + # acodec=mp2:vcodec=mpeg1video:vbitrate=1000 -o new.mpg old.avi + + # os.environ.update({"SDL_VIDEODRIVER":'windib'}) + + movie_file = test_utils.trunk_relative_path('examples/data/blue.mpg') + + # Need to init display before using it. + self.assertRaises(Exception, (pygame.movie.Movie, movie_file)) + + + pygame.display.init() # Needs to be init + + + movie = pygame.movie.Movie(movie_file) + movie_dimensions = movie.get_size() + screen = pygame.display.set_mode(movie_dimensions) + + self.assertEqual(movie_dimensions, (320, 240)) + + off_screen = pygame.Surface(movie_dimensions).convert() + + movie.set_display(off_screen) + frame_number = movie.render_frame(5) + + #self.assertEqual(off_screen.get_at((10,10)), (16, 16, 255, 255)) + #self.assert_(off_screen.get_at((10,10)) in [(16, 16, 255, 255), (18, 13, 238, 255)]) + self.assert_(within_seq( off_screen.get_at((10,10)), (16, 16, 255, 255), 20 )) + + pygame.display.quit() + + def dont_test_render_frame__on_screen(self): + + pygame.display.init() # Needs to be init or will segfault + + movie_file = test_utils.trunk_relative_path('examples/data/blue.mpg') + movie = pygame.movie.Movie(movie_file) + movie_dimensions = movie.get_size() + + self.assertEqual(movie_dimensions, (320, 240)) + + screen = pygame.display.set_mode(movie_dimensions) + movie.set_display(screen) + movie.render_frame(5) + + #self.assertEqual(screen.get_at((10,10)), (16, 16, 255, 255)) + #self.assert_(screen.get_at((10,10)) in [(16, 16, 255, 255), (18, 13, 238, 255)]) + self.assert_(within_seq( screen.get_at((10,10)), (16, 16, 255, 255), 20 )) + + pygame.display.quit() + +# def test_get_busy(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_busy: +# +# # Movie.get_busy(): return bool +# # check if the movie is currently playing +# +# self.assert_(test_not_implemented()) +# +# def test_get_frame(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_frame: +# +# # Movie.get_frame(): return frame_number +# # get the current video frame +# +# self.assert_(test_not_implemented()) +# +# def test_get_length(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_length: +# +# # Movie.get_length(): return seconds +# # the total length of the movie in seconds +# +# self.assert_(test_not_implemented()) +# +# def test_get_size(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_size: +# +# # Movie.get_size(): return (width, height) +# # get the resolution of the video +# +# self.assert_(test_not_implemented()) +# +# def test_get_time(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_time: +# +# # Movie.get_time(): return seconds +# # get the current vide playback time +# +# self.assert_(test_not_implemented()) +# +# def test_has_audio(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.has_audio: +# +# # Movie.get_audio(): return bool +# # check if the movie file contains audio +# +# self.assert_(test_not_implemented()) +# +# def test_has_video(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.has_video: +# +# # Movie.get_video(): return bool +# # check if the movie file contains video +# +# self.assert_(test_not_implemented()) +# +# def test_pause(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.pause: +# +# # Movie.pause(): return None +# # temporarily stop and resume playback +# +# self.assert_(test_not_implemented()) +# +# def test_play(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.play: +# +# # Movie.play(loops=0): return None +# # start playback of a movie +# +# self.assert_(test_not_implemented()) +# +# def test_render_frame(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.render_frame: +# +# # Movie.render_frame(frame_number): return frame_number +# # set the current video frame +# +# self.assert_(test_not_implemented()) +# +# def test_rewind(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.rewind: +# +# # Movie.rewind(): return None +# # restart the movie playback +# +# self.assert_(test_not_implemented()) +# +# def test_set_display(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.set_display: +# +# # Movie.set_display(Surface, rect=None): return None +# # set the video target Surface +# +# self.assert_(test_not_implemented()) +# +# def test_set_volume(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.set_volume: +# +# # Movie.set_volume(value): return None +# # set the audio playback volume +# +# self.assert_(test_not_implemented()) +# +# def test_skip(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.skip: +# +# # Movie.skip(seconds): return None +# # advance the movie playback position +# +# self.assert_(test_not_implemented()) +# +# def test_stop(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.stop: +# +# # Movie.stop(): return None +# # stop movie playback +# +# self.assert_(test_not_implemented()) + +if __name__ == '__main__': + unittest.main() diff -Nru pygame-1.8.0release/test/movie_test.py~ pygame-1.8.1release/test/movie_test.py~ --- pygame-1.8.0release/test/movie_test.py~ 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/movie_test.py~ 2008-07-18 20:55:42.000000000 -0400 @@ -0,0 +1,226 @@ +import test_utils +import test.unittest as unittest +import os, sys + +from test_utils import test_not_implemented + +import pygame, pygame.movie, time + +from pygame.locals import * + +# TODO fix bugs: checking to avoid segfaults + + + +def within(a,b, error_range): + return abs(a - b) < error_range + +def within_seq(a,b,error_range): + for x,y in zip(a,b): + #print x,y + if not within(x,y,error_range): + return 0 + return 1 + + + +class MovieTypeTest( unittest.TestCase ): + def test_render_frame__off_screen(self): + # __doc__ (as of 2008-06-25) for pygame.movie.Movie: + + # pygame.movie.Movie(filename): return Movie + # pygame.movie.Movie(object): return Movie + # load an mpeg movie file + + # pygame accepts only MPEG program stream containers, + # with MPEG1 video and MPEG2 audio. I found + # that the command + + # mencoder -of mpeg -ovc lavc -oac lavc -lavcopts \ + # acodec=mp2:vcodec=mpeg1video:vbitrate=1000 -o new.mpg old.avi + + # os.environ.update({"SDL_VIDEODRIVER":'windib'}) + + movie_file = test_utils.trunk_relative_path('examples/data/blue.mpg') + + # Need to init display before using it. + self.assertRaises(Exception, (pygame.movie.Movie, movie_file)) + + + pygame.display.init() # Needs to be init + + + movie = pygame.movie.Movie(movie_file) + movie_dimensions = movie.get_size() + screen = pygame.display.set_mode(movie_dimensions) + + self.assertEqual(movie_dimensions, (320, 240)) + + off_screen = pygame.Surface(movie_dimensions).convert() + + movie.set_display(off_screen) + frame_number = movie.render_frame(5) + + #self.assertEqual(off_screen.get_at((10,10)), (16, 16, 255, 255)) + #self.assert_(off_screen.get_at((10,10)) in [(16, 16, 255, 255), (18, 13, 238, 255)]) + self.assert_(within_seq( off_screen.get_at((10,10)), (16, 16, 255, 255), 20 )) + + pygame.display.quit() + + def test_render_frame__on_screen(self): + + pygame.display.init() # Needs to be init or will segfault + + movie_file = test_utils.trunk_relative_path('examples/data/blue.mpg') + movie = pygame.movie.Movie(movie_file) + movie_dimensions = movie.get_size() + + self.assertEqual(movie_dimensions, (320, 240)) + + screen = pygame.display.set_mode(movie_dimensions) + movie.set_display(screen) + movie.render_frame(5) + + #self.assertEqual(screen.get_at((10,10)), (16, 16, 255, 255)) + #self.assert_(screen.get_at((10,10)) in [(16, 16, 255, 255), (18, 13, 238, 255)]) + self.assert_(within_seq( screen.get_at((10,10)), (16, 16, 255, 255), 20 )) + + pygame.display.quit() + +# def test_get_busy(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_busy: +# +# # Movie.get_busy(): return bool +# # check if the movie is currently playing +# +# self.assert_(test_not_implemented()) +# +# def test_get_frame(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_frame: +# +# # Movie.get_frame(): return frame_number +# # get the current video frame +# +# self.assert_(test_not_implemented()) +# +# def test_get_length(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_length: +# +# # Movie.get_length(): return seconds +# # the total length of the movie in seconds +# +# self.assert_(test_not_implemented()) +# +# def test_get_size(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_size: +# +# # Movie.get_size(): return (width, height) +# # get the resolution of the video +# +# self.assert_(test_not_implemented()) +# +# def test_get_time(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.get_time: +# +# # Movie.get_time(): return seconds +# # get the current vide playback time +# +# self.assert_(test_not_implemented()) +# +# def test_has_audio(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.has_audio: +# +# # Movie.get_audio(): return bool +# # check if the movie file contains audio +# +# self.assert_(test_not_implemented()) +# +# def test_has_video(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.has_video: +# +# # Movie.get_video(): return bool +# # check if the movie file contains video +# +# self.assert_(test_not_implemented()) +# +# def test_pause(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.pause: +# +# # Movie.pause(): return None +# # temporarily stop and resume playback +# +# self.assert_(test_not_implemented()) +# +# def test_play(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.play: +# +# # Movie.play(loops=0): return None +# # start playback of a movie +# +# self.assert_(test_not_implemented()) +# +# def test_render_frame(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.render_frame: +# +# # Movie.render_frame(frame_number): return frame_number +# # set the current video frame +# +# self.assert_(test_not_implemented()) +# +# def test_rewind(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.rewind: +# +# # Movie.rewind(): return None +# # restart the movie playback +# +# self.assert_(test_not_implemented()) +# +# def test_set_display(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.set_display: +# +# # Movie.set_display(Surface, rect=None): return None +# # set the video target Surface +# +# self.assert_(test_not_implemented()) +# +# def test_set_volume(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.set_volume: +# +# # Movie.set_volume(value): return None +# # set the audio playback volume +# +# self.assert_(test_not_implemented()) +# +# def test_skip(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.skip: +# +# # Movie.skip(seconds): return None +# # advance the movie playback position +# +# self.assert_(test_not_implemented()) +# +# def test_stop(self): +# +# # __doc__ (as of 2008-07-18) for pygame.movie.Movie.stop: +# +# # Movie.stop(): return None +# # stop movie playback +# +# self.assert_(test_not_implemented()) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/movie_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/movie_test.pyc differ diff -Nru pygame-1.8.0release/test/overlay_test.py pygame-1.8.1release/test/overlay_test.py --- pygame-1.8.0release/test/overlay_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/overlay_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,42 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class OverlayTypeTest(unittest.TestCase): + def test_display(self): + + # __doc__ (as of 2008-06-25) for pygame.overlay.overlay.display: + + # Overlay.display((y, u, v)): return None + # Overlay.display(): return None + # set the overlay pixel data + + self.assert_(test_not_implemented()) + + def test_get_hardware(self): + + # __doc__ (as of 2008-06-25) for pygame.overlay.overlay.get_hardware: + + # Overlay.get_hardware(rect): return int + # test if the Overlay is hardware accelerated + + self.assert_(test_not_implemented()) + + def test_set_location(self): + + # __doc__ (as of 2008-06-25) for pygame.overlay.overlay.set_location: + + # Overlay.set_location(rect): return None + # control where the overlay is displayed + + self.assert_(test_not_implemented()) + + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/overlay_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/overlay_test.pyc differ diff -Nru pygame-1.8.0release/test/pixelarray_test.py pygame-1.8.1release/test/pixelarray_test.py --- pygame-1.8.0release/test/pixelarray_test.py 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/test/pixelarray_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,7 +1,18 @@ -import unittest +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented + import pygame -class PixelArrayTest (unittest.TestCase): +class PixelArrayTypeTest (unittest.TestCase): + def test_compare(self): + # __doc__ (as of 2008-06-25) for pygame.pixelarray.PixelArray.compare: + + # PixelArray.compare (array, distance=0, weights=(0.299, 0.587, 0.114)): Return PixelArray + # Compares the PixelArray with another one. + + self.assert_(test_not_implemented()) def test_pixel_array (self): for bpp in (8, 16, 24, 32): @@ -26,17 +37,17 @@ val = sf.map_rgb ((0, 0, 255)) ar = pygame.PixelArray (sf) - ar2 = ar[1] + ar2 = ar.__getitem__ (1) self.assertEqual (len(ar2), 8) - self.assertEqual (ar2[0], val) - self.assertEqual (ar2[1], val) - self.assertEqual (ar2[2], val) + self.assertEqual (ar2.__getitem__ (0), val) + self.assertEqual (ar2.__getitem__ (1), val) + self.assertEqual (ar2.__getitem__ (2), val) - ar2 = ar[-1] + ar2 = ar.__getitem__ (-1) self.assertEqual (len(ar2), 8) - self.assertEqual (ar2[0], val) - self.assertEqual (ar2[1], val) - self.assertEqual (ar2[2], val) + self.assertEqual (ar2.__getitem__ (0), val) + self.assertEqual (ar2.__getitem__ (1), val) + self.assertEqual (ar2.__getitem__ (2), val) def test_get_pixel (self): for bpp in (8, 16, 24, 32): @@ -49,16 +60,16 @@ ar = pygame.PixelArray (sf) - ar2 = ar[0][0] + ar2 = ar.__getitem__ (0).__getitem__ (0) self.assertEqual (ar2, sf.map_rgb ((0, 0, 255))) - ar2 = ar[1][0] + ar2 = ar.__getitem__ (1).__getitem__ (0) self.assertEqual (ar2, sf.map_rgb ((0, 0, 11))) - ar2 = ar[-4][1] + ar2 = ar.__getitem__ (-4).__getitem__ (1) self.assertEqual (ar2, sf.map_rgb ((0, 0, 11))) - ar2 = ar[-4][5] + ar2 = ar.__getitem__ (-4).__getitem__ (5) self.assertEqual (ar2, sf.map_rgb ((0, 0, 255))) def test_set_pixel (self): @@ -67,16 +78,16 @@ sf.fill ((0, 0, 0)) ar = pygame.PixelArray (sf) - ar[0][0] = (0, 255, 0) + ar.__getitem__ (0).__setitem__ (0, (0, 255, 0)) self.assertEqual (ar[0][0], sf.map_rgb ((0, 255, 0))) - ar[1][1] = (128, 128, 128) + ar.__getitem__ (1).__setitem__ (1, (128, 128, 128)) self.assertEqual (ar[1][1], sf.map_rgb ((128, 128, 128))) - ar[-1][-1] = (128, 128, 128) + ar.__getitem__(-1).__setitem__ (-1, (128, 128, 128)) self.assertEqual (ar[9][19], sf.map_rgb ((128, 128, 128))) - ar[-2][-2] = (128, 128, 128) + ar.__getitem__ (-2).__setitem__ (-2, (128, 128, 128)) self.assertEqual (ar[8][-2], sf.map_rgb ((128, 128, 128))) def test_set_column (self): @@ -90,32 +101,33 @@ ar2 = pygame.PixelArray (sf2) # Test single value assignment - ar[2] = (128, 128, 128) + ar.__setitem__ (2, (128, 128, 128)) self.assertEqual (ar[2][0], sf.map_rgb ((128, 128, 128))) self.assertEqual (ar[2][1], sf.map_rgb ((128, 128, 128))) - ar[-1] = (0, 255, 255) + ar.__setitem__ (-1, (0, 255, 255)) self.assertEqual (ar[5][0], sf.map_rgb ((0, 255, 255))) self.assertEqual (ar[-1][1], sf.map_rgb ((0, 255, 255))) - ar[-2] = (255, 255, 0) + ar.__setitem__ (-2, (255, 255, 0)) self.assertEqual (ar[4][0], sf.map_rgb ((255, 255, 0))) self.assertEqual (ar[-2][1], sf.map_rgb ((255, 255, 0))) # Test list assignment. - ar[0] = [(255, 255, 255)] * 8 + ar.__setitem__ (0, [(255, 255, 255)] * 8) self.assertEqual (ar[0][0], sf.map_rgb ((255, 255, 255))) self.assertEqual (ar[0][1], sf.map_rgb ((255, 255, 255))) # Test tuple assignment. - ar[1] = ((204, 0, 204), (17, 17, 17), (204, 0, 204), (17, 17, 17), - (204, 0, 204), (17, 17, 17), (204, 0, 204), (17, 17, 17)) + ar.__setitem__ (1, ((204, 0, 204), (17, 17, 17), (204, 0, 204), + (17, 17, 17), (204, 0, 204), (17, 17, 17), + (204, 0, 204), (17, 17, 17))) self.assertEqual (ar[1][0], sf.map_rgb ((204, 0, 204))) self.assertEqual (ar[1][1], sf.map_rgb ((17, 17, 17))) self.assertEqual (ar[1][2], sf.map_rgb ((204, 0, 204))) # Test pixel array assignment. - ar[1] = ar2[3] + ar.__setitem__ (1, ar2.__getitem__ (3)) self.assertEqual (ar[1][0], sf.map_rgb ((0, 255, 255))) self.assertEqual (ar[1][1], sf.map_rgb ((0, 255, 255))) @@ -125,12 +137,12 @@ sf.fill ((0, 0, 0)) ar = pygame.PixelArray (sf) - self.assertEqual (len (ar[0:2]), 2) - self.assertEqual (len (ar[3:7][3]), 20) + self.assertEqual (len (ar.__getslice__ (0, 2)), 2) + self.assertEqual (len (ar.__getslice__ (3, 7)[3]), 20) - self.assertEqual (ar[0:0], None) - self.assertEqual (ar[5:5], None) - self.assertEqual (ar[9:9], None) + self.assertEqual (ar.__getslice__ (0, 0), None) + self.assertEqual (ar.__getslice__ (5, 5), None) + self.assertEqual (ar.__getslice__ (9, 9), None) # Has to resolve to ar[7:8] self.assertEqual (len (ar[-3:-2]), 20) @@ -138,11 +150,11 @@ # Try assignments. # 2D assignment. - ar[2:5] = (255, 255, 255) + ar.__setslice__ (2, 5, (255, 255, 255)) self.assertEqual (ar[3][3], sf.map_rgb ((255, 255, 255))) # 1D assignment - ar[3][3:7] = (10, 10, 10) + ar[3].__setslice__ (3, 7, (10, 10, 10)) self.assertEqual (ar[3][5], sf.map_rgb ((10, 10, 10))) self.assertEqual (ar[3][6], sf.map_rgb ((10, 10, 10))) @@ -179,7 +191,7 @@ # Test single value assignment val = sf.map_rgb ((128, 128, 128)) - ar[0:2] = val + ar.__setslice__ (0, 2, val) self.assertEqual (ar[0][0], val) self.assertEqual (ar[0][1], val) self.assertEqual (ar[1][0], val) @@ -190,17 +202,35 @@ self.assertEqual (ar[3][0], val) self.assertEqual (ar[-2][1], val) - val = sf.map_rgb ((255, 255, 0)) - ar[-3:] = (255, 255, 0) - + val = sf.map_rgb ((255, 255, 255)) + ar[-3:] = (255, 255, 255) self.assertEqual (ar[4][0], val) self.assertEqual (ar[-1][1], val) - # Test list assignment. + # Test list assignment, this is a vertical assignment. val = sf.map_rgb ((0, 255, 0)) - ar[2:4] = [val] * 8 + ar.__setslice__ (2, 4, [val] * 8) self.assertEqual (ar[2][0], val) + self.assertEqual (ar[2][1], val) + self.assertEqual (ar[2][4], val) + self.assertEqual (ar[2][5], val) + self.assertEqual (ar[3][0], val) self.assertEqual (ar[3][1], val) + self.assertEqual (ar[3][4], val) + self.assertEqual (ar[3][5], val) + + # And the horizontal assignment. + val = sf.map_rgb ((255, 0, 0)) + val2 = sf.map_rgb ((128, 0, 255)) + ar.__setslice__ (0, 2, [val, val2]) + self.assertEqual (ar[0][0], val) + self.assertEqual (ar[1][0], val2) + self.assertEqual (ar[0][1], val) + self.assertEqual (ar[1][1], val2) + self.assertEqual (ar[0][4], val) + self.assertEqual (ar[1][4], val2) + self.assertEqual (ar[0][5], val) + self.assertEqual (ar[1][5], val2) # Test pixelarray assignment. ar[:] = (0, 0, 0) @@ -214,116 +244,219 @@ self.assertEqual (ar[0][0], val) self.assertEqual (ar[5][7], val) -## def test_subscript (self): -## for bpp in (32, ):#16, 24, 32): -## sf = pygame.Surface ((6, 8), 0, bpp) -## sf.set_at ((1, 3), (0, 255, 0)) -## sf.set_at ((0, 0), (0, 255, 0)) -## sf.set_at ((4, 4), (0, 255, 0)) -## val = sf.map_rgb ((0, 255, 0)) - -## ar = pygame.PixelArray (sf) - -## # Test single value requests. -## self.assertEqual (ar[1,3], val) -## self.assertEqual (ar[0,0], val) -## self.assertEqual (ar[4,4], val) -## self.assertEqual (ar[1][3], val) -## self.assertEqual (ar[0][0], val) -## self.assertEqual (ar[4][4], val) - -## # Test ellipse working. -## self.assertEqual (len (ar[...,...]), 6) -## self.assertEqual (len (ar[1,...]), 8) -## self.assertEqual (len (ar[...,3]), 6) - -## # Test simple slicing -## self.assertEqual (len (ar[:,:]), 6) -## self.assertEqual (len (ar[:,]), 6) -## self.assertEqual (len (ar[1,:]), 8) -## self.assertEqual (len (ar[:,2]), 6) -## # Empty slices -## self.assertEqual (ar[4:4,], None) -## self.assertEqual (ar[4:4,...], None) -## self.assertEqual (ar[4:4,2:2], None) -## self.assertEqual (ar[4:4,1:4], None) -## self.assertEqual (ar[4:4:2,], None) -## self.assertEqual (ar[4:4:-2,], None) -## self.assertEqual (ar[4:4:1,...], None) -## self.assertEqual (ar[4:4:-1,...], None) -## self.assertEqual (ar[4:4:1,2:2], None) -## self.assertEqual (ar[4:4:-1,1:4], None) -## self.assertEqual (ar[...,4:4], None) -## self.assertEqual (ar[1:4,4:4], None) -## self.assertEqual (ar[...,4:4:1], None) -## self.assertEqual (ar[...,4:4:-1], None) -## self.assertEqual (ar[2:2,4:4:1], None) -## self.assertEqual (ar[1:4,4:4:-1], None) - -## # Test advanced slicing -## ar[0] = 0 -## ar[1] = 1 -## ar[2] = 2 -## ar[3] = 3 -## ar[4] = 4 -## ar[5] = 5 + def test_subscript (self): + # By default we do not need to work with any special __***__ + # methods as map subscripts are the first looked up by the + # object system. + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((6, 8), 0, bpp) + sf.set_at ((1, 3), (0, 255, 0)) + sf.set_at ((0, 0), (0, 255, 0)) + sf.set_at ((4, 4), (0, 255, 0)) + val = sf.map_rgb ((0, 255, 0)) + + ar = pygame.PixelArray (sf) + + # Test single value requests. + self.assertEqual (ar[1,3], val) + self.assertEqual (ar[0,0], val) + self.assertEqual (ar[4,4], val) + self.assertEqual (ar[1][3], val) + self.assertEqual (ar[0][0], val) + self.assertEqual (ar[4][4], val) + + # Test ellipse working. + self.assertEqual (len (ar[...,...]), 6) + self.assertEqual (len (ar[1,...]), 8) + self.assertEqual (len (ar[...,3]), 6) + + # Test simple slicing + self.assertEqual (len (ar[:,:]), 6) + self.assertEqual (len (ar[:,]), 6) + self.assertEqual (len (ar[1,:]), 8) + self.assertEqual (len (ar[:,2]), 6) + # Empty slices + self.assertEqual (ar[4:4,], None) + self.assertEqual (ar[4:4,...], None) + self.assertEqual (ar[4:4,2:2], None) + self.assertEqual (ar[4:4,1:4], None) + self.assertEqual (ar[4:4:2,], None) + self.assertEqual (ar[4:4:-2,], None) + self.assertEqual (ar[4:4:1,...], None) + self.assertEqual (ar[4:4:-1,...], None) + self.assertEqual (ar[4:4:1,2:2], None) + self.assertEqual (ar[4:4:-1,1:4], None) + self.assertEqual (ar[...,4:4], None) + self.assertEqual (ar[1:4,4:4], None) + self.assertEqual (ar[...,4:4:1], None) + self.assertEqual (ar[...,4:4:-1], None) + self.assertEqual (ar[2:2,4:4:1], None) + self.assertEqual (ar[1:4,4:4:-1], None) + + # Test advanced slicing + ar[0] = 0 + ar[1] = 1 + ar[2] = 2 + ar[3] = 3 + ar[4] = 4 + ar[5] = 5 + + # We should receive something like [0,2,4] + self.assertEqual (ar[::2,1][0], 0) + self.assertEqual (ar[::2,1][1], 2) + self.assertEqual (ar[::2,1][2], 4) + # We should receive something like [2,2,2] + self.assertEqual (ar[2,::2][0], 2) + self.assertEqual (ar[2,::2][1], 2) + self.assertEqual (ar[2,::2][2], 2) -## # We should receive something like [0,2,4] -## self.assertEqual (ar[::2,1][0], 0) -## self.assertEqual (ar[::2,1][1], 2) -## self.assertEqual (ar[::2,1][2], 4) -## # We should receive something like [2,2,2] -## self.assertEqual (ar[2,::2][0], 2) -## self.assertEqual (ar[2,::2][1], 2) -## self.assertEqual (ar[2,::2][2], 2) + # Should create a 3x3 array of [0,2,4] + ar2 = ar[::2,::2] + self.assertEqual (len (ar2), 3) + self.assertEqual (ar2[0][0], 0) + self.assertEqual (ar2[0][1], 0) + self.assertEqual (ar2[0][2], 0) + self.assertEqual (ar2[2][0], 4) + self.assertEqual (ar2[2][1], 4) + self.assertEqual (ar2[2][2], 4) + self.assertEqual (ar2[1][0], 2) + self.assertEqual (ar2[2][0], 4) + self.assertEqual (ar2[1][1], 2) + + # Should create a reversed 3x8 array over X of [1,2,3] -> [3,2,1] + ar2 = ar[3:0:-1] + self.assertEqual (len (ar2), 3) + self.assertEqual (ar2[0][0], 3) + self.assertEqual (ar2[0][1], 3) + self.assertEqual (ar2[0][2], 3) + self.assertEqual (ar2[0][7], 3) + self.assertEqual (ar2[2][0], 1) + self.assertEqual (ar2[2][1], 1) + self.assertEqual (ar2[2][2], 1) + self.assertEqual (ar2[2][7], 1) + self.assertEqual (ar2[1][0], 2) + self.assertEqual (ar2[1][1], 2) + # Should completely reverse the array over X -> [5,4,3,2,1,0] + ar2 = ar[::-1] + self.assertEqual (len (ar2), 6) + self.assertEqual (ar2[0][0], 5) + self.assertEqual (ar2[0][1], 5) + self.assertEqual (ar2[0][3], 5) + self.assertEqual (ar2[0][-1], 5) + self.assertEqual (ar2[1][0], 4) + self.assertEqual (ar2[1][1], 4) + self.assertEqual (ar2[1][3], 4) + self.assertEqual (ar2[1][-1], 4) + self.assertEqual (ar2[-1][-1], 0) + self.assertEqual (ar2[-2][-2], 1) + self.assertEqual (ar2[-3][-1], 2) + + # Test advanced slicing + ar[:] = 0 + ar2 = ar[:,1] + ar2[:] = [99] * len(ar2) + self.assertEqual (ar2[0], 99) + self.assertEqual (ar2[-1], 99) + self.assertEqual (ar2[-2], 99) + self.assertEqual (ar2[2], 99) + self.assertEqual (ar[0,1], 99) + self.assertEqual (ar[1,1], 99) + self.assertEqual (ar[2,1], 99) + self.assertEqual (ar[-1,1], 99) + self.assertEqual (ar[-2,1], 99) + + def test_ass_subscript (self): + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((6, 8), 0, bpp) + sf.fill ((255, 255, 255)) + ar = pygame.PixelArray (sf) + + # Test ellipse working + ar[...,...] = (0, 0, 0) + self.assertEqual (ar[0,0], 0) + self.assertEqual (ar[1,0], 0) + self.assertEqual (ar[-1,-1], 0) + ar[...,] = (0, 0, 255) + self.assertEqual (ar[0,0], sf.map_rgb ((0, 0, 255))) + self.assertEqual (ar[1,0], sf.map_rgb ((0, 0, 255))) + self.assertEqual (ar[-1,-1], sf.map_rgb ((0, 0, 255))) + ar[:,...] = (255, 0, 0) + self.assertEqual (ar[0,0], sf.map_rgb ((255, 0, 0))) + self.assertEqual (ar[1,0], sf.map_rgb ((255, 0, 0))) + self.assertEqual (ar[-1,-1], sf.map_rgb ((255, 0, 0))) + + def test_make_surface (self): + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((10, 20), 0, bpp) + sf.fill ((255, 255, 255)) + ar = pygame.PixelArray (sf) + newsf = ar[::2,::2].make_surface () + rect = newsf.get_rect () + self.assertEqual (rect.width, 5) + self.assertEqual (rect.height, 10) + + def test_iter (self): + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((5, 10), 0, bpp) + ar = pygame.PixelArray (sf) + iterations = 0 + for col in ar: + self.assertEqual (len (col), 10) + iterations += 1 + self.assertEqual (iterations, 5) + + def test_replace (self): + #print "replace start" + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((10, 10), 0, bpp) + sf.fill ((255, 0, 0)) + rval = sf.map_rgb ((0, 0, 255)) + oval = sf.map_rgb ((255, 0, 0)) + ar = pygame.PixelArray (sf) + ar[::2].replace ((255, 0, 0), (0, 0, 255)) + self.assertEqual (ar[0][0], rval) + self.assertEqual (ar[1][0], oval) + self.assertEqual (ar[2][3], rval) + self.assertEqual (ar[3][6], oval) + self.assertEqual (ar[8][9], rval) + self.assertEqual (ar[9][9], oval) -## # Should create a 3x3 array of [0,2,4] -## ar2 = ar[::2,::2] -## self.assertEqual (len (ar2), 3) -## self.assertEqual (ar2[0][0], 0) -## self.assertEqual (ar2[0][1], 0) -## self.assertEqual (ar2[0][2], 0) -## self.assertEqual (ar2[2][0], 4) -## self.assertEqual (ar2[2][1], 4) -## self.assertEqual (ar2[2][2], 4) -## self.assertEqual (ar2[1][0], 2) -## self.assertEqual (ar2[2][0], 4) -## self.assertEqual (ar2[1][1], 2) - -## # Should create a reversed 3x8 array over X of [1,2,3] -> [3,2,1] -## ar2 = ar[3:0:-1] -## self.assertEqual (len (ar2), 3) -## self.assertEqual (ar2[0][0], 3) -## self.assertEqual (ar2[0][1], 3) -## self.assertEqual (ar2[0][2], 3) -## self.assertEqual (ar2[0][7], 3) -## self.assertEqual (ar2[2][0], 1) -## self.assertEqual (ar2[2][1], 1) -## self.assertEqual (ar2[2][2], 1) -## self.assertEqual (ar2[2][7], 1) -## self.assertEqual (ar2[1][0], 2) -## self.assertEqual (ar2[1][1], 2) -## # Should completely reverse the array over X -> [5,4,3,2,1,0] -## ar2 = ar[::-1] -## self.assertEqual (len (ar2), 6) -## self.assertEqual (ar2[0][0], 5) -## self.assertEqual (ar2[0][1], 5) -## self.assertEqual (ar2[0][3], 5) -## self.assertEqual (ar2[0][-1], 5) -## self.assertEqual (ar2[1][0], 4) -## self.assertEqual (ar2[1][1], 4) -## self.assertEqual (ar2[1][3], 4) -## self.assertEqual (ar2[1][-1], 4) -## self.assertEqual (ar2[-1][-1], 0) -## self.assertEqual (ar2[-2][-2], 1) -## self.assertEqual (ar2[-3][-1], 2) - -## # Test advanced slicing -## ar[:] = 0 -## print "done" -## ar2 = ar[:,1] -## ar2[:] = 99 -## print ar + ar[::2].replace ((0, 0, 255), (255, 0, 0), weights=(10, 20, 50)) + self.assertEqual (ar[0][0], oval) + self.assertEqual (ar[2][3], oval) + self.assertEqual (ar[3][6], oval) + self.assertEqual (ar[8][9], oval) + self.assertEqual (ar[9][9], oval) + #print "replace end" + + def test_extract (self): + #print "extract start" + for bpp in (8, 16, 24, 32): + sf = pygame.Surface ((10, 10), 0, bpp) + sf.fill ((0, 0, 255)) + sf.fill ((255, 0, 0), (2, 2, 6, 6)) + + white = sf.map_rgb ((255, 255, 255)) + black = sf.map_rgb ((0, 0, 0)) + + ar = pygame.PixelArray (sf) + newar = ar.extract ((255, 0, 0)) + + self.assertEqual (newar[0][0], black) + self.assertEqual (newar[1][0], black) + self.assertEqual (newar[2][3], white) + self.assertEqual (newar[3][6], white) + self.assertEqual (newar[8][9], black) + self.assertEqual (newar[9][9], black) + + newar = ar.extract ((255, 0, 0), weights=(10, 0.1, 50)) + self.assertEqual (newar[0][0], black) + self.assertEqual (newar[1][0], black) + self.assertEqual (newar[2][3], white) + self.assertEqual (newar[3][6], white) + self.assertEqual (newar[8][9], black) + self.assertEqual (newar[9][9], black) + #print "extract end" if __name__ == '__main__': unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/pixelarray_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/pixelarray_test.pyc differ diff -Nru pygame-1.8.0release/test/rect_test.py pygame-1.8.1release/test/rect_test.py --- pygame-1.8.0release/test/rect_test.py 2006-11-04 01:00:18.000000000 -0500 +++ pygame-1.8.1release/test/rect_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,10 +1,11 @@ +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented - -import unittest from pygame import Rect -class RectTest( unittest.TestCase ): +class RectTypeTest( unittest.TestCase ): def testConstructionXYWidthHeight( self ): r = Rect(1,2,3,4) self.assertEqual( 1, r.left ) @@ -41,7 +42,7 @@ self.assertEqual( (r.left,r.centery), r.midleft ) self.assertEqual( (r.right,r.centery), r.midright ) - def testNormalize( self ): + def test_normalize( self ): r = Rect( 1, 2, -3, -6 ) r2 = Rect(r) r2.normalize() @@ -50,7 +51,7 @@ self.assertEqual( (abs(r.width),abs(r.height)), r2.size ) self.assertEqual( (-2,-4), r2.topleft ) - def testSetLeft( self ): + def test_left( self ): """Changing the left attribute moves the rect and does not change the rect's width """ @@ -61,7 +62,7 @@ self.assertEqual( new_left, r.left ) self.assertEqual( Rect(new_left,2,3,4), r ) - def testSetRight( self ): + def test_right( self ): """Changing the right attribute moves the rect and does not change the rect's width """ @@ -75,7 +76,7 @@ self.assertEqual( expected_left, r.left ) self.assertEqual( old_width, r.width ) - def testSetTop( self ): + def test_top( self ): """Changing the top attribute moves the rect and does not change the rect's width """ @@ -86,7 +87,7 @@ self.assertEqual( Rect(1,new_top,3,4), r ) self.assertEqual( new_top, r.top ) - def testSetBottom( self ): + def test_bottom( self ): """Changing the bottom attribute moves the rect and does not change the rect's height """ @@ -100,7 +101,7 @@ self.assertEqual( expected_top, r.top ) self.assertEqual( old_height, r.height ) - def testSetCenterX( self ): + def test_centerx( self ): """Changing the centerx attribute moves the rect and does not change the rect's width """ @@ -114,7 +115,7 @@ self.assertEqual( expected_left, r.left ) self.assertEqual( old_width, r.width ) - def testSetCenterY( self ): + def test_centery( self ): """Changing the centerx attribute moves the rect and does not change the rect's width """ @@ -128,7 +129,7 @@ self.assertEqual( expected_top, r.top ) self.assertEqual( old_height, r.height ) - def testSetTopLeft( self ): + def test_topleft( self ): """Changing the topleft attribute moves the rect and does not change the rect's size """ @@ -140,7 +141,7 @@ self.assertEqual( new_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetBottomLeft( self ): + def test_bottomleft( self ): """Changing the bottomleft attribute moves the rect and does not change the rect's size """ @@ -154,7 +155,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetTopRight( self ): + def test_topright( self ): """Changing the bottomleft attribute moves the rect and does not change the rect's size """ @@ -168,7 +169,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetBottomRight( self ): + def test_bottomright( self ): """Changing the bottomright attribute moves the rect and does not change the rect's size """ @@ -182,7 +183,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetCenter( self ): + def test_center( self ): """Changing the center attribute moves the rect and does not change the rect's size """ @@ -196,7 +197,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetMidLeft( self ): + def test_midleft( self ): """Changing the midleft attribute moves the rect and does not change the rect's size """ @@ -210,7 +211,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetMidRight( self ): + def test_midright( self ): """Changing the midright attribute moves the rect and does not change the rect's size """ @@ -224,7 +225,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetMidTop( self ): + def test_midtop( self ): """Changing the midtop attribute moves the rect and does not change the rect's size """ @@ -238,7 +239,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetMidBottom( self ): + def test_midbottom( self ): """Changing the midbottom attribute moves the rect and does not change the rect's size """ @@ -252,7 +253,7 @@ self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size ) - def testSetWidth( self ): + def test_width( self ): "Changing the width resizes the rect from the top-left corner" r = Rect( 1, 2, 3, 4 ) new_width = 10 @@ -264,7 +265,7 @@ self.assertEqual( old_height, r.height ) self.assertEqual( old_topleft, r.topleft ) - def testSetHeight( self ): + def test_height( self ): "Changing the height resizes the rect from the top-left corner" r = Rect( 1, 2, 3, 4 ) new_height = 10 @@ -276,7 +277,7 @@ self.assertEqual( old_width, r.width ) self.assertEqual( old_topleft, r.topleft ) - def testSetSize( self ): + def test_size( self ): "Changing the size resizes the rect from the top-left corner" r = Rect( 1, 2, 3, 4 ) new_size = (10,20) @@ -286,7 +287,7 @@ self.assertEqual( new_size, r.size ) self.assertEqual( old_topleft, r.topleft ) - def testContains( self ): + def test_contains( self ): r = Rect( 1, 2, 3, 4 ) self.failUnless( r.contains( Rect( 2, 3, 1, 1 ) ), @@ -302,7 +303,7 @@ self.failIf( r.contains( Rect(4,6,0,0) ), "r contains Rect(4,6,0,0)" ) - def testCollidePoint( self ): + def test_collidepoint( self ): r = Rect( 1, 2, 3, 4 ) self.failUnless( r.collidepoint( r.left, r.top ), @@ -323,7 +324,7 @@ self.failIf( r.collidepoint( r.right, r.bottom-1 ), "r collides with point (right,bottom-1)" ) - def testInflateLarger( self ): + def test_inflate__larger( self ): "The inflate method inflates around the center of the rectangle" r = Rect( 2, 4, 6, 8 ) r2 = r.inflate( 4, 6 ) @@ -336,7 +337,7 @@ self.assertEqual( r.width+4, r2.width ) self.assertEqual( r.height+6, r2.height ) - def testInflateSmaller( self ): + def test_inflate__smaller( self ): "The inflate method inflates around the center of the rectangle" r = Rect( 2, 4, 6, 8 ) r2 = r.inflate( -4, -6 ) @@ -349,7 +350,7 @@ self.assertEqual( r.width-4, r2.width ) self.assertEqual( r.height-6, r2.height ) - def testInflateLargerIP( self ): + def test_inflate_ip__larger( self ): "The inflate_ip method inflates around the center of the rectangle" r = Rect( 2, 4, 6, 8 ) r2 = Rect( r ) @@ -363,7 +364,7 @@ self.assertEqual( r.width-4, r2.width ) self.assertEqual( r.height-6, r2.height ) - def testInflateSmallerIP( self ): + def test_inflate_ip__smaller( self ): "The inflate method inflates around the center of the rectangle" r = Rect( 2, 4, 6, 8 ) r2 = Rect( r ) @@ -377,7 +378,7 @@ self.assertEqual( r.width-4, r2.width ) self.assertEqual( r.height-6, r2.height ) - def testClamp( self ): + def test_clamp( self ): r = Rect(10, 10, 10, 10) c = Rect(19, 12, 5, 5).clamp(r) self.assertEqual(c.right, r.right) @@ -387,7 +388,7 @@ c = Rect(5, 500, 22, 33).clamp(r) self.assertEqual(c.center, r.center) - def testClampIP( self ): + def test_clamp_ip( self ): r = Rect(10, 10, 10, 10) c = Rect(19, 12, 5, 5) c.clamp_ip(r) @@ -400,7 +401,7 @@ c.clamp_ip(r) self.assertEqual(c.center, r.center) - def testClip( self ): + def test_clip( self ): r1 = Rect( 1, 2, 3, 4 ) self.assertEqual( Rect( 1, 2, 2, 2 ), r1.clip( Rect(0,0,3,4) ) ) self.assertEqual( Rect( 2, 2, 2, 4 ), r1.clip( Rect(2,2,10,20) ) ) @@ -409,7 +410,7 @@ self.assertEqual( r1, r1.clip( Rect(r1) ), "r1 does not clip an identical rect to itself" ) - def testMove( self ): + def test_move( self ): r = Rect( 1, 2, 3, 4 ) move_x = 10 move_y = 20 @@ -417,7 +418,7 @@ expected_r2 = Rect(r.left+move_x,r.top+move_y,r.width,r.height) self.assertEqual( expected_r2, r2 ) - def testMoveIP( self ): + def test_move_ip( self ): r = Rect( 1, 2, 3, 4 ) r2 = Rect( r ) move_x = 10 @@ -426,22 +427,22 @@ expected_r2 = Rect(r.left+move_x,r.top+move_y,r.width,r.height) self.assertEqual( expected_r2, r2 ) - def testUnion( self ): + def test_union( self ): r1 = Rect( 1, 1, 1, 2 ) r2 = Rect( -2, -2, 1, 2 ) self.assertEqual( Rect( -2, -2, 4, 5 ), r1.union(r2) ) - def testUnionWithIdenticalRect( self ): + def test_union__with_identical_Rect( self ): r1 = Rect( 1, 2, 3, 4 ) self.assertEqual( r1, r1.union( Rect(r1) ) ) - def testUnionIP( self ): + def test_union_ip( self ): r1 = Rect( 1, 1, 1, 2 ) r2 = Rect( -2, -2, 1, 2 ) r1.union_ip(r2) self.assertEqual( Rect( -2, -2, 4, 5 ), r1 ) - def testUnionAll( self ): + def test_unionall( self ): r1 = Rect( 0, 0, 1, 1 ) r2 = Rect( -2, -2, 1, 1 ) r3 = Rect( 2, 2, 1, 1 ) @@ -449,7 +450,7 @@ r4 = r1.unionall( [r2,r3] ) self.assertEqual( Rect(-2, -2, 5, 5), r4 ) - def testUnionAllIP( self ): + def test_unionall_ip( self ): r1 = Rect( 0, 0, 1, 1 ) r2 = Rect( -2, -2, 1, 1 ) r3 = Rect( 2, 2, 1, 1 ) @@ -459,7 +460,7 @@ - def testCollideRect( self ): + def test_colliderect( self ): r1 = Rect(1,2,3,4) self.failUnless( r1.colliderect( Rect(0,0,2,3) ), "r1 does not collide with Rect(0,0,2,3)" ) @@ -482,6 +483,50 @@ self.failIf( r1.colliderect( Rect(r1.right,r1.bottom,1,1) ), "r1 collides with Rect(r1.right,r1.bottom,1,1)" ) + def test_collidedict(self): + + # __doc__ (as of 2008-06-25) for pygame.rect.Rect.collidedict: + + # Rect.collidedict(dict): return (key, value) + # test if one rectangle in a dictionary intersects + + self.assert_(test_not_implemented()) + + def test_collidedictall(self): + + # __doc__ (as of 2008-06-25) for pygame.rect.Rect.collidedictall: + + # Rect.collidedictall(dict): return [(key, value), ...] + # test if all rectangles in a dictionary intersect + + self.assert_(test_not_implemented()) + + def test_collidelist(self): + + # __doc__ (as of 2008-06-25) for pygame.rect.Rect.collidelist: + + # Rect.collidelist(list): return index + # test if one rectangle in a list intersects + + self.assert_(test_not_implemented()) + + def test_collidelistall(self): + + # __doc__ (as of 2008-06-25) for pygame.rect.Rect.collidelistall: + + # Rect.collidelistall(list): return indices + # test if all rectangles in a list intersect + + self.assert_(test_not_implemented()) + + def test_fit(self): + + # __doc__ (as of 2008-06-25) for pygame.rect.Rect.fit: + + # Rect.fit(Rect): return Rect + # resize and move a rectangle with aspect ratio + + self.assert_(test_not_implemented()) def testEquals( self ): """ check to see how the rect uses __eq__ @@ -516,9 +561,5 @@ rect_list.remove(r2) self.assertRaises(ValueError, rect_list.remove, r2) - - - - if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/rect_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/rect_test.pyc differ diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/fake_2_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/fake_3_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/fake_3_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/fake_3_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/fake_3_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/fake_4_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/fake_4_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/fake_4_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/fake_4_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/fake_5_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/fake_5_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/fake_5_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/fake_5_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/fake_6_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/fake_6_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/fake_6_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/fake_6_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/no_assertions(ret_code_of_1)_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/no_assertions(ret_code_of_1)_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/no_assertions(ret_code_of_1)_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/no_assertions(ret_code_of_1)_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + pass + + def test_get_mods(self): + pass + + def test_get_pressed(self): + pass + + def test_name(self): + pass + + def test_set_mods(self): + pass + + def test_set_repeat(self): + pass + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/all_ok/zero_tests_test.py pygame-1.8.1release/test/run_tests__tests/all_ok/zero_tests_test.py --- pygame-1.8.0release/test/run_tests__tests/all_ok/zero_tests_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/all_ok/zero_tests_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,8 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + pass + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/failures1/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/failures1/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/failures1/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/failures1/fake_2_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/failures1/fake_3_test.py pygame-1.8.1release/test/run_tests__tests/failures1/fake_3_test.py --- pygame-1.8.0release/test/run_tests__tests/failures1/fake_3_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/failures1/fake_3_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/failures1/fake_4_test.py pygame-1.8.1release/test/run_tests__tests/failures1/fake_4_test.py --- pygame-1.8.0release/test/run_tests__tests/failures1/fake_4_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/failures1/fake_4_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,26 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(False, "Some Jibberish") + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + if 1: + if 1: + assert False + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/incomplete/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/incomplete/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/incomplete/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/incomplete/fake_2_test.py 2008-07-18 16:52:46.000000000 -0400 @@ -0,0 +1,25 @@ +import test_utils +import test.unittest as unittest +import test_utils + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(test_utils.test_not_implemented()) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(test_utils.test_not_implemented()) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/incomplete/fake_3_test.py pygame-1.8.1release/test/run_tests__tests/incomplete/fake_3_test.py --- pygame-1.8.0release/test/run_tests__tests/incomplete/fake_3_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/incomplete/fake_3_test.py 2008-07-18 16:52:46.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/infinite_loop/fake_1_test.py pygame-1.8.1release/test/run_tests__tests/infinite_loop/fake_1_test.py --- pygame-1.8.0release/test/run_tests__tests/infinite_loop/fake_1_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/infinite_loop/fake_1_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,25 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + while True: + pass + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/infinite_loop/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/infinite_loop/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/infinite_loop/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/infinite_loop/fake_2_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_2_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_3_test.py pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_3_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_3_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_3_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,26 @@ +import test_utils +import test.unittest as unittest +import sys + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + print >> sys.stderr, 'jibberish messes things up' + self.assert_(False) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_4_test.py pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_4_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stderr/fake_4_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stderr/fake_4_test.py 2008-07-18 16:52:47.000000000 -0400 @@ -0,0 +1,26 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(False, "Some Jibberish") + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + if 1: + if 1: + assert False + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_2_test.py pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_2_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_2_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_2_test.py 2008-07-18 16:52:48.000000000 -0400 @@ -0,0 +1,24 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(True) + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_3_test.py pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_3_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_3_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_3_test.py 2008-07-18 16:52:48.000000000 -0400 @@ -0,0 +1,26 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + print 'jibberish ruins everything' + self.assert_(False) + + def test_name(self): + print 'forgot to remove debug crap' + self.assert_(True) + + def test_set_mods(self): + self.assert_(True) + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_4_test.py pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_4_test.py --- pygame-1.8.0release/test/run_tests__tests/print_stdout/fake_4_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/print_stdout/fake_4_test.py 2008-07-18 16:52:48.000000000 -0400 @@ -0,0 +1,26 @@ +import test_utils +import test.unittest as unittest + +class KeyModuleTest(unittest.TestCase): + def test_get_focused(self): + self.assert_(True) + + def test_get_mods(self): + self.assert_(True) + + def test_get_pressed(self): + self.assert_(False, "Some Jibberish") + + def test_name(self): + self.assert_(True) + + def test_set_mods(self): + if 1: + if 1: + assert False + + def test_set_repeat(self): + self.assert_(True) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/run_tests__tests/run_tests__test.py pygame-1.8.1release/test/run_tests__tests/run_tests__test.py --- pygame-1.8.0release/test/run_tests__tests/run_tests__test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/run_tests__tests/run_tests__test.py 2008-07-15 09:42:40.000000000 -0400 @@ -0,0 +1,134 @@ +################################################################################ + +import subprocess, os, sys, re, difflib + +################################################################################ + +IGNORE = ( + '.svn', + 'infinite_loop', +) +NORMALIZERS = ( + (r"Ran (\d+) tests in (\d+\.\d+)s", "Ran \\1 tests in X.XXXs" ), + (r'File ".*?([^/\\.]+\.py)"', 'File "\\1"'), +) + +################################################################################ + +def norm_result(result): + "normalize differences, such as timing between output" + for normalizer, replacement in NORMALIZERS: + if callable(normalizer): + result = normalizer(result) + else: + result = re.sub(normalizer, replacement, result) + + return result + +def call_proc(cmd, cd=None): + proc = subprocess.Popen ( + cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd = cd, + universal_newlines = True, + ) + if proc.wait(): + print cmd, proc.wait() + raise Exception(proc.stdout.read()) + + return proc.stdout.read() + +################################################################################ + +unnormed_diff = '-u' in sys.argv +verbose = '-v' in sys.argv or unnormed_diff +if '-h' in sys.argv or '--help' in sys.argv: sys.exit ( + "\nCOMPARES OUTPUT OF SINGLE VS SUBPROCESS MODE OF RUN_TESTS.PY\n\n" + '-v, to output diffs even on success\n' + '-u, to output diffs of unnormalized tests\n\n' + "Each line of a Differ delta begins with a two-letter code:\n\n" + " '- ' line unique to sequence 1\n" + " '+ ' line unique to sequence 2\n" + " ' ' line common to both sequences\n" + " '? ' line not present in either input sequence\n" +) + +main_dir = os.path.split(os.path.abspath(sys.argv[0]))[0] +trunk_dir = os.path.normpath(os.path.join(main_dir, '../../')) + +test_suite_dirs = [x for x in os.listdir(main_dir) + if os.path.isdir(os.path.join(main_dir, x)) + and x not in IGNORE ] + + +################################################################################ + +def assert_on_results(suite, single, sub): + test = globals().get('%s_test' % suite) + if callable(test): + test(suite, single, sub) + print "assertions on %s OK" % suite + +def incomplete_test(suite, *args): + for results in args: + assert 'self.assert_(test_utils.test_not_implemented())' in results + +# Don't modify tests in suites below. These assertions are in place to make sure +# that tests are actually being ran + +def all_ok_test(uite, *args): + for results in args: + assert "Ran 36 tests" in results # some tests are runing + assert "OK" in results # OK + +def failures1_test(suite, *args): + for results in args: + assert "FAILED (failures=2)" in results + assert "Ran 18 tests" in results + +################################################################################ +# Test that output is the same in single process and subprocess modes +# + +base_cmd = [sys.executable, 'run_tests.py', '-i'] + +cmd = base_cmd + ['-f'] +sub_cmd = base_cmd + ['-s', '-f'] +time_out_cmd = base_cmd + ['-t', '4', '-s', '-f', 'infinite_loop' ] + +passes = 0 +failed = False + +for suite in test_suite_dirs: + single = call_proc(cmd + [suite], trunk_dir) + subs = call_proc(sub_cmd + [suite], trunk_dir) + + normed_single, normed_subs = map(norm_result,(single, subs)) + + failed = normed_single != normed_subs + if failed: + print '%s suite comparison FAILED\n' % suite + else: + passes += 1 + print '%s suite comparison OK' % suite + + assert_on_results(suite, single, subs) + + if verbose or failed: + print "difflib.Differ().compare(single, suprocessed):\n" + print ''.join ( list( + difflib.Differ().compare ( + (unnormed_diff and single or normed_single).splitlines(1), + (unnormed_diff and subs or normed_subs).splitlines(1) + )) + ) + +print "infinite_loop suite (subprocess mode timeout)", +loop_test = call_proc(time_out_cmd, trunk_dir) +assert "successfully terminated" in loop_test +passes += 1 +print "OK" + +print "\n%s/%s suites pass" % (passes, len(test_suite_dirs) + 1) + +print "\n-h for help" + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/test/scrap_test.py pygame-1.8.1release/test/scrap_test.py --- pygame-1.8.0release/test/scrap_test.py 2008-02-11 02:41:53.000000000 -0500 +++ pygame-1.8.1release/test/scrap_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,34 +1,82 @@ -import unittest -import pygame -import pygame.scrap as scrap - -class ScrapTest (unittest.TestCase): - - def test_scrap_mode (self): - scrap.set_mode (pygame.SCRAP_SELECTION) - scrap.set_mode (pygame.SCRAP_CLIPBOARD) - self.assertRaises (ValueError, scrap.set_mode, 1099) - - def test_scrap_put_text (self): - scrap.put (pygame.SCRAP_TEXT, "Hello world") - self.assertEquals (scrap.get (pygame.SCRAP_TEXT), "Hello world") - - scrap.put (pygame.SCRAP_TEXT, "Another String") - self.assertEquals (scrap.get (pygame.SCRAP_TEXT), "Another String") - - def test_scrap_put_image (self): - sf = pygame.image.load ("examples/data/asprite.bmp") - string = pygame.image.tostring (sf, "RGBA") - scrap.put (pygame.SCRAP_BMP, string) - self.assertEquals (scrap.get(pygame.SCRAP_BMP), string) - - def test_scrap_put (self): - scrap.put ("arbitrary buffer", "buf") - r = scrap.get ("arbitrary buffer") - self.assertEquals (r, "buf") - -if __name__ == '__main__': - pygame.init () - pygame.display.set_mode ((1, 1)) - scrap.init () - unittest.main() +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented + +import pygame +import pygame.scrap as scrap + +class ScrapModuleTest(unittest.TestCase): + def test_contains(self): + + # __doc__ (as of 2008-06-25) for pygame.scrap.contains: + + # scrap.contains (type) -> bool + # Checks, whether a certain type is available in the clipboard. + + self.assert_(test_not_implemented()) + + def test_get(self): + + # __doc__ (as of 2008-06-25) for pygame.scrap.get: + + # scrap.get (type) -> string + # Gets the data for the specified type from the clipboard. + + self.assert_(test_not_implemented()) + + def test_get_types(self): + + # __doc__ (as of 2008-06-25) for pygame.scrap.get_types: + + # scrap.get_types () -> list + # Gets a list of the available clipboard types. + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-25) for pygame.scrap.init: + + # scrap.init () -> None + # Initializes the scrap module. + + self.assert_(test_not_implemented()) + + def test_lost(self): + + # __doc__ (as of 2008-06-25) for pygame.scrap.lost: + + # scrap.lost() -> bool + # Checks whether the clipboard is currently owned by the application. + + self.assert_(test_not_implemented()) + + def test_set_mode (self): + scrap.set_mode (pygame.SCRAP_SELECTION) + scrap.set_mode (pygame.SCRAP_CLIPBOARD) + self.assertRaises (ValueError, scrap.set_mode, 1099) + + def test_scrap_put_text (self): + scrap.put (pygame.SCRAP_TEXT, "Hello world") + self.assertEquals (scrap.get (pygame.SCRAP_TEXT), "Hello world") + + scrap.put (pygame.SCRAP_TEXT, "Another String") + self.assertEquals (scrap.get (pygame.SCRAP_TEXT), "Another String") + + def test_scrap_put_image (self): + sf = pygame.image.load ("examples/data/asprite.bmp") + string = pygame.image.tostring (sf, "RGBA") + scrap.put (pygame.SCRAP_BMP, string) + self.assertEquals (scrap.get(pygame.SCRAP_BMP), string) + + def test_put (self): + scrap.put ("arbitrary buffer", "buf") + r = scrap.get ("arbitrary buffer") + self.assertEquals (r, "buf") + +if __name__ == '__main__': + pygame.init () + pygame.display.set_mode ((1, 1)) + scrap.init () + unittest.main() \ No newline at end of file diff -Nru pygame-1.8.0release/test/sndarray_test.py pygame-1.8.1release/test/sndarray_test.py --- pygame-1.8.0release/test/sndarray_test.py 2008-02-13 15:52:57.000000000 -0500 +++ pygame-1.8.1release/test/sndarray_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,21 +1,105 @@ -import unittest -import pygame - - -class SndarrayTest (unittest.TestCase): - - def test_import(self): - 'does it import' - import pygame.sndarray - - - - def test_add_more_tests(self): - 'we need to add more tests' - pass - #raise NotImplementedError("TODO: sndarray tests need improving.") - - - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented + +import pygame + +class SndarrayTest (unittest.TestCase): + def test_import(self): + 'does it import' + import pygame.sndarray + + def test_array(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.array: + + # pygame.sndarray.array(Sound): return array + # + # Copy Sound samples into an array. + # + # Creates a new array for the sound data and copies the samples. The + # array will always be in the format returned from + # pygame.mixer.get_init(). + + self.assert_(test_not_implemented()) + + def test_get_arraytype(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.get_arraytype: + + # pygame.sndarray.get_arraytype (): return str + # + # Gets the currently active array type. + # + # Returns the currently active array type. This will be a value of the + # get_arraytypes() tuple and indicates which type of array module is + # used for the array creation. + + self.assert_(test_not_implemented()) + + def test_get_arraytypes(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.get_arraytypes: + + # pygame.sndarray.get_arraytypes (): return tuple + # + # Gets the array system types currently supported. + # + # Checks, which array system types are available and returns them as a + # tuple of strings. The values of the tuple can be used directly in + # the use_arraytype () method. + # + # If no supported array system could be found, None will be returned. + + self.assert_(test_not_implemented()) + + def test_make_sound(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.make_sound: + + # pygame.sndarray.make_sound(array): return Sound + # + # Convert an array into a Sound object. + # + # Create a new playable Sound object from an array. The mixer module + # must be initialized and the array format must be similar to the mixer + # audio format. + + self.assert_(test_not_implemented()) + + def test_samples(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.samples: + + # pygame.sndarray.samples(Sound): return array + # + # Reference Sound samples into an array. + # + # Creates a new array that directly references the samples in a Sound + # object. Modifying the array will change the Sound. The array will + # always be in the format returned from pygame.mixer.get_init(). + + self.assert_(test_not_implemented()) + + def test_use_arraytype(self): + + # __doc__ (as of 2008-06-25) for pygame.sndarray.use_arraytype: + + # pygame.sndarray.use_arraytype (arraytype): return None + # + # Sets the array system to be used for sound arrays. + # + # Uses the requested array type for the module functions. + # Currently supported array types are: + # + # numeric + # numpy + # + # If the requested type is not available, a ValueError will be raised. + + self.assert_(test_not_implemented()) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/sndarray_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/sndarray_test.pyc differ diff -Nru pygame-1.8.0release/test/sprite_test.py pygame-1.8.1release/test/sprite_test.py --- pygame-1.8.0release/test/sprite_test.py 2008-03-03 05:51:13.000000000 -0500 +++ pygame-1.8.1release/test/sprite_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,326 +1,578 @@ +#################################### IMPORTS ################################### +import test_utils +import test.unittest as unittest +import pygame, test_utils +from test_utils import unordered_equality, test_not_implemented -import unittest -import pygame from pygame import sprite + +################################# MODULE LEVEL ################################# + +class SpriteModuleTest( unittest.TestCase ): + pass + +######################### SPRITECOLLIDE FUNCTIONS TEST ######################### + +class SpriteCollideTest( unittest.TestCase ): + def setUp(self): + self.ag = sprite.AbstractGroup() + self.ag2 = sprite.AbstractGroup() + self.s1 = sprite.Sprite(self.ag) + self.s2 = sprite.Sprite(self.ag2) + self.s3 = sprite.Sprite(self.ag2) + + self.s1.image = pygame.Surface((50,10), pygame.SRCALPHA, 32) + self.s2.image = pygame.Surface((10,10), pygame.SRCALPHA, 32) + self.s3.image = pygame.Surface((10,10), pygame.SRCALPHA, 32) + + self.s1.rect = self.s1.image.get_rect() + self.s2.rect = self.s2.image.get_rect() + self.s3.rect = self.s3.image.get_rect() + self.s2.rect.move_ip(40, 0) + self.s3.rect.move_ip(100, 100) + + def test_spritecollide__works_if_collided_cb_is_None(self): + # Test that sprites collide without collided function. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, collided = None + ), + [self.s2] + ) + + def test_spritecollide__works_if_collided_cb_not_passed(self): + # Should also work when collided function isn't passed at all. + self.assertEqual(sprite.spritecollide ( + self.s1, self.ag2, dokill = False), + [self.s2] + ) + + def test_spritecollide__collided_must_be_a_callable(self): + # Need to pass a callable. + self.assertRaises ( + TypeError, + sprite.spritecollide, self.s1, self.ag2, dokill = False, collided = 1 + ) + + def test_spritecollide__collided_defaults_to_collide_rect(self): + # collide_rect should behave the same as default. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, collided = sprite.collide_rect + ), + [self.s2] + ) + + def test_collide_rect_ratio__ratio_of_one_like_default(self): + # collide_rect_ratio should behave the same as default at a 1.0 ratio. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_rect_ratio(1.0) + ), + [self.s2] + ) + + def test_collide_rect_ratio__collides_all_at_ratio_of_twenty(self): + # collide_rect_ratio should collide all at a 20.0 ratio. + self.assert_ ( + unordered_equality ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_rect_ratio(20.0) + ), + [self.s2, self.s3] + ) + ) + + def test_collide_circle__no_radius_set(self): + # collide_circle with no radius set. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, collided = sprite.collide_circle + ), + [self.s2] + ) + + def test_collide_circle_ratio__no_radius_and_ratio_of_one(self): + # collide_circle_ratio with no radius set, at a 1.0 ratio. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_circle_ratio(1.0) + ), + [self.s2] + ) + + def test_collide_circle_ratio__no_radius_and_ratio_of_twenty(self): + # collide_circle_ratio with no radius set, at a 20.0 ratio. + self.assert_ ( + unordered_equality ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_circle_ratio(20.0) + ), + [self.s2, self.s3] + ) + ) + + def test_collide_circle__with_radii_set(self): + # collide_circle with a radius set. + + self.s1.radius = 50 + self.s2.radius = 10 + self.s3.radius = 400 + + self.assert_ ( + unordered_equality ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_circle + ), + [self.s2, self.s3] + ) + ) + + def test_collide_circle_ratio__with_radii_set(self): + self.s1.radius = 50 + self.s2.radius = 10 + self.s3.radius = 400 + + # collide_circle_ratio with a radius set. + self.assert_ ( + unordered_equality ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_circle_ratio(0.5) + ), + [self.s2, self.s3] + ) + ) + + def test_collide_mask(self): + # make some fully opaque sprites that will collide with masks. + self.s1.image.fill((255,255,255,255)) + self.s2.image.fill((255,255,255,255)) + self.s3.image.fill((255,255,255,255)) + + # masks should be autogenerated from image if they don't exist. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_mask + ), + [self.s2] + ) + + self.s1.mask = pygame.mask.from_surface(self.s1.image) + self.s2.mask = pygame.mask.from_surface(self.s2.image) + self.s3.mask = pygame.mask.from_surface(self.s3.image) + + # with set masks. + self.assertEqual ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, + collided = sprite.collide_mask + ), + [self.s2] + ) + + def test_collide_mask(self): + # make some sprites that are fully transparent, so they won't collide. + self.s1.image.fill((255,255,255,0)) + self.s2.image.fill((255,255,255,0)) + self.s3.image.fill((255,255,255,0)) + + self.s1.mask = pygame.mask.from_surface(self.s1.image, 255) + self.s2.mask = pygame.mask.from_surface(self.s2.image, 255) + self.s3.mask = pygame.mask.from_surface(self.s3.image, 255) + + self.assertFalse ( + sprite.spritecollide ( + self.s1, self.ag2, dokill = False, collided = sprite.collide_mask + ) + ) + + def test_groupcollide(self): + + # __doc__ (as of 2008-06-24) for pygame.sprite.groupcollide: + + # pygame.sprite.groupcollide(groupa, groupb, dokilla, dokillb) -> dict + # collision detection between group and group + # + # given two groups, this will find the intersections + # between all sprites in each group. it returns a + # dictionary of all sprites in the first group that + # collide. the value for each item in the dictionary + # is a list of the sprites in the second group it + # collides with. the two dokill arguments control if + # the sprites from either group will be automatically + # removed from all groups. + # collided is a callback function used to calculate if + # two sprites are colliding. it should take two sprites + # as values, and return a bool value indicating if + # they are colliding. if collided is not passed, all + # sprites must have a "rect" value, which is a + # rectangle of the sprite area, which will be used + # to calculate the collision. + + collision = pygame.sprite.groupcollide(self.ag, self.ag2, False, False) + + self.assert_(collision == {self.s1 : [self.s2]}) + + def test_spritecollideany(self): + + # __doc__ (as of 2008-06-24) for pygame.sprite.spritecollideany: + + # pygame.sprite.spritecollideany(sprite, group) -> sprite + # finds any sprites that collide + # + # given a sprite and a group of sprites, this will + # return return any single sprite that collides with + # with the given sprite. If there are no collisions + # this returns None. + # + # if you don't need all the features of the + # spritecollide function, this function will be a + # bit quicker. + # + # collided is a callback function used to calculate if + # two sprites are colliding. it should take two sprites + # as values, and return a bool value indicating if + # they are colliding. if collided is not passed, all + # sprites must have a "rect" value, which is a + # rectangle of the sprite area, which will be used + # to calculate the collision. + + self.assert_(test_not_implemented()) + + # TODO, move to gen_stubs.py IGNORE list + + test_collide_rect = test_spritecollide__collided_defaults_to_collide_rect + + # __doc__ (as of 2008-06-24) for pygame.sprite.collide_rect: + + # collision detection between two sprites, using rects. + # pygame.sprite.collide_rect(left, right): return bool + # + # Tests for collision between two sprites. Uses the + # pygame rect colliderect function to calculate the + # collision. Intended to be passed as a collided + # callback function to the *collide functions. + # Sprites must have a "rect" attributes. + # + # New in pygame 1.8.0 + + +################################################################################ + +class AbstractGroupTypeTest( unittest.TestCase ): + def test_has( self ): + " See if AbstractGroup.has() works as expected. " -class SpriteTest( unittest.TestCase ): - def testAbstractGroup_has( self ): - """ See if abstractGroup has works as expected. - """ ag = sprite.AbstractGroup() ag2 = sprite.AbstractGroup() s1 = sprite.Sprite(ag) s2 = sprite.Sprite(ag) s3 = sprite.Sprite(ag2) s4 = sprite.Sprite(ag2) - + self.assertEqual(True, s1 in ag ) - + self.assertEqual(True, ag.has(s1) ) - + self.assertEqual(True, ag.has([s1, s2]) ) - + # see if one of them not being in there. self.assertNotEqual(True, ag.has([s1, s2, s3]) ) - + # see if a second AbstractGroup works. self.assertEqual(True, ag2.has(s3) ) +################################################################################ +# A base class to share tests between similar classes - def test_spritecollide(self): - - ag = sprite.AbstractGroup() - ag2 = sprite.AbstractGroup() - s1 = sprite.Sprite(ag) - s2 = sprite.Sprite(ag2) - s1.image = pygame.Surface((10,10), pygame.SRCALPHA, 32) - s2.image = pygame.Surface((10,10), pygame.SRCALPHA, 32) - - s1.rect = s1.image.get_rect() - s2.rect = s2.image.get_rect() - - r = sprite.spritecollide(s1, ag2, dokill = False, collided = None) - self.assertTrue(r) - - - # need to pass a function. - self.assertRaises(TypeError, sprite.spritecollide, s1, ag2, dokill = False, collided = 1) - - self.assertTrue( sprite.spritecollide( s1, ag2, dokill = False, collided = sprite.collide_rect) ) - - # if there are no mask attributes. - self.assertRaises( AttributeError, sprite.spritecollide, s1, ag2, dokill = False, collided = sprite.collide_mask) - - # make some sprites that are fully transparent, so they won't collide. - s1.image.fill((255,255,255,0)) - s2.image.fill((255,255,255,0)) - - s1.mask = pygame.mask.from_surface(s1.image, 255) - s2.mask = pygame.mask.from_surface(s2.image, 255) +class LayeredGroupBase: + def test_get_layer_of_sprite(self): + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + self.LG.add(spr, layer=666) + self.assert_(len(self.LG._spritelist)==1) + self.assert_(self.LG.get_layer_of_sprite(spr)==666) + self.assert_(self.LG.get_layer_of_sprite(spr)==self.LG._spritelayers[spr]) + + + def test_add(self): + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + self.LG.add(spr) + self.assert_(len(self.LG._spritelist)==1) + self.assert_(self.LG.get_layer_of_sprite(spr)==self.LG._default_layer) - self.assertFalse( sprite.spritecollide( s1, ag2, dokill = False, collided = sprite.collide_mask) ) + def test_add__sprite_with_layer_attribute(self): + #test_add_sprite_with_layer_attribute - # make some fully opaque sprites that will collide with masks. - s1.image.fill((255,255,255,255)) - s2.image.fill((255,255,255,255)) - - s1.mask = pygame.mask.from_surface(s1.image) - s2.mask = pygame.mask.from_surface(s2.image) + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + spr._layer = 100 + self.LG.add(spr) + self.assert_(len(self.LG._spritelist)==1) + self.assert_(self.LG.get_layer_of_sprite(spr)==100) + + def test_add__passing_layer_keyword(self): + # test_add_sprite_passing_layer + + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + self.LG.add(spr, layer=100) + self.assert_(len(self.LG._spritelist)==1) + self.assert_(self.LG.get_layer_of_sprite(spr)==100) - self.assertTrue( sprite.spritecollide( s1, ag2, dokill = False, collided = sprite.collide_mask) ) + def test_add__overriding_sprite_layer_attr(self): + # test_add_sprite_overriding_layer_attr + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + spr._layer = 100 + self.LG.add(spr, layer=200) + self.assert_(len(self.LG._spritelist)==1) + self.assert_(self.LG.get_layer_of_sprite(spr)==200) - - - - -import pygame - -import unittest -import pygame.sprite as FastRenderGroup -from pygame.sprite import LayeredUpdates as LayeredRenderGroup - - -class Unit_test_LRG(unittest.TestCase): - - - def setUp(self): - self.LRG = LayeredRenderGroup() + def test_add__adding_sprite_on_init(self): + # test_add_sprite_init - def test_get_layer_of_sprite(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - self.LRG.add(spr, layer=666) - self.assert_(len(self.LRG._spritelist)==1) - self.assert_(self.LRG.get_layer_of_sprite(spr)==666) - self.assert_(self.LRG.get_layer_of_sprite(spr)==self.LRG._spritelayers[spr]) - - - def test_add_sprite(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - self.LRG.add(spr) - self.assert_(len(self.LRG._spritelist)==1) - self.assert_(self.LRG.get_layer_of_sprite(spr)==self.LRG._default_layer) - - def test_add_sprite_with_layer_attribute(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - spr._layer = 100 - self.LRG.add(spr) - self.assert_(len(self.LRG._spritelist)==1) - self.assert_(self.LRG.get_layer_of_sprite(spr)==100) - - def test_add_sprite_passing_layer(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - self.LRG.add(spr, layer=100) - self.assert_(len(self.LRG._spritelist)==1) - self.assert_(self.LRG.get_layer_of_sprite(spr)==100) - - def test_add_sprite_overriding_layer_attr(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - spr._layer = 100 - self.LRG.add(spr, layer=200) - self.assert_(len(self.LRG._spritelist)==1) - self.assert_(self.LRG.get_layer_of_sprite(spr)==200) - - def test_add_sprite_init(self): - spr = pygame.sprite.Sprite() - lrg2 = LayeredRenderGroup(spr) + spr = self.sprite() + lrg2 = sprite.LayeredUpdates(spr) self.assert_(len(lrg2._spritelist)==1) self.assert_(lrg2._spritelayers[spr]==lrg2._default_layer) - def test_add_sprite_init_layer_attr(self): - spr = pygame.sprite.Sprite() + def test_add__sprite_init_layer_attr(self): + # test_add_sprite_init_layer_attr + + spr = self.sprite() spr._layer = 20 - lrg2 = LayeredRenderGroup(spr) + lrg2 = sprite.LayeredUpdates(spr) self.assert_(len(lrg2._spritelist)==1) self.assert_(lrg2._spritelayers[spr]==20) - def test_add_sprite_init_passing_layer(self): - spr = pygame.sprite.Sprite() - lrg2 = LayeredRenderGroup(spr, layer=33) + def test_add__sprite_init_passing_layer(self): + # test_add_sprite_init_passing_layer + + spr = self.sprite() + lrg2 = sprite.LayeredUpdates(spr, layer=33) self.assert_(len(lrg2._spritelist)==1) self.assert_(lrg2._spritelayers[spr]==33) - def test_add_sprite_init_overiding_layer(self): - spr = pygame.sprite.Sprite() + def test_add__sprite_init_overiding_layer(self): + # test_add_sprite_init_overiding_layer + + spr = self.sprite() spr._layer = 55 - lrg2 = LayeredRenderGroup(spr, layer=33) + lrg2 = sprite.LayeredUpdates(spr, layer=33) self.assert_(len(lrg2._spritelist)==1) self.assert_(lrg2._spritelayers[spr]==33) - def test_add_spritelist(self): - self.assert_(len(self.LRG._spritelist)==0) + def test_add__spritelist(self): + # test_add_spritelist + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) - self.LRG.add(sprites) - self.assert_(len(self.LRG._spritelist)==10) + sprites.append(self.sprite()) + self.LG.add(sprites) + self.assert_(len(self.LG._spritelist)==10) for i in range(10): - self.assert_(self.LRG.get_layer_of_sprite(sprites[i])==self.LRG._default_layer) + self.assert_(self.LG.get_layer_of_sprite(sprites[i])==self.LG._default_layer) - def test_add_spritelist_with_layer_attr(self): - self.assert_(len(self.LRG._spritelist)==0) + def test_add__spritelist_with_layer_attr(self): + # test_add_spritelist_with_layer_attr + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) + sprites.append(self.sprite()) sprites[-1]._layer = i - self.LRG.add(sprites) - self.assert_(len(self.LRG._spritelist)==10) + self.LG.add(sprites) + self.assert_(len(self.LG._spritelist)==10) for i in range(10): - self.assert_(self.LRG.get_layer_of_sprite(sprites[i])==i) + self.assert_(self.LG.get_layer_of_sprite(sprites[i])==i) + + def test_add__spritelist_passing_layer(self): + # test_add_spritelist_passing_layer - def test_add_spritelist_passing_layer(self): - self.assert_(len(self.LRG._spritelist)==0) + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) - self.LRG.add(sprites, layer=33) - self.assert_(len(self.LRG._spritelist)==10) + sprites.append(self.sprite()) + self.LG.add(sprites, layer=33) + self.assert_(len(self.LG._spritelist)==10) for i in range(10): - self.assert_(self.LRG.get_layer_of_sprite(sprites[i])==33) + self.assert_(self.LG.get_layer_of_sprite(sprites[i])==33) - def test_add_spritelist_overriding_layer(self): - self.assert_(len(self.LRG._spritelist)==0) + def test_add__spritelist_overriding_layer(self): + # test_add_spritelist_overriding_layer + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) + sprites.append(self.sprite()) sprites[-1].layer = i - self.LRG.add(sprites, layer=33) - self.assert_(len(self.LRG._spritelist)==10) + self.LG.add(sprites, layer=33) + self.assert_(len(self.LG._spritelist)==10) for i in range(10): - self.assert_(self.LRG.get_layer_of_sprite(sprites[i])==33) + self.assert_(self.LG.get_layer_of_sprite(sprites[i])==33) - def test_add_spritelist_init(self): - self.assert_(len(self.LRG._spritelist)==0) + def test_add__spritelist_init(self): + # test_add_spritelist_init + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) - lrg2 = LayeredRenderGroup(sprites) + sprites.append(self.sprite()) + lrg2 = sprite.LayeredUpdates(sprites) self.assert_(len(lrg2._spritelist)==10) for i in range(10): - self.assert_(lrg2.get_layer_of_sprite(sprites[i])==self.LRG._default_layer) + self.assert_(lrg2.get_layer_of_sprite(sprites[i])==self.LG._default_layer) + + def test_remove__sprite(self): + # test_remove_sprite - def test_remove_sprite(self): - self.assert_(len(self.LRG._spritelist)==0) + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) + sprites.append(self.sprite()) sprites[-1].rect = 0 - self.LRG.add(sprites) - self.assert_(len(self.LRG._spritelist)==10) + self.LG.add(sprites) + self.assert_(len(self.LG._spritelist)==10) for i in range(10): - self.LRG.remove(sprites[i]) - self.assert_(len(self.LRG._spritelist)==0) + self.LG.remove(sprites[i]) + self.assert_(len(self.LG._spritelist)==0) def test_sprites(self): - self.assert_(len(self.LRG._spritelist)==0) + # test_sprites + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): - sprites.append(pygame.sprite.Sprite()) + sprites.append(self.sprite()) sprites[-1]._layer = 10-i - self.LRG.add(sprites) - self.assert_(len(self.LRG._spritelist)==10) - for idx,spr in enumerate(self.LRG.sprites()): + self.LG.add(sprites) + self.assert_(len(self.LG._spritelist)==10) + for idx,spr in enumerate(self.LG.sprites()): self.assert_(spr == sprites[9-idx]) def test_layers(self): - self.assert_(len(self.LRG._spritelist)==0) + # test_layers + + self.assert_(len(self.LG._spritelist)==0) sprites = [] for i in range(10): for j in range(5): - sprites.append(pygame.sprite.Sprite()) + sprites.append(self.sprite()) sprites[-1]._layer = i - self.LRG.add(sprites) - lays = self.LRG.layers() + self.LG.add(sprites) + lays = self.LG.layers() for i in range(10): self.assert_(lays[i] == i) - def test_layers2(self): - self.assert_(len(self.LRG)==0) + def test_add__layers_are_correct(self): #TODO + # test_layers2 + + self.assert_(len(self.LG)==0) layers = [1,4,6,8,3,6,2,6,4,5,6,1,0,9,7,6,54,8,2,43,6,1] for lay in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=lay) + self.LG.add(self.sprite(), layer=lay) layers.sort() - for idx, spr in enumerate(self.LRG.sprites()): - self.assert_(self.LRG.get_layer_of_sprite(spr)==layers[idx]) - + for idx, spr in enumerate(self.LG.sprites()): + self.assert_(self.LG.get_layer_of_sprite(spr)==layers[idx]) + def test_change_layer(self): - self.assert_(len(self.LRG._spritelist)==0) - spr = pygame.sprite.Sprite() - self.LRG.add(spr, layer=99) - self.assert_(self.LRG._spritelayers[spr] == 99) - self.LRG.change_layer(spr, 44) - self.assert_(self.LRG._spritelayers[spr] == 44) + # test_change_layer + + self.assert_(len(self.LG._spritelist)==0) + spr = self.sprite() + self.LG.add(spr, layer=99) + self.assert_(self.LG._spritelayers[spr] == 99) + self.LG.change_layer(spr, 44) + self.assert_(self.LG._spritelayers[spr] == 44) - spr2 = pygame.sprite.Sprite() + spr2 = self.sprite() spr2.layer = 55 - self.LRG.add(spr2) - self.LRG.change_layer(spr2, 77) + self.LG.add(spr2) + self.LG.change_layer(spr2, 77) self.assert_(spr2.layer == 77) def test_get_top_layer(self): + # test_get_top_layer + layers = [1,5,2,8,4,5,3,88,23,0] for i in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=i) - self.assert_(self.LRG.get_top_layer()==max(layers)) - self.assert_(self.LRG.get_top_layer()==max(self.LRG._spritelayers.values())) - self.assert_(self.LRG.get_top_layer()==self.LRG._spritelayers[self.LRG._spritelist[-1]]) + self.LG.add(self.sprite(), layer=i) + self.assert_(self.LG.get_top_layer()==max(layers)) + self.assert_(self.LG.get_top_layer()==max(self.LG._spritelayers.values())) + self.assert_(self.LG.get_top_layer()==self.LG._spritelayers[self.LG._spritelist[-1]]) def test_get_bottom_layer(self): + # test_get_bottom_layer + layers = [1,5,2,8,4,5,3,88,23,0] for i in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=i) - self.assert_(self.LRG.get_bottom_layer()==min(layers)) - self.assert_(self.LRG.get_bottom_layer()==min(self.LRG._spritelayers.values())) - self.assert_(self.LRG.get_bottom_layer()==self.LRG._spritelayers[self.LRG._spritelist[0]]) + self.LG.add(self.sprite(), layer=i) + self.assert_(self.LG.get_bottom_layer()==min(layers)) + self.assert_(self.LG.get_bottom_layer()==min(self.LG._spritelayers.values())) + self.assert_(self.LG.get_bottom_layer()==self.LG._spritelayers[self.LG._spritelist[0]]) def test_move_to_front(self): + # test_move_to_front + layers = [1,5,2,8,4,5,3,88,23,0] for i in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=i) - spr = pygame.sprite.Sprite() - self.LRG.add(spr, layer=3) - self.assert_(spr != self.LRG._spritelist[-1]) - self.LRG.move_to_front(spr) - self.assert_(spr == self.LRG._spritelist[-1]) + self.LG.add(self.sprite(), layer=i) + spr = self.sprite() + self.LG.add(spr, layer=3) + self.assert_(spr != self.LG._spritelist[-1]) + self.LG.move_to_front(spr) + self.assert_(spr == self.LG._spritelist[-1]) def test_move_to_back(self): + # test_move_to_back + layers = [1,5,2,8,4,5,3,88,23,0] for i in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=i) - spr = pygame.sprite.Sprite() - self.LRG.add(spr, layer=55) - self.assert_(spr != self.LRG._spritelist[0]) - self.LRG.move_to_back(spr) - self.assert_(spr == self.LRG._spritelist[0]) + self.LG.add(self.sprite(), layer=i) + spr = self.sprite() + self.LG.add(spr, layer=55) + self.assert_(spr != self.LG._spritelist[0]) + self.LG.move_to_back(spr) + self.assert_(spr == self.LG._spritelist[0]) def test_get_top_sprite(self): + # test_get_top_sprite + layers = [1,5,2,8,4,5,3,88,23,0] for i in layers: - self.LRG.add(pygame.sprite.Sprite(), layer=i) - self.assert_(self.LRG.get_layer_of_sprite(self.LRG.get_top_sprite())== self.LRG.get_top_layer()) + self.LG.add(self.sprite(), layer=i) + self.assert_(self.LG.get_layer_of_sprite(self.LG.get_top_sprite())== self.LG.get_top_layer()) def test_get_sprites_from_layer(self): - self.assert_(len(self.LRG)==0) + # test_get_sprites_from_layer + + self.assert_(len(self.LG)==0) sprites = {} layers = [1,4,5,6,3,7,8,2,1,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,0,1,6,5,4,3,2] for lay in layers: - spr = pygame.sprite.Sprite() + spr = self.sprite() spr._layer = lay - self.LRG.add(spr) + self.LG.add(spr) if not sprites.has_key(lay): sprites[lay] = [] sprites[lay].append(spr) - for lay in self.LRG.layers(): - for spr in self.LRG.get_sprites_from_layer(lay): + for lay in self.LG.layers(): + for spr in self.LG.get_sprites_from_layer(lay): self.assert_(spr in sprites[lay]) sprites[lay].remove(spr) if len(sprites[lay]) == 0: @@ -328,44 +580,157 @@ self.assert_(len(sprites.values())==0) def test_switch_layer(self): - self.assert_(len(self.LRG)==0) + # test_switch_layer + + self.assert_(len(self.LG)==0) sprites1 = [] sprites2 = [] layers = [3,2,3,2,3,3,2,2,3,2,3,2,3,2,3,2,3,3,2,2,3,2,3] for lay in layers: - spr = pygame.sprite.Sprite() + spr = self.sprite() spr._layer = lay - self.LRG.add(spr) + self.LG.add(spr) if lay==2: sprites1.append(spr) else: sprites2.append(spr) for spr in sprites1: - self.assert_(spr in self.LRG.get_sprites_from_layer(2)) + self.assert_(spr in self.LG.get_sprites_from_layer(2)) for spr in sprites2: - self.assert_(spr in self.LRG.get_sprites_from_layer(3)) - self.assert_(len(self.LRG)==len(sprites1)+len(sprites2)) - - self.LRG.switch_layer(2,3) - + self.assert_(spr in self.LG.get_sprites_from_layer(3)) + self.assert_(len(self.LG)==len(sprites1)+len(sprites2)) + + self.LG.switch_layer(2,3) + for spr in sprites1: - self.assert_(spr in self.LRG.get_sprites_from_layer(3)) + self.assert_(spr in self.LG.get_sprites_from_layer(3)) for spr in sprites2: - self.assert_(spr in self.LRG.get_sprites_from_layer(2)) - self.assert_(len(self.LRG)==len(sprites1)+len(sprites2)) - -#TODO: test FRG and DirtySprite (visible, layer, blendmode and dirty) + self.assert_(spr in self.LG.get_sprites_from_layer(2)) + self.assert_(len(self.LG)==len(sprites1)+len(sprites2)) + +########################## LAYERED RENDER GROUP TESTS ########################## + +class LayeredUpdatesTypeTest__SpriteTest(LayeredGroupBase, unittest.TestCase): + sprite = sprite.Sprite + + def setUp(self): + self.LG = sprite.LayeredUpdates() -if __name__ == "__main__": - unittest.main() +class LayeredUpdatesTypeTest__DirtySprite(LayeredGroupBase, unittest.TestCase): + sprite = sprite.DirtySprite + + def setUp(self): + self.LG = sprite.LayeredUpdates() + +class LayeredDirtyTypeTest__DirtySprite(LayeredGroupBase, unittest.TestCase): + sprite = sprite.DirtySprite + + def setUp(self): + self.LG = sprite.LayeredDirty() + +############################### SPRITE BASE CLASS ############################## +# +# tests common between sprite classes + +class SpriteBase: + def setUp(self): + self.groups = [] + for Group in self.Groups: + self.groups.append(Group()) + self.sprite = self.Sprite() + def test___init____added_to_groups_passed(self): + self.sprite = self.Sprite(self.groups) + + self.assert_(unordered_equality( + self.sprite.groups(), + self.groups + )) + + def test_add(self): + self.sprite.add(self.groups) + + self.assert_(unordered_equality( + self.sprite.groups(), + self.groups + )) + + def test_add_internal(self): + self.assert_(test_not_implemented()) + def test_alive(self): + self.assert_( + not self.sprite.alive(), + "Sprite should not be alive if in no groups" + ) + + self.sprite.add(self.groups) + self.assert_(self.sprite.alive()) + + def test_groups(self): + for i, g in enumerate(self.groups): + self.sprite.add(g) + + groups = self.sprite.groups() + self.assert_( unordered_equality ( + groups, + self.groups[:i+1], + )) + def test_kill(self): + self.sprite.add(self.groups) + + self.assert_(self.sprite.alive()) + self.sprite.kill() + + self.assert_(not self.sprite.groups() and not self.sprite.alive() ) + + def test_remove(self): + self.sprite.add(self.groups) + self.sprite.remove(self.groups) + self.assert_(not self.sprite.groups()) + def test_remove_internal(self): + self.assert_(test_not_implemented()) + def test_update(self): + # Doc string for pygame.sprite.Sprite.update: + + # method to control sprite behavior + # Sprite.update(*args): + # + # The default implementation of this method does nothing; it's just a + # convenient "hook" that you can override. This method is called by + # Group.update() with whatever arguments you give it. + # + # There is no need to use this method if not using the convenience + # method by the same name in the Group class. + # + + self.assert_(test_not_implemented()) + +############################## SPRITE CLASS TESTS ############################## + +class SpriteTypeTest(SpriteBase, unittest.TestCase): + Sprite = sprite.Sprite + + Groups = [ sprite.Group, + sprite.LayeredUpdates, + sprite.RenderUpdates, + sprite.OrderedUpdates, ] + +class DirtySpriteTypeTest(SpriteBase, unittest.TestCase): + Sprite = sprite.DirtySprite + + Groups = [ sprite.Group, + sprite.LayeredUpdates, + sprite.RenderUpdates, + sprite.OrderedUpdates, + sprite.LayeredDirty, ] +################################################################################ if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/sprite_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/sprite_test.pyc differ diff -Nru pygame-1.8.0release/test/surface_test.py pygame-1.8.1release/test/surface_test.py --- pygame-1.8.0release/test/surface_test.py 2008-03-03 05:06:15.000000000 -0500 +++ pygame-1.8.1release/test/surface_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,119 +1,552 @@ - -import unittest -import pygame - -from pygame.locals import * - -class SurfaceTest( unittest.TestCase ): - - def test_set_clip( self ): - """ see if surface.set_clip(None) works correctly. - """ - s = pygame.Surface((800, 600)) - r = pygame.Rect(10, 10, 10, 10) - s.set_clip(r) - r.move_ip(10, 0) - s.set_clip(None) - res = s.get_clip() - # this was garbled before. - self.assertEqual(res[0], 0) - self.assertEqual(res[2], 800) - - def test_print(self): - surf = pygame.Surface((70,70), 0, 32) - self.assertEqual(repr(surf), '') - - def test_keyword_arguments(self): - surf = pygame.Surface((70,70), flags=SRCALPHA, depth=32) - self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA) - self.assertEqual(surf.get_bitsize(), 32) - - # sanity check to make sure the check below is valid - surf_16 = pygame.Surface((70,70), 0, 16) - self.assertEqual(surf_16.get_bytesize(), 2) - - # try again with an argument list - surf_16 = pygame.Surface((70,70), depth=16) - self.assertEqual(surf_16.get_bytesize(), 2) - - def test_set_at(self): - - #24bit surfaces - s = pygame.Surface( (100, 100), 0, 24) - s.fill((0,0,0)) - - # set it with a tuple. - s.set_at((0,0), (10,10,10, 255)) - r = s.get_at((0,0)) - self.assertEqual(r, (10,10,10, 255)) - - # try setting a color with a single integer. - s.fill((0,0,0,255)) - s.set_at ((10, 1), 0x0000FF) - r = s.get_at((10,1)) - self.assertEqual(r, (0,0,255, 255)) - - - def test_SRCALPHA(self): - # has the flag been passed in ok? - surf = pygame.Surface((70,70), SRCALPHA, 32) - self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA) - - #24bit surfaces can not have SRCALPHA. - self.assertRaises(ValueError, pygame.Surface, (100, 100), pygame.SRCALPHA, 24) - - # if we have a 32 bit surface, the SRCALPHA should have worked too. - surf2 = pygame.Surface((70,70), SRCALPHA) - if surf2.get_bitsize() == 32: - self.assertEqual(surf2.get_flags() & SRCALPHA, SRCALPHA) - - def test_get_buffer (self): - surf = pygame.Surface ((70, 70), 0, 32) - buf = surf.get_buffer () - # 70*70*4 bytes = 19600 - self.assertEqual (repr (buf), "") - - def test_get_bounding_rect (self): - surf = pygame.Surface ((70, 70), SRCALPHA, 32) - surf.fill((0,0,0,0)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.width, 0) - self.assertEqual(bound_rect.height, 0) - surf.set_at((30,30),(255,255,255,1)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.left, 30) - self.assertEqual(bound_rect.top, 30) - self.assertEqual(bound_rect.width, 1) - self.assertEqual(bound_rect.height, 1) - surf.set_at((29,29),(255,255,255,1)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.left, 29) - self.assertEqual(bound_rect.top, 29) - self.assertEqual(bound_rect.width, 2) - self.assertEqual(bound_rect.height, 2) - - surf = pygame.Surface ((70, 70), 0, 24) - surf.fill((0,0,0)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.width, surf.get_width()) - self.assertEqual(bound_rect.height, surf.get_height()) - - surf.set_colorkey((0,0,0)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.width, 0) - self.assertEqual(bound_rect.height, 0) - surf.set_at((30,30),(255,255,255)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.left, 30) - self.assertEqual(bound_rect.top, 30) - self.assertEqual(bound_rect.width, 1) - self.assertEqual(bound_rect.height, 1) - surf.set_at((60,60),(255,255,255)) - bound_rect = surf.get_bounding_rect() - self.assertEqual(bound_rect.left, 30) - self.assertEqual(bound_rect.top, 30) - self.assertEqual(bound_rect.width, 31) - self.assertEqual(bound_rect.height, 31) - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest +import pygame + +from test_utils import test_not_implemented + +from pygame.locals import * + +class SurfaceTypeTest(unittest.TestCase): + def test_set_clip( self ): + """ see if surface.set_clip(None) works correctly. + """ + s = pygame.Surface((800, 600)) + r = pygame.Rect(10, 10, 10, 10) + s.set_clip(r) + r.move_ip(10, 0) + s.set_clip(None) + res = s.get_clip() + # this was garbled before. + self.assertEqual(res[0], 0) + self.assertEqual(res[2], 800) + + def test_print(self): + surf = pygame.Surface((70,70), 0, 32) + self.assertEqual(repr(surf), '') + + def test_keyword_arguments(self): + surf = pygame.Surface((70,70), flags=SRCALPHA, depth=32) + self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA) + self.assertEqual(surf.get_bitsize(), 32) + + # sanity check to make sure the check below is valid + surf_16 = pygame.Surface((70,70), 0, 16) + self.assertEqual(surf_16.get_bytesize(), 2) + + # try again with an argument list + surf_16 = pygame.Surface((70,70), depth=16) + self.assertEqual(surf_16.get_bytesize(), 2) + + def test_set_at(self): + + #24bit surfaces + s = pygame.Surface( (100, 100), 0, 24) + s.fill((0,0,0)) + + # set it with a tuple. + s.set_at((0,0), (10,10,10, 255)) + r = s.get_at((0,0)) + self.assertEqual(r, (10,10,10, 255)) + + # try setting a color with a single integer. + s.fill((0,0,0,255)) + s.set_at ((10, 1), 0x0000FF) + r = s.get_at((10,1)) + self.assertEqual(r, (0,0,255, 255)) + + + def test_SRCALPHA(self): + # has the flag been passed in ok? + surf = pygame.Surface((70,70), SRCALPHA, 32) + self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA) + + #24bit surfaces can not have SRCALPHA. + self.assertRaises(ValueError, pygame.Surface, (100, 100), pygame.SRCALPHA, 24) + + # if we have a 32 bit surface, the SRCALPHA should have worked too. + surf2 = pygame.Surface((70,70), SRCALPHA) + if surf2.get_bitsize() == 32: + self.assertEqual(surf2.get_flags() & SRCALPHA, SRCALPHA) + + def test_get_buffer (self): + surf = pygame.Surface ((70, 70), 0, 32) + buf = surf.get_buffer () + # 70*70*4 bytes = 19600 + self.assertEqual (repr (buf), "") + + def test_get_bounding_rect (self): + surf = pygame.Surface ((70, 70), SRCALPHA, 32) + surf.fill((0,0,0,0)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.width, 0) + self.assertEqual(bound_rect.height, 0) + surf.set_at((30,30),(255,255,255,1)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.left, 30) + self.assertEqual(bound_rect.top, 30) + self.assertEqual(bound_rect.width, 1) + self.assertEqual(bound_rect.height, 1) + surf.set_at((29,29),(255,255,255,1)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.left, 29) + self.assertEqual(bound_rect.top, 29) + self.assertEqual(bound_rect.width, 2) + self.assertEqual(bound_rect.height, 2) + + surf = pygame.Surface ((70, 70), 0, 24) + surf.fill((0,0,0)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.width, surf.get_width()) + self.assertEqual(bound_rect.height, surf.get_height()) + + surf.set_colorkey((0,0,0)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.width, 0) + self.assertEqual(bound_rect.height, 0) + surf.set_at((30,30),(255,255,255)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.left, 30) + self.assertEqual(bound_rect.top, 30) + self.assertEqual(bound_rect.width, 1) + self.assertEqual(bound_rect.height, 1) + surf.set_at((60,60),(255,255,255)) + bound_rect = surf.get_bounding_rect() + self.assertEqual(bound_rect.left, 30) + self.assertEqual(bound_rect.top, 30) + self.assertEqual(bound_rect.width, 31) + self.assertEqual(bound_rect.height, 31) + + + def test_blit(self): # See blit_test.py + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.blit: + + # Surface.blit(source, dest, area=None, special_flags = 0): return Rect + # draw one image onto another + + self.assert_(test_not_implemented()) + + def test_convert(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.convert: + + # Surface.convert(Surface): return Surface + # Surface.convert(depth, flags=0): return Surface + # Surface.convert(masks, flags=0): return Surface + # Surface.convert(): return Surface + # change the pixel format of an image + + self.assert_(test_not_implemented()) + + def test_convert_alpha(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.convert_alpha: + + # Surface.convert_alpha(Surface): return Surface + # Surface.convert_alpha(): return Surface + # change the pixel format of an image including per pixel alphas + + self.assert_(test_not_implemented()) + + def test_copy(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.copy: + + # Surface.copy(): return Surface + # create a new copy of a Surface + + color = (25, 25, 25, 25) + s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32) + s1.fill(color) + + s2 = s1.copy() + + s1rect = s1.get_rect() + s2rect = s2.get_rect() + + self.assert_(s1rect.size == s2rect.size) + self.assert_(s2.get_at((10,10)) == color) + + def test_fill(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.fill: + + # Surface.fill(color, rect=None, special_flags=0): return Rect + # fill Surface with a solid color + + color = (25, 25, 25, 25) + fill_rect = pygame.Rect(0, 0, 16, 16) + + s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32) + s1.fill(color, fill_rect) + + for pt in test_utils.rect_area_pts(fill_rect): + self.assert_(s1.get_at(pt) == color ) + + for pt in test_utils.rect_outer_bounds(fill_rect): + self.assert_(s1.get_at(pt) != color ) + + self.assert_(test_not_implemented()) + + def test_get_abs_offset(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_abs_offset: + + # Surface.get_abs_offset(): return (x, y) + # find the absolute position of a child subsurface inside its top level parent + + self.assert_(test_not_implemented()) + + def test_get_abs_parent(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_abs_parent: + + # Surface.get_abs_parent(): return Surface + # find the top level parent of a subsurface + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_get_alpha(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_alpha: + + # Surface.get_alpha(): return int_value or None + # get the current Surface transparency value + + s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32) + self.assert_(s1.get_alpha() == 255) + + for alpha in (0, 32, 127, 255): + s1.set_alpha(alpha) + for t in range(4): s1.set_alpha(s1.get_alpha()) + self.assert_(s1.get_alpha() == alpha) + + def test_set_alpha(self): + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.set_alpha: + + # Surface.set_alpha(value, flags=0): return None + # Surface.set_alpha(None): return None + # set the alpha value for the full Surface image + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_get_at(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_at: + + # Surface.get_at((x, y)): return Color + # get the color value at a single pixel + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_get_bitsize(self): + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_bitsize: + + # Surface.get_bitsize(): return int + # get the bit depth of the Surface pixel format + + self.assert_(test_not_implemented()) + + def test_get_bytesize(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_bytesize: + + # Surface.get_bytesize(): return int + # get the bytes used per Surface pixel + + s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32) + self.assert_(s1.get_bytesize() == 4) + self.assert_(s1.get_bitsize() == 32) + + ######################################################################## + + def test_get_clip(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_clip: + + # Surface.get_clip(): return Rect + # get the current clipping area of the Surface + + self.assert_(test_not_implemented()) + + def test_get_flags(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_flags: + + # Surface.get_flags(): return int + # get the additional flags used for the Surface + + s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32) + self.assert_(s1.get_flags() == pygame.SRCALPHA) + + def test_get_locked(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_locked: + + # Surface.get_locked(): return bool + # test if the Surface is current locked + + self.assert_(test_not_implemented()) + + def test_get_locks(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_locks: + + # Surface.get_locks(): return tuple + # Gets the locks for the Surface + + self.assert_(test_not_implemented()) + + def test_get_losses(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_losses: + + # Surface.get_losses(): return (R, G, B, A) + # the significant bits used to convert between a color and a mapped integer + + self.assert_(test_not_implemented()) + + def test_get_masks(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_masks: + + # Surface.get_masks(): return (R, G, B, A) + # the bitmasks needed to convert between a color and a mapped integer + + self.assert_(test_not_implemented()) + + def test_get_offset(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_offset: + + # Surface.get_offset(): return (x, y) + # find the position of a child subsurface inside a parent + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_subsurface(self): + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.subsurface: + + # Surface.subsurface(Rect): return Surface + # create a new surface that references its parent + + self.assert_(test_not_implemented()) + + def test_get_parent(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_parent: + + # Surface.get_parent(): return Surface + # find the parent of a subsurface + + parent = pygame.Surface((16, 16)) + child = parent.subsurface((0,0,5,5)) + + self.assert_(child.get_parent() is parent) + + ######################################################################## + + def test_get_pitch(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_pitch: + + # Surface.get_pitch(): return int + # get the number of bytes used per Surface row + + self.assert_(test_not_implemented()) + + def test_get_rect(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_rect: + + # Surface.get_rect(**kwargs): return Rect + # get the rectangular area of the Surface + + surf = pygame.Surface((16, 16)) + + rect = surf.get_rect() + + self.assert_(rect.size == (16, 16)) + + def test_get_shifts(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_shifts: + + # Surface.get_shifts(): return (R, G, B, A) + # the bit shifts needed to convert between a color and a mapped integer + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_get_size(self): + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_size: + + # Surface.get_size(): return (width, height) + # get the dimensions of the Surface + + self.assert_(test_not_implemented()) + + def test_get_width__size_and_height(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_width: + + # Surface.get_width(): return width + # get the width of the Surface + + for w in xrange(0, 255, 32): + for h in xrange(0, 127, 15): + s = pygame.Surface((w, h)) + self.assertEquals(s.get_width(), w) + self.assertEquals(s.get_height(), h) + self.assertEquals(s.get_size(), (w, h)) + + ######################################################################## + + def test_lock(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.lock: + + # Surface.lock(): return None + # lock the Surface memory for pixel access + + self.assert_(test_not_implemented()) + + def test_map_rgb(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.map_rgb: + + # Surface.map_rgb(Color): return mapped_int + # convert a color into a mapped color value + + self.assert_(test_not_implemented()) + + def test_mustlock(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.mustlock: + + # Surface.mustlock(): return bool + # test if the Surface requires locking + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_get_colorkey(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_colorkey: + + # Surface.get_colorkey(): return RGB or None + # Get the current transparent colorkey + + self.assert_(test_not_implemented()) + + def test_set_colorkey(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.set_colorkey: + + # Surface.set_colorkey(Color, flags=0): return None + # Surface.set_colorkey(None): return None + # Set the transparent colorkey + + s = pygame.Surface((16,16), pygame.SRCALPHA, 32) + + colorkeys = ((20,189,20, 255),(128,50,50,255), (23, 21, 255,255)) + + for colorkey in colorkeys: + s.set_colorkey(colorkey) + for t in range(4): s.set_colorkey(s.get_colorkey()) + self.assertEquals(s.get_colorkey(), colorkey) + + ######################################################################## + + def test_set_palette(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.set_palette: + + # Surface.set_palette([RGB, RGB, RGB, ...]): return None + # set the color palette for an 8bit Surface + + self.assert_(test_not_implemented()) + + def test_get_palette(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_palette: + + # Surface.get_palette(): return [RGB, RGB, RGB, ...] + # get the color index palette for an 8bit Surface + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_set_palette_at(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.set_palette_at: + + # Surface.set_at(index, RGB): return None + # set the color for a single index in an 8bit Surface palette + + self.assert_(test_not_implemented()) + + def test_get_palette_at(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.get_palette_at: + + # Surface.get_palette_at(index): return RGB + # get the color for a single entry in a palette + + self.assert_(test_not_implemented()) + + ######################################################################## + + def test_unlock(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.unlock: + + # Surface.unlock(): return None + # unlock the Surface memory from pixel access + + self.assert_(test_not_implemented()) + + def test_unmap_rgb(self): + + # __doc__ (as of 2008-06-25) for pygame.surface.Surface.unmap_rgb: + + # Surface.map_rgb(mapped_int): return Color + # convert a mapped integer color value into a Color + + self.assert_(test_not_implemented()) + + + + def test_set_masks(self): + s = pygame.Surface((32,32)) + r,g,b,a = s.get_masks() + s.set_masks((b,g,r,a)) + r2,g2,b2,a2 = s.get_masks() + self.assertEqual((r,g,b,a), (b2,g2,r2,a2)) + + + def test_set_shifts(self): + s = pygame.Surface((32,32)) + r,g,b,a = s.get_shifts() + s.set_shifts((b,g,r,a)) + r2,g2,b2,a2 = s.get_shifts() + self.assertEqual((r,g,b,a), (b2,g2,r2,a2)) + + + + + + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/surface_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/surface_test.pyc differ diff -Nru pygame-1.8.0release/test/surfarray_test.py pygame-1.8.1release/test/surfarray_test.py --- pygame-1.8.0release/test/surfarray_test.py 2008-02-13 15:53:05.000000000 -0500 +++ pygame-1.8.1release/test/surfarray_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,24 +1,244 @@ -import unittest -import pygame - - -class SurfarrayTest (unittest.TestCase): - - def test_import(self): - 'does it import' - import pygame.surfarray - - def test_setpixel(self): - 'Can a pixel be set' - - - - def test_add_more_tests(self): - 'we need to add more tests' - pass - #raise NotImplementedError("TODO: surfarray tests need improving.") - - - -if __name__ == '__main__': - unittest.main() +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +import pygame + +class SurfarrayModuleTest (unittest.TestCase): + def test_import(self): + 'does it import' + import pygame.surfarray + + def test_array2d(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.array2d: + + # pygame.surfarray.array2d (Surface): return array + # + # Copy pixels into a 2d array. + # + # Copy the pixels from a Surface into a 2D array. The bit depth of the + # surface will control the size of the integer values, and will work + # for any type of pixel format. + # + # This function will temporarily lock the Surface as pixels are copied + # (see the Surface.lock - lock the Surface memory for pixel access + # method). + + self.assert_(test_not_implemented()) + + def test_array3d(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.array3d: + + # pygame.surfarray.array3d (Surface): return array + # + # Copy pixels into a 3d array. + # + # Copy the pixels from a Surface into a 3D array. The bit depth of the + # surface will control the size of the integer values, and will work + # for any type of pixel format. + # + # This function will temporarily lock the Surface as pixels are copied + # (see the Surface.lock - lock the Surface memory for pixel access + # method). + + self.assert_(test_not_implemented()) + + def test_array_alpha(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.array_alpha: + + # pygame.surfarray.array_alpha (Surface): return array + # + # Copy pixel alphas into a 2d array. + # + # Copy the pixel alpha values (degree of transparency) from a Surface + # into a 2D array. This will work for any type of Surface + # format. Surfaces without a pixel alpha will return an array with all + # opaque values. + # + # This function will temporarily lock the Surface as pixels are copied + # (see the Surface.lock - lock the Surface memory for pixel access + # method). + + self.assert_(test_not_implemented()) + + def test_array_colorkey(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.array_colorkey: + + # pygame.surfarray.array_colorkey (Surface): return array + # + # Copy the colorkey values into a 2d array. + # + # Create a new array with the colorkey transparency value from each + # pixel. If the pixel matches the colorkey it will be fully + # tranparent; otherwise it will be fully opaque. + # + # This will work on any type of Surface format. If the image has no + # colorkey a solid opaque array will be returned. + # + # This function will temporarily lock the Surface as pixels are + # copied. + + self.assert_(test_not_implemented()) + + def test_blit_array(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.blit_array: + + # pygame.surfarray.blit_array (Surface, array): return None + # + # Blit directly from a array values. + # + # Directly copy values from an array into a Surface. This is faster + # than converting the array into a Surface and blitting. The array + # must be the same dimensions as the Surface and will completely + # replace all pixel values. + # + # This function will temporarily lock the Surface as the new values + # are copied. + + self.assert_(test_not_implemented()) + + def test_get_arraytype(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.get_arraytype: + + # pygame.surfarray.get_arraytype (): return str + # + # Gets the currently active array type. + # + # Returns the currently active array type. This will be a value of the + # get_arraytypes() tuple and indicates which type of array module is + # used for the array creation. + + self.assert_(test_not_implemented()) + + def test_get_arraytypes(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.get_arraytypes: + + # pygame.surfarray.get_arraytypes (): return tuple + # + # Gets the array system types currently supported. + # + # Checks, which array system types are available and returns them as a + # tuple of strings. The values of the tuple can be used directly in + # the use_arraytype () method. + # + # If no supported array system could be found, None will be returned. + + self.assert_(test_not_implemented()) + + def test_make_surface(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.make_surface: + + # pygame.surfarray.make_surface (array): return Surface + # + # Copy an array to a new surface. + # + # Create a new Surface that best resembles the data and format on the + # array. The array can be 2D or 3D with any sized integer values. + + self.assert_(test_not_implemented()) + + def test_map_array(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.map_array: + + # pygame.surfarray.map_array (Surface, array3d): return array2d + # + # Map a 3D array into a 2D array. + # + # Convert a 3D array into a 2D array. This will use the given Surface + # format to control the conversion. Palette surface formats are not + # supported. + + self.assert_(test_not_implemented()) + + def test_pixels2d(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.pixels2d: + + # pygame.surfarray.pixels2d (Surface): return array + # + # Reference pixels into a 2d array. + # + # Create a new 2D array that directly references the pixel values in a + # Surface. Any changes to the array will affect the pixels in the + # Surface. This is a fast operation since no data is copied. + # + # Pixels from a 24-bit Surface cannot be referenced, but all other + # Surface bit depths can. + # + # The Surface this references will remain locked for the lifetime of + # the array (see the Surface.lock - lock the Surface memory for pixel + # access method). + + self.assert_(test_not_implemented()) + + def test_pixels3d(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.pixels3d: + + # pygame.surfarray.pixels3d (Surface): return array + # + # Reference pixels into a 3d array. + # + # Create a new 3D array that directly references the pixel values in a + # Surface. Any changes to the array will affect the pixels in the + # Surface. This is a fast operation since no data is copied. + # + # This will only work on Surfaces that have 24-bit or 32-bit + # formats. Lower pixel formats cannot be referenced. + # + # The Surface this references will remain locked for the lifetime of + # the array (see the Surface.lock - lock the Surface memory for pixel + # access method). + + self.assert_(test_not_implemented()) + + def test_pixels_alpha(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.pixels_alpha: + + # pygame.surfarray.pixels_alpha (Surface): return array + # + # Reference pixel alphas into a 2d array. + # + # Create a new 2D array that directly references the alpha values + # (degree of transparency) in a Surface. Any changes to the array will + # affect the pixels in the Surface. This is a fast operation since no + # data is copied. + # + # This can only work on 32-bit Surfaces with a per-pixel alpha value. + # + # The Surface this array references will remain locked for the + # lifetime of the array. + + self.assert_(test_not_implemented()) + + def test_use_arraytype(self): + + # __doc__ (as of 2008-06-25) for pygame.surfarray.use_arraytype: + + # pygame.surfarray.use_arraytype (arraytype): return None + # + # Sets the array system to be used for surface arrays. + # + # Uses the requested array type for the module functions. + # Currently supported array types are: + # + # numeric + # numpy + # + # If the requested type is not available, a ValueError will be raised. + + self.assert_(test_not_implemented()) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/surfarray_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/surfarray_test.pyc differ diff -Nru pygame-1.8.0release/test/surflock_test.py pygame-1.8.1release/test/surflock_test.py --- pygame-1.8.0release/test/surflock_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/surflock_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,160 @@ +import test_utils +import test.unittest as unittest +import sys, test_utils +import pygame + +class SurfaceLockTest (unittest.TestCase): + + def test_lock (self): + sf = pygame.Surface ((5, 5)) + + sf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (sf,)) + + sf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (sf, sf)) + + sf.unlock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (sf,)) + + sf.unlock () + self.assertEquals (sf.get_locked (), False) + self.assertEquals (sf.get_locks (), ()) + + def test_subsurface_lock (self): + sf = pygame.Surface ((5, 5)) + subsf = sf.subsurface ((1, 1, 2, 2)) + sf2 = pygame.Surface ((5, 5)) + + # Simple blits, nothing should happen here. + sf2.blit (subsf, (0, 0)) + sf2.blit (sf, (0, 0)) + + # Test blitting on self: + self.assertRaises (pygame.error, sf.blit, subsf, (0, 0)) + #self.assertRaises (pygame.error, subsf.blit, sf, (0, 0)) + # ^ Fails although it should not in my opinion. If I cannot + # blit the subsurface to the surface, it should not be allowed + # the other way around as well. + + # Test additional locks. + sf.lock () + sf2.blit (subsf, (0, 0)) + self.assertRaises (pygame.error, sf2.blit, sf, (0, 0)) + + subsf.lock () + self.assertRaises (pygame.error, sf2.blit, subsf, (0, 0)) + self.assertRaises (pygame.error, sf2.blit, sf, (0, 0)) + + # sf and subsf are now explicitly locked. Unlock sf, so we can + # (assume) to blit it. + # It will fail though as the subsurface still has a lock around, + # which is okay and correct behaviour. + sf.unlock () + self.assertRaises (pygame.error, sf2.blit, subsf, (0, 0)) + self.assertRaises (pygame.error, sf2.blit, sf, (0, 0)) + + # Run a second unlock on the surface. This should ideally have + # no effect as the subsurface is the locking reason! + sf.unlock () + self.assertRaises (pygame.error, sf2.blit, sf, (0, 0)) + self.assertRaises (pygame.error, sf2.blit, subsf, (0, 0)) + subsf.unlock () + + sf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (sf,)) + self.assertEquals (subsf.get_locked (), False) + self.assertEquals (subsf.get_locks (), ()) + + subsf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (sf, subsf)) + self.assertEquals (subsf.get_locked (), True) + self.assertEquals (subsf.get_locks (), (subsf,)) + + sf.unlock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (subsf,)) + self.assertEquals (subsf.get_locked (), True) + self.assertEquals (subsf.get_locks (), (subsf,)) + + subsf.unlock () + self.assertEquals (sf.get_locked (), False) + self.assertEquals (sf.get_locks (), ()) + self.assertEquals (subsf.get_locked (), False) + self.assertEquals (subsf.get_locks (), ()) + + subsf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (subsf,)) + self.assertEquals (subsf.get_locked (), True) + self.assertEquals (subsf.get_locks (), (subsf,)) + + subsf.lock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (subsf, subsf)) + self.assertEquals (subsf.get_locked (), True) + self.assertEquals (subsf.get_locks (), (subsf, subsf)) + + def test_pxarray_ref (self): + sf = pygame.Surface ((5, 5)) + ar = pygame.PixelArray (sf) + ar2 = pygame.PixelArray (sf) + + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (ar, ar2)) + + del ar + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (ar2,)) + + ar = ar2[:] + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (ar2,)) + + del ar + self.assertEquals (sf.get_locked (), True) + self.assertEquals (len (sf.get_locks ()), 1) + + def test_buffer (self): + sf = pygame.Surface ((5, 5)) + buf = sf.get_buffer () + + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (buf,)) + + sf.unlock () + self.assertEquals (sf.get_locked (), True) + self.assertEquals (sf.get_locks (), (buf,)) + + del buf + self.assertEquals (sf.get_locked (), False) + self.assertEquals (sf.get_locks (), ()) + + def test_surfarray_ref (self): + sf = pygame.Surface ((5, 5), 32) + for atype in pygame.surfarray.get_arraytypes (): + pygame.surfarray.use_arraytype (atype) + + ar = pygame.surfarray.pixels2d (sf) + self.assertEquals (sf.get_locked (), True) + + # Numpy uses the Surface's buffer. + if atype == "numeric": + self.assertEquals (sf.get_locks (), (ar,)) + + sf.unlock () + self.assertEquals (sf.get_locked (), True) + + del ar + self.assertEquals (sf.get_locked (), False) + self.assertEquals (sf.get_locks (), ()) + + #print "test_surfarray_ref - end" + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/surflock_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/surflock_test.pyc differ diff -Nru pygame-1.8.0release/test/sysfont_test.py pygame-1.8.1release/test/sysfont_test.py --- pygame-1.8.0release/test/sysfont_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/sysfont_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,53 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +################################################################################ + +class SysfontModuleTest(unittest.TestCase): + def test_create_aliases(self): + + # __doc__ (as of 2008-06-25) for pygame.sysfont.create_aliases: + + # + + self.assert_(test_not_implemented()) + + def test_initsysfonts(self): + + # __doc__ (as of 2008-06-25) for pygame.sysfont.initsysfonts: + + # + + self.assert_(test_not_implemented()) + + def test_initsysfonts_darwin(self): + + # __doc__ (as of 2008-06-25) for pygame.sysfont.initsysfonts_darwin: + + # + + self.assert_(test_not_implemented()) + + def test_initsysfonts_unix(self): + + # __doc__ (as of 2008-06-25) for pygame.sysfont.initsysfonts_unix: + + # + + self.assert_(test_not_implemented()) + + def test_initsysfonts_win32(self): + + # __doc__ (as of 2008-06-25) for pygame.sysfont.initsysfonts_win32: + + # + + self.assert_(test_not_implemented()) + +################################################################################ + +if __name__ == '__main__': + unittest.main() Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/sysfont_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/sysfont_test.pyc differ diff -Nru pygame-1.8.0release/test/test_test_.py pygame-1.8.1release/test/test_test_.py --- pygame-1.8.0release/test/test_test_.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/test_test_.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,3 @@ +while True: + pass + \ No newline at end of file diff -Nru pygame-1.8.0release/test/test_utils.py pygame-1.8.1release/test/test_utils.py --- pygame-1.8.0release/test/test_utils.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/test_utils.py 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,174 @@ +#################################### IMPORTS ################################### + +import tempfile, sys, pygame, time, os + +################################################################################ + +trunk_dir = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0] + +def trunk_relative_path(relative): + return os.path.normpath(os.path.join(trunk_dir, relative)) + +sys.path.insert(0, trunk_relative_path('.')) + +import test.unittest as unittest + +############################### INCOMPLETE TESTS ############################### +# TODO: PHASE THIS OUT +# Just prefix TODO test names with todo_. +# eg def todo_test_sanity__is_overrated(self): self.fail() +# Change test loader to load test_ and todo_ TestCase callables as tests + +fail_incomplete_tests = 0 + +def test_not_implemented(): + return not fail_incomplete_tests + +################################## TEMP FILES ################################## + +def get_tmp_dir(): + return tempfile.mkdtemp() + +################################################################################ + +def question(q): + return raw_input('%s ' % q.rstrip(' ')).lower().strip() == 'y' + +def prompt(p): + return raw_input('%s (and press enter to continue) ' % p.rstrip(' ')) + +#################################### HELPERS ################################### + +def rgba_between(value, minimum=0, maximum=255): + if value < minimum: return minimum + elif value > maximum: return maximum + else: return value + +def combinations(seqs): + """ + + Recipe 496807 from ActiveState Python CookBook + + Non recursive technique for getting all possible combinations of a sequence + of sequences. + + """ + + r=[[]] + for x in seqs: + r = [ i + [y] for y in x for i in r ] + return r + +def gradient(width, height): + """ + + Yields a pt and corresponding RGBA tuple, for every (width, height) combo. + Useful for generating gradients. + + Actual gradient may be changed, no tests rely on specific values. + + Used in transform.rotate lossless tests to generate a fixture. + + """ + + for l in xrange(width): + for t in xrange(height): + yield (l,t), tuple(map(rgba_between, (l, t, l, l+t))) + +def unordered_equality(seq1, seq2): + """ + + Tests to see if the contents of one sequence is contained in the other + and that they are of the same length. + + """ + + if len(seq1) != len(seq2): + return False + + for val in seq1: + if val not in seq2: + return False + + return True + +def rect_area_pts(rect): + for l in xrange(rect.left, rect.right): + for t in xrange(rect.top, rect.bottom): + yield l, t + +def rect_perimeter_pts(rect): + """ + + Returns pts ((L, T) tuples) encompassing the perimeter of a rect. + + The order is clockwise: + + topleft to topright + topright to bottomright + bottomright to bottomleft + bottomleft to topleft + + Duplicate pts are not returned + + """ + clock_wise_from_top_left = ( + ((l, rect.top) for l in xrange(rect.left, rect.right) ), + ((rect.right -1, t) for t in xrange(rect.top + 1, rect.bottom) ), + ((l, rect.bottom -1) for l in xrange(rect.right -2, rect.left -1, -1)), + ((rect.left, t) for t in xrange(rect.bottom -2, rect.top, -1)) + ) + + for line in clock_wise_from_top_left: + for pt in line: yield pt + +def rect_outer_bounds(rect): + """ + + Returns topleft outerbound if possible and then the other pts, that are + "exclusive" bounds of the rect + + ?------O + |RECT| ?|0)uterbound + |----| + O O + + """ + return ( + (rect.left is not 0 and [(rect.left-1, rect.top)] or []) + + [ rect.topright, + rect.bottomleft, + rect.bottomright] + ) + +def helpers_test(): + """ + + Lightweight test for helpers + + """ + + r = pygame.Rect(0, 0, 10, 10) + assert ( + rect_outer_bounds ( r ) == [(10, 0), # tr + ( 0, 10), # bl + (10, 10)] # br + ) + + assert len(list(rect_area_pts(r))) == 100 + + + r = pygame.Rect(0, 0, 3, 3) + assert list(rect_perimeter_pts(r)) == [ + (0, 0), (1, 0), (2, 0), # tl -> tr + (2, 1), (2, 2), # tr -> br + (1, 2), (0, 2), # br -> bl + (0, 1) # bl -> tl + ] + + print 'Tests: OK' + +if __name__ == '__main__': + helpers_test() + +################################################################################ Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/test_utils.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/test_utils.pyc differ diff -Nru pygame-1.8.0release/test/threads_test.py pygame-1.8.1release/test/threads_test.py --- pygame-1.8.0release/test/threads_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/threads_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,204 @@ +#################################### IMPORTS ################################### + +import test_utils, time +import test.unittest as unittest + +from test_utils import test_not_implemented + +from pygame.threads import FuncResult, tmap, WorkerQueue, Empty, STOP + +import pygame.threads as threads + +################################################################################ + +class WorkerQueueTypeTest(unittest.TestCase): + def test_usage_with_different_functions(self): + def f(x): + return x+1 + + def f2(x): + return x+2 + + wq = WorkerQueue() + fr = FuncResult(f) + fr2 = FuncResult(f2) + wq.do(fr, 1) + wq.do(fr2, 1) + wq.wait() + wq.stop() + + self.assert_(fr.result == 2) + self.assert_(fr2.result == 3) + + def test_do(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.WorkerQueue.do: + + # puts a function on a queue for running later. + # + return + + def test_stop(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.WorkerQueue.stop: + + # Stops the WorkerQueue, waits for all of the threads to finish up. + # + + wq = WorkerQueue() + + self.assert_(len(wq.pool) > 0) + for t in wq.pool: self.assert_(t.isAlive()) + + for i in xrange(200): wq.do(lambda x: x+1, i) + + wq.stop() + for t in wq.pool: self.assert_(not t.isAlive()) + + self.assert_(wq.queue.get() is STOP) + + def test_threadloop(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.WorkerQueue.threadloop: + + # Loops until all of the tasks are finished. + # + + self.assert_(test_not_implemented()) + + def test_wait(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.WorkerQueue.wait: + + # waits until all tasks are complete. + # + + wq = WorkerQueue() + + for i in xrange(2000): wq.do(lambda x: x+1, i) + wq.wait() + + self.assertRaises(Empty, wq.queue.get_nowait) + + wq.stop() + +class ThreadsModuleTest(unittest.TestCase): + def test_benchmark_workers(self): + "tags:long_running" + + # __doc__ (as of 2008-06-28) for pygame.threads.benchmark_workers: + + # does a little test to see if workers are at all faster. + # Returns the number of workers which works best. + # Takes a little bit of time to run, so you should only really call + # it once. + # You can pass in benchmark data, and functions if you want. + # a_bench_func - f(data) + # the_data - data to work on. + + self.assert_(test_not_implemented()) + + def test_init(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.init: + + # Does a little test to see if threading is worth it. + # Sets up a global worker queue if it's worth it. + # + # Calling init() is not required, but is generally better to do. + + threads.init(8) + + self.assert_(isinstance(threads._wq, WorkerQueue)) + + threads.quit() + + def test_quit(self): + + # __doc__ (as of 2008-06-28) for pygame.threads.quit: + + # cleans up everything. + # + + threads.init(8) + + threads.quit() + + self.assert_(threads._wq is None) + + def test_tmap(self): + # __doc__ (as of 2008-06-28) for pygame.threads.tmap: + + # like map, but uses a thread pool to execute. + # num_workers - the number of worker threads that will be used. If pool + # is passed in, then the num_workers arg is ignored. + # worker_queue - you can optionally pass in an existing WorkerQueue. + # wait - True means that the results are returned when everything is finished. + # False means that we return the [worker_queue, results] right away instead. + # results, is returned as a list of FuncResult instances. + # stop_on_error - + + func, data = lambda x:x+1, xrange(100) + + tmapped = tmap(func, data) + mapped = map(func, data) + + self.assert_(tmapped == mapped) + + def test_tmap__None_func_and_multiple_sequences(self): + return #TODO + + """ Using a None as func and multiple seqences """ + + res = tmap(None, [1,2,3,4]) + + res2 = tmap(None, [1,2,3,4], [22, 33, 44, 55]) + + res3 = tmap(None, [1,2,3,4], [22, 33, 44, 55, 66]) + + res4 = tmap(None, [1,2,3,4,5], [22, 33, 44, 55]) + + self.assertEqual([1, 2, 3, 4], res) + self.assertEqual([(1, 22), (2, 33), (3, 44), (4, 55)], res2) + self.assertEqual([(1, 22), (2, 33), (3, 44), (4, 55), (None, 66)], res3) + self.assertEqual([(1, 22), (2, 33), (3, 44), (4, 55), (5,None)], res4) + + def test_tmap__wait(self): + r = range(1000) + wq, results = tmap(lambda x:x, r, num_workers = 5, wait=False) + wq.wait() + r2 = map(lambda x:x.result, results) + self.assert_(r == r2) + + def test_FuncResult(self): + # as of 2008-06-28 + # FuncResult(f, callback = None, errback = None) + + # Used for wrapping up a function call so that the results are stored + # inside the instances result attribute. + + + # f - is the function we that we call + # callback(result) - this is called when the function(f) returns + # errback(exception) - this is called when the function(f) raises + # an exception. + + # Results are stored in result attribute + fr = FuncResult(lambda x:x+1) + fr(2) + self.assert_(fr.result == 3) + + # Exceptions are store in exception attribute + self.assert_(fr.exception is None, "when no exception raised") + + exception = ValueError('rast') + def x(sdf): + raise exception + fr = FuncResult(x) + fr(None) + self.assert_(fr.exception is exception) + +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/threads_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/threads_test.pyc differ diff -Nru pygame-1.8.0release/test/time_test.py pygame-1.8.1release/test/time_test.py --- pygame-1.8.0release/test/time_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/time_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,139 @@ +#################################### IMPORTS ################################### + +import test_utils +import test.unittest as unittest +from test_utils import test_not_implemented + +import pygame, time + +Clock = pygame.time.Clock + +################################################################################ + +class ClockTypeTest(unittest.TestCase): + def test_construction(self): + c = Clock() + self.assert_(c, "Clock can be constructed") + + def test_get_fps(self): + self.assert_(test_not_implemented()) + return + + # __doc__ (as of 2008-07-03) for pygame.time.Clock.get_fps: + + # Clock.get_fps(): return float + # compute the clock framerate + + delay_per_frame = 1 / 100.0 + + c = Clock() + + for f in range(100): + c.tick() + time.sleep(delay_per_frame) + + self.assert_(99.0 < c.get_fps() < 101.0) + + def test_tick(self): + self.assert_(test_not_implemented()) + return + + # __doc__ (as of 2008-07-03) for pygame.time.Clock.tick: + + # Clock.tick(framerate=0): return milliseconds + # control timer events + # update the clock + + collection = [] + c = Clock() + + c.tick() + for i in range(100): + time.sleep(0.005) + collection.append(c.tick()) + + for outlier in [min(collection), max(collection)]: + if outlier != 5: collection.remove(outlier) + + self.assert_(sum(collection) / len(collection) == 5) + + + def test_get_rawtime(self): + # __doc__ (as of 2008-07-03) for pygame.time.Clock.get_rawtime: + + # Clock.get_rawtime(): return milliseconds + # actual time used in the previous tick + + self.assert_(test_not_implemented()) + + def test_get_time(self): + + # __doc__ (as of 2008-07-03) for pygame.time.Clock.get_time: + + # Clock.get_time(): return milliseconds + # time used in the previous tick + + self.assert_(test_not_implemented()) + return + + c = Clock() + c.tick() #between here + time.sleep(0.02) + #get_time() + c.tick() # here + + time.sleep(0.02) + + self.assert_(20 <= c.get_time() <= 30) + + def test_tick_busy_loop(self): + + # __doc__ (as of 2008-07-03) for pygame.time.Clock.tick_busy_loop: + + # Clock.tick_busy_loop(framerate=0): return milliseconds + # control timer events + # update the clock + + self.assert_(test_not_implemented()) + +class TimeModuleTest(unittest.TestCase): + def test_delay(self): + + # __doc__ (as of 2008-06-25) for pygame.time.delay: + + # pygame.time.delay(milliseconds): return time + # pause the program for an amount of time + + self.assert_(test_not_implemented()) + + def test_get_ticks(self): + + # __doc__ (as of 2008-06-25) for pygame.time.get_ticks: + + # pygame.time.get_ticks(): return milliseconds + # get the time in milliseconds + + self.assert_(test_not_implemented()) + + def test_set_timer(self): + + # __doc__ (as of 2008-06-25) for pygame.time.set_timer: + + # pygame.time.set_timer(eventid, milliseconds): return None + # repeatedly create an event on the event queue + + self.assert_(test_not_implemented()) + + def test_wait(self): + + # __doc__ (as of 2008-06-25) for pygame.time.wait: + + # pygame.time.wait(milliseconds): return time + # pause the program for an amount of time + + self.assert_(test_not_implemented()) + +################################################################################ + +if __name__ == '__main__': + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/time_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/time_test.pyc differ diff -Nru pygame-1.8.0release/test/transform_test.py pygame-1.8.1release/test/transform_test.py --- pygame-1.8.0release/test/transform_test.py 2008-01-19 21:26:19.000000000 -0500 +++ pygame-1.8.1release/test/transform_test.py 2008-07-18 16:52:49.000000000 -0400 @@ -1,8 +1,11 @@ -import unittest +import test_utils +import test.unittest as unittest + +from test_utils import test_not_implemented + import pygame, pygame.transform from pygame.locals import * - def show_image(s, images = []): #pygame.display.init() size = s.get_rect()[2:] @@ -30,10 +33,6 @@ pygame.display.quit() pygame.display.init() - - - - def threshold(return_surf, surf, color, threshold = (0,0,0), diff_color = (0,0,0), change_return = True ): """ given the color it makes return_surf only have areas with the given colour. """ @@ -75,11 +74,8 @@ return similar - - -class TransformTest( unittest.TestCase ): - - def test_scale_alpha( self ): +class TransformModuleTest( unittest.TestCase ): + def test_scale__alpha( self ): """ see if set_alpha information is kept. """ @@ -95,7 +91,7 @@ self.assertEqual(s.get_alpha(),s2.get_alpha()) - def test_scale_destination( self ): + def test_scale__destination( self ): """ see if the destination surface can be passed in to use. """ @@ -120,18 +116,165 @@ # the wrong size surface is past in. Should raise an error. self.assertRaises(ValueError, pygame.transform.smoothscale, s, (33,64), s3) + + def test_threshold__honors_third_surface(self): + # __doc__ for threshold as of Tue 07/15/2008 + + # pygame.transform.threshold(DestSurface, Surface, color, threshold = + # (0,0,0,0), diff_color = (0,0,0,0), change_return = True, Surface = + # None): return num_threshold_pixels + + # When given the optional third + # surface, it would use the colors in that rather than the "color" + # specified in the function to check against. + + # New in pygame 1.8 + + ################################################################ + # Sizes + (w, h) = size = (32, 32) + + # the original_color is within the threshold of the threshold_color + threshold = (20, 20, 20, 20) + + original_color = (25,25,25,25) + threshold_color = (10, 10, 10, 10) + + # Surfaces + original_surface = pygame.Surface(size, pygame.SRCALPHA, 32) + dest_surface = pygame.Surface(size, pygame.SRCALPHA, 32) + + # Third surface is used in lieu of 3rd position arg color + third_surface = pygame.Surface(size, pygame.SRCALPHA, 32) + + # Color filling + original_surface.fill(original_color) + third_surface.fill(threshold_color) + + ################################################################ + # All pixels for color should be within threshold + # + pixels_within_threshold = pygame.transform.threshold ( + dest_surface, original_surface, threshold_color, + threshold, + 0, # diff_color + 0 # change_return + ) + + self.assertEqual(w*h, pixels_within_threshold) + + ################################################################ + # This should respect third_surface colors in place of 3rd arg + # color Should be the same as: surface.fill(threshold_color) + # all within threshold + + pixels_within_threshold = pygame.transform.threshold ( + dest_surface, + original_surface, + 0, # color (would fail if honored) + threshold, + 0, # diff_color + 0, # change_return + third_surface, + ) + self.assertEqual(w*h, pixels_within_threshold) + + + ################################################################ + # Change dest_surface on return (not expected) + + change_color = (255, 10, 10, 10) + + pixels_within_threshold = pygame.transform.threshold ( + dest_surface, + original_surface, + 0, # color + threshold, + change_color, # diff_color + 1, # change_return + third_surface, + ) + + # Return, of pixels within threshold is correct + self.assertEqual(w*h, pixels_within_threshold) + + # Size of dest surface is correct + dest_rect = dest_surface.get_rect() + dest_size = dest_rect.size + self.assertEqual(size, dest_size) + + # The color is not the change_color specified for every pixel As all + # pixels are within threshold + + for pt in test_utils.rect_area_pts(dest_rect): + self.assert_(dest_surface.get_at(pt) != change_color) + + ################################################################ + # Lowering the threshold, expecting changed surface + + pixels_within_threshold = pygame.transform.threshold ( + dest_surface, + original_surface, + 0, # color + 0, # threshold + change_color, # diff_color + 1, # change_return + third_surface, + ) + + # Return, of pixels within threshold is correct + self.assertEqual(0, pixels_within_threshold) + + # Size of dest surface is correct + dest_rect = dest_surface.get_rect() + dest_size = dest_rect.size + self.assertEqual(size, dest_size) + + # The color is the change_color specified for every pixel As all + # pixels are not within threshold + + for pt in test_utils.rect_area_pts(dest_rect): + self.assertEqual(dest_surface.get_at(pt), change_color) + + + def test_threshold__uneven_colors(self): + (w,h) = size = (16, 16) + + original_surface = pygame.Surface(size, pygame.SRCALPHA, 32) + dest_surface = pygame.Surface(size, pygame.SRCALPHA, 32) + + original_surface.fill(0) + + threshold_color_template = [5, 5, 5, 5] + threshold_template = [6, 6, 6, 6] + ################################################################ + for pos in range(len('rgb')): + threshold_color = threshold_color_template[:] + threshold = threshold_template + + threshold_color[pos] = 45 + threshold[pos] = 50 + + pixels_within_threshold = pygame.transform.threshold ( + dest_surface, original_surface, threshold_color, + threshold, + 0, # diff_color + 0 # change_return + ) + + self.assertEqual(w*h, pixels_within_threshold) + + ################################################################ - def test_threshold_surface(self): + def test_threshold__surface(self): """ """ #pygame.transform.threshold(DestSurface, Surface, color, threshold = (0,0,0,0), diff_color = (0,0,0,0), change_return = True): return num_threshold_pixels threshold = pygame.transform.threshold - - s1 = pygame.Surface((32,32)) s2 = pygame.Surface((32,32)) s3 = pygame.Surface((1,1)) @@ -215,10 +358,6 @@ self.assertEqual(s2.get_at((3,10)), (255,0,0,255)) self.assertEqual(s2.get_at((0,31)), (255,0,0,255)) self.assertEqual(s2.get_at((31,31)), (255,0,0,255)) - - - - def test_average_surfaces(self): """ @@ -250,8 +389,82 @@ self.assertRaises(TypeError, pygame.transform.average_surfaces, (s for s in [s1, s2,s3] )) + def test_chop(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.chop: + + # pygame.transform.chop(Surface, rect): return Surface + # gets a copy of an image with an interior area removed + + self.assert_(test_not_implemented()) + + def test_flip(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.flip: + + # pygame.transform.flip(Surface, xbool, ybool): return Surface + # flip vertically and horizontally + + self.assert_(test_not_implemented()) + + def test_rotate(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.rotate: + + # pygame.transform.rotate(Surface, angle): return Surface + # rotate an image + + self.assert_(test_not_implemented()) + + # color = (128, 128, 128, 255) + # s = pygame.Surface((3, 3)) + + # s.set_at((2, 0), color) + + # self.assert_(s.get_at((0, 0)) != color) + # s = pygame.transform.rotate(s, 90) + # self.assert_(s.get_at((0, 0)) == color) + + def test_rotate__lossless_at_90_degrees(self): + w, h = 32, 32 + s = pygame.Surface((w, h), pygame.SRCALPHA) + + gradient = list(test_utils.gradient(w, h)) + + for pt, color in gradient: s.set_at(pt, color) + + for rotation in (90, -90): + s = pygame.transform.rotate(s,rotation) + + for pt, color in gradient: + self.assert_(s.get_at(pt) == color) + + def test_rotozoom(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.rotozoom: + + # pygame.transform.rotozoom(Surface, angle, scale): return Surface + # filtered scale and rotation + + self.assert_(test_not_implemented()) + + def test_scale2x(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.scale2x: + + # pygame.transform.scale2x(Surface, DestSurface = None): Surface + # specialized image doubler + + self.assert_(test_not_implemented()) + + def test_smoothscale(self): + + # __doc__ (as of 2008-06-25) for pygame.transform.smoothscale: + # pygame.transform.smoothscale(Surface, (width, height), DestSurface = None): return Surface + # scale a surface to an arbitrary size smoothly + self.assert_(test_not_implemented()) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/transform_test.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/transform_test.pyc differ diff -Nru pygame-1.8.0release/test/unittest.py pygame-1.8.1release/test/unittest.py --- pygame-1.8.0release/test/unittest.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/unittest.py 2008-07-18 16:52:49.000000000 -0400 @@ -0,0 +1,815 @@ +#!/usr/bin/env python + +''' +Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's +Smalltalk testing framework. + +This module contains the core framework classes that form the basis of +specific test cases and suites (TestCase, TestSuite etc.), and also a +text-based utility class for running the tests and reporting the results + (TextTestRunner). + +Simple usage: + + import unittest + + class IntegerArithmenticTestCase(unittest.TestCase): + def testAdd(self): ## test method names begin 'test*' + self.assertEquals((1 + 2), 3) + self.assertEquals(0 + 1, 1) + def testMultiply(self): + self.assertEquals((0 * 10), 0) + self.assertEquals((5 * 8), 40) + + if __name__ == '__main__': + unittest.main() + +Further information is available in the bundled documentation, and from + + http://pyunit.sourceforge.net/ + +Copyright (c) 1999-2003 Steve Purcell +This module is free software, and you may redistribute it and/or modify +it under the same terms as Python itself, so long as this copyright message +and disclaimer are retained in their original form. + +IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF +THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, +AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, +SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +''' + +__author__ = "Steve Purcell" +__email__ = "stephen_purcell at yahoo dot com" +__version__ = "#Revision: 1.63 $"[11:-2] + +import time +import sys +import traceback +import os +import types + +############################################################################## +# Exported classes and functions +############################################################################## +__all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner', + 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader'] + +# Expose obsolete functions for backwards compatibility +__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) + + +############################################################################## +# Backward compatibility +############################################################################## +if sys.version_info[:2] < (2, 2): + False, True = 0, 1 + def isinstance(obj, clsinfo): + import __builtin__ + if type(clsinfo) in (tuple, list): + for cls in clsinfo: + if cls is type: cls = types.ClassType + if __builtin__.isinstance(obj, cls): + return 1 + return 0 + else: return __builtin__.isinstance(obj, clsinfo) + + +############################################################################## +# Test framework core +############################################################################## + +# All classes defined herein are 'new-style' classes, allowing use of 'super()' +__metaclass__ = type + +def _strclass(cls): + return "%s.%s" % (cls.__module__, cls.__name__) + +__unittest = 1 + +class TestResult: + """Holder for test result information. + + Test results are automatically managed by the TestCase and TestSuite + classes, and do not need to be explicitly manipulated by writers of tests. + + Each instance holds the total number of tests run, and collections of + failures and errors that occurred among those test runs. The collections + contain tuples of (testcase, exceptioninfo), where exceptioninfo is the + formatted traceback of the error that occurred. + """ + def __init__(self): + self.failures = [] + self.errors = [] + self.testsRun = 0 + self.shouldStop = 0 + + def startTest(self, test): + "Called when the given test is about to be run" + self.testsRun = self.testsRun + 1 + + def stopTest(self, test): + "Called when the given test has been run" + pass + + def addError(self, test, err): + """Called when an error has occurred. 'err' is a tuple of values as + returned by sys.exc_info(). + """ + self.errors.append((test, self._exc_info_to_string(err, test))) + + def addFailure(self, test, err): + """Called when an error has occurred. 'err' is a tuple of values as + returned by sys.exc_info().""" + self.failures.append((test, self._exc_info_to_string(err, test))) + + def addSuccess(self, test): + "Called when a test has completed successfully" + pass + + def wasSuccessful(self): + "Tells whether or not this result was a success" + return len(self.failures) == len(self.errors) == 0 + + def stop(self): + "Indicates that the tests should be aborted" + self.shouldStop = True + + def _exc_info_to_string(self, err, test): + """Converts a sys.exc_info()-style tuple of values into a string.""" + exctype, value, tb = err + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + if exctype is test.failureException: + # Skip assert*() traceback levels + length = self._count_relevant_tb_levels(tb) + return ''.join(traceback.format_exception(exctype, value, tb, length)) + return ''.join(traceback.format_exception(exctype, value, tb)) + + def _is_relevant_tb_level(self, tb): + return tb.tb_frame.f_globals.has_key('__unittest') + + def _count_relevant_tb_levels(self, tb): + length = 0 + while tb and not self._is_relevant_tb_level(tb): + length += 1 + tb = tb.tb_next + return length + + def __repr__(self): + return "<%s run=%i errors=%i failures=%i>" % \ + (_strclass(self.__class__), self.testsRun, len(self.errors), + len(self.failures)) + +class TestCase: + """A class whose instances are single test cases. + + By default, the test code itself should be placed in a method named + 'runTest'. + + If the fixture may be used for many test cases, create as + many test methods as are needed. When instantiating such a TestCase + subclass, specify in the constructor arguments the name of the test method + that the instance is to execute. + + Test authors should subclass TestCase for their own tests. Construction + and deconstruction of the test's environment ('fixture') can be + implemented by overriding the 'setUp' and 'tearDown' methods respectively. + + If it is necessary to override the __init__ method, the base class + __init__ method must always be called. It is important that subclasses + should not change the signature of their __init__ method, since instances + of the classes are instantiated automatically by parts of the framework + in order to be run. + """ + + # This attribute determines which exception will be raised when + # the instance's assertion methods fail; test methods raising this + # exception will be deemed to have 'failed' rather than 'errored' + + failureException = AssertionError + + def __init__(self, methodName='runTest'): + """Create an instance of the class that will use the named test + method when executed. Raises a ValueError if the instance does + not have a method with the specified name. + """ + try: + self._testMethodName = methodName + testMethod = getattr(self, methodName) + self._testMethodDoc = testMethod.__doc__ + except AttributeError: + raise ValueError, "no such test method in %s: %s" % \ + (self.__class__, methodName) + + def setUp(self): + "Hook method for setting up the test fixture before exercising it." + pass + + def tearDown(self): + "Hook method for deconstructing the test fixture after testing it." + pass + + def countTestCases(self): + return 1 + + def defaultTestResult(self): + return TestResult() + + def shortDescription(self): + """Returns a one-line description of the test, or None if no + description has been provided. + + The default implementation of this method returns the first line of + the specified test method's docstring. + """ + doc = self._testMethodDoc + return doc and doc.split("\n")[0].strip() or None + + def id(self): + return "%s.%s" % (_strclass(self.__class__), self._testMethodName) + + def __str__(self): + return "%s (%s)" % (self._testMethodName, _strclass(self.__class__)) + + def __repr__(self): + return "<%s testMethod=%s>" % \ + (_strclass(self.__class__), self._testMethodName) + + def run(self, result=None): + if result is None: result = self.defaultTestResult() + result.startTest(self) + testMethod = getattr(self, self._testMethodName) + try: + try: + self.setUp() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + return + + ok = False + try: + testMethod() + ok = True + except self.failureException: + result.addFailure(self, self._exc_info()) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + ok = False + if ok: result.addSuccess(self) + finally: + result.stopTest(self) + + def __call__(self, *args, **kwds): + return self.run(*args, **kwds) + + def debug(self): + """Run the test without collecting errors in a TestResult""" + self.setUp() + getattr(self, self._testMethodName)() + self.tearDown() + + def _exc_info(self): + """Return a version of sys.exc_info() with the traceback frame + minimised; usually the top level of the traceback frame is not + needed. + """ + exctype, excvalue, tb = sys.exc_info() + if sys.platform[:4] == 'java': ## tracebacks look different in Jython + return (exctype, excvalue, tb) + return (exctype, excvalue, tb) + + def fail(self, msg=None): + """Fail immediately, with the given message.""" + raise self.failureException, msg + + def failIf(self, expr, msg=None): + "Fail the test if the expression is true." + if expr: raise self.failureException, msg + + def failUnless(self, expr, msg=None): + """Fail the test unless the expression is true.""" + if not expr: raise self.failureException, msg + + def failUnlessRaises(self, excClass, callableObj, *args, **kwargs): + """Fail unless an exception of class excClass is thrown + by callableObj when invoked with arguments args and keyword + arguments kwargs. If a different type of exception is + thrown, it will not be caught, and the test case will be + deemed to have suffered an error, exactly as for an + unexpected exception. + """ + try: + callableObj(*args, **kwargs) + except excClass: + return + else: + if hasattr(excClass,'__name__'): excName = excClass.__name__ + else: excName = str(excClass) + raise self.failureException, "%s not raised" % excName + + def failUnlessEqual(self, first, second, msg=None): + """Fail if the two objects are unequal as determined by the '==' + operator. + """ + if not first == second: + raise self.failureException, \ + (msg or '%r != %r' % (first, second)) + + def failIfEqual(self, first, second, msg=None): + """Fail if the two objects are equal as determined by the '==' + operator. + """ + if first == second: + raise self.failureException, \ + (msg or '%r == %r' % (first, second)) + + def failUnlessAlmostEqual(self, first, second, places=7, msg=None): + """Fail if the two objects are unequal as determined by their + difference rounded to the given number of decimal places + (default 7) and comparing to zero. + + Note that decimal places (from zero) are usually not the same + as significant digits (measured from the most signficant digit). + """ + if round(second-first, places) != 0: + raise self.failureException, \ + (msg or '%r != %r within %r places' % (first, second, places)) + + def failIfAlmostEqual(self, first, second, places=7, msg=None): + """Fail if the two objects are equal as determined by their + difference rounded to the given number of decimal places + (default 7) and comparing to zero. + + Note that decimal places (from zero) are usually not the same + as significant digits (measured from the most signficant digit). + """ + if round(second-first, places) == 0: + raise self.failureException, \ + (msg or '%r == %r within %r places' % (first, second, places)) + + # Synonyms for assertion methods + + assertEqual = assertEquals = failUnlessEqual + + assertNotEqual = assertNotEquals = failIfEqual + + assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual + + assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual + + assertRaises = failUnlessRaises + + assert_ = assertTrue = failUnless + + assertFalse = failIf + + + +class TestSuite: + """A test suite is a composite test consisting of a number of TestCases. + + For use, create an instance of TestSuite, then add test case instances. + When all tests have been added, the suite can be passed to a test + runner, such as TextTestRunner. It will run the individual test cases + in the order in which they were added, aggregating the results. When + subclassing, do not forget to call the base class constructor. + """ + + def __init__(self, tests=()): + self._tests = [] + self.addTests(tests) + + def __repr__(self): + return "<%s tests=%s>" % (_strclass(self.__class__), self._tests) + + __str__ = __repr__ + + def __iter__(self): + return iter(self._tests) + + def countTestCases(self): + cases = 0 + for test in self._tests: + cases += test.countTestCases() + return cases + + def addTest(self, test): + # sanity checks + if not callable(test): + raise TypeError("the test to add must be callable") + if (isinstance(test, (type, types.ClassType)) and + issubclass(test, (TestCase, TestSuite))): + raise TypeError("TestCases and TestSuites must be instantiated " + "before passing them to addTest()") + self._tests.append(test) + + def addTests(self, tests): + if isinstance(tests, basestring): + raise TypeError("tests must be an iterable of tests, not a string") + for test in tests: + self.addTest(test) + + def run(self, result): + for test in self._tests: + if result.shouldStop: + break + test(result) + return result + + def __call__(self, *args, **kwds): + return self.run(*args, **kwds) + + def debug(self): + """Run the tests without collecting errors in a TestResult""" + for test in self._tests: test.debug() + + +class FunctionTestCase(TestCase): + """A test case that wraps a test function. + + This is useful for slipping pre-existing test functions into the + PyUnit framework. Optionally, set-up and tidy-up functions can be + supplied. As with TestCase, the tidy-up ('tearDown') function will + always be called if the set-up ('setUp') function ran successfully. + """ + + def __init__(self, testFunc, setUp=None, tearDown=None, + description=None): + TestCase.__init__(self) + self.__setUpFunc = setUp + self.__tearDownFunc = tearDown + self.__testFunc = testFunc + self.__description = description + + def setUp(self): + if self.__setUpFunc is not None: + self.__setUpFunc() + + def tearDown(self): + if self.__tearDownFunc is not None: + self.__tearDownFunc() + + def runTest(self): + self.__testFunc() + + def id(self): + return self.__testFunc.__name__ + + def __str__(self): + return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__) + + def __repr__(self): + return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc) + + def shortDescription(self): + if self.__description is not None: return self.__description + doc = self.__testFunc.__doc__ + return doc and doc.split("\n")[0].strip() or None + +############################################################################## +# Locating and loading tests +############################################################################## + +class TestLoader: + """This class is responsible for loading tests according to various + criteria and returning them wrapped in a Test + """ + testMethodPrefix = 'test' + sortTestMethodsUsing = cmp + suiteClass = TestSuite + + def loadTestsFromTestCase(self, testCaseClass): + """Return a suite of all tests cases contained in testCaseClass""" + if issubclass(testCaseClass, TestSuite): + raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?") + testCaseNames = self.getTestCaseNames(testCaseClass) + if not testCaseNames and hasattr(testCaseClass, 'runTest'): + testCaseNames = ['runTest'] + return self.suiteClass(map(testCaseClass, testCaseNames)) + + def loadTestsFromModule(self, module): + """Return a suite of all tests cases contained in the given module""" + tests = [] + for name in dir(module): + obj = getattr(module, name) + if (isinstance(obj, (type, types.ClassType)) and + issubclass(obj, TestCase)): + tests.append(self.loadTestsFromTestCase(obj)) + return self.suiteClass(tests) + + def loadTestsFromName(self, name, module=None): + """Return a suite of all tests cases given a string specifier. + + The name may resolve either to a module, a test case class, a + test method within a test case class, or a callable object which + returns a TestCase or TestSuite instance. + + The method optionally resolves the names relative to a given module. + """ + parts = name.split('.') + if module is None: + parts_copy = parts[:] + while parts_copy: + try: + module = __import__('.'.join(parts_copy)) + break + except ImportError: + del parts_copy[-1] + if not parts_copy: raise + parts = parts[1:] + obj = module + for part in parts: + parent, obj = obj, getattr(obj, part) + + if type(obj) == types.ModuleType: + return self.loadTestsFromModule(obj) + elif (isinstance(obj, (type, types.ClassType)) and + issubclass(obj, TestCase)): + return self.loadTestsFromTestCase(obj) + elif type(obj) == types.UnboundMethodType: + return parent(obj.__name__) + elif isinstance(obj, TestSuite): + return obj + elif callable(obj): + test = obj() + if not isinstance(test, (TestCase, TestSuite)): + raise ValueError, \ + "calling %s returned %s, not a test" % (obj,test) + return test + else: + raise ValueError, "don't know how to make test from: %s" % obj + + def loadTestsFromNames(self, names, module=None): + """Return a suite of all tests cases found using the given sequence + of string specifiers. See 'loadTestsFromName()'. + """ + suites = [self.loadTestsFromName(name, module) for name in names] + return self.suiteClass(suites) + + def getTestCaseNames(self, testCaseClass): + """Return a sorted sequence of method names found within testCaseClass + """ + def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix): + return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname)) + testFnNames = filter(isTestMethod, dir(testCaseClass)) + for baseclass in testCaseClass.__bases__: + for testFnName in self.getTestCaseNames(baseclass): + if testFnName not in testFnNames: # handle overridden methods + testFnNames.append(testFnName) + if self.sortTestMethodsUsing: + testFnNames.sort(self.sortTestMethodsUsing) + return testFnNames + + + +defaultTestLoader = TestLoader() + + +############################################################################## +# Patches for old functions: these functions should be considered obsolete +############################################################################## + +def _makeLoader(prefix, sortUsing, suiteClass=None): + loader = TestLoader() + loader.sortTestMethodsUsing = sortUsing + loader.testMethodPrefix = prefix + if suiteClass: loader.suiteClass = suiteClass + return loader + +def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): + return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass) + +def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite): + return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass) + +def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite): + return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module) + + +############################################################################## +# Text UI +############################################################################## + +class _WritelnDecorator: + """Used to decorate file-like objects with a handy 'writeln' method""" + def __init__(self,stream): + self.stream = stream + + def __getattr__(self, attr): + return getattr(self.stream,attr) + + def writeln(self, arg=None): + if arg: self.write(arg) + self.write('\n') # text-mode streams translate to \r\n if needed + + +class _TextTestResult(TestResult): + """A test result class that can print formatted text results to a stream. + + Used by TextTestRunner. + """ + separator1 = '=' * 70 + separator2 = '-' * 70 + + def __init__(self, stream, descriptions, verbosity): + TestResult.__init__(self) + self.stream = stream + self.showAll = verbosity > 1 + self.dots = verbosity == 1 + self.descriptions = descriptions + + def getDescription(self, test): + if self.descriptions: + return test.shortDescription() or str(test) + else: + return str(test) + + def startTest(self, test): + TestResult.startTest(self, test) + if self.showAll: + self.stream.write(self.getDescription(test)) + self.stream.write(" ... ") + + def addSuccess(self, test): + TestResult.addSuccess(self, test) + if self.showAll: + self.stream.writeln("ok") + elif self.dots: + self.stream.write('.') + + def addError(self, test, err): + TestResult.addError(self, test, err) + if self.showAll: + self.stream.writeln("ERROR") + elif self.dots: + self.stream.write('E') + + def addFailure(self, test, err): + TestResult.addFailure(self, test, err) + if self.showAll: + self.stream.writeln("FAIL") + elif self.dots: + self.stream.write('F') + + def printErrors(self): + if self.dots or self.showAll: + self.stream.writeln() + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + + def printErrorList(self, flavour, errors): + for test, err in errors: + self.stream.writeln(self.separator1) + self.stream.writeln("%s: %s" % (flavour, self.getDescription(test))) + self.stream.writeln(self.separator2) + self.stream.writeln("%s" % err) + + +class TextTestRunner: + """A test runner class that displays results in textual form. + + It prints out the names of tests as they are run, errors as they + occur, and a summary of the results at the end of the test run. + """ + def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1): + self.stream = _WritelnDecorator(stream) + self.descriptions = descriptions + self.verbosity = verbosity + + def _makeResult(self): + return _TextTestResult(self.stream, self.descriptions, self.verbosity) + + def run(self, test): + "Run the given test case or test suite." + result = self._makeResult() + startTime = time.time() + test(result) + stopTime = time.time() + timeTaken = stopTime - startTime + result.printErrors() + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run != 1 and "s" or "", timeTaken)) + self.stream.writeln() + if not result.wasSuccessful(): + self.stream.write("FAILED (") + failed, errored = map(len, (result.failures, result.errors)) + if failed: + self.stream.write("failures=%d" % failed) + if errored: + if failed: self.stream.write(", ") + self.stream.write("errors=%d" % errored) + self.stream.writeln(")") + else: + self.stream.writeln("OK") + return result + + + +############################################################################## +# Facilities for running tests from the command line +############################################################################## + +class TestProgram: + """A command-line program that runs a set of tests; this is primarily + for making test modules conveniently executable. + """ + USAGE = """\ +Usage: %(progName)s [options] [test] [...] + +Options: + -h, --help Show this message + -v, --verbose Verbose output + -q, --quiet Minimal output + +Examples: + %(progName)s - run default set of tests + %(progName)s MyTestSuite - run suite 'MyTestSuite' + %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething + %(progName)s MyTestCase - run all 'test*' test methods + in MyTestCase +""" + def __init__(self, module='__main__', defaultTest=None, + argv=None, testRunner=None, testLoader=defaultTestLoader): + if type(module) == type(''): + self.module = __import__(module) + for part in module.split('.')[1:]: + self.module = getattr(self.module, part) + else: + self.module = module + if argv is None: + argv = sys.argv + self.verbosity = 1 + self.defaultTest = defaultTest + self.testRunner = testRunner + self.testLoader = testLoader + self.progName = os.path.basename(argv[0]) + self.parseArgs(argv) + self.runTests() + + def usageExit(self, msg=None): + if msg: print msg + print self.USAGE % self.__dict__ + sys.exit(2) + + def parseArgs(self, argv): + import getopt + try: + options, args = getopt.getopt(argv[1:], 'hHvq', + ['help','verbose','quiet']) + for opt, value in options: + if opt in ('-h','-H','--help'): + self.usageExit() + if opt in ('-q','--quiet'): + self.verbosity = 0 + if opt in ('-v','--verbose'): + self.verbosity = 2 + if len(args) == 0 and self.defaultTest is None: + self.test = self.testLoader.loadTestsFromModule(self.module) + return + if len(args) > 0: + self.testNames = args + else: + self.testNames = (self.defaultTest,) + self.createTests() + except getopt.error, msg: + self.usageExit(msg) + + def createTests(self): + self.test = self.testLoader.loadTestsFromNames(self.testNames, + self.module) + + def runTests(self): + if self.testRunner is None: + self.testRunner = TextTestRunner(verbosity=self.verbosity) + result = self.testRunner.run(self.test) + sys.exit(not result.wasSuccessful()) + +main = TestProgram + +############################################################################## +# Executing this module from the command line +############################################################################## + +if __name__ == "__main__": + main(module=None) \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test/unittest.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test/unittest.pyc differ diff -Nru pygame-1.8.0release/test/util/buildpage/callproc.py pygame-1.8.1release/test/util/buildpage/callproc.py --- pygame-1.8.0release/test/util/buildpage/callproc.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/buildpage/callproc.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,48 @@ +import subprocess +import os +import sys + +def ExecuteAssertSuccess(cmd, *args, **keywords): + retcode, output = GetReturnCodeAndOutput(cmd, *args, **keywords) + if retcode != 0: + if isinstance(cmd, str): + cmd_line = cmd + else: + cmd_line = " ".join(cmd) + raise Exception("calling: "+cmd_line+" failed with output:\n"+output) + return output + +def GetReturnCodeAndOutput(cmd, dir=None, env=None, bufsize=-1, lineprintdiv=1): + if isinstance(cmd, str): + print "executing:",cmd + else: + print "executing:"," ".join(cmd) + if sys.platform == "darwin": + cmd = " ".join(cmd) + proc = subprocess.Popen(cmd, cwd=dir, env=env, shell=True, bufsize=bufsize, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + response = "" + finished = False + numlines = 0 + while not finished or proc.poll() == None: + line = proc.stdout.readline() + if line == "": + finished = True + else: + numlines += 1 + if numlines % lineprintdiv == 0: + sys.stdout.write(".") + response += line.replace("\r\n", "\n").replace("\r", "\n") + sys.stdout.write("\n") + return proc.wait(), response + +def InteractiveGetReturnCodeAndOutput(cmd, input_string, dir=None, env=None, bufsize=-1): + if isinstance(cmd, str): + print "executing:",cmd + else: + print "executing:"," ".join(cmd) + if sys.platform == "darwin": + cmd = " ".join(cmd) + proc = subprocess.Popen(cmd, cwd=dir, env=env, shell=True, bufsize=bufsize, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print "---------------" + response = proc.communicate(input_string)[0] + return proc.wait(), response diff -Nru pygame-1.8.0release/test/util/buildpage/config/build_config.ini.template pygame-1.8.1release/test/util/buildpage/config/build_config.ini.template --- pygame-1.8.0release/test/util/buildpage/config/build_config.ini.template 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/buildpage/config/build_config.ini.template 2008-07-07 01:58:16.000000000 -0400 @@ -0,0 +1,7 @@ +[DEFAULT] +python_path=C:/Python25 +make_package=bdist_howtomakepackage +package_mask=*.ext +test_dir_subpath=Lib/site-packages + +[build_env] diff -Nru pygame-1.8.0release/test/util/buildpage/config/upload.ini.template pygame-1.8.1release/test/util/buildpage/config/upload.ini.template --- pygame-1.8.0release/test/util/buildpage/config/upload.ini.template 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/buildpage/config/upload.ini.template 2008-07-07 01:58:16.000000000 -0400 @@ -0,0 +1,5 @@ +[DEFAULT] +host=website.com +user=user +remote_path=path/to/builds +scp=scp %(local_path)s %(user)s@%(host)s:%(remote_path)s/%(remote_file)s \ No newline at end of file diff -Nru pygame-1.8.0release/test/util/buildpage/update_build.py pygame-1.8.1release/test/util/buildpage/update_build.py --- pygame-1.8.0release/test/util/buildpage/update_build.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/buildpage/update_build.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,291 @@ +import os +import sys +import re +import callproc +import time +import glob +import ConfigParser +import shutil +import upload_results + +def write_file_lines(filename, line_list): + file_obj = file(filename, "w") + for line in line_list: + if not isinstance(line, str): + line = str(line) + file_obj.write(line) + file_obj.write("\n") + file_obj.close() + +def re_sub_file(file_path, match, replace): + content = file(file_path, "r").read() + content, count = re.subn(match, replace, content) + assert(count > 0) + output = file(file_path, "w") + output.write(content) + output.close() + +def assert_path_exists(path, description): + if not os.path.exists(path): + raise Exception("ERROR: can't find "+description+" at : "+path) + +def cleardir(path_to_clear): + for root, dirs, files in os.walk(path_to_clear, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + +def GetAndBrandLatestFromSVN(src_path): + output = callproc.ExecuteAssertSuccess(["svn","co","svn://seul.org/svn/pygame/trunk",src_path]) + + rev_match = re.search(r"(At)|(Checked out) revision ([0-9]+)\.", output) + latest_rev = int(rev_match.group(3)) + + callproc.ExecuteAssertSuccess(["svn","revert",src_path,"-R"]) + + version_source = src_path + '/lib/version.py' + re_sub_file(version_source, r"(ver\s*=\s*)'([0-9]+\.[0-9]+\.[0-9]+[^']*)'", r"\1'\2-svn"+str(latest_rev)+"'") + + return latest_rev + +def AppendBlameInfoToErrorsByFile(src_root, errors_by_file, line_func = lambda(x) : int(x[0])): + for error_file in errors_by_file: + print "blame for",error_file + ret_code, blame_output = callproc.GetReturnCodeAndOutput(["svn", "blame", error_file], src_root, lineprintdiv=100) + if ret_code == 0: + blame_lines = blame_output.split('\n') + for error in errors_by_file[error_file]: + line = line_func(error) + line_match = re.match(r"\s*([0-9]+)\s+([^ ]+)\s([^\r\n]*)", blame_lines[line - 1]) + rev = line_match.group(1) + user = line_match.group(2) + line = line_match.group(3) + error.append(user) + error.append(line) + error.append(rev) + +def GetBuildWarningsHTML(src_path, build_output): + warnings_by_file = {} + warning_matches = re.findall(r"^([^\(\s]+\.c)(?:\(|:)([0-9]+)(?:\)|:) ?:? warning:? ([^\r\n]+)[\r\n]", build_output, re.MULTILINE) + if len(warning_matches) > 0: + print "WARNING - found",len(warning_matches),"warnings" + for warning_match in warning_matches: + warning_file, line, message = warning_match + if warning_file not in warnings_by_file: + warnings_by_file[warning_file] = [] + warnings_by_file[warning_file].append([line, message]) + + AppendBlameInfoToErrorsByFile(src_path, warnings_by_file) + + web_friendly_warnings = [] + for warning_file in warnings_by_file: + for warning in warnings_by_file[warning_file]: + file_location = os.path.split(warning_file)[1] + ":" + warning[0] + " last rev: " + warning[-1] + ":" + warning[-3] + code_line = warning[-2].replace("<", "<").replace(">", ">").replace(" ", " ") + web_friendly_warnings.append(file_location + "
        warning:" + warning[1] + '
        ' + code_line + '') + return "
        ".join(web_friendly_warnings) + else: + print "no warnings found in:" + print build_output + return "" + +script_path = os.path.split(sys.argv[0])[0] +print 'executing pygamebuilder from:',script_path +if script_path != "": + os.chdir(script_path) +print "-------------------------" + +if not os.path.exists("./source"): + os.mkdir("./source") +src_path = './source/pygame' +latest_rev = GetAndBrandLatestFromSVN(src_path) + +if not os.path.exists("./output"): + os.mkdir("./output") + +if len(sys.argv) > 1: + config_file_list = "./config/build_"+sys.argv[1:]+".ini" +else: + config_file_list = glob.glob("./config/build_*.ini") + +for config_file in config_file_list: + + config_data = ConfigParser.SafeConfigParser() + config_data.read([config_file]) + platform_id = os.path.split(config_file)[1].replace(".ini", "").replace("build_", "") + + last_rev_filename = "./output/last_rev_"+platform_id+".txt" + + assert(config_data.has_option("DEFAULT", "python_path")) + python_path = config_data.get("DEFAULT", "python_path") + assert_path_exists(python_path, "expected python version") + + print "-------------------------" + print "building",platform_id,"with python at",python_path + try: + previous_rev = int(file(last_rev_filename, "r").read()) + except: + print "WARNING: could not find last rev built" + previous_rev = 0 + + if latest_rev == previous_rev: + print "exiting - already built rev",latest_rev + else: + print "building",latest_rev,"(last built %d)" % previous_rev + valid_build_attempt = True + + build_env = {} + for option in config_data.options("build_env"): + build_env[option] = config_data.get("build_env", option) + + ret_code, output = callproc.InteractiveGetReturnCodeAndOutput([python_path, "config.py"], "Y\nY\nY\n", src_path, build_env) + print output + if ret_code != 0: + print "ERROR running config.py!" + assert(ret_code == 0) + + dist_path = src_path + "/dist" + if os.path.exists(dist_path): + cleardir(dist_path) + + package_command = config_data.get("DEFAULT", "make_package") + ret_code, output = callproc.GetReturnCodeAndOutput([python_path, "setup.py", package_command], src_path, build_env) + if ret_code == 0: + build_warnings = GetBuildWarningsHTML(src_path, output) + + package_mask = config_data.get("DEFAULT", "package_mask") + installer_dist_path = glob.glob(dist_path+"/"+package_mask)[0] + print "got installer at:", installer_dist_path + installer_filename = os.path.split(installer_dist_path)[1] + installer_path = "./output/"+installer_filename + shutil.move(installer_dist_path, installer_path) + + temp_install_path = os.path.join(os.getcwd(), "install_test") + if os.path.exists(temp_install_path): + cleardir(temp_install_path) + else: + os.mkdir(temp_install_path) + + test_subpath = config_data.get("DEFAULT", "test_dir_subpath") + temp_install_pythonpath = os.path.join(temp_install_path, test_subpath) + os.makedirs(temp_install_pythonpath) + + test_env = {"PYTHONPATH":temp_install_pythonpath} + install_env = build_env.copy() + install_env.update(test_env) + + print "installing to:",temp_install_path + callproc.ExecuteAssertSuccess([python_path, "setup.py", "install", "--prefix", temp_install_path], src_path, install_env) + + print "running tests..." + ret_code, output = callproc.GetReturnCodeAndOutput([python_path, "run_tests.py"], src_path, test_env) + error_match = re.search("FAILED \([^\)]+=([0-9]+)\)", output) + if ret_code != 0 or error_match != None: + errors_by_file = {} + error_matches = error_matches = re.findall(r"^((?:ERROR|FAIL): [^\n]+)\n+-+\n+((?:[^\n]+\n)+)\n", output, re.MULTILINE) + if len(error_matches) > 0: + print "TESTS FAILED - found",len(error_matches),"errors" + for error_match in error_matches: + message, traceback = error_match + trace_top_match = re.search(r'File "([^"]+)", line ([0-9]+)', traceback) + error_file, line = trace_top_match.groups() + if error_file not in errors_by_file: + errors_by_file[error_file] = [] + errors_by_file[error_file].append([line, message, traceback]) + AppendBlameInfoToErrorsByFile(src_path, errors_by_file) + + for error_file in errors_by_file: + print "test failures in:", error_file + for error in errors_by_file[error_file]: + print error + + build_result = "Build Successful, Tests FAILED" + web_friendly_errors = [] + for error_file in errors_by_file: + for error in errors_by_file[error_file]: + file_location = os.path.split(error_file)[1] + ":" + error[0] + " last rev: " + error[-1] + ":" + error[-3] + web_friendly_errors.append(file_location + "
        " + error[1]) + build_errors = "
        ".join(web_friendly_errors) + else: + build_result = "Build Successful, Invalid Test Results" + build_errors = output.replace("\n", "
        ") + print "ERROR - tests failed! could not parse output:" + print output + else: + print "success! uploading..." + result_filename = "./output/prebuilt_%s.txt" % platform_id + write_file_lines(result_filename, [str(latest_rev), time.strftime("%Y-%m-%d %H:%M"), "uploading"]) + upload_results.scp(result_filename) + upload_results.scp(installer_path) + write_file_lines(result_filename, [str(latest_rev), time.strftime("%Y-%m-%d %H:%M"), installer_filename]) + upload_results.scp(result_filename) + build_result = "Build Successful, Tests Passed" + tests_run = re.findall(r"^loading ([\r\n]+)$", output, re.MULTILINE) + + test_text = [test + " passed" for test in tests_run] + build_errors = "
        ".join(test_text) + else: + error_matches = re.findall(r"^([^\(\s]+\.c)(?:\(|:)([0-9]+)(?:\)|:) ?:? error:? ([^\r\n]+)[\r\n]", output, re.MULTILINE) + if len(error_matches) > 0: + print "FAILED - found",len(error_matches),"errors" + errors_by_file = {} + for error_match in error_matches: + error_file, line, message = error_match + if error_file not in errors_by_file: + errors_by_file[error_file] = [] + errors_by_file[error_file].append([line, message]) + + AppendBlameInfoToErrorsByFile(src_path, errors_by_file) + + for error_file in errors_by_file: + print "errors in:",error_file + for error in errors_by_file[error_file]: + print error + + build_result = "Build FAILED, Tests not run" + web_friendly_errors = [] + for error_file in errors_by_file: + for error in errors_by_file[error_file]: + file_location = os.path.split(error_file)[1] + ":" + error[0] + " last rev: " + error[-1] + ":" + error[-3] + web_friendly_errors.append(file_location + "
        ERROR:" + error[1]) + build_errors = "
        ".join(web_friendly_errors) + else: + + link_error_matches = re.findall(r"^([^\(\s]+)\.obj : error ([^\r\n]+)[\r\n]", output, re.MULTILINE) + if len(link_error_matches) > 0: + build_result = "Link FAILED, Tests not run" + print "FAILED - found",len(link_error_matches),"errors" + build_errors = "" + for error_match in link_error_matches: + source_name, message = error_match + build_errors += source_name + " : " + message + "
        " + + else: + exception_match = re.search(r"^Traceback \(most recent call [a-z]+\):[\r\n]+(.+[^\r\n]+Error:[^\r\n]+)", output, re.MULTILINE | re.DOTALL) + if exception_match != None: + build_result = "Build FAILED, Tests not run" + build_errors = exception_match.group(1).replace("\n", "
        ") + + else: + build_result = "Build FAILED, Tests not run" + build_errors = "" + error_matches = re.findall(r"^error: ([^\r\n]+)", output, re.MULTILINE) + for error_match in error_matches: + build_errors += error_match + "
        " + + print "FAILED - unrecognized errors in:" + print output + + build_warnings = GetBuildWarningsHTML(src_path, output) + + if valid_build_attempt: + result_filename = "./output/buildresults_%s.txt" % platform_id + write_file_lines(result_filename, [latest_rev, time.strftime("%Y-%m-%d %H:%M"), build_result, build_errors, build_warnings]) + upload_results.scp(result_filename) + file(last_rev_filename, "w").write(str(latest_rev)) + print "COMPLETED build of",latest_rev + print "-------------------------" + else: + print "FAILED build attempt of",latest_rev + \ No newline at end of file diff -Nru pygame-1.8.0release/test/util/buildpage/upload_results.py pygame-1.8.1release/test/util/buildpage/upload_results.py --- pygame-1.8.0release/test/util/buildpage/upload_results.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/buildpage/upload_results.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,15 @@ +import os +import callproc +import ConfigParser + +def scp(local_path, remote_file = None): + if remote_file == None: + remote_file = os.path.split(local_path)[1] + config_file = "./config/upload.ini" + config_data = ConfigParser.SafeConfigParser() + config_data.read([config_file]) + + file_vars = {"local_path":local_path, "remote_file":remote_file} + command = config_data.get("DEFAULT", "scp", vars = file_vars) + callproc.ExecuteAssertSuccess(command) + \ No newline at end of file diff -Nru pygame-1.8.0release/test/util/gen_stubs.py pygame-1.8.1release/test/util/gen_stubs.py --- pygame-1.8.0release/test/util/gen_stubs.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/gen_stubs.py 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,317 @@ +#################################### IMPORTS ################################### + +from __future__ import with_statement +from optparse import OptionParser +from inspect import isclass, ismodule, getdoc, isgetsetdescriptor, getmembers + +import pygame, sys, datetime, re, types +import relative_indentation + +################################ TESTS DIRECTORY ############################### + +from os.path import normpath, join, dirname, abspath + +for relpath in ('../../','../'): + sys.path.insert(0, abspath(normpath( join(dirname(__file__), relpath) )) ) + +from test.unittest import TestCase + +#################################### IGNORES ################################### + +# Anything not wanted to be stubbed, such as aliases, or redundancies + +IGNORES = set([ + + pygame.rect.Rect.h, pygame.rect.Rect.w, + pygame.rect.Rect.x, pygame.rect.Rect.y, + + pygame.color.Color.a, pygame.color.Color.b, + pygame.color.Color.g, pygame.color.Color.r, + + # Ignore by class: all methods and getter setters cut from root + + # pygame.sprite.AbstractGroup, + + pygame.sprite.LayeredUpdates, + pygame.sprite.LayeredDirty, + pygame.sprite.OrderedUpdates, + pygame.sprite.GroupSingle, + pygame.sprite.RenderUpdates, + pygame.sprite.Group, + + pygame.image.tostring, +]) + +# pygame.sprite.Sprite.__module__ = 'pygame.sprite' +# pygame.sprite.Rect.__module__ = 'pygame' + +# Mapping of callable to module where it's defined +# Place any object that appears in modules other than it's home in here + +REAL_HOMES = { + pygame.rect.Rect : pygame.rect, + pygame.mask.from_surface : pygame.mask, + pygame.time.get_ticks : pygame.time, + pygame.event.Event : pygame.event, + pygame.event.event_name : pygame.event, + pygame.font.SysFont : pygame.font, + pygame.font.get_fonts : pygame.font, + pygame.font.match_font : pygame.font, +} + +MUST_INSTANTIATE = { + # BaseType / Helper # (Instantiator / Args) / Callable + + pygame.cdrom.CDType : (pygame.cdrom.CD, (0,)), + pygame.mixer.ChannelType : (pygame.mixer.Channel, (0,)), + pygame.time.Clock : (pygame.time.Clock, ()), + + # pygame.event.Event : None, + # pygame.joystick.Joystick : None, + # pygame.movie.Movie : None, + # pygame.mask.Mask : None, + # pygame.display.Info : None, +} + +def get_instance(type_): + pygame.init() + + helper = MUST_INSTANTIATE.get(type_) + if callable(helper): return helper() + helper, arg = helper + + try: + return helper(*arg) + except Exception, e: + raw_input("FAILED TO CREATE INSTANCE OF %s\n%s\n" + "Press Enter to continue" % (type_, e)) + return type_ + +##################################### TODO ##################################### + +""" + +Test + +""" + +################################ STUB TEMPLATES ################################ + +date = datetime.datetime.now().date() + +STUB_TEMPLATE = relative_indentation.Template ( ''' + def ${test_name}(self): + + # __doc__ (as of %s) for ${unitname}: + + ${comments} + + self.assert_(test_not_implemented()) ''' % date, + + strip_common = 0, strip_excess = 0 +) + +############################## REGULAR EXPRESSIONS ############################# + +module_re = re.compile(r"pygame\.([^.]+)\.?") + +#################################### OPTIONS ################################### + +opt_parser = OptionParser() + +opt_parser.add_option ( + "-l", "--list", action = 'store_true', + help = "list callable names not stubs" ) + +opt_parser.add_option ( + "-t", "--test_names", action = 'store_true', + help = "list test names not stubs" ) + +opt_parser.set_usage( +""" +$ %prog ROOT + +eg. + +$ %prog sprite.Sprite + +def test_add(self): + + # Doc string for pygame.sprite.Sprite: + + ... +""" +) + +################################### FUNCTIONS ################################## + +def module_in_package(module, pkg): + return ("%s." % pkg.__name__) in module.__name__ + +def get_package_modules(pkg): + modules = (getattr(pkg, x) for x in dir(pkg) if is_public(x)) + return [m for m in modules if ismodule(m) and module_in_package(m, pkg)] + # Don't want to pick up + # string module for example +def py_comment(input_str): + return '\n'.join ( + [('# ' + l) for l in input_str.split('\n')] + ) + +def is_public(obj_name): + try: obj_name += '' + except TypeError: obj_name = obj_name.__name__ + return not obj_name.startswith(('__','_')) + +def get_callables(obj, if_of = None, check_where_defined=False): + publics = (getattr(obj, x) for x in dir(obj) if is_public(x)) + callables = (x for x in publics if callable(x) or isgetsetdescriptor(x)) + + if check_where_defined: + callables = (c for c in callables if ( 'pygame' in c.__module__ or + ('__builtin__' == c.__module__ and isclass(c)) ) + and REAL_HOMES.get(c, 0) in (obj, 0)) + + if if_of: + callables = (x for x in callables if if_of(x)) # isclass, ismethod etc + + return set(callables) + +def get_class_from_test_case(TC): + TC = TC.__name__ + if 'Type' in TC: + return '.' + TC[:TC.rindex('Type')] + +def names_of(*args): + return tuple(map(lambda o: getattr(o, "__name__", str(o)), args)) + +def callable_name(*args): + args = [a for a in args if a] + return ('.'.join(['%s'] * len(args))) % names_of(*args) + +################################################################################ + +def test_stub(f, module, parent_class = None): + test_name = 'todo_test_%s' % f.__name__ + unit_name = callable_name(module, parent_class, f) + + stub = STUB_TEMPLATE.render ( + + test_name = test_name, + comments = py_comment(getdoc(f) or ''), + unitname = unit_name, + ) + + return unit_name, (test_name, stub) + +def make_stubs(seq, module, class_=None): + return dict( test_stub(c, module, class_) for c in seq ) + +def module_stubs(module): + stubs = {} + all_callables = get_callables(module, check_where_defined = True) - IGNORES + classes = set ( + c for c in all_callables if isclass(c) or c in MUST_INSTANTIATE + ) + + for class_ in classes: + base_type = class_ + + if class_ in MUST_INSTANTIATE: + class_ = get_instance(class_) + + stubs.update ( + make_stubs(get_callables(class_) - IGNORES, module, base_type) + ) + + stubs.update(make_stubs(all_callables - classes, module)) + + return stubs + +def package_stubs(package): + stubs = dict() + + for module in get_package_modules(package): + stubs.update(module_stubs(module)) + + return stubs + +################################################################################ + +TEST_NAME_RE = re.compile(r"test[_\d]+(.*)") + +def is_test(f): + return f.__name__.startswith(('test_', 'todo_')) + +def get_tested_from_testname(test): + tn = test.__name__ + separated = tn.rfind('__') + if separated != -1: tn = tn[:separated] + return TEST_NAME_RE.search(tn).group(1) + +################################################################################ + +def already_tested_in_module(module): + already = [] + + mod_name = module.__name__ + test_name = "%s_test" % mod_name[7:] + + try: test_file = __import__(test_name) + except ImportError: #TODO: create a test file? + return [] + + classes = get_callables(test_file, isclass) + test_cases = (t for t in classes if TestCase in t.__bases__) + + for class_ in test_cases: + class_tested = get_class_from_test_case(class_) or '' + + for test in get_callables(class_, is_test): + fname = get_tested_from_testname(test) + already.append("%s%s.%s" % (mod_name, class_tested, fname)) + + return already + +def already_tested_in_package(package): + already = [] + + for module in get_package_modules(package): + already += already_tested_in_module(module) + + return already + +################################################################################ + +def get_stubs(root): + module_root = module_re.search(root) + if module_root: + module = getattr(pygame, module_root.group(1)) + stubs = module_stubs(module) + tested = already_tested_in_module(module) + else: + stubs = package_stubs(pygame) + tested = already_tested_in_package(pygame) + + return stubs, tested + +if __name__ == "__main__": + options, args = opt_parser.parse_args() + if not sys.argv[1:]: + sys.exit(opt_parser.print_help()) + + root = args and args[0] or 'pygame' + if not root.startswith('pygame'): + root = '%s.%s' % ('pygame', root) + + stubs, tested = get_stubs(root) + + for fname in sorted(s for s in stubs.iterkeys() if s not in tested): + if not fname.startswith(root): continue # eg. module.Class + test_name, stub = stubs[fname] + + if options.list: print "%s," % fname + elif options.test_names: print test_name + else: print stub + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/test/util/gen_stubs_test.py pygame-1.8.1release/test/util/gen_stubs_test.py --- pygame-1.8.0release/test/util/gen_stubs_test.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/gen_stubs_test.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,14 @@ +######################### PYGAME UNITTEST STUBBER TESTS ######################## +""" + +TODO +==== + +tests for new stubber: deleted tests for missing units + +""" + +import pygame, unittest, gen_stubs + + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/test/util/relative_indentation.py pygame-1.8.1release/test/util/relative_indentation.py --- pygame-1.8.0release/test/util/relative_indentation.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test/util/relative_indentation.py 2008-07-07 01:58:17.000000000 -0400 @@ -0,0 +1,111 @@ +################ QUICK AND NASTY RELATIVE INDENTATION TEMPLATES ################ + +import re + +################################################################################ + +def strip_common_preceding_space(input_str): + "Strips preceding common space so only relative indentation remains" + + preceding_whitespace = re.compile("^(?:(\s*?)\S)?") + common_start = len(input_str) + + split = input_str.split("\n") + for line in (l for l in split if l.strip()): + for match in preceding_whitespace.finditer(line): + common_start = min(match.span(1)[1], common_start) + + return "\n".join( [l[common_start:] for l in split] ) + +def pad_secondary_lines(input_str, padding): + split = input_str.split('\n') + return '\n'.join( [split[0]] + [(padding+l) for l in split[1:]] ) + +################################################################################ + +ph_re = re.compile("\${(.*?)}") +multi_line_re = re.MULTILINE | re.DOTALL + +################################################################################ + +class Template(object): + def __call__(self): + return self + + def __init__(self, template, strip_common = True, strip_excess = True): + if strip_common: template = strip_common_preceding_space(template) + if strip_excess: template = template.strip() + '\n' + + self.template = template + + self.find_ph_offsets() + + def find_ph_offsets(self): + self.ph_offsets = dict() + + for lines in self.template.split('\n'): + for match in ph_re.finditer(lines): + self.ph_offsets[match.group(1)] = match.span()[0] + + def render(self, replacements = None, **kw): + if not replacements: replacements = kw + + # missing_ph = [k for k in self.ph_offsets if k not in replacements] + # excess_repl = [k for k in replacements if k not in self.ph_offsets] + + # A lot more performant + assert len(replacements) == len(self.ph_offsets) + + # errors = [] + # if missing_ph: errors.append ( + # 'Missing replacements: %s' % ', '.join(missing_ph) + # ) + # if excess_repl: errors.append ( + # 'Excess replacements: %s' % ', '.join(excess_repl) + # ) + # if errors: raise ValueError("\n".join(errors)) + + template = self.template[:] + for ph_name, replacement in replacements.iteritems(): + ph_offset = self.ph_offsets[ph_name] + + ph_search = re.search ("\${%s}" % ph_name, template, multi_line_re) + + ph_start, ph_end = ph_search.span() + + padded = pad_secondary_lines(replacement, ph_offset * ' ') + + template = template[0:ph_start] + padded + template[ph_end:] + + return template + +if __name__ == "__main__": + + print Template( ''' + + def test_${test_name}(self): + + """ + + ${docstring} + + """ + + ${comments} + + self.assert_(not_completed() ''' + + ).render( test_name = 'this_please', + docstring = 'Heading:\n\n Indented Line\n More', + comments = '# some comment\n# another comment', ) + + check_that = Template('works with ${one} on each line, or even ${two_four}') + + print check_that.render(one='one', two_four='two') + + # BUG: Multiline replacements with 2 ph per line will go awry -> .ph_offsets + # Outside scope of stubber + + print check_that.render(one='one\n one', two_four='two\n not_right\n') + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/test_runner.py pygame-1.8.1release/test_runner.py --- pygame-1.8.0release/test_runner.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/test_runner.py 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,266 @@ +################################################################################ + +import test.unittest as unittest + +import sys, os, re, StringIO, time, optparse +from inspect import getdoc, getmembers, isclass +from pprint import pformat + +import unittest_patch +from unittest_patch import StringIOContents + +################################################################################ + +def prepare_test_env(): + main_dir = os.path.split(os.path.abspath(__file__))[0] + test_subdir = os.path.join(main_dir, 'test') + sys.path.insert(0, test_subdir) + fake_test_subdir = os.path.join(test_subdir, 'run_tests__tests') + return main_dir, test_subdir, fake_test_subdir + +main_dir, test_subdir, fake_test_subdir = prepare_test_env() +import test_utils + +################################################################################ +# Set the command line options +# +# options are shared with run_tests.py so make sure not to conflict +# in time more will be added here + +opt_parser = optparse.OptionParser() + +opt_parser.add_option ( + "-i", "--incomplete", action = 'store_true', + help = "fail incomplete tests" ) + +opt_parser.add_option ( + "-s", "--subprocess", action = 'store_true', + help = "run test suites in subprocesses (default: same process)" ) + +opt_parser.add_option ( + "-d", "--dump", action = 'store_true', + help = "dump failures/errors as dict ready to eval" ) + +opt_parser.add_option ( + "-T", "--timings", type = 'int', default = 1, metavar = 'T', + help = "get timings for individual tests.\n" + "Run test T times, giving average time") + +opt_parser.add_option ( + "-e", "--exclude", default = '', + help = "exclude tests containing any of TAGS" ) + +opt_parser.add_option ( + "-w", "--show_output", action = 'store_true', + help = "show silenced stderr/stdout on errors" ) + +opt_parser.add_option ( + "-a", "--all", action = 'store_true', + help = "dump all results not just errors eg. -da" ) + +opt_parser.add_option ( + "-H", "--human", action = 'store_true', + help = "dump results as dict ready to eval if unsure " + "that pieced together results are correct " + "(subprocess mode)" ) + +opt_parser.add_option ( + "-m", "--multi_thread", metavar = 'THREADS', type = 'int', + help = "run subprocessed tests in x THREADS" ) + +opt_parser.add_option ( + "-t", "--time_out", metavar = 'SECONDS', type = 'int', + help = "kill stalled subprocessed tests after SECONDS" ) + +opt_parser.add_option ( + "-f", "--fake", metavar = "DIR", + help = "run fake tests in run_tests__tests/$DIR" ) + +opt_parser.add_option ( + "-p", "--python", metavar = "PYTHON", + help = "path to python excutable to run subproccesed tests\n" + "default (sys.executable): %s" % sys.executable) + +################################################################################ +# Human readable output +# + +COMPLETE_FAILURE_TEMPLATE = """ +====================================================================== +ERROR: all_tests_for (%(module)s.AllTestCases) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "test\%(module)s.py", line 1, in all_tests_for +subprocess completely failed with return code of %(return_code)s +cmd: %(cmd)s +test_env: %(test_env)s +working_dir: %(working_dir)s +return (top 5 lines): +%(raw_return)s + +""" # Leave that last empty line else build page regex won't match + # Text also needs to be vertically compressed + + +RAN_TESTS_DIV = (70 * "-") + "\nRan" + +DOTS = re.compile("^([FE.]*)$", re.MULTILINE) + +def combine_results(all_results, t): + """ + + Return pieced together results in a form fit for human consumption. Don't + rely on results if piecing together subprocessed results (single process + mode is fine). Was originally meant for that purpose but was found to be + unreliable. See options.dump or options.human for reliable results. + + """ + + all_dots = '' + failures = [] + + for module, results in sorted(all_results.items()): + output, return_code, raw_return = map ( + results.get, ('output','return_code', 'raw_return') + ) + + if not output or (return_code and RAN_TESTS_DIV not in output): + # would this effect the original dict? TODO + results['raw_return'] = ''.join(raw_return.splitlines(1)[:5]) + failures.append( COMPLETE_FAILURE_TEMPLATE % results ) + all_dots += 'E' + continue + + dots = DOTS.search(output).group(1) + all_dots += dots + + if 'E' in dots or 'F' in dots: + failures.append( output[len(dots)+1:].split(RAN_TESTS_DIV)[0] ) + + total_fails, total_errors = map(all_dots.count, 'FE') + total_tests = len(all_dots) + + combined = [all_dots] + if failures: combined += [''.join(failures).lstrip('\n')[:-1]] + combined += ["%s %s tests in %.3fs\n" % (RAN_TESTS_DIV, total_tests, t)] + + if not failures: combined += ['OK\n'] + else: combined += [ + 'FAILED (%s)\n' % ', '.join ( + (total_fails and ["failures=%s" % total_fails] or []) + + (total_errors and ["errors=%s" % total_errors] or []) + )] + + return total_tests, '\n'.join(combined) + +################################################################################ + +TEST_RESULTS_START = "<--!! TEST RESULTS START HERE !!-->" +TEST_RESULTS_RE = re.compile('%s\n(.*)' % TEST_RESULTS_START, re.DOTALL | re.M) + +def get_test_results(raw_return): + test_results = TEST_RESULTS_RE.search(raw_return) + if test_results: + try: return eval(test_results.group(1)) + except: raise Exception ( + "BUGGY TEST RESULTS EVAL:\n %s" % test_results.group(1) + ) + +################################################################################ +# ERRORS +# TODO + +def make_complete_failure_error(result): + return ( + "ERROR: all_tests_for (%s.AllTestCases)" % result['module'], + "Complete Failure (ret code: %s)" % result['return_code'], + result['test_file'], + '1', + ) + +# For combined results, plural +def test_failures(results): + errors = {} + total = sum(v.get('num_tests', 0) for v in results.values()) + for module, result in results.items(): + num_errors = ( + len(result.get('failures', [])) + len(result.get('errors', [])) + ) + if num_errors is 0 and result.get('return_code'): + result.update(RESULTS_TEMPLATE) + result['errors'].append(make_complete_failure_error(result)) + num_errors += 1 + total += 1 + if num_errors: errors.update({module:result}) + + return total, errors + +def combined_errs(results): + for result in results.values(): + combined_errs = result['errors'] + result['failures'] + for err in combined_errs: + yield err + +################################################################################ +# For complete failures (+ namespace saving) + +def from_namespace(ns, template): + if isinstance(template, dict): + return dict((i, ns.get(i, template[i])) for i in template) + return dict((i, ns[i]) for i in template) + +RESULTS_TEMPLATE = { + 'output' : '', + 'num_tests' : 0, + 'failures' : [], + 'errors' : [], + 'tests' : {}, +} + +################################################################################ + +def run_test(module, options): + suite = unittest.TestSuite() + test_utils.fail_incomplete_tests = options.incomplete + + m = __import__(module) + if m.unittest is not unittest: + raise ImportError( + "%s is not using correct unittest\n\n" % module + + "should be: %s\n is using: %s" % (unittest.__file__, + m.unittest.__file__) + ) + + print 'loading', module + + test = unittest.defaultTestLoader.loadTestsFromName(module) + suite.addTest(test) + + output = StringIO.StringIO() + runner = unittest.TextTestRunner(stream = output) + + results = runner.run(suite) + output = StringIOContents(output) + + num_tests = results.testsRun + failures = results.failures + errors = results.errors + tests = results.tests + + results = {module:from_namespace(locals(), RESULTS_TEMPLATE)} + + if options.subprocess: + print TEST_RESULTS_START + print pformat(results) + else: + return results + +################################################################################ + +if __name__ == '__main__': + options, args = opt_parser.parse_args() + unittest_patch.patch(options) + if not args: sys.exit('Called from run_tests.py, use that') + run_test(args[0], options) + +################################################################################ \ No newline at end of file Binary files /tmp/9GC0abmqLm/pygame-1.8.0release/test_runner.pyc and /tmp/IykkPtY_EN/pygame-1.8.1release/test_runner.pyc differ diff -Nru pygame-1.8.0release/unittest_patch.py pygame-1.8.1release/unittest_patch.py --- pygame-1.8.0release/unittest_patch.py 1969-12-31 19:00:00.000000000 -0500 +++ pygame-1.8.1release/unittest_patch.py 2008-07-28 05:36:49.000000000 -0400 @@ -0,0 +1,253 @@ +################################################################################ + +import test.unittest as unittest +import re, time, sys, StringIO +from inspect import getdoc + +# This is needed for correct tracebacks +__unittest = 1 + +################################################################################ +# Redirect stdout / stderr for the tests + +def redirect_output(): + yield sys.stderr, sys.stdout + sys.stderr, sys.stdout = StringIO.StringIO(), StringIO.StringIO() + yield sys.stderr, sys.stdout + +def restore_output(err, out): + sys.stderr, sys.stdout = err, out + +def StringIOContents(io): + io.seek(0) + return io.read() + +################################################################################ +# TestCase patching +# + +def TestCase_run(self, result=None): + if result is None: result = self.defaultTestResult() + result.startTest(self) + testMethod = getattr(self, self._testMethodName) + try: + + ######################################################################## + # Pre run: + + #TODO: only redirect output if not tagged interactive + + result.tests[self.dot_syntax_name()] = {} + tests = result.tests[self.dot_syntax_name()] + (realerr, realout), (stderr, stdout) = redirect_output() + + if 0 or 'interactive' in get_tags(testMethod): # DEBUG + restore_output(realerr, realout) + + t = time.time() + + ######################################################################## + + for i in range(self.times_run): + try: + self.setUp() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + return + + ok = False + try: + testMethod() + ok = True + except self.failureException: + result.addFailure(self, self._exc_info()) + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + result.addError(self, self._exc_info()) + ok = False + + if ok: + if i == 0: + result.addSuccess(self) + else: break + + ######################################################################## + # Post run + + t = (time.time() -t) / self.times_run + + restore_output(realerr, realout) + + tests["time"] = t + tests["stdout"] = StringIOContents(stdout) + tests["stderr"] = StringIOContents(stderr) + + ######################################################################## + + finally: + result.stopTest(self) + +################################################################################ +# TestResult +# + +def TestResult___init__(self): + self.failures = [] + self.errors = [] + self.tests = {} + self.testsRun = 0 + self.shouldStop = 0 + +# TODO: all this is available in the traceback object err +FILE_LINENUMBER_RE = re.compile(r'File "([^"]+)", line ([0-9]+)') + +def errorHandling(key): + def handling(self, test, err): + traceback = self._exc_info_to_string(err, test) + error_file, line_number = FILE_LINENUMBER_RE.search(traceback).groups() + error = ( + test.dot_syntax_name(), + traceback, + error_file, + line_number, #TODO: add locals etc + ) + getattr(self, key).append(error) + + # Append it to individual test dict for easy access + self.tests[test.dot_syntax_name()][key[:-1]] = error + + return handling + +################################################################################ + +def printErrorList(self, flavour, errors): + for test, err in ((e[0], e[1]) for e in errors): + self.stream.writeln(self.separator1) + self.stream.writeln("%s: %s" % (flavour, test)) + self.stream.writeln(self.separator2) + self.stream.writeln("%s" % err) + + # DUMP REDIRECTED STDERR / STDOUT ON ERROR / FAILURE + if self.show_redirected_on_errors: + stderr, stdout = map(self.tests[test].get, ('stderr','stdout')) + if stderr: self.stream.writeln("STDERR:\n%s" % stderr) + if stdout: self.stream.writeln("STDOUT:\n%s" % stdout) + +################################################################################ +# Exclude by tags +# + +TAGS_RE = re.compile(r"\|[tT]ags:(-?[ a-zA-Z,0-9_\n]+)\|", re.M) + +class TestTags: + def __init__(self): + self.memoized = {} + self.parent_modules = {} + + def get_parent_module(self, class_): + while class_ not in self.parent_modules: + self.parent_modules[class_] = __import__(class_.__module__) + return self.parent_modules[class_] + + def __call__(self, obj): + while obj not in self.memoized: + parent_class = obj.im_class + parent_module = self.get_parent_module(parent_class) + + module_tags = getattr(parent_module, '__tags__', []) + class_tags = getattr(parent_class, '__tags__', []) + + tags = TAGS_RE.search(getdoc(obj) or '') + if tags: test_tags = [t.strip() for t in tags.group(1).split(',')] + else: test_tags = [] + + combined = set() + for tags in (module_tags, class_tags, test_tags): + if not tags: continue + + add = set(t for t in tags if not t.startswith('-')) + remove = set(t[1:] for t in tags if t not in add) + + if add: combined.update(add) + if remove: combined.difference_update(remove) + + self.memoized[obj] = combined + + return self.memoized[obj] + +get_tags = TestTags() + +################################################################################ + +def getTestCaseNames(self, testCaseClass): + def test_wanted(attrname, testCaseClass=testCaseClass, + prefix=self.testMethodPrefix): + if not attrname.startswith(prefix): return False + else: + actual_attr = getattr(testCaseClass, attrname) + return ( + callable(actual_attr) and + not [t for t in get_tags(actual_attr) if t in self.exclude] + ) + + # TODO: + + # Replace test_not_implemented mechanism with technique that names the tests + # todo_test_xxxxxx, then when wanting to fail them, loads any members that + # startswith(test_prefix) + + # REGEX FOR TEST_NOT_IMPLEMENTED + # SEARCH: + # def (test_[^ ]+)((?:\s+#.*\n?)+\s+)self\.assert_\(test_not_implemented\(\)\) + # REPLACE: + # def todo_\1\2self.fail() + + testFnNames = filter(test_wanted, dir(testCaseClass)) + + for baseclass in testCaseClass.__bases__: + for testFnName in self.getTestCaseNames(baseclass): + if testFnName not in testFnNames: # handle overridden methods + testFnNames.append(testFnName) + + if self.sortTestMethodsUsing: + testFnNames.sort(self.sortTestMethodsUsing) + + return testFnNames + +################################################################################ + +def patch(options): + if options.incomplete: + unittest.TestLoader.testMethodPrefix = ( + unittest.TestLoader.testMethodPrefix, 'todo_' + ) + + unittest.TestLoader.getTestCaseNames = getTestCaseNames + unittest.TestLoader.exclude = ( + [e.strip() for e in options.exclude.split(',')] ) + + # Timing + unittest.TestCase.times_run = options.timings + unittest.TestCase.run = TestCase_run + unittest.TestCase.dot_syntax_name = lambda self: ( + "%s.%s"% (self.__class__.__name__, self._testMethodName) ) + + # Error logging + unittest.TestResult.show_redirected_on_errors = options.show_output + unittest.TestResult.__init__ = TestResult___init__ + unittest.TestResult.addError = errorHandling('errors') + unittest.TestResult.addFailure = errorHandling('failures') + + unittest._TextTestResult.printErrorList = printErrorList + +################################################################################ \ No newline at end of file diff -Nru pygame-1.8.0release/WHATSNEW pygame-1.8.1release/WHATSNEW --- pygame-1.8.0release/WHATSNEW 2008-03-28 17:45:44.000000000 -0400 +++ pygame-1.8.1release/WHATSNEW 2008-07-17 17:36:02.000000000 -0400 @@ -5,7 +5,100 @@ # BUG = fixed a bug that was (or could have been) crashing # # +Jul 18, 2008 + Added Surface.set_masks and .set_shifts useful for using data in + b,g,r,a mode... and other fun hacks. + +Jul 14, 2008 + [BUG] Fixed bug with transform.threshold() not honoring third surface + Updated transform.threshold() docs Thanks Nirav Patel + +Jul 10, 2008 + Added patch for filelikes in mixer.music.load thanks Forrest Voight! + +Jul 8, 2008 + run_tests.py improved with --help and running stuff in subprocesses. + +Jun 25, 2008 + Added many extra empty test stubs for untested things. Thanks Nicholas! + Test runner that works with subprocess and threads to isolate tests. + So that if a crash happens in one test the other tests still run. + Thanks Nicholas! + + [BUG] Added a fix for rotate on multiples of 90.0000001-90.99999 degrees. + Thanks Charlie Nolan, and Marcus! + +Jun 21, 2008 + Added BLEND_RGBA_* special flags for blit, and fill. + +Jun 16, 2008 + Reworked locking code. Locks are now more strict and can only be + removed by the object(s), that caused them. + New Surface.get_locks() method, which returns the currently existing + locks. + [BUG] Fixed Surface.get_locked() bug for Surfaces which do not + require locking, but have third-party locks attached. + +Jun 13, 2008 + [BUG] Fixed bug with mixer.get_init() Thanks Frankie Robertson! + [BUG] Fixed long alpha overflow bug in Surface.set_alpha(). + +Jun 9, 2008 + [BUG] Fixed locking and reference count leaks in Numeric surfarray + implementation. + +May 31, 2008 + Updated sprite documentation - mainly for new stuff added in pygame 1.8.0 + +May 24, 2008 + New Color class for color management. + +Apr 30, 2008 + updates to the sprite.py collision functions that update them to match + the modules coding style, include appropriate comments, and are + about 20% faster. It also includes a collide_circle_ratio function + for completeness, and perhaps most importantly, fixes a bug in + colide_mask which kept it from working correctly. Also added unittests + for the collision functions. Thanks John Krukoff! + + [BUG] sound crackles on windows; restored chunk size + calculation to pre 1143 + + Added \#!/usr/bin/env python to the top of examples that didn't have it. + +Apr 13, 2008 + [BUG] Fixed pygame.surfarray.pixels3d() for 24bpp surfaces using numpy. + Thanks Lorenz Quack! + +Apr 12, 2008 + [BUG] Fixed png saving, and saving jpeg with capital letter extensions + Thanks Nick Irvine! + +Apr 11, 2008 + New PixelArray.compare() method to compare two PixelArrays. + +Apr 8, 2008 + [BUG] Fixed pygame.draw.aaline() for cases in which only a single point + has to be drawn. + +Apr 4, 2008 + New PixelArray.replace() and PixelArray.extract() methods to quickly + replace or extract a certain color. + +Apr 3, 2008 + Added iter support to PixelArray. + +Apr 2, 2008 + [BUG] Fixed mask settings for 8-bit surfaces created by + surfarray.make_surface() + [BUG] Fixed integer color value assignment bound checking in PixelArray. + +Mar 30, 2008 + Added subscript support to PixelArray and PixelArray.make_surface() + to create a new surface from the PixelArray view. + Fixed mask namespace pollution and docs. +release_1_8_0release Mar 18, 2008 Updated credits. Mac OSX binary now has movie module working.