Commits

Anonymous committed a072db7

0.4 release candidate

Comments (0)

Files changed (25)

-CDROM & Joystick:
-	Both work, but the interface needs to be rethought. Currently, 
-	they are similar to the pysdl interface (which is too similar 
-	to the C interface)
+surfarray module
+	will swap the red and blue planes for you in some blitting
+	conditions. also have noticed the occasional crash with a
+	few combinations of bit depths and array types. (volunteers?)
 
 
-There are likely others. This is an early-ish release, and much
-testing is still pending.
+Keep your eye out for more! :]
 
 
 Pete Shinners       -       pete@shinners.org
-Version: 0.3
-November 20, 2000
+Version: 0.4
+December 13, 2000
 (Installation instructions and more in the "docs" directory...)
 
 
-With the 0.3 release things are looking really good. We've reached
+With the 0.4 release things are looking really good. We've reached
 the point where full python games are approachable with pygame.
 Thanks to all that have helped push things along this far. 
-
+(Especially coming through the bumpy road that was 0.2 through 0.3)
 
 
 pygame is a cross-platfrom library designed to make it easy to write
 Things could change that will break code relying on older versions. Any
 changes will be easy to make. There will be warning of coming changes,
 but just know that it will likely happen.
-(with the 0.3 release, the interface cement is drying!)(not joy and cd)
+(with the 0.4 release, the interface cement is stiff)
 
 Here are some main things i'd like to have done (or at least well
 looked at) by the time 1.0 rolls around. Most of these are ideas
 for covering other libraries and routiens SDL does not offer.
 
- * Joystick and CDROM modules cleaned up
  * Support for OpenGL (need to experiment with pyopengl)
  * Support for Piddle (drawing lines, shapes, text)
  * Surfarray with alpha and colormap support
 #This is a list of changes in pygame's history.
 
+Dec 13, 2000
+	display.update() is entirely better in many ways [BUG]
+
 Dec 3, 2000
 	fixed timing issues. negative time.delay() will become 0
 
 <br>
 <h2 align=center>CD</h2>
 The CD object represents a CDROM drive and allows you to
-access the CD inside that drive. All functions (except get_name())
+access the CD inside that drive. All functions (except get_name() and get_id())
 require the CD object to be initialized. This is done with the
 CD.init() function.
 <br>&nbsp;<br>

docs/ref/Rect.html

 rectangle cropped inside another</td></tr>
 
 
+<tr><td><a href=#collidelist>collidelist</a></td><td> -
+find overlapping rectangle</td></tr>
+
+
+<tr><td><a href=#collidelistall>collidelistall</a></td><td> -
+find all overlapping rectangles</td></tr>
+
+
 <tr><td><a href=#collidepoint>collidepoint</a></td><td> -
 point inside rectangle</td></tr>
 
 check overlapping rectangles</td></tr>
 
 
-<tr><td><a href=#colliderect>colliderect</a></td><td> -
-find overlapping rectangle</td></tr>
-
-
-<tr><td><a href=#colliderectall>colliderectall</a></td><td> -
-find all overlapping rectangles</td></tr>
-
-
 <tr><td><a href=#contains>contains</a></td><td> -
 check if rectangle fully inside another</td></tr>
 
 begin with, you will get a rectangle with 0 size.
 </ul><br>&nbsp;<br>
 
+<a name=collidelist><font size=+2><b>collidelist
+</b></font><br><font size=+1><tt>
+Rect.collidelist(rectstyle list) -> int index
+</tt></font><ul>
+Returns the index of the first rectangle in the
+list to overlap the base rectangle. Once an
+overlap is found, this will stop checking the
+remaining list. If no overlap is found, it will
+return -1.
+</ul><br>&nbsp;<br>
+
+<a name=collidelistall><font size=+2><b>collidelistall
+</b></font><br><font size=+1><tt>
+Rect.collidelistall(rectstyle list) -> int index
+</tt></font><ul>
+Returns a list of the indexes that contain
+rectangles overlapping the base rectangle. If no
+overlap is found, it will return an empty
+sequence.
+</ul><br>&nbsp;<br>
+
 <a name=collidepoint><font size=+2><b>collidepoint
 </b></font><br><font size=+1><tt>
 Rect.collidepoint(x, y) -> bool
 will be counted as overlapping.
 </ul><br>&nbsp;<br>
 
-<a name=colliderect><font size=+2><b>colliderect
-</b></font><br><font size=+1><tt>
-Rect.colliderect(rectstyle list) -> int index
-</tt></font><ul>
-Returns the index of the first rectangle in the
-list to overlap the base rectangle. Once an
-overlap is found, this will stop checking the
-remaining list. If no overlap is found, it will
-return -1.
-</ul><br>&nbsp;<br>
-
-<a name=colliderectall><font size=+2><b>colliderectall
-</b></font><br><font size=+1><tt>
-Rect.colliderectall(rectstyle list) -> int index
-</tt></font><ul>
-Returns a list of the indexes that contain
-rectangles overlapping the base rectangle. If no
-overlap is found, it will return an empty
-sequence.
-</ul><br>&nbsp;<br>
-
 <a name=contains><font size=+2><b>contains
 </b></font><br><font size=+1><tt>
 Rect.contains(rectstyle) -> bool

docs/ref/Surface.html

 surrounding pixel access. It is safe to lock() and unlock()
 surfaces that do not require locking. Nonetheless, you can check
 to see if a Surface really needs to be locked with the mustlock()
-function.
-<br>&nbsp;<br>
-The packed pixel values are a single interger with the red,
-green, and blue components packed in to match the current
-bitdepth for the Surface. You generally don't need to care how
-this is done, the map_rgb() and unmap_rgb() will convert back and
-forth between the packed pixel values for you. Information on how
-the pixels are packed can be retreived from the get_masks(),
-get_losses() and get_shifts() routines.<p>&nbsp;</p>Here is the quick breakdown of how packed pixels work (don't worry if
+function.<p>&nbsp;</p>Here is the quick breakdown of how packed pixels work (don't worry if
 you don't quite understand this, it is only here for informational
 purposes, it is not needed). Each colorplane mask can be used to
 isolate the values for a colorplane from the packed pixel color.
 Surface.map_rgb(RGBA) -> int
 </tt></font><ul>
 Uses the Surface format to convert RGBA into a mapped color value.
+<br>&nbsp;<br>
+This function is not as needed as normal C code using SDL. The pygame
+functions do not used mapped colors, so there is no need to map them.
 </ul><br>&nbsp;<br>
 
 <a name=mustlock><font size=+2><b>mustlock
 </tt></font><ul>
 This function returns the RGBA components for a mapped color
 value. If Surface has no per-pixel alpha, alpha will be 255 (opaque).
+<br>&nbsp;<br>
+This function is not as needed as normal C code using SDL. The pygame
+functions do not used mapped colors, so there is no need to unmap them.
 </ul><br>&nbsp;<br>
 
 

docs/ref/pygame.html

 <br>
 <h2 align=center>pygame</h2>
 Contains the core routines that are used by the rest of the
-pyGame modules. It's routines are merged directly into the pygame
-namespace. This mainly includes the autoinitialization init() and
+pygame modules. It's routines are merged directly into the pygame
+namespace. This mainly includes the auto-initialization init() and
 quit() routines.
 <br>&nbsp;<br>
 There is a small module named 'locals' that also gets merged into
 
 
 <tr><td><a href=#Surface>Surface</a></td><td> -
-Surface</td></tr>
+create a new Surface</td></tr>
 
 
 <tr><td><a href=#get_error>get_error</a></td><td> -
 
 <a name=Surface><font size=+2><b>Surface
 </b></font><br><font size=+1><tt>
-pygame.Surface(size, [flags, [depth|Surface, [masks]]]) ->
+pygame.Surface(size, [flags, [depth|Surface, [masks]]]) -> Surface
 </tt></font><ul>
-<br>&nbsp;<br>
 Creates a new surface object. Size is a 2-int-sequence containing
 width and height. Depth is the number of bits used per pixel. If
 omitted, depth will use the current display depth. Masks is a

docs/ref/pygame_cdrom.html

 You can call the CD.get_name() and CD.get_id() functions
 without initializing the CD object.
 <br>&nbsp;<br>
-Be sure to understand the difference between the cdrom module
+Be sure to understand there is a difference between the cdrom module
 and the CD objects.
 
 <hr>

docs/ref/pygame_display.html

 After you have initialized your video mode, you can take the
 surface that was returned and write to it like any other Surface
 object. Be sure to call update() or flip() to keep what is on the
-screen synchronized with what is on the surface.
+screen synchronized with what is on the surface. Be sure not to call
+display routines that modify the display surface while it is locked.
 
 <hr>
 

docs/ref/pygame_event.html

 events default to allowed.
 <br>&nbsp;<br>
 Also know that you will not receive any events from a joystick
-device, until you have opened that joystick from the joystick
-module.<p>&nbsp;</p>An Event object contains an event type and a readonly set of
+device, until you have initialized that individual joystick from
+the joystick module.<p>&nbsp;</p>An Event object contains an event type and a readonly set of
 member data. The Event object contains no method functions, just
 member data. Event objects are retrieved from the pygame event
 queue. You can create your own new events with the
-pygame.event.event() function.
+pygame.event.Event() function.
 <br>&nbsp;<br>
 All Event objects contain an event type identifier in the
 Event.type member. You may also get full access to the Event's

docs/ref/pygame_font.html

 Most of the work done with fonts are done by using the actual
 Font objects. The module by itself only has routines to
 initialize the module and create Font objects with
-pygame.font.font().
+pygame.font.Font().
 
 <hr>
 

docs/ref/pygame_joystick.html

 any input handling. Once a joystick object has been initialized, it will
 start to send joystick events to the input queue.
 <br>&nbsp;<br>
-Be sure to understand the difference between the joystick module
+Be sure to understand there is a difference between the joystick module
 and the Joystick objects.
 
 <hr>

docs/ref/pygame_mixer.html

 functions are not that good, so it is best if you initialize
 pygame.mixer to the same format as your sound resources. Also
 setting the mixer frequency to even multiples of your sound
-resources will result in a clean conversion.
+resources will result in a cleaner conversion.
 <br>&nbsp;<br>
 The mixer also contains a special channel for music. You can
 control the music channel through pygame.mixer.music./

docs/ref/pygame_time.html

 pygame.time.delay(millseconds) -> none
 </tt></font><ul>
 Will pause for a given number of milliseconds.
-The maximum resolution of this delay is 10 milliseconds. The
-time you request to delay will be truncated down to the nearest
-10 milliseconds. This will help <u>delay()</u> return a little before
-the requested time has passed, instead of a little afterwards.
 </ul><br>&nbsp;<br>
 
 <a name=get_ticks><font size=+2><b>get_ticks

examples/aliens.py

         keystate = pygame.key.get_pressed()
         if keystate[K_ESCAPE] or pygame.event.peek(QUIT):
             break
+        
 
         if difficulty:
             difficulty -= 1
 #headers to install
 headers = glob.glob(os.path.join('src', '*.h'))
 
+
 #get compile info for all extensions
 try:
     extensions = read_setup_file('Setup')
 except IOError:
     raise SystemExit, 'Need a "Setup" file for compiling.' + morehelp
 
+
 #extra files to install
+data_path = os.path.join(distutils.sysconfig.get_python_lib(), 'pygame')
 data_files = []
 
 #add non .py files in lib directory
             if os.path.isfile(p) and p not in data_files:
                 data_files.append(p)
 
+
 #don't need to actually compile the COPYLIB modules, remove them
 for e in extensions[:]:
     if e.name.startswith('COPYLIB_'):
         extensions.remove(e)
 
+
 #we can detect the presence of python dependencies, remove any unfound
 pythondeps = {'surfarray': ['Numeric']}
 for e in extensions[:]:
 
 
 setup (name = "pygame",
-       version = '0.3',
+       version = '0.4',
        maintainer = "Pete Shinners",
-       maintainer_email = "shredwheat@mediaone.net",
+       maintainer_email = "pygame@seul.org",
        description = "Python Game Development module",
        url = "http://pygame.seul.org",
        packages = [''],
        extra_path = ('pygame/ignore', 'pygame'),
        headers = headers,
        ext_modules = extensions,
-       data_files = [['pygame', data_files]]
+       data_files = [[data_path, data_files]]
      )  
 
     /*DOC*/ static char doc_pygame_MODULE[] =
     /*DOC*/    "Contains the core routines that are used by the rest of the\n"
-    /*DOC*/    "pyGame modules. It's routines are merged directly into the pygame\n"
-    /*DOC*/    "namespace. This mainly includes the autoinitialization init() and\n"
+    /*DOC*/    "pygame modules. It's routines are merged directly into the pygame\n"
+    /*DOC*/    "namespace. This mainly includes the auto-initialization init() and\n"
     /*DOC*/    "quit() routines.\n"
     /*DOC*/    "\n"
     /*DOC*/    "There is a small module named 'locals' that also gets merged into\n"
 
     /*DOC*/ static char doc_CD_MODULE[] =
     /*DOC*/    "The CD object represents a CDROM drive and allows you to\n"
-    /*DOC*/    "access the CD inside that drive. All functions (except get_name())\n"
+    /*DOC*/    "access the CD inside that drive. All functions (except get_name() and get_id())\n"
     /*DOC*/    "require the CD object to be initialized. This is done with the\n"
     /*DOC*/    "CD.init() function.\n"
     /*DOC*/    "\n"
 
 
 /*BAD things happen when out-of-bound rects go to updaterect*/
-static void screencroprect(GAME_Rect* r, int w, int h)
+static int screencroprect(GAME_Rect* r, int w, int h)
 {
-	if(r->x >= w || r->y >= h)
-		r->x = r->y = r->w = r->h = 0;
+	if(r->x >= w || r->y >= h || r->x < 0 || r->y < 0)
+		return 0;
 	else
 	{
 		if(r->x < 0) r->x = 0;
 		if(r->x + r->w >= w) r->w = (w-1)-r->x;
 		if(r->y + r->h >= h) r->h = (h-1)-r->y;
 	}
+	return 1;
 }
 
     /*DOC*/ static char doc_update[] =
 		if(!screen)
 			return RAISE(PyExc_SDLError, SDL_GetError());
 		
-		screencroprect(gr, screen->w, screen->h);
-		SDL_UpdateRect(screen, gr->x, gr->y, gr->w, gr->h);
+		if(screencroprect(gr, screen->w, screen->h))
+			SDL_UpdateRect(screen, gr->x, gr->y, gr->w, gr->h);
 	}
 	else
 	{
 		PyObject* seq;
 		PyObject* r;
-		int loop, num;
+		int loop, num, count;
 		SDL_Rect* rects;
 
 		if(PyTuple_Size(arg) != 1)
 		num = PySequence_Length(seq);
 		rects = PyMem_New(SDL_Rect, num);
 		if(!rects) return NULL;
+		count = 0;
 		for(loop = 0; loop < num; ++loop)
 		{
 			r = PySequence_GetItem(seq, loop);
+			if(r == Py_None)
+			{
+				Py_DECREF(r);
+				continue;
+			}
 			gr = GameRect_FromObject(r, &temp);
 			if(!gr)
 			{
 				PyMem_Free(rects);
 				return RAISE(PyExc_ValueError, "update_rects requires a single list of rects");
 			}
-			screencroprect(gr, screen->w, screen->h);
-			rects[loop].x = gr->x;
-			rects[loop].y = gr->y;
-			rects[loop].w = (unsigned short)gr->w;
-			rects[loop].h = (unsigned short)gr->h;
+			if(!screencroprect(gr, screen->w, screen->h))
+				continue;
+			rects[count].x = gr->x;
+			rects[count].y = gr->y;
+			rects[count].w = (unsigned short)gr->w;
+			rects[count].h = (unsigned short)gr->h;
+			++count;
 		}
 
-		SDL_UpdateRects(screen, num, rects);
+		SDL_UpdateRects(screen, count, rects);
 		PyMem_Free(rects);
 	}
 	
     /*DOC*/    "After you have initialized your video mode, you can take the\n"
     /*DOC*/    "surface that was returned and write to it like any other Surface\n"
     /*DOC*/    "object. Be sure to call update() or flip() to keep what is on the\n"
-    /*DOC*/    "screen synchronized with what is on the surface.\n"
+    /*DOC*/    "screen synchronized with what is on the surface. Be sure not to call\n"
+    /*DOC*/    "display routines that modify the display surface while it is locked.\n"
     /*DOC*/ ;
 
 void initdisplay()
     /*DOC*/    "member data. The Event object contains no method functions, just\n"
     /*DOC*/    "member data. Event objects are retrieved from the pygame event\n"
     /*DOC*/    "queue. You can create your own new events with the\n"
-    /*DOC*/    "pygame.event.event() function.\n"
+    /*DOC*/    "pygame.event.Event() function.\n"
     /*DOC*/    "\n"
     /*DOC*/    "All Event objects contain an event type identifier in the\n"
     /*DOC*/    "Event.type member. You may also get full access to the Event's\n"
     /*DOC*/    "events default to allowed.\n"
     /*DOC*/    "\n"
     /*DOC*/    "Also know that you will not receive any events from a joystick\n"
-    /*DOC*/    "device, until you have opened that joystick from the joystick\n"
-    /*DOC*/    "module.\n"
+    /*DOC*/    "device, until you have initialized that individual joystick from\n"
+    /*DOC*/    "the joystick module.\n"
     /*DOC*/ ;
 
 void initevent()
     /*DOC*/    "Most of the work done with fonts are done by using the actual\n"
     /*DOC*/    "Font objects. The module by itself only has routines to\n"
     /*DOC*/    "initialize the module and create Font objects with\n"
-    /*DOC*/    "pygame.font.font().\n"
+    /*DOC*/    "pygame.font.Font().\n"
     /*DOC*/ ;
 
 void initfont()
     /*DOC*/    "functions are not that good, so it is best if you initialize\n"
     /*DOC*/    "pygame.mixer to the same format as your sound resources. Also\n"
     /*DOC*/    "setting the mixer frequency to even multiples of your sound\n"
-    /*DOC*/    "resources will result in a clean conversion.\n"
+    /*DOC*/    "resources will result in a cleaner conversion.\n"
     /*DOC*/    "\n"
     /*DOC*/    "The mixer also contains a special channel for music. You can\n"
     /*DOC*/    "control the music channel through pygame.mixer.music./\n"
 		if(PySequence_Length(obj) == 2)
 		{
 			PyObject* sub = PySequence_GetItem(obj, 0);
-			if(!sub || !PySequence_Check(sub)) {Py_XDECREF(sub); return NULL;}
+			if(!sub || !PySequence_Check(sub) || PySequence_Length(sub)!=2)
+				{Py_XDECREF(sub); return NULL;}
 			if(!ShortFromObjIndex(sub, 0, &val)) {Py_DECREF(sub); return NULL;} temp->x = val;
 			if(!ShortFromObjIndex(sub, 1, &val)) {Py_DECREF(sub); return NULL;} temp->y = val;
 			sub = PySequence_GetItem(obj, 1);
-			if(!sub || !PySequence_Check(sub)) {Py_XDECREF(sub); return NULL;}
+			if(!sub || !PySequence_Check(sub) || PySequence_Length(sub)!=2)
+				{Py_XDECREF(sub); return NULL;}
 			if(!ShortFromObjIndex(sub, 0, &val)) {Py_DECREF(sub); return NULL;} temp->w = val;
 			if(!ShortFromObjIndex(sub, 1, &val)) {Py_DECREF(sub); return NULL;} temp->h = val;
 			return temp;
 
 
     /*DOC*/ static char doc_collidelist[] =
-    /*DOC*/    "Rect.colliderect(rectstyle list) -> int index\n"
+    /*DOC*/    "Rect.collidelist(rectstyle list) -> int index\n"
     /*DOC*/    "find overlapping rectangle\n"
     /*DOC*/    "\n"
     /*DOC*/    "Returns the index of the first rectangle in the\n"
 
 
     /*DOC*/ static char doc_collidelistall[] =
-    /*DOC*/    "Rect.colliderectall(rectstyle list) -> int index\n"
+    /*DOC*/    "Rect.collidelistall(rectstyle list) -> int index\n"
     /*DOC*/    "find all overlapping rectangles\n"
     /*DOC*/    "\n"
     /*DOC*/    "Returns a list of the indexes that contain\n"
     /*DOC*/    "convert RGB into a mapped color\n"
     /*DOC*/    "\n"
     /*DOC*/    "Uses the Surface format to convert RGBA into a mapped color value.\n"
-    /*DOC*/ ;
+    /*DOC*/    "\n"
+    /*DOC*/    "This function is not as needed as normal C code using SDL. The pygame\n"
+    /*DOC*/    "functions do not used mapped colors, so there is no need to map them.\n"
+   /*DOC*/ ;
 
 static PyObject* surf_map_rgb(PyObject* self,PyObject* args)
 {
     /*DOC*/    "\n"
     /*DOC*/    "This function returns the RGBA components for a mapped color\n"
     /*DOC*/    "value. If Surface has no per-pixel alpha, alpha will be 255 (opaque).\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "This function is not as needed as normal C code using SDL. The pygame\n"
+    /*DOC*/    "functions do not used mapped colors, so there is no need to unmap them.\n"
     /*DOC*/ ;
 
 static PyObject* surf_unmap_rgb(PyObject* self,PyObject* args)
     /*DOC*/    "surfaces that do not require locking. Nonetheless, you can check\n"
     /*DOC*/    "to see if a Surface really needs to be locked with the mustlock()\n"
     /*DOC*/    "function.\n"
-    /*DOC*/    "\n"
-    /*DOC*/    "The packed pixel values are a single interger with the red,\n"
-    /*DOC*/    "green, and blue components packed in to match the current\n"
-    /*DOC*/    "bitdepth for the Surface. You generally don't need to care how\n"
-    /*DOC*/    "this is done, the map_rgb() and unmap_rgb() will convert back and\n"
-    /*DOC*/    "forth between the packed pixel values for you. Information on how\n"
-    /*DOC*/    "the pixels are packed can be retreived from the get_masks(),\n"
-    /*DOC*/    "get_losses() and get_shifts() routines.\n"
     /*DOC*/ ;
 #if 0 /*extra help, only for docs*/
     /*DOC*/ static char doc_Surface_EXTRA[] =
 /* surface module functions */
 
     /*DOC*/ static char doc_Surface[] =
-    /*DOC*/    "pygame.Surface(size, [flags, [depth|Surface, [masks]]]) ->\n"
-    /*DOC*/    "Surface\n"
+    /*DOC*/    "pygame.Surface(size, [flags, [depth|Surface, [masks]]]) -> Surface\n"
     /*DOC*/    "create a new Surface\n"
     /*DOC*/    "\n"
     /*DOC*/    "Creates a new surface object. Size is a 2-int-sequence containing\n"