Source code for libretro.api.av

"""
Types to describe the parameters of a core's rendered audio and video.

.. seealso:: :mod:`libretro.drivers.video`, :mod:`libretro.drivers.audio`
"""

from ctypes import Structure, c_double, c_float, c_uint
from dataclasses import dataclass
from enum import CONFORM, IntEnum, IntFlag

RETRO_REGION_NTSC = 0
RETRO_REGION_PAL = 1

retro_av_enable_flags = c_uint
RETRO_AV_ENABLE_VIDEO = 1 << 0
RETRO_AV_ENABLE_AUDIO = 1 << 1
RETRO_AV_ENABLE_FAST_SAVESTATES = 1 << 2
RETRO_AV_ENABLE_HARD_DISABLE_AUDIO = 1 << 3
RETRO_AV_ENABLE_DUMMY = 0x7FFFFFFF


[docs] class Region(IntEnum): """ TV region. .. seealso:: :meth:`.Core.get_region` """ NTSC = RETRO_REGION_NTSC """ Corresponds to :c:macro:`RETRO_REGION_NTSC`. .. tip:: Cores may also return this if the NTSC/PAL region isn't applicable, e.g. for handhelds or arcade machines. """ PAL = RETRO_REGION_PAL """Corresponds to :c:macro:`RETRO_REGION_PAL`."""
[docs] class AvEnableFlags(IntFlag, boundary=CONFORM): """ Bit flags that denote whether the loaded :term:`core` should render audio and/or video frames. .. tip:: These flags can be set even if libretro.py isn't literally showing audio or video output to the user. .. seealso:: :attr:`.EnvironmentCall.GET_AUDIO_VIDEO_ENABLE` """ VIDEO = RETRO_AV_ENABLE_VIDEO """ If not set, the :term:`core` can safely skip rendering the next video frame. Corresponds to :c:macro:`RETRO_AV_ENABLE_VIDEO`. """ AUDIO = RETRO_AV_ENABLE_AUDIO """ If not set, the :term:`core` can safely skip rendering the next audio frame. Corresponds to :c:macro:`RETRO_AV_ENABLE_AUDIO`. """ FAST_SAVESTATES = RETRO_AV_ENABLE_FAST_SAVESTATES """ Indicates that savestates will only be used by this process and will not be saved to disk. Corresponds to :c:macro:`RETRO_AV_ENABLE_FAST_SAVESTATES`. .. seealso:: :attr:`.EnvironmentCall.GET_SAVESTATE_CONTEXT` """ HARD_DISABLE_AUDIO = RETRO_AV_ENABLE_HARD_DISABLE_AUDIO """ If set, the :term:`core` can safely skip rendering audio frames for the entire duration of its execution. Corresponds to :c:macro:`RETRO_AV_ENABLE_HARD_DISABLE_AUDIO`. """ ALL = VIDEO | AUDIO | FAST_SAVESTATES | HARD_DISABLE_AUDIO """ All other flags are set. .. caution:: If additional flags are added in the future, this value will be updated to include them. Try not to rely on the exact value of this constant. """
[docs] @dataclass(init=False, slots=True) class retro_game_geometry(Structure): """ The expected (and possible) dimensions of the framebuffer. Corresponds to :c:type:`retro_game_geometry`. .. warning:: This object is mutable, therefore :class:`.VideoDriver` s should not expose or store references to it; all access should be done through copies, otherwise you run the risk of encountering hard-to-debug issues! .. seealso:: :attr:`.VideoDriver.geometry` """ # Structure subclasses implicitly convert primitive fields # to and from their ctypes equivalents, so we can define these # as their natural types for better type checking and readability. base_width: int """ Nominal video width in pixels. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. """ base_height: int """ Nominal video height in pixels. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. """ max_width: int """ Maximum possible video width in pixels. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. """ max_height: int """ Maximum possible video height in pixels. Assigned values will be bitwise-masked to fit into an :c:expr:`unsigned int`. """ aspect_ratio: float """ Nominal aspect ratio. ``0.0`` indicates that it should be calculated from :attr:`base_width` and :attr:`base_height`. Assigned values will be converted to a C :c:expr:`float`. """ _fields_ = ( ("base_width", c_uint), ("base_height", c_uint), ("max_width", c_uint), ("max_height", c_uint), ("aspect_ratio", c_float), ) # ctypes structures don't natively support deepcopy, so we have to implement it ourselves.
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object. Intended for use with :func:`copy.deepcopy`. >>> import copy >>> from libretro.api import retro_game_geometry >>> geom = retro_game_geometry(base_width=320, base_height=240, max_width=640, max_height=480, aspect_ratio=0.0) >>> geom2 = copy.deepcopy(geom) >>> geom == geom2 True >>> geom is geom2 False """ return retro_game_geometry( base_width=self.base_width, base_height=self.base_height, max_width=self.max_width, max_height=self.max_height, aspect_ratio=self.aspect_ratio, )
@property def base_size(self) -> tuple[int, int]: """ The base (nominal) resolution as ``(width, height)``. >>> from libretro.api import retro_game_geometry >>> geom = retro_game_geometry(base_width=256, base_height=224, max_width=256, max_height=224) >>> geom.base_size (256, 224) >>> (geom.base_width, geom.base_height) == geom.base_size True """ return self.base_width, self.base_height @property def max_size(self) -> tuple[int, int]: """ The maximum possible resolution as ``(width, height)``. >>> from libretro.api import retro_game_geometry >>> geom = retro_game_geometry(base_width=256, base_height=224, max_width=512, max_height=448) >>> geom.max_size (512, 448) >>> (geom.max_width, geom.max_height) == geom.max_size True """ return self.max_width, self.max_height
[docs] @dataclass(init=False, slots=True) class retro_system_timing(Structure): """ Description of the emulated system's video and audio output timings. Corresponds to :c:type:`retro_system_timing` in ``libretro.h``. """ fps: float """ The :term:`core`'s video refresh rate in frames per second. Assigned values will be converted to a C :c:expr:`double`. """ sample_rate: float """ The :term:`core`'s audio output rate in Hz. Assigned values will be converted to a C :c:expr:`double`. """ _fields_ = ( ("fps", c_double), ("sample_rate", c_double), )
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object. Intended for use with :func:`copy.deepcopy`. >>> import copy >>> from libretro.api import retro_system_timing >>> timing = retro_system_timing(fps=60.0, sample_rate=44100.0) >>> copy.deepcopy(timing).sample_rate 44100.0 """ return retro_system_timing(self.fps, self.sample_rate)
[docs] @dataclass(init=False, slots=True) class retro_system_av_info(Structure): """ Description of the emulated platform's audio and video characteristics. Corresponds to :c:type:`retro_system_av_info` in ``libretro.h``. .. warning:: This object is mutable, therefore :class:`.VideoDriver` s and :class:`.AudioDriver` s should not expose or store references to it; all access should be done through copies, otherwise you run the risk of encountering hard-to-debug issues! >>> from libretro.api import retro_system_av_info, retro_game_geometry, retro_system_timing >>> geom = retro_game_geometry(base_width=320, base_height=240, max_width=320, max_height=240) >>> timing = retro_system_timing(fps=60.0, sample_rate=32000.0) >>> av = retro_system_av_info(geom, timing) >>> av.geometry.base_width 320 >>> av.timing.fps 60.0 .. seealso:: :attr:`.Core.get_system_av_info` """ geometry: retro_game_geometry """Video output geometry.""" timing: retro_system_timing """Audio/video timing information.""" _fields_ = ( ("geometry", retro_game_geometry), ("timing", retro_system_timing), )
[docs] def __deepcopy__(self, _): """ Return a deep copy of this object. Intended for use with :func:`copy.deepcopy`. >>> import copy >>> from libretro.api import retro_system_av_info, retro_game_geometry, retro_system_timing >>> geom = retro_game_geometry(base_width=320, base_height=240, max_width=320, max_height=240) >>> timing = retro_system_timing(fps=60.0, sample_rate=32000.0) >>> av = retro_system_av_info(geom, timing) >>> av2 = copy.deepcopy(av) >>> av2.timing.sample_rate 32000.0 """ return retro_system_av_info(self.geometry, self.timing)
__all__ = [ "Region", "AvEnableFlags", "retro_game_geometry", "retro_system_timing", "retro_system_av_info", "retro_av_enable_flags", ]