' SFX Generator ' ' Copyright (C) 2006 Ian Cowburn (ianc@noddybox.co.uk) ' ' 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; either version 2 of the License, or ' (at your option) any later version. ' ' 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. ' ' You should have received a copy of the GNU General Public License ' along with this program; if not, write to the Free Software ' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ' ' ------------------------------------------------------------------------- ' ' $Id$ ' SuperStrict Import noddybox.mwidget Import noddybox.algorithm Import brl.audio Import brl.audiosample Const MAGIC:String="SFXV0001" Type TPoint Field x:Int Field y:Int Function Create:TPoint(x:Int, y:Int) Local o:TPoint=New TPoint o.x=x o.y=y Return o End Function Method Draw(drag:Int) If drag SetColor(255,255,0) Else SetColor(220,220,220) EndIf DrawRect(x-2,y-2,5,5) End Method Method InRange:Int(mx:Int, my:Int) Return Abs(mx-x)<3 And Abs(my-y)<3 End Method Method ToStream(s:TStream) WriteInt(s,x) WriteInt(s,y) End Method Function FromStream:TPoint(s:TStream) Local x:Int=ReadInt(s) Local y:Int=ReadInt(s) Return Create(x,y) End Function End Type Type TPointList Field arr:Object[] Field link:TLink Field x:Int Field p:Int Field cur:TList Field depth:Int Function Create:TPointList(l:TList, depth:Int) Local o:TPointList=New TPointList o.arr=l.ToArray() o.depth=depth-1 o.Reset() Return o End Function Method NextLine() p:+1 If p=arr.length Return EndIf Local p1:TPoint=TPoint(arr[p-1]) Local p2:TPoint=TPoint(arr[p]) cur=DoLine(p1.x,p1.y,p2.x,p2.y) End Method Method AtEnd:Int() Return p=arr.length End Method Method Point:Double() Local p:TAlgoPoint=TAlgoPoint(cur.RemoveFirst()) If Not cur.Count() NextLine() EndIf Return Double(depth-p.y)/depth End Method Method Reset() x=0 p=0 NextLine() End Method End Type Type EnvelopeControl Extends TMCanvas Field points:TList Field drag:TPoint Field pleft:TPoint Field pright:TPoint Field mx:Int Field my:Int Method New() points=CreateList() drag=Null pleft=Null pright=Null End Method Function Init:TMCanvas(x:Int, y:Int, w:Int, h:Int, p:TMWidget) Local o:TMCanvas=New EnvelopeControl.Create(x,y,w,h,p) Return o End Function Method Clear() points.Clear() points.AddLast(TPoint.Create(0,Height()/2)) points.AddLast(TPoint.Create(Width()-1,Height()/2)) End Method Method ToStream(s:TStream) WriteInt(s,points.Count()) For Local p:TPoint=EachIn points p.ToStream(s) Next End Method Method FromStream(s:TStream) Local c:Int=ReadInt(s) points.Clear() For Local f:Int=1 To c points.AddLast(TPoint.FromStream(s)) Next Draw() End Method Method LocatePoint() pleft=Null Local l:TLink=points.FirstLink() While l Local p:TPoint=TPoint(l.Value()) If p.InRange(mx,my) drag=p l=l.NextLink() If l pright=TPoint(l.Value()) EndIf Return End If If p.x>mx drag=TPoint.Create(mx,my) pright=p points.InsertBeforeLink(drag,l) Return EndIf pleft=p l=l.NextLink() Wend drag=Null pleft=Null pright=Null End Method Method Draw() SetupGraphics() Cls() Local prev:TPoint=Null SetColor(180,180,180) For Local p:TPoint=EachIn points If prev DrawLine(prev.x,prev.y,p.x,p.y) EndIf prev=p Next For Local p:TPoint=EachIn points p.Draw(p=drag) Next Flip End Method Method OnRedraw() Draw() End Method Method OnMouseEnter() SetPointer(POINTER_CROSS) End Method Method OnMouseLeave() SetPointer(POINTER_DEFAULT) End Method Method OnButtonDown(b:Int) If Not drag LocatePoint() Draw() EndIf End Method Method OnButtonUp(b:Int) If drag If pleft And pleft.InRange(drag.x,drag.y) points.Remove(drag) ElseIf pright And pright.InRange(drag.x,drag.y) points.Remove(drag) End If drag=Null pleft=Null pright=Null Draw() EndIf End Method Method OnMouseMove(x:Int, y:Int) mx=x my=y If drag If pleft And pright drag.x=Max(pleft.x,Min(pright.x,mx)) ElseIf pleft drag.x=Width()-1 Else drag.x=0 EndIf drag.y=Max(0,Min(Height()-1,my)) Draw() EndIf End Method Method OnMouseWheel(b:Int) End Method Method OnKeyDown(b:Int) End Method Method OnKeyUp(b:Int) End Method Method OnKey(b:Int) End Method Method GetPointList:TPointList() Return TPointList.Create(points,Height()) End Method End Type Type WaveControl Extends EnvelopeControl Const EMPTY:Int=0 Const SINE:Int=1 Const SQUARE:Int=2 Const SAW:Int=3 Const TRIANGLE:Int=4 Const NOISE:Int=5 Method SetWave(t:Int) Select t Case EMPTY Clear() Case SINE points.Clear() For Local x:Int=0 Until Width() points.AddLast(TPoint.Create(x,Height()/2+Sin(x)*((Height()-5)/2))) Next Case SQUARE points.Clear() points.AddLast(TPoint.Create(0,0)) points.AddLast(TPoint.Create(Width()/2,0)) points.AddLast(TPoint.Create(Width()/2,Height()-1)) points.AddLast(TPoint.Create(Width()-1,Height()-1)) Case SAW points.Clear() points.AddLast(TPoint.Create(0,Height()-1)) points.AddLast(TPoint.Create(Width()-1,0)) Case TRIANGLE points.Clear() points.AddLast(TPoint.Create(0,Height()-1)) points.AddLast(TPoint.Create(Width()/2,0)) points.AddLast(TPoint.Create(Width()-1,Height()-1)) Case NOISE points.Clear() For Local x:Int=0 Until Width() points.AddLast(TPoint.Create(x,Rand(0,Height()-1))) Next Default Clear() End Select Draw() End Method End Type Type SampleControl Extends TMCanvas Field sample:TAudioSample Field sound:TSound Method Draw() SetupGraphics() Cls If sample Local s:Int=Max(1,sample.length/Width()) Local p:Int=0 Local x:Int=0 SetColor(255,255,255) While p