├── README.md ├── donut.go └── go.mod /README.md: -------------------------------------------------------------------------------- 1 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 2 | -------------------------------------------------------------------------------- /donut.go: -------------------------------------------------------------------------------- 1 | /* 2 | I was inspired by this: https://www.youtube.com/watch?v=DEqXNfs_HhY 3 | 4 | "floatMemset" and "byteMemset" - analogue of memset from C 5 | https://stackoverflow.com/questions/30614165/is-there-analog-of-memset-in-go 6 | 7 | Original C code: https://www.dropbox.com/s/79ga2m7p2bnj1ga/donut_deobfuscated.c?dl=0 8 | */ 9 | 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | "math" 15 | "time" 16 | ) 17 | 18 | const ( 19 | delay = 16 * time.Millisecond // 60 fps hahaha 20 | coreString = ".,-~:;=!*#$@" 21 | ) 22 | 23 | type sliceType interface { 24 | len() int 25 | } 26 | 27 | func floatMemset(arr []float64, v float64) { 28 | for i := range arr { 29 | arr[i] = v 30 | } 31 | } 32 | 33 | func byteMemset(arr []string, v string) { 34 | for i := range arr { 35 | arr[i] = v 36 | } 37 | } 38 | 39 | func main() { 40 | A := float64(0) 41 | B := float64(0) 42 | 43 | var i, j float64 44 | var k int 45 | 46 | z := make([]float64, 1760) 47 | b := make([]string, 1760) 48 | 49 | fmt.Print("\033[H\033[2J") // clear previous stdout 50 | 51 | for { 52 | byteMemset(b, " ") 53 | floatMemset(z, 0) 54 | 55 | for j = 0; j < 6.28; j += 0.07 { 56 | for i = 0; i < 6.28; i += 0.02 { 57 | c := math.Sin(i) 58 | d := math.Cos(j) 59 | e := math.Sin(A) 60 | f := math.Sin(j) 61 | g := math.Cos(A) 62 | h := d + 2 63 | D := 1 / (c*h*e + f*g + 5) 64 | l := math.Cos(i) 65 | m := math.Cos(B) 66 | n := math.Sin(B) 67 | t := c*h*g - f*e 68 | 69 | x := int(40 + 30*D*(l*h*m-t*n)) 70 | y := int(12 + 15*D*(l*h*n+t*m)) 71 | 72 | o := int(x + 80*y) 73 | 74 | N := int(8 * ((f*e-c*d*g)*m - c*d*e - f*g - l*d*n)) 75 | 76 | if y < 22 && y > 0 && x > 0 && x < 80 && D > z[o] { 77 | z[o] = D 78 | 79 | // golang doesn't have ternary operator 80 | point := 0 81 | if N > 0 { 82 | point = N 83 | } 84 | 85 | b[o] = string(coreString[point]) 86 | } 87 | 88 | } 89 | } 90 | 91 | print("\x1b[H") 92 | 93 | for k = 0; k < 1761; k++ { 94 | 95 | v := "\n" 96 | 97 | if k%80 > 0 { 98 | v = string(b[k]) 99 | } 100 | 101 | fmt.Printf(v) 102 | 103 | A += 0.00004 104 | B += 0.00002 105 | } 106 | 107 | time.Sleep(delay) 108 | 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module ascii-render 2 | 3 | go 1.14 4 | --------------------------------------------------------------------------------