ibitfit/electric_sieve/pgfw/Mainloop.py

109 lines
3.9 KiB
Python

from pygame import display
from pygame.font import Font
from pygame.time import get_ticks, wait
from GameChild import GameChild
class Mainloop(GameChild):
def __init__(self, parent):
GameChild.__init__(self, parent)
self.overflow = 0
self.frame_count = 1
self.actual_frame_duration = 0
self.frames_this_second = 0
self.last_framerate_display = 0
self.load_configuration()
self.init_framerate_display()
self.last_ticks = get_ticks()
self.stopping = False
def load_configuration(self):
config = self.get_configuration("display")
self.target_frame_duration = config["frame-duration"]
self.wait_duration = config["wait-duration"]
self.skip_frames = config["skip-frames"]
self.show_framerate = config["show-framerate"]
self.framerate_text_size = config["framerate-text-size"]
self.framerate_text_color = config["framerate-text-color"]
self.framerate_text_background = config["framerate-text-background"]
self.framerate_display_flag = config["framerate-display-flag"]
def init_framerate_display(self):
if self.framerate_display_active():
screen = self.get_screen()
self.last_framerate_count = 0
self.framerate_topright = screen.get_rect().topright
self.display_surface = screen
self.font = Font(None, self.framerate_text_size)
self.font.set_bold(True)
self.render_framerate()
def framerate_display_active(self):
return self.check_command_line(self.framerate_display_flag) or \
self.show_framerate
def render_framerate(self):
text = self.font.render(str(self.last_framerate_count), False,
self.framerate_text_color,
self.framerate_text_background)
rect = text.get_rect()
rect.topright = self.framerate_topright
self.framerate_text = text
self.framerate_text_rect = rect
def run(self):
while not self.stopping:
self.advance_frame()
self.update_frame_duration()
self.update_overflow()
self.stopping = False
def advance_frame(self):
refresh = False
while self.frame_count > 0:
refresh = True
self.parent.frame()
if self.framerate_display_active():
self.update_framerate()
self.frame_count -= 1
if not self.skip_frames:
break
if refresh:
display.update()
def update_frame_duration(self):
last_ticks = self.last_ticks
actual_frame_duration = get_ticks() - last_ticks
last_ticks = get_ticks()
while actual_frame_duration < self.target_frame_duration:
wait(self.wait_duration)
actual_frame_duration += get_ticks() - last_ticks
last_ticks = get_ticks()
self.actual_frame_duration = actual_frame_duration
self.last_ticks = last_ticks
def update_overflow(self):
self.frame_count = 1
target_frame_duration = self.target_frame_duration
overflow = self.overflow
overflow += self.actual_frame_duration - target_frame_duration
while overflow > target_frame_duration:
self.frame_count += 1
overflow -= target_frame_duration
overflow = self.overflow
def update_framerate(self):
count = self.frames_this_second + 1
if get_ticks() - self.last_framerate_display > 1000:
if count != self.last_framerate_count:
self.last_framerate_count = count
self.render_framerate()
self.last_framerate_display = get_ticks()
count = 0
self.display_surface.blit(self.framerate_text, self.framerate_text_rect)
self.frames_this_second = count
def stop(self):
self.stopping = True