Beispiel #1
0
 def _set_at(self, x, y, c_color):
     bpp = self._format.BytesPerPixel
     if bpp == 1:
         pixels = ffi.cast("uint8_t*", self._c_surface.pixels)
         pixels[y * self._c_surface.pitch // bpp + x] = c_color
     elif bpp == 2:
         pixels = ffi.cast("uint16_t*", self._c_surface.pixels)
         pixels[y * self._c_surface.pitch // bpp + x] = c_color
     elif bpp == 3:
         pixels = ffi.cast("uint8_t*", self._c_surface.pixels)
         base = y * self._c_surface.pitch + x * 3
         fmt = self._format
         if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
             pixels[base + (fmt.Rshift >> 3)] = ffi.cast('uint8_t', c_color >> 16)
             pixels[base + (fmt.Gshift >> 3)] = ffi.cast('uint8_t', c_color >> 8)
             pixels[base + (fmt.Bshift >> 3)] = ffi.cast('uint8_t', c_color)
         else:
             pixels[base + 2 - (fmt.Rshift >> 3)] = ffi.cast('uint8_t', c_color >> 16)
             pixels[base + 2 - (fmt.Gshift >> 3)] = ffi.cast('uint8_t', c_color >> 8)
             pixels[base + 2 - (fmt.Bshift >> 3)] = ffi.cast('uint8_t', c_color)
     elif bpp == 4:
         pixels = ffi.cast("uint32_t*", self._c_surface.pixels)
         pixels[y * (self._c_surface.pitch // bpp) + x] = c_color
     else:
         raise RuntimeError("invalid color depth for surface")
Beispiel #2
0
def _drawvertline(surface, c_color, start_y, end_y, x):
    """Draw a vertical line using SDL_FillRect"""
    sdlrect = ffi.new('SDL_Rect*')
    if start_y > end_y:
        end_y, start_y = start_y, end_y
    sdlrect.x = ffi.cast("int16_t", x)
    sdlrect.y = ffi.cast("int16_t", start_y)
    sdlrect.w = 1
    sdlrect.h = ffi.cast("uint16_t", end_y - start_y + 1)
    sdl.SDL_FillRect(surface._c_surface, sdlrect, c_color)
Beispiel #3
0
def _drawhorizline(surface, c_color, start_x, end_x, y):
    """Draw a horizontal line using SDL_FillRect"""
    sdlrect = ffi.new('SDL_Rect*')
    if start_x > end_x:
        end_x, start_x = start_x, end_x
    sdlrect.x = ffi.cast("int16_t", start_x)
    sdlrect.y = ffi.cast("int16_t", y)
    sdlrect.w = ffi.cast("uint16_t", end_x - start_x + 1)
    sdlrect.h = 1
    sdl.SDL_FillRect(surface._c_surface, sdlrect, c_color)
Beispiel #4
0
def check_surface_overlap(c_src, srcrect, c_dest, destrect):
    srcx, srcy, destx, desty, w, h = (srcrect.x, srcrect.y,
                                      destrect.x, destrect.y,
                                      srcrect.w, srcrect.h)
    if srcx < 0:
        w += srcx
        destx -= srcx
        srcx = 0
    maxw = c_src.w - srcx
    if maxw < w:
        w = maxw
    if srcy < 0:
        h += srcy
        desty -= srcy
        srcy = 0
    maxh = c_src.h - srcy
    if maxh < h:
        h = maxh

    clip = c_dest.clip_rect
    x = clip.x - destx
    if x > 0:
        w -= x
        destx += x
        srcx += x
    x = destx + w - clip.x - clip.w
    if x > 0:
        w -= x
    y = clip.y - desty
    if y > 0:
        h -= y
        desty += y
        srcy += y
    y = desty + h - clip.y - clip.h
    if y > 0:
        h -= y

    if w <= 0 or h <= 0:
        return None

    srcpixels = ffi.cast("uint8_t*", c_src.pixels)
    srcpixels += c_src.offset + srcy * c_src.pitch + \
                 srcx * c_src.format.BytesPerPixel
    destpixels = ffi.cast("uint8_t*", c_dest.pixels)
    destpixels += c_src.offset + desty * c_dest.pitch + \
                  destx * c_dest.format.BytesPerPixel

    if destpixels <= srcpixels:
        return False
    span = w * c_src.format.BytesPerPixel
    if destpixels >= (srcpixels + (h - 1) * c_src.pitch + span):
        return False
    destoffset = (destpixels - srcpixels) % c_src.pitch
    return (destoffset < span) or (destoffset > c_src.pitch - span)
Beispiel #5
0
def save_jpg(surf, filename):
    if (surf.format.BytesPerPixel == 3
            and not (surf.flags & sdl.SDL_SRCALPHA)
            and surf.format.Rshift == 0):
        ss_surf = surf
    else:
        if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
            rmask, gmask, bmask, amask = 0xff, 0xff00, 0xff0000, 0xff000000
        else:
            rmask, gmask, bmask, amask = 0xff00, 0xff, 0xff0000, 0xff000000
        ss_surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SWSURFACE, surf.w, surf.h,
                                           24, rmask, gmask, bmask, amask)
        if not ss_surf:
            return -1
        rect = ffi.new('SDL_Rect*')
        rect.w = surf.w
        rect.h = surf.h
        sdl.SDL_BlitSurface(surf, rect, ss_surf, ffi.NULL)

    ss_rows = ffi.new('unsigned char*[]', surf.h)
    ss_pixels = ffi.cast('unsigned char*', ss_surf.pixels)
    for i in range(surf.h):
        ss_rows[i] = ss_pixels + i * ss_surf.pitch
    err_msg = ffi.new('char**')
    result = jpglib.write_jpeg(filename, ss_rows, surf.w, surf.h, 85, err_msg)

    if ss_surf is not surf:
        sdl.SDL_FreeSurface(ss_surf)
    if result == -1:
        raise IOError("JPGError: %s" % ffi.string(err_msg[0]))
    return result
Beispiel #6
0
def save_png(surf, filename):
    alpha = bool(surf.format.Amask)
    if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
        rmask, gmask, bmask, amask = 0xff, 0xff00, 0xff0000, 0xff000000
    else:
        rmask, gmask, bmask, amask = 0xff00, 0xff0000, 0xff, 0x000000ff
    ss_surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SWSURFACE | sdl.SDL_SRCALPHA,
                                       surf.w, surf.h, 32 if alpha else 24,
                                       rmask, gmask, bmask, amask)
    if not ss_surf:
        return -1
    with opaque(surf):
        rect = ffi.new('SDL_Rect*')
        rect.w = surf.w
        rect.h = surf.h
        sdl.SDL_BlitSurface(surf, rect, ss_surf, ffi.NULL)

    ss_rows = ffi.new('unsigned char*[]', surf.h)
    ss_pixels = ffi.cast('unsigned char*', ss_surf.pixels)
    for i in range(surf.h):
        ss_rows[i] = ss_pixels + i * ss_surf.pitch
    err_msg = ffi.new('char**')
    result = pnglib.write_png(filename, ss_rows, surf.w, surf.h,
                              (pnglib.PNG_COLOR_TYPE_RGB_ALPHA if alpha else
                               pnglib.PNG_COLOR_TYPE_RGB), 8, err_msg)

    sdl.SDL_FreeSurface(ss_surf)
    if result == -1:
        raise IOError("PNGError: %s" % ffi.string(err_msg[0]))
    return result
Beispiel #7
0
 def get_raw(self):
     """ get_raw() -> bytes
     return a bytestring copy of the Sound samples.
     """
     check_mixer()
     return ffi.buffer(ffi.cast('char*', self.chunk.abuf),
                       self.chunk.alen)[:]
Beispiel #8
0
 def _get_at(self, x, y):
     bpp = self._format.BytesPerPixel
     if bpp == 1:
         pixels = ffi.cast("uint8_t*", self._c_surface.pixels)
         return pixels[y * self._c_surface.pitch // bpp + x]
     elif bpp == 2:
         pixels = ffi.cast("uint16_t*", self._c_surface.pixels)
         return pixels[y * self._c_surface.pitch // bpp + x]
     elif bpp == 3:
         pixels = ffi.cast("uint8_t*", self._c_surface.pixels)
         base = y * self._c_surface.pitch + x * 3
         return (pixels[base + BYTE0] +
                 (pixels[base + BYTE1] << 8) +
                 (pixels[base + BYTE2] << 16))
     elif bpp == 4:
         pixels = ffi.cast("uint32_t*", self._c_surface.pixels)
         return pixels[y * self._c_surface.pitch // bpp + x]
Beispiel #9
0
def _timer_callback(interval, param):
    if sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO):
        event = ffi.new("SDL_Event*")
        event.type = ffi.cast("intptr_t", param)
        # SDL will make a copy of the event while handling SDL_PushEvent,
        # so we don't need to hold the allocated memory after this call.
        sdl.SDL_PushEvent(event)
    return interval
Beispiel #10
0
def smoothscale(surface, size, dest_surface=None):
    """ smoothscale(Surface, (width, height), DestSurface = None) -> Surface
    scale a surface to an arbitrary size smoothly
    """
    width, height = size
    if width < 0 or height < 0:
        raise ValueError("Cannot scale to negative size")

    c_surf = surface._c_surface

    bpp = c_surf.format.BytesPerPixel
    if bpp < 3 or bpp > 4:
        raise ValueError("Only 24-bit or 32-bit surfaces can be"
                         " smoothly scaled")

    if dest_surface is None:
        new_surf = new_surface_from_surface(c_surf, width, height)
    else:
        new_surf = dest_surface._c_surface

    if new_surf.w != width or new_surf.h != height:
        raise ValueError("Destination surface not the given width or height.")

    if (width * bpp + 3) // 4 > new_surf.pitch:
        raise ValueError("SDL Error: destination surface pitch not"
                         " 4-byte aligned.")

    if width and height:
        with locked(new_surf):
            with locked(c_surf):
                if c_surf.w == width and c_surf.h == height:
                    # Non-scaling case, so just copy the correct pixels
                    c_pitch = c_surf.pitch
                    n_pitch = new_surf.pitch
                    srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                    destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                    step = width * bpp
                    for y in range(0, height):
                        offset_n = y * n_pitch
                        offset_c = y * c_pitch
                        destpixels[offset_n:offset_n + step] = srcpixels[offset_c:offset_c + step]
                else:
                    sdl.scalesmooth(c_surf, new_surf)
    if dest_surface:
        return dest_surface
    return Surface._from_sdl_surface(new_surf)
Beispiel #11
0
 def unmap_rgb(self, mapped_int):
     """ unmap_rgb(mapped_int) -> Color
     convert a mapped integer color value into a Color
     """
     self.check_surface()
     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])
Beispiel #12
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
Beispiel #13
0
def smoothscale(surface, size, dest_surface=None):
    """ smoothscale(Surface, (width, height), DestSurface = None) -> Surface
    scale a surface to an arbitrary size smoothly
    """
    width, height = size
    if width < 0 or height < 0:
        raise ValueError("Cannot scale to negative size")

    c_surf = surface._c_surface

    bpp = c_surf.format.BytesPerPixel
    if bpp < 3 or bpp > 4:
        raise ValueError("Only 24-bit or 32-bit surfaces can be"
                         " smoothly scaled")

    if dest_surface is None:
        new_surf = new_surface_from_surface(c_surf, width, height)
    else:
        new_surf = dest_surface._c_surface

    if new_surf.w != width or new_surf.h != height:
        raise ValueError("Destination surface not the given width or height.")

    if (width * bpp + 3) // 4 > new_surf.pitch:
        raise ValueError("SDL Error: destination surface pitch not"
                         " 4-byte aligned.")

    if width and height:
        with locked(new_surf):
            with locked(c_surf):
                if c_surf.w == width and c_surf.h == height:
                    pitch = c_surf.pitch
                    # Trivial case
                    srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                    destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                    destpixels[0:height * pitch] = srcpixels[0:height * pitch]
                else:
                    sdl.scalesmooth(c_surf, new_surf)
    if dest_surface:
        return dest_surface
    return Surface._from_sdl_surface(new_surf)
Beispiel #14
0
 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
     """
     self.check_surface()
     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")
Beispiel #15
0
 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
     """
     self.check_surface()
     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")
Beispiel #16
0
def flip(surface, xaxis, yaxis):
    c_surf = surface._c_surface
    w, h = c_surf.w, c_surf.h
    new_surf = new_surface_from_surface(c_surf, w, h)
    bpp = c_surf.format.BytesPerPixel
    pitch = c_surf.pitch

    with locked(new_surf):
        with locked(surface._c_surface):
            # only have to deal with rows
            if not xaxis:
                srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                if not yaxis:
                    # no changes - just copy pixels
                    destpixels[0:h * pitch] = srcpixels[0:h * pitch]
                else:
                    for y in range(h):
                        dest_start = (h - y - 1) * pitch
                        src_start = y * pitch
                        destpixels[dest_start:dest_start + pitch] = \
                                srcpixels[src_start:src_start + pitch]
            # have to calculate position for individual pixels
            else:
                if not yaxis:
                    def get_y(y):
                        return y
                else:
                    def get_y(y):
                        return h - y - 1

                if bpp in (1, 2, 4):
                    ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel
                    srcpixels = ffi.cast(ptr_type, c_surf.pixels)
                    destpixels = ffi.cast(ptr_type, new_surf.pixels)
                    for y in range(h):
                        dest_row_start = get_y(y) * w
                        src_row_start = y * w
                        for x in range(w):
                            destpixels[dest_row_start + (w - x - 1)] = \
                                    srcpixels[src_row_start + x]
                else:
                    srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                    destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                    for y in range(h):
                        dest_row_start = get_y(y) * pitch
                        src_row_start = y * pitch
                        for x in range(0, pitch, 3):
                            dest_pix_start = dest_row_start + (pitch - x - 3)
                            src_pix_start = src_row_start + x
                            destpixels[dest_pix_start:dest_pix_start + 3] = \
                                srcpixels[src_pix_start:src_pix_start + 3]

    return Surface._from_sdl_surface(new_surf)
Beispiel #17
0
def post(event):
    """post(Event): return None
       place a new event on the queue"""
    # SDL requires video to be initialised before PushEvent does the right thing
    check_video()
    is_blocked = sdl.SDL_EventState(event.type, sdl.SDL_QUERY) == sdl.SDL_IGNORE
    if is_blocked:
        raise RuntimeError("event post blocked for %s" % event_name(event.type))

    sdl_event = ffi.new("SDL_Event *")
    sdl_event.type = event.type
    sdl_event.user.code = _USEROBJECT_CHECK1
    sdl_event.user.data1 = _USEROBJECT_CHECK2
    sdl_event.user.data2 = ffi.cast("void*", sdl_event)
    _user_events[sdl_event] = event
    if sdl.SDL_PushEvent(sdl_event) == -1:
        raise SDLError.from_sdl_error()
Beispiel #18
0
def post(event):
    """post(Event): return None
       place a new event on the queue"""
    # SDL requires video to be initialised before PushEvent does the right thing
    check_video()
    is_blocked = sdl.SDL_EventState(event.type, sdl.SDL_QUERY) == sdl.SDL_IGNORE
    if is_blocked:
        # Silently drop blocked events, since that's what pygame does
        # (maybe worth logging somehow?)
        return None

    sdl_event = ffi.new("SDL_Event *")
    sdl_event.type = event.type
    sdl_event.user.code = _USEROBJECT_CHECK1
    sdl_event.user.data1 = _USEROBJECT_CHECK2
    sdl_event.user.data2 = ffi.cast("void*", sdl_event)
    _user_events[sdl_event] = event
    if sdl.SDL_PushEvent(sdl_event) == -1:
        raise SDLError.from_sdl_error()
Beispiel #19
0
    def subsurface(self, *rect):
        self.check_opengl()

        try:
            if hasattr(rect[0], '__iter__'):
                rect = game_rect_from_obj(rect[0])
            else:
                rect = game_rect_from_obj(rect)
        except TypeError:
            raise ValueError("not a valid rect style object")

        if (rect.x < 0 or rect.x + rect.w > self._c_surface.w or rect.y < 0 or
            rect.y + rect.h > self._c_surface.h):
            raise ValueError("subsurface rectangle outside surface area")
        with locked(self._c_surface):
            format = self._format
            pixeloffset = (rect.x * format.BytesPerPixel +
                           rect.y * self._c_surface.pitch)
            startpixel = ffi.cast("char*", self._c_surface.pixels) + pixeloffset
            surf = self._c_surface
            sub = sdl.SDL_CreateRGBSurfaceFrom(startpixel, rect.w, rect.h,
                                               format.BitsPerPixel, surf.pitch,
                                               format.Rmask, format.Gmask,
                                               format.Bmask, format.Amask)
        if not sub:
            raise SDLError.from_sdl_error()

        if format.BytesPerPixel == 1 and format.palette:
            sdl.SDL_SetPalette(sub, sdl.SDL_LOGPAL,
                               format.palette.colors, 0,
                               format.palette.ncolors);
        if surf.flags & sdl.SDL_SRCALPHA:
            sdl.SDL_SetAlpha(sub, surf.flags & sdl.SDL_SRCALPHA,
                             format.alpha);
        if surf.flags & sdl.SDL_SRCCOLORKEY:
            sdl.SDL_SetColorKey(sub, surf.flags & (sdl.SDL_SRCCOLORKEY |
                                                   sdl.SDL_RLEACCEL),
                                                   format.colorkey)
        subsurface = Surface._from_sdl_surface(sub)
        data = SubSurfaceData(self, pixeloffset, rect.x, rect.y)
        subsurface.subsurfacedata = data
        return subsurface
Beispiel #20
0
def tostring(surface, format, flipped=False):
    """ tostring(Surface, format, flipped=False) -> string
    transfer image to string buffer
    """
    surf = surface._c_surface
    if surf.flags & sdl.SDL_OPENGL:
        raise NotImplementedError()

    if format == "P":
        if surf.format.BytesPerPixel != 1:
            raise ValueError("Can only create \"P\" format data with "
                             "8bit Surfaces")
        with locked(surf):
            string = ffi.buffer(ffi.cast('char*', surf.pixels))[:]
    else:
        _tostring = globals().get('_tostring_%s' % format, None)
        if _tostring is None:
            raise ValueError("Unrecognized type of format")
        with locked(surf):
            string = _tostring(surf, flipped)
    return string
Beispiel #21
0
def set_timer(eventid, milliseconds):
    """set_timer(eventid, milliseconds) -> None
    repeatedly create an event on the event queue"
    """
    if eventid <= sdl.SDL_NOEVENT or eventid >= sdl.SDL_NUMEVENTS:
        raise ValueError("Event id must be between NOEVENT(0) and" " NUMEVENTS(32)")

    old_event = _event_timers.pop(eventid, None)
    if old_event:
        sdl.SDL_RemoveTimer(old_event)

    if milliseconds <= 0:
        return

    _try_init()

    handle = ffi.cast("void *", eventid)
    newtimer = sdl.SDL_AddTimer(milliseconds, _timer_callback, handle)
    if not newtimer:
        SDLError.from_sdl_error()

    _event_timers[eventid] = newtimer
Beispiel #22
0
def set_timer(eventid, milliseconds):
    """set_timer(eventid, milliseconds) -> None
    repeatedly create an event on the event queue"
    """
    if eventid <= sdl.SDL_NOEVENT or eventid >= sdl.SDL_NUMEVENTS:
        raise ValueError("Event id must be between NOEVENT(0) and"
                         " NUMEVENTS(32)")

    old_event = _event_timers.pop(eventid, None)
    if old_event:
        sdl.SDL_RemoveTimer(old_event)

    if milliseconds <= 0:
        return

    _try_init()

    handle = ffi.cast("void *", eventid)
    newtimer = sdl.SDL_AddTimer(milliseconds, _timer_callback, handle)
    if not newtimer:
        raise SDLError.from_sdl_error()

    _event_timers[eventid] = newtimer
Beispiel #23
0
def _timer_callback(interval, param):
    if sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO):
        event = ffi.new("SDL_Event")
        event.type = ffi.cast("intptr_t", param)
        sdl.SDL_PushEvent(event)
    return interval
Beispiel #24
0
    return result


def fromstring(string, (w, h), format, flipped=False):
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
Beispiel #25
0
""" The pygame event module """

from pygame._sdl import sdl, ffi
from pygame._error import SDLError
from pygame.display import check_video

from pygame.constants import (
    ACTIVEEVENT, KEYDOWN, KEYUP, MOUSEMOTION, MOUSEBUTTONDOWN, MOUSEBUTTONUP,
    JOYAXISMOTION, JOYBALLMOTION, JOYHATMOTION, JOYBUTTONDOWN, JOYBUTTONUP,
    QUIT, SYSWMEVENT, VIDEORESIZE, VIDEOEXPOSE, USEREVENT, NUMEVENTS, NOEVENT,
    USEREVENT_DROPFILE)

# We do this to avoid roundtripping issues caused by 0xDEADBEEF casting to a 
# negative number
_USEROBJECT_CHECK1 = ffi.cast('int', 0xDEADBEEF)
_USEROBJECT_CHECK2 = ffi.cast('void*', 0xFEEDF00D)

# I'm not wild about this global dict, but it's the same idea as the linked
# list pygame uses and I don't have a better approach right now
_user_events = {}


def _button_state(state, button):
    if state & sdl._pygame_SDL_BUTTON(button):
        return 1
    return 0


class EventType(object):
    """An event object"""
Beispiel #26
0
def _tostring_RGBA_PREMULT(surf, flipped, argb=False):
    if surf.format.BytesPerPixel == 1 or surf.format.Amask == 0:
        raise ValueError("Can only create pre-multiplied alpha strings if "
                         "the surface has per-pixel alpha")

    rmask, gmask, bmask, amask = (surf.format.Rmask,
                                  surf.format.Gmask,
                                  surf.format.Bmask,
                                  surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift,
                                      surf.format.Gshift,
                                      surf.format.Bshift,
                                      surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss,
                                  surf.format.Gloss,
                                  surf.format.Bloss,
                                  surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w
    if argb:
        ri, gi, bi, ai = 1, 2, 3, 0
    else:
        ri, gi, bi, ai = 0, 1, 2, 3

    data = ffi.new('char[]', w * h * 4)
    if bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                alpha = ((color & amask) >> ashift) << aloss
                data[dest + ri] = chr_((((color & rmask) >> rshift) << rloss)
                                       * alpha // 255)
                data[dest + gi] = chr_((((color & gmask) >> gshift) << gloss)
                                       * alpha // 255)
                data[dest + bi] = chr_((((color & bmask) >> bshift) << bloss)
                                       * alpha // 255)
                data[dest + ai] = chr_(alpha)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 4 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                alpha = ((color & amask) >> ashift) << aloss
                data[dest + ri] = chr_((((color & rmask) >> rshift) << rloss)
                                       * alpha // 255)
                data[dest + gi] = chr_((((color & gmask) >> gshift) << gloss)
                                       * alpha // 255)
                data[dest + bi] = chr_((((color & bmask) >> bshift) << bloss)
                                       * alpha // 255)
                data[dest + ai] = chr_(alpha)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                alpha = ((color & amask) >> ashift) << aloss
                if alpha == 0:
                    data[dest + ri] = data[dest + gi] = data[dest + bi] \
                        = chr_(0)
                else:
                    data[dest + ri] = chr_(
                        (((color & rmask) >> rshift) << rloss) * alpha // 255)
                    data[dest + gi] = chr_(
                        (((color & gmask) >> gshift) << gloss) * alpha // 255)
                    data[dest + bi] = chr_(
                        (((color & bmask) >> bshift) << bloss) * alpha // 255)
                data[dest + ai] = chr_(alpha)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #27
0
def _tostring_RGB(surf, flipped):
    rmask, gmask, bmask, amask = (surf.format.Rmask,
                                  surf.format.Gmask,
                                  surf.format.Bmask,
                                  surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift,
                                      surf.format.Gshift,
                                      surf.format.Bshift,
                                      surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss,
                                  surf.format.Gloss,
                                  surf.format.Bloss,
                                  surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w

    data = ffi.new('char[]', w * h * 3)
    if bpp == 1:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        colors = surf.format.palette.colors
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(colors[color].r)
                data[dest + 1] = chr_(colors[color].g)
                data[dest + 2] = chr_(colors[color].b)
    elif bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 3 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #28
0
 def _samples_address(self):
     return int(ffi.cast('long', self.chunk.abuf))
Beispiel #29
0
def fromstring(string, size, format, flipped=False):
    w, h = size
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 3 if flipped else y * w * 3
                row = string[src_start:src_start + w * 3]
                for x in range(0, w * 3, 3):
                    # BYTE0, BYTE1 and BYTE2 are determined by byte order
                    pixels[dest + x + BYTE0] = row[x + BYTE0]
                    pixels[dest + x + BYTE1] = row[x + BYTE1]
                    pixels[dest + x + BYTE2] = row[x + BYTE2]

    elif format in ("RGBA", "RGBAX", "ARGB"):
        if len(string) != w * h * 4:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        if format == "ARGB":
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask, amask = (0xff << 8, 0xff << 16,
                                              0xff << 24, 0xff)
            else:
                rmask, gmask, bmask, amask = (0xff << 16, 0xff << 8, 0xff,
                                              0xff << 24)
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA, w, h, 32, rmask,
                                            gmask, bmask, amask)
        else:
            alphamult = format == "RGBA"
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask = 0xff, 0xff << 8, 0xff << 16
                amask = 0xff << 24 if alphamult else 0
            else:
                rmask, gmask, bmask = 0xff << 24, 0xff << 16, 0xff << 8
                amask = 0xff if alphamult else 0
            surf = sdl.SDL_CreateRGBSurface(
                sdl.SDL_SRCALPHA if alphamult else 0, w, h, 32, rmask, gmask,
                bmask, amask)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 4 if flipped else y * w * 4
                pixels[dest:dest + w * 4] = string[src_start:src_start + w * 4]

    else:
        raise ValueError("Unrecognized type of format")

    return Surface._from_sdl_surface(surf)
Beispiel #30
0
def chop(surface, rect):
    """ chop(Surface, rect) -> Surface
    gets a copy of an image with an interior area removed
    """
    rect = Rect(rect)
    width = rect.width
    height = rect.width
    x = rect.x
    y = rect.y
    if rect.right > surface._w:
        width = surface._w - rect.x
    if rect.height > surface._h:
        height = surface._h - rect.y
    if rect.x < 0:
        width -= -x
        x = 0
    if rect.y < 0:
        height -= -y
        y = 0
    c_surf = surface._c_surface

    new_surf = new_surface_from_surface(c_surf, surface._w, surface._h)

    bpp = c_surf.format.BytesPerPixel
    pitch = c_surf.pitch
    w, h = c_surf.w, c_surf.h

    with locked(new_surf):
        with locked(c_surf):
            if bpp in (1, 2, 4):
                ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel
                srcpixels = ffi.cast(ptr_type, c_surf.pixels)
                destpixels = ffi.cast(ptr_type, new_surf.pixels)
            else:
                srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                destpixels = ffi.cast('uint8_t*', new_surf.pixels)
            dy = 0
            for sy in range(0, surface._h):
                if sy >= y and sy < y + height:
                    continue
                dx = 0
                if bpp in (1, 2, 4):
                    dest_row_start = dy * w
                    src_row_start = sy * w
                else:
                    dest_row_start = dy * pitch
                    src_row_start = sy * pitch

                for sx in range(0, surface._w):
                    if sx >= x and sx < x + width:
                        continue
                    if bpp in (1, 2, 4):
                        destpixels[dest_row_start + dx] = \
                            srcpixels[src_row_start + sx]
                    else:
                        dest_pix_start = dest_row_start + dx
                        src_pix_start = src_row_start + sx
                        destpixels[dest_pix_start:dest_pix_start + 3] = \
                            srcpixels[src_pix_start:src_pix_start + 3]
                    dx += 1
                dy += 1

    return Surface._from_sdl_surface(new_surf)
Beispiel #31
0
    return result


def fromstring(string, (w, h), format, flipped=False):
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest =  surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
Beispiel #32
0
""" The pygame event module """

from pygame._sdl import sdl, ffi
from pygame._error import SDLError
from pygame.display import check_video
from pygame.compat import unichr_

from pygame.constants import (
    ACTIVEEVENT, KEYDOWN, KEYUP, MOUSEMOTION, MOUSEBUTTONDOWN, MOUSEBUTTONUP,
    JOYAXISMOTION, JOYBALLMOTION, JOYHATMOTION, JOYBUTTONDOWN, JOYBUTTONUP,
    QUIT, SYSWMEVENT, VIDEORESIZE, VIDEOEXPOSE, USEREVENT, NUMEVENTS, NOEVENT,
    USEREVENT_DROPFILE)

# We do this to avoid roundtripping issues caused by 0xDEADBEEF casting to a 
# negative number
_USEROBJECT_CHECK1 = ffi.cast('int', 0xDEADBEEF)
_USEROBJECT_CHECK2 = ffi.cast('void*', 0xFEEDF00D)

# I'm not wild about this global dict, but it's the same idea as the linked
# list pygame uses and I don't have a better approach right now
_user_events = {}


def _button_state(state, button):
    if state & sdl._pygame_SDL_BUTTON(button):
        return 1
    return 0


class EventType(object):
    """An event object"""
Beispiel #33
0
def flip(surface, xaxis, yaxis):
    c_surf = surface._c_surface
    w, h = c_surf.w, c_surf.h
    new_surf = new_surface_from_surface(c_surf, w, h)
    bpp = c_surf.format.BytesPerPixel
    src_pitch = c_surf.pitch
    dest_pitch = new_surf.pitch
    step = w * bpp

    with locked(new_surf):
        with locked(surface._c_surface):
            # only have to deal with rows
            if not xaxis:
                srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                if not yaxis:
                    # no changes - just copy pixels
                    for y in range(h):
                        dest_start = y * dest_pitch
                        src_start = y * src_pitch
                        destpixels[dest_start:dest_start + step] = \
                                srcpixels[src_start:src_start + step]
                else:
                    for y in range(h):
                        dest_start = (h - y - 1) * dest_pitch
                        src_start = y * src_pitch
                        destpixels[dest_start:dest_start + step] = \
                                srcpixels[src_start:src_start + step]
            # have to calculate position for individual pixels
            else:
                if not yaxis:

                    def get_y(y):
                        return y
                else:

                    def get_y(y):
                        return h - y - 1

                if bpp in (1, 2, 4):
                    ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel
                    srcpixels = ffi.cast(ptr_type, c_surf.pixels)
                    destpixels = ffi.cast(ptr_type, new_surf.pixels)
                    dest_step = dest_pitch // bpp
                    src_step = src_pitch // bpp
                    for y in range(h):
                        dest_row_start = get_y(y) * dest_step
                        src_row_start = y * src_step
                        for x in range(w):
                            destpixels[dest_row_start + (w - x - 1)] = \
                                    srcpixels[src_row_start + x]
                else:
                    srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                    destpixels = ffi.cast('uint8_t*', new_surf.pixels)
                    for y in range(h):
                        dest_row_start = get_y(y) * dest_pitch
                        src_row_start = y * src_pitch
                        for x in range(0, src_pitch, 3):
                            dest_pix_start = dest_row_start + (dest_pitch - x -
                                                               3)
                            src_pix_start = src_row_start + x
                            destpixels[dest_pix_start:dest_pix_start + 3] = \
                                srcpixels[src_pix_start:src_pix_start + 3]

    return Surface._from_sdl_surface(new_surf)
Beispiel #34
0
def _tostring_RGB(surf, flipped):
    rmask, gmask, bmask, amask = (surf.format.Rmask, surf.format.Gmask,
                                  surf.format.Bmask, surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift, surf.format.Gshift,
                                      surf.format.Bshift, surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss, surf.format.Gloss,
                                  surf.format.Bloss, surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w

    data = ffi.new('char[]', w * h * 3)
    if bpp == 1:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        colors = surf.format.palette.colors
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(colors[color].r)
                data[dest + 1] = chr_(colors[color].g)
                data[dest + 2] = chr_(colors[color].b)
    elif bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 3 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 3 * (y * w + x)
                color = pixels[src_start + x]
                data[dest] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + 1] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + 2] = chr_(((color & bmask) >> bshift) << bloss)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #35
0
def _tostring_RGBA_PREMULT(surf, flipped, argb=False):
    if surf.format.BytesPerPixel == 1 or surf.format.Amask == 0:
        raise ValueError("Can only create pre-multiplied alpha strings if "
                         "the surface has per-pixel alpha")

    rmask, gmask, bmask, amask = (surf.format.Rmask, surf.format.Gmask,
                                  surf.format.Bmask, surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift, surf.format.Gshift,
                                      surf.format.Bshift, surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss, surf.format.Gloss,
                                  surf.format.Bloss, surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w
    if argb:
        ri, gi, bi, ai = 1, 2, 3, 0
    else:
        ri, gi, bi, ai = 0, 1, 2, 3

    data = ffi.new('char[]', w * h * 4)
    if bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                alpha = ((color & amask) >> ashift) << aloss
                data[dest + ri] = chr_(
                    (((color & rmask) >> rshift) << rloss) * alpha // 255)
                data[dest + gi] = chr_(
                    (((color & gmask) >> gshift) << gloss) * alpha // 255)
                data[dest + bi] = chr_(
                    (((color & bmask) >> bshift) << bloss) * alpha // 255)
                data[dest + ai] = chr_(alpha)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 4 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                alpha = ((color & amask) >> ashift) << aloss
                data[dest + ri] = chr_(
                    (((color & rmask) >> rshift) << rloss) * alpha // 255)
                data[dest + gi] = chr_(
                    (((color & gmask) >> gshift) << gloss) * alpha // 255)
                data[dest + bi] = chr_(
                    (((color & bmask) >> bshift) << bloss) * alpha // 255)
                data[dest + ai] = chr_(alpha)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                alpha = ((color & amask) >> ashift) << aloss
                if alpha == 0:
                    data[dest + ri] = data[dest + gi] = data[dest + bi] \
                        = chr_(0)
                else:
                    data[dest + ri] = chr_(
                        (((color & rmask) >> rshift) << rloss) * alpha // 255)
                    data[dest + gi] = chr_(
                        (((color & gmask) >> gshift) << gloss) * alpha // 255)
                    data[dest + bi] = chr_(
                        (((color & bmask) >> bshift) << bloss) * alpha // 255)
                data[dest + ai] = chr_(alpha)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #36
0
def _tostring_RGBA(surf, flipped, has_colorkey=True, argb=False):
    rmask, gmask, bmask, amask = (surf.format.Rmask, surf.format.Gmask,
                                  surf.format.Bmask, surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift, surf.format.Gshift,
                                      surf.format.Bshift, surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss, surf.format.Gloss,
                                  surf.format.Bloss, surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w
    colorkey = surf.format.colorkey
    if argb:
        has_colorkey = False
        ri, gi, bi, ai = 1, 2, 3, 0
    else:
        has_colorkey = (has_colorkey and surf.flags & sdl.SDL_SRCCOLORKEY
                        and not amask)
        ri, gi, bi, ai = 0, 1, 2, 3

    data = ffi.new('char[]', w * h * 4)
    if bpp == 1:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        colors = surf.format.palette.colors
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(colors[color].r)
                data[dest + gi] = chr_(colors[color].g)
                data[dest + bi] = chr_(colors[color].b)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(255)
    elif bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(((
                        (color & amask) >> ashift) << aloss) if amask else 255)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 4 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(((
                        (color & amask) >> ashift) << aloss) if amask else 255)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(((
                        (color & amask) >> ashift) << aloss) if amask else 255)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #37
0
    def __init__(self, sdlevent, d=None, **kwargs):
        self._sdlevent = sdlevent
        if isinstance(sdlevent, int):
            # User specificed event with kwargs
            self.type = sdlevent
            # XXX: Pygame manipulates __dict__, we're currently don't
            # this causes a failure in test_Event
            if d:
                self._dict = d.copy()
            else:
                self._dict = {}
            if kwargs:
                self._dict.update(kwargs)
            for attr, value in self._dict.items():
                setattr(self, attr, value)
            return
        if not sdlevent:
            self.type = sdl.SDL_NOEVENT
            return
        self.type = self._sdlevent.type

        if (sdlevent.user.code == int(_USEROBJECT_CHECK1) and
                sdlevent.user.data1 == _USEROBJECT_CHECK2):
            eventkey = ffi.cast("SDL_Event *", sdlevent.user.data2)
            if eventkey in _user_events:
                self._dict = _user_events[eventkey]._dict
                del _user_events[eventkey]
                for attr, value in self._dict.items():
                    setattr(self, attr, value)
                return
            raise NotImplementedError("TODO: Error handling for user-posted events.")

        if self.type == ACTIVEEVENT:
            self.gain = sdlevent.active.gain
            self.state = sdlevent.active.state

        elif self.type == KEYDOWN:
            self.unicode = sdlevent.key.keysym.unicode
            self.key = sdlevent.key.keysym.sym
            self.mod = sdlevent.key.keysym.mod
            self.scancode = sdlevent.key.keysym.scancode
        elif self.type == KEYUP:
            self.key = sdlevent.key.keysym.sym
            self.mod = sdlevent.key.keysym.mod
            self.scancode = sdlevent.key.keysym.scancode

        elif self.type == MOUSEMOTION:
            self.pos = (sdlevent.motion.x, sdlevent.motion.y)
            self.rel = (sdlevent.motion.xrel, sdlevent.motion.yrel)
            self.buttons = (_button_state(sdlevent.motion.state, 1),
                            _button_state(sdlevent.motion.state, 2),
                            _button_state(sdlevent.motion.state, 3))
        elif self.type in (MOUSEBUTTONDOWN, MOUSEBUTTONUP):
            self.pos = (sdlevent.button.x, sdlevent.button.y)
            self.button = sdlevent.button.button

        elif self.type == JOYAXISMOTION:
            self.joy = sdlevent.jaxis.which
            self.axis = sdlevent.jaxis.axis
            self.value = sdlevent.jaxis.value / 32767.0
        elif self.type == JOYBALLMOTION:
            self.joy = sdlevent.jball.which
            self.ball = sdlevent.jball.ball
            self.rel = (sdlevent.jball.xrel, sdlevent.jball.yrel)
        elif self.type == JOYHATMOTION:
            self.joy = sdlevent.jhat.which
            self.hat = sdlevent.jhat.hat
            hx = hy = 0
            if sdlevent.jhat.value & sdl.SDL_HAT_UP:
                hy = 1
            elif sdlevent.jhat.value & sdl.SDL_HAT_DOWN:
                hy = -1
            if sdlevent.jhat.value & sdl.SDL_HAT_RIGHT:
                hx = 1
            elif sdlevent.jhat.value & sdl.SDL_HAT_LEFT:
                hx = -1
            self.value = (hx, hy)
        elif self.type in (JOYBUTTONUP, JOYBUTTONDOWN):
            self.joy = sdlevent.jbutton.which
            self.button = sdlevent.jbutton.button

        elif self.type == VIDEORESIZE:
            self.size = (sdlevent.resize.w, sdlevent.resize.h)
            self.w = sdlevent.resize.w
            self.h = sdlevent.resize.h

        elif self.type == SYSWMEVENT:
            raise NotImplementedError("SYSWMEVENT not properly supported yet.")

        elif self.type in (VIDEOEXPOSE, QUIT):
            pass  # No attributes here.

        elif USEREVENT <= self.type < NUMEVENTS:
            self.code = sdlevent.user.code
            if self.type == USEREVENT and sdlevent.user.code == USEREVENT_DROPFILE:
                # mirrors what pygame does - not sure if correct
                self.filename = ffi.string(sdlevent.user.data1)
                sdl.free(sdlevent.user.data1)
                sdlevent.user.data1 = ffi.NULL
Beispiel #38
0
    def __init__(self, sdlevent, d=None, **kwargs):
        self._sdlevent = sdlevent
        if isinstance(sdlevent, int):
            # User specificed event with kwargs
            self.type = sdlevent
            # XXX: Pygame manipulates __dict__, we're currently don't
            # this causes a failure in test_Event
            if d:
                self._dict = d.copy()
            else:
                self._dict = {}
            if kwargs:
                self._dict.update(kwargs)
            for attr, value in self._dict.items():
                setattr(self, attr, value)
            return
        if not sdlevent:
            self.type = sdl.SDL_NOEVENT
            return
        self.type = self._sdlevent.type

        if (sdlevent.user.code == int(_USEROBJECT_CHECK1) and
                sdlevent.user.data1 == _USEROBJECT_CHECK2):
            eventkey = ffi.cast("SDL_Event *", sdlevent.user.data2)
            if eventkey in _user_events:
                self._dict = _user_events[eventkey]._dict
                del _user_events[eventkey]
                for attr, value in self._dict.items():
                    setattr(self, attr, value)
                return
            raise NotImplementedError("TODO: Error handling for user-posted events.")

        if self.type == ACTIVEEVENT:
            self.gain = sdlevent.active.gain
            self.state = sdlevent.active.state

        elif self.type == KEYDOWN:
            self.unicode = unichr_(sdlevent.key.keysym.unicode)
            self.key = sdlevent.key.keysym.sym
            self.mod = sdlevent.key.keysym.mod
            self.scancode = sdlevent.key.keysym.scancode
        elif self.type == KEYUP:
            self.key = sdlevent.key.keysym.sym
            self.mod = sdlevent.key.keysym.mod
            self.scancode = sdlevent.key.keysym.scancode

        elif self.type == MOUSEMOTION:
            self.pos = (sdlevent.motion.x, sdlevent.motion.y)
            self.rel = (sdlevent.motion.xrel, sdlevent.motion.yrel)
            self.buttons = (_button_state(sdlevent.motion.state, 1),
                            _button_state(sdlevent.motion.state, 2),
                            _button_state(sdlevent.motion.state, 3))
        elif self.type in (MOUSEBUTTONDOWN, MOUSEBUTTONUP):
            self.pos = (sdlevent.button.x, sdlevent.button.y)
            self.button = sdlevent.button.button

        elif self.type == JOYAXISMOTION:
            self.joy = sdlevent.jaxis.which
            self.axis = sdlevent.jaxis.axis
            self.value = sdlevent.jaxis.value / 32767.0
        elif self.type == JOYBALLMOTION:
            self.joy = sdlevent.jball.which
            self.ball = sdlevent.jball.ball
            self.rel = (sdlevent.jball.xrel, sdlevent.jball.yrel)
        elif self.type == JOYHATMOTION:
            self.joy = sdlevent.jhat.which
            self.hat = sdlevent.jhat.hat
            hx = hy = 0
            if sdlevent.jhat.value & sdl.SDL_HAT_UP:
                hy = 1
            elif sdlevent.jhat.value & sdl.SDL_HAT_DOWN:
                hy = -1
            if sdlevent.jhat.value & sdl.SDL_HAT_RIGHT:
                hx = 1
            elif sdlevent.jhat.value & sdl.SDL_HAT_LEFT:
                hx = -1
            self.value = (hx, hy)
        elif self.type in (JOYBUTTONUP, JOYBUTTONDOWN):
            self.joy = sdlevent.jbutton.which
            self.button = sdlevent.jbutton.button

        elif self.type == VIDEORESIZE:
            self.size = (sdlevent.resize.w, sdlevent.resize.h)
            self.w = sdlevent.resize.w
            self.h = sdlevent.resize.h

        elif self.type == SYSWMEVENT:
            raise NotImplementedError("SYSWMEVENT not properly supported yet.")

        elif self.type in (VIDEOEXPOSE, QUIT):
            pass  # No attributes here.

        elif USEREVENT <= self.type < NUMEVENTS:
            self.code = sdlevent.user.code
            if self.type == USEREVENT and sdlevent.user.code == USEREVENT_DROPFILE:
                # mirrors what pygame does - not sure if correct
                self.filename = ffi.string(sdlevent.user.data1)
                sdl.free(sdlevent.user.data1)
                sdlevent.user.data1 = ffi.NULL
Beispiel #39
0
    def __init__(self, obj=None, **kwargs):
        check_mixer()
        self.chunk = None
        self._mem = None

        # nasty mangling of parameters!
        # if 1 position arg: could be filename, file or buffer
        # if 1 keyword arg: could be filename, file, buffer or array where
        # filename and file use the same keyword 'file'
        if obj is not None:
            if kwargs:
                raise TypeError("Sound takes either 1 positional or "
                                "1 keyword argument")

            filename = None
            buff = None
            err = None
            if isinstance(obj, string_types):
                filename = obj
                if not isinstance(obj, unicode_):
                    buff = obj
            elif isinstance(obj, bytes):
                # For python3, we need to try both paths
                filename = obj
                buff = obj
            elif isinstance(obj, IOBase):
                rwops = rwops_from_file(obj)
                self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
            else:
                buff = obj

            if filename is not None:
                try:
                    filename = rwops_encode_file_path(filename)
                    rwops = rwops_from_file_path(filename)
                    self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
                except SDLError as e:
                    err = e

            if not self.chunk and buff is not None:
                if isinstance(buff, unicode_):
                    raise TypeError("Unicode object not allowed as "
                                    "buffer object")
                try:
                    self._load_from_buffer(buff)
                except TypeError:
                    # Pygame is special here, and falls through to a
                    # different error if the object doesn't support
                    # the buffer interface.
                    pass
        else:
            if len(kwargs) != 1:
                raise TypeError("Sound takes either 1 positional or "
                                "1 keyword argument")

            # Py3k Dictionary Views are iterables, not iterators
            arg_name, arg_value = next(iter(kwargs.items()))
            if arg_name == 'file':
                if isinstance(arg_value, string_types):
                    filename = rwops_encode_file_path(arg_value)
                    rwops = rwops_from_file_path(filename, 'rb')
                elif isinstance(arg_value, bytes):
                    # Needed for python 3
                    filename = rwops_encode_file_path(arg_value)
                    rwops = rwops_from_file_path(filename, 'rb')
                else:
                    rwops = rwops_from_file(arg_value)
                self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
            elif arg_name == 'buffer':
                if isinstance(arg_value, unicode_):
                    raise TypeError("Unicode object not allowed as "
                                    "buffer object")
                self._load_from_buffer(arg_value)
            elif arg_name == 'array':
                raise NotImplementedError("Loading from array not "
                                          "implemented yet")
            else:
                raise TypeError("Unrecognized keyword argument '%s'" %
                                arg_name)

        # pygame uses the pointer address as the tag to ensure
        # uniqueness, we use id for the same effect
        # Since we don't have the some automatic casting rules as
        # C, we explicitly cast to int here. This matches pygames
        # behaviour, so we're bug-compatible
        self._chunk_tag = ffi.cast("int", id(self.chunk))
        if not self.chunk:
            if not err:
                raise TypeError("Unrecognized argument (type %s)" %
                                type(obj).__name__)
            raise SDLError.from_sdl_error()
Beispiel #40
0
def _tostring_RGBA(surf, flipped, has_colorkey=True, argb=False):
    rmask, gmask, bmask, amask = (surf.format.Rmask,
                                  surf.format.Gmask,
                                  surf.format.Bmask,
                                  surf.format.Amask)
    rshift, gshift, bshift, ashift = (surf.format.Rshift,
                                      surf.format.Gshift,
                                      surf.format.Bshift,
                                      surf.format.Ashift)
    rloss, gloss, bloss, aloss = (surf.format.Rloss,
                                  surf.format.Gloss,
                                  surf.format.Bloss,
                                  surf.format.Aloss)
    bpp = surf.format.BytesPerPixel
    h, w = surf.h, surf.w
    colorkey = surf.format.colorkey
    if argb:
        has_colorkey = False
        ri, gi, bi, ai = 1, 2, 3, 0
    else:
        has_colorkey = (has_colorkey and surf.flags & sdl.SDL_SRCCOLORKEY
                        and not amask)
        ri, gi, bi, ai = 0, 1, 2, 3

    data = ffi.new('char[]', w * h * 4)
    if bpp == 1:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        colors = surf.format.palette.colors
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(colors[color].r)
                data[dest + gi] = chr_(colors[color].g)
                data[dest + bi] = chr_(colors[color].b)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(255)
    elif bpp == 2:
        pixels = ffi.cast('uint16_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(
                        (((color & amask) >> ashift) << aloss)
                        if amask else 255)
    elif bpp == 3:
        pixels = ffi.cast('uint8_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * surf.pitch if flipped \
                        else y * surf.pitch
            for x in range(w):
                dest = 4 * (y * w + x)
                color = (pixels[src_start + x * 3 + BYTE0] +
                         (pixels[src_start + x * 3 + BYTE1] << 8) +
                         (pixels[src_start + x * 3 + BYTE2] << 16))
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(
                        (((color & amask) >> ashift) << aloss)
                        if amask else 255)
    elif bpp == 4:
        pixels = ffi.cast('uint32_t*', surf.pixels)
        for y in range(h):
            src_start = (h - 1 - y) * w if flipped \
                        else y * w
            for x in range(w):
                dest = 4 * (y * w + x)
                color = pixels[src_start + x]
                data[dest + ri] = chr_(((color & rmask) >> rshift) << rloss)
                data[dest + gi] = chr_(((color & gmask) >> gshift) << gloss)
                data[dest + bi] = chr_(((color & bmask) >> bshift) << bloss)
                if has_colorkey:
                    data[dest + ai] = chr_(
                        ffi.cast('char', color != colorkey) * 255)
                else:
                    data[dest + ai] = chr_(
                        (((color & amask) >> ashift) << aloss)
                        if amask else 255)
    else:
        raise ValueError("invalid color depth")
    return ffi.buffer(data)[:]
Beispiel #41
0
def chop(surface, rect):
    """ chop(Surface, rect) -> Surface
    gets a copy of an image with an interior area removed
    """
    rect = Rect(rect)
    width = rect.width
    height = rect.width
    x = rect.x
    y = rect.y
    if rect.right > surface._w:
        width = surface._w - rect.x
    if rect.height > surface._h:
        height = surface._h - rect.y
    if rect.x < 0:
        width -= -x
        x = 0
    if rect.y < 0:
        height -= -y
        y = 0
    c_surf = surface._c_surface

    new_surf = new_surface_from_surface(c_surf, surface._w, surface._h)

    bpp = c_surf.format.BytesPerPixel
    src_pitch = c_surf.pitch
    dest_pitch = new_surf.pitch
    w, h = c_surf.w, c_surf.h

    with locked(new_surf):
        with locked(c_surf):
            if bpp in (1, 2, 4):
                ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel
                srcpixels = ffi.cast(ptr_type, c_surf.pixels)
                destpixels = ffi.cast(ptr_type, new_surf.pixels)
            else:
                srcpixels = ffi.cast('uint8_t*', c_surf.pixels)
                destpixels = ffi.cast('uint8_t*', new_surf.pixels)
            dy = 0
            if bpp in (1, 2, 4):
                dest_step = dest_pitch // bpp
                src_step = src_pitch // bpp
            for sy in range(0, surface._h):
                if sy >= y and sy < y + height:
                    continue
                dx = 0
                if bpp in (1, 2, 4):
                    dest_row_start = dy * dest_step
                    src_row_start = sy * src_step
                else:
                    dest_row_start = dy * dest_pitch
                    src_row_start = sy * src_pitch

                for sx in range(0, surface._w):
                    if sx >= x and sx < x + width:
                        continue
                    if bpp in (1, 2, 4):
                        destpixels[dest_row_start + dx] = \
                            srcpixels[src_row_start + sx]
                    else:
                        dest_pix_start = dest_row_start + dx
                        src_pix_start = src_row_start + sx
                        destpixels[dest_pix_start:dest_pix_start + 3] = \
                            srcpixels[src_pix_start:src_pix_start + 3]
                    dx += 1
                dy += 1

    return Surface._from_sdl_surface(new_surf)
Beispiel #42
0
def _timer_callback(interval, param):
    if sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO):
        event = ffi.new("SDL_Event")
        event.type = ffi.cast("intptr_t", param)
        sdl.SDL_PushEvent(event)
    return interval
Beispiel #43
0
def fromstring(string, size, format, flipped=False):
    w, h = size
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest =  surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 3 if flipped else y * w * 3
                row = string[src_start:src_start + w * 3]
                for x in range(0, w * 3, 3):
                    # BYTE0, BYTE1 and BYTE2 are determined by byte order
                    pixels[dest + x + BYTE0] = row[x + BYTE0]
                    pixels[dest + x + BYTE1] = row[x + BYTE1]
                    pixels[dest + x + BYTE2] = row[x + BYTE2]

    elif format in ("RGBA", "RGBAX", "ARGB"):
        if len(string) != w * h * 4:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        if format == "ARGB":
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask, amask = (0xff << 8, 0xff << 16,
                                              0xff << 24, 0xff)
            else:
                rmask, gmask, bmask, amask = (0xff << 16, 0xff << 8,
                                              0xff, 0xff << 24)
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA, w, h, 32,
                                            rmask, gmask, bmask, amask)
        else:
            alphamult = format == "RGBA"
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask = 0xff, 0xff << 8, 0xff << 16
                amask = 0xff << 24 if alphamult else 0
            else:
                rmask, gmask, bmask = 0xff << 24, 0xff << 16, 0xff << 8
                amask = 0xff if alphamult else 0
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA if alphamult
                                            else 0, w, h, 32, rmask, gmask,
                                            bmask, amask)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 4 if flipped else y * w * 4
                pixels[dest:dest + w * 4]  = string[src_start:src_start + w * 4]

    else:
        raise ValueError("Unrecognized type of format")

    return Surface._from_sdl_surface(surf)
Beispiel #44
0
    def __init__(self, obj=None, **kwargs):
        check_mixer()
        self.chunk = None

        # nasty mangling of parameters!
        # if 1 position arg: could be filename, file or buffer
        # if 1 keyword arg: could be filename, file, buffer or array where
        # filename and file use the same keyword 'file'
        if obj is not None:
            if kwargs:
                raise TypeError("Sound takes either 1 positional or "
                                "1 keyword argument")

            filename = None
            buff = None
            err = None
            if isinstance(obj, basestring):
                filename = obj
                if not isinstance(obj, unicode):
                    buff = obj
            elif isinstance(obj, file):
                rwops = rwops_from_file(obj)
                self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
            else:
                buff = obj

            if filename is not None:
                try:
                    filename = rwops_encode_file_path(filename)
                    rwops = rwops_from_file_path(filename)
                    self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
                except SDLError as e:
                    err = e

            if not self.chunk and buff is not None:
                raise NotImplementedError("Loading from buffer not "
                                          "implemented yet")
                # TODO: check if buff implements buffer interface.
                # If it does, load from buffer. If not, re-raise
                # error from filename if filename is not None.

        else:
            if len(kwargs) != 1:
                raise TypeError("Sound takes either 1 positional or "
                                "1 keyword argument")

            arg_name = kwargs.keys()[0]
            arg_value = kwargs[arg_name]
            if arg_name == 'file':
                if isinstance(arg_value, basestring):
                    filename = rwops_encode_file_path(arg_value)
                    rwops = rwops_from_file_path(filename, 'rb')
                else:
                    rwops = rwops_from_file(arg_value)
                self.chunk = sdl.Mix_LoadWAV_RW(rwops, 1)
            elif arg_name == 'buffer':
                if isinstance(arg_name, unicode):
                    raise TypeError("Unicode object not allowed as "
                                    "buffer object")
                raise NotImplementedError("Loading from buffer not "
                                          "implemented yet")
            elif arg_name == 'array':
                raise NotImplementedError("Loading from array not "
                                          "implemented yet")
            else:
                raise TypeError("Unrecognized keyword argument '%s'" %
                                arg_name)

        # pygame uses the pointer address as the tag to ensure
        # uniqueness, we use id for the same effect
        # Since we don't have the some automatic casting rules as
        # C, we explicitly cast to int here. This matches pygames
        # behaviour, so we're bug-compatible
        self._chunk_tag = ffi.cast("int", id(self.chunk))
        if not self.chunk:
            raise SDLError.from_sdl_error()