From d8daeaae741f42e77ba15007cf33407220f17817 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Sun, 3 Nov 2024 21:40:52 -0800 Subject: [PATCH 01/26] Optimize pg_Two(Ints/Floats)FromObj pg_IntFromObjIndex doesn't take advantage of the fact that pg_TwoIntsFromObj already knows that obj is a sequence. Since obj is known to be a sequence, and negative indices are not needed, PySequence_ITEM can be used instead of PySequence_GetItem for better performance. --- src_c/base.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index f42b045783..e7959ace57 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -541,10 +541,25 @@ pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { return 0; } - if (!pg_IntFromObjIndex(obj, 0, val1) || - !pg_IntFromObjIndex(obj, 1, val2)) { + + PyObject *item1 = PySequence_ITEM(obj, 0); + PyObject *item2 = PySequence_ITEM(obj, 1); + + if (item1 == NULL || item2 == NULL) { + Py_XDECREF(item1); + Py_XDECREF(item2); + PyErr_Clear(); return 0; } + + if (!pg_IntFromObj(item1, val1) || !pg_IntFromObj(item2, val2)) { + Py_DECREF(item1); + Py_DECREF(item2); + return 0; + } + + Py_DECREF(item1); + Py_DECREF(item2); return 1; } @@ -586,10 +601,25 @@ pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { return 0; } - if (!pg_FloatFromObjIndex(obj, 0, val1) || - !pg_FloatFromObjIndex(obj, 1, val2)) { + + PyObject *item1 = PySequence_ITEM(obj, 0); + PyObject *item2 = PySequence_ITEM(obj, 1); + + if (item1 == NULL || item2 == NULL) { + Py_XDECREF(item1); + Py_XDECREF(item2); + PyErr_Clear(); return 0; } + + if (!pg_FloatFromObj(item1, val1) || !pg_FloatFromObj(item2, val2)) { + Py_DECREF(item1); + Py_DECREF(item2); + return 0; + } + + Py_DECREF(item1); + Py_DECREF(item2); return 1; } From 4de546610e507ea740190a3c69d3070db02bc251 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:10:51 -0800 Subject: [PATCH 02/26] Optimize twoints/twofloats: add comments --- src_c/base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src_c/base.c b/src_c/base.c index e7959ace57..2761c8c3aa 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -542,6 +542,7 @@ pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) return 0; } + // Can use PySequence_ITEM because of the PySequence_Check above. PyObject *item1 = PySequence_ITEM(obj, 0); PyObject *item2 = PySequence_ITEM(obj, 1); @@ -602,6 +603,7 @@ pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) return 0; } + // Can use PySequence_ITEM because of the PySequence_Check above. PyObject *item1 = PySequence_ITEM(obj, 0); PyObject *item2 = PySequence_ITEM(obj, 1); From 480a472432040d8e4a43be94bf700c5d7ad61d28 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:20:34 -0800 Subject: [PATCH 03/26] Another pg_Int/Float helper optimization approach. --- src_c/base.c | 111 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 26 deletions(-) diff --git a/src_c/base.c b/src_c/base.c index 2761c8c3aa..b07f18e4e3 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -496,24 +496,19 @@ pg_base_get_init(PyObject *self, PyObject *_null) static int pg_IntFromObj(PyObject *obj, int *val) { - int tmp_val; - if (PyFloat_Check(obj)) { /* Python3.8 complains with deprecation warnings if we pass * floats to PyLong_AsLong. */ - double dv = PyFloat_AsDouble(obj); - tmp_val = (int)dv; + *val = (int)PyFloat_AS_DOUBLE(obj); } else { - tmp_val = PyLong_AsLong(obj); - } - - if (tmp_val == -1 && PyErr_Occurred()) { - PyErr_Clear(); - return 0; + *val = PyLong_AsLong(obj); + if (*val == -1 && PyErr_Occurred()) { + PyErr_Clear(); + return 0; + } } - *val = tmp_val; return 1; } @@ -535,17 +530,29 @@ pg_IntFromObjIndex(PyObject *obj, int _index, int *val) static int pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) { - if (PyTuple_Check(obj) && PyTuple_Size(obj) == 1) { + // First, lets check the size. This returns -1 if invalid and may set an + // error. + Py_ssize_t obj_size = PySequence_Size(obj); + + // If the object is a tuple of one element, try that one element. + if (obj_size == 1 && PyTuple_Check(obj)) { return pg_TwoIntsFromObj(PyTuple_GET_ITEM(obj, 0), val1, val2); } - if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { + + // Otherwise lets make sure this is a legit sequence and has two elements. + // Some objects can passing PySequence_Size but fail PySequence_Check + // (like sets) + if (obj_size != 2 || !PySequence_Check(obj)) { + PyErr_Clear(); // Clear the potential error from PySequence_Size return 0; } - // Can use PySequence_ITEM because of the PySequence_Check above. + // Now we can extract the items, using this macro because we know + // obj is a PySequence. PyObject *item1 = PySequence_ITEM(obj, 0); PyObject *item2 = PySequence_ITEM(obj, 1); + // If either item is NULL lets get out of here if (item1 == NULL || item2 == NULL) { Py_XDECREF(item1); Py_XDECREF(item2); @@ -553,7 +560,26 @@ pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) return 0; } - if (!pg_IntFromObj(item1, val1) || !pg_IntFromObj(item2, val2)) { + // Fastest way to extract numbers I tested (in Python 3.13) is to extract + // Python floats as doubles with the below macro, and get everything else + // through PyLong_AsLong, using C casting to turn into the final type. + if (PyFloat_Check(item1)) { + *val1 = (int)PyFloat_AS_DOUBLE(item1); + } + else { + *val1 = PyLong_AsLong(item1); + } + + if (PyFloat_Check(item2)) { + *val2 = (int)PyFloat_AS_DOUBLE(item2); + } + else { + *val2 = PyLong_AsLong(item2); + } + + // This catches the case where either of the PyLong_AsLong's failed + if ((*val1 == -1 || *val2 == -1) && PyErr_Occurred()) { + PyErr_Clear(); Py_DECREF(item1); Py_DECREF(item2); return 0; @@ -567,14 +593,16 @@ pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) static int pg_FloatFromObj(PyObject *obj, float *val) { - float f = (float)PyFloat_AsDouble(obj); - - if (f == -1 && PyErr_Occurred()) { - PyErr_Clear(); - return 0; + if (PyFloat_Check(obj)) { + *val = (float)PyFloat_AS_DOUBLE(obj); + } + else { + *val = (float)PyLong_AsLong(obj); + if (*val == -1.0f && PyErr_Occurred()) { + PyErr_Clear(); + return 0; + } } - - *val = f; return 1; } @@ -596,17 +624,29 @@ pg_FloatFromObjIndex(PyObject *obj, int _index, float *val) static int pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) { - if (PyTuple_Check(obj) && PyTuple_Size(obj) == 1) { + // First, lets check the size. This returns -1 if invalid and may set an + // error. + Py_ssize_t obj_size = PySequence_Size(obj); + + // If the object is a tuple of one element, try that one element. + if (obj_size == 1 && PyTuple_Check(obj)) { return pg_TwoFloatsFromObj(PyTuple_GET_ITEM(obj, 0), val1, val2); } - if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { + + // Otherwise lets make sure this is a legit sequence and has two elements. + // Some objects can passing PySequence_Size but fail PySequence_Check + // (like sets) + if (obj_size != 2 || !PySequence_Check(obj)) { + PyErr_Clear(); // Clear the potential error from PySequence_Size return 0; } - // Can use PySequence_ITEM because of the PySequence_Check above. + // Now we can extract the items, using this macro because we know + // obj is a PySequence. PyObject *item1 = PySequence_ITEM(obj, 0); PyObject *item2 = PySequence_ITEM(obj, 1); + // If either item is NULL lets get out of here if (item1 == NULL || item2 == NULL) { Py_XDECREF(item1); Py_XDECREF(item2); @@ -614,7 +654,26 @@ pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) return 0; } - if (!pg_FloatFromObj(item1, val1) || !pg_FloatFromObj(item2, val2)) { + // Fastest way to extract numbers I tested (in Python 3.13) is to extract + // Python floats as doubles with the below macro, and get everything else + // through PyLong_AsLong, using C casting to turn into the final type. + if (PyFloat_Check(item1)) { + *val1 = (float)PyFloat_AS_DOUBLE(item1); + } + else { + *val1 = (float)PyLong_AsLong(item1); + } + + if (PyFloat_Check(item2)) { + *val2 = (float)PyFloat_AS_DOUBLE(item2); + } + else { + *val2 = (float)PyLong_AsLong(item2); + } + + // This catches the case where either of the PyLong_AsLong's failed + if ((*val1 == -1.0f || *val2 == -1.0f) && PyErr_Occurred()) { + PyErr_Clear(); Py_DECREF(item1); Py_DECREF(item2); return 0; From 4b8f96c4bcf8183db1836df26dea78ee75c3f2cc Mon Sep 17 00:00:00 2001 From: yunline Date: Fri, 6 Dec 2024 16:27:30 +0800 Subject: [PATCH 04/26] Add missing newline in sndarray.rst and cursors.rst --- docs/reST/ref/cursors.rst | 1 + docs/reST/ref/sndarray.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/reST/ref/cursors.rst b/docs/reST/ref/cursors.rst index c45af2a973..f5c7bb2d18 100644 --- a/docs/reST/ref/cursors.rst +++ b/docs/reST/ref/cursors.rst @@ -219,6 +219,7 @@ The following strings can be converted into cursor bitmaps with | :sg:`copy() -> Cursor` Returns a new Cursor object with the same data and hotspot as the original. + .. ## pygame.cursors.Cursor.copy ## diff --git a/docs/reST/ref/sndarray.rst b/docs/reST/ref/sndarray.rst index bc2899f614..75dbd1b21b 100644 --- a/docs/reST/ref/sndarray.rst +++ b/docs/reST/ref/sndarray.rst @@ -62,6 +62,7 @@ one. DEPRECATED: Uses the requested array type for the module functions. The only supported arraytype is ``'numpy'``. Other values will raise ValueError. Using this function will raise a ``DeprecationWarning``. + .. ## pygame.sndarray.use_arraytype ## .. function:: get_arraytype From 3ef8e8d1b8a8fe37d738a3feae30ba695e177256 Mon Sep 17 00:00:00 2001 From: yunline Date: Mon, 9 Dec 2024 11:11:24 +0800 Subject: [PATCH 05/26] Add BLENDMODE_MUL to constants --- buildconfig/stubs/pygame/__init__.pyi | 1 + buildconfig/stubs/pygame/constants.pyi | 1 + buildconfig/stubs/pygame/locals.pyi | 1 + src_c/constants.c | 1 + src_c/cython/pygame/_sdl2/video.pxd | 1 + 5 files changed, 5 insertions(+) diff --git a/buildconfig/stubs/pygame/__init__.pyi b/buildconfig/stubs/pygame/__init__.pyi index ffb58f4cdb..76ed89d986 100644 --- a/buildconfig/stubs/pygame/__init__.pyi +++ b/buildconfig/stubs/pygame/__init__.pyi @@ -111,6 +111,7 @@ from .constants import ( BLENDMODE_ADD as BLENDMODE_ADD, BLENDMODE_BLEND as BLENDMODE_BLEND, BLENDMODE_MOD as BLENDMODE_MOD, + BLENDMODE_MUL as BLENDMODE_MUL, BLENDMODE_NONE as BLENDMODE_NONE, BLEND_ADD as BLEND_ADD, BLEND_ALPHA_SDL2 as BLEND_ALPHA_SDL2, diff --git a/buildconfig/stubs/pygame/constants.pyi b/buildconfig/stubs/pygame/constants.pyi index 463f2509c8..2c4f5030f9 100644 --- a/buildconfig/stubs/pygame/constants.pyi +++ b/buildconfig/stubs/pygame/constants.pyi @@ -34,6 +34,7 @@ BIG_ENDIAN: int BLENDMODE_ADD: int BLENDMODE_BLEND: int BLENDMODE_MOD: int +BLENDMODE_MUL: int BLENDMODE_NONE: int BLEND_ADD: int BLEND_ALPHA_SDL2: int diff --git a/buildconfig/stubs/pygame/locals.pyi b/buildconfig/stubs/pygame/locals.pyi index e596355311..b1d3a99093 100644 --- a/buildconfig/stubs/pygame/locals.pyi +++ b/buildconfig/stubs/pygame/locals.pyi @@ -34,6 +34,7 @@ BIG_ENDIAN: int BLENDMODE_ADD: int BLENDMODE_BLEND: int BLENDMODE_MOD: int +BLENDMODE_MUL: int BLENDMODE_NONE: int BLEND_ADD: int BLEND_ALPHA_SDL2: int diff --git a/src_c/constants.c b/src_c/constants.c index 771aefca5a..04b8e0771d 100644 --- a/src_c/constants.c +++ b/src_c/constants.c @@ -160,6 +160,7 @@ MODINIT_DEFINE(constants) DEC_CONST(BLENDMODE_BLEND); DEC_CONST(BLENDMODE_ADD); DEC_CONST(BLENDMODE_MOD); + DEC_CONST(BLENDMODE_MUL); DEC_CONST(GL_STEREO); DEC_CONST(GL_MULTISAMPLEBUFFERS); DEC_CONST(GL_MULTISAMPLESAMPLES); diff --git a/src_c/cython/pygame/_sdl2/video.pxd b/src_c/cython/pygame/_sdl2/video.pxd index 8d3d868286..1d87ba43b2 100644 --- a/src_c/cython/pygame/_sdl2/video.pxd +++ b/src_c/cython/pygame/_sdl2/video.pxd @@ -107,6 +107,7 @@ cdef extern from "SDL.h" nogil: SDL_BLENDMODE_BLEND = 0x00000001, SDL_BLENDMODE_ADD = 0x00000002, SDL_BLENDMODE_MOD = 0x00000004, + SDL_BLENDMODE_MUL = 0x00000008, SDL_BLENDMODE_INVALID = 0x7FFFFFFF # https://wiki.libsdl.org/SDL_MessageBoxData From 0f1918356e516c9826e19feb0924a13ac28cac41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:57:39 +0000 Subject: [PATCH 06/26] Bump actions/cache from 4.1.2 to 4.2.0 Bumps [actions/cache](https://github.com/actions/cache) from 4.1.2 to 4.2.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4.1.2...v4.2.0) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index d3684924cc..5ceb5d1f20 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -51,7 +51,7 @@ jobs: - name: Test for Mac Deps cache hit id: macdep-cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ${{ github.workspace }}/pygame_mac_deps_${{ matrix.macarch }} # The hash of all files in buildconfig manylinux-build and macdependencies is @@ -118,14 +118,14 @@ jobs: - uses: actions/checkout@v4.2.2 - name: pip cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ~/Library/Caches/pip # This cache path is only right on mac key: pip-cache-${{ matrix.macarch }}-${{ matrix.os }} - name: Fetch Mac deps id: macdep-cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ${{ github.workspace }}/pygame_mac_deps_${{ matrix.macarch }} key: macdep-${{ hashFiles('buildconfig/manylinux-build/**') }}-${{ hashFiles('buildconfig/macdependencies/*.sh') }}-${{ matrix.macarch }} From ae149b4bab05527f1d751a789d54cce56e69bc9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:57:41 +0000 Subject: [PATCH 07/26] Bump actions/attest-build-provenance from 1.4.4 to 2.0.1 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.4.4 to 2.0.1. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v1.4.4...v2.0.1) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release-gh-draft.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-gh-draft.yml b/.github/workflows/release-gh-draft.yml index c56e9d3bfd..601ab1f4ad 100644 --- a/.github/workflows/release-gh-draft.yml +++ b/.github/workflows/release-gh-draft.yml @@ -61,7 +61,7 @@ jobs: run: echo "VER=${GITHUB_REF_NAME#'release/'}" >> $GITHUB_OUTPUT - name: Generate release attestation - uses: actions/attest-build-provenance@v1.4.4 + uses: actions/attest-build-provenance@v2.0.1 with: subject-path: "pygame-wheels/*" From ae7be63f3d10276a742f88367c58f050c5691259 Mon Sep 17 00:00:00 2001 From: Ankith Date: Mon, 9 Dec 2024 23:05:06 +0530 Subject: [PATCH 08/26] Bump SDL2 to 2.30.10 --- buildconfig/download_win_prebuilt.py | 8 ++++---- .../docker_base/sdl_libs/build-sdl2-libs.sh | 2 +- .../manylinux-build/docker_base/sdl_libs/sdl2.sha512 | 2 +- meson.build | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/buildconfig/download_win_prebuilt.py b/buildconfig/download_win_prebuilt.py index aa12faca0f..0a5d6f6b5a 100644 --- a/buildconfig/download_win_prebuilt.py +++ b/buildconfig/download_win_prebuilt.py @@ -78,8 +78,8 @@ def get_urls(x86=True, x64=True): url_sha1 = [] url_sha1.extend([ [ - 'https://github.com/libsdl-org/SDL/releases/download/release-2.30.9/SDL2-devel-2.30.9-VC.zip', - 'd89a2ad46b98ba08db5ec5877cb2fde46e127825', + 'https://github.com/libsdl-org/SDL/releases/download/release-2.30.10/SDL2-devel-2.30.10-VC.zip', + '42378fd090d547d03dca8c9df584ba8f38555809', ], [ 'https://github.com/libsdl-org/SDL/releases/download/preview-3.1.6/SDL3-devel-3.1.6-VC.zip', @@ -238,12 +238,12 @@ def copy(src, dst): copy( os.path.join( temp_dir, - 'SDL2-devel-2.30.9-VC/SDL2-2.30.9' + 'SDL2-devel-2.30.10-VC/SDL2-2.30.10' ), os.path.join( move_to_dir, prebuilt_dir, - 'SDL2-2.30.9' + 'SDL2-2.30.10' ) ) copy( diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh index d0546b18bb..de66b0b132 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh @@ -3,7 +3,7 @@ set -e -x cd $(dirname `readlink -f "$0"`) -SDL2_VER="2.30.9" +SDL2_VER="2.30.10" SDL2="SDL2-$SDL2_VER" IMG2_VER="2.8.2" IMG2="SDL2_image-$IMG2_VER" diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 index 2cae1f3830..b968e6c540 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 @@ -1,4 +1,4 @@ -30dfa86fcced174fef0ed78ffa53476a31765e19cdcdf8233ab92876445b4dedaa758fc42a3ec332324d13faa2daafcadcc44fc0f536a2969ef836162ec3cd36 SDL2-2.30.9.tar.gz +bcb220749cd3b0874288d617419e622701138bcb8fe55e9b665e8843c65afda031d01afe0d11e308a9608724ed151f342e5f5670c84204b36943cb323ced41da SDL2-2.30.10.tar.gz 0ff345824f95158dfa72f83f9d4a540601c178cd759334bf849c14a2920b5330d0763413b58c08b3deba8d3a4ccb6ea2a8159f87efe4cbb0e8ea850f63d09454 SDL2_image-2.8.2.tar.gz 5ddbc4b0b5fad2e0844a503daa79564b912654192599ef8fa7698531f08323ce01801f6bb17b2b3905020a3df362a967b7566ae725eb085da991578cc0807aad SDL2_mixer-2.8.0.tar.gz 34a1d210d8f1b1e802139d65ba47e36033bb7881e75a8862c1b1c515565bef85e3d81ee42e952aa664de043debef387ba60088a9cf3ba3297413db39a13af912 SDL2_ttf-2.22.0.tar.gz diff --git a/meson.build b/meson.build index 318de28b1f..b4f99359b3 100644 --- a/meson.build +++ b/meson.build @@ -109,7 +109,7 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') ) endif - sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.9' + sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.10' sdl_image_ver = '2.8.2' sdl_mixer_ver = '2.8.0' sdl_ttf_ver = '2.22.0' From 25eaf281aa818455f2644266bf49f52719e53056 Mon Sep 17 00:00:00 2001 From: Brett Kaplan Date: Tue, 10 Dec 2024 21:20:42 -0500 Subject: [PATCH 09/26] this statement seems to be false, removing --- docs/reST/ref/surface.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/surface.rst b/docs/reST/ref/surface.rst index 7153dc7fd3..06c14b2e83 100644 --- a/docs/reST/ref/surface.rst +++ b/docs/reST/ref/surface.rst @@ -205,7 +205,7 @@ object and dest is its destination position on this Surface. It draws each source Surface fully (meaning that unlike `blit()` you cannot pass an "area" parameter to represent a smaller portion of the source Surface to draw) on this Surface with the same blending - mode specified by special_flags. The sequence must have at least one (source, dest) pair. + mode specified by special_flags. :param blit_sequence: a sequence of (source, dest) :param special_flags: the flag(s) representing the blend mode used for each surface. From ee46e25c175d364e08b1695bf8e4463c902a14ef Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sat, 14 Dec 2024 19:40:47 -0800 Subject: [PATCH 10/26] Correctly type display.get_surface() return type --- buildconfig/stubs/pygame/display.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index 5124e92b47..5f630a57e1 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -44,7 +44,7 @@ def set_mode( display: int = 0, vsync: int = 0, ) -> Surface: ... -def get_surface() -> Surface: ... +def get_surface() -> Optional[Surface]: ... def flip() -> None: ... @overload def update( From bfcec34636b3ffc965aff4d2205c44f98226dfd7 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sat, 14 Dec 2024 19:43:32 -0800 Subject: [PATCH 11/26] Type display.update() as taking floats --- buildconfig/stubs/pygame/display.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index 5f630a57e1..c12630ca09 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -51,7 +51,7 @@ def update( rectangle: Optional[Union[RectLike, Iterable[Optional[RectLike]]]] = None, / ) -> None: ... @overload -def update(x: int, y: int, w: int, h: int, /) -> None: ... +def update(x: float, y: float, w: float, h: float, /) -> None: ... @overload def update(xy: Point, wh: Point, /) -> None: ... def get_driver() -> str: ... From 803a9da140d363380b50e5921c50b3f900dd0567 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:24:31 -0800 Subject: [PATCH 12/26] Fix get_surface() docs --- docs/reST/ref/display.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/reST/ref/display.rst b/docs/reST/ref/display.rst index 310ebb38fa..c739bfbf57 100644 --- a/docs/reST/ref/display.rst +++ b/docs/reST/ref/display.rst @@ -251,6 +251,7 @@ required). | :sl:`Get a reference to the currently set display surface` | :sg:`get_surface() -> Surface` + | :sg:`get_surface() -> None` Return a reference to the currently set display Surface. If no display mode has been set this will return None. From 629cc2fb0ddb059e0139923524c66049a1e13eb0 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:36:31 -0800 Subject: [PATCH 13/26] Document overloads of `display.update()` --- buildconfig/stubs/pygame/display.pyi | 4 +++- docs/reST/ref/display.rst | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index c12630ca09..43e1ec8c05 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -47,8 +47,10 @@ def set_mode( def get_surface() -> Optional[Surface]: ... def flip() -> None: ... @overload +def update() -> None: ... +@overload def update( - rectangle: Optional[Union[RectLike, Iterable[Optional[RectLike]]]] = None, / + rectangle: Optional[Union[RectLike, Iterable[Optional[RectLike]]]], / ) -> None: ... @overload def update(x: float, y: float, w: float, h: float, /) -> None: ... diff --git a/docs/reST/ref/display.rst b/docs/reST/ref/display.rst index c739bfbf57..223a3744de 100644 --- a/docs/reST/ref/display.rst +++ b/docs/reST/ref/display.rst @@ -273,7 +273,10 @@ required). .. function:: update | :sl:`Update all, or a portion, of the display. For non-OpenGL displays.` - | :sg:`update(rectangle=None, /) -> None` + | :sg:`update() -> None` + | :sg:`update(rectangle, /) -> None` + | :sg:`update(x, y, w, h, /) -> None` + | :sg:`update((x, y), (w, h), /) -> None` | :sg:`update(rectangle_iterable, /) -> None` For non OpenGL display Surfaces, this function is very similar to From 998738ea382bab0a3627aa7a18da7960c590adb1 Mon Sep 17 00:00:00 2001 From: aatle <168398276+aatle@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:40:46 -0800 Subject: [PATCH 14/26] Update display_doc.h --- src_c/doc/display_doc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/doc/display_doc.h b/src_c/doc/display_doc.h index 17b881bd49..8e03e368fe 100644 --- a/src_c/doc/display_doc.h +++ b/src_c/doc/display_doc.h @@ -4,9 +4,9 @@ #define DOC_DISPLAY_QUIT "quit() -> None\nUninitialize the display module" #define DOC_DISPLAY_GETINIT "get_init() -> bool\nReturns True if the display module has been initialized" #define DOC_DISPLAY_SETMODE "set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface\nInitialize a window or screen for display" -#define DOC_DISPLAY_GETSURFACE "get_surface() -> Surface\nGet a reference to the currently set display surface" +#define DOC_DISPLAY_GETSURFACE "get_surface() -> Surface\nget_surface() -> None\nGet a reference to the currently set display surface" #define DOC_DISPLAY_FLIP "flip() -> None\nUpdate the full display Surface to the screen" -#define DOC_DISPLAY_UPDATE "update(rectangle=None, /) -> None\nupdate(rectangle_iterable, /) -> None\nUpdate all, or a portion, of the display. For non-OpenGL displays." +#define DOC_DISPLAY_UPDATE "update() -> None\nupdate(rectangle, /) -> None\nupdate(x, y, w, h, /) -> None\nupdate((x, y), (w, h), /) -> None\nupdate(rectangle_iterable, /) -> None\nUpdate all, or a portion, of the display. For non-OpenGL displays." #define DOC_DISPLAY_GETDRIVER "get_driver() -> name\nGet the name of the pygame display backend" #define DOC_DISPLAY_INFO "Info() -> VideoInfo\nCreate a video display information object" #define DOC_DISPLAY_GETWMINFO "get_wm_info() -> dict\nGet information about the current windowing system" From 86d3086b3f823daaae63f76e0bd2b0bfa0dbc288 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Sun, 15 Dec 2024 20:25:42 -0800 Subject: [PATCH 15/26] Typo fixes --- buildconfig/stubs/stubcheck.py | 2 +- docs/reST/ref/draw.rst | 4 ++-- docs/reST/ref/window.rst | 2 +- examples/ninepatch.py | 2 +- src_c/_sdl2/controller.c | 16 ++++++++-------- src_c/doc/window_doc.h | 2 +- src_c/simd_transform_avx2.c | 2 +- src_c/window.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/buildconfig/stubs/stubcheck.py b/buildconfig/stubs/stubcheck.py index d0c544a4c8..fba1938f73 100644 --- a/buildconfig/stubs/stubcheck.py +++ b/buildconfig/stubs/stubcheck.py @@ -49,7 +49,7 @@ def stubs_check(): continue cmd = " ".join(stubtest) - print(f"Using stubtest invokation: `{cmd}` (version: {version})") + print(f"Using stubtest invocation: `{cmd}` (version: {version})") prev_dir = os.getcwd() try: os.chdir(STUBS_BASE_DIR) diff --git a/docs/reST/ref/draw.rst b/docs/reST/ref/draw.rst index 53f5c35b44..01f39e4f4c 100644 --- a/docs/reST/ref/draw.rst +++ b/docs/reST/ref/draw.rst @@ -492,7 +492,7 @@ object around the draw calls (see :func:`pygame.Surface.lock` and .. versionchangedold:: 2.0.0 Added support for keyword arguments. .. versionchanged:: 2.4.0 Removed deprecated 'blend' argument - .. versionchanged:: 2.5.0 ``blend`` argument readded for backcompat, but will always raise a deprecation exception when used + .. versionchanged:: 2.5.0 ``blend`` argument re-added for backcompat, but will always raise a deprecation exception when used .. versionchanged:: 2.5.3 Added line width .. ## pygame.draw.aaline ## @@ -533,7 +533,7 @@ object around the draw calls (see :func:`pygame.Surface.lock` and .. versionchangedold:: 2.0.0 Added support for keyword arguments. .. versionchanged:: 2.4.0 Removed deprecated ``blend`` argument - .. versionchanged:: 2.5.0 ``blend`` argument readded for backcompat, but will always raise a deprecation exception when used + .. versionchanged:: 2.5.0 ``blend`` argument re-added for backcompat, but will always raise a deprecation exception when used .. ## pygame.draw.aalines ## diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index af81d53267..b460047bd7 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -291,7 +291,7 @@ .. attribute:: utility - | :sl:`Get if the windos is an utility window (**read-only**)` + | :sl:`Get if the window is an utility window (**read-only**)` | :sg:`utility -> bool` ``True`` if the window doesn't appear in the task bar, ``False`` otherwise. diff --git a/examples/ninepatch.py b/examples/ninepatch.py index ccdac7dc4f..375a1b7970 100644 --- a/examples/ninepatch.py +++ b/examples/ninepatch.py @@ -44,7 +44,7 @@ def ninepatch_scale( ) # when alpha is False the flags become 0 # aliases - ret_w, ret_h = size # non-sequence argument catched by python + ret_w, ret_h = size # non-sequence argument caught by python src_w, src_h = surface.size c = corner_size scale_func = pygame.transform.smoothscale if smooth else pygame.transform.scale diff --git a/src_c/_sdl2/controller.c b/src_c/_sdl2/controller.c index 331ffd876d..648af64a09 100644 --- a/src_c/_sdl2/controller.c +++ b/src_c/_sdl2/controller.c @@ -159,7 +159,7 @@ controller_attached(pgControllerObject *self, PyObject *_null) { CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } return PyBool_FromLong(SDL_GameControllerGetAttached(self->controller)); @@ -171,7 +171,7 @@ controller_as_joystick(pgControllerObject *self, PyObject *_null) CONTROLLER_INIT_CHECK(); JOYSTICK_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } return pgJoystick_New(self->id); @@ -188,7 +188,7 @@ controller_get_axis(pgControllerObject *self, PyObject *args, PyObject *kwargs) } CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } if (axis < 0 || axis > SDL_CONTROLLER_AXIS_MAX - 1) { @@ -210,7 +210,7 @@ controller_get_button(pgControllerObject *self, PyObject *args, } CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } if (button < 0 || button > SDL_CONTROLLER_BUTTON_MAX) { @@ -230,7 +230,7 @@ controller_get_mapping(pgControllerObject *self, PyObject *_null) CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } mapping = SDL_GameControllerMapping(self->controller); @@ -285,7 +285,7 @@ controller_set_mapping(pgControllerObject *self, PyObject *args, CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } char guid_str[64]; @@ -364,7 +364,7 @@ controller_rumble(pgControllerObject *self, PyObject *args, PyObject *kwargs) CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } // rumble takes values in range 0 to 0xFFFF (65535) @@ -382,7 +382,7 @@ controller_stop_rumble(pgControllerObject *self, PyObject *_null) { CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } SDL_GameControllerRumble(self->controller, 0, 0, 1); Py_RETURN_NONE; diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index bed2a7cd27..8a1063a54b 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,7 +17,7 @@ #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" #define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" -#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the windos is an utility window (**read-only**)" +#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the window is an utility window (**read-only**)" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." diff --git a/src_c/simd_transform_avx2.c b/src_c/simd_transform_avx2.c index 2cd0a81bbb..18c27ac355 100644 --- a/src_c/simd_transform_avx2.c +++ b/src_c/simd_transform_avx2.c @@ -165,7 +165,7 @@ grayscale_avx2(SDL_Surface *src, SDL_Surface *newsurf) mm256_dst = _mm256_hadd_epi16(mm256_dstA, mm256_dstB); mm256_dst = _mm256_add_epi16(mm256_dst, _mm256_srli_epi32(mm256_dst, 16)); - // Shuffle the gray value from ther first channel of each pixel + // Shuffle the gray value from the first channel of each pixel // into every channel of each pixel mm256_dst = _mm256_shuffle_epi8(mm256_dst, mm256_shuff_mask_gray); diff --git a/src_c/window.c b/src_c/window.c index aec40e8688..8934898d4d 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -835,7 +835,7 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) const char *_key_str; int _value_bool; - // ensure display is init at this point, diplay init automatically calls + // ensure display is init at this point, display init automatically calls // the window init in this module if (!pg_mod_autoinit(IMPPREFIX "display")) return -1; @@ -1071,7 +1071,7 @@ window_from_display_module(PyTypeObject *cls, PyObject *_null) return NULL; } - // ensure display is init at this point, diplay init automatically calls + // ensure display is init at this point, display init automatically calls // the window init in this module if (!pg_mod_autoinit(IMPPREFIX "display")) return NULL; From 216f52b24027671d2cf04e80f7adb581cd5b964b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 06:34:29 +0000 Subject: [PATCH 16/26] Bump actions/attest-build-provenance from 2.0.1 to 2.1.0 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2.0.1 to 2.1.0. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v2.0.1...v2.1.0) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release-gh-draft.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-gh-draft.yml b/.github/workflows/release-gh-draft.yml index 601ab1f4ad..0f5acc8f22 100644 --- a/.github/workflows/release-gh-draft.yml +++ b/.github/workflows/release-gh-draft.yml @@ -61,7 +61,7 @@ jobs: run: echo "VER=${GITHUB_REF_NAME#'release/'}" >> $GITHUB_OUTPUT - name: Generate release attestation - uses: actions/attest-build-provenance@v2.0.1 + uses: actions/attest-build-provenance@v2.1.0 with: subject-path: "pygame-wheels/*" From 80f7130bce68d9369c68700cb853928e186611fd Mon Sep 17 00:00:00 2001 From: Ankith Date: Wed, 18 Dec 2024 11:31:03 +0530 Subject: [PATCH 17/26] Bump SDL2_image to 2.8.3 --- buildconfig/download_win_prebuilt.py | 8 ++++---- .../docker_base/sdl_libs/build-sdl2-libs.sh | 2 +- .../manylinux-build/docker_base/sdl_libs/sdl2.sha512 | 2 +- meson.build | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/buildconfig/download_win_prebuilt.py b/buildconfig/download_win_prebuilt.py index 0a5d6f6b5a..5daaf54a76 100644 --- a/buildconfig/download_win_prebuilt.py +++ b/buildconfig/download_win_prebuilt.py @@ -86,8 +86,8 @@ def get_urls(x86=True, x64=True): '7a3b9ed85cfe735c7e106d98c4b6395a113e5d7e' ], [ - 'https://github.com/pygame-community/SDL_image/releases/download/2.8.2-pgce/SDL2_image-devel-2.8.2-VCpgce.zip', - '983484dd816abf25cdd5bce88ac69dbca1ea713a' + 'https://github.com/pygame-community/SDL_image/releases/download/2.8.3-pgce/SDL2_image-devel-2.8.3-VCpgce.zip', + '71ad2b5aacbc934a39e390ad733421313dd5d059' ], [ 'https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-devel-2.22.0-VC.zip', @@ -205,12 +205,12 @@ def copy(src, dst): copy( os.path.join( temp_dir, - 'SDL2_image-devel-2.8.2-VCpgce/SDL2_image-2.8.2' + 'SDL2_image-devel-2.8.3-VCpgce/SDL2_image-2.8.3' ), os.path.join( move_to_dir, prebuilt_dir, - 'SDL2_image-2.8.2' + 'SDL2_image-2.8.3' ) ) copy( diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh index de66b0b132..7d6da64605 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh @@ -5,7 +5,7 @@ cd $(dirname `readlink -f "$0"`) SDL2_VER="2.30.10" SDL2="SDL2-$SDL2_VER" -IMG2_VER="2.8.2" +IMG2_VER="2.8.3" IMG2="SDL2_image-$IMG2_VER" TTF2_VER="2.22.0" TTF2="SDL2_ttf-$TTF2_VER" diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 index b968e6c540..8d171a1031 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 @@ -1,4 +1,4 @@ bcb220749cd3b0874288d617419e622701138bcb8fe55e9b665e8843c65afda031d01afe0d11e308a9608724ed151f342e5f5670c84204b36943cb323ced41da SDL2-2.30.10.tar.gz -0ff345824f95158dfa72f83f9d4a540601c178cd759334bf849c14a2920b5330d0763413b58c08b3deba8d3a4ccb6ea2a8159f87efe4cbb0e8ea850f63d09454 SDL2_image-2.8.2.tar.gz +b49e466494a4bebcacc09e3fe2afbe5edbae636c007cd26e7e04301bf8fe54db6751258b750a79656e5aa261869900d39703f1311df4c63ef415ae443f62295f SDL2_image-2.8.3.tar.gz 5ddbc4b0b5fad2e0844a503daa79564b912654192599ef8fa7698531f08323ce01801f6bb17b2b3905020a3df362a967b7566ae725eb085da991578cc0807aad SDL2_mixer-2.8.0.tar.gz 34a1d210d8f1b1e802139d65ba47e36033bb7881e75a8862c1b1c515565bef85e3d81ee42e952aa664de043debef387ba60088a9cf3ba3297413db39a13af912 SDL2_ttf-2.22.0.tar.gz diff --git a/meson.build b/meson.build index b4f99359b3..ac93a648cc 100644 --- a/meson.build +++ b/meson.build @@ -110,7 +110,7 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') endif sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.10' - sdl_image_ver = '2.8.2' + sdl_image_ver = '2.8.3' sdl_mixer_ver = '2.8.0' sdl_ttf_ver = '2.22.0' From 64bebe7e4947696e8497d1a31ff8a4bec4c63111 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:57:03 -0800 Subject: [PATCH 18/26] Remove old info and improve mixer docs --- docs/reST/ref/mixer.rst | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/reST/ref/mixer.rst b/docs/reST/ref/mixer.rst index 76d1122772..6df8e7ca94 100644 --- a/docs/reST/ref/mixer.rst +++ b/docs/reST/ref/mixer.rst @@ -9,9 +9,7 @@ | :sl:`pygame module for loading and playing sounds` This module contains classes for loading Sound objects and controlling -playback. The mixer module is optional and depends on SDL_mixer. Your program -should test that :mod:`pygame.mixer` is available and initialized before using -it. +playback. The mixer module has a limited number of channels for playback of sounds. Usually programs tell pygame to start playing audio and it selects an available @@ -30,9 +28,7 @@ streams the music from the files without loading music at once into memory. The mixer module must be initialized like other pygame modules, but it has some extra conditions. The ``pygame.mixer.init()`` function takes several optional -arguments to control the playback rate and sample size. Pygame will default to -reasonable values, but pygame cannot perform Sound resampling, so the mixer -should be initialized to match the values of your audio resources. +arguments to control the playback rate and sample size. ``NOTE``: For less laggy sound use a smaller buffer size. The default is set to reduce the chance of scratchy sounds on some computers. You can @@ -91,7 +87,7 @@ The following file formats are supported the next nearest power of 2). The devicename parameter is the name of sound device to open for audio - playback. Allowed device names will vary based on the host system. + playback. Allowed device names will vary based on the host system. If left as ``None`` then a sensible default will be chosen for you. Some platforms require the :mod:`pygame.mixer` module to be initialized @@ -331,7 +327,7 @@ The following file formats are supported :rtype: tuple .. note:: - The linked and compile version numbers should be the same. + The linked and compiled version numbers should be the same. .. versionaddedold:: 2.0.0 From 5d4be795bf0619352d50207c15f04cc5768102ff Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:57:14 -0800 Subject: [PATCH 19/26] Fix NumPy capitalization --- docs/reST/ref/image.rst | 4 ++-- docs/reST/ref/mixer.rst | 2 +- docs/reST/ref/surfarray.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/reST/ref/image.rst b/docs/reST/ref/image.rst index 65438a9e82..e851ccdf0e 100644 --- a/docs/reST/ref/image.rst +++ b/docs/reST/ref/image.rst @@ -245,7 +245,7 @@ following formats. .. note:: The use of this function is recommended over :func:`tostring` as of pygame 2.1.3. This function was introduced so it matches nicely with other - libraries (PIL, numpy, etc), and with people's expectations. + libraries (PIL, NumPy, etc), and with people's expectations. .. versionadded:: 2.1.3 .. versionchanged:: 2.2.0 Now supports keyword arguments. @@ -290,7 +290,7 @@ following formats. .. note:: The use of this function is recommended over :func:`fromstring` as of pygame 2.1.3. This function was introduced so it matches nicely with other - libraries (PIL, numpy, etc), and with people's expectations. + libraries (PIL, NumPy, etc), and with people's expectations. .. versionadded:: 2.1.3 .. versionadded:: 2.1.4 Added a 'pitch' argument and support for keyword arguments. diff --git a/docs/reST/ref/mixer.rst b/docs/reST/ref/mixer.rst index 6df8e7ca94..0558fb62fa 100644 --- a/docs/reST/ref/mixer.rst +++ b/docs/reST/ref/mixer.rst @@ -364,7 +364,7 @@ The following file formats are supported it and the Sound object. For now buffer and array support is consistent with ``sndarray.make_sound`` - for Numeric arrays, in that sample sign and byte order are ignored. This + for NumPy arrays, in that sample sign and byte order are ignored. This will change, either by correctly handling sign and byte order, or by raising an exception when different. Also, source samples are truncated to fit the audio sample size. This will not change. diff --git a/docs/reST/ref/surfarray.rst b/docs/reST/ref/surfarray.rst index 48b917fbfd..9b56a0dfb8 100644 --- a/docs/reST/ref/surfarray.rst +++ b/docs/reST/ref/surfarray.rst @@ -30,7 +30,7 @@ specific pixel value of a color. Integer pixel values can only be used directly between surfaces with matching pixel layouts (see :class:`pygame.Surface`). All functions that refer to "array" will copy the surface information to a new -numpy array. All functions that refer to "pixels" will directly reference the +NumPy array. All functions that refer to "pixels" will directly reference the pixels from the surface and any changes performed to the array will make changes in the surface. As this last functions share memory with the surface, this one will be locked during the lifetime of the array. From 2973c8bd9a2480e3149bcbac7408294142afa3e3 Mon Sep 17 00:00:00 2001 From: Ankith Date: Mon, 9 Dec 2024 23:25:41 +0530 Subject: [PATCH 20/26] Port imageext.c to SDL3(_image) --- .github/workflows/build-sdl3.yml | 11 +++++++++++ buildconfig/download_win_prebuilt.py | 16 ++++++++++++++++ dev.py | 1 - meson.build | 14 ++++++++++---- src_c/imageext.c | 8 ++++++++ src_c/meson.build | 6 +++--- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-sdl3.yml b/.github/workflows/build-sdl3.yml index 066439e04e..7b2cfe9987 100644 --- a/.github/workflows/build-sdl3.yml +++ b/.github/workflows/build-sdl3.yml @@ -86,6 +86,17 @@ jobs: cmake --build . --config Release --parallel sudo cmake --install . --config Release + - name: Install SDL3_image + if: matrix.os != 'windows-latest' + run: | + git clone https://github.com/libsdl-org/SDL_image + cd SDL_image + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release .. + cmake --build . --config Release --parallel + sudo cmake --install . --config Release + - name: Build with SDL3 run: python3 dev.py build --sdl3 diff --git a/buildconfig/download_win_prebuilt.py b/buildconfig/download_win_prebuilt.py index 5daaf54a76..9c56e007f6 100644 --- a/buildconfig/download_win_prebuilt.py +++ b/buildconfig/download_win_prebuilt.py @@ -90,6 +90,10 @@ def get_urls(x86=True, x64=True): '71ad2b5aacbc934a39e390ad733421313dd5d059' ], [ + 'https://github.com/libsdl-org/SDL_image/releases/download/preview-3.1.0/SDL3_image-devel-3.1.0-VC.zip', + '8538fea0cc4aabba2fc64db06196f1bb76a2785f' + ], + [ 'https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-devel-2.22.0-VC.zip', '2d4f131909af2985b5ebc5ed296d28628c87c243' ], @@ -213,6 +217,18 @@ def copy(src, dst): 'SDL2_image-2.8.3' ) ) + copy( + os.path.join( + temp_dir, + 'SDL3_image-devel-3.1.0-VC/SDL3_image-3.1.0' + ), + os.path.join( + move_to_dir, + prebuilt_dir, + 'SDL3_image-3.1.0' + ) + ) + copy( os.path.join( temp_dir, diff --git a/dev.py b/dev.py index c7a5dfb29e..7695f7eba0 100644 --- a/dev.py +++ b/dev.py @@ -26,7 +26,6 @@ SDL3_ARGS = [ "-Csetup-args=-Dsdl_api=3", - "-Csetup-args=-Dimage=disabled", "-Csetup-args=-Dmixer=disabled", "-Csetup-args=-Dfont=disabled", ] diff --git a/meson.build b/meson.build index ac93a648cc..7b8017c390 100644 --- a/meson.build +++ b/meson.build @@ -110,7 +110,7 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') endif sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.10' - sdl_image_ver = '2.8.3' + sdl_image_ver = (sdl_api == 3) ? '3.1.0' : '2.8.3' sdl_mixer_ver = '2.8.0' sdl_ttf_ver = '2.22.0' @@ -131,12 +131,18 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') pg_lib_dirs += sdl_image_lib_dir dlls += [ sdl_image_lib_dir / '@0@.dll'.format(sdl_image), - sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll', - sdl_image_lib_dir / 'optional' / 'libpng16-16.dll', - sdl_image_lib_dir / 'optional' / 'libtiff-5.dll', + sdl_image_lib_dir / 'optional' / (sdl_api == 3 ? 'libtiff-6.dll' : 'libtiff-5.dll'), sdl_image_lib_dir / 'optional' / 'libwebp-7.dll', sdl_image_lib_dir / 'optional' / 'libwebpdemux-2.dll', ] + # temporary solution to get things compiling under SDL3_image. In the future + # we would want to have libpng and libjpeg on SDL3_image as well. + if sdl_api != 3 + dlls += [ + sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll', + sdl_image_lib_dir / 'optional' / 'libpng16-16.dll', + ] + endif endif # SDL_mixer diff --git a/src_c/imageext.c b/src_c/imageext.c index d2823fcb00..bb5873c5d7 100644 --- a/src_c/imageext.c +++ b/src_c/imageext.c @@ -46,7 +46,15 @@ #include "pgopengl.h" +#ifdef PG_SDL3 +#include + +// SDL3_images uses SDL3 error reporting API +#define IMG_GetError SDL_GetError +#else #include +#endif + #ifdef WIN32 #define strcasecmp _stricmp #else diff --git a/src_c/meson.build b/src_c/meson.build index bb94eddcb2..c8eb46677b 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -407,9 +407,6 @@ endif # optional modules -# TODO: support SDL3 -if sdl_api != 3 - if sdl_image_dep.found() imageext = py.extension_module( 'imageext', @@ -421,6 +418,9 @@ if sdl_image_dep.found() ) endif +# TODO: support SDL3 +if sdl_api != 3 + if sdl_ttf_dep.found() font = py.extension_module( 'font', From 63ae32cefa5e903254f0ea29a2ccbf7c510e5ae8 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Mon, 30 Dec 2024 15:41:15 +0000 Subject: [PATCH 21/26] Fix the Deprecation Warnings in surfarray_test --- test/surfarray_test.py | 46 ++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/test/surfarray_test.py b/test/surfarray_test.py index 2288f9b862..947bb3a677 100644 --- a/test/surfarray_test.py +++ b/test/surfarray_test.py @@ -13,6 +13,7 @@ rint, arange, __version__ as np_version, + array ) import pygame @@ -114,10 +115,10 @@ def _make_array3d(self, dtype): def _fill_array2d(self, arr, surf): palette = self.test_palette - arr[:5, :6] = surf.map_rgb(palette[1]) - arr[5:, :6] = surf.map_rgb(palette[2]) - arr[:5, 6:] = surf.map_rgb(palette[3]) - arr[5:, 6:] = surf.map_rgb(palette[4]) + arr[:5, :6] = array(surf.map_rgb(palette[1])).astype(int) + arr[5:, :6] = array(surf.map_rgb(palette[2])).astype(int) + arr[:5, 6:] = array(surf.map_rgb(palette[3])).astype(int) + arr[5:, 6:] = array(surf.map_rgb(palette[4])).astype(int) def _fill_array3d(self, arr): palette = self.test_palette @@ -487,17 +488,19 @@ def do_blit(surf, arr): # this test should be removed soon, when the function is deleted def test_get_arraytype(self): - array_type = pygame.surfarray.get_arraytype() + with self.assertWarns(DeprecationWarning): + array_type = pygame.surfarray.get_arraytype() - self.assertEqual(array_type, "numpy", f"unknown array type {array_type}") + self.assertEqual(array_type, "numpy", f"unknown array type {array_type}") # this test should be removed soon, when the function is deleted def test_get_arraytypes(self): - arraytypes = pygame.surfarray.get_arraytypes() - self.assertIn("numpy", arraytypes) + with self.assertWarns(DeprecationWarning): + arraytypes = pygame.surfarray.get_arraytypes() + self.assertIn("numpy", arraytypes) - for atype in arraytypes: - self.assertEqual(atype, "numpy", f"unknown array type {atype}") + for atype in arraytypes: + self.assertEqual(atype, "numpy", f"unknown array type {atype}") def test_make_surface(self): # How does one properly test this with 2d arrays. It makes no sense @@ -711,24 +714,23 @@ def test_use_arraytype(self): def do_use_arraytype(atype): pygame.surfarray.use_arraytype(atype) - pygame.surfarray.use_arraytype("numpy") - self.assertEqual(pygame.surfarray.get_arraytype(), "numpy") - self.assertRaises(ValueError, do_use_arraytype, "not an option") + with self.assertWarns(DeprecationWarning): + pygame.surfarray.use_arraytype("numpy") + self.assertEqual(pygame.surfarray.get_arraytype(), "numpy") + self.assertRaises(ValueError, do_use_arraytype, "not an option") def test_surf_lock(self): sf = pygame.Surface((5, 5), 0, 32) - for atype in pygame.surfarray.get_arraytypes(): - pygame.surfarray.use_arraytype(atype) - ar = pygame.surfarray.pixels2d(sf) - self.assertTrue(sf.get_locked()) + ar = pygame.surfarray.pixels2d(sf) + self.assertTrue(sf.get_locked()) - sf.unlock() - self.assertTrue(sf.get_locked()) + sf.unlock() + self.assertTrue(sf.get_locked()) - del ar - self.assertFalse(sf.get_locked()) - self.assertEqual(sf.get_locks(), ()) + del ar + self.assertFalse(sf.get_locked()) + self.assertEqual(sf.get_locks(), ()) if __name__ == "__main__": From e8f79d1647c1f1dcb50df6f5b3424ff153d6c3f1 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Mon, 30 Dec 2024 15:42:30 +0000 Subject: [PATCH 22/26] formatting --- test/surfarray_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/surfarray_test.py b/test/surfarray_test.py index 947bb3a677..45bce35912 100644 --- a/test/surfarray_test.py +++ b/test/surfarray_test.py @@ -13,7 +13,7 @@ rint, arange, __version__ as np_version, - array + array, ) import pygame From e2d1bafa08972b9d52d51430abc151caf0e02563 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Mon, 30 Dec 2024 16:10:18 +0000 Subject: [PATCH 23/26] Rename TestTags so it doesn't get confused for a test --- test/test_utils/test_machinery.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_utils/test_machinery.py b/test/test_utils/test_machinery.py index 0531cc2f71..068e52df9c 100644 --- a/test/test_utils/test_machinery.py +++ b/test/test_utils/test_machinery.py @@ -44,7 +44,7 @@ def getTestCaseNames(self, testCaseClass): TAGS_RE = re.compile(r"\|[tT]ags:(-?[ a-zA-Z,0-9_\n]+)\|", re.M) -class TestTags: +class TheTestTags: def __init__(self): self.memoized = {} self.parent_modules = {} @@ -86,4 +86,4 @@ def __call__(self, parent_class, meth): return self.memoized[key] -get_tags = TestTags() +get_tags = TheTestTags() From 59b0d3629d6b3a2fe3c29a04a760a045c8144231 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Mon, 30 Dec 2024 16:38:31 +0000 Subject: [PATCH 24/26] Fix mypy to 1.13.0 to avoid __all__ duplication --- .github/workflows/build-ubuntu-sdist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ubuntu-sdist.yml b/.github/workflows/build-ubuntu-sdist.yml index c58b9d8a6c..64ec5ef716 100644 --- a/.github/workflows/build-ubuntu-sdist.yml +++ b/.github/workflows/build-ubuntu-sdist.yml @@ -84,7 +84,7 @@ jobs: - name: Test typestubs run: | - pip3 install mypy + pip3 install mypy==1.13.0 python3 buildconfig/stubs/stubcheck.py # We upload the generated files under github actions assets From d0b8e73abc2dad51e869d4826700bcfbffaca0d9 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Tue, 31 Dec 2024 09:02:48 +0000 Subject: [PATCH 25/26] Revert numpy array().astype(int) fix Ankith believes we can fix this better in the library code. --- test/surfarray_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/surfarray_test.py b/test/surfarray_test.py index 45bce35912..bfcf8f15fe 100644 --- a/test/surfarray_test.py +++ b/test/surfarray_test.py @@ -115,10 +115,10 @@ def _make_array3d(self, dtype): def _fill_array2d(self, arr, surf): palette = self.test_palette - arr[:5, :6] = array(surf.map_rgb(palette[1])).astype(int) - arr[5:, :6] = array(surf.map_rgb(palette[2])).astype(int) - arr[:5, 6:] = array(surf.map_rgb(palette[3])).astype(int) - arr[5:, 6:] = array(surf.map_rgb(palette[4])).astype(int) + arr[:5, :6] = surf.map_rgb(palette[1]) + arr[5:, :6] = surf.map_rgb(palette[2]) + arr[:5, 6:] = surf.map_rgb(palette[3]) + arr[5:, 6:] = surf.map_rgb(palette[4]) def _fill_array3d(self, arr): palette = self.test_palette From d69b9e2e0314c0cbb72cf2142bbb041ce5d3a517 Mon Sep 17 00:00:00 2001 From: Noah Date: Tue, 31 Dec 2024 20:57:42 +0900 Subject: [PATCH 26/26] Add readme for Traditional Chinese. (#3113) ------- Co-authored-by: noahcse Co-authored-by: hisa10 --- docs/readmes/README.zh-tw.rst | 180 ++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 docs/readmes/README.zh-tw.rst diff --git a/docs/readmes/README.zh-tw.rst b/docs/readmes/README.zh-tw.rst new file mode 100644 index 0000000000..30cbb6d6eb --- /dev/null +++ b/docs/readmes/README.zh-tw.rst @@ -0,0 +1,180 @@ +.. image:: https://raw.githubusercontent.com/pygame-community/pygame-ce/main/docs/reST/_static/pygame_ce_logo.svg + :alt: pygame + :target: https://pyga.me/ + + +|DocsStatus| +|PyPiVersion| |PyPiLicense| +|Python3| |GithubCommits| |BlackFormatBadge| + +`English`_ `简体中文`_ **繁體中文** `Français`_ `فارسی`_ `Español`_ +---- + +Pygame_ 是一款自由且開源的跨平台程式庫,用於開發電子遊戲等多媒體應用。Pygame基於 `Simple DirectMedia Layer library`_ 以及其他幾個廣受歡迎的程式庫,提取其中最常見的函數,讓編寫遊戲成為更符合直覺的事情。 + +本發行版名為 **“pygame - Community Edition“** (簡稱 “pygame-ce“)。 + +pygame-ce是上游pygame專案的分支,由此前pygame專案的核心開發者創建。開發者們在上游的開發中受到了強烈的阻撓,無法繼續,所以創建了這個發行版。新的發行版主旨在提供更頻繁的版本更新,持續不斷的bug修復與功能增強,以及更民主的管理模式。 + +歡迎新的貢獻者加入我們。 + +安装 +------------ + +:: + + pip install pygame-ce + + +入門 +---- + +剛接觸pygame的初學者應該可以快速入門。pygame提供了大量教學與介紹,也提供了整個函式庫的完整參考文件。你可以在 `docs page`_ 瀏覽文件。也可以在終端機中執行`python -m pygame.docs`,在本機瀏覽文件。如果找不到本機文檔,會自動開啟線上文檔。 + +線上文件與github中的開發版pygame同步。文件版本可能比你正在使用的pygame版本新一些。在終端機中執行 ``pip install pygame-ce --upgrade`` 可以升級到最新完整版本。 + +最重要的是,examples目錄中有許多可以玩的小程序,可以讓你立即開啟程式碼之旅。 + +從原始碼開始編譯 +-------------------- + +如果你想使用那些正在開發的特性,或者你想要為pygame做出貢獻,你需要從原始碼開始編譯pygame,而不是用pip來安裝。 + +編譯與安裝的流程是高度自動化的。你要做的工作主要是pygame依賴的編譯與安裝。一旦完成,你就可以執行`setup.py`,它會嘗試完成自動配置,編譯,然後安裝pygame。 + +更多關於編譯與安裝訊息,請參閱 `Compilation wiki page`_ 。 + + + +鳴謝 +------- + +感謝為本資源庫貢獻的每一個人。 + +特別鳴謝: + +* Marcus Von Appen: many changes, and fixes, 1.7.1+ freebsd maintainer +* Lenard Lindstrom: the 1.8+ windows maintainer, many changes, and fixes +* Brian Fisher for svn auto builder, bug tracker and many contributions +* Rene Dudfield: many changes, and fixes, 1.7+ release manager/maintainer +* Phil Hassey for his work on the pygame.org website +* DR0ID for his work on the sprite module +* Richard Goedeken for his smoothscale function +* Ulf Ekström for his pixel perfect collision detection code +* Pete Shinners: original author +* David Clark for filling the right-hand-man position +* Ed Boraas and Francis Irving: Debian packages +* Maxim Sobolev: FreeBSD packaging +* Bob Ippolito: macOS and OS X porting (much work!) +* Jan Ekhol, Ray Kelm, and Peter Nicolai: putting up with early design ideas +* Nat Pryce for starting our unit tests +* Dan Richter for documentation work +* TheCorruptor for his incredible logos and graphics +* Nicholas Dudfield: many test improvements +* Alex Folkner for pygame-ctypes + +感謝發送補丁/修復的人:Niki Spahiev, Gordon +Tyler, Nathaniel Pryce, Dave Wallace, John Popplewell, Michael Urman, +Andrew Straw, Michael Hudson, Ole Martin Bjoerndalen, Herve Cauwelier, +James Mazer, Lalo Martins, Timothy Stranex, Chad Lester, Matthias +Spiller, Bo Jangeborg, Dmitry Borisov, Campbell Barton, Diego Essaya, +Eyal Lotem, Regis Desgroppes, Emmanuel Hainry, Randy Kaelber, +Matthew L Daniel, Nirav Patel, Forrest Voight, Charlie Nolan, +Frankie Robertson, John Krukoff, Lorenz Quack, Nick Irvine, +Michael George, Saul Spatz, Thomas Ibbotson, Tom Rothamel, Evan Kroske, +Cambell Barton. + +以及我們卓越的bug獵人:Angus, Guillaume Proux, Frank +Raiser, Austin Henry, Kaweh Kazemi, Arturo Aldama, Mike Mulcheck, +Michael Benfield, David Lau + +還有許多人提交了有用的想法,助力本計畫前進,使我們的生活變得更加輕鬆。感謝你們! + +非常感謝人們提出文件評論並添加到 pygame 文件和 pygame-ce 文檔 + +感謝製作遊戲並把遊戲放到pygame.org網站供人學習與娛樂的人。 + +感謝 James Paige 建立了pygame bugzilla。 + +感謝 Roger Dingledine 與SEUL.ORG上的crew,感謝我們優秀的主持。 + +依賴 +------------ + + +pygame顯然依賴SDL和Python。此外pygame也嵌入了幾個較小的函式庫:font模組依賴SDL_ttf(SDL_ttf依賴freetype);mixer模組(以及mixer.music模組)依賴SDL_mixer;image模組依賴SDL_image(SDL_image使用到libjpeg與libpng) ;transform模組內嵌了一個SDL_rotozoom來實現它的rotozoom函式;surfarray模組用到了Numpy中的多維數組。 + +依賴的版本要求如下: + + + ++----------+------------------------+ +| CPython | >= 3.9 (或 PyPy3) | ++----------+------------------------+ +| SDL | >= 2.0.14 | ++----------+------------------------+ +| SDL_mixer| >= 2.0.4 | ++----------+------------------------+ +| SDL_image| >= 2.0.4 | ++----------+------------------------+ +| SDL_ttf | >= 2.0.15 | ++----------+------------------------+ + + +如何貢獻 +-------- + +首先,感謝你考慮為 pygame-ce 做出貢獻!正是像你這樣的人讓 pygame-ce 成為一個偉大的函式庫。請依照以下步驟開始: + +1. 閱讀 `Contribution Guidelines`_ 和 `Many Ways to Contribute`_ wiki 頁面。 +2. 閱讀 `Opening A Pull Request`_ 和 `Opening a Great Pull Request`_ 的相關文件。 +3. 學習How to `label and link reported issues`_ 。 +4. 檢查 `issue tracker`_ 以查找你有興趣的issue,或建立一個新的issue來開始討論你的想法。 + +`wiki pages`_ 上還有許多資源可以幫助你入門。 + +如果有任何問題,請隨時在 `Pygame Community Discord Server`_ 詢問或建立一個issue。 + + +授權條款 +------- +**授權條款版本:** LGPL-2.1-or-later + +本函式庫在 `GNU LGPL version 2.1`_ 下發布,許可文件: ``docs/LGPL.txt`` 。我們保留將此函式庫的未來版本置於其他許可證下的權利。 + +這基本上代表你可以在任意專案中使用pygame,但如果你修改或增加了pygame庫的內容,這些內容必須使用原授權條款相容的授權發布(我們更希望修改者將其提交回pygame專案)。閉源或商業性遊戲中可以使用pygame。 + +``examples`` 目錄中的程式不受版權限制。 + +有關依賴相的許可證,請參閱 ``docs/licenses`` 。 + + + +.. |PyPiVersion| image:: https://img.shields.io/pypi/v/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |PyPiLicense| image:: https://img.shields.io/pypi/l/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |Python3| image:: https://img.shields.io/badge/python-3-blue.svg?v=1 + +.. |GithubCommits| image:: https://img.shields.io/github/commits-since/pygame-community/pygame-ce/2.3.0.svg + :target: https://github.com/pygame-community/pygame-ce/compare/2.3.0...main + +.. |DocsStatus| image:: https://img.shields.io/website?down_message=offline&label=docs&up_message=online&url=https%3A%2F%2Fpyga.me%2Fdocs%2F + :target: https://pyga.me/docs/ + +.. |BlackFormatBadge| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + +.. _pygame: https://www.pyga.me +.. _Simple DirectMedia Layer library: https://www.libsdl.org +.. _Compilation wiki page: https://github.com/pygame-community/pygame-ce/wiki#compiling +.. _docs page: https://pyga.me/docs +.. _GNU LGPL version 2.1: https://www.gnu.org/copyleft/lesser.html + +.. _English: ./../../README.rst +.. _简体中文: README.zh-cn.rst +.. _Français: README.fr.rst +.. _فارسی: README.fa.rst +.. _Español: README.es.rst