src/display.cpp

Thu, 12 Nov 2020 20:26:35 +0100

author
David Douard <david.douard@sdf3.org>
date
Thu, 12 Nov 2020 20:26:35 +0100
changeset 53
74e85b34d26b
parent 51
d8042bff0e00
child 54
f6774bd0d570
permissions
-rw-r--r--

Reorganize the display + improvements for dimmed flags

- the whole upper zone is now dediacated to the main character line
- make sure eash flag has a dedicated non-overlaping area
- improve support for dimmed flags (not yet properly functionning since this
dimm state is actually stateful, so some major refactorings are needed to
properly handle this).

#include "stdio.h"
#include <mbed.h>
#include <rtos.h>
#include "display.h"


Display::Display(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC,
				 const char* name)
		: SSD1322(Hz, mosi, miso, sclk, CS, reset, DC, name)
{
	must_refresh = 0;
}

Display::~Display()
{
}

void Display::show_splashscreen()
{
	locate(30, 10);
	set_font((unsigned char*)Mono19x27);
	this->printf("HP34970A");
	set_font((unsigned char*)Terminal6x8);
	locate(90, 40);
	this->printf("David Douard");
	copy_to_lcd();
}

void Display::show_byescreen()
{
	cls();
	background(0x00);
	foreground(0xFF);
	locate(30, 10);
	set_font((unsigned char*)Mono19x27);
	this->printf("Bye...");
	copy_to_lcd();
}

void Display::dimm_char(uint8_t n)
{
	// dimm the char number of the currently displayed string of the main area;
	// do this by printing a modifed version of the last displayed string
	// but only alphanumeric chars should be counted (not the punctuation)
	char c;
	uint8_t len, i, j;
	// for which we need to look for the entry in the table
	for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
		if (table[i].cmd == 0x00) {

			background(table[i].bgcolor);
			foreground(table[i].color / 2);  // dimmed
			set_font((unsigned char*) table[i].font);
			locate(table[i].x0, table[i].y0);

			len = strlen(table[i].buffer);
			if (n >= len)
				break;  // nothing to do
			//::printf("DIMM CHAR %d\n", n);
			//::printf("  in (len=%d) '%s'\n", len, table[i].buffer);

			for (j=0; (j<len); j++)
			{
				// advae the location up to the char to dimm
				c = table[i].buffer[j];
				if ((c == ',') || (c == '.') || (c == ';') || (c == ':'))
					// it's a "zero" width char, skip it
					n++;
				if (n == 0)
				{
					//::printf("  Found at pos %d char '%c'\n", j, c);
					// found it
					character(c);
					break;
				}
				// otherwise, just advance the char_x
				//::printf("  move %d for '%c' [%X]\n", , c, c);
				char_width(c, true);
				n--;
			}
		}
	}
}

void Display::show(uint8_t cmd, const char *intxt, uint8_t nchar=0)
{
	uint8_t i;
	// uint8_t len;
	uint16_t bgcolor, fgcolor;
	char *oldv;
	// char *txt;
	char *txtp;
	static char txt[64];


	if (cmd == 0xFF) // cls
	{
		clrbuff();
	}
	else if (cmd == 0x0D)
	{ // dimm a character of the main area
		dimm_char(intxt[0]);
	}
	else
	{
		pixel_buffer_mutex.lock();
		for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
			if (table[i].cmd == cmd) {
				strcpy(txt, intxt);
				txtp = txt;

				bgcolor = table[i].bgcolor;
				fgcolor = table[i].color;
				background(bgcolor);
				foreground(fgcolor);
				set_font((unsigned char*) table[i].font);
				oldv = table[i].buffer;

				locate(table[i].x0, table[i].y0);

				if (table[i].fmt & FMT_ASCII)  // ASCII text
				{
					// check if the string has changed since last time
					if (true) //(strncmp(oldv, txt, table[i].maxsize) != 0)
					{
						// clear the text area
						if (table[i].width > 0)
							fillrect(table[i].x0,
									 table[i].y0,
									 table[i].x0 + table[i].width,
									 table[i].y0 + table[i].font[2] - 1,
									 bgcolor);
						// draw chars by portions of string separated by \t (highlight)
						for (uint8_t k=0; ;k++)
						{
							if (txtp[k] == 0x00)
							{ // end of string, display it
								this->printf(txtp);
								break;
							}
							if (txtp[k] == 0x09)
							{ // \t is a special char for 'unselected' display value
								// first disply the beginning of the string
								txtp[k] = 0x00;
								this->printf(txtp);

								// swap the fg color (dimm/bright)
								if (fgcolor == table[i].color)
									fgcolor /= 2;
								else
									fgcolor = table[i].color;
								foreground(fgcolor);
								// continue on the next with part of the string
								txtp = &(txtp[k+1]);
								k = 0;
							}
						}
						must_refresh = 1;
					}
				}
				/*
					if (table[i].fmt & FMT_HEX ) {
					// hex
					for (uint8_t j=0;; j++) {
					if (txt[j] == 0x00)
					break;
					this->printf("%02X ", txt[j]);
					}
					for (uint8_t j=3*strlen(txt); j<table[i].maxsize; j++)
					this->printf(" ");
					}
				*/
				if (table[i].fmt & FMT_FLAGS )  // flag indicators
				{
					uint8_t nbyte;
					uint8_t nbit;
					uint16_t color;
					// flags
					for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l)
					{
						nbyte = flags[l].flag / 8;
						nbit = flags[l].flag % 8;
						if (flags[l].dimm)
							color = fgcolor/4;
						else
							color = fgcolor;

						if (intxt[nbyte] & (1 << nbit))
						{  // draw the flag, possibly reversed fg/bg
							foreground(flags[l].reverse ? bgcolor : color);
							background(flags[l].reverse ? color : bgcolor);
						}
						else
						{  // erase the flag
							foreground(bgcolor);
							background(bgcolor);
						}
						if (flags[l].msg != NULL)
						{ // flag is a string
							locate(flags[l].x, flags[l].y);
							this->printf(flags[l].msg);}
						else
						{ // flag is an icon
							Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon};
							Bitmap_BW(pic, flags[l].x, flags[l].y);
						}
					}

					// draw frames (Alarm and Channel)
					for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l)
					{
						nbyte = frames[l].flag / 8;
						nbit = frames[l].flag % 8;
						if (intxt[nbyte] & (1 << nbit))
							color = fgcolor/6;
						else
							color = bgcolor;
						hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color);
						hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color);
						hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color);

						vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color);
						vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color);
					}
					must_refresh = 1; //|= zones[m].flag;
				}

				for(uint8_t j=0; j<table[i].maxsize; j++)
					oldv[j] = txt[j];
				break;
			}
		}
		pixel_buffer_mutex.unlock();

		//free(txt);
		//this->copy_to_lcd();
	}
}


void Display::set_flag(uint8_t flag, bool show, bool dimm)
{
	uint8_t i;
	uint8_t bgcolor = 0x00, fgcolor = 0x0F;

	if (dimm)
		fgcolor = fgcolor / 4;

	for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l)
	{
		if (flag == flags[l].flag)
		{
			set_font((unsigned char*)Terminal6x8);
			::printf("  %s flag %x %s\n", show ? "show": "hide", flag, dimm ? "dimmed":"bright");
			if (show)
			{
				foreground(flags[l].reverse ? bgcolor : fgcolor);
				background(flags[l].reverse ? fgcolor : bgcolor);
			}
			else
			{
				foreground(bgcolor);
				background(bgcolor);
			}
			if (flags[l].msg != NULL)
			{ // flag is a string
				locate(flags[l].x, flags[l].y);
				::printf("Move cursor at %dx%d\n", flags[l].x, flags[l].y);
				::printf("  using fgcolor=%x\n", fgcolor);
				this->printf(flags[l].msg);}
			else
			{ // flag is an icon
				Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon};
				Bitmap_BW(pic, flags[l].x, flags[l].y);
			}
		}
	}

	// draw frames (Alarm and Channel)
	for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l)
	{
		if (flag == frames[l].flag)
		{
			uint16_t color;
			if (show)
				color = fgcolor/6;
			else
				color = bgcolor;
			hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color);
			hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color);
			hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color);

			vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color);
			vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color);
		}
	}
	must_refresh = 1;
}


void Display::test_dsp()
{
	const FRAME *z;
	printf("TEST DSP\r\n");
	cls();
	printf("TEST DSP #2\r\n");
	show(0x00, "8g8g8g8g8g8g8", 13); // main dsp
	show(0x0C, "888", 3); // channel dsp
	show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags
	copy_to_lcd();
	ThisThread::sleep_for(3ms);
	cls();
	printf("TEST DSP #3\r\n");
	/*
	for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++)
	{
		z = &zones[i];
		fillrect(z->x0, z->y0, z->x1, z->y1, 4+i);
		locate(z->x0+1, z->y0+1);
		this->printf("%d", i);
	}
	*/
	/*
		for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++)
		{
		z = &zones[i];
		printf("Zone %d [%x]: %d, %d, %d, %d\n", i, z->flag,
		z->x0, z->y0, z->x1, z->y1);
		must_refresh = z->flag;
		wait(1);
		}
		printf("Done\n");
		wait(2);
		printf("Copy ALL\n");
		copy_to_lcd();
	*/
	ThisThread::sleep_for(2ms);
	cls();
	printf("TEST DSP DONE\r\n");
}

mercurial