Path: blob/main/misc/emulator/xnes/snem/drawansi.h
28550 views
#ifndef uint161#define uint16 unsigned short2#endif3#include <stdio.h>4// COLOR_MODE 0:ansi 1:grayscale 2:xterm-color256 3: konsole 24bit56#define COLOR_MODE 278// palette theme9//#define LINUX_CONSOLE10//#define PCMAN11#define XTERM_COLOR121314#define COLS 8015#define ROWS 301617#define TRUE 118#define FALSE 019#if COLOR_MODE <= 120static char gray_string[]=" .:-=+*#%$";21#endif22#if COLOR_MODE == 023static unsigned ansi_color_table[65536][3];24static int ansi_color_table_ready=FALSE;25#ifdef PCMAN26static unsigned int dct[16][3] = { //default color table27//Darker color28{0,0,0}, //0;30m Black29{128,0,0}, //0;31m Dark red30{0,128,0}, //0;32m Dark green31{128,128,0}, //0;33m Brown32{0,0,128}, //0;34m Dark blue33{128,0,128}, //0;35m Dark magenta34{0,128,128}, //0;36m Dark cyan35{192,192,192}, //0;37m Light gray36//Bright color37{128,128,128}, //1;30m Gray38{255,0,0}, //1;31m Red39{0,255,0}, //1;32m Green40{255,255,0}, //1;33m Yellow41{0,0,255}, //1;34m Blue42{255,0,255}, //1;35m Magenta43{0,255,255}, //1;36m Cyan44{255, 255,255} //1;37m White45};46#define LIGHT_ADJUST(x) ((x)/2)47#endif48#ifdef XTERM_COLOR49static unsigned int dct[16][3] = {50{0,0,0}, {205,0,0}, {0,205,0}, {205,205,0},51{0,0,238}, {205,0,205}, {0,205,205}, {229,229,229},52{127,127,127}, {0xff,0,0}, {0,255,0}, {0xff,0xff,0},53{92,92,0xff}, {0xff,0,0xff}, {0,0xff,0xff}, {0xff,0xff,0xff}};54#define LIGHT_ADJUST(x) ((x)*10/16)55#endif56#ifdef TANGO_COLOR57static unsigned int dct[16][3] = {58{0,0,0}, {205,0,0}, {0,205,0}, {205,205,0},59{0,0,238}, {205,0,205}, {0,205,205}, {229,229,229},60{127,127,127}, {0xff,0,0}, {0,255,0}, {0xff,0xff,0},61{92,92,0xff}, {0xff,0,0xff}, {0,0xff,0xff}, {0xff,0xff,0xff}};62#define LIGHT_ADJUST(x) ((x)*9/13)63#endif64#ifdef LINUX_CONSOLE65static unsigned int dct[16][3] = {66{0,0,0}, {0xaa,0,0}, {0,0xaa,0}, {0xaa,0x55,0},67{0,0,0xaa}, {0xaa,0,0xaa}, {0,0xaa,0xaa}, {0xaa,0xaa,0xaa},68{0x55,0x55,0x55}, {0xff,0x55,0x55}, {0x55,0xff,0x55}, {0xff,0xff,0x55},69{0x55,0x55,0xff}, {0xff,0x55,0xff}, {0x55,0xff,0xff}, {0xff,0xff,0xff}};70#define LIGHT_ADJUST(x) ((x)*7/13)71#endif72static void init_ansi_color_table(){73unsigned int c;74for(c=0;c<65536;c++){75int best_fg=0, best_bg=0, best_level,min_diff=0xffffff;76int fg,bg,level, diff,r,g,b,rmean;77int rgb[3], rgb2[3];78int i;79rgb[0]=((c>>11)&0x1f)<<3;80rgb[1]=((c>>5)&0x3f)<<2;81rgb[2]=(c&0x1f)<<3;82for(fg=0;fg<16;fg++)83for(bg=0;bg<8;bg++)84for(level=0;level<10;level++){85for(i=0;i<3;i++)86rgb2[i]=(dct[fg][i]*level+dct[bg][i]*(18-level))/36- LIGHT_ADJUST(rgb[i]);87rmean = (2*rgb[0]+rgb2[0])/2;88r=rgb2[0];g=rgb2[1];b=rgb2[2];89diff=(((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8);90if(diff < min_diff){91best_level=level;92best_fg=fg;93best_bg=bg;94min_diff=diff;95}96}97ansi_color_table[c][0]=best_fg;98ansi_color_table[c][1]=best_bg;99ansi_color_table[c][2]=best_level;100}101ansi_color_table_ready=TRUE;102}103104#endif105static void print_color(uint32 c, uint32 c2){106#if COLOR_MODE>=1107unsigned int r,g,b, level;108r=((c>>11)&0x1f)<<3;109g=((c>>5)&0x3f)<<2;110b=(c&0x1f)<<3;111#endif112#if COLOR_MODE >=2113#if COLOR_MODE == 2114level=16+(r*6/256)*36+(g*6/256)*6+(b*6/256);115printf("\033[48;5;%d;", level);116#else117printf("\033[48;2;%d;%d;%d;", r,g,b);118#endif119r=((c2>>11)&0x1f)<<3;120g=((c2>>5)&0x3f)<<2;121b=(c2&0x1f)<<3;122#if COLOR_MODE == 2123level=16+(r*6/256)*36+(g*6/256)*6+(b*6/256);124printf("38;5;%dm\xe2\x96\x84", level);125#else126printf("38;2;%d;%d;%dm\xe2\x96\x84", r, g,b);127#endif128#endif129#if COLOR_MODE == 1130level=(((r * 0.30) + (g * 0.59) + (b * 0.11))/256.0*10.0);131if(level>9) level=9;132printf("%c",gray_string[level]);133#endif134#if COLOR_MODE == 0135static unsigned int last_fg, last_bg;136if(!ansi_color_table_ready) init_ansi_color_table();137if(c2 || last_fg!=ansi_color_table[c][0] || last_bg!=ansi_color_table[c][1])138printf("\033[%d;3%d;4%dm", ansi_color_table[c][0]>>3,139ansi_color_table[c][0]&7,140ansi_color_table[c][1]);141printf("%c", gray_string[ansi_color_table[c][2]]);142last_fg=ansi_color_table[c][0];143last_bg=ansi_color_table[c][1];144#endif145146147}148static uint32 RGB565FromRGB24(uint32 c){149unsigned r,g,b;150b=((c>>3)&0x1f);151g=((c>>10)&0x3f);152r=((c>>19)&0x1f);153return (r<<11)|(g<<5)|b;154155}156#define RGB565FromRGB555(t) ( (((t)&0x1f)<<11) | (((t)&0x3e0)<<1) | (((t)&0x7c00)>>10) )157static unsigned get_average_color(int x1, int y1, int x2, int y2, void * data, int bpp, int pitch){158#if 0159unsigned char *bp=(unsigned char *)data+y1*pitch;160return RGB565FromRGB24(((uint32 *)bp)[x1]);161#else162int x,y;163unsigned int r=0,g=0,b=0;164unsigned color;165unsigned char *bp;166int size=(y2-y1)*(x2-x1);167if (size <=0) {y2=y1+1; x2=x1+1;size=1;}168for(y=y1;y<y2;y++){169bp=(unsigned char *)data+y*pitch;170for(x=x1;x<x2;x++){171color = RGB565FromRGB24(((uint32 *)bp)[x]);172r+=color>>11;173g+=(color>>5)&0x3f;174b+=color&0x1f;175}176}177r/=size;178g/=size;179b/=size;180return (r<<11)|(g<<5)|b;181#endif182}183static void drawansi (int width, int height, void *data, int bpp, int pitch)184{185unsigned c1,c2;186int x,y, xstep, ystep, xstart, xend, ystart, yend;187int cols=COLS, rows=ROWS;188xstep=width/cols;189ystep=height/rows;190xstart=(width-xstep*cols)/2;191ystart=(height-ystep*rows)/2;192xend=xstart+cols*xstep;193yend=ystart+rows*ystep;194printf("\033[H");195uint32 reset=1;196for(y=ystart;y<yend;y+=ystep)197{198if(y!=ystart) printf("\r\n");199for(x=xstart;x<xend;x+=xstep)200{201#if COLOR_MODE >=2202c1=get_average_color(x, y, x+xstep, y+ystep/2, data, bpp, pitch);203c2=get_average_color(x, y+ystep/2, x+xstep, y+ystep, data, bpp, pitch);204print_color(c1, c2);205#else206c1=get_average_color(x, y, x+xstep, y+ystep, data, bpp, pitch);207print_color(c1, reset);208reset=0;209#endif210}211212}213printf("\033[0m");214fflush(stdout);215216}217218219