Skip to content

Commit e13f80c

Browse files
committed
fix coordinate system interpretation
1 parent 08b4943 commit e13f80c

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

pyboy/plugins/game_wrapper_pokemon_pinball.pxd

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ cdef class GameWrapperPokemonPinball(PyBoyGameWrapper):
1010
cdef readonly int ball_saver_seconds_left
1111
cdef readonly int ball_size
1212
cdef readonly int ball_type
13-
cdef readonly int ball_x
14-
cdef readonly int ball_x_velocity
15-
cdef readonly int ball_y
16-
cdef readonly int ball_y_velocity
13+
cdef readonly float ball_x
14+
cdef readonly float ball_x_velocity
15+
cdef readonly float ball_y
16+
cdef readonly float ball_y_velocity
1717
cdef readonly int balls_left
1818
cdef readonly int current_map
1919
cdef readonly int current_stage

pyboy/plugins/game_wrapper_pokemon_pinball.py

+23-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import logging
1313
from enum import Enum
1414

15-
from pyboy.utils import PyBoyException, WindowEvent, bcd_to_dec
15+
from pyboy.utils import PyBoyException, WindowEvent, bcd_to_dec, fixed_point_to_value
1616

1717
from .base_plugin import PyBoyGameWrapper
1818

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

697697
self.ball_size = self.pyboy.memory[ADDR_BALL_SIZE]
698-
699-
self.ball_x = self.pyboy.memory[ADDR_BALL_X]
700-
self.ball_y = self.pyboy.memory[ADDR_BALL_Y]
701-
self.ball_x_velocity = self.pyboy.memory[ADDR_BALL_X_VELOCITY]
702-
self.ball_y_velocity = self.pyboy.memory[ADDR_BALL_Y_VELOCITY]
698+
self.ball_x = fixed_point_to_value(
699+
self.pyboy.memory[ADDR_BALL_X:ADDR_BALL_X+2],
700+
num_bytes=2,
701+
is_signed=True
702+
)
703+
self.ball_y = fixed_point_to_value(
704+
self.pyboy.memory[ADDR_BALL_Y:ADDR_BALL_Y+2],
705+
num_bytes=2,
706+
is_signed=True
707+
)
708+
709+
# Velocity values (likely signed since they can be negative)
710+
self.ball_x_velocity = fixed_point_to_value(
711+
self.pyboy.memory[ADDR_BALL_X_VELOCITY:ADDR_BALL_X_VELOCITY+2],
712+
num_bytes=2,
713+
is_signed=True
714+
)
715+
self.ball_y_velocity = fixed_point_to_value(
716+
self.pyboy.memory[ADDR_BALL_Y_VELOCITY:ADDR_BALL_Y_VELOCITY+2],
717+
num_bytes=2,
718+
is_signed=True
719+
)
703720

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

pyboy/utils.py

+33
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,36 @@ def bcd_to_dec(value, byte_width=1, byteorder="little"):
488488
multiplier *= 100
489489

490490
return decimal_value
491+
492+
def fixed_point_to_value(raw_bytes, num_bytes=2, is_signed=False, fractional_bits=8):
493+
"""
494+
Convert fixed-point bytes to appropriate value
495+
496+
Args:
497+
raw_bytes: Byte array containing the fixed-point value
498+
num_bytes: Number of bytes in the value (default: 2 for 16-bit)
499+
is_signed: Whether to interpret as signed (two's complement)
500+
fractional_bits: Number of bits used for the fractional part
501+
502+
Returns:
503+
A float value representing the fixed-point number
504+
"""
505+
value = int.from_bytes(raw_bytes, "little")
506+
507+
total_bits = num_bytes * 8
508+
509+
# Calculate integer and fractional parts
510+
integer_part = value >> fractional_bits
511+
fractional_part = value & ((1 << fractional_bits) - 1)
512+
513+
# Handle two's complement for signed values
514+
if is_signed and (value & (1 << (total_bits - 1))):
515+
# It's a negative value in two's complement
516+
# Calculate the negative value properly
517+
integer_value = value
518+
if integer_value & (1 << (total_bits - 1)):
519+
integer_value = -((~integer_value + 1) & ((1 << total_bits) - 1))
520+
return integer_value / (1 << fractional_bits)
521+
522+
# Return the full fixed-point value
523+
return integer_part + (fractional_part / (1 << fractional_bits))

0 commit comments

Comments
 (0)