Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fece657

Browse files
committedApr 9, 2024·
Add initial drafts of camera and disk drivers
1 parent 7d1be1b commit fece657

File tree

8 files changed

+204
-12
lines changed

8 files changed

+204
-12
lines changed
 

‎src/libretro/api/camera.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
from ctypes import CFUNCTYPE, POINTER, c_bool, c_uint, c_size_t, c_uint32, c_float, Structure, c_uint64, \
2-
c_int
1+
from ctypes import CFUNCTYPE, POINTER, c_bool, c_uint, c_size_t, c_uint32, c_float, Structure, c_uint64, c_int
32
from dataclasses import dataclass
4-
from enum import IntEnum
3+
from enum import IntEnum, IntFlag
54

65
from libretro.api._utils import FieldsFromTypeHints
76

87

98
retro_camera_buffer = c_int
109
RETRO_CAMERA_BUFFER_OPENGL_TEXTURE = 0
11-
RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER = (RETRO_CAMERA_BUFFER_OPENGL_TEXTURE + 1)
12-
RETRO_CAMERA_BUFFER_DUMMY = 0x7fffffff
10+
RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER = RETRO_CAMERA_BUFFER_OPENGL_TEXTURE + 1
11+
RETRO_CAMERA_BUFFER_DUMMY = 0x7FFFFFFF
1312

1413

1514
retro_camera_start_t = CFUNCTYPE(c_bool)
@@ -19,10 +18,18 @@
1918
retro_camera_frame_opengl_texture_t = CFUNCTYPE(None, c_uint, c_uint, POINTER(c_float))
2019

2120

22-
class CameraBufferType(IntEnum):
21+
class CameraCapabilities(IntEnum):
2322
OPENGL_TEXTURE = RETRO_CAMERA_BUFFER_OPENGL_TEXTURE
2423
RAW_FRAMEBUFFER = RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER
2524

25+
def flag(self) -> int:
26+
return 1 << self.value
27+
28+
29+
class CameraCapabilityFlags(IntFlag):
30+
OPENGL_TEXTURE = 1 << CameraCapabilities.OPENGL_TEXTURE
31+
RAW_FRAMEBUFFER = 1 << CameraCapabilities.RAW_FRAMEBUFFER
32+
2633

2734
@dataclass(init=False)
2835
class retro_camera_callback(Structure, metaclass=FieldsFromTypeHints):
@@ -57,6 +64,7 @@ def __deepcopy__(self, _):
5764
'retro_camera_frame_raw_framebuffer_t',
5865
'retro_camera_frame_opengl_texture_t',
5966
'retro_camera_callback',
60-
'CameraBufferType',
67+
'CameraCapabilities',
68+
'CameraCapabilityFlags',
6169
'retro_camera_buffer',
6270
]

‎src/libretro/driver/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .audio import *
22
from .camera import *
33
from .content import *
4+
from .disk import *
45
from .environment import *
56
from .input import *
67
from .led import *
+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .driver import *
2+
from .generator import *

‎src/libretro/driver/camera/driver.py

+81-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,88 @@
1+
from abc import abstractmethod
12
from typing import Protocol, runtime_checkable
2-
from libretro.api.camera import *
3+
4+
from libretro.api.camera import (
5+
retro_camera_callback,
6+
retro_camera_start_t,
7+
retro_camera_stop_t,
8+
retro_camera_lifetime_status_t,
9+
retro_camera_frame_raw_framebuffer_t,
10+
retro_camera_frame_opengl_texture_t, CameraCapabilityFlags,
11+
)
312

413

514
@runtime_checkable
615
class CameraDriver(Protocol):
7-
pass
16+
@abstractmethod
17+
def __init__(self):
18+
self._as_parameter_: retro_camera_callback = retro_camera_callback()
19+
self._as_parameter_.start = retro_camera_start_t(self.start)
20+
self._as_parameter_.stop = retro_camera_stop_t(self.stop)
21+
22+
@property
23+
@abstractmethod
24+
def caps(self) -> CameraCapabilityFlags: ...
25+
26+
@caps.setter
27+
@abstractmethod
28+
def caps(self, value: CameraCapabilityFlags) -> None: ...
29+
30+
@abstractmethod
31+
def start(self) -> bool: ...
32+
33+
@abstractmethod
34+
def stop(self) -> None: ...
35+
36+
@abstractmethod
37+
def poll(self) -> None: ...
38+
39+
@property
40+
@abstractmethod
41+
def width(self) -> int: ...
42+
43+
@width.setter
44+
@abstractmethod
45+
def width(self, value: int) -> None: ...
46+
47+
@property
48+
@abstractmethod
49+
def height(self) -> int: ...
50+
51+
@height.setter
52+
@abstractmethod
53+
def height(self, value: int) -> None: ...
54+
55+
@property
56+
@abstractmethod
57+
def frame_raw_framebuffer(self) -> retro_camera_frame_raw_framebuffer_t | None: ...
58+
59+
@frame_raw_framebuffer.setter
60+
@abstractmethod
61+
def frame_raw_framebuffer(self, value: retro_camera_frame_raw_framebuffer_t) -> None: ...
62+
63+
@property
64+
@abstractmethod
65+
def frame_opengl_texture(self) -> retro_camera_frame_opengl_texture_t | None: ...
66+
67+
@frame_opengl_texture.setter
68+
@abstractmethod
69+
def frame_opengl_texture(self, value: retro_camera_frame_opengl_texture_t) -> None: ...
70+
71+
@property
72+
@abstractmethod
73+
def initialized(self) -> retro_camera_lifetime_status_t | None: ...
74+
75+
@initialized.setter
76+
@abstractmethod
77+
def initialized(self, value: retro_camera_lifetime_status_t) -> None: ...
78+
79+
@property
80+
@abstractmethod
81+
def deinitialized(self) -> retro_camera_lifetime_status_t | None: ...
82+
83+
@deinitialized.setter
84+
@abstractmethod
85+
def deinitialized(self, value: retro_camera_lifetime_status_t) -> None: ...
886

987

10-
__all__ = ["CameraDriver"]
88+
__all__ = ["CameraDriver"]
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from typing import override
2+
3+
from .driver import CameraDriver
4+
from ... import retro_camera_lifetime_status_t, retro_camera_frame_raw_framebuffer_t, \
5+
CameraCapabilityFlags, retro_camera_frame_opengl_texture_t
6+
7+
class CameraFrame:
8+
pass
9+
# TODO: Add a buffer
10+
# TODO: Add dimensions
11+
12+
13+
class GeneratorCameraDriver(CameraDriver):
14+
@override
15+
def __init__(self):
16+
super().__init__()
17+
18+
# TODO: Accept a generator for camera frames
19+
20+
@property
21+
def caps(self) -> CameraCapabilityFlags:
22+
pass
23+
24+
def start(self) -> bool:
25+
pass
26+
27+
def stop(self) -> None:
28+
pass
29+
30+
def poll(self) -> None:
31+
pass
32+
33+
@property
34+
def width(self) -> int:
35+
pass
36+
37+
@property
38+
def height(self) -> int:
39+
pass
40+
41+
@property
42+
def frame_raw_framebuffer(self) -> retro_camera_frame_raw_framebuffer_t | None:
43+
pass
44+
45+
@property
46+
def frame_opengl_texture(self) -> retro_camera_frame_opengl_texture_t | None:
47+
pass
48+
49+
@property
50+
def initialized(self) -> retro_camera_lifetime_status_t | None:
51+
pass
52+
53+
@property
54+
def deinitialized(self) -> retro_camera_lifetime_status_t | None:
55+
pass
56+
57+
58+
__all__ = [
59+
"GeneratorCameraDriver",
60+
]

‎src/libretro/driver/disk/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .driver import *

‎src/libretro/driver/disk/driver.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from abc import abstractmethod
2+
from typing import Protocol, runtime_checkable
3+
4+
from libretro.api.disk import (
5+
retro_disk_control_ext_callback,
6+
retro_disk_control_callback,
7+
)
8+
9+
10+
@runtime_checkable
11+
class DiskDriver(Protocol):
12+
@property
13+
@abstractmethod
14+
def version(self) -> int: ...
15+
16+
@property
17+
@abstractmethod
18+
def callback(self) -> retro_disk_control_callback | retro_disk_control_ext_callback | None: ...
19+
20+
@callback.setter
21+
@abstractmethod
22+
def callback(self, value: retro_disk_control_callback | retro_disk_control_ext_callback) -> None: ...
23+
24+
@callback.deleter
25+
@abstractmethod
26+
def callback(self) -> None: ...
27+
28+
@property
29+
@abstractmethod
30+
def eject_state(self) -> bool: ...
31+
32+
@eject_state.setter
33+
@abstractmethod
34+
def eject_state(self, value: bool) -> None: ...
35+
36+
37+
__all__ = [
38+
"DiskDriver",
39+
]

‎src/libretro/driver/environment/composite.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ def video(self) -> VideoDriver:
268268
def content(self) -> ContentDriver | None:
269269
return self._content
270270

271+
@property
272+
def camera(self) -> CameraDriver | None:
273+
return self._camera
274+
271275
@property
272276
def user(self) -> UserDriver | None:
273277
return self._user
@@ -611,11 +615,11 @@ def __get_sensor_input(self, port: int, id: int) -> float:
611615
return self._input.sensor.get_sensor_input(port, Sensor(id))
612616

613617
@override
614-
def _get_camera_interface(self, interface: POINTER(retro_camera_callback)) -> bool:
618+
def _get_camera_interface(self, callback_ptr: POINTER(retro_camera_callback)) -> bool:
615619
if not self._camera:
616620
return False
617621

618-
if not interface:
622+
if not callback_ptr:
619623
raise ValueError("RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE doesn't accept NULL")
620624

621625
return False # TODO: Implement

0 commit comments

Comments
 (0)