Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
8 changes: 4 additions & 4 deletions pyboy/plugins/game_wrapper_pokemon_pinball.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ cdef class GameWrapperPokemonPinball(PyBoyGameWrapper):
cdef readonly int ball_saver_seconds_left
cdef readonly int ball_size
cdef readonly int ball_type
cdef readonly int ball_x
cdef readonly int ball_x_velocity
cdef readonly int ball_y
cdef readonly int ball_y_velocity
cdef readonly float ball_x
cdef readonly float ball_x_velocity
cdef readonly float ball_y
cdef readonly float ball_y_velocity
cdef readonly int balls_left
cdef readonly int current_map
cdef readonly int current_stage
Expand Down
29 changes: 23 additions & 6 deletions pyboy/plugins/game_wrapper_pokemon_pinball.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import logging
from enum import Enum

from pyboy.utils import PyBoyException, WindowEvent, bcd_to_dec
from pyboy.utils import PyBoyException, WindowEvent, bcd_to_dec, fixed_point_to_value

from .base_plugin import PyBoyGameWrapper

Expand Down Expand Up @@ -695,11 +695,28 @@ def post_tick(self):
self.multiplier = self.pyboy.memory[ADDR_MULTIPLIER]

self.ball_size = self.pyboy.memory[ADDR_BALL_SIZE]

self.ball_x = self.pyboy.memory[ADDR_BALL_X]
self.ball_y = self.pyboy.memory[ADDR_BALL_Y]
self.ball_x_velocity = self.pyboy.memory[ADDR_BALL_X_VELOCITY]
self.ball_y_velocity = self.pyboy.memory[ADDR_BALL_Y_VELOCITY]
self.ball_x = fixed_point_to_value(
self.pyboy.memory[ADDR_BALL_X:ADDR_BALL_X+2],
num_bytes=2,
is_signed=True
)
self.ball_y = fixed_point_to_value(
self.pyboy.memory[ADDR_BALL_Y:ADDR_BALL_Y+2],
num_bytes=2,
is_signed=True
)

# Velocity values (likely signed since they can be negative)
self.ball_x_velocity = fixed_point_to_value(
self.pyboy.memory[ADDR_BALL_X_VELOCITY:ADDR_BALL_X_VELOCITY+2],
num_bytes=2,
is_signed=True
)
self.ball_y_velocity = fixed_point_to_value(
self.pyboy.memory[ADDR_BALL_Y_VELOCITY:ADDR_BALL_Y_VELOCITY+2],
num_bytes=2,
is_signed=True
)

self.pikachu_saver_charge = self.pyboy.memory[ADDR_PIKACHU_SAVER_CHARGE]

Expand Down
33 changes: 33 additions & 0 deletions pyboy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,36 @@ def bcd_to_dec(value, byte_width=1, byteorder="little"):
multiplier *= 100

return decimal_value

def fixed_point_to_value(raw_bytes, num_bytes=2, is_signed=False, fractional_bits=8):
"""
Convert fixed-point bytes to appropriate value

Args:
raw_bytes: Byte array containing the fixed-point value
num_bytes: Number of bytes in the value (default: 2 for 16-bit)
is_signed: Whether to interpret as signed (two's complement)
fractional_bits: Number of bits used for the fractional part

Returns:
A float value representing the fixed-point number
"""
value = int.from_bytes(raw_bytes, "little")

total_bits = num_bytes * 8
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you deduce the num_bytes from the length of raw_bytes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes you absolutely can, i think ive been writing too much c lately. ill fix it in the morning, i thnk i still have 1 other small edit i wanna work in this pr, going to make it a draft for now i think


# Calculate integer and fractional parts
integer_part = value >> fractional_bits
fractional_part = value & ((1 << fractional_bits) - 1)

# Handle two's complement for signed values
if is_signed and (value & (1 << (total_bits - 1))):
# It's a negative value in two's complement
# Calculate the negative value properly
integer_value = value
if integer_value & (1 << (total_bits - 1)):
integer_value = -((~integer_value + 1) & ((1 << total_bits) - 1))
return integer_value / (1 << fractional_bits)

# Return the full fixed-point value
return integer_part + (fractional_part / (1 << fractional_bits))
Loading