def check_opengl(): screen = sdl.SDL_GetVideoSurface() if not screen: raise SDLError("Display mode not set") if not (screen.flags & sdl.SDL_OPENGL): raise SDLError("Not an OPENGL display")
def set_palette(palette=None): """ set_palette(palette=None) -> None Set the display color palette for indexed displays """ check_video() screen = sdl.SDL_GetVideoSurface() if not screen: raise SDLError("Display mode not set") if palette and not hasattr(palette, '__iter__'): raise TypeError("Argument must be a sequence type") default_pal = screen.format.palette if screen.format.BytesPerPixel != 1 or default_pal is None: raise SDLError("Display mode is not colormapped") if palette is None: sdl.SDL_SetPalette(screen, sdl.SDL_PHYSPAL, default_pal.colors, 0, default_pal.ncolors) else: ncolors = min(default_pal.ncolors, len(palette)) colors = ffi.new('SDL_Color[]', ncolors) for i in range(ncolors): try: r, g, b = palette[i] except (ValueError, TypeError): raise TypeError("takes a sequence of sequence of RGB") try: colors[i].r = r colors[i].g = g colors[i].b = b except: raise TypeError("RGB sequence must contain numeric values") sdl.SDL_SetPalette(screen, sdl.SDL_PHYSPAL, colors, 0, ncolors)
def set_palette(self, colors): """ set_palette([RGB, RGB, RGB, ...]) -> None set the color palette for an 8bit Surface """ palette = self._format.palette if not palette: raise SDLError("Surface has no palette") if not hasattr(colors, '__iter__'): raise ValueError("Argument must be a sequence type") if not sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO): raise SDLError( "cannot set palette without pygame.display initialized") length = min(palette.ncolors, len(colors)) c_colors = ffi.new('SDL_Color[]', length) for i in range(length): rgb = colors[i] if (not hasattr(rgb, '__iter__')) or len(rgb) < 3 or len(rgb) > 4: raise ValueError("takes a sequence of integers of RGB") c_colors[i].r = rgb[0] c_colors[i].g = rgb[1] c_colors[i].b = rgb[2] if len(rgb) == 4 and rgb[3] != 255: raise ValueError("takes an alpha value of 255") sdl.SDL_SetColors(self._c_surface, c_colors, 0, length)
def rwops_encode_file_path(filepath): if isinstance(filepath, unicode_): filepath = filesystem_encode(filepath) if isinstance(filepath, bytes_): if b'\x00' in filepath: raise SDLError("File path '%.1024s' contains null " "characters" % filepath) return filepath raise SDLError("filepath argument needs to be a unicode or str value")
def update(rectangle=None): """ update(rectangle=None) -> None update(rectangle_list) -> None Update portions of the screen for software displays """ check_video() screen = sdl.SDL_GetVideoSurface() if not screen: raise SDLError("Display mode not set") if (screen.flags & sdl.SDL_OPENGL): raise SDLError("Cannot update an OPENGL display") if not rectangle: sdl.SDL_UpdateRect(screen, 0, 0, 0, 0) return try: if hasattr(rectangle, '__iter__'): # it can either be a rect style 4-tuple or # a sequence of rects or rect styles try: int(rectangle[0]) rects = (rectangle, ) except (ValueError, TypeError): rects = rectangle else: rects = (rectangle, ) if len(rects) == 1: rect = game_rect_from_obj(rects[0]) if screen_crop_rect(rect, screen.w, screen.h): sdl.SDL_UpdateRect(screen, rect.x, rect.y, rect.w, rect.h) return rect_array = ffi.new('SDL_Rect[]', len(rects)) count = 0 for obj in rects: if not obj: continue rect = game_rect_from_obj(obj) if screen_crop_rect(rect, screen.w, screen.h): sdlrect = rect_array[count] sdlrect.x = rect.x sdlrect.y = rect.y sdlrect.w = rect.w sdlrect.h = rect.h count += 1 sdl.SDL_UpdateRects(screen, count, rect_array) except (NotImplementedError, TypeError): raise ValueError( "update requires a rectstyle or sequence of recstyles")
def get_pitch(self): """ get_pitch() -> int get the number of bytes used per Surface row """ if not self._c_surface: raise SDLError("display Surface quit") return self._c_surface.flags
def get_flags(self): """ get_flags() -> int get the additional flags used for the Surface """ if not self._c_surface: raise SDLError("display Surface quit") return self._c_surface.flags
def play(loops=0, startpos=0.0): """play(loops=0, start=0.0): return None Start the playback of the music stream""" global _current_music, _music_pos, _music_pos_time, \ _music_frequency, _music_format, _music_channels check_mixer() if not _current_music: raise SDLError("music not loaded") sdl.Mix_HookMusicFinished(_endmusic_callback) sdl.Mix_SetPostMix(_mixmusic_callback, ffi.NULL) frequency, format, channels = (ffi.new('int*'), ffi.new('uint16_t*'), ffi.new('int*')) sdl.Mix_QuerySpec(frequency, format, channels) _music_pos = 0 _music_pos_time = sdl.SDL_GetTicks() _music_frequency = frequency[0] _music_format = format[0] _music_channels = channels[0] volume = sdl.Mix_VolumeMusic(-1) val = sdl.Mix_FadeInMusicPos(_current_music, loops, 0, startpos) sdl.Mix_VolumeMusic(volume) if val == -1: raise SDLError.from_sdl_error()
def get_buffer(self): """ get_buffer() -> BufferProxy acquires a buffer object for the pixels of the Surface. """ if not self._c_surface: raise SDLError("display Surface quit") raise NotImplementedError
def get_view(self, kind): """ get_view(<kind>='2') -> BufferProxy return a buffer view of the Surface's pixels. """ if not self._c_surface: raise SDLError("display Surface quit") raise NotImplementedError
def load(filename, namehint=""): try: filename = rwops_encode_file_path(filename) c_surface = sdl.IMG_Load(filename) except SDLError: # filename is not a string, try as file object try: rwops = rwops_from_file(filename) if namehint: name, ext = path.splitext(namehint) elif hasattr(filename, 'name'): name, ext = path.splitext(filename.name) else: # No name info, so we pass an empty extension to # SDL to indicate we can only load files with # suitable magic format markers in the file. name, ext = '', '' if len(ext) == 0: ext = name ext = rwops_encode_file_path(ext) c_surface = sdl.IMG_LoadTyped_RW(rwops, 1, ext) except TypeError: raise TypeError("file argument must be a valid path " "string or file object") if not c_surface: raise SDLError(ffi.string(sdl.IMG_GetError())) return Surface._from_sdl_surface(c_surface)
def get_shifts(self): """ get_shifts() -> (R, G, B, A) the bit shifts needed to convert between a color and a mapped integer """ if not self._c_surface: raise SDLError("display Surface quit") format = self._format return (format.Rshift, format.Gshift, format.Bshift, format.Ashift)
def set_pos(pos): """ set_pos(pos) -> None set position to play from """ check_mixer() pos = float(pos) if sdl.Mix_SetMusicPosition(pos) == -1: raise SDLError("set_pos unsupported for this codec")
def get_clip(self): """ get_clip() -> Rect get the current clipping area of the Surface """ if not self._c_surface: raise SDLError("display Surface quit") c_rect = self._c_surface.clip_rect return Rect._from4(c_rect.x, c_rect.y, c_rect.w, c_rect.h)
def get_losses(self): """ get_losses() -> (R, G, B, A) the significant bits used to convert between a color and a mapped integer """ if not self._c_surface: raise SDLError("display Surface quit") format = self._format return (format.Rloss, format.Gloss, format.Bloss, format.Aloss)
def get_masks(self): """ get_masks() -> (R, G, B, A) the bitmasks needed to convert between a color and a mapped integer """ if not self._c_surface: raise SDLError("display Surface quit") format = self._format return (format.Rmask, format.Gmask, format.Bmask, format.Amask)
def get_button(self, i): """ get_button(button) -> bool get the current button state """ joydata = self._joydata if i < 0 or i >= sdl.SDL_JoystickNumButtons(joydata): raise SDLError("Invalid joystick button") return sdl.SDL_JoystickGetButton(joydata, i)
def toggle_fullscreen(): """ toggle_fullscreen() -> bool Switch between fullscreen and windowed displays """ check_video() screen = sdl.SDL_GetVideoSurface() if not screen: raise SDLError("Display mode not set") return (sdl.SDL_WM_ToggleFullScreen(screen) != 0)
def unmap_rgb(self, mapped_int): """ unmap_rgb(mapped_int) -> Color convert a mapped integer color value into a Color """ if not self._c_surface: raise SDLError("display Surface quit") mapped_int = ffi.cast('uint32_t', mapped_int) r, g, b, a = [ffi.new('uint8_t*') for i in range(4)] sdl.SDL_GetRGBA(mapped_int, self._format, r, g, b, a) return Color(r[0], g[0], b[0], a[0])
def set_palette_at(self, index, rgb): """ set_palette_at(index, RGB) -> None set the color for a single index in an 8bit Surface palette """ palette = self._format.palette if not palette: raise SDLError("Surface has no palette") if index < 0 or index >= palette.ncolors: raise IndexError("index out of bounds") if not sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO): raise SDLError("cannot set palette without pygame.display initialized") if (not hasattr(rgb, '__iter__')) or len(rgb) < 3 or len(rgb) > 4: raise ValueError("takes a sequence of integers of RGB for argument 2") color = ffi.new('SDL_Color*') color[0].r = rgb[0] color[0].g = rgb[1] color[0].b = rgb[2] sdl.SDL_SetColors(self._c_surface, color, index, 1)
def get_axis(self, i): """ get_axis(axis_number) -> float get the current position of an axis """ joydata = self._joydata if i < 0 or i >= sdl.SDL_JoystickNumAxes(joydata): raise SDLError("Invalid joystick axis") value = sdl.SDL_JoystickGetAxis(joydata, i) return value / 32768.0
def scroll(self, dx=0, dy=0): """ scroll(dx=0, dy=0) -> None Shift the surface image in place """ self.check_surface() if self.is_pure_opengl(): raise SDLError( "Cannot scroll an OPENGL Surfaces (OPENGLBLIT is ok)") if not (dx or dy): return None clip_rect = self._c_surface.clip_rect w = clip_rect.w h = clip_rect.h if dx >= w or dx <= -w or dy >= h or dy <= -h: return None with locked(self._c_surface): bpp = self._c_surface.format.BytesPerPixel pitch = self._c_surface.pitch pixels = ffi.cast("uint8_t*", self._c_surface.pixels) src = dst = pixels + clip_rect.y * pitch + clip_rect.x * bpp if dx >= 0: w -= dx if dy > 0: h -= dy dst += dy * pitch + dx * bpp else: h += dy src -= dy * pitch dst += dx * bpp else: w += dx if dy > 0: h -= dy src -= dx * bpp dst += dy * pitch else: h += dy src -= dy * pitch + dx * bpp if src < dst: src += (h - 1) * pitch dst += (h - 1) * pitch pitch = -pitch span = w * bpp for _ in range(h): sdl.memmove(dst, src, span) src += pitch dst += pitch return None
def get_ball(self, i): """ get_ball(ball_number) -> x, y get the relative position of a trackball """ joydata = self._joydata if i < 0 or i >= sdl.SDL_JoystickNumBalls(joydata): raise SDLError("Invalid joystick trackball") dx, dy = ffi.new('int*'), ffi.new('int*') sdl.SDL_JoystickGetBall(joydata, i, dx, dy) return (dx[0], dy[0])
def get_palette_at(self, index): """ get_palette_at(index) -> RGB get the color for a single entry in a palette """ palette = self._c_surface.format.palette if not palette: raise SDLError("Surface has no palette to get") if index < 0 or index >= palette.ncolors: raise IndexError("index out of bounds") c = palette.colors[index] return Color(c.r, c.g, c.b)
def get_palette(self): """ get_palette() -> [RGB, RGB, RGB, ...] get the color index palette for an 8bit Surface """ palette = self._format.palette if not palette: raise SDLError("Surface has no palette to get") colors = [] for i in range(palette.ncolors): c = palette.colors[i] colors.append(Color(c.r, c.g, c.b)) return colors
def map_rgb(self, col): """ map_rgb(Color) -> mapped_int convert a color into a mapped color value """ if not self._c_surface: raise SDLError("display Surface quit") try: if len(col) == 3: a = 255 else: a = col[3] return sdl.SDL_MapRGBA(self._format, col[0], col[1], col[2], a) except (IndexError, TypeError): raise TypeError("Invalid RGBA argument")
def size(self, text): """Font.size(text): return (width, height) determine the amount of space needed to render text""" if not isinstance(text, (bytes_, unicode_)): raise TypeError("text must be a string or unicode") if isinstance(text, unicode_): text = text.encode('utf-8', 'replace') w = ffi.new("int*") h = ffi.new("int*") ecode = sdl.TTF_SizeUTF8(self._sdl_font, text, w, h) if ecode == -1: raise SDLError(ffi.string(sdl.TTF_GetError())) return int(w[0]), int(h[0])
def set_mode(resolution=(0, 0), flags=0, depth=0): """ set_mode(resolution=(0,0), flags=0, depth=0) -> Surface Initialize a window or screen for display """ w, h = unpack_rect(resolution) if w < 0 or h < 0: raise SDLError("Cannot set negative sized display mode") if flags == 0: flags = sdl.SDL_SWSURFACE if not get_init(): init() # depth and double buffering attributes need to be set specially for OpenGL if flags & sdl.SDL_OPENGL: if flags & sdl.SDL_DOUBLEBUF: gl_set_attribute(sdl.SDL_GL_DOUBLEBUFFER, 1) else: gl_set_attribute(sdl.SDL_GL_DOUBLEBUFFER, 0) if depth: gl_set_attribute(sdl.SDL_GL_DEPTH_SIZE, depth) c_surface = sdl.SDL_SetVideoMode(w, h, depth, flags) if c_surface and gl_get_attribute(sdl.SDL_GL_DOUBLEBUFFER): c_surface.flags |= sdl.SDL_DOUBLEBUF else: if depth == 0: flags |= sdl.SDL_ANYFORMAT c_surface = sdl.SDL_SetVideoMode(w, h, depth, flags) if not c_surface: raise SDLError.from_sdl_error() title = ffi.new("char*[1]") icon = ffi.new("char*[1]") sdl.SDL_WM_GetCaption(title, icon) if not title: sdl.SDL_WM_SetCaption("pygame window", "pygame") # pygame does this, so it's possibly a good idea sdl.SDL_PumpEvents() global _display_surface _display_surface = SurfaceNoFree._from_sdl_surface(c_surface) # TODO: set icon stuff return _display_surface
def set_masks(self, masks): """ set_masks((r,g,b,a)) -> None set the bitmasks needed to convert between a color and a mapped integer """ if not self._c_surface: raise SDLError("display Surface quit") try: r, g, b, a = [ffi.cast('uint32_t', m) for m in masks] format = self._format format.Rmask = r format.Gmask = g format.Bmask = b format.Amask = a except (ValueError, TypeError): raise TypeError("invalid argument for masks")
def set_shifts(self, shifts): """ set_shifts((r,g,b,a)) -> None sets the bit shifts needed to convert between a color and a mapped integer """ if not self._c_surface: raise SDLError("display Surface quit") try: r, g, b, a = [ffi.cast('uint8_t', s) for s in shifts] format = self._format format.Rshift = r format.Gshift = g format.Bshift = b format.Ashift = a except (ValueError, TypeError): raise TypeError("invalid argument for shifts")