1 /*
2 * bit_display.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7 
8 #include "bit_display.h"
9 #include "dingl.h"
10 
bit_display(int w,int h)11 bit_display::bit_display (int w, int h) {
12 	num_bits = 0;
13 	lsnr = 0;
14 	prev_id = -1;
15 	set_size (w, h);
16 }
17 
set_size(int w,int h)18 void bit_display::set_size (int w, int h) {
19 	set_extents (extents.left, extents.bottom, extents.left + w, extents.bottom + h);
20 	set_pos (posx, posy);
21 }
22 
set_pos(int x,int y)23 void bit_display::set_pos (int x, int y) {
24 	widget::set_pos (x, y);
25 	calc_visual_params ();
26 }
27 
set(void * bytes,int num_bytes)28 void bit_display::set (void* bytes, int num_bytes) { // show bits of the given bytes
29 	num_bits = 8 * num_bytes;
30 	last_bit = num_bits - 1;
31 	bits.resize (num_bits); // init bit array
32 	unsigned char* pchar = (unsigned char *) bytes; // treat as character array
33 	for (int i = 0, k = 0; i < num_bytes; ++i) { // number of bytes = number of characters now
34 		unsigned char ci = pchar[i]; // ith character
35 		for (int j = 0; j < 8; ++j) { // extract bits of this character and store in bit array
36 			unsigned char tb = (ci & 0x80) >> 7; // extract left most bit
37 			bits[k++] = tb;
38 			ci = ci << 1; // left shift character by 1 bit
39 		}
40 	}
41 	calc_visual_params ();
42 }
43 
calc_visual_params()44 void bit_display::calc_visual_params () {
45 	if (num_bits) {
46 		d_width = int (extents.width / num_bits); // display width for each bit
47 		int width = d_width * num_bits; // total width occupied by displayed bits
48 		xstart = extents.left;
49 		xend = xstart + width;
50 	}
51 }
52 
53 extern int mousex, mouseyy;
54 
find_bit_id()55 int bit_display::find_bit_id () {
56 	if (mousex < xstart) return 0;
57 	else if (mousex > xend) return last_bit;
58 	return (mousex - xstart) / d_width;;
59 }
60 
handle_input()61 int bit_display::handle_input () {
62 	int ret = widget::handle_input ();
63 	if (hover) {
64 		if (lmb) {
65 			cur_id = find_bit_id ();
66 			if (cur_id != prev_id) {
67 				prev_id = cur_id;
68 				bits[cur_id] = !bits[cur_id];
69 				if (lsnr) lsnr->changed (*this);
70 			}
71 		} else prev_id = -1;
72 	}
73 	return ret;
74 }
75 
draw()76 void bit_display::draw () {
77 	glColor3f (clr.r, clr.g, clr.b);
78 	glPolygonMode (GL_FRONT, GL_LINE);
79 	glRecti (xstart, extents.bottom, xend, extents.top);
80 	int xl = xstart, xr = xl;
81 	for (int i = 0; i < num_bits; ++i) {
82 		unsigned char bi = bits[i];
83 		if (bi) glPolygonMode (GL_FRONT, GL_FILL); else glPolygonMode (GL_FRONT, GL_LINE);
84 		xr = xl + d_width;
85 		glRecti (xl, extents.bottom, xr, extents.top);
86 		xl = xr;
87 	}
88 	glPolygonMode (GL_FRONT, GL_FILL);
89 }
90 
get_color(ucolor_t * uc)91 void bit_display::get_color (ucolor_t* uc) {
92 	unsigned char* pchar = (unsigned char*) uc;
93 	for (int i = 0, j = 0; i < 3; ++i) {
94 		unsigned char uci = 0;
95 		for (int k = 7; k > -1; --k) {
96 			unsigned char bj = bits[j++];
97 			uci = uci | (bj << k);
98 		}
99 		pchar[i] = uci;
100 	}
101 }
102