spinrite.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package door
  2. type SpinRite struct {
  3. Width uint8 // Width of the animation (must be odd)
  4. Length uint8 // Width of the worm (must be odd)
  5. Color string // Color (default CYAN ON BLUE)
  6. OutputB []byte // Output CP437/bytes (Width)
  7. OutputR []rune // Output Unicode (Width)
  8. Buffer []uint8 // Output calculate buffer (Width)
  9. Runes []rune // blank, center, top, bottom, both
  10. Bytes []byte // blank, center, top, bottom, both
  11. CenterPos uint8 // Center Position (Width - 1) / 2
  12. StartPos uint8 // Starting Position (Length -1) / 2
  13. Index uint8 // Index of current iteration
  14. }
  15. func SpinRiteInit(width uint8, length uint8, color string) SpinRite {
  16. if color == "" {
  17. color = ColorText("CYAN ON BLUE")
  18. }
  19. var center uint8 = ((width - 1) / 2)
  20. var start uint8 = ((length - 1) / 2)
  21. var result SpinRite = SpinRite{Width: width,
  22. Length: length,
  23. Color: color,
  24. CenterPos: center,
  25. StartPos: start,
  26. Buffer: make([]uint8, width),
  27. Index: 0}
  28. if Unicode {
  29. result.OutputR = make([]rune, width)
  30. result.Runes = []rune{' ', '\u221e', '\u2580', '\u2584', '\u2588'}
  31. } else {
  32. result.OutputB = make([]byte, width)
  33. result.Bytes = []byte{' ', 0xec, 0xdf, 0xdc, 0xdb}
  34. }
  35. return result
  36. }
  37. func (sr *SpinRite) PosToIndex(pos int8, top bool) (index uint8, level bool) {
  38. if top {
  39. if pos >= int8(sr.Width) {
  40. // wrap around
  41. level = !top
  42. idx := int8(sr.Width) + (int8(sr.Width) - (pos + 1))
  43. index = uint8(idx)
  44. } else {
  45. level = top
  46. index = uint8(pos)
  47. }
  48. } else {
  49. // bottom
  50. if pos < 0 {
  51. level = !top
  52. pos++
  53. index = uint8(-pos)
  54. } else {
  55. level = top
  56. index = uint8(pos)
  57. }
  58. }
  59. return
  60. }
  61. func (sr *SpinRite) Calculate() {
  62. for i := range sr.Buffer {
  63. sr.Buffer[i] = 0
  64. }
  65. sr.Buffer[sr.CenterPos] = 1
  66. // [ S C s ]
  67. var top int8 = int8(sr.CenterPos) - int8(sr.StartPos) + int8(sr.Index)
  68. var bottom int8 = int8(sr.CenterPos) + int8(sr.StartPos) - int8(sr.Index)
  69. var l int8
  70. for l = 0; l < int8(sr.Length); l++ {
  71. var index uint8
  72. var level bool
  73. index, level = sr.PosToIndex(top+l, true)
  74. // log.Println("TOP", l, top+l, index, level)
  75. if level {
  76. sr.Buffer[index] |= 0x02
  77. } else {
  78. sr.Buffer[index] |= 0x04
  79. }
  80. index, level = sr.PosToIndex(bottom-l, false)
  81. // log.Println("BOT", l, bottom-l, index, level)
  82. if level {
  83. sr.Buffer[index] |= 0x02
  84. } else {
  85. sr.Buffer[index] |= 0x04
  86. }
  87. }
  88. // log.Println("Index", sr.Index, "Buffer", sr.Buffer)
  89. var reset bool = true
  90. // Convert from buffer to output
  91. if Unicode {
  92. for l = 0; l < int8(sr.Width); l++ {
  93. switch sr.Buffer[l] {
  94. case 0:
  95. sr.OutputR[l] = sr.Runes[0]
  96. case 1:
  97. sr.OutputR[l] = sr.Runes[1]
  98. reset = false
  99. case 2, 3:
  100. sr.OutputR[l] = sr.Runes[2]
  101. reset = false
  102. case 4, 5:
  103. sr.OutputR[l] = sr.Runes[3]
  104. reset = false
  105. case 6, 7:
  106. sr.OutputR[l] = sr.Runes[4]
  107. }
  108. }
  109. } else {
  110. for l = 0; l < int8(sr.Width); l++ {
  111. switch sr.Buffer[l] {
  112. case 0:
  113. sr.OutputB[l] = sr.Bytes[0]
  114. case 1:
  115. sr.OutputB[l] = sr.Bytes[1]
  116. reset = false
  117. case 2, 3:
  118. sr.OutputB[l] = sr.Bytes[2]
  119. reset = false
  120. case 4, 5:
  121. sr.OutputB[l] = sr.Bytes[3]
  122. reset = false
  123. case 6, 7:
  124. sr.OutputB[l] = sr.Bytes[4]
  125. }
  126. }
  127. }
  128. if reset {
  129. // log.Println("RESET")
  130. sr.Index = 0
  131. }
  132. }
  133. func (sr *SpinRite) Output() string {
  134. var result string
  135. sr.Calculate()
  136. if Unicode {
  137. result = string(sr.OutputR)
  138. } else {
  139. result = string(sr.OutputB)
  140. }
  141. sr.Index++
  142. return sr.Color + result
  143. }
  144. type SpinRiteMsg struct {
  145. SpinRite
  146. Messages []string
  147. MsgIndex int
  148. Next bool
  149. }
  150. func SpinRiteMsgInit(width uint8, length uint8, color string, messages []string) SpinRiteMsg {
  151. var result SpinRiteMsg = SpinRiteMsg{SpinRite: SpinRiteInit(width, length, color)}
  152. if Unicode {
  153. result.Runes[1] = result.Runes[0]
  154. } else {
  155. result.SpinRite.Bytes[1] = result.SpinRite.Bytes[0]
  156. }
  157. result.Messages = messages
  158. result.MsgIndex = 0
  159. result.Next = false
  160. return result
  161. }
  162. func (sr *SpinRiteMsg) Output() string {
  163. var result string
  164. sr.Calculate()
  165. if sr.Next && sr.Index == 0 {
  166. sr.MsgIndex++
  167. if sr.MsgIndex == len(sr.Messages) {
  168. sr.MsgIndex = 0
  169. }
  170. }
  171. if sr.Index != 0 {
  172. sr.Next = true
  173. }
  174. // Place message
  175. var msg string = sr.Messages[sr.MsgIndex]
  176. var pos int = int(sr.CenterPos) - (len(msg) / 2)
  177. for i := 0; i < len(msg); i++ {
  178. if Unicode {
  179. if sr.OutputR[pos+i] == ' ' {
  180. sr.OutputR[pos+i] = []rune(msg)[i]
  181. }
  182. } else {
  183. if sr.OutputB[pos+i] == ' ' {
  184. sr.OutputB[pos+i] = byte(msg[i])
  185. }
  186. }
  187. }
  188. if Unicode {
  189. result = string(sr.OutputR)
  190. } else {
  191. result = string(sr.OutputB)
  192. }
  193. sr.Index++
  194. return sr.Color + result
  195. }
  196. /*
  197. Or possibly: · ∞
  198. [ █████ ]
  199. [ ▄▄███▀▀ ]
  200. [ ▄▄▄▄█▀▀▀▀ ]
  201. [ ▄▄▄▄▄•▀▀▀▀▀ ]
  202. [▄▄▄▄▄ • ▀▀▀▀▀]
  203. [█▄▄▄ • ▀▀▀█]
  204. [██▄ • ▀██]
  205. [██▀ • ▄██]
  206. [█▀▀▀ • ▄▄▄█]
  207. [█▀▀▀▀ • ▄▄▄▄█]
  208. [ ▀▀▀▀▀•▄▄▄▄▄ ]
  209. [ ▀▀▀▀█▄▄▄▄ ]
  210. [ ▀▀███▄▄ ]
  211. */