1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

* added support pygame (sound)

git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@63 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2006-09-05 21:28:19 +00:00
parent 1c51b62a11
commit 28099110b9
8 changed files with 292 additions and 99 deletions

View file

@ -7,13 +7,26 @@ include pysol setup.py setup.cfg MANIFEST.in Makefile COPYING README
include pysollib/*.py pysollib/tk/*.py pysollib/pysolgtk/*.py
include pysollib/games/*.py pysollib/games/special/*.py
include pysollib/games/ultra/*.py pysollib/games/mahjongg/*.py
include docs/*
include po/*
include scripts/build.bat scripts/create_iss.py scripts/mahjongg_utils.py
include scripts/all_games.py scripts/cardset_viewer.py
##
## data
##
include docs/*
graft data/html
graft data/html-src
#graft data/images
recursive-include data/images *.gif *.png
#graft data/music
#graft data/plugins
graft data/sound
graft data/tiles
include data/pysol.xbm data/pysol.xpm data/pysol.ico
include po/*
graft locale
##
## cardsets
##
graft data/cardset-2000
graft data/cardset-crystal-mahjongg
graft data/cardset-dashavatara-ganjifa
@ -26,13 +39,3 @@ graft data/cardset-oxymoron
graft data/cardset-standard
graft data/cardset-tuxedo
graft data/cardset-vienna-2k
graft data/html
graft data/html-src
#graft data/images
recursive-include data/images *.gif *.png
#graft data/music
#graft data/plugins
graft data/sound
graft data/tiles
include data/pysol.xbm data/pysol.xpm data/pysol.ico
graft locale

View file

@ -1675,7 +1675,7 @@ Please select a %s type %s.
except:
pass
##print dirs
ext_re = re.compile(r"\.((it)|(mod)|(mp3)|(pym)|(s3m)|(xm))$", re.I)
ext_re = re.compile(self.audio.EXTENTIONS)
self.initResource(manager, dirs, ext_re, Music)

View file

@ -48,7 +48,8 @@ from resource import Tile
from gamedb import GI
from app import Application
from pysolaudio import thread, pysolsoundserver
from pysolaudio import AbstractAudioClient, PysolSoundServerModuleClient, Win32AudioClient, OSSAudioClient
from pysolaudio import AbstractAudioClient, PysolSoundServerModuleClient
from pysolaudio import Win32AudioClient, OSSAudioClient, PyGameAudioClient
# Toolkit imports
from pysoltk import tkversion, wm_withdraw, wm_set_icon, loadImage
@ -91,6 +92,7 @@ def parse_option(argv):
"noplugins",
"nosound",
"debug=",
"sound-mod=",
"help"])
except getopt.GetoptError, err:
print _("%s: %s\ntry %s --help for more information") \
@ -105,6 +107,7 @@ def parse_option(argv):
"french-only": False,
"noplugins": False,
"nosound": False,
"sound-mod": None,
"debug": 0,
}
for i in optlist:
@ -126,6 +129,9 @@ def parse_option(argv):
opts["noplugins"] = True
elif i[0] == "--nosound":
opts["nosound"] = True
elif i[0] == "--sound-mod":
assert i[1] in ('pss', 'pygame', 'oss', 'win')
opts["sound-mod"] = i[1]
elif i[0] in ("-D", "--debug"):
opts["debug"] = i[1]
@ -237,23 +243,27 @@ def pysol_init(app, args):
warn_pysolsoundserver = 0
app.audio = None
if not opts["nosound"]:
if os.name == "nt" and app.opt.sound_mode == 0:
app.audio = Win32AudioClient()
elif pysolsoundserver:
app.audio = PysolSoundServerModuleClient()
elif os.name == "nt":
app.audio = Win32AudioClient()
elif os.name == 'posix':
app.audio = OSSAudioClient()
if app.audio:
app.audio.startServer()
if app.audio.server is None:
if os.name == "nt" and not isinstance(app.audio, Win32AudioClient):
app.audio.destroy()
app.audio = Win32AudioClient()
app.audio.startServer()
else:
app.audio = AbstractAudioClient()
if opts['sound-mod']:
d = {'pss': PysolSoundServerModuleClient,
'pygame': PyGameAudioClient,
'oss': OSSAudioClient,
'win': Win32AudioClient}
c = d[opts['sound-mod']]
app.audio = c()
else:
for c in (PysolSoundServerModuleClient,
PyGameAudioClient,
OSSAudioClient,
Win32AudioClient,
AbstractAudioClient):
try:
app.audio = c()
except:
pass
else:
# success
break
app.audio.startServer()
# update sound_mode
if isinstance(app.audio, PysolSoundServerModuleClient):
app.opt.sound_mode = 1
@ -394,7 +404,7 @@ Please check your %s installation.
app.audio.connectServer(app)
if app.audio.audiodev is None:
app.opt.sound = 0
if not opts["nosound"] and pysolsoundserver and not app.audio.connected:
if not opts["nosound"] and not opts['sound-mod'] and pysolsoundserver and not app.audio.connected:
print PACKAGE + ": could not connect to pysolsoundserver, sound disabled."
warn_pysolsoundserver = 1
app.audio.updateSettings()

View file

@ -35,7 +35,7 @@
# imports
import os, sys
import os, sys, time
import traceback
try:
@ -55,6 +55,12 @@ except ImportError:
# ************************************************************************/
class AbstractAudioClient:
EXTENTIONS = r"\.((it)|(mod)|(mp3)|(pym)|(s3m)|(xm))$"
CAN_PLAY_SOUND = False
CAN_PLAY_MUSIC = False
def __init__(self):
self.server = None
self.audiodev = None
@ -100,10 +106,6 @@ class AbstractAudioClient:
# high-level interface
#
def stopAll(self):
self.stopSamples()
self.stopMusic()
def playSample(self, name, priority=0, loop=0, volume=-1):
##print 'AbstractAudioClient.playSample', name
if self.audiodev is None or not self.app or not self.app.opt.sound:
@ -142,33 +144,6 @@ class AbstractAudioClient:
self.sample_priority = -1
self.sample_loop = 0
def playMusic(self, basename, priority=0, loop=0, volume=-1):
if self.audiodev is None or not self.app or not self.app.opt.sound:
return 0
if priority <= self.music_priority and self.music_loop:
return 0
obj = self.app.music_manager.getByBasename(basename)
if not obj or not obj.absname:
return 0
try:
if self._playMusic(obj.absname, priority, loop, volume):
self.music_priority = priority
self.music_loop = loop
return 1
except:
if traceback: traceback.print_exc()
return 0
def stopMusic(self):
if self.audiodev is None:
return
try:
self._stopMusic()
except:
if traceback: traceback.print_exc()
self.music_priority = -1
self.music_loop = 0
#
# subclass - core implementation
#
@ -188,12 +163,6 @@ class AbstractAudioClient:
def _stopSamplesLoop(self):
self._stopSamples()
def _playMusic(self, name, priority, loop, volume):
return 0
def _stopMusic(self):
pass
#
# subclass - extensions
#
@ -216,6 +185,14 @@ class AbstractAudioClient:
# ************************************************************************/
class PysolSoundServerModuleClient(AbstractAudioClient):
CAN_PLAY_SOUND = True
CAN_PLAY_MUSIC = True
def __init__(self):
import pysolsoundserver
AbstractAudioClient.__init__(self)
def startServer(self):
# use the module
try:
@ -257,13 +234,6 @@ class PysolSoundServerModuleClient(AbstractAudioClient):
def _stopSamplesLoop(self):
self.cmd("stopwavloop")
def _playMusic(self, filename, priority, loop, volume):
self.cmd("playmus '%s' %d %d %d %d" % (filename, -1, priority, loop, volume))
return 1
def _stopMusic(self):
self.cmd("stopmus")
def getMusicInfo(self):
if self.audiodev:
return self.audiodev.getMusicInfo()
@ -303,12 +273,19 @@ class PysolSoundServerModuleClient(AbstractAudioClient):
# ************************************************************************/
class Win32AudioClient(AbstractAudioClient):
CAN_PLAY_SOUND = True
CAN_PLAY_MUSIC = False
def __init__(self):
import winsound
AbstractAudioClient.__init__(self)
def startServer(self):
# use the built-in winsound module
try:
import winsound
self.audiodev = winsound
del winsound
self.server = 0 # success - see also tk/menubar.py
except:
self.server = None
@ -338,31 +315,32 @@ class Win32AudioClient(AbstractAudioClient):
# // OSS audio
# ************************************************************************/
#import wave, ossaudiodev
class OSSAudioServer:
def __init__(self, pipe):
import ossaudiodev
self.pipe = pipe
#import ossaudiodev
#self.audiodev = ossaudiodev.open('w')
self.sound_priority = -1
self._busy = False
def mainLoop(self):
while True:
s = os.read(self.pipe, 256)
ss = s.split('\0', 2)
ss = s.split('\0')
if not ss[0]:
os._exit(0)
if ss[0] == 'break':
self._play_loop = False
continue
filename, loop = ss[0], int(ss[1])
filename, priority, loop = ss[0], int(ss[1]), int(ss[2])
if loop:
self._play_loop = True
th = Thread(target=self.playLoop, args=(filename,))
th.start()
else:
self.play(filename)
if not self._busy:
self.play(filename, priority)
def _getParameters(self, filename):
import ossaudiodev, wave
@ -392,10 +370,11 @@ class OSSAudioServer:
if traceback: traceback.print_exc()
return 0
def play(self, filename, priority=None):
def play(self, filename, priority):
##print '_play:', filename
import ossaudiodev, wave
try:
self._busy = True
#audiodev = self.audiodev
audiodev = ossaudiodev.open('w')
#audiodev.nonblock()
@ -404,15 +383,22 @@ class OSSAudioServer:
audiodev.write(frames)
#audiodev.close()
#self.audiodev = ossaudiodev.open('w')
self.sound_priority = priority
self._busy = False
return 1
except:
if traceback: traceback.print_exc()
self._busy = False
return 0
class OSSAudioClient(AbstractAudioClient):
CAN_PLAY_SOUND = True
CAN_PLAY_MUSIC = False
def __init__(self):
import ossaudiodev, wave
AbstractAudioClient.__init__(self)
def startServer(self):
@ -434,12 +420,213 @@ class OSSAudioClient(AbstractAudioClient):
def _playSample(self, filename, priority, loop, volume):
##print '_playSample:', filename, loop
os.write(self.pout, '%s\0%s\0' % (filename, loop))
os.write(self.pout, '%s\0%s\0%s\0' % (filename, priority, loop))
return 1
def _stopSamples(self):
os.write(self.pout, 'break\0\0')
os.write(self.pout, 'break\0\0\0')
def _destroy(self):
os.write(self.pout, '\0\0')
os.write(self.pout, '\0\0\0')
# /***********************************************************************
# // PyMedia (http://pymedia.org/)
# ************************************************************************/
class PyMediaAudioClient(AbstractAudioClient):
CAN_PLAY_SOUND = True
CAN_PLAY_MUSIC = True
def __init__(self):
import pymedia, wave
AbstractAudioClient.__init__(self)
def startServer(self):
try:
import pymedia, wave
self.server = 1 # success - see also tk/menubar.py
self.audiodev = pymedia
self.splayer = pymedia.Player()
self.splayer.start()
self.mplayer = pymedia.Player()
self.mplayer.start()
except:
if traceback: traceback.print_exc()
self.server = None
self.audiodev = None
def _playSample(self, filename, priority, loop, volume):
print '_playSample:', filename, loop
self.splayer.setLoops(loop)
self.splayer.startPlayback(filename)
return 1
def _stopSamples(self):
self.splayer.stopPlayback()
def _playMusicLoop(self, music_list):
while True:
if not self.play_music:
break
for m in music_list:
if not self.play_music:
break
if m.absname.endswith('.mp3'):
print m.absname, m.volume
self.mplayer.startPlayback(m.absname)
while self.mplayer and self.mplayer.isPlaying() and self.play_music:
time.sleep(0.1)
if self.mplayer:
self.mplayer.stopPlayback()
def playContinuousMusic(self, music_list):
print 'playContinuousMusic'
if self.audiodev is None or not self.app:
return
self.play_music = True
th = Thread(target=self._playMusicLoop, args=(music_list,))
th.start()
def updateSettings(self):
if self.audiodev is None or not self.app:
return
s, m = 0, 0
if self.app.opt.sound:
s = self.app.opt.sound_sample_volume*512
s = min(65535, s)
s = max(0, s)
m = self.app.opt.sound_music_volume*512
m = min(65535, m)
m = max(0, m)
print 'updateSettings:', s, m
try:
pass
self.splayer.setVolume(s)
self.mplayer.setVolume(m)
except:
if traceback: traceback.print_exc()
# /***********************************************************************
# // PyGame
# ************************************************************************/
class PyGameAudioClient(AbstractAudioClient):
EXTENTIONS = r'\.((ogg)|(mp3)|(it)|(mod)|(s3m)|(xm)|(mid))$'
if os.name == 'nt': # without mp3
EXTENTIONS = r'\.((ogg)|(it)|(mod)|(s3m)|(xm)|(mid))$'
CAN_PLAY_SOUND = True
CAN_PLAY_MUSIC = True
def __init__(self):
import pygame.mixer, pygame.time
AbstractAudioClient.__init__(self)
def startServer(self):
try:
import pygame.mixer, pygame.time
self.server = 0 # success - see also tk/menubar.py
self.audiodev = pygame.mixer
self.mixer = pygame.mixer
self.mixer.init()
self.music = self.mixer.music
self.time = pygame.time
self.sound = None
self.sound_channel = None
self.sound_priority = -1
except:
if traceback: traceback.print_exc()
self.server = None
self.audiodev = None
def _playSample(self, filename, priority, loop, volume):
##print '_playSample:', filename, priority, loop, volume
if self.sound_channel and self.sound_channel.get_busy():
if self.sound_priority >= priority:
return 0
else:
self.sound.stop()
vol = self.app.opt.sound_sample_volume/128.0
try:
self.sound = self.mixer.Sound(filename)
self.sound.set_volume(vol)
self.sound_channel = self.sound.play(loop)
self.sound_priority = priority
except:
if traceback: traceback.print_exc()
pass
return 1
def _stopSamples(self):
if self.sound:
self.sound.stop()
self.sound = None
self.sound_channel = None
def _playMusicLoop(self):
##print '_playMusicLoop'
music_list = self.music_list
if not music_list:
return
while True:
if not self.music:
break
for m in music_list:
if not self.music:
break
vol = self.app.opt.sound_music_volume/128.0
try:
self.music.load(m.absname)
self.music.set_volume(vol)
self.music.play()
while self.music and self.music.get_busy():
self.time.wait(200)
if self.time:
self.time.wait(300)
except:
if traceback: traceback.print_exc()
self.time.wait(1000)
def playContinuousMusic(self, music_list):
##print 'playContinuousMusic'
self.music_list = music_list
#if self.audiodev is None or not self.app:
# return
if not music_list:
return
th = Thread(target=self._playMusicLoop)
th.start()
def _destroy(self):
try:
self.mixer.stop()
self.mixer.quit()
self.music = None
except:
if traceback: traceback.print_exc()
pass
def updateSettings(self):
if not self.app.opt.sound or self.app.opt.sound_music_volume == 0:
if self.music:
self.music.stop()
self.music = None
else:
if not self.music:
self.music = self.mixer.music
th = Thread(target=self._playMusicLoop)
th.start()
else:
vol = self.app.opt.sound_music_volume/128.0
self.music.set_volume(vol)
def playNextMusic(self):
if self.music:
self.music.stop()

View file

@ -449,7 +449,7 @@ class PysolMenubar(PysolMenubarActions):
menu = ui_manager.get_widget('/menubar/select').get_submenu()
self._createSelectMenu(games, menu)
if self.app.audio.audiodev is None:
if not self.app.audio.CAN_PLAY_SOUND:
item = ui_manager.get_widget('/menubar/options/sound')
item.set_sensitive(False)

View file

@ -29,7 +29,7 @@ PACKAGE = 'PySol'
PACKAGE_URL = 'http://sourceforge.net/projects/pysolfc/'
VERSION = '4.82'
FC_VERSION = '0.9.3'
FC_VERSION = '0.9.4'
VERSION_TUPLE = (4, 82)
TOOLKIT = 'gtk'

View file

@ -47,7 +47,6 @@ from pysollib.settings import PACKAGE
from pysollib.settings import TOP_TITLE
from pysollib.gamedb import GI
from pysollib.actions import PysolMenubarActions
from pysollib.pysolaudio import pysolsoundserver
# toolkit imports
from tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS
@ -463,7 +462,7 @@ class PysolMenubar(PysolMenubarActions):
submenu.add_checkbutton(label=n_("Show hint &arrow (in Shisen-Sho games)"), variable=self.tkopt.shisen_show_hint, command=self.mOptShisenShowHint)
menu.add_separator()
label = n_("&Sound...")
if self.app.audio.audiodev is None:
if not self.app.audio.CAN_PLAY_SOUND:
menu.add_checkbutton(label=label, variable=self.tkopt.sound, command=self.mOptSoundDialog, state=Tkinter.DISABLED)
else:
menu.add_checkbutton(label=label, variable=self.tkopt.sound, command=self.mOptSoundDialog)
@ -1113,12 +1112,6 @@ class PysolMenubar(PysolMenubarActions):
self.app.opt.shisen_show_hint = self.tkopt.shisen_show_hint.get()
##self.game.updateMenus()
## def mOptSound(self, *args):
## if self._cancelDrag(break_pause=False): return
## self.app.opt.sound = self.tkopt.sound.get()
## if not self.app.opt.sound:
## self.app.audio.stopAll()
def mSelectCardsetDialog(self, *event):
if self._cancelDrag(break_pause=False): return
##strings, default = ("&OK", "&Load", "&Cancel"), 0

View file

@ -118,7 +118,7 @@ class SoundOptionsDialog(MfxDialog):
command=self.mOptSoundDirectX, anchor='w')
w.grid(row=row, column=0, columnspan=2, sticky='ew')
#
if pysolsoundserver and app.startup_opt.sound_mode > 0:
if app.audio.CAN_PLAY_MUSIC: # and app.startup_opt.sound_mode > 0:
row += 1
w = Tkinter.Label(frame, text=_('Sample volume:'))
w.grid(row=row, column=0, sticky='w')