Microsoft Small Basic

Program Listing: FQH921-1
' Musical Score
' Version 0.4b
' Copyright © 2014-2017 Nonki Takahashi. The MIT License.
' Program ID FQH921-1
'
' History:
' 0.4 2017-05-21 Changed to use Unicode characters.
' 0.3 2016-03-20 Song changed.
' 0.2 2016-03-19 Rewrote to use png images. (FQH921-0)
' 0.1 2014-01-06 Created. (FQH921)
'
GraphicsWindow.Title = "Musical Score 0.4b"
Form()
mml = "O5C4O5C4O4B8O5C8R8O5D8R2O4B8O4A8R8O4G8R1R1" ' ACOM
mml = "O4E4O4G4O4A4O4G4O4E4O4G4O5C4O5C4O4A4O4A4O4G4O4E4O4D4O4E4O4C2" ' Haru no ogawa
DrawAndPlay()

Sub Form
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
x = gw - 10
For y = 40 To 120 Step 20
GraphicsWindow.DrawLine(10, y, x, y)
EndFor
For x = gw / 2 + 37 To gw - 10 Step gw / 2 - 47
GraphicsWindow.DrawLine(x, 40, x, 120)
EndFor
GraphicsWindow.FontName = "Segoe UI Symbol"
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.FontSize = 140
gclef = "𝄞"
fclef = "𝄢"
GraphicsWindow.DrawText(10, -30, gclef)
x = gw - 10
For y = 240 To 320 Step 20
GraphicsWindow.DrawLine(10, y, x, y)
EndFor
For x = gw / 2 + 37 To gw - 10 Step gw / 2 - 47
GraphicsWindow.DrawLine(x, 240, x, 320)
If gw - 10 < x + gw / 2 - 47 Then
GraphicsWindow.DrawLine(x - 6, 240, x - 6, 320)
GraphicsWindow.DrawLine(x - 2, 240, x - 2, 320)
EndIf
EndFor
GraphicsWindow.DrawText(10, 170, gclef)
EndSub

Sub DrawAndPlay
whole = "𝅝"
half = "𝅗"
quoter = "𝅘"
tail = "𝅮"
r1 = "𝄻"
r2 = "𝄼"
r4 = "𝄽"
r8 = "𝄾"
r16 = "𝄿"
len = Text.GetLength(mml)
p = 1
x = 100
yc = 131
ys = 60 ' y shift for notes
While p < len
GetNote()
If n <> "R" Then
yp = (Text.GetIndexOf("CDEFGAB", n) - 1 + (o - 4) * 7) * 10
GraphicsWindow.FontSize = 30
GraphicsWindow.DrawText(x - 3, yc + 30, n)
EndIf
If yp = 0 Then
GraphicsWindow.DrawLine(x - 6, yc + 9, x + 27, yc + 9)
EndIf
GraphicsWindow.FontSize = 70
If l = 8 Then
If n = "R" Then
GraphicsWindow.DrawText(x - 3, yc - 28 - ys, r8)
Else
GraphicsWindow.DrawText(x - 3, yc - yp - ys, quoter)
If 60 <= yp Then
GraphicsWindow.DrawLine(x + 4, yc - yp + 13, x + 4, yc - yp + 80)
Else
GraphicsWindow.DrawLine(x + 20, yc - yp + 5, x + 20, yc - yp - 60)
GraphicsWindow.DrawText(x + 19, yc - yp - ys - 28, tail)
EndIf
EndIf
x = x + 30
ElseIf l = 4 Then
If n = "R" Then
GraphicsWindow.DrawText(x - 3, yc - 42 - ys, r4)
Else
GraphicsWindow.DrawText(x - 3, yc - yp - ys, quoter)
If 60 <= yp Then
GraphicsWindow.DrawLine(x + 4, yc - yp + 13, x + 4, yc - yp + 80)
Else
GraphicsWindow.DrawLine(x + 20, yc - yp + 5, x + 20, yc - yp - 60)
EndIf
EndIf
x = x + 60
ElseIf l = 2 Then
If n = "R" Then
GraphicsWindow.DrawText(x - 3, yc - 34 - ys, r2)
Else
GraphicsWindow.DrawText(x - 3, yc - yp - ys, half)
If 60 <= yp Then
GraphicsWindow.DrawLine(x + 4, yc - yp + 13, x + 4, yc - yp + 80)
Else
GraphicsWindow.DrawLine(x + 20, yc - yp + 5, x + 20, yc - yp - 60)
EndIf
EndIf
x = x + 120
ElseIf l = 1 Then
If n = "R" Then
GraphicsWindow.DrawText(x - 3, yc - 42 - ys, r1)
Else
GraphicsWindow.DrawText(x, yc - yp - ys, whole)
EndIf
x = x + 240
EndIf
If (gw - 20) < x Then
x = x - 480
yc = yc + 200
EndIf
EndWhile
Sound.PlayMusic(mml)
EndSub

Sub GetNote
' param p - pointer to MML
' param mml - MML
' return o - octave
' return n - note
' return l - length
If Text.GetSubText(mml, p, 1) = "O" Then
p = p + 1
GetNum()
o = num
EndIf
If Text.IsSubText("CDEFGABR", Text.GetSubText(mml, p, 1)) Then
n = Text.GetSubText(mml, p, 1)
p = p + 1
EndIf
GetNum()
l = num
EndSub

Sub GetNum
' param p - pointer to MML
' param mml - MML
' return num - number
num = ""
While Text.IsSubText("0123456789", Text.GetSubText(mml, p, 1))
num = Text.Append(num, Text.GetSubText(mml, p, 1))
p = p + 1
EndWhile
EndSub