Beispiel #1
0
    def compute_rectangles(self, texture, game_object, camera):
        flags = sdl2.stdinc.Uint32()
        access = ctypes.c_int()
        img_w = ctypes.c_int()
        img_h = ctypes.c_int()
        sdl_call(
            SDL_QueryTexture, texture, ctypes.byref(flags), ctypes.byref(access),
            ctypes.byref(img_w), ctypes.byref(img_h),
            _check_error=lambda rv: rv < 0
        )

        rect = getattr(game_object, 'rect', None)
        if rect:
            src_rect = SDL_Rect(*rect)
            win_w = rect[2] * game_object.size
            win_h = rect[3] * game_object.size
        else:
            src_rect = SDL_Rect(x=0, y=0, w=img_w, h=img_h)
            if hasattr(game_object, 'width'):
                obj_w = game_object.width
                obj_h = game_object.height
            else:
                obj_w, obj_h = game_object.size

            win_w, win_h = self.target_resolution(img_w.value, img_h.value, obj_w, obj_h, camera.pixel_ratio)

        center = camera.translate_point_to_screen(game_object.position)
        dest_rect = SDL_Rect(
            x=int(center.x - win_w / 2),
            y=int(center.y - win_h / 2),
            w=int(win_w),
            h=int(win_h),
        )

        return src_rect, dest_rect, ctypes.c_double(-game_object.rotation)
Beispiel #2
0
 def _draw_shape(self, renderer, rgb, **_):
     sdl_call(SDL_SetRenderDrawColor,
              renderer,
              *rgb,
              255,
              _check_error=lambda rv: rv < 0)
     sdl_call(SDL_RenderFillRect,
              renderer,
              None,
              _check_error=lambda rv: rv < 0)
Beispiel #3
0
    def __init__(self, red: int, green: int, blue: int):
        color = red, green, blue
        self._surface = _create_surface(color)

        renderer = sdl_call(SDL_CreateSoftwareRenderer,
                            self._surface,
                            _check_error=lambda rv: not rv)
        try:
            self._draw_shape(renderer, rgb=color)
        finally:
            sdl_call(SDL_DestroyRenderer, renderer)
Beispiel #4
0
 def _draw_shape(self, renderer, rgb, **_):
     half = int(DEFAULT_SPRITE_SIZE / 2)
     sdl_call(
         filledCircleRGBA,
         renderer,
         half,
         half,  # Center
         half,  # Radius
         *rgb,
         255,
         _check_error=lambda rv: rv < 0)
Beispiel #5
0
 def render_background(self, scene):
     bg = scene.background_color
     sdl_call(SDL_SetRenderDrawColor,
              self.renderer,
              bg[0],
              bg[1],
              bg[2],
              255,
              _check_error=lambda rv: rv < 0)
     sdl_call(SDL_RenderClear,
              self.renderer,
              _check_error=lambda rv: rv < 0)
Beispiel #6
0
 def _draw_shape(self, renderer, rgb, **_):
     sdl_call(filledTrigonRGBA,
              renderer,
              0,
              DEFAULT_SPRITE_SIZE,
              int(DEFAULT_SPRITE_SIZE / 2),
              0,
              DEFAULT_SPRITE_SIZE,
              DEFAULT_SPRITE_SIZE,
              *rgb,
              255,
              _check_error=lambda rv: rv < 0)
Beispiel #7
0
    def _background(self):
        surface = _create_surface(self.color)

        renderer = sdl_call(SDL_CreateSoftwareRenderer,
                            surface,
                            _check_error=lambda rv: not rv)
        try:
            self._draw_shape(renderer, rgb=self.color)
        finally:
            sdl_call(SDL_DestroyRenderer, renderer)

        return surface
Beispiel #8
0
    def background_parse(self, data):
        file = rw_from_object(io.BytesIO(data))
        # ^^^^ is a pure-python emulation, does not need cleanup.
        surface = img_call(IMG_Load_RW,
                           file,
                           False,
                           _check_error=lambda rv: not rv)

        sdl_call(SDL_SetSurfaceBlendMode,
                 surface,
                 SDL_BLENDMODE_BLEND,
                 _check_error=lambda rv: rv < 0)

        return surface
Beispiel #9
0
    def prepare_resource(self, game_object):
        """
        Get the SDL Texture for an object.
        """
        if not self._object_has_dimension(game_object):
            return None

        if not hasattr(game_object, '__image__'):
            return

        image = game_object.__image__()
        if image is flags.DoNotRender or image is None:
            return None

        surface = image.load()
        try:
            return self._texture_cache[surface]
        except KeyError:
            texture = SmartPointer(
                sdl_call(SDL_CreateTextureFromSurface,
                         self.renderer,
                         surface,
                         _check_error=lambda rv: not rv), SDL_DestroyTexture)
            self._texture_cache[surface] = texture
            return texture
Beispiel #10
0
 def __enter__(self):
     super().__enter__()
     img_call(IMG_Init, IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF)
     ttf_call(TTF_Init, _check_error=lambda rv: rv == -1)
     self.window = ctypes.POINTER(SDL_Window)()
     self.renderer = ctypes.POINTER(SDL_Renderer)()
     sdl_call(
         SDL_CreateWindowAndRenderer,
         self.resolution[0],  # Width
         self.resolution[1],  # Height
         0,  # Flags
         # SDL_WINDOW_ALLOW_HIGHDPI - Allow the renderer to work in HiDPI natively
         ctypes.byref(self.window),
         ctypes.byref(self.renderer),
         _check_error=lambda rv: rv < 0)
     # NOTE: It looks like SDL_RENDERER_PRESENTVSYNC will cause SDL_RenderPresent() to block?
     sdl_call(SDL_SetWindowTitle, self.window,
              self.window_title.encode('utf-8'))
Beispiel #11
0
    def on_render(self, render_event, signal):
        camera = render_event.scene.main_camera

        self.render_background(render_event.scene)

        for game_object in render_event.scene.sprite_layers():
            texture = self.prepare_resource(game_object)
            if texture is None:
                continue
            src_rect, dest_rect, angle = self.compute_rectangles(
                texture.inner, game_object, camera
            )
            flip = getattr(game_object, 'flip', SDL_FLIP_NONE)
            sdl_call(
                SDL_RenderCopyEx, self.renderer, texture.inner,
                ctypes.byref(src_rect), ctypes.byref(dest_rect),
                angle, None, flip,
                _check_error=lambda rv: rv < 0
            )
        sdl_call(SDL_RenderPresent, self.renderer)
Beispiel #12
0
def _create_surface(color):
    """
    Creates a surface for assets and sets the color key.
    """
    surface = sdl_call(SDL_CreateRGBSurface,
                       0,
                       DEFAULT_SPRITE_SIZE,
                       DEFAULT_SPRITE_SIZE,
                       32,
                       0,
                       0,
                       0,
                       0,
                       _check_error=lambda rv: not rv)
    color_key = BLACK if color != BLACK else MAGENTA
    color = sdl2.ext.Color(*color_key)
    sdl_call(SDL_SetColorKey,
             surface,
             True,
             sdl2.ext.prepare_color(color, surface.contents),
             _check_error=lambda rv: rv < 0)
    sdl2.ext.fill(surface.contents, color)
    return surface
Beispiel #13
0
    def prepare_resource(self, game_object):
        """
        Get the SDL Texture for an object.
        """
        if not self._object_has_dimension(game_object):
            return None

        if not hasattr(game_object, '__image__'):
            return

        image = game_object.__image__()
        if image is None:
            return None

        surface = image.load()
        try:
            texture = self._texture_cache[surface]
        except KeyError:
            texture = SmartPointer(
                sdl_call(SDL_CreateTextureFromSurface,
                         self.renderer,
                         surface,
                         _check_error=lambda rv: not rv), SDL_DestroyTexture)
            self._texture_cache[surface] = texture

        opacity = getattr(game_object, 'opacity', 255)
        opacity_mode = getattr(game_object, 'opacity_mode',
                               flags.BlendModeBlend)
        opacity_mode = OPACITY_MODES[opacity_mode]
        tint = getattr(game_object, 'tint', (255, 255, 255))

        sdl_call(SDL_SetTextureAlphaMod,
                 texture.inner,
                 opacity,
                 _check_error=lambda rv: rv < 0)

        sdl_call(SDL_SetTextureBlendMode,
                 texture.inner,
                 opacity_mode,
                 _check_error=lambda rv: rv < 0)

        sdl_call(SDL_SetTextureColorMod,
                 texture.inner,
                 tint[0],
                 tint[1],
                 tint[2],
                 _check_error=lambda rv: rv < 0)

        return texture
Beispiel #14
0
    def prepare_resource(self, game_object):
        texture = super().prepare_resource(game_object)
        if texture:
            opacity = getattr(game_object, 'opacity', 255)
            opacity_mode = getattr(game_object, 'opacity_mode', 'blend')
            color = getattr(game_object, 'color', (255, 255, 255))

            if True:  # opacity != self.last_opacity:
                sdl_call(SDL_SetTextureAlphaMod,
                         texture.inner,
                         opacity,
                         _check_error=lambda rv: rv < 0)
                self.last_opacity = opacity

            if True:  #opacity_mode != self.last_opacity_mode:
                self.last_opacity_mode = opacity_mode
                if opacity_mode == 'add':
                    sdl_call(SDL_SetTextureBlendMode,
                             texture.inner,
                             SDL_BLENDMODE_ADD,
                             _check_error=lambda rv: rv < 0)
                elif opacity_mode == 'blend':
                    sdl_call(SDL_SetTextureBlendMode,
                             texture.inner,
                             SDL_BLENDMODE_BLEND,
                             _check_error=lambda rv: rv < 0)
                else:
                    raise ValueError(
                        f"Support modes for translucent sprites are 'add' or 'blend', not '{opacity_mode}'."
                    )

            if True:  # color != self.last_color:
                sdl_call(SDL_SetTextureColorMod,
                         texture.inner,
                         color[0],
                         color[1],
                         color[2],
                         _check_error=lambda rv: rv < 0)
                self.last_color = color

            return texture
Beispiel #15
0
    def file_missing(self):
        width = height = 70  # Pixels, arbitrary
        surface = sdl_call(SDL_CreateRGBSurface,
                           0,
                           width,
                           height,
                           32,
                           0,
                           0,
                           0,
                           0,
                           _check_error=lambda rv: not rv)

        rand = random.Random(str(self.name))
        r = rand.randint(65, 255)
        g = rand.randint(65, 255)
        b = rand.randint(65, 255)
        color = sdl2.ext.Color(r, g, b)

        sdl2.ext.fill(surface.contents, color)
        return surface
Beispiel #16
0
 def __exit__(self, *exc):
     sdl_call(SDL_DestroyRenderer, self.renderer)
     sdl_call(SDL_DestroyWindow, self.window)
     ttf_call(TTF_Quit)
     img_call(IMG_Quit)
     super().__exit__(*exc)