aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2017-03-19 11:27:32 +0100
committertomsmeding <tom.smeding@gmail.com>2017-03-19 11:27:32 +0100
commitac500f4a786d975b492cc879bf6195a066b0a398 (patch)
tree66f8015b78ba3e57f02cbe1af0bd76425155c22f
parent5c61d5f9c3b21df1a41de6960a9e67f21805bdc2 (diff)
Add colours to terminal sim output
-rw-r--r--screenbuffer.cpp41
-rw-r--r--screenbuffer.h18
-rw-r--r--world.cpp14
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();
diff --git a/world.cpp b/world.cpp
index 5d82073..1d5efa3 100644
--- a/world.cpp
+++ b/world.cpp
@@ -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(" ");
}