Example #1
0
    def add_light(self, name, width, height):

        # set on first call only
        if 0 == self.light_size:
            self.light_size = width

        if width != height:
            raise SDLError('width and height of light image must be equal')

        # check for different size
        if width != self.light_size:
            raise SDLError('all light images must have the same resolution')

        self.lights[name] = width
Example #2
0
def aapolygon(surface, points, color, sdlgfx=None):
    """
    Draw anti-aliased polygon with alpha blending.

    Minimum number of points (vertices coordinates) is 3.

    Args:
    surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
    with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
    points (list of n 2-tuple int): list of X and Y tuples with vertices
    coordinates for the aa-polygon.
    color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    lx, ly = zip(*points)

    vx = (ctypes.c_short * len(lx))(*lx)
    vy = (ctypes.c_short * len(ly))(*ly)

    n = len(vy)

    if sdlgfx.aapolygonRGBA(surface, vx, vy, n, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.aapolygonRGBA failure")
Example #3
0
def rectangle(surface, rect, color, sdlgfx=None):
    """Draw rectangle with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x1 (int): X coordinate of the first point (i.e. top right) of the
        rectangle.
        y1 (int): Y coordinate of the first point (i.e. top right) of the
        rectangle.
        x2 (int): X coordinate of the second point (i.e. bottom left) of the
        rectangle.
        y2 (int): Y coordinate of the second point (i.e. bottom left) of the
        rectangle.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if not isinstance(rect, Rect):
        rect = Rect(rect)
    if sdlgfx.rectangleRGBA(surface, rect.x, rect.y, rect.x + rect.w,
                            rect.y + rect.h, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.rectangleRGBA failure")
Example #4
0
    def render(self, sprites, x=None, y=None):
        """Overrides the render method of sdl2.ext.TextureSpriteRenderSystem to
        use "SDL_RenderCopyEx" instead of "SDL_RenderCopy" to allow sprite
        rotation:
        http://wiki.libsdl.org/SDL_RenderCopyEx
        """
        r = SDL_Rect(0, 0, 0, 0)
        if isiterable(sprites):
            rcopy = SDL_RenderCopyEx
            renderer = self.sdlrenderer
            x = x or 0
            y = y or 0
            for sp in sprites:
                r.x = x + sp.x
                r.y = y + sp.y
                r.w, r.h = sp.size
                if rcopy(renderer, sp.texture, None, r, sp.angle, None,
                         SDL_FLIP_NONE) == -1:
                    raise SDLError()
        else:
            r.x = sprites.x
            r.y = sprites.y
            r.w, r.h = sprites.size
            if x is not None and y is not None:
                r.x = x
                r.y = y
            SDL_RenderCopyEx(self.sdlrenderer, sprites.texture, None, r,
                             sprites.angle, None, SDL_FLIP_NONE)

        SDL_RenderPresent(self.sdlrenderer)
Example #5
0
def bezier(surface, points, steps, color, sdlgfx=None):
    """
    Draw a bezier curve with alpha blending.

    Minimum number of points (vertices coordinates) is 3.
    Minimum number of steps for interpolation is 2.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        points (list of n 2-tuple int): list of X and Y tuples with points
        of the bezier curve.
        steps (int): Number of steps for the interpolation.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    lx, ly = zip(*points)

    vx = (ctypes.c_short * len(lx))(*lx)
    vy = (ctypes.c_short * len(ly))(*ly)

    n = len(vy)

    if sdlgfx.bezierRGBA(surface, vx, vy, n, steps, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.bezierRGBA failure")
Example #6
0
    def _create_texture(self):
        text_surface = TTF_RenderText_Shaded(self.font, self._text.encode("UTF-8"), self.text_color,
                                             self.background_color)
        if text_surface is None:
            raise TTF_GetError()

        texture = SDL_CreateTextureFromSurface(self.renderer, text_surface)

        if texture is None:
            raise SDLError()

        SDL_FreeSurface(text_surface)
        return texture
Example #7
0
def pixel(surface, x, y, color, sdlgfx=None):
    """Draw pixel with blending enabled if alpha < 255.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x (int): X (horizontal) coordinate of the pixel.
        y (int): Y (vertical) coordinate of the pixel.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.pixelRGBA(surface, x, y, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.pixelRGBA failure")
Example #8
0
def hline(surface, x1, x2, y, color, sdlgfx=None):
    """Draw horizontal line with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x1 (int):  X coordinate of the first point (i.e. left) of the line.
        x2 (int):  X coordinate of the second point (i.e. right) of the line.
        y  (int):  Y coordinate of the points of the line.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.hlineRGBA(surface, x1, x2, y, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.hlineRGBA failure")
Example #9
0
def filled_circle(surface, x, y, r, color, sdlgfx=None):
    """Draw filled circle with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x (int): X coordinate of the center of the filled circle.
        y (int): Y coordinate of the center of the filled circle.
        rad (int): Radius in pixels of the filled circle.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.filledCircleRGBA(surface, x, y, r, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.filledCircleRGBA failure")
Example #10
0
def aaellipse(surface, x, y, rx, ry, color, sdlgfx=None):
    """Draw anti-aliased ellipse with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x (int): X coordinate of the center of the aa-ellipse.
        y (int): Y coordinate of the center of the aa-ellipse.
        rx (int): Horizontal radius in pixels of the aa-ellipse.
        ry (int): Vertical radius in pixels of the aa-ellipse.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.aaellipseRGBA(surface, x, y, rx, ry, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.aaellipseRGBA failure")
Example #11
0
def aaline(surface, x1, y1, x2, y2, color, sdlgfx=None):
    """Draw anti-aliased line with alpha blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x1 (int): X coordinate of the first point of the line.
        y1 (int): Y coordinate of the first point of the line.
        x2 (int): X coordinate of the second point of the line.
        y2 (int): Y coordinate of the second point of the line.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.aalineRGBA(surface, x1, y1, x2, y2, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.aalineRGBA failure")
Example #12
0
def box(surface, rect, color, sdlgfx=None):
    """Draw a filled rectangle with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        rect (Rect): A rectangle representing the area to be draw.
        rad (int): The radius of the corner arc.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if not isinstance(rect, Rect):
        rect = Rect(rect)
    if sdlgfx.boxRGBA(surface, rect.x, rect.y, rect.x + rect.w,
                      rect.y + rect.h, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.boxRGBA failure")
Example #13
0
def pie(surface, x, y, r, start, end, color, sdlgfx=None):
    """Draw pie outline with alpha blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x (int): X coordinate of the center of the pie.
        y (int):   Y coordinate of the center of the pie.
        rad (int): Radius in pixels of the pie.
        start (int): Starting radius in degrees of the pie.
        end (int): Ending radius in degrees of the pie.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.pieRGBA(surface, x, y, r, start, end, c.r, c.g, c.b, c.a):
        raise SDLError("sdlgfx.pieRGBA failure")
Example #14
0
def rounded_rectangle(surface, rect, rad, color, sdlgfx=None):
    """Draw rounded-corner rectangle with blending.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        rect (Rect): A rectangle representing the area to be draw.
        rad (int): The radius of the corner arc.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if not isinstance(rect, Rect):
        rect = Rect(rect)
    if sdlgfx.roundedRectangleRGBA(surface, rect.right - 1, rect.top + 1,
                                   rect.left + 1, rect.bottom - 1, rad, c.r,
                                   c.g, c.b, c.a):
        raise SDLError("sdlgfx.rectangleRGBA failure")
Example #15
0
def textured_polygon(surface,
                     points,
                     texture,
                     texture_dx,
                     texture_dy,
                     sdlgfx=None):
    """
    Draw a polygon filled with the given texture.

    Minimum number of points (vertices coordinates) is 3.
    If you move the polygon and want the texture to apear the same you need
    to change the texture_dx and/or texture_dy values.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        points (list of n 2-tuple int): list of X and Y tuples with vertices
        coordinates for the polygon.
        texture (SDL_Surface): the surface to use to fill the polygon
        texture_dx (int): the horizontal offset of the texture relative to
        the screeen.
        texture_dy (int): the vertical offset of the texture relative to
        the screeen.

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    lx, ly = zip(*points)

    vx = (ctypes.c_short * len(lx))(*lx)
    vy = (ctypes.c_short * len(ly))(*ly)

    n = len(vy)

    if sdlgfx.texturedPolygon(surface, vx, vy, n, texture, texture_dx,
                              texture_dy):
        raise SDLError("sdlgfx.texturedPolygon failure")
Example #16
0
def filled_trigon(surface, x1, y1, x2, y2, x3, y3, color, sdlgfx=None):
    """Draw filled trigon (triangle) with alpha blending.

    Note: Creates vertex array and uses aapolygon routine to render.

    Args:
        surface (SDL_RENDERER, SDL_TEXTURE): The renderer or texture (created
        with the SDL_TEXTUREACCESS_TARGET flag) to draw on.
        x1 (int): X coordinate of the first point of the aa-trigon.
        y1 (int): Y coordinate of the first point of the aa-trigon.
        x2 (int): X coordinate of the second point of the aa-trigon.
        y2 (int): Y coordinate of the second point of the aa-trigon.
        x3 (int): X coordinate of the third point of the aa-trigon.
        y3 (int): Y coordinate of the third point of the aa-trigon.
        color (Color or 4-tuple with ints between 0-255): RGBA color

    Raises:
        SDLError
    """
    sdlgfx = sdlgfx_tex if (sdlgfx is None or sdlgfx == "tex") else sdlgfx_sfc
    c = Color(*color)
    if sdlgfx.filledTrigonRGBA(surface, x1, y1, x2, y2, x3, y3, c.r, c.g, c.b,
                               c.a):
        raise SDLError("sdlgfx.filledTrigonRGBA failure")
Example #17
0
def run():

    # get monitors (used to get desktop resolution)
    monitors = get_monitors()
    if len(monitors) > 1:
        raise SDLError('only single screen supported')

    # init calculator (used for positions)
    calculator = Calculator()
    calculator.set_screen_size(monitors[0].width, monitors[0].height)

    # init main window
    sdl2.ext.init()
    window = sdl2.ext.Window('c2k',
                             size=calculator.get_screen_size(),
                             flags=sdl2.SDL_WINDOW_BORDERLESS)
    window.show()

    # init renderer (software)
    sprite_renderer = SoftwareRenderer(window)
    factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)

    # init world an add renderer
    world = sdl2.ext.World()
    world.add_system(sprite_renderer)

    # dict of all lights as sprite in correct size
    light_sprites = {name: None for name in lights}

    for sprite_name in lights:

        # load surface and add resolution to calculator
        surface = sdl2.ext.load_image('resources/{}.png'.format(sprite_name))
        calculator.add_light(sprite_name, surface.w, surface.h)

        # scale the surface
        light_sprites[sprite_name] = get_scaled_surface(
            surface, calculator.get_light_scale(sprite_name))

    # calculate light positions
    calculator.calculate()

    # draw big grey lights
    for pos in calculator.get_big_grey_positions():
        Light(world, factory.from_surface(light_sprites.get('big_grey')),
              pos[0], pos[1], -2)

    # draw small grey lights
    for pos in calculator.get_small_grey_positions():
        Light(world, factory.from_surface(light_sprites.get('small_grey')),
              pos[0], pos[1], -2)

    _lights = {index: set() for index in range(5)}

    while True:

        # listen for exit event
        events = sdl2.ext.get_events()
        for event in events:
            if event.type == sdl2.SDL_QUIT:
                sys.exit(0)

        changes = calculator.get_changes()
        for index, change in changes.items():

            if change['changed']:

                for entity in _lights[index]:
                    world.delete(entity)

                _lights[index] = set()

                for position in change['positions']:
                    _lights[index].add(
                        Light(
                            world,
                            factory.from_surface(
                                light_sprites.get(row_lights[index])),
                            position[0], position[1]))

        world.process()
        sleep(1)
Example #18
0
def _image2sprite(image, factory):
    # pylint: disable=missing-docstring,bad-continuation,protected-access
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements
    mode = image.mode
    width, height = image.size
    rmask = gmask = bmask = amask = 0
    if mode in ("1", "L", "P"):
        # 1 = B/W, 1 bit per byte
        # "L" = greyscale, 8-bit
        # "P" = palette-based, 8-bit
        pitch = width
        depth = 8
    elif mode == "RGB":
        # 3x8-bit, 24bpp
        if endian.SDL_BYTEORDER == endian.SDL_LIL_ENDIAN:
            rmask = 0x0000FF
            gmask = 0x00FF00
            bmask = 0xFF0000
        else:
            rmask = 0xFF0000
            gmask = 0x00FF00
            bmask = 0x0000FF
        depth = 24
        pitch = width * 3
    elif mode in ("RGBA", "RGBX"):
        # RGBX: 4x8-bit, no alpha
        # RGBA: 4x8-bit, alpha
        if endian.SDL_BYTEORDER == endian.SDL_LIL_ENDIAN:
            rmask = 0x000000FF
            gmask = 0x0000FF00
            bmask = 0x00FF0000
            if mode == "RGBA":
                amask = 0xFF000000
        else:
            rmask = 0xFF000000
            gmask = 0x00FF0000
            bmask = 0x0000FF00
            if mode == "RGBA":
                amask = 0x000000FF
        depth = 32
        pitch = width * 4
    else:
        # We do not support CMYK or YCbCr for now
        raise TypeError("unsupported image format")

    pxbuf = image.tobytes()
    imgsurface = surface.SDL_CreateRGBSurfaceFrom(pxbuf, width, height,
                                                    depth, pitch, rmask,
                                                    gmask, bmask, amask)
    if not imgsurface:
        raise SDLError()
    imgsurface = imgsurface.contents
    # the pixel buffer must not be freed for the lifetime of the surface
    imgsurface._pxbuf = pxbuf

    if mode == "P":
        # Create a SDL_Palette for the SDL_Surface
        def _chunk(seq, size):
            for x in range(0, len(seq), size):
                yield seq[x:x + size]

        rgbcolors = image.getpalette()
        sdlpalette = pixels.SDL_AllocPalette(len(rgbcolors) // 3)
        if not sdlpalette:
            raise SDLError()
        SDL_Color = pixels.SDL_Color
        # pylint: disable=invalid-name
        for idx, (r, g, b) in enumerate(_chunk(rgbcolors, 3)):
            sdlpalette.contents.colors[idx] = SDL_Color(r, g, b)
        ret = surface.SDL_SetSurfacePalette(imgsurface, sdlpalette)
        # This will decrease the refcount on the palette, so it gets
        # freed properly on releasing the SDL_Surface.
        pixels.SDL_FreePalette(sdlpalette)
        if ret != 0:
            raise SDLError()

    return factory.from_surface(imgsurface, free=True)