diff options
| author | tomsmeding <tom.smeding@gmail.com> | 2017-03-19 11:27:32 +0100 | 
|---|---|---|
| committer | tomsmeding <tom.smeding@gmail.com> | 2017-03-19 11:27:32 +0100 | 
| commit | ac500f4a786d975b492cc879bf6195a066b0a398 (patch) | |
| tree | 66f8015b78ba3e57f02cbe1af0bd76425155c22f | |
| parent | 5c61d5f9c3b21df1a41de6960a9e67f21805bdc2 (diff) | |
Add colours to terminal sim output
| -rw-r--r-- | screenbuffer.cpp | 41 | ||||
| -rw-r--r-- | screenbuffer.h | 18 | ||||
| -rw-r--r-- | world.cpp | 14 | 
3 files changed, 64 insertions, 9 deletions
| diff --git a/screenbuffer.cpp b/screenbuffer.cpp index d224181..781e646 100644 --- a/screenbuffer.cpp +++ b/screenbuffer.cpp @@ -10,6 +10,15 @@  using namespace std; +bool operator!=(const ScreenBuffer::Style &a,const ScreenBuffer::Style &b){ +	return memcmp(&a,&b,sizeof(ScreenBuffer::Style))!=0; +} + +bool operator!=(const ScreenBuffer::Cell &a,const ScreenBuffer::Cell &b){ +	return memcmp(&a,&b,sizeof(ScreenBuffer::Cell))!=0; +} + +  static void initTerminal(){  	cout<<"\x1B[?1049h"  // start alternate screen  	      "\x1B[2J"  // clear screen @@ -25,10 +34,8 @@ static void deinitTerminal(){  ScreenBuffer::ScreenBuffer(int W,int H)  		:W(W),H(H){ -	screen=new char[W*H]; -	prevscreen=new char[W*H]; -	memset(screen,' ',W*H); -	memset(prevscreen,' ',W*H); +	screen=new Cell[W*H]; +	prevscreen=new Cell[W*H];  	initTerminal();  } @@ -56,7 +63,8 @@ void ScreenBuffer::printstr(const char *buf){  				curx=basex;  				cury++;  			} -			screen[W*cury+curx]=buf[i]; +			screen[W*cury+curx].c=buf[i]; +			screen[W*cury+curx].style=curstyle;  			curx++;  		} else {  			if(cury==H-1)break; @@ -103,6 +111,16 @@ int ScreenBuffer::mvprintf(int x,int y,const char *format,...){  	return ret;  } +void ScreenBuffer::setfg(int fg){ +	assert((fg>=0&&fg<=7)||fg==9); +	curstyle.fg=fg; +} + +void ScreenBuffer::setbg(int bg){ +	assert((bg>=0&&bg<=7)||bg==9); +	curstyle.bg=bg; +} +  void ScreenBuffer::draw(){  	bool changed[W*H];  	for(int i=0;i<W*H;i++){ @@ -116,6 +134,8 @@ void ScreenBuffer::draw(){  	bool prepped=false; +	Style termstyle; +  	for(int y=0;y<H;y++){  		bool needtomove=true;  		for(int x=0;x<W;x++){ @@ -124,14 +144,19 @@ void ScreenBuffer::draw(){  				continue;  			}  			if(!prepped){ -				cout<<"\x1B[?25l";  // invisible cursor +				cout<<"\x1B[?25l"  // invisible cursor +				      "\x1B[0m";  // reset style  				prepped=true;  			}  			if(needtomove){  				cout<<"\x1B["<<y+1<<';'<<x+1<<'H';  				needtomove=false;  			} -			cout.put(screen[W*y+x]); +			if(screen[W*y+x].style!=termstyle){ +				cout<<"\x1B[0;3"<<screen[W*y+x].style.fg<<";4"<<screen[W*y+x].style.bg<<"m"; +				termstyle=screen[W*y+x].style; +			} +			cout.put(screen[W*y+x].c);  		}  	}  	if(prepped){ @@ -140,7 +165,7 @@ void ScreenBuffer::draw(){  		    <<flush;  	} -	memcpy(prevscreen,screen,W*H); +	memcpy(prevscreen,screen,W*H*sizeof(Cell));  }  void ScreenBuffer::emergencyDeinit(){ diff --git a/screenbuffer.h b/screenbuffer.h index 7a2883e..a461145 100644 --- a/screenbuffer.h +++ b/screenbuffer.h @@ -6,13 +6,26 @@ using namespace std;  class ScreenBuffer{ +	struct Style{ +		int fg=9,bg=9; +	}; + +	struct Cell{ +		char c=' '; +		Style style; +	}; +  	int W,H; -	char *prevscreen,*screen; +	Cell *prevscreen,*screen;  	int curx=0,cury=0; +	Style curstyle;  	void printstr(const char *buf);  	int printf_varargs(const char *format,va_list ap); +	friend bool operator!=(const ScreenBuffer::Style &a,const ScreenBuffer::Style &b); +	friend bool operator!=(const ScreenBuffer::Cell &a,const ScreenBuffer::Cell &b); +  public:  	ScreenBuffer(int W,int H);  	~ScreenBuffer(); @@ -21,6 +34,9 @@ public:  	int printf(const char *format,...) __attribute__((format (printf, 2, 3)));  	int mvprintf(int x,int y,const char *format,...) __attribute__((format (printf, 4, 5))); +	void setfg(int fg); +	void setbg(int bg); +  	void draw();  	void emergencyDeinit(); @@ -1,6 +1,7 @@  #include <cstdlib>  #include <cassert>  #include <cstring> +#include <unordered_map>  #include "world.h" @@ -351,6 +352,17 @@ Robot* World::targetbot(const Robot *r){  	return *targetbotptr(r);  } +static int colourCode(const Team *team){ +	static unordered_map<const Team*,int> mappings; +	static int nextCode=1; +	auto it=mappings.find(team); +	if(it!=mappings.end())return it->second; +	int code=nextCode; +	mappings[team]=code; +	nextCode=nextCode%6+1; +	return code; +} +  void World::print(ScreenBuffer &sb) const {  	for(int y=0;y<SIZE;y++){  		sb.moveto(0,y); @@ -359,7 +371,9 @@ void World::print(ScreenBuffer &sb) const {  			else {  				char c2="^>v<"[board[y][x]->heading%4];  				char c1=board[y][x]->active?c2:'X'; +				sb.setfg(colourCode(board[y][x]->team));  				sb.printf("%c%c",c1,c2); +				sb.setfg(9);  			}  			sb.printf(" ");  		} | 
