aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZoltan Szabatin <[email protected]>2025-05-14 21:36:56 -0700
committerZoltan Szabatin <[email protected]>2025-05-14 21:36:56 -0700
commit70a4c41a75275be6050683191e05ec1cb693ffce (patch)
treeffa5257b21e227e17ab65d0ead0dd2851f22c97e /src
parentswitched from usb hid to cdc (diff)
downloadsplitscreen-duo-main.tar.xz
splitscreen-duo-main.zip
feat: Split updates screen sizeHEADmain
Diffstat (limited to 'src')
-rw-r--r--src/splitscreen_duo/__init__.py5
-rw-r--r--src/splitscreen_duo/games/benchmark.py37
-rw-r--r--src/splitscreen_duo/games/breakout.py26
-rw-r--r--src/splitscreen_duo/games/game_base.py17
-rw-r--r--src/splitscreen_duo/games/pong.py43
-rw-r--r--src/splitscreen_duo/games/snake.py12
-rw-r--r--src/splitscreen_duo/menu.py45
7 files changed, 160 insertions, 25 deletions
diff --git a/src/splitscreen_duo/__init__.py b/src/splitscreen_duo/__init__.py
index defba37..3df7290 100644
--- a/src/splitscreen_duo/__init__.py
+++ b/src/splitscreen_duo/__init__.py
@@ -28,6 +28,7 @@ def main() -> int:
print("The Dual Screen Console")
logger.info(f"running as {os.getenv('INSTANCE', 'unknown')}")
menu.init_display()
+ menu.set_screen_orientation(is_joint_mode[0])
font = pygame.font.Font(None, 36)
BLACK = (0, 0, 0)
@@ -92,10 +93,12 @@ def main() -> int:
if command == Command.ENTER_JOINT_MODE.value:
is_joint_mode[0] = True
+ menu.set_screen_orientation(is_joint_mode[0])
logger.info("secondary entering joint mode")
elif command == Command.EXIT_JOINT_MODE.value:
is_joint_mode[0] = False
+ menu.set_screen_orientation(is_joint_mode[0])
logger.info("secondary exiting joint mode")
elif command == Command.QUIT.value:
pygame.quit()
@@ -167,8 +170,6 @@ def main() -> int:
if result == 0:
return 0
- menu.draw_menu()
-
pygame.quit()
return 0
diff --git a/src/splitscreen_duo/games/benchmark.py b/src/splitscreen_duo/games/benchmark.py
index 3c8ea81..efe48c3 100644
--- a/src/splitscreen_duo/games/benchmark.py
+++ b/src/splitscreen_duo/games/benchmark.py
@@ -18,10 +18,18 @@ class Ball:
def main_loop(screen, serial):
clock = pygame.time.Clock()
+ screen_width = screen.get_width()
+ screen_height = screen.get_height()
+
+ global BALL_SIZE
+
+ BALL_SIZE = max(15, min(25, min(screen_width, screen_height) // 20))
+ is_vertical = screen_height > screen_width * 1.5
ball_list = []
balls = 1
- ball = Ball(screen.get_width(), screen.get_height())
+ ball = Ball(screen_width, screen_height)
is_running = True
+ font = pygame.font.Font(None, 36)
ball_list.append(ball)
@@ -52,11 +60,38 @@ def main_loop(screen, serial):
if ball.x > screen.get_width() - BALL_SIZE or ball.x < BALL_SIZE:
ball.change_x *= -1
+ current_width = screen.get_width()
+ current_height = screen.get_height()
+
+ if current_width != screen_width or current_height != screen_height:
+ screen_width = current_width
+ screen_height = current_height
+ BALL_SIZE = max(15, min(25, min(screen_width, screen_height) // 20))
+ is_vertical = screen_height > screen_width * 1.5
+
+ for b in ball_list:
+ if b.x > screen_width - BALL_SIZE:
+ b.x = screen_width - BALL_SIZE
+
+ if b.y > screen_height - BALL_SIZE:
+ b.y = screen_height - BALL_SIZE
+
screen.fill(BLACK)
for ball in ball_list:
pygame.draw.circle(screen, WHITE, [int(ball.x), int(ball.y)], BALL_SIZE)
+ fps = clock.get_fps()
+ fps_text = font.render(f"FPS: {fps:.1f}", True, WHITE)
+ ball_text = font.render(f"Balls: {balls}", True, WHITE)
+
+ if is_vertical:
+ screen.blit(fps_text, (screen_width // 2 - fps_text.get_width() // 2, 10))
+ screen.blit(ball_text, (screen_width // 2 - ball_text.get_width() // 2, 40))
+ else:
+ screen.blit(fps_text, (10, 10))
+ screen.blit(ball_text, (10, 40))
+
pygame.display.flip()
# clock.tick(60)
clock.tick()
diff --git a/src/splitscreen_duo/games/breakout.py b/src/splitscreen_duo/games/breakout.py
index 3f6aa16..6a5e2cc 100644
--- a/src/splitscreen_duo/games/breakout.py
+++ b/src/splitscreen_duo/games/breakout.py
@@ -23,12 +23,27 @@ logger = logging.getLogger(__name__)
class Breakout(GameBase):
def __init__(self, screen, serial, instance, is_joint_mode=False):
super().__init__(screen, serial, instance, is_joint_mode)
- self.screen_width = screen.get_width()
- self.screen_height = screen.get_height()
-
self.reset()
def reset(self):
+ global PADDLE_WIDTH, PADDLE_HEIGHT, BALL_SIZE, BRICK_WIDTH, BRICK_HEIGHT, BRICK_ROWS, BRICK_COLS, SPEED
+
+ scale_factor = min(self.screen_width / 640, self.screen_height / 480)
+
+ if self.is_vertical:
+ PADDLE_WIDTH = min(100, int(80 * scale_factor))
+ BRICK_COLS = max(5, min(8, int(self.screen_width / 90)))
+ else:
+ PADDLE_WIDTH = min(100, int(100 * scale_factor))
+ BRICK_COLS = max(6, min(10, int(self.screen_width / 90)))
+
+ PADDLE_HEIGHT = max(8, int(10 * scale_factor))
+ BALL_SIZE = max(6, int(10 * scale_factor))
+ BRICK_WIDTH = int((self.screen_width - 20) / BRICK_COLS) - 5
+ BRICK_HEIGHT = max(15, min(30, int(30 * scale_factor)))
+ BRICK_ROWS = max(3, min(5, int(self.screen_height / 120)))
+ SPEED = max(3, min(5, int(5 * scale_factor)))
+
self.paddle = [
self.screen_width // 2 - PADDLE_WIDTH // 2,
self.screen_height - 40,
@@ -163,7 +178,10 @@ class Breakout(GameBase):
if not self.is_joint_mode or self.instance != "primary":
score_text = self.font.render(f"Score: {self.score}", True, WHITE)
- self.screen.blit(score_text, (10, 10))
+ if self.is_vertical:
+ self.screen.blit(score_text, (self.screen_width // 2 - score_text.get_width() // 2, 10))
+ else:
+ self.screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
diff --git a/src/splitscreen_duo/games/game_base.py b/src/splitscreen_duo/games/game_base.py
index 8ef02ec..a539ba0 100644
--- a/src/splitscreen_duo/games/game_base.py
+++ b/src/splitscreen_duo/games/game_base.py
@@ -24,6 +24,9 @@ class GameBase:
self.BLACK = (0, 0, 0)
self.WHITE = (255, 255, 255)
self.input_handler = Input(debug=os.getenv("DEVELOPMENT", "").lower() != "")
+ self.screen_width = screen.get_width()
+ self.screen_height = screen.get_height()
+ self.is_vertical = is_joint_mode
def handle_common_events(self, event):
action = self.input_handler.get_input(event)
@@ -93,7 +96,21 @@ class GameBase:
+ b"\n"
)
+ def update_screen_dimensions(self):
+ current_width = self.screen.get_width()
+ current_height = self.screen.get_height()
+
+ if (current_width != self.screen_width or current_height != self.screen_height):
+ self.screen_width = current_width
+ self.screen_height = current_height
+ self.is_vertical = current_height > current_width * 1.5
+
+ self.reset()
+ logger.debug(f"screen dimensions updated: {self.screen_width}x{self.screen_height}, vertical: {self.is_vertical}")
+
def update(self):
+ self.update_screen_dimensions()
+
if self.is_joint_mode:
return None
diff --git a/src/splitscreen_duo/games/pong.py b/src/splitscreen_duo/games/pong.py
index 0c0df84..d82cdc7 100644
--- a/src/splitscreen_duo/games/pong.py
+++ b/src/splitscreen_duo/games/pong.py
@@ -19,8 +19,7 @@ logger = logging.getLogger(__name__)
class Pong(GameBase):
def __init__(self, screen, serial, instance, is_joint_mode=False):
super().__init__(screen, serial, instance, is_joint_mode)
- self.screen_width = screen.get_width()
- self.screen_height = screen.get_height()
+
self.player_score = 0
self.ai_score = 0
self.score_display_time = 0
@@ -28,6 +27,22 @@ class Pong(GameBase):
self.reset()
def reset(self):
+ global PADDLE_WIDTH, PADDLE_HEIGHT, BALL_SIZE, PADDLE_SPEED, AI_SPEED, BALL_SPEED
+
+ scale_factor = min(self.screen_width / 640, self.screen_height / 480)
+
+ if self.is_vertical:
+ PADDLE_WIDTH = min(100, int(80 * scale_factor))
+ PADDLE_SPEED = max(5, min(8, int(8 * scale_factor)))
+ else:
+ PADDLE_WIDTH = min(100, int(100 * scale_factor))
+ PADDLE_SPEED = max(8, min(10, int(10 * scale_factor)))
+
+ PADDLE_HEIGHT = max(8, int(10 * scale_factor))
+ BALL_SIZE = max(6, int(10 * scale_factor))
+ AI_SPEED = max(3, min(4, int(4 * scale_factor)))
+ BALL_SPEED = max(4, min(5, int(5 * scale_factor)))
+
self.player_paddle = [
self.screen_width // 2 - PADDLE_WIDTH // 2,
self.screen_height - 40,
@@ -113,6 +128,8 @@ class Pong(GameBase):
return None
def update(self):
+ self.update_screen_dimensions()
+
if self.score_display_time:
self.screen.fill(BLACK)
@@ -122,26 +139,27 @@ class Pong(GameBase):
f"Your Score: {self.player_score}", True, WHITE
)
ai_score_text = self.font.render(f"AI Score: {self.ai_score}", True, WHITE)
+ vertical_spacing = 30 if self.is_vertical else 20
self.screen.blit(
result_display,
(
self.screen_width // 2 - result_display.get_width() // 2,
- self.screen_height // 2 - 40,
+ self.screen_height // 2 - vertical_spacing * 2,
),
)
self.screen.blit(
player_score_text,
(
self.screen_width // 2 - player_score_text.get_width() // 2,
- self.screen_height // 2 - 20,
+ self.screen_height // 2,
),
)
self.screen.blit(
ai_score_text,
(
self.screen_width // 2 - ai_score_text.get_width() // 2,
- self.screen_height // 2 + 20,
+ self.screen_height // 2 + vertical_spacing,
),
)
pygame.display.flip()
@@ -226,8 +244,19 @@ class Pong(GameBase):
f"AI: {self.ai_score}", True, WHITE
)
- self.screen.blit(player_score_text, (10, self.screen_height - 40))
- self.screen.blit(ai_score_text, (10, 10))
+ if self.is_vertical:
+ self.screen.blit(
+ player_score_text,
+ (self.screen_width // 2 - player_score_text.get_width() // 2,
+ self.screen_height - 40)
+ )
+ self.screen.blit(
+ ai_score_text,
+ (self.screen_width // 2 - ai_score_text.get_width() // 2, 10)
+ )
+ else:
+ self.screen.blit(player_score_text, (10, self.screen_height - 40))
+ self.screen.blit(ai_score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
diff --git a/src/splitscreen_duo/games/snake.py b/src/splitscreen_duo/games/snake.py
index 83ee987..11b66f7 100644
--- a/src/splitscreen_duo/games/snake.py
+++ b/src/splitscreen_duo/games/snake.py
@@ -17,12 +17,15 @@ logger = logging.getLogger(__name__)
class Snake(GameBase):
def __init__(self, screen, serial, instance, is_joint_mode=False):
super().__init__(screen, serial, instance, is_joint_mode)
- self.screen_width = screen.get_width()
- self.screen_height = screen.get_height()
self.reset()
def reset(self):
+ global BLOCK_SIZE, SPEED
+
+ min_dimension = min(self.screen_width, self.screen_height)
+ BLOCK_SIZE = max(10, min(20, min_dimension // 30))
+ SPEED = 15 if self.screen_width >= 400 else 12
self.body = [
[
self.screen_width // 2 - self.screen_width // 2 % BLOCK_SIZE,
@@ -143,7 +146,10 @@ class Snake(GameBase):
if not self.is_joint_mode or self.instance != "primary":
score_text = self.font.render(f"Score: {self.score}", True, WHITE)
- self.screen.blit(score_text, (10, 10))
+ if self.is_vertical:
+ self.screen.blit(score_text, (self.screen_width // 2 - score_text.get_width() // 2, 10))
+ else:
+ self.screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(SPEED)
diff --git a/src/splitscreen_duo/menu.py b/src/splitscreen_duo/menu.py
index 18dcca6..bd292e7 100644
--- a/src/splitscreen_duo/menu.py
+++ b/src/splitscreen_duo/menu.py
@@ -13,15 +13,15 @@ IS_DEVELOPMENT_MODE = os.getenv("DEVELOPMENT", "").lower() != ""
OPTIONS = Game.all() + ["Quit"]
logger = logging.getLogger(__name__)
WIDTH = HEIGHT = FONT = screen = selected_index = None
+ORIGINAL_WIDTH = ORIGINAL_HEIGHT = None
def init_display():
- global WIDTH, HEIGHT, FONT, screen, selected_index
+ global WIDTH, HEIGHT, FONT, screen, selected_index, ORIGINAL_WIDTH, ORIGINAL_HEIGHT
- WIDTH, HEIGHT = (
- pygame.display.Info().current_w // 2,
- pygame.display.Info().current_h // 2,
- )
+ ORIGINAL_WIDTH = pygame.display.Info().current_w // 2
+ ORIGINAL_HEIGHT = pygame.display.Info().current_h // 2
+ WIDTH, HEIGHT = ORIGINAL_WIDTH, ORIGINAL_HEIGHT
FONT = pygame.font.Font(None, 36)
screen = pygame.display.set_mode(
(WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0),
@@ -30,17 +30,41 @@ def init_display():
selected_index = 0
-def draw_menu():
+def draw_menu(is_joint_mode=False):
screen.fill(WHITE)
+ is_vertical = HEIGHT > WIDTH * 1.5
+ start_y = 100 if is_vertical else 150
+ spacing = 40 if is_vertical else 50
+ title_text = FONT.render("SplitScreen Duo", True, BLACK)
+
+ screen.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, start_y - 50))
+
for i, option in enumerate(OPTIONS):
text = FONT.render(option, True, BLACK if i != selected_index else (200, 0, 0))
- screen.blit(text, (WIDTH // 2 - text.get_width() // 2, 150 + i * 50))
+ screen.blit(text, (WIDTH // 2 - text.get_width() // 2, start_y + i * spacing))
pygame.display.flip()
+def set_screen_orientation(is_joint_mode):
+ global WIDTH, HEIGHT, screen, ORIGINAL_WIDTH, ORIGINAL_HEIGHT
+
+ if is_joint_mode:
+ WIDTH = ORIGINAL_WIDTH
+ HEIGHT = ORIGINAL_HEIGHT * 2
+ else:
+ WIDTH = ORIGINAL_WIDTH
+ HEIGHT = ORIGINAL_HEIGHT
+
+ screen = pygame.display.set_mode(
+ (WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0),
+ pygame.RESIZABLE if IS_DEVELOPMENT_MODE else pygame.FULLSCREEN,
+ )
+
+ logger.info(f"screen orientation changed to {'vertical' if is_joint_mode else 'horizontal'}")
+
def process_events(serial, instance, is_joint_mode):
global selected_index
@@ -84,7 +108,10 @@ def process_events(serial, instance, is_joint_mode):
):
is_joint_mode[0] = not is_joint_mode[0]
- logger.info(f"Toggled joint mode to {is_joint_mode[0]}")
+ if instance == "primary":
+ set_screen_orientation(is_joint_mode[0])
+
+ logger.info(f"toggled joint mode to {is_joint_mode[0]}")
command = (
Command.ENTER_JOINT_MODE.value
@@ -94,4 +121,6 @@ def process_events(serial, instance, is_joint_mode):
serial.write(json.dumps({"command": command}).encode("utf-8"))
+ draw_menu(is_joint_mode[0] if isinstance(is_joint_mode, list) else is_joint_mode)
+
return None