| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 | package doorimport "strings"type SpinRite struct {	Width     uint8   // Width of the animation (must be odd)	Length    uint8   // Width of the worm (must be odd)	Color     string  // Color (default CYAN ON BLUE)	OutputB   []byte  // Output CP437/bytes (Width)	OutputR   []rune  // Output Unicode (Width)	Buffer    []uint8 // Output calculate buffer (Width)	Runes     []rune  // blank, center, top, bottom, both	Bytes     []byte  // blank, center, top, bottom, both	CenterPos uint8   // Center Position (Width - 1) / 2	StartPos  uint8   // Starting Position (Length -1) / 2	Index     uint8   // Index of current iteration}/*Other center character options: · ∞We default to ∞[    █████    ][   ▄▄███▀▀   ][  ▄▄▄▄█▀▀▀▀  ][ ▄▄▄▄▄•▀▀▀▀▀ ][▄▄▄▄▄ • ▀▀▀▀▀][█▄▄▄  •  ▀▀▀█][██▄   •   ▀██][██▀   •   ▄██][█▀▀▀  •  ▄▄▄█][█▀▀▀▀ • ▄▄▄▄█][ ▀▀▀▀▀•▄▄▄▄▄ ][  ▀▀▀▀█▄▄▄▄  ][   ▀▀███▄▄   ]*//*0 = Blank1 = Center Character2 = Top3 = Bottom4 = Full Block*/func SpinRiteInit(width uint8, length uint8, color string) SpinRite {	if color == "" {		color = ColorText("CYAN ON BLUE")	}	var center uint8 = ((width - 1) / 2)	var start uint8 = ((length - 1) / 2)	var result SpinRite = SpinRite{Width: width,		Length:    length,		Color:     color,		CenterPos: center,		StartPos:  start,		Buffer:    make([]uint8, width),		Index:     0}	if Unicode {		result.OutputR = make([]rune, width)		result.Runes = []rune{' ', '\u221e', '\u2580', '\u2584', '\u2588'}	} else {		result.OutputB = make([]byte, width)		result.Bytes = []byte{' ', 0xec, 0xdf, 0xdc, 0xdb}	}	return result}func (sr *SpinRite) PosToIndex(pos int8, top bool) (index uint8, level bool) {	if top {		if pos >= int8(sr.Width) {			// wrap around			level = !top			idx := int8(sr.Width) + (int8(sr.Width) - (pos + 1))			index = uint8(idx)		} else {			level = top			index = uint8(pos)		}	} else {		// bottom		if pos < 0 {			level = !top			pos++			index = uint8(-pos)		} else {			level = top			index = uint8(pos)		}	}	return}func (sr *SpinRite) Calculate() {	for i := range sr.Buffer {		sr.Buffer[i] = 0	}	sr.Buffer[sr.CenterPos] = 1	// [    S C s    ]	var top int8 = int8(sr.CenterPos) - int8(sr.StartPos) + int8(sr.Index)	var bottom int8 = int8(sr.CenterPos) + int8(sr.StartPos) - int8(sr.Index)	var l int8	for l = 0; l < int8(sr.Length); l++ {		var index uint8		var level bool		index, level = sr.PosToIndex(top+l, true)		// log.Println("TOP", l, top+l, index, level)		if level {			sr.Buffer[index] |= 0x02		} else {			sr.Buffer[index] |= 0x04		}		index, level = sr.PosToIndex(bottom-l, false)		// log.Println("BOT", l, bottom-l, index, level)		if level {			sr.Buffer[index] |= 0x02		} else {			sr.Buffer[index] |= 0x04		}	}	// log.Println("Index", sr.Index, "Buffer", sr.Buffer)	var reset bool = true	// Convert from buffer to output	if Unicode {		for l = 0; l < int8(sr.Width); l++ {			switch sr.Buffer[l] {			case 0:				sr.OutputR[l] = sr.Runes[0]			case 1:				sr.OutputR[l] = sr.Runes[1]				reset = false			case 2, 3:				sr.OutputR[l] = sr.Runes[2]				reset = false			case 4, 5:				sr.OutputR[l] = sr.Runes[3]				reset = false			case 6, 7:				sr.OutputR[l] = sr.Runes[4]			}		}	} else {		for l = 0; l < int8(sr.Width); l++ {			switch sr.Buffer[l] {			case 0:				sr.OutputB[l] = sr.Bytes[0]			case 1:				sr.OutputB[l] = sr.Bytes[1]				reset = false			case 2, 3:				sr.OutputB[l] = sr.Bytes[2]				reset = false			case 4, 5:				sr.OutputB[l] = sr.Bytes[3]				reset = false			case 6, 7:				sr.OutputB[l] = sr.Bytes[4]			}		}	}	if reset {		// log.Println("RESET")		sr.Index = 0	}}func (sr *SpinRite) Output() string {	// var result string	var result strings.Builder	// sr.Result.Reset()	result.WriteString(sr.Color)	sr.Calculate()	if Unicode {		// result = string(sr.OutputR)		/*			for _, r := range sr.OutputR {				result.WriteRune(r)			}		*/		result.WriteString(string(sr.OutputR))	} else {		//result = string(sr.OutputB)		result.WriteString(string(sr.OutputB))	}	sr.Index++	// return sr.Color + result	return result.String()}type SpinRiteMsg struct {	SpinRite	Messages []string	MsgIndex int	Next     bool}func SpinRiteMsgInit(width uint8, length uint8, color string, messages []string) SpinRiteMsg {	var result SpinRiteMsg = SpinRiteMsg{SpinRite: SpinRiteInit(width, length, color)}	if Unicode {		result.Runes[1] = result.Runes[0]	} else {		result.SpinRite.Bytes[1] = result.SpinRite.Bytes[0]	}	result.Messages = messages	result.MsgIndex = 0	result.Next = false	return result}func (sr *SpinRiteMsg) Output() string {	var result string	sr.Calculate()	if sr.Next && sr.Index == 0 {		sr.MsgIndex++		if sr.MsgIndex == len(sr.Messages) {			sr.MsgIndex = 0		}	}	if sr.Index != 0 {		sr.Next = true	}	// Place message	var msg string = sr.Messages[sr.MsgIndex]	var pos int = int(sr.CenterPos)	// Bug:  If we're changing to next message (sr.Next == True) ... but the	// message is > SpinRite.Length, it shows the text beyond what it should.	var texthalf int = StringLen(msg) / 2	// Place text center, outwards.  Stopping if there's no space.	for i := 0; i < texthalf+1; i++ {		if Unicode {			if sr.OutputR[pos+i] == ' ' {				if texthalf+i < StringLen(msg) {					sr.OutputR[pos+i] = []rune(msg)[texthalf+i]				}			} else {				break			}			if i != 0 {				if sr.OutputR[pos-i] == ' ' {					sr.OutputR[pos-i] = []rune(msg)[texthalf-i]				} else {					break				}			}		} else {			if sr.OutputB[pos+i] == ' ' {				if texthalf+i < StringLen(msg) {					sr.OutputB[pos+i] = byte(msg[texthalf+i])				}			} else {				break			}			if i != 0 {				if sr.OutputB[pos-i] == ' ' {					sr.OutputB[pos-i] = byte(msg[texthalf-i])				} else {					break				}			}		}	}	/*		for i := 0; i < len(msg); i++ {			if Unicode {				if sr.OutputR[pos+i] == ' ' {					sr.OutputR[pos+i] = []rune(msg)[i]				}			} else {				if sr.OutputB[pos+i] == ' ' {					sr.OutputB[pos+i] = byte(msg[i])				}			}		}	*/	if Unicode {		result = string(sr.OutputR)	} else {		result = string(sr.OutputB)	}	sr.Index++	return sr.Color + result}
 |