pgfw/pgfw/Game.py

124 lines
4.5 KiB
Python

import os, pygame
from pygame.locals import *
from .Animation import Animation
from .Mainloop import Mainloop
from .Audio import Audio
from .Display import Display
from .Configuration import Configuration
from .Delegate import Delegate
from .Input import Input
from .ScreenGrabber import ScreenGrabber
from .Profile import Profile
from .VideoRecorder import VideoRecorder
from .Interpolator import Interpolator
from .TimeFilter import TimeFilter
from .Sprite import Sprite
from .confirm_quit_message import CONFIRM_QUIT_MESSAGE
from .extension import *
class Game(Animation):
resource_path = None
def __init__(self, config_rel_path=None, type_declarations=None):
self.confirming_quit = False
self.profile = Profile(self)
self.time_filter = TimeFilter(self)
Animation.__init__(self, self)
self.print_debug(pygame.version.ver)
self.config_rel_path = config_rel_path
self.type_declarations = type_declarations
self.set_configuration()
if self.get_configuration("display", "use-framebuffer"):
os.putenv("SDL_FBDEV", "/dev/fb0")
os.putenv("SDL_VIDEODRIVER", "fbcon")
os.putenv("SDL_NOMOUSE", "1")
pygame.init()
self.set_children()
self.register(self.get_input().unsuppress)
self.delegate.enable()
def set_configuration(self):
self.configuration = Configuration(self.config_rel_path,
self.resource_path,
self.type_declarations)
def set_children(self):
self.delegate = Delegate(self)
self.subscribe(self.end, QUIT)
self.subscribe(self.end)
self.display = Display(self)
self.mainloop = Mainloop(self)
self.input = Input(self)
self.audio = Audio(self)
self.screen_grabber = ScreenGrabber(self)
self.video_recorder = VideoRecorder(self)
self.interpolator = Interpolator(self)
def frame(self):
self.time_filter.update()
self.delegate.dispatch()
if not self.interpolator.is_gui_active() and not self.get_audio().is_audio_panel_active():
Animation.update(self)
if self.confirming_quit:
self.time_filter.close()
self.draw_confirm_quit_dialog()
else:
self.time_filter.open()
self.update()
elif self.interpolator.is_gui_active():
self.interpolator.gui.update()
self.audio.update()
if self.video_recorder.requested:
self.video_recorder.update()
def draw_confirm_quit_dialog(self):
dialog = Sprite(self)
dialog.add_frame(self.get_confirm_quit_surface())
dialog.location.center = self.get_display_surface().get_rect().center
dialog.update()
def get_confirm_quit_surface(self):
lines = CONFIRM_QUIT_MESSAGE.strip().split("\n")
w, h = len(lines[0]), len(lines)
text = pygame.Surface((w, h), SRCALPHA)
for y, line in enumerate(lines):
for x, char in enumerate(line.strip()):
if char == "#":
text.set_at((x, y), (0, 0, 0))
text = pygame.transform.scale2x(text)
text = pygame.transform.scale2x(text)
return get_boxed_surface(
text, background=(255, 255, 255), border=(0, 0, 0), border_width=24, padding=12)
def run(self):
self.mainloop.run()
def update(self):
pass
def blit(self, source, destination, area=None, special_flags=0):
self.get_screen().blit(source, destination, area, special_flags)
def get_rect(self):
return self.get_screen().get_rect()
def suppress_input_temporarily(self, length=700):
self.get_input().suppress()
self.play(self.get_input().unsuppress, delay=length, play_once=True)
def end(self, event):
if event.type == QUIT or self.delegate.compare(event, "quit"):
if self.confirming_quit or not self.get_configuration("input", "confirm-quit"):
self.mainloop.stop()
self.profile.end()
else:
print("press quit again to confirm or press any other button to cancel...")
self.confirming_quit = True
elif self.delegate.compare(event, "any"):
if self.confirming_quit and self.delegate.compare(event, "any"):
print("cancelled quit...")
self.confirming_quit = False
self.delegate.cancel_propagation()