Пример #1
0
    def test_SDL_GL_LoadUnloadLibrary(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")
        # Try the default library
        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()
        video.SDL_GL_UnloadLibrary()

        if has_opengl_lib():
            fpath = get_opengl_path().encode("utf-8")
            assert video.SDL_GL_LoadLibrary(fpath) == 0, SDL_GetError()
            video.SDL_GL_UnloadLibrary()
Пример #2
0
    def test_SDL_GL_GetSetSwapInterval(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")

        #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, None)
        #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, "Test")
        #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, 1234)

        # No current OpenGL context yet.
        # Might crash on certain platforms, since the internal state of
        # SDL2 does not support calling GL functions without having a
        # GL library loaded.
        # self.assertRaises(sdl.SDLError, video.SDL_GL_SetSwapInterval, 1)
        # self.assertRaises(sdl.SDLError, video.SDL_GL_SetSwapInterval, 0)

        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()
        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)
        ctx = video.SDL_GL_CreateContext(window)
        video.SDL_GL_MakeCurrent(window, ctx)

        ret = video.SDL_GL_SetSwapInterval(0)
        if ret == 0:
            assert video.SDL_GL_GetSwapInterval() == 0
        ret = video.SDL_GL_SetSwapInterval(1)
        if ret == 0:
            assert video.SDL_GL_GetSwapInterval() == 1

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_UnloadLibrary()
Пример #3
0
    def test_SDL_GL_CreateDeleteContext(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")

        # self.assertRaises((AttributeError, TypeError),
        #                  video.SDL_GL_CreateContext, None)
        # self.assertRaises((AttributeError, TypeError),
        #                  video.SDL_GL_CreateContext, "Test")
        # self.assertRaises((AttributeError, TypeError),
        #                  video.SDL_GL_CreateContext, 1234)

        window = video.SDL_CreateWindow(b"No OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_BORDERLESS)

        #self.assertRaises(sdl.SDLError, video.SDL_GL_CreateContext, window)
        video.SDL_DestroyWindow(window)

        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()
        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)

        ctx = video.SDL_GL_CreateContext(window)

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)

        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)

        ctx = video.SDL_GL_CreateContext(window)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_DeleteContext(ctx)

        video.SDL_GL_UnloadLibrary()
Пример #4
0
 def test_SDL_GetDisplayDPI(self):
     if video.SDL_GetCurrentVideoDriver() == b"dummy":
         pytest.skip("dummy video driver does not support display DPI")
     numdisplays = video.SDL_GetNumVideoDisplays()
     for index in range(numdisplays):
         ddpi, hdpi, vdpi = c_float(), c_float(), c_float()
         ret = video.SDL_GetDisplayDPI(index, byref(ddpi), byref(hdpi),
                                       byref(vdpi))
         assert ret == 0, SDL_GetError()
         assert ddpi.value >= 96.0
         assert hdpi.value >= 96.0
         assert vdpi.value >= 96.0
Пример #5
0
 def test_SDL_GetDisplayDPI(self):
     if video.SDL_GetCurrentVideoDriver() == b"dummy":
         self.skipTest("dummy video driver does not support display DPI")
     numdisplays = video.SDL_GetNumVideoDisplays()
     for index in range(numdisplays):
         ddpi, hdpi, vdpi = c_float(), c_float(), c_float()
         ret = video.SDL_GetDisplayDPI(index, byref(ddpi), byref(hdpi),
                                       byref(vdpi))
         self.assertEqual(ret, 0, SDL_GetError())
         self.assertGreaterEqual(ddpi.value, 96.0)
         self.assertGreaterEqual(hdpi.value, 96.0)
         self.assertGreaterEqual(vdpi.value, 96.0)
Пример #6
0
    def test_SDL_GL_SwapWindow(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")

        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()
        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)
        ctx = video.SDL_GL_CreateContext(window)
        video.SDL_GL_MakeCurrent(window, ctx)
        video.SDL_GL_SwapWindow(window)
        video.SDL_GL_SwapWindow(window)
        video.SDL_GL_SwapWindow(window)
        video.SDL_GL_SwapWindow(window)
        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_UnloadLibrary()
Пример #7
0
def sdl_call(func, *pargs, _check_error=None, **kwargs):
    """
    Wrapper for calling SDL functions for handling errors.

    If _check_error is given, called with the return value to check for errors.
    If _check_error returns truthy, an error occurred.

    If _check_error is not given, it is assumed that a non-empty error from
    Mix_GetError indicates error.
    """
    SDL_ClearError()
    rv = func(*pargs, **kwargs)
    err = SDL_GetError()
    if (_check_error(rv) if _check_error else err):
        raise SdlError(f"Error calling {func.__name__}: {err.decode('utf-8')}")
    else:
        return rv
Пример #8
0
 def test_SDL_GetClosestDisplayMode(self):
     if video.SDL_GetCurrentVideoDriver() == b"dummy":
         pytest.skip(
             "dummy video driver does not support closest display modes")
     numdisplays = video.SDL_GetNumVideoDisplays()
     for index in range(numdisplays):
         modes = video.SDL_GetNumDisplayModes(index)
         dmode = video.SDL_DisplayMode()
         for mode in range(modes):
             ret = video.SDL_GetDisplayMode(index, mode, byref(dmode))
             #self.assertIsInstance(dmode.contents, video.SDL_DisplayMode)
             assert ret == 0
             cmode = video.SDL_DisplayMode(dmode.format, dmode.w - 1,
                                           dmode.h - 1, dmode.refresh_rate)
             closest = video.SDL_DisplayMode()
             video.SDL_GetClosestDisplayMode(index, cmode, byref(closest))
             assert closest == dmode, SDL_GetError()
Пример #9
0
 def test_SDL_GetSetWindowOpacity(self):
     window = video.SDL_CreateWindow(b"Opacity", 10, 10, 10, 10, 0)
     opacity = c_float()
     ret = video.SDL_GetWindowOpacity(window, byref(opacity))
     assert ret == 0
     assert opacity.value == 1.0
     if video.SDL_GetCurrentVideoDriver() != b"dummy":
         ret = video.SDL_SetWindowOpacity(window, 0.0)
         assert ret == 0, SDL_GetError()
         ret = video.SDL_GetWindowOpacity(window, byref(opacity))
         assert ret == 0
         assert opacity.value == 0.0
         ret = video.SDL_SetWindowOpacity(window, 0.653)
         assert ret == 0
         ret = video.SDL_GetWindowOpacity(window, byref(opacity))
         assert ret == 0
         assert round(abs(opacity.value - 0.653), 2) == 0
     video.SDL_DestroyWindow(window)
Пример #10
0
 def test_SDL_GetSetWindowOpacity(self):
     window = video.SDL_CreateWindow(b"Opacity", 10, 10, 10, 10, 0)
     opacity = c_float()
     ret = video.SDL_GetWindowOpacity(window, byref(opacity))
     self.assertEqual(ret, 0)
     self.assertEqual(opacity.value, 1.0)
     if video.SDL_GetCurrentVideoDriver() != b"dummy":
         ret = video.SDL_SetWindowOpacity(window, 0.0)
         self.assertEqual(ret, 0, SDL_GetError())
         ret = video.SDL_GetWindowOpacity(window, byref(opacity))
         self.assertEqual(ret, 0)
         self.assertEqual(opacity.value, 0.0)
         ret = video.SDL_SetWindowOpacity(window, 0.653)
         self.assertEqual(ret, 0)
         ret = video.SDL_GetWindowOpacity(window, byref(opacity))
         self.assertEqual(ret, 0)
         self.assertAlmostEqual(opacity.value, 0.653, 2)
     video.SDL_DestroyWindow(window)
Пример #11
0
    def test_SDL_GL_GetSetAttribute(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")

        # self.assertRaises(sdl.SDLError, video.SDL_GL_GetAttribute,
        #                  video.SDL_GL_DEPTH_SIZE)
        # self.assertRaises(sdl.SDLError, video.SDL_GL_SetAttribute,
        #                  1455, 24)

        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()

        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)

        ctx = video.SDL_GL_CreateContext(window)

        depth = c_int()
        video.SDL_GL_GetAttribute(video.SDL_GL_DEPTH_SIZE, byref(depth))

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)

        newdepth = 24
        if depth == 8:
            newdepth = 16
        elif depth == 16:
            newdepth = 24
        elif depth == 24:
            newdepth = 16
        video.SDL_GL_SetAttribute(video.SDL_GL_DEPTH_SIZE, newdepth)

        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)
        ctx = video.SDL_GL_CreateContext(window)

        val = c_int()
        video.SDL_GL_GetAttribute(video.SDL_GL_DEPTH_SIZE, byref(val))
        assert depth != val
        assert val.value >= newdepth
        # self.assertEqual(val.value, newdepth)

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_UnloadLibrary()
Пример #12
0
    def test_SDL_GL_MakeCurrent(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            self.skipTest("dummy video driver does not support GL loading")

        self.assertEqual(video.SDL_GL_LoadLibrary(None), 0, SDL_GetError())

        # self.assertRaises((AttributeError, TypeError),
        #                  video.SDL_GL_MakeCurrent, None, None)

        window = video.SDL_CreateWindow(b"No OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_BORDERLESS)

        #self.assertRaises(sdl.SDLError, video.SDL_GL_CreateContext, window)
        video.SDL_DestroyWindow(window)

        # self.assertRaises((AttributeError, TypeError),
        #                  video.SDL_GL_MakeCurrent, None, None)

        video.SDL_GL_UnloadLibrary()
Пример #13
0
    def test_SDL_GL_ExtensionSupported(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            self.skipTest("dummy video driver does not support GL loading")

        self.assertFalse(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra"))

        self.assertEqual(video.SDL_GL_LoadLibrary(None), 0, SDL_GetError())
        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)

        ctx = video.SDL_GL_CreateContext(window)

        self.assertTrue(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra"))

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_UnloadLibrary()

        self.assertFalse(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra"))
Пример #14
0
    def test_SDL_GL_GetProcAddress(self):
        if video.SDL_GetCurrentVideoDriver() == b"dummy":
            pytest.skip("dummy video driver does not support GL loading")

        procaddr = video.SDL_GL_GetProcAddress(b"glGetString")
        assert procaddr is None

        assert video.SDL_GL_LoadLibrary(None) == 0, SDL_GetError()

        # Behaviour is undefined as long as there is no window and context.
        window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10,
                                        video.SDL_WINDOW_OPENGL)

        ctx = video.SDL_GL_CreateContext(window)

        procaddr = video.SDL_GL_GetProcAddress(b"glGetString")
        assert procaddr is not None and int(procaddr) != 0

        video.SDL_GL_DeleteContext(ctx)
        video.SDL_DestroyWindow(window)
        video.SDL_GL_UnloadLibrary()

        procaddr = video.SDL_GL_GetProcAddress(b"glGetString")
        assert procaddr is None
Пример #15
0
 def test_SDL_INIT_HAPTIC(self):
     ret = SDL_Init(SDL_INIT_HAPTIC)
     self.assertEqual(ret, 0, SDL_GetError())
     ret = SDL_WasInit(SDL_INIT_HAPTIC)
     self.assertEqual(ret, SDL_INIT_HAPTIC)
     SDL_QuitSubSystem(SDL_INIT_HAPTIC)
Пример #16
0
class Audio(Media):

    _channels_groups_lock = threading.Lock()
    _channels_groups = list()

    if SDL_Init(SDL_INIT_AUDIO) != 0:
        raise RuntimeError('Cannot initialize audio: ' + SDL_GetError())
    if Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024):
        raise RuntimeError('Cannot open mixed audio: ' + Mix_GetError())

    _volume = None

    @classmethod
    def _channel_finished(cls, channel):
        def find_player(channel):
            with cls._channels_groups_lock:
                for group in cls._channels_groups:
                    if channel in group:
                        return group[channel]
                raise KeyError(channel)

        try:
            player, sample = find_player(channel)
            player._sample_ended(sample, channel)
        except KeyError:
            pass

    @classmethod
    def _create_channels_group(cls):
        with cls._channels_groups_lock:
            cls._channels_groups.append(dict())
            return len(cls._channels_groups) - 1

    @classmethod
    def set_volume(cls, value: int):
        value = int(value)
        Mix_Volume(-1, value)
        cls._volume = value

    def __init__(self, files, *, loop=False, loop_last=False):
        files = ensure_iter(files)
        super().__init__(', '.join(map(str, files)))
        self.loop = loop
        self.loop_last = loop_last
        self.__loop = asyncio.get_event_loop()
        self._samples = list()
        self.__group_id = self._create_channels_group()
        self._stoping = False
        self._ended = asyncio.Event()
        self._ended.set()
        self._open(files)

    def __bool__(self):
        return bool(self.__channels_group)

    def __str__(self):
        return f'sound "{self.name}"'

    async def wait(self):
        await self._ended.wait()

    @property
    def __channels_group(self):
        return self._channels_groups[self.__group_id]

    def _sample_ended(self, sample, channel):
        try:
            if self._stoping:
                raise StopIteration()
            samples = iter(self._samples)
            while True:
                if next(samples) is sample:
                    next_sample = next(samples)
                    loop = self.loop_last and next_sample is self._samples[-1]
                    return self._play(next_sample, channel, loop=loop)
        except StopIteration:
            if not Mix_GroupChannel(channel, -1):
                print('ERROR, cannot remove channel from group')
            with self._channels_groups_lock:
                self.__channels_group.pop(channel)
            if not self:
                self.__loop.call_soon_threadsafe(self._ended.set)

    def _open(self, files):
        for file in files:
            sample = Mix_LoadWAV(byteify(str(file), 'utf-8'))
            if sample is None:
                raise RuntimeError('Cannot open audio file: ' + Mix_GetError())
            self._samples.append(sample)

    def _play(self, sample, channel=-1, *, loop=False):
        self._ended.clear()
        channel = Mix_PlayChannel(channel, sample, -1 if loop else 0)
        if not Mix_GroupChannel(channel, self.__group_id):
            print('ERROR, cannot remove channel from group')
        with self._channels_groups_lock:
            self.__channels_group[channel] = (self, sample)

    def play(self):
        self._play(self._samples[0], loop=self.loop)
        # TODO return self instead which can be awaited
        return asyncio.create_task(self._ended.wait())

    async def _reset(self):
        self._stoping = True
        Mix_HaltGroup(self.__group_id)
        await self._ended.wait()
        self._stoping = False

    def stop(self):
        return asyncio.create_task(self._reset())