package main import ( "fmt" "log" "red-green/door" "runtime/debug" "strconv" "strings" "time" ) 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 press_a_key(d *door.Door) int { d.Write(door.Reset + door.CRNL + "Press a key to continue...") k := d.Key() d.Write(door.CRNL) return k } 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 WHITE"), door.ColorText("BOLD CYAN")) 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("C", "Crash") m.AddSelection("D", "Display Information (dropfile, screen)") m.AddSelection("F", "Font Demo") m.AddSelection("I", "Input Prompt Demo") m.AddSelection("M", "Menu 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("Full CP437", strconv.FormatBool(door.Full_CP437))) d.Write(nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height))) } func display_ansi(d *door.Door) { art := GROWL() d.Write(door.Clrscr) for _, line := range art { if door.Unicode { d.Write(door.CP437_to_Unicode(line) + door.CRNL) } else { d.Write(line + door.CRNL) } } } func font_demo(d *door.Door) { var output [][]byte var l int var centering string d.Write(door.Clrscr) // + door.CRNL + door.CRNL) fac := FontAmazonCyan() output, l = fac.Output("ABCDEFGHIJKL") if l > door.Width { output, l = fac.Output("Cyan") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(fmt.Sprintf("%s%s%s", centering, CP437Bytes_to_Unicode(o), door.Reset) + door.CRNL) } else { d.Write(fmt.Sprintf("%s%s%s", centering, string(o), door.Reset) + door.CRNL) } } d.Write(door.CRNL) } fab := FontAnarchyBlue() output, l = fab.Output("Bugz is Here!") if l > door.Width { output, l = fab.Output("Hello") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } unchain := FontUnchained() output, l = unchain.Output("Hi There!") if l > door.Width { output, l = unchain.Output("Meow") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } press_a_key(d) asylum := FontAsylum() output, l = asylum.Output("Bugz ROCKS") if l > door.Width { output, l = asylum.Output("Aslym") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } brain := FontBrainDmgBlu() output, l = brain.Output("I'm so BLUE") if l > door.Width { output, l = brain.Output("Blue") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } boner := FontBoner() output, l = boner.Output("Welcome!") if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } press_a_key(d) descent := FontDescent() output, l = descent.Output("Meanwhile...") if l > door.Width { output, l = descent.Output("BUGZ") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } remorse := FontRemorse() output, l = remorse.Output("Enjoy the fonts") if l > door.Width { output, l = remorse.Output("Amazing") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(door.CRNL) } dungeon := FontDungeon() output, l = dungeon.Output("Until NEXT time") if l > door.Width { output, l = dungeon.Output("Beware") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { if door.Unicode { d.Write(centering + CP437Bytes_to_Unicode(o) + door.Reset + door.CRNL) } else { d.Write(centering + string(o) + door.Reset + door.CRNL) } } d.Write(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") d.Write(door.HideCursor) 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) } d.Write(door.ShowCursor) } 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}) single := door.Panel{X: 6, Y: 12, Width: 10, Style: door.SINGLE, BorderColor: door.ColorText("WHITE ON BLUE"), Title: "< Single >"} single.Lines = append(single.Lines, door.Line{Text: "Example ", DefaultColor: door.ColorText("WHI ON BLACK")}) ds := door.Panel{X: 26, Y: 12, Width: 15, Style: door.DOUBLE_SINGLE, BorderColor: door.ColorText("BRI CYAN ON GREEN"), Title: "Double", TitleOffset: 3} ds.Lines = append(ds.Lines, door.Line{Text: "Double / Single", DefaultColor: door.ColorText("BRI WHI ON GREEN")}) sd := door.Panel{X: 46, Y: 12, Width: 15, Style: door.SINGLE_DOUBLE, BorderColor: door.ColorText("BRI YELL ON RED")} sd.Lines = append(sd.Lines, door.Line{Text: "Single / Double", DefaultColor: door.ColorText("BRI WHI ON RED")}) d.Write(door.Clrscr) d.Write(p.Output()) d.Write(single.Output()) d.Write(ds.Output()) d.Write(sd.Output()) } func main() { var message string fmt.Println("Starting testdoor.go") d := door.Door{} d.Init() defer func() { if err := recover(); err != nil { log.Println("FAILURE:", err) // Display error to user d.Write(fmt.Sprintf(door.Reset+door.CRNL+"Exception: %v"+door.CRNL, err)) // This displays stack trace stderr debug.PrintStack() } }() 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 + door.HideCursor) choice = mainmenu.Choose(&d) d.Write(door.ShowCursor) 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 'F': font_demo(&d) press_a_key(&d) case 'I': d.Write(door.Reset + door.CRNL + door.CRNL) input_demo(&d) press_a_key(&d) case 'M': d.Write(door.Reset + door.CRNL + "TO DO: Provide menu of options to select from..." + door.CRNL) 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 case 'C': z := 0 a := 10 / z z = a } } d.Write(door.Reset + door.CRNL) message = fmt.Sprintf("Returning to the %s BBS..."+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("Ending testdoor.go") }