package main import ( "fmt" "log" "red-green/door" "runtime/debug" "strconv" "strings" "time" // "net/http" // _ "net/http/pprof" "github.com/mitchellh/go-wordwrap" ) //go:generate sh -c "font-util extract -f 'Amazon Cyan,Serpent,Unchained,Asylum,ArmageonRed,BrainDmgBlu,Boner,Descent,Remorse,Dungeon' ../TDFONTS.TDF ../TDFONTS2.TDF ../TDFONTS9.TDF > fonts.go" //go:generate sh -c "font-util extract -f Armageddon -c 7,1 -c 4,2 ../TDFONTS2.TDF > rgfont.go; sed -i 's/Armageddon/RedGreen/g' rgfont.go" func pctUpdate(pct *int64) func() int64 { return func() int64 { return *pct } } func press_keys(d *door.Door) { d.Write(door.Reset + door.CRNL + "Press some keys... to exit.") var r rune var ex door.Extended var err error for (r != 0x0d) && (err == nil) { r, ex, err = d.WaitKey(door.Inactivity) if ex == door.MOUSE { m, ok := d.GetMouse() if ok { // var m door.MouseInfo = door.Mouse d.Write(fmt.Sprintf("M %d (%d,%d) ", m.Button, m.X, m.Y)) } } else { if ex == door.NOP { d.Write(fmt.Sprintf("%d (%x) ", r, r)) } else { d.Write(fmt.Sprintf("<%s> ", ex.String())) } } } d.Write(door.Reset + door.CRNL) } func press_a_key(d *door.Door) error { var err error var ex door.Extended d.Write(door.Reset + door.CRNL + "Press a key, or LEFT mouse click to continue...") for { _, ex, err = d.WaitKey(door.Inactivity) if ex == door.MOUSE { m, ok := d.GetMouse() if ok { if m.Button == 1 { break } } } else { break } } d.Write(door.CRNL) return err } func about_test_door(d *door.Door) { var W int = 60 var center_x int = (door.Width - W) / 2 var center_y int = (door.Height - 16) / 2 var about door.Panel = door.Panel{X: center_x, Y: center_y, Width: W, Style: door.SINGLE_DOUBLE, BorderColor: door.ColorText("BOLD YELLOW ON BLUE"), } about.Lines = append(about.Lines, door.Line{Text: fmt.Sprintf("%*s", -W, "About This Door"), DefaultColor: door.ColorText("BOLD CYAN ON BLUE")}) about.Lines = append(about.Lines, about.Spacer()) about.Lines = append(about.Lines, door.Line{Text: fmt.Sprintf("%*s", -W, "Test Door written in go, using go door.")}) var copyright string = "(C) 2022 Bugz, Red Green Software" if door.Unicode { copyright = strings.Replace(copyright, "(C)", "\u00a9", -1) } about.Lines = append(about.Lines, door.Line{Text: copyright, Width: W, DefaultColor: door.ColorText("BOLD WHITE ON BLUE")}) for _, text := range []string{"", "This door was written by Bugz.", "", "It is written in Go, detects CP437/unicode, detects screen", "size, supports door.sys & door32.sys, supports TheDraw Fonts", "(the fonts are compiled into the door), has NoMoreSecrets", "and SpinRite effects, and runs on Linux", "and sometimes even Windows..."} { about.Lines = append(about.Lines, door.Line{Text: text, Width: W}) } var better door.NoMoreSecretsConfig = door.NoMoreSecretsDefault better.Jumble_Loop_Speed = 75 // 35 better.Reveal_Loop_Speed = 100 // 50 better.Color = door.ColorText("BRI CYAN ON BLUE") door.NoMoreSecrets(about.Output(), d, &better) } func MainMenu() door.Menu { // Make the main menu // Width was 45 var menu door.Menu = door.Menu{Panel: door.Panel{Width: 35, X: 2, Y: 5, Style: door.DOUBLE, Title: "[ Main Menu: ]", TitleOffset: 3, BorderColor: door.ColorText("BRI CYAN ON BLA")}} menu.SelectedR = door.MakeMenuRender(door.ColorText("BOLD CYAN"), door.ColorText("BOLD BLUE"), door.ColorText("BOLD WHITE"), door.ColorText("BOLD CYAN")) menu.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")) menu.AddSelection("A", "ANSI Display") // m.AddSelection("C", "Crash") menu.AddSelection("D", "Display Information") menu.AddSelection("F", "Font Demo") menu.AddSelection("I", "Input Prompt Demo") menu.AddSelection("M", "Menu Demo") menu.AddSelection("P", "Progress Bars Demo") menu.AddSelection("S", "Show Panel") menu.AddSelection("T", "Test Door About") menu.AddSelection("W", "Screen Width") menu.AddSelection("Q", "Quit") var descriptions []string = []string{ // 12345678901234567890123456789012345678901234567890 "Display an ANSI file. It is compiled into the door itself.", // "Crash go, see a handled error.", // The error shows up in the logs. "Display dropfile information.", "Display TheDraw Fonts. Font information is compiled into the door.", "Input some values, while updating the time.", "Isn't this is a menu?", "Display progress bar styles: half step, display percentage, and gradient.", "Show multiple panels. Panels can be mouse drag/drop around.", "Show about the door, using NoMoreSecrets effect.", "Examples using the full width of the screen.", "Exit this door.", } var widthLeft int = door.Width - (menu.Width + menu.X + 2) var panelWidth int = widthLeft - (2 + 2) var maxLines int = 1 var maxLineLength int // Calculate the max lines needed for each line. for _, line := range descriptions { var wrapped string = wordwrap.WrapString(line, uint(panelWidth)) var lines int = len(strings.Split(wrapped, "\n")) if lines > maxLines { maxLines = lines } if len(line) > maxLineLength { maxLineLength = len(line) } } if maxLines == 1 { // Ok! Everything fits into one line, SO use max line length as width of panel. panelWidth = maxLineLength } // Position the description panel beside the menu. m.Width + m.X + 2 (1 one to give it a space) var descPanel door.Panel = door.Panel{X: menu.Width + menu.X + 2 + 1, Y: menu.Y, Width: panelWidth, Style: door.SINGLE, BorderColor: door.ColorText("WHI ON BLU")} for x := 0; x < maxLines; x++ { descPanel.Lines = append(descPanel.Lines, door.Line{Text: "", Width: panelWidth}) } menu.Activated = func(item int, d *door.Door) { var line string = descriptions[item] var lines []string = strings.Split(wordwrap.WrapString(line, uint(panelWidth)), "\n") for idx := range descPanel.Lines { if idx >= len(lines) { descPanel.Lines[idx].Text = "" } else { descPanel.Lines[idx].Text = lines[idx] } } d.Write(door.SavePos + descPanel.Output() + door.RestorePos) } return menu } func display_information(d *door.Door) { d.Write(door.Clrscr) var headerColor string = door.ColorText("BRI CYAN") var keyColor string = door.ColorText("BRI GREEN") var sepColor string = door.ColorText("BRI YEL") var valColor string = door.ColorText("CYAN") var nice_format func(string, string) string = func(key string, value string) string { return fmt.Sprintf("%s%-20s %s: %s%s", keyColor, key, sepColor, valColor, value) + door.CRNL } var offset string var header string = "DropFile: " offset = strings.Repeat(" ", len(header)) d.Write(headerColor + header) d.Write(nice_format("Comm Type", strconv.Itoa(d.Config.Comm_type))) if d.Config.BBSID != "" { d.Write(offset + nice_format("BBS Software", d.Config.BBSID)) } d.Write(offset + nice_format("Time Left", strconv.Itoa(d.Config.Time_left))) d.Write(offset + nice_format("Real Name", d.Config.Real_name)) // d.Write(nice_format("Comm Handle", strconv.Itoa(d.Config.Comm_handle))) d.Write(offset + nice_format("Handle", d.Config.Handle)) d.Write(offset + nice_format("User #", strconv.Itoa(d.Config.User_number))) d.Write(offset + nice_format("Security Level", strconv.Itoa(d.Config.Security_level))) d.Write(offset + nice_format("Node #", strconv.Itoa(d.Config.Node))) header = "Detected: " offset = strings.Repeat(" ", len(header)) d.Write(door.CRNL + headerColor + header) d.Write(nice_format("Unicode", strconv.FormatBool(door.Unicode))) d.Write(offset + nice_format("CP437", strconv.FormatBool(door.CP437))) d.Write(offset + nice_format("Full CP437", strconv.FormatBool(door.Full_CP437))) d.Write(offset + nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height))) var time time.Duration = d.TimeLeft() d.Write(offset + nice_format("Door Time Left", fmt.Sprintf("%d Hours, %d Minutes, %d Seconds", int(time.Hours()), int(time.Minutes())%60, int(time.Seconds())%60))) time = d.TimeUsed() d.Write(offset + nice_format("Door Time Used", fmt.Sprintf("%d Minutes, %d Seconds", int(time.Minutes()), int(time.Seconds())%60))) press_a_key(d) d.Write(door.Clrscr + door.CRNL + door.CRNL + door.CRNL) modules := GetModules() header = "Build: " offset = strings.Repeat(" ", len(header)) d.Write(headerColor + header) gover, gitver, goarch, goos := GetVersion() d.Write(nice_format("go version", gover)) d.Write(offset + nice_format("git commit", gitver)) d.Write(offset + nice_format("Arch", goarch)) d.Write(offset + nice_format("OS", goos)) for mod, version := range modules { d.Write(offset + nice_format(mod, version)) } } func display_ansi(d *door.Door) { var art []string = ANSIGrowl() d.Write(door.Clrscr) for _, line := range art { d.Write(line + door.CRNL) } } func font_demo(d *door.Door) { var output []string var l int var centering string var now time.Time = time.Now() // I have checks here (but not all are complete), that verify the font // output doesn't exceed the size of the screen. d.Write(door.Clrscr + door.CRNL) // + door.CRNL + door.CRNL) var fac door.ColorFont = FontAmazonCyan() output, l = fac.Output(now.Format("Jan Mon")) // Size check: Is this too big for the screen? /* if l > door.Width { output, l = fac.Output("Jan") } */ if l < door.Width { centering = "" // centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL) } d.Write(door.CRNL) } var patch door.ColorMap = fac.Scan(6) // log.Printf("Patch: %#v\n", patch) fac.Modify(4, patch) output, l = fac.Output(now.Format("Monday")) centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL) } d.Write(door.CRNL) fac.Modify(1, patch) output, l = fac.Output(now.Format("January")) // 3:04:05 PM")) centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL) } d.Write(door.CRNL) press_a_key(d) // Anarchy Blue - no digits var fab door.ColorFont = FontSerpent() output, l = fab.Output("Date/Time:") if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } var unchain door.ColorFont = FontUnchained() now = time.Now() output, l = unchain.Output(now.Format("01/02/2006")) if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } output, l = unchain.Output(now.Format("3:04:05 PM")) if l > door.Width { output, l = unchain.Output("Meow") } if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } press_a_key(d) var asylum door.ColorFont = 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 { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } var brain door.ColorFont = 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 { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } var boner door.ColorFont = FontBoner() output, l = boner.Output("Welcome!") if l < door.Width { centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } press_a_key(d) var descent door.ColorFont = 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 { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } var remorse door.ColorFont = 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 { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } var dungeon door.ColorFont = 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 { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } /* redgreen := FontArmageddon() white := redgreen.Scan(7) blue := redgreen.Scan(4) redgreen.Modify(1, white) redgreen.Modify(2, blue) */ redgreen := FontRedGreen() output, l = redgreen.Output("Red-Green") if l < door.Width { press_a_key(d) centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) output, l = redgreen.Output("Software") centering = strings.Repeat(" ", (door.Width-l)/2) for _, o := range output { d.Write(centering + o + door.Reset + door.CRNL) } d.Write(door.CRNL) } } func input_demo(d *door.Door) { var ticker *time.Ticker = time.NewTicker(time.Second) var StopIt = make(chan bool) go func() { for { select { case <-StopIt: return case t := <-ticker.C: const tf = "January 2, 2006 03:04:05 PM MST" output := door.SavePos + door.Goto(5, 2) + door.ColorText("BRI WHI ON CYAN") + t.Format(tf) + door.RestorePos d.Write(output) } } }() var inputColor string = door.ColorText("BRI WHI ON BLUE") var inputColor2 string = door.ColorText("BRI WHI ON GREEN") var prompt door.Line = door.Line{Text: "What is YOUR Name: "} prompt.RenderF = door.RenderBlueYellow d.Write(prompt.Output() + inputColor) var name string = d.Input(25) d.Write(door.Reset + door.CRNL) prompt.Text = "What is Your Quest: " d.Write(prompt.Output() + inputColor2) var quest string = d.Input(35) d.Write(door.Reset + door.CRNL) prompt.Text = "What is your Favorite CoLoR: " d.Write(prompt.Output() + inputColor) var color string = d.Input(15) d.Write(door.Reset + door.CRNL) ticker.Stop() StopIt <- true 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) var bar door.BarLine = door.BarLine{Line: door.Line{DefaultColor: door.ColorText("BOLD YELLOW")}, Width: 20, Style: door.HALF_STEP} var bar2 door.BarLine = door.BarLine{Width: 30, Style: door.SOLID, PercentStyle: door.PERCENT_SPACE} bar2.ColorRange = []door.BarRange{ {Percent: 2500, Color: door.ColorText("RED")}, {Percent: 5000, Color: door.ColorText("BROWN")}, {Percent: 7500, Color: door.ColorText("BOLD YEL")}, {Percent: 9500, Color: door.ColorText("GREEN")}, {Percent: 10100, Color: door.ColorText("BRI GRE")}} var bar3 door.BarLine = 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++ { d.Write(door.Goto(3, 10) + door.Reset + fmt.Sprintf("Value: %d", f)) percentage = int64(f * 100) update_bars() d.Write(bar_start + bar.Output() + " " + door.Reset + bar2.Output() + door.Reset + " " + bar3.Output()) if d.Disconnect() { // don't continue to sleep if we're disconnected break } time.Sleep(time.Millisecond * 100) } d.Write(door.ShowCursor) } func width_demo(d *door.Door) { var w int = door.Width var panel door.Panel = door.Panel{X: 1, Y: 1, Width: w} var lineColor string = door.ColorText("WHI") var line string for y := 1; y <= door.Height; y++ { if y%10 == 0 { line = strings.Repeat("1234567890", w/10) for x := len(line); x < w; x++ { line += strconv.Itoa((x + 1) % 10) } } else { line = "" for x := 1; x < w; x++ { if x%10 == 0 { line += strconv.Itoa(y % 10) } else { line += " " } } } var l door.Line = door.Line{Text: line, DefaultColor: lineColor} panel.Lines = append(panel.Lines, l) } var message string = fmt.Sprintf("Screen Size: %d X %d", door.Width, door.Height) d.Write(panel.Output()) // Output alert on top of panel var cx, cy int cx = (door.Width - len(message) + 2) / 2 cy = (door.Height - 3) / 2 var alert []string = door.AlertBox(message, 1) d.Write(door.ColorText("BRI YEL ON BLUE")) for idx, ab := range alert { d.Write(door.Goto(cx, cy+idx) + ab) } d.Write(door.Reset + panel.GotoEnd()) // Pause for key d.WaitKey(door.Inactivity) panel.Lines = make([]door.Line, 0) var background string = "BUGZ Test Door in GO " var bl int = len(background) for y := 1; y <= door.Height; y++ { offset := (y - 1) % bl line = background[offset:] for len(line) < w { if len(line)+bl <= w { line += background } else { line += background[0 : w-len(line)] } } var l door.Line = door.Line{Text: line, RenderF: door.RenderBlueYellow} panel.Lines = append(panel.Lines, l) } d.Write(panel.Output()) d.WaitKey(door.Inactivity) } type TrackPanels struct { Panel *door.Panel XPos int YPos int BColor string } func FindPanel(m door.Mouse, panels []TrackPanels) int { for idx, p := range panels { hit, _, _ := p.Panel.Within(int(m.X), int(m.Y)) if hit { return idx } } return -1 } func panel_demo(d *door.Door) { var width int = 55 var panel door.Panel = door.Panel{X: 5, Y: 5, Width: width, Style: door.DOUBLE, BorderColor: door.ColorText("CYAN ON BLUE"), Title: "[ Panel Demo ]"} var moveColor string = door.ColorText("CYAN ON BLACK") var lineColor string = 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) } var l door.Line = door.Line{Text: line, Width: width, DefaultColor: lineColor} panel.Lines = append(panel.Lines, l) } panel.Lines = append(panel.Lines, panel.Spacer()) panel.Lines = append(panel.Lines, door.Line{Text: "Welcome to golang!", Width: width, DefaultColor: lineColor}) width = 10 var single door.Panel = door.Panel{X: 6, Y: 12, Width: width, Style: door.SINGLE, BorderColor: door.ColorText("WHITE ON BLUE"), Title: "< Single >"} single.Lines = append(single.Lines, door.Line{Text: "Example", Width: width, DefaultColor: door.ColorText("WHI ON BLACK")}) single.Lines = append(single.Lines, single.Spacer()) single.Lines = append(single.Lines, door.Line{Text: "More Text", Width: width, DefaultColor: door.ColorText("BRI GREEN ON BLACK")}) width = 15 var double_single door.Panel = door.Panel{X: 26, Y: 12, Width: width, Style: door.DOUBLE_SINGLE, BorderColor: door.ColorText("BRI CYAN ON GREEN"), Title: "Double", TitleOffset: 3} double_single.Lines = append(double_single.Lines, door.Line{Text: "Double / Single", Width: width, DefaultColor: door.ColorText("BRI WHI ON GREEN")}) double_single.Lines = append(double_single.Lines, double_single.Spacer()) double_single.Lines = append(double_single.Lines, door.Line{Text: "Some Other Text", Width: width, DefaultColor: door.ColorText("BRI CYAN ON GREEN")}) var single_double door.Panel = door.Panel{X: 46, Y: 12, Width: width, Style: door.SINGLE_DOUBLE, BorderColor: door.ColorText("BRI YELL ON RED")} single_double.Lines = append(single_double.Lines, door.Line{Text: "Single / Double", Width: width, DefaultColor: door.ColorText("BRI WHI ON RED")}) single_double.Lines = append(single_double.Lines, single_double.Spacer()) single_double.Lines = append(single_double.Lines, door.Line{Text: "Text Goes Here ", Width: width, DefaultColor: door.ColorText("BRI GREEN ON RED")}) d.Write(door.Clrscr) d.Write(panel.Output()) d.Write(single.Output()) d.Write(double_single.Output()) d.Write(single_double.Output()) d.Write(door.Goto(1, 20) + door.Reset + "Use MOUSE to click/drag panels, Right-Click Exits, R to Reset, Q to quit...") var panels []TrackPanels = []TrackPanels{ {&panel, panel.X, panel.Y, panel.BorderColor}, {&single, single.X, single.Y, single.BorderColor}, {&double_single, double_single.X, double_single.Y, single.BorderColor}, {&single_double, single_double.X, single_double.Y, single_double.BorderColor}} var movingPanel *door.Panel var moveX, moveY int var panelColor string for { key, ex, err := d.WaitKey(door.Inactivity) if err != nil { return } if ex == door.MOUSE { m, ok := d.GetMouse() if ok { // Process Mouse Event if m.Button == 3 { // Exit on right click return } if m.Button == 1 { idx := FindPanel(m, panels) if idx != -1 { movingPanel = panels[idx].Panel panelColor = movingPanel.BorderColor moveX = int(m.X) moveY = int(m.Y) } else { continue } // Should we do something to the panel? Yes! movingPanel.BorderColor = moveColor d.Update(movingPanel.Output()) } else if m.Button == 4 { if movingPanel != nil { PR, PB := movingPanel.RightBottomPos() log.Printf("Panel (%d,%d) End(%d,%d) W %d, L %d\n", movingPanel.X, movingPanel.Y, PR, PB, movingPanel.Width, movingPanel.Length()) // Ok, panel is move! d.Update(movingPanel.Clear()) // Restore panel border movingPanel.BorderColor = panelColor // move panel movingPanel.X -= (moveX - int(m.X)) movingPanel.Y -= (moveY - int(m.Y)) // sanity checks if movingPanel.X < 1 { movingPanel.X = 1 } // var edgeX bool if movingPanel.X+movingPanel.Width >= door.Width { movingPanel.X = door.Width - movingPanel.Width - 1 // edgeX = true } if movingPanel.Y < 1 { movingPanel.Y = 1 } // var edgeY bool if movingPanel.Y+movingPanel.Length() >= door.Height { movingPanel.Y = door.Height - movingPanel.Length() - 1 // edgeY = true } PR, PB = movingPanel.RightBottomPos() log.Printf("Panel Now (%d,%d) End (%d,%d) %d, %d\n", movingPanel.X, movingPanel.Y, PR, PB, movingPanel.Width, movingPanel.Length()) //, edgeX, edgeY) // If panel is at the end of the screen -- it scrolls (syncterm) // This "fixes" it. (Maybe a better way would be to not use last // line on the screen?) // Or another way: if PR == door.Width && PB == door.Height { movingPanel.X-- } /* if edgeX && edgeY { movingPanel.X-- log.Printf("Panel adjust X\n") } */ d.Update(movingPanel.Output()) } movingPanel = nil } } } else { if (key == 'Q') || (key == 'q') || (key == '\x1b') { return } if (key == 'R') || (key == 'r') { for _, p := range panels { d.Update(p.Panel.Clear()) } for _, p := range panels { p.Panel.X = p.XPos p.Panel.Y = p.YPos p.Panel.BorderColor = p.BColor d.Update(p.Panel.Output()) } } if key == '0' { d.Write(panels[0].Panel.GotoEnd()) } if key == '1' { d.Write(panels[1].Panel.GotoEnd()) } } } } func main() { var message string /* go func() { http.ListenAndServe(":6060", nil) }() */ var d door.Door = door.Door{} d.Init("testdoor") defer func() { if err := recover(); err != nil { // This displays stack trace stderr debug.PrintStack() fmt.Println("ERROR:", err) log.Println("FAILURE:", err) // Display error to user d.Write(fmt.Sprintf(door.Reset+door.CRNL+"Exception: %v"+door.CRNL, err)) } }() defer d.Close() // Updaters work best when the screen doesn't scroll, so start // us off at the very top. d.Write(door.Clrscr) // Start spinrite effects var ticker *time.Ticker = time.NewTicker(time.Millisecond * time.Duration(100)) var spin door.SpinRiteMsg = door.SpinRiteMsgInit(15, 5, door.ColorText("RED ON GREEN"), []string{"RED", "GREEN", "SOFTWARE"}) var spin2 door.SpinRite = door.SpinRiteInit(13, 5, door.ColorText("BRI CYA ON BLUE")) // Add in the GoRoutine Status panel var goPanel door.Panel = door.Panel{X: 0, Y: 1, Width: 18, Style: door.DOUBLE, Title: "] GoRoutines [", BorderColor: door.ColorText("BOLD YEL ON BLU"), } goLineUpdater := func() string { status := GoRoutinesStatus() // log.Println(status) return status } var goLine door.Line = door.Line{ UpdateF: goLineUpdater, Width: goPanel.Width, } // goLine.Update() // Force Update goPanel.Lines = append(goPanel.Lines, goLine) goPanel.Lines = append(goPanel.Lines, door.Line{Width: goPanel.Width}) var lIndex int = 0 var legendCount int = 0 const legendUpdate = 20 go func() { var output string var legend []string = []string{ "R=run r=Runnable", "S=Select s=Syscall", "Chan write", "Z=Sleep P=Preempt", "I=Idle D=Dead", "W=Wait C=Copystk", } goPanel.Lines[1].Text = legend[0] for range ticker.C { // output = door.SavePos + door.Goto(door.Width-16, 1) + spin.Output() + // door.Goto(door.Width-15, 3) + spin2.Output() + door.RestorePos legendCount++ if legendCount >= legendUpdate { legendCount = 0 lIndex++ if lIndex == len(legend) { lIndex = 0 } goPanel.Lines[1].Text = legend[lIndex] } if goPanel.X == 0 { goPanel.X = door.Width - 40 } goPanel.Update() output = door.Goto(door.Width-16, 1) + spin.Output() + door.Goto(door.Width-15, 3) + spin2.Output() + goPanel.Output() if !d.Disconnect() { d.Update(output) } else { ticker.Stop() return } } }() var wopr door.WOPR wopr.Init(d.StartTime, d.TimeOut, "") // TimeUsed(), d.TimeLeft(), "") wopr.ElapsedPanel.X = door.Width - 19 wopr.ElapsedPanel.Y = door.Height - 15 wopr.RemainingPanel.X = door.Width - 19 wopr.RemainingPanel.Y = door.Height - 8 wopr.Animate(&d) // bold := door.Color(1, 37, 40) var bolder string = door.ColorText("BOLD YEL ON BLUE") d.Write("Welcome to " + bolder + "go door go TestDoor." + door.Reset + door.CRNL + "..." + door.CRNL) d.EnableMouse(door.Normal) press_a_key(&d) d.Write(door.CRNL) var b []string if door.CP437 { b = door.AlertBox("Alert: go \xfb is in use!", 1) } else { b = door.AlertBox("Alert: go \u221a is in use!", 1) } warningColor := door.ColorText("BRI WHI ON GREEN") for _, line := range b { // Prevent color bleeding. d.Write(warningColor + line + door.Reset + door.CRNL) } d.Write(door.Reset + door.CRNL) var left time.Duration = 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) var mainmenu door.Menu = 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) wopr.Stop() // Clear WOPR panels. d.Write(door.Reset + wopr.Clear()) r, b := mainmenu.Panel.RightBottomPos() d.Write(door.Goto(r, b)) // 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': // Why is this so far down on the screen? (Scrolls) 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 'T': about_test_door(&d) press_a_key(&d) case 'W': width_demo(&d) case 'Q': // This is also far down on the screen ... choice = -1 case 'C': // Disabled var a, z int z = 0 a = 10 / z z = a _ = a _ = z } wopr.Animate(&d) } // d.Write("\x1b[?1000l") // disable mouse // d.Write("\x1b[?1002l") d.DisableMouse() d.Write(door.Reset + door.CRNL) if d.Config.BBSID != "" { message = fmt.Sprintf("Returning to the %s BBS..."+door.CRNL, d.Config.BBSID) } else { message = "Returning to the BBS..." + door.CRNL } d.Write(message) d.WaitKey(time.Second) left = d.TimeLeft() ticker.Stop() message = fmt.Sprintf("You had %0.2f minutes remaining!"+door.CRNL, left.Minutes()) 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") }