- added volume adjust to SoundEffect
- removed original volumes audio hack - added width and height to render box
This commit is contained in:
parent
697eb22633
commit
987b154b26
183
pgfw/Audio.py
183
pgfw/Audio.py
|
@ -13,7 +13,7 @@ class Audio(GameChild):
|
|||
|
||||
def __init__(self, game):
|
||||
GameChild.__init__(self, game)
|
||||
self.original_volumes = {}
|
||||
# self.original_volumes = {}
|
||||
self.volume = self.BASE_VOLUME
|
||||
if self.check_command_line("-mute"):
|
||||
self.volume = 0
|
||||
|
@ -43,6 +43,7 @@ class Audio(GameChild):
|
|||
elif compare(event, "volume-down"):
|
||||
self.set_volume(increment=self.DOWN)
|
||||
|
||||
#
|
||||
# Loading SFX procedure
|
||||
#
|
||||
# - load config file name/path definitions at init
|
||||
|
@ -52,8 +53,10 @@ class Audio(GameChild):
|
|||
# and get written to config file
|
||||
#
|
||||
def load_sfx(self, sfx_location=None):
|
||||
for name, path in self.get_configuration("sfx").items():
|
||||
self.load_sfx_file(path, name, True)
|
||||
for name, sfx_definition in self.get_configuration("sfx").items():
|
||||
path, volume = sfx_definition.split(",")
|
||||
volume = float(volume)
|
||||
self.load_sfx_file(path, name, True, volume=volume)
|
||||
if sfx_location is None:
|
||||
sfx_location = self.get_configuration("audio", "sfx-project-path") + \
|
||||
self.get_configuration("audio", "sfx-default-path")
|
||||
|
@ -75,7 +78,7 @@ class Audio(GameChild):
|
|||
prefix = re.sub("/", "_", prefix) + "_"
|
||||
self.load_sfx_file(os.path.join(node, leaf,), prefix=prefix)
|
||||
|
||||
def load_sfx_file(self, path, name=None, replace=False, prefix=""):
|
||||
def load_sfx_file(self, path, name=None, replace=False, prefix="", volume=1.0):
|
||||
path = self.get_resource(path)
|
||||
if path and path.split(".")[-1] in self.get_configuration("audio", "sfx-extensions"):
|
||||
if name is None:
|
||||
|
@ -84,18 +87,18 @@ class Audio(GameChild):
|
|||
print("skipping existing sound effect for %s: %s" % (name, path))
|
||||
else:
|
||||
print("loading sound effect %s into %s" % (path, name))
|
||||
self.sfx[name] = SoundEffect(self, path)
|
||||
self.sfx[name] = SoundEffect(self, path, volume)
|
||||
return True
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
for ii in range(pygame.mixer.get_num_channels()):
|
||||
channel = pygame.mixer.Channel(ii)
|
||||
sound = channel.get_sound()
|
||||
if sound is not None:
|
||||
if sound not in self.original_volumes.keys():
|
||||
self.original_volumes[sound] = sound.get_volume()
|
||||
sound.set_volume(self.original_volumes[sound] * self.volume)
|
||||
# for ii in range(pygame.mixer.get_num_channels()):
|
||||
# channel = pygame.mixer.Channel(ii)
|
||||
# sound = channel.get_sound()
|
||||
# if sound is not None:
|
||||
# if sound not in self.original_volumes.keys():
|
||||
# self.original_volumes[sound] = sound.get_volume()
|
||||
# sound.set_volume(self.original_volumes[sound] * self.volume)
|
||||
self.audio_panel.update()
|
||||
|
||||
|
||||
|
@ -107,11 +110,10 @@ class SoundEffect(GameChild, pygame.mixer.Sound):
|
|||
pygame.mixer.Sound.__init__(self, path)
|
||||
self.display_surface = self.get_display_surface()
|
||||
self.initial_volume = volume
|
||||
self.set_volume(volume)
|
||||
self.set_volume(self.initial_volume * self.get_configuration("audio", "sfx-volume"))
|
||||
|
||||
def play(self, loops=0, maxtime=0, fade_ms=0, position=None, x=None):
|
||||
self.set_volume(self.initial_volume *
|
||||
self.get_configuration("audio", "sfx-volume"))
|
||||
self.set_volume(self.initial_volume * self.get_configuration("audio", "sfx-volume"))
|
||||
channel = pygame.mixer.Sound.play(self, loops, maxtime, fade_ms)
|
||||
if x is not None:
|
||||
position = float(x) / self.display_surface.get_width()
|
||||
|
@ -123,6 +125,14 @@ class SoundEffect(GameChild, pygame.mixer.Sound):
|
|||
return 1 - max(0, ((position - .5) * 2)), \
|
||||
1 + min(0, ((position - .5) * 2))
|
||||
|
||||
def adjust_volume(self, increment):
|
||||
self.initial_volume += increment
|
||||
if self.initial_volume > 1.0:
|
||||
self.initial_volume = 1.0
|
||||
elif self.initial_volume < 0:
|
||||
self.initial_volume = 0
|
||||
self.set_volume(self.initial_volume * self.get_configuration("audio", "sfx-volume"))
|
||||
|
||||
|
||||
class AudioPanel(Animation):
|
||||
|
||||
|
@ -130,16 +140,21 @@ class AudioPanel(Animation):
|
|||
|
||||
def __init__(self, parent):
|
||||
Animation.__init__(self, parent)
|
||||
self.rows = []
|
||||
self.file_browser = AudioPanelFileBrowser(self)
|
||||
self.subscribe(self.respond)
|
||||
self.subscribe(self.respond, pygame.MOUSEBUTTONDOWN)
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.selected = None
|
||||
self.row_offset = 0
|
||||
self.deactivate()
|
||||
|
||||
def get_selected(self):
|
||||
for row in self.rows:
|
||||
if row.selected:
|
||||
return row
|
||||
|
||||
def activate(self):
|
||||
pygame.mouse.set_visible(True)
|
||||
self.active = True
|
||||
|
@ -158,24 +173,15 @@ class AudioPanel(Animation):
|
|||
self.activate()
|
||||
elif self.active:
|
||||
if event.type == pygame.MOUSEBUTTONDOWN and self.file_browser.is_hidden():
|
||||
if event.button == 1:
|
||||
for row in self.rows:
|
||||
if row.location.collidepoint(event.pos):
|
||||
if row != self.selected:
|
||||
self.file_browser.visit(self.file_browser.HOME)
|
||||
self.selected = row
|
||||
self.selected.start_blinking()
|
||||
self.file_browser.unhide()
|
||||
else:
|
||||
if row == self.selected:
|
||||
self.selected = None
|
||||
row.stop_blinking()
|
||||
elif event.button == 5:
|
||||
if event.button == 5:
|
||||
self.row_offset += 1
|
||||
elif event.button == 4:
|
||||
self.row_offset -= 1
|
||||
|
||||
def build(self):
|
||||
for row in self.rows:
|
||||
row.unsubscribe(row.respond, pygame.MOUSEBUTTONDOWN)
|
||||
del row
|
||||
self.rows = []
|
||||
for key in sorted(self.parent.sfx):
|
||||
self.rows.append(AudioPanelRow(self, key))
|
||||
|
@ -187,6 +193,8 @@ class AudioPanel(Animation):
|
|||
dsr = ds.get_rect()
|
||||
corner = Vector(self.MARGIN, self.MARGIN)
|
||||
index = self.row_offset
|
||||
for row in self.rows:
|
||||
row.location.bottom = 0
|
||||
while corner.y < dsr.height - self.MARGIN:
|
||||
row = self.rows[index % len(self.rows)]
|
||||
row.location.topleft = corner.copy()
|
||||
|
@ -209,8 +217,23 @@ class AudioPanelRow(BlinkingSprite):
|
|||
def __init__(self, parent, key):
|
||||
BlinkingSprite.__init__(self, parent, 500)
|
||||
self.key = key
|
||||
self.selected = False
|
||||
self.build()
|
||||
self.halt()
|
||||
self.stop_blinking()
|
||||
self.subscribe(self.respond, pygame.MOUSEBUTTONDOWN)
|
||||
|
||||
def respond(self, event):
|
||||
if event.button == 1:
|
||||
if self.parent.file_browser.is_hidden() and self.location.collidepoint(event.pos):
|
||||
if not self.selected:
|
||||
self.parent.file_browser.visit(self.parent.file_browser.HOME)
|
||||
self.selected = True
|
||||
self.start_blinking()
|
||||
self.parent.file_browser.unhide()
|
||||
elif self.parent.file_browser.is_hidden():
|
||||
if self.selected:
|
||||
self.selected = False
|
||||
self.stop_blinking()
|
||||
|
||||
def build(self):
|
||||
font = pygame.font.Font(
|
||||
|
@ -255,19 +278,42 @@ class AudioPanelFileBrowser(Sprite):
|
|||
|
||||
WIDTH = .75
|
||||
HEIGHT = .75
|
||||
BACKGROUND = pygame.Color(255, 255, 255)
|
||||
FOREGROUND = pygame.Color(0, 0, 0)
|
||||
COLORS = pygame.Color(255, 255, 255), pygame.Color(0, 0, 0)
|
||||
HOME, UP = "[HOME]", "[UP]"
|
||||
FONT_SIZE = 16
|
||||
VOLUME_WIDTH = .1
|
||||
VOLUME_INDICATOR_HEIGHT = .1
|
||||
VOLUME_STEP = .05
|
||||
|
||||
def __init__(self, parent):
|
||||
Sprite.__init__(self, parent)
|
||||
self.font = pygame.font.Font(
|
||||
self.get_resource(self.get_configuration("audio", "panel-font")),
|
||||
self.FONT_SIZE)
|
||||
ds = self.get_display_surface()
|
||||
dsr = ds.get_rect()
|
||||
surface = pygame.Surface((dsr.w * self.WIDTH, dsr.h * self.HEIGHT), SRCALPHA)
|
||||
surface.fill(self.BACKGROUND)
|
||||
self.add_frame(surface)
|
||||
surface = pygame.Surface((dsr.w * self.WIDTH - 2, dsr.h * self.HEIGHT - 2), SRCALPHA)
|
||||
surface.fill(self.COLORS[0])
|
||||
self.background = get_boxed_surface(surface, self.COLORS[0], self.COLORS[1])
|
||||
self.add_frame(self.background.copy())
|
||||
self.location.center = dsr.center
|
||||
self.volume_buttons = []
|
||||
for text in "VOL -", "VOL +":
|
||||
button = Sprite(self)
|
||||
button.add_frame(render_box(
|
||||
self.font, text, color=self.COLORS[1], background=self.COLORS[0],
|
||||
border=self.COLORS[1], width=self.VOLUME_WIDTH * dsr.w))
|
||||
button.location.top = self.location.bottom - 1
|
||||
self.volume_buttons.append(button)
|
||||
self.volume_buttons[0].location.left = self.location.left
|
||||
self.volume_buttons[1].location.right = self.location.right
|
||||
self.volume_indicator = Sprite(self)
|
||||
self.volume_indicator.add_frame(pygame.Surface((
|
||||
self.location.w - self.volume_buttons[0].location.w * 2,
|
||||
self.volume_buttons[0].location.h), SRCALPHA))
|
||||
self.volume_indicator.get_current_frame().fill(self.COLORS[0])
|
||||
self.volume_indicator.location.topleft = (
|
||||
self.volume_buttons[0].location.right, self.location.bottom - 1)
|
||||
self.reset()
|
||||
self.subscribe(self.respond, pygame.MOUSEBUTTONDOWN)
|
||||
|
||||
|
@ -278,7 +324,11 @@ class AudioPanelFileBrowser(Sprite):
|
|||
def respond(self, event):
|
||||
if not self.is_hidden():
|
||||
if event.button == 1:
|
||||
if self.location.collidepoint(event.pos):
|
||||
if self.volume_buttons[0].collide(event.pos):
|
||||
self.adjust_volume(-self.VOLUME_STEP)
|
||||
elif self.volume_buttons[1].collide(event.pos):
|
||||
self.adjust_volume(self.VOLUME_STEP)
|
||||
elif self.collide(event.pos):
|
||||
for row in self.rows:
|
||||
if row.collide(Vector(*event.pos).get_moved(-self.location.left, -self.location.top)):
|
||||
full_path = os.path.join(os.path.sep.join(self.trail), row.path)
|
||||
|
@ -286,15 +336,9 @@ class AudioPanelFileBrowser(Sprite):
|
|||
os.path.isdir(full_path) and os.access(full_path, os.R_OK):
|
||||
self.visit(row.path)
|
||||
elif os.path.isfile(full_path) and os.access(full_path, os.R_OK):
|
||||
key = self.parent.selected.key
|
||||
key = self.parent.get_selected().key
|
||||
if self.get_audio().load_sfx_file(full_path, key, True):
|
||||
if not self.get_configuration().has_section("sfx"):
|
||||
self.get_configuration().add_section("sfx")
|
||||
self.get_configuration().set("sfx", key, full_path)
|
||||
config_path = self.get_configuration().locate_project_config_file()
|
||||
backup_path = config_path + ".backup"
|
||||
shutil.copyfile(config_path, backup_path)
|
||||
self.get_configuration().write(open(config_path, "w"))
|
||||
self.update_config(key, full_path)
|
||||
self.hide()
|
||||
self.get_delegate().cancel_propagation()
|
||||
self.parent.build()
|
||||
|
@ -306,6 +350,33 @@ class AudioPanelFileBrowser(Sprite):
|
|||
elif event.button == 5:
|
||||
self.row_offset += 1
|
||||
|
||||
def adjust_volume(self, step):
|
||||
selected = self.parent.get_selected()
|
||||
sound_effect = selected.get_sound_effect()
|
||||
print(sound_effect)
|
||||
sound_effect.adjust_volume(step)
|
||||
# sound_effect.set_volume(.1)
|
||||
print(sound_effect.get_volume())
|
||||
sound_effect.play()
|
||||
self.update_config(selected.key, sound_effect.path)
|
||||
|
||||
def update_config(self, key, path):
|
||||
if not self.get_configuration().has_section("sfx"):
|
||||
self.get_configuration().add_section("sfx")
|
||||
volume = self.get_audio().sfx[key].initial_volume
|
||||
print(self.get_audio().sfx[key])
|
||||
self.get_configuration().set("sfx", key, "{}, {}".format(path, volume))
|
||||
config_path = self.get_configuration().locate_project_config_file()
|
||||
backup_path = config_path + ".backup"
|
||||
shutil.copyfile(config_path, backup_path)
|
||||
self.get_configuration().write(open(config_path, "w"))
|
||||
|
||||
def hide(self):
|
||||
for row in self.parent.rows:
|
||||
row.selected = False
|
||||
row.stop_blinking()
|
||||
Sprite.hide(self)
|
||||
|
||||
def visit(self, path):
|
||||
if path == self.UP and len(self.trail) > 1:
|
||||
path = self.trail[-2]
|
||||
|
@ -332,11 +403,8 @@ class AudioPanelFileBrowser(Sprite):
|
|||
self.rows = []
|
||||
for path in self.paths:
|
||||
row = Sprite(self)
|
||||
font = pygame.font.Font(
|
||||
self.get_resource(self.get_configuration("audio", "panel-font")),
|
||||
self.FONT_SIZE)
|
||||
row.path = path
|
||||
text = font.render(path, True, self.FOREGROUND)
|
||||
text = self.font.render(path, True, self.COLORS[1])
|
||||
surface = pygame.Surface((self.location.w, text.get_height()), SRCALPHA)
|
||||
surface.blit(text, (0, 0))
|
||||
row.add_frame(surface)
|
||||
|
@ -345,28 +413,29 @@ class AudioPanelFileBrowser(Sprite):
|
|||
self.rows.append(row)
|
||||
|
||||
def update(self):
|
||||
self.get_current_frame().fill(self.BACKGROUND)
|
||||
self.get_current_frame().blit(self.background, (0, 0))
|
||||
if not self.is_hidden():
|
||||
# ds = self.get_display_surface()
|
||||
# dsr = ds.get_rect()
|
||||
# corner = Vector(self.MARGIN, self.MARGIN)
|
||||
corner = Vector(0, 0)
|
||||
corner = Vector(1, 1)
|
||||
index = self.row_offset
|
||||
# while corner.y < dsr.height - self.MARGIN:
|
||||
for row in self.rows:
|
||||
row.remove_locations()
|
||||
row.location.bottom = 0
|
||||
# row.hide()
|
||||
while corner.y < self.location.h:
|
||||
row = self.rows[index % len(self.rows)]
|
||||
# row.unhide()
|
||||
if index - self.row_offset >= len(self.rows):
|
||||
row.add_location(corner.copy())
|
||||
else:
|
||||
row.location.topleft = corner.copy()
|
||||
# corner.y += row.location.height + self.MARGIN
|
||||
corner.y += row.location.height
|
||||
index += 1
|
||||
for row in self.rows:
|
||||
row.update()
|
||||
self.volume_indicator.get_current_frame().fill(self.COLORS[0])
|
||||
self.volume_indicator.get_current_frame().fill(
|
||||
self.COLORS[1],
|
||||
(0, 0, self.volume_indicator.location.w * self.parent.get_selected().get_sound_effect().initial_volume,
|
||||
self.volume_indicator.location.h))
|
||||
self.volume_indicator.update()
|
||||
for button in self.volume_buttons:
|
||||
button.update()
|
||||
Sprite.update(self)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from os.path import exists, join, basename, normpath, abspath
|
||||
from os.path import exists, join, basename, normpath, abspath, commonprefix, sep
|
||||
from sys import argv, version_info
|
||||
|
||||
from pygame import mixer, event, time
|
||||
|
@ -69,7 +69,7 @@ class GameChild:
|
|||
continue
|
||||
path = join(root, rel_path)
|
||||
if exists(path):
|
||||
return path
|
||||
return normpath(path)
|
||||
self.print_debug("Couldn't find resource: {0} {1}".format(
|
||||
path_or_section, option))
|
||||
|
||||
|
|
|
@ -186,9 +186,21 @@ def get_boxed_surface(surface, background=None, border=None, border_width=1,
|
|||
return surface
|
||||
|
||||
def render_box(font, text, antialias=True, color=(0, 0, 0), background=None, border=None,
|
||||
border_width=1, padding=0):
|
||||
return get_boxed_surface(font.render(text, antialias, color, background),
|
||||
background, border, border_width, padding)
|
||||
border_width=1, padding=0, width=None, height=None):
|
||||
surface = font.render(text, antialias, color, background)
|
||||
if width is not None or height is not None:
|
||||
if width is None:
|
||||
width = surface.get_width()
|
||||
if height is None:
|
||||
height = surface.get_height()
|
||||
container = Surface((width, height), SRCALPHA)
|
||||
if background is not None:
|
||||
container.fill(background)
|
||||
text_rect = surface.get_rect()
|
||||
text_rect.center = container.get_rect().center
|
||||
container.blit(surface, text_rect)
|
||||
surface = container
|
||||
return get_boxed_surface(surface, background, border, border_width, padding)
|
||||
|
||||
def get_wrapped_text_surface(font, text, width, antialias, color,
|
||||
background=None, border=None, border_width=1,
|
||||
|
|
Loading…
Reference in New Issue