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()
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()
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()
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
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)
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()
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
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()
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)
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)
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()
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()
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"))
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
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)
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())