From b45f4b9dd669111894d7904157067e4f46db67b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 5 Nov 2023 22:04:18 +0000
Subject: [PATCH] chore: support for next_frame() Allowing frame by frame
 "navigation".

---
 CHANGELOG.md                     |  3 ++-
 examples/python/pocket.py        |  3 ++-
 src/gb.rs                        | 12 ++++++++++++
 src/py.rs                        |  4 ++++
 src/python/boytacean/__init__.py |  3 +++
 5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1aa0d661..a92c0b59 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-*
+* Support for Python 3 API - [#36](https://gitlab.stage.hive.pt/joamag/boytacean/-/issues/36)
+* `next_frame()` method for frame by frame navigation
 
 ### Changed
 
diff --git a/examples/python/pocket.py b/examples/python/pocket.py
index 9fdb09df..3ec7a284 100644
--- a/examples/python/pocket.py
+++ b/examples/python/pocket.py
@@ -3,5 +3,6 @@ import boytacean
 gb = boytacean.GameBoy()
 gb.load()
 gb.load_rom("../../res/roms/demo/pocket.gb")
-gb.clocks(10000000)
+for _ in range(6000):
+    gb.next_frame()
 gb.save_image("pocket.png")
diff --git a/src/gb.rs b/src/gb.rs
index eba01657..e58c612f 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -487,6 +487,18 @@ impl GameBoy {
         cycles
     }
 
+    pub fn next_frame(&mut self) -> u32 {
+        let mut cycles = 0u32;
+        let current_frame = self.ppu_frame();
+        loop {
+            cycles += self.clock() as u32;
+            if self.ppu_frame() != current_frame {
+                break;
+            }
+        }
+        cycles
+    }
+
     pub fn key_press(&mut self, key: PadKey) {
         self.pad().key_press(key);
     }
diff --git a/src/py.rs b/src/py.rs
index d71cab0e..9222bd62 100644
--- a/src/py.rs
+++ b/src/py.rs
@@ -43,6 +43,10 @@ impl GameBoy {
         self.system.clocks(count)
     }
 
+    pub fn next_frame(&mut self) -> u32 {
+        self.system.next_frame()
+    }
+
     pub fn frame_buffer(&mut self, py: Python) -> PyObject {
         let pybytes = PyBytes::new(py, self.system.frame_buffer());
         pybytes.into()
diff --git a/src/python/boytacean/__init__.py b/src/python/boytacean/__init__.py
index 04e22e06..eab8e194 100644
--- a/src/python/boytacean/__init__.py
+++ b/src/python/boytacean/__init__.py
@@ -23,6 +23,9 @@ class GameBoy:
     def clocks(self, count: int) -> int:
         return self._system.clocks(count)
 
+    def next_frame(self) -> int:
+        return self._system.next_frame()
+
     def frame_buffer(self):
         return self._system.frame_buffer()
 
-- 
GitLab