| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 | 
							- package door
 
- import "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 = Blank
 
- 1 = Center Character
 
- 2 = Top
 
- 3 = Bottom
 
- 4 = 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
 
- }
 
 
  |