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(" "); } |