Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixups #355

Open
wants to merge 100 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
1c6c05f
Remove unify
Baekalfen Nov 15, 2024
497c4e9
Updated pre-commit
Baekalfen Nov 15, 2024
f9d72b6
pre-commit all files
Baekalfen Nov 15, 2024
d9a330c
Fix placement of log_level in PyBoy.__init__
Baekalfen Nov 15, 2024
33c42b9
Introduce PyBoyException
Baekalfen Nov 15, 2024
da16fc2
Introduce exceptions to all load_state
Baekalfen Nov 15, 2024
bfdda5a
Track if compiled with Cython from utils
Baekalfen Nov 15, 2024
a225943
Introduce PyBoyDependencyError and PillowImportError
Baekalfen Nov 15, 2024
229dcc2
Convert existing Exception to PyBoyException
Baekalfen Nov 21, 2024
789ea11
Update Discord invite to channel "rules"
Baekalfen Nov 21, 2024
f980721
Replace asserts with PyBoyExceptions
Baekalfen Nov 21, 2024
8d858d1
Add button test and fix name collision on log level test
Baekalfen Nov 21, 2024
d6079e1
Fix use of noexcept to remove warnings
Baekalfen Nov 21, 2024
58932b7
Move CGB rendering from Renderer to CGBRenderer
Baekalfen Nov 21, 2024
6ae7a99
Actually release the GIL and benchmark to test it
Baekalfen Nov 21, 2024
d1a420b
Update tests to new exceptions
Baekalfen Nov 21, 2024
4ddc813
Mock cython.gil/nogil when Cython is not present (PyPy)
Baekalfen Nov 23, 2024
1819180
Clean up unused "is_pypy"
Baekalfen Nov 23, 2024
6173fb8
Skip doctests if compiled with Cython instead of failing
Baekalfen Nov 23, 2024
80d9a82
Add pytest.ini options to pyproject.toml; ignore SDL2 warning; disabl…
Baekalfen Nov 23, 2024
364888d
Add benchmarking to CI
Baekalfen Nov 23, 2024
94753a2
Move linting and formatting to ruff
Baekalfen Nov 23, 2024
95e0e86
Run full ruff linting and formating
Baekalfen Nov 23, 2024
45479bd
Remove Python 3.8 EOL
Baekalfen Nov 23, 2024
01be86c
Clean up LCD helper functions and correct _cycles_to_interrupt to 1<<31
Baekalfen Nov 23, 2024
45810cf
Automatically add documentation for plugins to PyBoy constructor
Baekalfen Dec 6, 2024
cb94dcf
Add missing gameshark doc
Baekalfen Dec 6, 2024
adc6434
Add set_time_left to Mario wrapper, change error to exception
Baekalfen Dec 11, 2024
d043669
Improve Makefile docs
Baekalfen Dec 11, 2024
a15dc57
Remove .stop() from tests as it saves RAM, while __del__ does not. Th…
Baekalfen Dec 11, 2024
06b8541
Move color_palette and cgb_color_palette to PyBoy constructor
Baekalfen Dec 11, 2024
2ac0c3b
Fix no_input, test and move it from plugin to PyBoy
Baekalfen Dec 11, 2024
17f05fe
Remove redundant .set_emulation_speed(0) from tests with null window
Baekalfen Dec 13, 2024
40986de
Fixed punctuation
Baekalfen Dec 13, 2024
490ea9f
Introduce partial save/load-state to sound
Baekalfen Dec 16, 2024
5999401
Tests and fixes for LCD frame timings
Baekalfen Nov 23, 2024
fe5d13f
Improvements to LCDC and STAT registers
Baekalfen Dec 16, 2024
ca7e5f2
Move test-skips from "is_pypy" to "cython_compiled"
Baekalfen Dec 16, 2024
7fc45e9
Fix wrong serialization of scanline parameters in saved state
Baekalfen Dec 15, 2024
3951a77
Fix save/load state of STATRegister not restoring mode correctly
Baekalfen Dec 15, 2024
fdba22c
Add _cycles_to_interrupt to Timer save/load state
Baekalfen Dec 15, 2024
6eb0f44
Comprehensive testing for save/load state and all attributes
Baekalfen Dec 16, 2024
a05872b
Updated test results
Baekalfen Dec 16, 2024
90ffd16
Change gamewrapper errors to exceptions
Baekalfen Dec 16, 2024
a80a0ca
Introduce _bcd_to_dec and _dec_to_bcd
Baekalfen Dec 16, 2024
89c3f7a
Update game wrapper tetris to new timings
Baekalfen Dec 16, 2024
e0c9966
Minor tests fixes
Baekalfen Dec 16, 2024
4c7d2da
Add PYTEST_SECRET_KEY to doc tests in GHA
Baekalfen Dec 16, 2024
8b29e5f
Bump version to v2.5.0
Baekalfen Dec 11, 2024
87f9234
Update docs
Baekalfen Dec 11, 2024
5c363da
Add vectroid to tests. Not booting
Baekalfen Dec 16, 2024
5935cdb
Rename LCD-test and check cycles
Baekalfen Dec 16, 2024
3414dd0
Avoid saving game in tests
Baekalfen Dec 16, 2024
980a4c8
Run doctests in 1 thread to avoid race conditions on GHA
Baekalfen Dec 17, 2024
92ebbc8
Remove "pyboy_fast" boot rom
Baekalfen Dec 17, 2024
f1b9417
Robust CGB detection with tests
Baekalfen Dec 17, 2024
5624879
Blank out first frame after enabling LCD
Baekalfen Dec 20, 2024
6e3c177
Change errors to exceptions
Baekalfen Dec 21, 2024
9dea193
Add cycle count to cpu.dump_state
Baekalfen Dec 27, 2024
ac39a88
Fix singlestepping after CPU cycles_target has been introduced
Baekalfen Dec 27, 2024
f2c048e
Fix tests to be explicit about window
Baekalfen Dec 27, 2024
20a3c7c
Introduce DEBUG var in setup.py
Baekalfen Dec 27, 2024
36df43f
Move lcd,sound,timer tick in mb get/setitem into specific addresses
Baekalfen Dec 27, 2024
983e4ae
Add TurtleTests
Baekalfen Dec 23, 2024
3c1e83f
Add '.inner_loop' to default_rom for testing
Baekalfen Dec 29, 2024
1cd6cc6
WIP breakpoint remove itself
Baekalfen Dec 30, 2024
4e787c4
[Incomplete] Improved exception handling
Baekalfen Dec 22, 2024
b1f4f35
LCD: Introduce consistent frame cycles, and proper handling of enable…
Baekalfen Jan 11, 2025
7341655
Implement LCD tests to verify timing and on enable/disable
Baekalfen Jan 11, 2025
69dfc65
wip sound
Baekalfen Jan 16, 2025
566cfef
wip sound working
Baekalfen Jan 16, 2025
e53b6d6
wip sound2
Baekalfen Jan 16, 2025
f6df1dd
wip sound cython
Baekalfen Jan 16, 2025
f7788de
fixup
Baekalfen Jan 16, 2025
ebb1b4d
sound int->int64_t
Baekalfen Jan 17, 2025
4266411
sound save/load state
Baekalfen Jan 17, 2025
a0f6aae
Allow save_state to raise exceptions
Baekalfen Jan 17, 2025
b77e56b
Fix events not cleared on pause and verify with toggle
Baekalfen Jan 17, 2025
0733cc2
Add arguments to control sound, sample rate, emulation and volume
Baekalfen Jan 17, 2025
fabe93c
Implement sound pcm12 and pcm34
Baekalfen Jan 17, 2025
5e0e523
SDL2 window improve sound and mixing
Baekalfen Jan 17, 2025
612238b
Sound API
Baekalfen Jan 17, 2025
e03e54c
wip sound3
Baekalfen Jan 17, 2025
28ce4b8
Fix missing return in breakpoint symbol lookup
Baekalfen Jan 17, 2025
f9743b6
wip debug prompt
Baekalfen Jan 17, 2025
37a9397
Sound CH1 debug info in dump_state
Baekalfen Jan 17, 2025
91fb146
Added log debug to CGB speed switching
Baekalfen Jan 17, 2025
259db71
fixup! Sound API
Baekalfen Jan 17, 2025
9c90218
fixup! wip sound cython
Baekalfen Jan 17, 2025
7bd500b
Fixed wave channel period and expanded inline if-else
Baekalfen Jan 20, 2025
c924b8c
Initial API for sound
Baekalfen Jan 20, 2025
c6bb86f
Convert RTC usage of float to double, and remove cast to int
Baekalfen Jan 20, 2025
f3a88f5
Correct screen documentation to say "memoryview" instead of "bytes"
Baekalfen Jan 20, 2025
e56effa
Convert sound to use double for clock_target. Fixes issue with accumu…
Baekalfen Jan 20, 2025
ae52988
fixup! Initial API for sound
Baekalfen Jan 20, 2025
cb91041
Fix sound tick in CGB mode and when to count cycles
Baekalfen Jan 20, 2025
4043277
fixup! Sound API
Baekalfen Jan 20, 2025
8c5cb37
fixup! Initial API for sound
Baekalfen Jan 20, 2025
1a776ae
Add test for memoryview for raw buffers in sound and screen API
Baekalfen Jan 20, 2025
b82a8ce
Fixing sound issues when pausing, by pausing audio device in window
Baekalfen Jan 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version: [3.8, 3.9, "3.10", 3.11, 3.12, 3.13]
python-version: [3.9, "3.10", 3.11, 3.12, 3.13]

steps:
- uses: actions/checkout@v3
Expand All @@ -33,8 +33,10 @@ jobs:
pip install --prefer-binary -r requirements_tests.txt
- name: Doctest
if: ${{ !contains(matrix.os, 'windows') }}
env:
PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }}
run: |
python -m pytest pyboy/ -n auto
python -m pytest pyboy/ -v
- name: Build PyBoy
run: |
python setup.py build_ext -j $(getconf _NPROCESSORS_ONLN) --inplace
Expand All @@ -50,6 +52,13 @@ jobs:
TEST_NO_UI: 1
run: |
python -m pytest tests/ -n auto -v
- name: Run PyTest Benchmark
env:
PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }}
TEST_VERBOSE_IMAGES: 0
TEST_NO_UI: 1
run: |
python -m pytest tests/test_benchmark.py --benchmark-enable --benchmark-min-rounds=10
- name: Build wheel
run: |
echo "Building wheel"
Expand Down Expand Up @@ -106,8 +115,10 @@ jobs:
pypy3 -m pip install --prefer-binary -r requirements_tests.txt
- name: Doctest
if: ${{ !contains(matrix.os, 'windows') }}
env:
PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }}
run: |
pypy3 -m pytest pyboy/ -n auto
pypy3 -m pytest pyboy/ -v
- name: Run PyTest
env:
PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }}
Expand All @@ -122,7 +133,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['cp38-cp38', 'cp39-cp39', 'cp310-cp310', 'cp311-cp311', 'cp312-cp312', 'cp313-cp313']
python-version: ['cp39-cp39', 'cp310-cp310', 'cp311-cp311', 'cp312-cp312', 'cp313-cp313']
manylinux-version: ['manylinux_2_28_x86_64', 'musllinux_1_2_x86_64'] # GHA doesn't support manylinux_2_24_aarch64

steps:
Expand All @@ -145,16 +156,22 @@ jobs:
fi

cd /work
echo "Starting build"
echo "Preparing pip"
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools

echo "Starting tests"
python -m pip install --prefer-binary -r requirements.txt
python -m pip install --prefer-binary -r requirements_tests.txt

echo "Starting Doctests"
PYTEST_SECRETS_KEY=${{ secrets.PYTEST_SECRETS_KEY }} python -m pytest pyboy/ -v

echo "Building PyBoy"
python setup.py build_ext -j $(getconf _NPROCESSORS_ONLN) --inplace

python -m pip install --prefer-binary -r requirements_tests.txt
PYTEST_SECRETS_KEY=${{ secrets.PYTEST_SECRETS_KEY }} TEST_CI=1 TEST_NO_UI=1 python -m pytest tests/ -n2 -v
echo "Starting pytests"
PYTEST_SECRETS_KEY=${{ secrets.PYTEST_SECRETS_KEY }} TEST_NO_UI=1 python -m pytest tests/ -n2 -v

echo "Building wheel"
python -m pip install wheel
Expand All @@ -170,10 +187,10 @@ jobs:
echo "Dists built:"
ls -lah dist/

- name: Set up Python 3.8 (just for PyPi upload)
- name: Set up Python 3.11 (just for PyPi upload)
uses: actions/setup-python@v3
with:
python-version: 3.8
python-version: 3.11
- name: Upload wheel
if: ${{ github.event_name == 'release' && github.event.action == 'published' && !github.event.release.prerelease }}
run: |
Expand Down
22 changes: 7 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
exclude: (opcodes.py|manager.py|manager.pxd)
repos:
- repo: https://github.com/myint/unify
rev: v0.5
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: unify
args: [--quote, '"', --in-place]
language: python
types: [python]
- repo: https://github.com/google/yapf
rev: 'v0.40.2'
hooks:
- id: yapf
additional_dependencies: [toml]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
# Run the linter.
- id: ruff
args: [--select, I, --fix]
# Run the formatter.
- id: ruff-format
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

.PHONY: build clean run install test
.PHONY: build clean run install test benchmark docs

all: build

Expand Down Expand Up @@ -65,7 +65,7 @@ uninstall:
${PY} -m pip uninstall pyboy

test: export DEBUG=1
test: clean test_pypy test_cpython_doctest build test_cython
test: clean test_pypy test_cpython_doctest build test_cython benchmark

test_cpython_doctest:
${PY} -m pytest pyboy/ ${PYTEST_ARGS}
Expand All @@ -78,9 +78,13 @@ test_pypy:

test_all: test

benchmark:
${PY} -m pytest -m benchmark tests/test_benchmark.py --benchmark-enable --benchmark-min-rounds=10

docs: clean
bash -O extglob -c 'rm -rf -- ${ROOT_DIR}/docs/!(templates|CNAME)'
find ./docs -type f ! -path "./docs/templates/*" ! -path "./docs/CNAME" ! -name "*.png" -exec rm -rf {} +
mkdir -p ${ROOT_DIR}/docs/templates
cd ${ROOT_DIR}/pyboy/plugins && ${PY} manager_gen.py
pdoc --html --force -c latex_math=True -c sort_identifiers=False -c show_type_annotations=True --template-dir docs/templates pyboy
cp -r html/pyboy/ ${ROOT_DIR}/docs/
rm -rf html
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<img src="extras/README/pyboy.svg" width="480">
</p>

__If you have any questions, or just want to chat, [join us on Discord](https://discord.gg/Zrf2nyH).__
__If you have any questions, or just want to chat, [join us on Discord](https://discord.gg/wUbag3KNqQ).__

[![Discord](https://img.shields.io/discord/584149554132418570?style=for-the-badge&logo=Discord&label=PyBoy)](https://discord.gg/Zrf2nyH)
[![Discord](https://img.shields.io/discord/584149554132418570?style=for-the-badge&logo=Discord&label=PyBoy)](https://discord.gg/wUbag3KNqQ)

<!---
Generate GIF with the layout and captions
Expand Down Expand Up @@ -98,7 +98,7 @@ If you are looking to make a bot or AI, then these resources are a good place to
* [Example: Tetris](https://github.com/Baekalfen/PyBoy/wiki/Example-Tetris)
* [Example: Super Mario Land](https://github.com/Baekalfen/PyBoy/wiki/Example-Super-Mario-Land)
* [Code Examples](https://github.com/Baekalfen/PyBoy/tree/master/extras/examples)
* [Discord](https://discord.gg/Zrf2nyH)
* [Discord](https://discord.gg/wUbag3KNqQ)


When the emulator is running, you can easily access [PyBoy's API](https://baekalfen.github.io/PyBoy/index.html):
Expand Down Expand Up @@ -186,9 +186,9 @@ do 3160 hours of gameplay in 1 hour.

Contributing
============
Any contribution is appreciated. The currently known problems are tracked in [the Issues tab](https://github.com/Baekalfen/PyBoy/issues). Feel free to take a swing at any one of them. If you have something original in mind, come and [discuss it on on Discord](https://discord.gg/Zrf2nyH).
Any contribution is appreciated. The currently known problems are tracked in [the Issues tab](https://github.com/Baekalfen/PyBoy/issues). Feel free to take a swing at any one of them. If you have something original in mind, come and [discuss it on on Discord](https://discord.gg/wUbag3KNqQ).

[![Discord](https://img.shields.io/discord/584149554132418570?style=for-the-badge&logo=Discord&label=PyBoy)](https://discord.gg/Zrf2nyH)
[![Discord](https://img.shields.io/discord/584149554132418570?style=for-the-badge&logo=Discord&label=PyBoy)](https://discord.gg/wUbag3KNqQ)

For the more major features, there are the following that you can give a try. They are also described in more detail in the [project list in the Wiki](https://github.com/Baekalfen/PyBoy/wiki/Student-Projects):
* Hacking games
Expand Down
28 changes: 14 additions & 14 deletions docs/api/gameshark.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ <h1 class="title">Module <code>pyboy.api.gameshark</code></h1>
self.enabled = False

def _convert_cheat(self, gameshark_code):
&#39;&#39;&#39;
&#34;&#34;&#34;
A GameShark code for these consoles is written in the format ttvvaaaa. tt specifies the type, which is usually 01.
vv specifies the hexadecimal value the code will write into the game&#39;s memory. aaaa specifies the memory address
that will be modified, with the low byte first (e.g. address C056 is written as 56C0).
Expand All @@ -59,18 +59,18 @@ <h1 class="title">Module <code>pyboy.api.gameshark</code></h1>
https://doc.kodewerx.org/hacking_gb.html

There seems to be conflicting information about the presence of other types than 01.
&#39;&#39;&#39;
&#34;&#34;&#34;
# Check if the input cheat code has the correct length (8 characters)
if len(gameshark_code) != 8:
raise ValueError(&#34;Invalid cheat code length. Cheat code must be 8 characters long.&#34;)

# Extract components from the cheat code
_type = int(gameshark_code[:2], 16)
value = int(gameshark_code[2:4], 16) # Convert hexadecimal value to an integer
unconverted_address = gameshark_code[4:] # Ex: 1ED1
lower = unconverted_address[:2] # Ex: 1E
upper = unconverted_address[2:] # Ex: D1
address_converted = upper + lower # Ex: 0xD11E # Converting to Ram Readable address
value = int(gameshark_code[2:4], 16) # Convert hexadecimal value to an integer
unconverted_address = gameshark_code[4:] # Ex: 1ED1
lower = unconverted_address[:2] # Ex: 1E
upper = unconverted_address[2:] # Ex: D1
address_converted = upper + lower # Ex: 0xD11E # Converting to Ram Readable address
address = int(address_converted, 16)

if not 0x8000 &lt;= address:
Expand Down Expand Up @@ -210,7 +210,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.enabled = False

def _convert_cheat(self, gameshark_code):
&#39;&#39;&#39;
&#34;&#34;&#34;
A GameShark code for these consoles is written in the format ttvvaaaa. tt specifies the type, which is usually 01.
vv specifies the hexadecimal value the code will write into the game&#39;s memory. aaaa specifies the memory address
that will be modified, with the low byte first (e.g. address C056 is written as 56C0).
Expand All @@ -223,18 +223,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
https://doc.kodewerx.org/hacking_gb.html

There seems to be conflicting information about the presence of other types than 01.
&#39;&#39;&#39;
&#34;&#34;&#34;
# Check if the input cheat code has the correct length (8 characters)
if len(gameshark_code) != 8:
raise ValueError(&#34;Invalid cheat code length. Cheat code must be 8 characters long.&#34;)

# Extract components from the cheat code
_type = int(gameshark_code[:2], 16)
value = int(gameshark_code[2:4], 16) # Convert hexadecimal value to an integer
unconverted_address = gameshark_code[4:] # Ex: 1ED1
lower = unconverted_address[:2] # Ex: 1E
upper = unconverted_address[2:] # Ex: D1
address_converted = upper + lower # Ex: 0xD11E # Converting to Ram Readable address
value = int(gameshark_code[2:4], 16) # Convert hexadecimal value to an integer
unconverted_address = gameshark_code[4:] # Ex: 1ED1
lower = unconverted_address[:2] # Ex: 1E
upper = unconverted_address[2:] # Ex: D1
address_converted = upper + lower # Ex: 0xD11E # Converting to Ram Readable address
address = int(address_converted, 16)

if not 0x8000 &lt;= address:
Expand Down
6 changes: 4 additions & 2 deletions docs/api/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ <h1 class="title">Module <code>pyboy.api</code></h1>
from .tilemap import TileMap

# __pdoc__ = {
# &#34;gameshark.GameShark.tick&#34;: False,
# }</code></pre>
# &#34;constants&#34;: False,
# &#34;manager&#34;: False,
# }
# __all__ = [&#34;API&#34;]</code></pre>
</details>
</section>
<section>
Expand Down
Loading
Loading