|  | @@ -0,0 +1,413 @@
 | 
	
		
			
				|  |  | +package main
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import (
 | 
	
		
			
				|  |  | +	"database/sql"
 | 
	
		
			
				|  |  | +	"fmt"
 | 
	
		
			
				|  |  | +	"math/rand"
 | 
	
		
			
				|  |  | +	"os"
 | 
	
		
			
				|  |  | +	"path/filepath"
 | 
	
		
			
				|  |  | +	"red-green/door"
 | 
	
		
			
				|  |  | +	"regexp"
 | 
	
		
			
				|  |  | +	"strconv"
 | 
	
		
			
				|  |  | +	"strings"
 | 
	
		
			
				|  |  | +	"time"
 | 
	
		
			
				|  |  | +	"unicode"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	_ "github.com/mattn/go-sqlite3"
 | 
	
		
			
				|  |  | +	"github.com/seehuhn/mt19937"
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func pctUpdate(pct *int64) func() int64 {
 | 
	
		
			
				|  |  | +	return func() int64 {
 | 
	
		
			
				|  |  | +		return *pct
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Can I add a function to Door?
 | 
	
		
			
				|  |  | +// NO:  cannot define new methods on non-local type door.Door
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +func (d *door.Door) PressAKey() {
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL + "Press a key to continue...")
 | 
	
		
			
				|  |  | +	d.Key()
 | 
	
		
			
				|  |  | +	d.Write(door.CRNL)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func find_words(text string) [][]int {
 | 
	
		
			
				|  |  | +	word, _ := regexp.Compile("([A-Za-z]+)")
 | 
	
		
			
				|  |  | +	return word.FindAllStringIndex(text, -1)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func press_a_key(d *door.Door) int {
 | 
	
		
			
				|  |  | +	green := door.ColorText("BOLD GREEN")
 | 
	
		
			
				|  |  | +	blue := door.ColorText("BOLD BLUE")
 | 
	
		
			
				|  |  | +	yellow := door.ColorText("BOLD YELLOW")
 | 
	
		
			
				|  |  | +	any_caps := green
 | 
	
		
			
				|  |  | +	any_lower := yellow
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	any_color := func(text string) string {
 | 
	
		
			
				|  |  | +		var output string
 | 
	
		
			
				|  |  | +		var lastColor string
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		for _, letter := range text {
 | 
	
		
			
				|  |  | +			if unicode.IsUpper(letter) {
 | 
	
		
			
				|  |  | +				if lastColor != any_caps {
 | 
	
		
			
				|  |  | +					lastColor = any_caps
 | 
	
		
			
				|  |  | +					output += any_caps
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				output += string(letter)
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				if lastColor != any_lower {
 | 
	
		
			
				|  |  | +					lastColor = any_lower
 | 
	
		
			
				|  |  | +					output += any_lower
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				output += string(letter)
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return output
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	text := "Press a key to continue..."
 | 
	
		
			
				|  |  | +	work_text := []rune(text)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + any_color(text))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	var r int = -1
 | 
	
		
			
				|  |  | +	var t int
 | 
	
		
			
				|  |  | +	sleep_ms := 250
 | 
	
		
			
				|  |  | +	ms_sleep := 0
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	words := find_words(text)
 | 
	
		
			
				|  |  | +	var word int = 0
 | 
	
		
			
				|  |  | +	var wpos int = 0
 | 
	
		
			
				|  |  | +	current_word := text[words[word][0]:words[word][1]]
 | 
	
		
			
				|  |  | +	t = 0
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	r = d.WaitKey(0, int64(sleep_ms)*1000)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for r == -1 {
 | 
	
		
			
				|  |  | +		ms_sleep += sleep_ms
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if ms_sleep > 1000 {
 | 
	
		
			
				|  |  | +			ms_sleep -= 1000
 | 
	
		
			
				|  |  | +			t++
 | 
	
		
			
				|  |  | +			if t >= int(door.Inactivity) {
 | 
	
		
			
				|  |  | +				d.Write(strings.Repeat("\b", len(text)))
 | 
	
		
			
				|  |  | +				d.Write(any_color(text) + door.CRNL)
 | 
	
		
			
				|  |  | +				return -1
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		wpos++
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if wpos == len(current_word) {
 | 
	
		
			
				|  |  | +			word++
 | 
	
		
			
				|  |  | +			wpos = 0
 | 
	
		
			
				|  |  | +			work_text = []rune(text)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if word == len(words) {
 | 
	
		
			
				|  |  | +				word = 0
 | 
	
		
			
				|  |  | +				if any_caps == green {
 | 
	
		
			
				|  |  | +					any_caps = blue
 | 
	
		
			
				|  |  | +				} else {
 | 
	
		
			
				|  |  | +					any_caps = green
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				d.Write(strings.Repeat("\b", len(text)))
 | 
	
		
			
				|  |  | +				d.Write(any_color(string(work_text)))
 | 
	
		
			
				|  |  | +				current_word = text[words[word][0]:words[word][1]]
 | 
	
		
			
				|  |  | +				goto READKEY
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			current_word = text[words[word][0]:words[word][1]]
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			c := rune(current_word[wpos])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			for !unicode.IsLower(c) {
 | 
	
		
			
				|  |  | +				wpos++
 | 
	
		
			
				|  |  | +				if wpos == len(current_word) {
 | 
	
		
			
				|  |  | +					wpos = 0
 | 
	
		
			
				|  |  | +					word++
 | 
	
		
			
				|  |  | +					work_text = []rune(text)
 | 
	
		
			
				|  |  | +					if word == len(words) {
 | 
	
		
			
				|  |  | +						word = 0
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					current_word = text[words[word][0]:words[word][1]]
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				c = rune(current_word[wpos])
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			// Ok, we found something that's lower case
 | 
	
		
			
				|  |  | +			work_text[words[word][0]+wpos] = unicode.ToUpper(c)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		d.Write(strings.Repeat("\b", len(text)))
 | 
	
		
			
				|  |  | +		d.Write(any_color(string(work_text)))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	READKEY:
 | 
	
		
			
				|  |  | +		r = d.WaitKey(0, int64(sleep_ms)*1000)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(strings.Repeat("\b", len(text)))
 | 
	
		
			
				|  |  | +	d.Write(any_color(text))
 | 
	
		
			
				|  |  | +	return r
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func MainMenu() door.Menu {
 | 
	
		
			
				|  |  | +	// Make the main menu
 | 
	
		
			
				|  |  | +	m := door.Menu{Panel: door.Panel{Width: 45,
 | 
	
		
			
				|  |  | +		X:           5,
 | 
	
		
			
				|  |  | +		Y:           5,
 | 
	
		
			
				|  |  | +		Style:       door.DOUBLE,
 | 
	
		
			
				|  |  | +		Title:       "[ Main Menu: ]",
 | 
	
		
			
				|  |  | +		TitleOffset: 3,
 | 
	
		
			
				|  |  | +		BorderColor: door.ColorText("BRI CYAN ON BLA")}}
 | 
	
		
			
				|  |  | +	m.SelectedR = door.MakeMenuRender(door.ColorText("BOLD CYAN"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD BLUE"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD CYAN"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD BLUE"))
 | 
	
		
			
				|  |  | +	m.UnselectedR = door.MakeMenuRender(door.ColorText("BOLD YEL ON BLUE"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD WHI ON BLUE"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD YEL ON BLUE"),
 | 
	
		
			
				|  |  | +		door.ColorText("BOLD CYAN ON BLUE"))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	m.AddSelection("A", "ANSI Display")
 | 
	
		
			
				|  |  | +	m.AddSelection("D", "Display Information (dropfile, screen)")
 | 
	
		
			
				|  |  | +	m.AddSelection("I", "Input Prompt Demo")
 | 
	
		
			
				|  |  | +	m.AddSelection("P", "Progress Bars Demo")
 | 
	
		
			
				|  |  | +	m.AddSelection("S", "Show Panel")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	m.AddSelection("Q", "Quit")
 | 
	
		
			
				|  |  | +	return m
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func display_information(d *door.Door) {
 | 
	
		
			
				|  |  | +	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	keyColor := door.ColorText("BRI GREEN")
 | 
	
		
			
				|  |  | +	sepColor := door.ColorText("BRI YEL")
 | 
	
		
			
				|  |  | +	valColor := door.ColorText("CYAN")
 | 
	
		
			
				|  |  | +	nice_format := func(key string, value string) string {
 | 
	
		
			
				|  |  | +		return fmt.Sprintf("%s%-20s %s: %s%s", keyColor, key, sepColor, valColor, value) + door.CRNL
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(nice_format("BBS Software", d.Config.BBSID))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Real Name", d.Config.Real_name))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Handle", d.Config.Handle))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("User #", strconv.Itoa(d.Config.User_number)))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Security Level", strconv.Itoa(d.Config.Security_level)))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Node #", strconv.Itoa(d.Config.Node)))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Unicode", strconv.FormatBool(door.Unicode)))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("CP437", strconv.FormatBool(door.CP437)))
 | 
	
		
			
				|  |  | +	d.Write(nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height)))
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func display_ansi(d *door.Door) {
 | 
	
		
			
				|  |  | +	space := SPACE()
 | 
	
		
			
				|  |  | +	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | +	for _, line := range space {
 | 
	
		
			
				|  |  | +		if door.Unicode {
 | 
	
		
			
				|  |  | +			d.Write(door.CP437_to_Unicode(line) + door.CRNL)
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			d.Write(line + door.CRNL)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func input_demo(d *door.Door) {
 | 
	
		
			
				|  |  | +	inputColor := door.ColorText("BRI WHI ON BLUE")
 | 
	
		
			
				|  |  | +	inputColor2 := door.ColorText("BRI WHI ON GREEN")
 | 
	
		
			
				|  |  | +	prompt := door.Line{Text: "What is YOUR Name: "}
 | 
	
		
			
				|  |  | +	prompt.RenderF = door.RenderBlueYellow
 | 
	
		
			
				|  |  | +	d.Write(prompt.Output() + inputColor)
 | 
	
		
			
				|  |  | +	name := d.Input(25)
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | +	prompt.Text = "What is Your Quest: "
 | 
	
		
			
				|  |  | +	d.Write(prompt.Output() + inputColor2)
 | 
	
		
			
				|  |  | +	quest := d.Input(35)
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | +	prompt.Text = "What is your Favorite CoLoR: "
 | 
	
		
			
				|  |  | +	d.Write(prompt.Output() + inputColor2)
 | 
	
		
			
				|  |  | +	color := d.Input(15)
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | +	d.Write(fmt.Sprintf("You're %s on the %s quest, and fond of %s."+door.CRNL, name, quest, color))
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func progress_bars(d *door.Door) {
 | 
	
		
			
				|  |  | +	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bar := door.BarLine{Line: door.Line{DefaultColor: door.ColorText("BOLD YELLOW")}, Width: 20, Style: door.HALF_STEP}
 | 
	
		
			
				|  |  | +	bar2 := door.BarLine{Width: 30, Style: door.SOLID, PercentStyle: door.PERCENT_SPACE}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bar2.ColorRange = []door.BarRange{
 | 
	
		
			
				|  |  | +		{2500, door.ColorText("RED")},
 | 
	
		
			
				|  |  | +		{5000, door.ColorText("BROWN")},
 | 
	
		
			
				|  |  | +		{7500, door.ColorText("BOLD YEL")},
 | 
	
		
			
				|  |  | +		{9500, door.ColorText("GREEN")},
 | 
	
		
			
				|  |  | +		{10100, door.ColorText("BRI GRE")}}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bar3 := door.BarLine{Width: 15, Style: door.GRADIENT, Line: door.Line{DefaultColor: door.ColorText("CYAN")}}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	var percentage int64
 | 
	
		
			
				|  |  | +	bar.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | +	bar2.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | +	bar3.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	update_bars := func() {
 | 
	
		
			
				|  |  | +		bar.Update()
 | 
	
		
			
				|  |  | +		bar2.Update()
 | 
	
		
			
				|  |  | +		bar3.Update()
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(door.Goto(3, 12) + "Half-Step")
 | 
	
		
			
				|  |  | +	d.Write(door.Goto(25, 12) + "% with space and Color Range")
 | 
	
		
			
				|  |  | +	d.Write(door.Goto(57, 12) + "Gradient")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bar_start := door.Goto(3, 15)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for f := 0; f <= 100; f++ {
 | 
	
		
			
				|  |  | +		percentage = int64(f * 100)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		update_bars()
 | 
	
		
			
				|  |  | +		d.Write(bar_start + bar.Output() + "  " + door.Reset + bar2.Output() + door.Reset + "  " + bar3.Output())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if d.Disconnected {
 | 
	
		
			
				|  |  | +			// don't continue to sleep if we're disconnected
 | 
	
		
			
				|  |  | +			break
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		time.Sleep(time.Millisecond * 100)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func panel_demo(d *door.Door) {
 | 
	
		
			
				|  |  | +	width := 55
 | 
	
		
			
				|  |  | +	fmtStr := "%-55s"
 | 
	
		
			
				|  |  | +	p := door.Panel{X: 5, Y: 5, Width: width, Style: door.DOUBLE, BorderColor: door.ColorText("CYAN ON BLUE"), Title: "[ Panel Demo ]"}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	lineColor := door.ColorText("BRIGHT WHI ON BLUE")
 | 
	
		
			
				|  |  | +	// Add lines to the panel
 | 
	
		
			
				|  |  | +	for _, line := range []string{"The BBS Door Panel Demo", "(C) 2021 Red Green Software, https://red-green.com"} {
 | 
	
		
			
				|  |  | +		if door.Unicode {
 | 
	
		
			
				|  |  | +			line = strings.Replace(line, "(C)", "\u00a9", -1)
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		l := door.Line{Text: fmt.Sprintf(fmtStr, line), DefaultColor: lineColor}
 | 
	
		
			
				|  |  | +		p.Lines = append(p.Lines, l)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	p.Lines = append(p.Lines, p.Spacer())
 | 
	
		
			
				|  |  | +	p.Lines = append(p.Lines, door.Line{Text: fmt.Sprintf(fmtStr, "Welcome to golang!"), DefaultColor: lineColor})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | +	d.Write(p.Output())
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func createTable(db *sql.DB) {
 | 
	
		
			
				|  |  | +	db.Exec("CREATE TABLE IF NOT EXISTS settings(username TEXT, setting TEXT, value TEXT, PRIMARY KEY(username, setting));")
 | 
	
		
			
				|  |  | +	db.Exec("CREATE TABLE IF NOT EXISTS scores ( \"username\" TEXT, \"when\" INTEGER, \"date\" INTEGER, \"hand\" INTEGER, \"won\" INTEGER, \"score\" INTEGER, PRIMARY KEY(\"username\", \"date\", \"hand\"));")
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func main() {
 | 
	
		
			
				|  |  | +	var message string
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Get path to binary, and chdir to it.
 | 
	
		
			
				|  |  | +	binaryPath, _ := os.Executable()
 | 
	
		
			
				|  |  | +	binaryPath = filepath.Dir(binaryPath)
 | 
	
		
			
				|  |  | +	_ = os.Chdir(binaryPath)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	fmt.Println("Starting space-ace")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	rng := rand.New(mt19937.New())
 | 
	
		
			
				|  |  | +	rng.Seed(time.Now().UnixNano())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	sqliteDatabase, err := sql.Open("sqlite3", "./space-database.db")
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		fmt.Printf("%#v\n", err)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	defer sqliteDatabase.Close()
 | 
	
		
			
				|  |  | +	createTable(sqliteDatabase)
 | 
	
		
			
				|  |  | +	d := door.Door{}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Init("space-ace")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	s := StarField{}
 | 
	
		
			
				|  |  | +	s.Regenerate()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	s.Display(&d)
 | 
	
		
			
				|  |  | +	d.Write(door.Goto(1, 1) + door.Reset)
 | 
	
		
			
				|  |  | +	d.Key()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	bold := door.Color(1, 37, 40)
 | 
	
		
			
				|  |  | +	bolder := door.ColorText("BLI BOLD YEL ON BLUE")
 | 
	
		
			
				|  |  | +	d.Write("Welcome to " + bolder + "door32.sys" + door.Reset + door.CRNL + "..." + door.CRNL)
 | 
	
		
			
				|  |  | +	key := press_a_key(&d)
 | 
	
		
			
				|  |  | +	d.Write(fmt.Sprintf("Key %s%d / %x%s", bold, key, key, door.Reset) + door.CRNL)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	b := door.AlertBox("Warning: golang is in use!", 1)
 | 
	
		
			
				|  |  | +	d.Write(door.ColorText("BRI WHI ON GREEN"))
 | 
	
		
			
				|  |  | +	for _, line := range b {
 | 
	
		
			
				|  |  | +		d.Write(line + door.CRNL)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	left := d.TimeLeft()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	message = fmt.Sprintf("You have %0.2f minutes / %0.2f seconds remaining..."+door.CRNL, left.Minutes(), left.Seconds())
 | 
	
		
			
				|  |  | +	d.Write(message)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	press_a_key(&d)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	mainmenu := MainMenu()
 | 
	
		
			
				|  |  | +	var choice int
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for choice >= 0 {
 | 
	
		
			
				|  |  | +		d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | +		choice = mainmenu.Choose(&d)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if choice < 0 {
 | 
	
		
			
				|  |  | +			break
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		option := mainmenu.GetOption(choice)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		// fmt.Printf("Choice: %d, Option: %c\n", choice, option)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		switch option {
 | 
	
		
			
				|  |  | +		case 'A':
 | 
	
		
			
				|  |  | +			display_ansi(&d)
 | 
	
		
			
				|  |  | +			press_a_key(&d)
 | 
	
		
			
				|  |  | +		case 'D':
 | 
	
		
			
				|  |  | +			display_information(&d)
 | 
	
		
			
				|  |  | +			press_a_key(&d)
 | 
	
		
			
				|  |  | +		case 'I':
 | 
	
		
			
				|  |  | +			d.Write(door.Reset + door.CRNL + door.CRNL)
 | 
	
		
			
				|  |  | +			input_demo(&d)
 | 
	
		
			
				|  |  | +			press_a_key(&d)
 | 
	
		
			
				|  |  | +		case 'P':
 | 
	
		
			
				|  |  | +			progress_bars(&d)
 | 
	
		
			
				|  |  | +			press_a_key(&d)
 | 
	
		
			
				|  |  | +		case 'S':
 | 
	
		
			
				|  |  | +			panel_demo(&d)
 | 
	
		
			
				|  |  | +			press_a_key(&d)
 | 
	
		
			
				|  |  | +		case 'Q':
 | 
	
		
			
				|  |  | +			choice = -1
 | 
	
		
			
				|  |  | +			break
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	message = fmt.Sprintf("Returning to %s ..."+door.CRNL, d.Config.BBSID)
 | 
	
		
			
				|  |  | +	d.Write(message)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	d.WaitKey(1, 0)
 | 
	
		
			
				|  |  | +	left = d.TimeLeft()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	message = fmt.Sprintf("You had %0.2f minutes / %0.2f seconds remaining!"+door.CRNL, left.Minutes(), left.Seconds())
 | 
	
		
			
				|  |  | +	d.Write(message)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	left = d.TimeUsed()
 | 
	
		
			
				|  |  | +	d.Write(fmt.Sprintf("You used %0.2f seconds / %0.2f minutes."+door.CRNL, left.Seconds(), left.Minutes()))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	fmt.Println("Exiting space-ace")
 | 
	
		
			
				|  |  | +}
 |