diff --git a/.gitignore b/.gitignore index fa07992..6860e07 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ __pycache__/ build/ cydoomgeneric/cydoomgeneric.c +dist/ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..423294a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include cydoomgeneric/cydoomgeneric.pyx +include cydoomgeneric/cydoomgeneric.pxd +include doomgeneric/*.h diff --git a/README.md b/README.md index 27ef949..edc202b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,18 @@ To try it you will need a WAD file (game data). If you don't own the game, share cyDoomGeneric should run on Linux, MacOS, and Windows. +## Installation + +Either install the latest release from PyPI +```sh +pip install cydoomgeneric +``` + +Or run the following command to build from the repository +```sh +pip install . +``` + ## Porting You must implement the `draw_frame` and `get_key` functions. @@ -43,14 +55,6 @@ If any function that was passed to `cdg.init` raises an exception during the exe Some additional documentation can be found in `cydoomgeneric/cydoomgeneric.pyx`. -## Building - -To build and install cydoomgeneric, run the following command: - -```sh -pip install . -``` - ## Demo Screenshots #### Pyplot diff --git a/cydoomgeneric/__init__.pyi b/cydoomgeneric/__init__.pyi index b54b259..242e74c 100644 --- a/cydoomgeneric/__init__.pyi +++ b/cydoomgeneric/__init__.pyi @@ -13,41 +13,24 @@ """ from enum import IntEnum -from typing import Callable, Optional, Sequence +from typing import Any, Callable, Literal, Optional, Sequence import numpy as np def init(resx: int, resy: int, - draw_frame: Callable[[np.ndarray], None], + draw_frame: Callable[ + [np.ndarray[tuple[Any, Any, Literal[4]], + np.dtype[np.uint8]]], None], get_key: Callable[[], Optional[tuple[int, int]]], sleep_ms: Optional[Callable[[int], None]] = None, get_ticks_ms: Optional[Callable[[], int]] = None, set_window_title: Optional[Callable[[str], None]] = None) -> None: - """ - Initializes the doom context. - - :param resx: - :param resy: - :param draw_frame: Called every frame. Takes framebuffer as np.ndarray in - shape [resy, resx, 4]. Pixels are BGR. - :param get_key: Called multiple times every frame until input is exhausted. - Return None when input is exhausted. Otherwise, return - (is pressed ~0/1~, key). - :param sleep_ms: - :param get_ticks_ms: - :param set_window_title: - """ + ... def main(argv: Optional[Sequence[str]] = None) -> int: - """ - main(argv) -> int - - Run doom. Must be called after init. - - :param Optional[Sequence[str]] argv: - """ + ... class Keys(IntEnum): diff --git a/cydoomgeneric/cydoomgeneric.pxd b/cydoomgeneric/cydoomgeneric.pxd index 8387d5b..053ec13 100644 --- a/cydoomgeneric/cydoomgeneric.pxd +++ b/cydoomgeneric/cydoomgeneric.pxd @@ -27,7 +27,7 @@ cdef extern from "doomgeneric.h": void (*pDG_SleepMs)(uint32_t) noexcept, uint32_t (*pDG_GetTicksMs)() noexcept, int (*pDG_GetKey)(int*, unsigned char*) noexcept, - void (*pDG_SetWindowTitle)(const char*) noexcept) except * + void (*pDG_SetWindowTitle)(const char*) noexcept) noexcept int dg_main(int argc, char **argv) noexcept diff --git a/cydoomgeneric/cydoomgeneric.pyx b/cydoomgeneric/cydoomgeneric.pyx index 575e271..31a3a06 100644 --- a/cydoomgeneric/cydoomgeneric.pyx +++ b/cydoomgeneric/cydoomgeneric.pyx @@ -79,14 +79,27 @@ cdef void __set_window_title(const char *title) noexcept: sys.exit(1) -def init(resx: int, - resy: int, - draw_frame: Callable[[np.ndarray], None], - get_key: Callable[[int], str], +def init(int resx, + int resy, + draw_frame not None: Callable[[np.ndarray], None], + get_key not None: Callable[[int], str], sleep_ms: Optional[Callable[[int], None]]=None, get_ticks_ms: Optional[Callable[[], int]]=None, set_window_title: Optional[Callable[[str], None]]=None ) -> None: + """Initializes the doom context. + + :param resx: + :param resy: + :param draw_frame: Called every frame. Takes framebuffer as np.ndarray in + shape [resy, resx, 4]. Pixels are BGR. + :param get_key: Called multiple times every frame until input is exhausted. + Return None when input is exhausted. Otherwise, return + (is pressed ~0/1~, key). + :param sleep_ms: + :param get_ticks_ms: + :param set_window_title: + """ global __draw_frame_f global __sleep_ms_f global __get_ticks_ms_f @@ -111,6 +124,12 @@ def init(resx: int, def main(argv: Optional[Sequence[str]]=None) -> int: + """Runs doom. + + Must be called after `init`. + + :param Optional[Sequence[str]] argv: + """ if argv is None: return cdg.dg_main(0, NULL) diff --git a/pyproject.toml b/pyproject.toml index 4e5d9ca..c2d4976 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "cydoomgeneric" description = "Easily portable doom for python" +readme = "README.md" version = "0.1.0" authors = [ {name = "Wojciech Graj"} @@ -14,6 +15,18 @@ requires-python = ">=3.9" dependencies = [ "numpy>=1.25" ] +classifiers=[ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Cython", +] +keywords= ["doom"] [project.urls] homepage = "https://github.com/wojciech-graj/cydoomgeneric" diff --git a/setup.py b/setup.py index a6ad0e3..c1e1e29 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ """ import sys +from typing import Union import numpy from Cython.Build import cythonize @@ -103,7 +104,7 @@ ) libraries: list[str] = [] -define_macros: list[tuple[str, str | None]] = [] +define_macros: list[tuple[str, Union[str, None]]] = [] extra_link_args: list[str] = [] if sys.platform == "win32": @@ -124,6 +125,7 @@ extra_link_args=extra_link_args, libraries=libraries), ], + build_dir="build", language_level=3), package_data={"cydoomgeneric": ["py.typed", "__init__.pyi"]}, packages=["cydoomgeneric"])