GameStarter for Blender
A graphical user interface for launching blenderplayer.
USING:
Standalone Python http://arctrix.com/nas/python/standalone.html
Wxpython http://www.wxpython.org
Inno Setup http://www.jrsoftware.org/isinfo.php
SimpleOSC http://www.ixi-software.net/content/body_backyard_osc.html
Pure Data http://www.puredata.info

# -*- coding: utf-8 -*-
import wx
import sys, time, re
from subprocess import Popen, PIPE
class Hardware:
sc = []
md = []
def __init__(self):
self.renu = re.compile("[\d][.][ \t\n\r\f\v]")
self.resc = re.compile("audio output devices")
self.rescstop = re.compile("API number 3")
self.remd= re.compile("MIDI input devices")
self.remdstop = re.compile("MIDI output devices")
self.scin = 0
self.mdin = 0
self.p = Popen(['bin/pd.exe','-stderr','-listdev', '-nogui', 'App/soundcard.pd'], stdout=PIPE, stderr=PIPE)
while True:
self.pdout = self.p.stderr.readline()
if not self.pdout:
break
# SOUNDCARD - OUT
if self.resc.search(str(self.pdout)) or self.scin == 1:
self.scin = 1
if self.rescstop.search(str(self.pdout)):
self.scin = 0
else:
if self.renu.search(str(self.pdout)):
self.sc.append(self.pdout[+3:])
# MIDI - IN
if self.remd.search(str(self.pdout)) or self.mdin == 1:
self.mdin = 1
if self.remdstop.search(str(self.pdout)):
self.mdin = 0
else:
if self.renu.search(str(self.pdout)):
self.md.append(self.pdout[+3:])
#------------------- GUI (WXPYTHON) --------------------
ID_HELP = 102
ID_ABOUT = 101
ID_EXIT = 110
class Splash(wx.SplashScreen):
def __init__(self, parent=None):
aBitmap = wx.Bitmap("./App/gamestarter.bmp", wx.BITMAP_TYPE_BMP)
splashStyle = wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT
splashDuration = 1000
wx.SplashScreen.__init__(self, aBitmap, splashStyle, splashDuration, parent)
self.Bind(wx.EVT_CLOSE, self.OnExit)
wx.Yield()
def OnExit(self, evt):
self.Hide()
MyFrame = MainWindow(None,-1,"GameStarter")
app.SetTopWindow(MyFrame)
MyFrame.Show(True)
MyFrame.Center()
evt.Skip()
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
self.pdhf = Hardware()
#------------------- FRAME --------------------
wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (535,350), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.SetBackgroundColour(wx.Colour(180, 180, 180))
self.frameicon = wx.Icon("./App/8885.ico", wx.BITMAP_TYPE_ICO)
self.SetIcon(self.frameicon)
#------------------- IMAGE -------------------
self.background = wx.Bitmap("./App/gamestarter.bmp", wx.BITMAP_TYPE_BMP)
self.Bind(wx.EVT_PAINT, self.OnPaint)
#------------------- FONT --------------------
font = wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD)
#------------------- WIDGETS --------------------
self.txsey = wx.StaticText(self, -1, "EYE", pos=(191,15))
self.txsey.SetFont(font)
self.txsre = wx.StaticText(self, -1, "Fullscreen", pos=(192,40))
self.bfull = wx.CheckBox( self, -1, "", pos=(250,40))
self.txsre = wx.StaticText(self, -1, "Resolution", pos=(192,63))
self.dlre = wx.ComboBox(self, -1, "", (250, 60), wx.DefaultSize, ["320x240","400x300","512x384","640x384","640x480","640x512","700x525","720x450","800x512","800x600","840x525","1024x768","1280x768","1280x800","1280x1024","1440x900","1920x1080"], wx.CB_DROPDOWN)
self.txsea = wx.StaticText(self, -1, "EAR", pos=(191,90))
self.txsea.SetFont(font)
self.txsdv = wx.StaticText(self, -1, "Driver", pos=(192,112))
self.dldv = wx.ComboBox(self, -1, "", (190, 126), wx.DefaultSize, ["asio","mmio"], wx.CB_READONLY)
self.dldv.Bind(wx.EVT_COMBOBOX, self.onDriver)
self.txsbf = wx.StaticText(self, -1, "Buffer", pos=(262,112))
self.dlbf = wx.ComboBox(self, -1, "", (260, 126), wx.DefaultSize, ["16","32","64","128","256","512"], wx.CB_READONLY)
self.txssc = wx.StaticText(self, -1, "Sound card", pos=(192,155))
self.dlsc = wx.ComboBox(self, -1, "", (190, 170), wx.DefaultSize, self.pdhf.sc, wx.CB_READONLY)
#self.dlsc.Enable(False)
self.txsto = wx.StaticText(self, -1, "TOUCH", pos=(191,205))
self.txsto.SetFont(font)
self.txsmd = wx.StaticText(self, -1, "Midi (input)", pos=(192,227))
self.dlmd = wx.ComboBox(self, -1, "", (190, 242), wx.DefaultSize, self.pdhf.md, wx.CB_READONLY)
self.dlmd.Bind(wx.EVT_COMBOBOX, self.onMidi)
#------------------- BUTTON --------------------
self.bttestvideo = wx.Button(self, 100, "Test Video", pos=(435,20))
self.bttestvideo.Bind(wx.EVT_BUTTON, self.OnTestVideo)
self.bttestaudio = wx.Button(self, 100, "Test Audio", pos=(435,50))
self.bttestaudio.Bind(wx.EVT_BUTTON, self.OnTestAudio)
self.bttestmidi = wx.Button(self, 100, "Test Midi", pos=(435,80))
self.bttestmidi.Enable(False)
self.bttestmidi.Bind(wx.EVT_BUTTON, self.OnTestMidi)
self.btlaunch = wx.Button(self, 100, "Launch", pos=(435,240))
self.Bind(wx.EVT_BUTTON, self.OnLaunch, self.btlaunch)
#-------------------- DEBUG ---------------------
#self.control = wx.TextCtrl(self, 1, style = wx.TE_MULTILINE, size=(360,350))
#self.control.AppendText(str(ptout))
#------------------- OPTION --------------------
self.CreateStatusBar()
#------------------- MENU -----------------------
filemenu = wx.Menu()
filemenu.Append(ID_HELP, "&Help", "Help")
filemenu.Append(ID_ABOUT, "&About", "Credits")
filemenu.AppendSeparator()
filemenu.Append(ID_EXIT, "E&xit", "Quit without saving")
menubar = wx.MenuBar()
menubar.Append(filemenu, "&File")
self.SetMenuBar(menubar)
#------------------- MENU - EVENT -----------------------
wx.EVT_MENU(self, ID_HELP, self.OnHelp)
wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
wx.EVT_MENU(self, ID_EXIT, self.OnExit)
self.Show(True)
#--- START EVENT HANDLERS ---
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.Clear()
dc.DrawBitmap(self.background, 0, 0, False)
def onDriver(self, event):
if self.dldv.GetValue() == "mmio":
self.dlsc.Enable(False)
else:
self.dlsc.Enable(True)
def onMidi(self, event):
if not self.dlmd.GetValue() == "":
self.bttestmidi.Enable(True)
else:
self.bttestmidi.Enable(False)
def OnTestVideo(self, event):
#DEFAULT FEEDBACK
if self.dlre.GetValue() == "":
self.dlre.SetValue("640x480")
tv = []
tv.append('App/blenderplayer.exe')
if self.dlre.GetValue() == "":
tv.append('-p')
tv.append('0')
tv.append('0')
tv.append('640')
tv.append('480')
else:
tv.append('-p')
tv.append('0')
tv.append('0')
tv.append(str(self.dlre.GetValue().split('x')[0]))
tv.append(str(self.dlre.GetValue().split('x')[1]))
if self.bfull.GetValue():
tv.append('-f')
tv.append('-g')
tv.append('show_framerate')
tv.append('=')
tv.append('1')
tv.append('App/test_video.blend')
p = Popen(tv, stdout=PIPE, stderr=PIPE)
def OnTestAudio(self, event):
#DEFAULT FEEDBACK
if self.dlbf.GetValue() == "":
self.dlbf.SetValue("128")
if self.dldv.GetValue() == "":
self.dldv.SetValue("asio")
if self.dlsc.GetValue() == "":
self.dlsc.SetValue(sc[0])
test = []
test.append('bin/pd.exe')
if self.dldv.GetValue() == "":
test.append('-asio')
else:
test.append('-'+str(self.dldv.GetValue()))
if self.dlsc.GetValue() == "":
if not self.dldv.GetValue() == "mmio":
test.append('-audiodev')
test.append('1')
else:
if not self.dldv.GetValue() == "mmio":
test.append('-audiodev')
test.append(str(self.dlsc.GetCurrentSelection()+1))
if self.dlbf.GetValue() == "":
test.append('-audiobuf')
test.append('128')
else:
test.append('-audiobuf')
test.append(str(self.dlbf.GetValue()))
if self.dlmd.GetValue() == "":
test.append('-midiindev')
test.append('1')
else:
test.append('-midiindev')
test.append(str(self.dlmd.GetCurrentSelection()+1))
test.append('-r')
test.append('44100')
test.append('-nogui')
test.append('-open')
test.append('App/tone.pd')
pt = Popen(test, stdout=PIPE, stderr=PIPE)
#AVOID A BUG WITH MMIO
while True:
ptout = pt.stderr.readline()
if not ptout:
break
def OnTestMidi(self, event):
tv = []
tv.append('App/blenderplayer.exe')
if self.dlre.GetValue() == "":
tv.append('-p')
tv.append('0')
tv.append('0')
tv.append('640')
tv.append('480')
else:
tv.append('-p')
tv.append('0')
tv.append('0')
tv.append(str(self.dlre.GetValue().split('x')[0]))
tv.append(str(self.dlre.GetValue().split('x')[1]))
if self.bfull.GetValue():
tv.append('-f')
tv.append('App/test_midi.blend')
p = Popen(tv, stdout=PIPE, stderr=PIPE)
test = []
test.append('bin/pd.exe')
if self.dldv.GetValue() == "":
test.append('-asio')
else:
test.append('-'+str(self.dldv.GetValue()))
if self.dlsc.GetValue() == "":
if not self.dldv.GetValue() == "mmio":
test.append('-audiodev')
test.append('1')
else:
if not self.dldv.GetValue() == "mmio":
test.append('-audiodev')
test.append(str(self.dlsc.GetCurrentSelection()+1))
if self.dlbf.GetValue() == "":
test.append('-audiobuf')
test.append('128')
else:
test.append('-audiobuf')
test.append(str(self.dlbf.GetValue()))
if self.dlmd.GetValue() == "":
test.append('-midiindev')
test.append('1')
else:
test.append('-midiindev')
test.append(str(self.dlmd.GetCurrentSelection()+1))
test.append('-r')
test.append('44100')
test.append('-nogui')
test.append('-open')
test.append('App/oscmidi.pd')
pt = Popen(test, stdout=PIPE, stderr=PIPE)
#AVOID A BUG WITH MMIO
while True:
ptout = pt.stderr.readline()
if not ptout:
break
def OnLaunch(self, event):
#TODO LAUNCH PD
#SAVE XML
launch = []
launch.append('App/blenderplayer.exe')
if self.dlre.GetValue() == "":
launch.append('-p')
launch.append('0')
launch.append('0')
launch.append('640')
launch.append('480')
else:
launch.append('-p')
launch.append('0')
launch.append('0')
launch.append(str(self.dlre.GetValue().split('x')[0]))
launch.append(str(self.dlre.GetValue().split('x')[1]))
if self.bfull.GetValue():
launch.append('-f')
launch.append('App/bounce.blend')
p = Popen(launch, stdout=PIPE, stderr=PIPE)
def OnHelp(self, event):
d = wx.MessageDialog(self, "human can ear sense a latency of 12 ms and above", "Help", wx.OK)
d.ShowModal()
d.Destroy()
#human can ear/sense a latency of 12 ms and above
#sound takes about 1ms to traval 1 foot
#Latency is another way of saying delay.
#If your computer is busy and it doesn't process the audio in time then you will get glitches-pops-clicks in your recordings.
def OnAbout(self, event):
d = wx.MessageDialog(self, "GUI for configuring Edubeat\nProgramming by Patrick Sébastien Coulombe", "About", wx.OK)
d.ShowModal()
d.Destroy()
def OnExit(self, event):
self.Close(True)
class GMA(wx.App):
def OnInit(self):
CSplash = Splash()
CSplash.Show()
return True
app = GMA(redirect=True, filename = "demo.log")
app.MainLoop()
Inno Setup code
[Setup]
AppName=Edubeat
AppVerName=Edubeat 0.1
DefaultDirName={pf}\Edubeat
DefaultGroupName=Edubeat
UninstallDisplayIcon={app}\Edubeat.exe
Compression=lzma
SolidCompression=yes
OutputDir=userdocs:edubeatsetup
[Files]
Source: "Edubeat.exe"; DestDir: "{app}"
Source: "msvcr71.dll"; DestDir: "{app}"
Source: "python25.dll"; DestDir: "{app}"
Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
Source: C:\gamestarter\bin\*.*; DestDir: {app}\bin; Flags: ignoreversion recursesubdirs
Source: C:\gamestarter\App\*.*; DestDir: {app}\App; Flags: ignoreversion recursesubdirs
Source: C:\gamestarter\DLLs\*.*; DestDir: {app}\DLLs; Flags: ignoreversion recursesubdirs
Source: C:\gamestarter\extra\*.*; DestDir: {app}\extra; Flags: ignoreversion recursesubdirs
Source: C:\gamestarter\Lib\*.*; DestDir: {app}\Lib; Flags: ignoreversion recursesubdirs
[Tasks]
Name: "quicklaunchicon"; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: unchecked
Name: "quickdesktopicon"; Description: "Create a &Desktop icon"; GroupDescription: "Additional icons:"; Flags: unchecked
[Icons]
Name: "{group}\Edubeat"; Filename: "{app}\Edubeat.exe"
Name: "{commondesktop}\Edubeat"; Filename: "{app}\Edubeat.exe"; WorkingDir: "{app}"; Tasks: quickdesktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Edubeat"; Filename: "{app}\Edubeat.exe"; WorkingDir: "{app}"; Tasks: quicklaunchicon
page revision: 38, last edited: 11 Jan 2009 20:22