# HG changeset patch # User Emmanuel Gil Peyrot # Date 1339594183 -7200 # Node ID 61adb5453e46850e71449d4581d95b40eeee3373 # Parent 1a4ffdda87357e9ab41a55f395a97bb090477dec Implement music playback. diff --git a/eosd b/eosd --- a/eosd +++ b/eosd @@ -43,13 +43,14 @@ def main(path, stage_num, rank, characte resource_loader = Loader(path) resource_loader.scan_archives(data) - default_power = [0, 64, 128, 128, 128, 128, 0][stage_num - 1] - game = EoSDGame(resource_loader, [PlayerState(character=character, power=default_power)], stage_num, rank, 16, - prng=prng) # Load stage data stage = resource_loader.get_stage('stage%d.std' % stage_num) + default_power = [0, 64, 128, 128, 128, 128, 0][stage_num - 1] + game = EoSDGame(resource_loader, [PlayerState(character=character, power=default_power)], stage_num, rank, 16, + prng=prng, bgms=stage.bgms) + background_anm_wrapper = resource_loader.get_anm_wrapper(('stg%dbg.anm' % stage_num,)) background = Background(stage, background_anm_wrapper) @@ -62,6 +63,7 @@ pathsep = os.path.pathsep default_data = (pathsep.join(('CM.DAT', 'th06*_CM.DAT', '*CM.DAT', '*cm.dat')), pathsep.join(('ST.DAT', 'th6*ST.DAT', '*ST.DAT', '*st.dat')), pathsep.join(('IN.DAT', 'th6*IN.DAT', '*IN.DAT', '*in.dat')), + pathsep.join(('MD.DAT', 'th6*MD.DAT', '*MD.DAT', '*md.dat')), pathsep.join(('102h.exe', '102*.exe', '東方紅魔郷.exe', '*.exe'))) diff --git a/pytouhou/formats/music.py b/pytouhou/formats/music.py new file mode 100644 --- /dev/null +++ b/pytouhou/formats/music.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +## +## Copyright (C) 2012 Emmanuel Gil Peyrot +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + + +from struct import unpack + + +class Track(object): + def __init__(self): + self.start = 0 + self.end = 0 + + + @classmethod + def read(cls, file): + self = cls() + self.start, self.end = unpack(' +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + + +from pyglet.media import AudioData +from pyglet.media.riff import WaveSource + + +class InfiniteWaveSource(WaveSource): + def __init__(self, filename, start, end, file=None): + WaveSource.__init__(self, filename, file) + + self._start = self.audio_format.bytes_per_sample * start + self._end = self.audio_format.bytes_per_sample * end + + if self._end > self._max_offset: + raise Exception #TODO + + self._duration = None + + + def _get_audio_data(self, bytes): + if bytes % self.audio_format.bytes_per_sample != 0: + bytes -= bytes % self.audio_format.bytes_per_sample + + length = bytes + while True: + size = min(length, self._end - self._offset) + data = self._file.read(size) + if size == length: + break + + self._offset = self._start + self._file.seek(self._offset + self._start_offset) + length -= size + + self._offset += length + + timestamp = float(self._offset) / self.audio_format.bytes_per_second + duration = float(bytes) / self.audio_format.bytes_per_second + + return AudioData(data, bytes, timestamp, duration) diff --git a/pytouhou/vm/msgrunner.py b/pytouhou/vm/msgrunner.py --- a/pytouhou/vm/msgrunner.py +++ b/pytouhou/vm/msgrunner.py @@ -128,6 +128,11 @@ class MSGRunner(object): self._game.msg_wait = False + @instruction(7) + def change_music(self, track): + self._game.change_music(track) + + @instruction(10) def freeze(self): self.frozen = True