Commit 28b0a29a authored by talljosh's avatar talljosh

If pygame 2 is installed, and you're using a 4k monitor, enable scaling mode.

parent 223d5cb441de
......@@ -188,6 +188,8 @@ class PygameRunnerAPI(Protocol):
coroutine: Callable[[], Awaitable[T]],
size: Optional[Tuple[int, int]] = None,
full_screen: Optional[bool] = None,
scaled: Optional[bool] = None,
*,
target_frame_rate: float = 60,
hide_qt: bool = True,
) -> T:
......@@ -208,6 +210,9 @@ class PygameRunnerAPI(Protocol):
will be shown in full-screen mode. Note that if full_screen
is True and size is not a supported full-screen size, a
suitable size will be automatically chosen.
:param scaled: If provided, controls whether the window will be
scaled to be visible on higher resolution monitors. May have
no effect if full_screen is True.
:param target_frame_rate: This value controls the length of
delay between each frame of the event loop. Expressed in
units of frames per second.
......@@ -222,8 +227,12 @@ class PygameRunnerAPI(Protocol):
raise NotImplementedError
def resize_window(
self, window_size: Tuple[int, int], full_screen: Optional[bool] = None,
from_event=False) -> None:
self,
window_size: Tuple[int, int],
full_screen: Optional[bool] = None,
scaled: Optional[bool] = None,
from_event=False,
) -> None:
'''
Resizes the currently showing Pygame window.
......@@ -231,6 +240,8 @@ class PygameRunnerAPI(Protocol):
:param full_screen: If provided, controls whether the window
will be shown in full-screen mode. If not provided, the
current value will be used.
:param scaled: If provided, controls whether the window will be
scaled to be visible on higher resolution monutors.
:param from_event: Should be True iff this call is in response
to a VIDEORESIZE event.
:raises:
......@@ -241,9 +252,10 @@ class PygameRunnerAPI(Protocol):
def launch_application(
self,
coroutine: Callable[[], Awaitable[T]],
*,
size: Tuple[int, int],
full_screen: bool,
scaled: bool,
*,
target_frame_rate: float = 60,
) -> T:
'''
......@@ -260,6 +272,9 @@ class PygameRunnerAPI(Protocol):
full-screen mode. Note that if full_screen is true and size
is not a supported full-screen size, a suitable size will be
automatically chosen.
:param scaled: controls whether the window will be scaled to be
visible on higher resolution monitors. May have no effect
if full_screen is True.
:param target_frame_rate: This value controls the length of
delay between each frame of the event loop. Expressed in
units of frames per second.
......@@ -278,6 +293,7 @@ class PygameRunner(PygameRunnerAPI):
def __init__(self):
self.full_screen_requested = False
self.last_screen_size = (800, 600)
self.scaled_requested = False
self.on_resize = Event([])
self.on_tick = Event(['delta_t'])
self.on_pygame_event = Event(['event'])
......@@ -300,25 +316,36 @@ class PygameRunner(PygameRunnerAPI):
return surface.get_size()
def resize_window(
self, window_size: Tuple[int, int], full_screen: Optional[bool] = None,
from_event=False) -> None:
self,
window_size: Tuple[int, int],
full_screen: Optional[bool] = None,
scaled: Optional[bool] = None,
from_event=False,
) -> None:
if not self.is_showing():
raise PygameWindowNotOpen('No pygame window currently open')
if full_screen is None:
full_screen = self.full_screen_requested
self.set_display_mode(window_size, full_screen, from_event=from_event)
if scaled is None:
scaled = self.scaled_requested
self.set_display_mode(window_size, full_screen, scaled, from_event=from_event)
self.on_resize()
def set_display_mode(self, size, full_screen, from_event=False):
def set_display_mode(self, size, full_screen, scaled=False, from_event=False):
if pygame.vernum[0] >= 2 and from_event:
self.last_screen_size = size
self.full_screen_requested = full_screen
if size == self.last_screen_size and full_screen == self.full_screen_requested:
if self.is_showing():
return
self.scaled_requested = scaled
if (
size == self.last_screen_size and
full_screen == self.full_screen_requested and
scaled == self.scaled_requested and
self.is_showing()):
return
self.last_screen_size = size
self.full_screen_requested = full_screen
self.scaled_requested = scaled
kwargs = {}
if full_screen:
......@@ -330,6 +357,9 @@ class PygameRunner(PygameRunnerAPI):
# Ask for vertical sync if possible
kwargs['vsync'] = True
if scaled and not full_screen:
flags |= pygame.SCALED
pygame.display.init()
self.set_default_icon()
return pygame.display.set_mode(size, flags, **kwargs)
......@@ -343,9 +373,15 @@ class PygameRunner(PygameRunnerAPI):
pygame.display.set_icon(icon)
async def show_window(
self, coroutine: Callable[[], Awaitable[T]], size: Optional[Tuple[int, int]] = None,
full_screen: Optional[bool] = None, target_frame_rate: float = 60,
hide_qt: bool = True) -> T:
self,
coroutine: Callable[[], Awaitable[T]],
size: Optional[Tuple[int, int]] = None,
full_screen: Optional[bool] = None,
scaled: Optional[bool] = None,
*,
target_frame_rate: float = 60,
hide_qt: bool = True
) -> T:
if self.is_showing():
raise PygameWindowAlreadyOpen('Pygame window is already showing')
......@@ -354,7 +390,9 @@ class PygameRunner(PygameRunnerAPI):
size = self.last_screen_size
if full_screen is None:
full_screen = self.full_screen_requested
screen = self.set_display_mode(size, full_screen)
if scaled is None:
scaled = self.scaled_requested
screen = self.set_display_mode(size, full_screen, scaled)
try:
if hide_qt:
......@@ -416,13 +454,20 @@ class PygameRunner(PygameRunnerAPI):
await asyncio.sleep(max(0.001, target_frame_interval - processing_time))
def launch_application(
self, coroutine: Callable[[], Awaitable[T]], *,
size: Tuple[int, int], full_screen: bool, target_frame_rate: float = 60) -> T:
self,
coroutine: Callable[[],
Awaitable[T]],
size: Tuple[int, int],
full_screen: bool,
scaled: bool,
*,
target_frame_rate: float = 60,
) -> T:
pygame.init()
pygame.display.init()
try:
return run_async_main_function(functools.partial(
self.show_window, coroutine, size=size, full_screen=full_screen,
self.show_window, coroutine, size, full_screen, scaled,
target_frame_rate=target_frame_rate, hide_qt=False))
finally:
pygame.quit()
......
......@@ -123,7 +123,7 @@ class TrosnothAppEventListener:
def apply_display_settings(self):
display_settings = self.app.settings.display
get_pygame_runner().resize_window(*display_settings.get_size_and_full_screen())
get_pygame_runner().resize_window(*display_settings.get_video_parameters())
class TrosnothApp(MultiWindowApplication):
......
......@@ -28,13 +28,12 @@ class SoloGameClosed(Exception):
def launch_solo_game(**kwargs):
with new_console_context():
size, full_screen = ClientSettings.get().display.get_size_and_full_screen()
params = ClientSettings.get().display.get_video_parameters()
try:
get_pygame_runner().launch_application(
functools.partial(
launch_solo_game_async, return_when_level_completes=False, **kwargs),
size=size,
full_screen=full_screen,
*params,
)
except (UserClosedPygameWindow, SoloGameClosed):
pass
......
......@@ -223,12 +223,12 @@ class DisplaySettings(SettingsBase):
self._force_windowed = True
try:
if pygame_runner.is_showing() and pygame_runner.is_full_screen():
pygame_runner.resize_window(*self.get_size_and_full_screen())
pygame_runner.resize_window(*self.get_video_parameters())
yield
finally:
self._force_windowed = already_forced
if pygame_runner.is_showing():
pygame_runner.resize_window(*self.get_size_and_full_screen())
pygame_runner.resize_window(*self.get_video_parameters())
def parse_size_string(self, size_string):
if size_string and 'x' in size_string:
......@@ -256,16 +256,31 @@ class DisplaySettings(SettingsBase):
self.data['show_timings'] = str(self.show_timings)
self.data['show_range'] = str(self.show_range)
def get_size_and_full_screen(self):
def get_video_parameters(self):
if self.full_screen and not self._force_windowed:
allowed_modes = self.get_available_resolutions()
if self.full_screen_size not in allowed_modes:
return max(allowed_modes), True
return self.full_screen_size, True
return max(allowed_modes), True, False
return self.full_screen_size, True, False
if self.size == (0, 0):
self.size = (1000, 750)
return self.size, False
# For high resolution monitors, just give a scaled window
if pygame.vernum[0] > 1:
display_width = 0 # Unknown
pygame.display.init()
if pygame.display.get_surface():
modes = pygame.display.list_modes()
if modes != -1 and modes:
display_width = modes[0][0]
else:
display_width = pygame.display.Info().current_w
if display_width > 2000:
return (1920, 1200), False, True
return self.size, False, False
def get_available_resolutions(self):
pygame.display.init()
......
......@@ -211,11 +211,10 @@ def run_in_pygame(fn):
return await fn(*args, **kwargs)
from trosnoth.settings import ClientSettings
size, full_screen = ClientSettings.get().display.get_size_and_full_screen()
params = ClientSettings.get().display.get_video_parameters()
return await pygame_runner.show_window(
functools.partial(fn, *args, **kwargs),
size=size,
full_screen=full_screen,
*params,
)
return wrapper
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment