1 // Copyright 2022 Garrett D'Amore 2 // 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE or https://www.boost.org/LICENSE_1_0.txt) 5 6 /** 7 * Colors (Dcell) 8 */ 9 module color; 10 11 import std.stdio; 12 import std.string; 13 import std.concurrency; 14 import std.random; 15 import std.range; 16 import dcell; 17 18 class ColorBoxes 19 { 20 import std.random; 21 22 int r; 23 int g; 24 int b; 25 int ri; 26 int gi; 27 int bi; 28 Random rng; 29 enum inc = 8; 30 int cnt; 31 32 bool flip() 33 { 34 return (rng.uniform!ubyte() & 0x1) != 0; 35 } 36 37 this() 38 { 39 rng = rndGen(); 40 r = rng.uniform!ubyte(); 41 g = rng.uniform!ubyte(); 42 b = rng.uniform!ubyte(); 43 ri = inc; 44 gi = inc / 4; // humans are very sensitive to green 45 bi = inc; 46 } 47 48 void makeBox(Screen s) 49 { 50 Coord wsz = s.size(); 51 dchar dc = ' '; 52 Style style; 53 cnt++; 54 55 if (s.colors() == 0) 56 { 57 dchar[] glyphs = ['@', '#', '&', '*', '=', '%', 'Z', 'A']; 58 dc = choice(glyphs, rng); 59 if (flip()) 60 style.attr |= Attr.reverse; 61 else 62 style.attr &= ~Attr.reverse; 63 } 64 else 65 { 66 r += ri; 67 g += gi; 68 b += bi; 69 if (r >= 256 || r < 0) 70 { 71 ri = -ri; 72 r += ri; 73 } 74 if (g >= 256 || g < 0) 75 { 76 gi = -gi; 77 g += gi; 78 } 79 if (b >= 256 || b < 0) 80 { 81 bi = -bi; 82 b += bi; 83 } 84 if (cnt % (256 / inc) == 0) 85 { 86 if (flip()) 87 { 88 ri = -ri; 89 } 90 91 if (flip()) 92 { 93 gi = -gi; 94 } 95 96 if (flip()) 97 { 98 bi = -bi; 99 } 100 } 101 style.bg = fromHex( 102 int(r) << 15 | int(g) << 8 | int(b)); 103 } 104 105 // half the width and half the height 106 Coord c1 = Coord(wsz.x / 4, wsz.y / 4); 107 Coord c2 = Coord(c1.x + wsz.x / 2, c1.y + wsz.y / 2); 108 Coord pos = c1; 109 Cell cell = Cell(dc, style); 110 for (pos.y = c1.y; pos.y <= c2.y; pos.y++) 111 { 112 for (pos.x = c1.x; pos.x <= c2.x; pos.x++) 113 { 114 s[pos] = cell; 115 } 116 } 117 s.show(); 118 } 119 } 120 121 void main() 122 { 123 import std.stdio; 124 import core.time; 125 import core.stdc.stdlib; 126 127 auto s = newScreen(); 128 assert(s !is null); 129 ColorBoxes cb = new ColorBoxes(); 130 131 auto now = MonoTime.currTime(); 132 133 s.start(); 134 bool done = false; 135 while (!done) 136 { 137 cb.makeBox(s); 138 auto ev = s.receiveEvent(msecs(50)); 139 switch (ev.type) 140 { 141 case EventType.key: 142 switch (ev.key.key) 143 { 144 case Key.esc, Key.enter: 145 done = true; 146 break; 147 case Key.ctrlL: 148 s.resize(); 149 s.sync(); 150 break; 151 default: 152 153 } 154 break; 155 case EventType.resize: 156 s.resize(); 157 break; 158 case EventType.closed: 159 done = true; 160 break; 161 case EventType.error: 162 assert(0, "errror received"); 163 default: 164 } 165 } 166 auto end = MonoTime.currTime(); 167 s.stop(); 168 writefln("Drew %d boxes in %s.", cb.cnt, end - now); 169 writefln("Average per box %s.", (end - now) / cb.cnt); 170 }