Clean up for git storage

Add shebang
dos2unix - This is primary a Windows tool, so oops
This commit is contained in:
Trysdyn Black 2018-09-26 18:46:24 -07:00
parent a5463094e2
commit 9ac2bf04dc

446
main.pyw Normal file → Executable file
View file

@ -1,222 +1,224 @@
import json
import os
import sys
import pygame
import time
class Visualizer:
def __init__(self, profile):
# Change to script dir to allow loading of configs relative to script
if getattr(sys, 'frozen', False):
# The application is frozen, figure out the path of the EXE
pathname = os.path.dirname(sys.executable)
else:
# The application is not frozen, get PWD
pathname = os.path.dirname(__file__)
if pathname:
os.chdir(pathname)
# Load config
self.config = self.load_config(profile)["profile"]
# initialize the screen
self.win_size = self.config["size"]
pygame.init()
self.screen = pygame.display.set_mode(self.config["size"], pygame.RESIZABLE)
pygame.display.set_caption("SRTK Gamepad Visualizer: %s" % profile)
# Load and prep the background
background_file = os.path.join("profiles", profile, self.config["background_image"])
self.background = pygame.image.load(background_file).convert_alpha()
# Create the buffer image to draw on, set to the size of the background image
self.buffer = pygame.surface.Surface(self.background.get_size())
# Create the font
self.text_font = pygame.font.SysFont(self.config["font_face"], self.config["font_size"])
self.font_color = self.config["font_color"]
self.text_pos = self.config["text_pos"]
# APS counter
self.actions = []
self.aps_min = self.config["aps_minimum"]
self.aps = 0
self.aps_throttle = 3
# Set up our inputs
# Inputs are defined as key = (light position, light surface object)
self.active_inputs = set()
self.last_inputs = set()
self.inputs = {}
inputs = self.config["inputs"]
for i in inputs:
if "enabled" in inputs[i] and not inputs[i]["enabled"]:
continue
pos = inputs[i]["pos"]
size = inputs[i]["size"]
color = inputs[i]["color"] if "color" in inputs[i] else self.config["default_color"]
img = pygame.Surface(size)
img.fill(color)
try:
i = int(i)
except:
pass
self.inputs[i] = (pos, img)
def load_config(self, profile):
infile_name = os.path.join("profiles", profile, "config.txt")
infile = open(infile_name, "r")
config = json.load(infile)
return config
def button_down(self, button_id):
self.active_inputs.add(button_id)
self.actions.append(time.time())
def button_up(self, button_id):
try:
self.active_inputs.remove(button_id)
except:
pass
def axis_change(self, axis, value):
if value > 0.1:
self.active_inputs.add("A%dP" % axis)
elif value < -0.1:
self.active_inputs.add("A%dM" % axis)
else:
for a in ["A%dM" % axis, "A%dP" % axis]:
try:
self.active_inputs.remove(a)
except:
pass
def hat_change(self, hat, value):
# H0U, H0D, H0L, H0R
if value[0] < 0:
self.active_inputs.add("H%dL" % hat)
elif value[0] > 0:
self.active_inputs.add("H%dR" % hat)
else:
for a in ["H%dL" % hat, "H%dR" % hat]:
try:
self.active_inputs.remove(a)
except:
pass
if value[1] < 0:
self.active_inputs.add("H%dD" % hat)
elif value[1] > 0:
self.active_inputs.add("H%dU" % hat)
else:
for a in ["H%dU" % hat, "H%dD" % hat]:
try:
self.active_inputs.remove(a)
except:
pass
def update(self):
"""
Handles screen drawing. Blits images to a buffer image, resizes the
buffer to the size of the screen, then blits the buffer to the screen.
"""
if self.active_inputs == self.last_inputs:
return None
self.last_inputs = set(self.active_inputs)
buf = self.buffer
screen = self.screen
# Blank the buffer, draw the button hilights
buf.fill(self.config["background_color"])
for i in self.active_inputs:
try:
loc, img = self.inputs[i]
buf.blit(img, loc)
except KeyError:
pass
# Draw the background overtop as a mask
buf.blit(self.background, (0, 0))
# Draw APS
# Throttle keeps us from "Vibrating number syndrome"
self.aps_throttle -= 1
if self.aps_throttle < 1:
self.aps_throttle = 3
# Only score APS off the last 30 actions and last 5s
while self.actions and self.actions[0] < (time.time() - 5):
self.actions.pop(0)
if len(self.actions) > 30:
self.actions = self.actions[-30:]
# Time from last action to current time, to get APS
# We want at least 5 actions before we consider drawing APS
if len(self.actions) > 5:
aps_len = time.time() - self.actions[0] + 0.01
self.aps = len(self.actions) / aps_len
else:
self.aps = 0
# We only care about APS if we're mashing, so only draw it if it's over aps_min
if self.aps > self.aps_min:
aps_surf = self.text_font.render("%0.1f" % self.aps, 1, self.font_color)
buf.blit(aps_surf, self.config["text_pos"])
# Scale the buffer to the screen size if necessary
if buf.get_size() != screen.get_size():
buf = pygame.transform.scale(buf, screen.get_size())
# Blit buffer to screen
screen.blit(buf, (0, 0))
pygame.display.flip()
if __name__ == "__main__":
# Read in a profile name from commandline
if len(sys.argv) == 2:
profile = sys.argv[1]
else:
profile = "universal"
# Initialize all our joysticks so we get the one we want
# Since this is a one-player app, this should be fine...
pygame.joystick.init()
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
for joy in joysticks:
joy.init()
# Initialize our visualizer context
vis = Visualizer(profile)
quit = False
while not quit:
# Note that we wait for pygame events before doing any redraws
# This limits redraws to when button states change, normally
event = pygame.event.wait()
if event.type == pygame.VIDEORESIZE:
vis.win_size = (event.w, event.h)
vis.screen = pygame.display.set_mode(vis.win_size, pygame.RESIZABLE)
elif event.type == pygame.QUIT:
quit = True
elif event.type == pygame.JOYBUTTONDOWN:
vis.button_down(event.button)
elif event.type == pygame.JOYBUTTONUP:
vis.button_up(event.button)
elif event.type == pygame.JOYAXISMOTION:
vis.axis_change(event.axis, event.value)
elif event.type == pygame.JOYHATMOTION:
vis.hat_change(event.hat, event.value)
vis.update()
#!/usr/bin/env python
import json
import os
import sys
import pygame
import time
class Visualizer:
def __init__(self, profile):
# Change to script dir to allow loading of configs relative to script
if getattr(sys, 'frozen', False):
# The application is frozen, figure out the path of the EXE
pathname = os.path.dirname(sys.executable)
else:
# The application is not frozen, get PWD
pathname = os.path.dirname(__file__)
if pathname:
os.chdir(pathname)
# Load config
self.config = self.load_config(profile)["profile"]
# initialize the screen
self.win_size = self.config["size"]
pygame.init()
self.screen = pygame.display.set_mode(self.config["size"], pygame.RESIZABLE)
pygame.display.set_caption("SRTK Gamepad Visualizer: %s" % profile)
# Load and prep the background
background_file = os.path.join("profiles", profile, self.config["background_image"])
self.background = pygame.image.load(background_file).convert_alpha()
# Create the buffer image to draw on, set to the size of the background image
self.buffer = pygame.surface.Surface(self.background.get_size())
# Create the font
self.text_font = pygame.font.SysFont(self.config["font_face"], self.config["font_size"])
self.font_color = self.config["font_color"]
self.text_pos = self.config["text_pos"]
# APS counter
self.actions = []
self.aps_min = self.config["aps_minimum"]
self.aps = 0
self.aps_throttle = 3
# Set up our inputs
# Inputs are defined as key = (light position, light surface object)
self.active_inputs = set()
self.last_inputs = set()
self.inputs = {}
inputs = self.config["inputs"]
for i in inputs:
if "enabled" in inputs[i] and not inputs[i]["enabled"]:
continue
pos = inputs[i]["pos"]
size = inputs[i]["size"]
color = inputs[i]["color"] if "color" in inputs[i] else self.config["default_color"]
img = pygame.Surface(size)
img.fill(color)
try:
i = int(i)
except:
pass
self.inputs[i] = (pos, img)
def load_config(self, profile):
infile_name = os.path.join("profiles", profile, "config.txt")
infile = open(infile_name, "r")
config = json.load(infile)
return config
def button_down(self, button_id):
self.active_inputs.add(button_id)
self.actions.append(time.time())
def button_up(self, button_id):
try:
self.active_inputs.remove(button_id)
except:
pass
def axis_change(self, axis, value):
if value > 0.1:
self.active_inputs.add("A%dP" % axis)
elif value < -0.1:
self.active_inputs.add("A%dM" % axis)
else:
for a in ["A%dM" % axis, "A%dP" % axis]:
try:
self.active_inputs.remove(a)
except:
pass
def hat_change(self, hat, value):
# H0U, H0D, H0L, H0R
if value[0] < 0:
self.active_inputs.add("H%dL" % hat)
elif value[0] > 0:
self.active_inputs.add("H%dR" % hat)
else:
for a in ["H%dL" % hat, "H%dR" % hat]:
try:
self.active_inputs.remove(a)
except:
pass
if value[1] < 0:
self.active_inputs.add("H%dD" % hat)
elif value[1] > 0:
self.active_inputs.add("H%dU" % hat)
else:
for a in ["H%dU" % hat, "H%dD" % hat]:
try:
self.active_inputs.remove(a)
except:
pass
def update(self):
"""
Handles screen drawing. Blits images to a buffer image, resizes the
buffer to the size of the screen, then blits the buffer to the screen.
"""
if self.active_inputs == self.last_inputs:
return None
self.last_inputs = set(self.active_inputs)
buf = self.buffer
screen = self.screen
# Blank the buffer, draw the button hilights
buf.fill(self.config["background_color"])
for i in self.active_inputs:
try:
loc, img = self.inputs[i]
buf.blit(img, loc)
except KeyError:
pass
# Draw the background overtop as a mask
buf.blit(self.background, (0, 0))
# Draw APS
# Throttle keeps us from "Vibrating number syndrome"
self.aps_throttle -= 1
if self.aps_throttle < 1:
self.aps_throttle = 3
# Only score APS off the last 30 actions and last 5s
while self.actions and self.actions[0] < (time.time() - 5):
self.actions.pop(0)
if len(self.actions) > 30:
self.actions = self.actions[-30:]
# Time from last action to current time, to get APS
# We want at least 5 actions before we consider drawing APS
if len(self.actions) > 5:
aps_len = time.time() - self.actions[0] + 0.01
self.aps = len(self.actions) / aps_len
else:
self.aps = 0
# We only care about APS if we're mashing, so only draw it if it's over aps_min
if self.aps > self.aps_min:
aps_surf = self.text_font.render("%0.1f" % self.aps, 1, self.font_color)
buf.blit(aps_surf, self.config["text_pos"])
# Scale the buffer to the screen size if necessary
if buf.get_size() != screen.get_size():
buf = pygame.transform.scale(buf, screen.get_size())
# Blit buffer to screen
screen.blit(buf, (0, 0))
pygame.display.flip()
if __name__ == "__main__":
# Read in a profile name from commandline
if len(sys.argv) == 2:
profile = sys.argv[1]
else:
profile = "universal"
# Initialize all our joysticks so we get the one we want
# Since this is a one-player app, this should be fine...
pygame.joystick.init()
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
for joy in joysticks:
joy.init()
# Initialize our visualizer context
vis = Visualizer(profile)
quit = False
while not quit:
# Note that we wait for pygame events before doing any redraws
# This limits redraws to when button states change, normally
event = pygame.event.wait()
if event.type == pygame.VIDEORESIZE:
vis.win_size = (event.w, event.h)
vis.screen = pygame.display.set_mode(vis.win_size, pygame.RESIZABLE)
elif event.type == pygame.QUIT:
quit = True
elif event.type == pygame.JOYBUTTONDOWN:
vis.button_down(event.button)
elif event.type == pygame.JOYBUTTONUP:
vis.button_up(event.button)
elif event.type == pygame.JOYAXISMOTION:
vis.axis_change(event.axis, event.value)
elif event.type == pygame.JOYHATMOTION:
vis.hat_change(event.hat, event.value)
vis.update()