#! /.bi/dcon
#  this program prints an ascii-art fingering chart for a stringed
#  instrument, The fretted variety, basically.
#  It takes two arrays, a tuning and a "scale". 
#  we can add a "key" to offset the scale by too, RSN
#  I guess I'll use strings for arrays
#  Rick Hohensee 19980204     http://cqi.com/~humbubba


# VARIABLES-USED HIGHLIGHTS
# $c is the argument to chomp. use $c immediately after returning from chomp
# l is the length of the chart in frets
# i is used for short-scope stuff, like innermost loop indices
# $t is a string decribing an instrument tuning
# s is # of strings on instrument, = length of #t
# $f is current note, or string/fret point, first char of $r
# $s is the scale we input. $r is made from $s. $s doesn't get modified

:tuning        #  it's here if we want it
print "Type y<return> for standard guitar tuning, anything else for other\n"
input $i
let $t="ebgdae"	#  high to low, for high strings at top of page, nut to left
let s=6		#   strings, 6 if std
if $i="y" goto scale
	gosub other
	gosub mapping

:scale
print "input a 12 charachter string. Visible charachters are notes, spaces are"
print " non-notes.\n"
print "aAbcCdDefFgG_\n"
input $s
if len($s)>12 goto toolong		# funky FORTRANish 3-state IF	#
if len($s)<12 goto tooshort						#
goto ok									#
:toolong								#
print "12 charachters please, that was too long, try again\n\n\n\n"	#
goto scale								#
:tooshort								#
print "12 charachters long please, that wasn't enough\n\n\n"		#
goto scale								#
:ok					# =12, so end input checks	#

print "neck\n"
:neck		#  enter here once per neck, i.e. loop over string
		
let $c=$t 	#  $c is the string to chomp, set it on the way in....
gosub chomp	#  chomp it, set $c to the now-chomped version
let $t=$c      	#  truncates $t, leaves chomp $c re-entrant (available) for use with scales
		#  goshdarn I miss a data stack :o)
let s=s-1

:string		# :string will use $f from the tuning
print $f"   "
gosub offset  	# this gets o from $f, so now we can clobber it when we use chomp on scale

let $r=$s+$s+$s+$s 	# we'll need a backup copy
			# and it is handy to lengthen it to treat it like a ring           

let l = 18		# length of printout in frets
let $r=$mid($r,o,l)  
# print $f"  "$r"\n" 	# cheap debugging version, which first showed that it works.
			#  might could send this to a file for conversion to pixx

let i=l  		# loopcount is length of neck displayed
:frets
let $c = $r		# a wrapped call for re-entrancy, $c is for chomp 
gosub chomp		# 
let $r = $c		# $f is now the note in question, $c is now clobberable

if $f=" " print "---|"		#  minimal visual enhancement
if $f!=" " print "-O-|"		#  we could sling this into a /tmp file too, and 
if i=l print "|"		#	call it a file format :o)
let i=i-1
if i>0 goto frets
print "\n"

if s>0 goto neck	#  loop if more strings


exit 0           #  end of main, axis of flow and subroutines, flow above, subs below


:mapping
print "since we don't have a good way to express flats/sharps, we'll map em\n"
print "like so....sharps are capitalized\n"
print "  a A b c C d D e f F g G \n" 
return

:other			# get a $t  tuning string
gosub mapping
print "Input a string describing the tuning of the instrument you want to chart."
print " The first charachters in the string will be at the top of the chart. "
print "Example: standard guitar tuning is specified by ebgdae<return>, and "
print "a standard bass guitar is gdae<return>.\n"
input $t
let s=len($t)
return

:chomp			#  recieve a string in $c, leave the first char in $f, balance in $c
let $f=$mid($c,0,1)
let $c=$mid($c,1,len($c)-1)
return

:offset    #	sets o  from $f
let o=44
if $f="a" let o=0
if $f="A" let o=1      
if $f="b" let o=2      
if $f="c" let o=3      
if $f="C" let o=4      
if $f="d" let o=5      
if $f="D" let o=6      
if $f="e" let o=7      
if $f="f" let o=8      
if $f="F" let o=9     
if $f="g" let o=10     
if $f="G" let o=11    
if o<44 return
print "Huh? I have a charachter here I can't convert to a note value.\n\n"
print "The following describes the charachters that mean notes to me....\n"
gosub mapping
goto tuning
