sdlterm/src/sdlterm.cc
changeset 50 c5b8b9d2da95
parent 49 1611c462c3e3
child 51 dce7325109c1
equal deleted inserted replaced
49:1611c462c3e3 50:c5b8b9d2da95
     2 
     2 
     3 #include <exception>
     3 #include <exception>
     4 #include <algorithm>
     4 #include <algorithm>
     5 
     5 
     6 
     6 
       
     7 void ColorMap::index_to_rgb(int index, SDL_Color &color)
       
     8 {
       
     9 	color.r = _map[index][0];
       
    10 	color.g = _map[index][1];
       
    11 	color.b = _map[index][2];
       
    12 }
       
    13 
       
    14 
     7 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch)
    15 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch)
     8 {
    16 {
     9 	auto iter = _glyph_map.find(ch);
    17 	auto iter = _glyph_map.find(ch);
    10 	if (iter == _glyph_map.end())
    18 	if (iter == _glyph_map.end())
    11 	{
    19 	{
    30 	_glyph_map.clear();
    38 	_glyph_map.clear();
    31 }
    39 }
    32 
    40 
    33 
    41 
    34 GlyphRenderer::GlyphRenderer()
    42 GlyphRenderer::GlyphRenderer()
    35  : _font_regular(NULL), _font_bold(NULL)
    43  : _font_regular(NULL), _font_bold(NULL), _cell_width(0), _cell_height(0), _cache(), _colormap()
    36 {
    44 {
    37 	if (TTF_Init() == -1)
    45 	if (TTF_Init() == -1)
    38 	{
    46 	{
    39 	    printf("TTF_Init: %s\n", TTF_GetError());
    47 	    printf("TTF_Init: %s\n", TTF_GetError());
    40 	    throw std::exception();
    48 	    throw std::exception();
   109 		_font_bold = NULL;
   117 		_font_bold = NULL;
   110 	}
   118 	}
   111 }
   119 }
   112 
   120 
   113 
   121 
   114 SDL_Surface *GlyphRenderer::render_glyph(Uint16 ch)
   122 SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr)
   115 {
   123 {
   116 	SDL_Surface *cell_surface;
   124 	SDL_Surface *cell_surface;
       
   125 	TTF_Font *font;
       
   126 	SDL_Color fgcolor, bgcolor;
   117 
   127 
   118 	// try cache
   128 	// try cache
   119 	cell_surface = _cache.lookup_glyph(ch);
   129 	cell_surface = _cache.lookup_glyph(ch);
   120 	if (cell_surface)
   130 	if (cell_surface)
   121 	{
   131 	{
   122 		return cell_surface;
   132 		return cell_surface;
   123 	}
   133 	}
   124 
   134 
   125 	TTF_Font *font = _font_regular;
   135 	// load attributes
   126 	SDL_Color color={0xff,0xff,0xff}, bgcolor={0,0,0};
   136 	_colormap.index_to_rgb(attr & 0x000F, fgcolor);
       
   137 	_colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor);
       
   138 	Style style = (Style) ((attr & 0xFF00) >> 8);
       
   139 	font = (style == Style::BOLD) ? _font_bold : _font_regular;
   127 
   140 
   128 	// create surface for whole cell and fill it with bg color
   141 	// create surface for whole cell and fill it with bg color
   129 	cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
   142 	cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
   130 			_cell_width, _cell_height, 32, 0, 0, 0, 0);
   143 			_cell_width, _cell_height, 32, 0, 0, 0, 0);
   131 	SDL_Rect dst_rect;
   144 	SDL_Rect dst_rect;
   137 	SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped);
   150 	SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped);
   138 
   151 
   139 	// render glyph, blit it onto cell surface
   152 	// render glyph, blit it onto cell surface
   140 	if (ch)
   153 	if (ch)
   141 	{
   154 	{
   142 		SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor);
   155 		SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor);
   143 		int minx, maxy;
   156 		int minx, maxy;
   144 		TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL);
   157 		TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL);
   145 		dst_rect.x = minx;
   158 		dst_rect.x = minx;
   146 		dst_rect.y = TTF_FontAscent(font) - maxy;
   159 		dst_rect.y = TTF_FontAscent(font) - maxy;
   147 		SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
   160 		SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
   201 
   214 
   202 void TerminalScreen::commit()
   215 void TerminalScreen::commit()
   203 {
   216 {
   204 	auto front_iter = _cells_front.begin();
   217 	auto front_iter = _cells_front.begin();
   205 	auto back_iter = _cells_back.begin();
   218 	auto back_iter = _cells_back.begin();
   206 	SDL_Surface *glyph_surface;
   219 	SDL_Surface *cell_surface;
   207 	SDL_Rect dst_rect;
   220 	SDL_Rect dst_rect;
   208 	for (int y = 0; y < _height; y++)
   221 	for (int y = 0; y < _height; y++)
   209 	{
   222 	{
   210 		for (int x = 0; x < _width; x++)
   223 		for (int x = 0; x < _width; x++)
   211 		{
   224 		{
   212 			if (*front_iter != *back_iter)
   225 			if (*front_iter != *back_iter)
   213 			{
   226 			{
   214 				dst_rect.x = x * _cell_width;
   227 				dst_rect.x = x * _cell_width;
   215 				dst_rect.y = y * _cell_height;
   228 				dst_rect.y = y * _cell_height;
   216 				glyph_surface = _render.render_glyph(front_iter->ch);
   229 				cell_surface = _render.render_cell(front_iter->ch, front_iter->attr);
   217 				SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect);
   230 				SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect);
   218 				*back_iter = *front_iter;
   231 				*back_iter = *front_iter;
   219 			}
   232 			}
   220 			front_iter++;
   233 			front_iter++;
   221 			back_iter++;
   234 			back_iter++;
   222 		}
   235 		}
   228 
   241 
   229 void TerminalScreen::_reset_cells()
   242 void TerminalScreen::_reset_cells()
   230 {
   243 {
   231 	_cell_width = _render.get_cell_width();
   244 	_cell_width = _render.get_cell_width();
   232 	_cell_height = _render.get_cell_height();
   245 	_cell_height = _render.get_cell_height();
       
   246 	if (!_cell_width || !_cell_height)
       
   247 		return;
       
   248 
   233 	_width = _pixel_width / _cell_width;
   249 	_width = _pixel_width / _cell_width;
   234 	_height = _pixel_height / _cell_height;
   250 	_height = _pixel_height / _cell_height;
       
   251 	if (!_width || !_height)
       
   252 		return;
   235 
   253 
   236 	int num_cells = _width * _height;
   254 	int num_cells = _width * _height;
   237 	_cells_front.resize(num_cells);
   255 	_cells_front.resize(num_cells, TerminalCell());
   238 	_cells_back.resize(num_cells);
   256 	_cells_back.resize(num_cells, TerminalCell());
   239 }
   257 }
   240 
   258 
   241 
   259 
   242 Terminal::Terminal()
   260 Terminal::Terminal()
   243  : _screen(), _mousemove_last_x(-1)
   261  : _screen(), _attr(7), _mousemove_last_x(-1)
   244 {
   262 {
   245     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   263     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   246     {
   264     {
   247 		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   265 		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   248 		throw std::exception();
   266 		throw std::exception();
   325 	{
   343 	{
   326 		case SDLK_BACKSPACE: 	return "backspace";
   344 		case SDLK_BACKSPACE: 	return "backspace";
   327 		case SDLK_TAB:			return "tab";
   345 		case SDLK_TAB:			return "tab";
   328 		case SDLK_RETURN:		return "enter";
   346 		case SDLK_RETURN:		return "enter";
   329 		case SDLK_KP_ENTER:		return "enter";
   347 		case SDLK_KP_ENTER:		return "enter";
   330 		case SDLK_PAUSE:	    return "pause";
       
   331 		case SDLK_ESCAPE:		return "escape";
   348 		case SDLK_ESCAPE:		return "escape";
   332 		case SDLK_DELETE:		return "delete";
   349 		case SDLK_DELETE:		return "delete";
   333 		case SDLK_INSERT:		return "insert";
   350 		case SDLK_INSERT:		return "insert";
   334 		case SDLK_UP:			return "up";
   351 		case SDLK_UP:			return "up";
   335 		case SDLK_DOWN:			return "down";
   352 		case SDLK_DOWN:			return "down";
   349 		case SDLK_F8:			return "f8";
   366 		case SDLK_F8:			return "f8";
   350 		case SDLK_F9:			return "f9";
   367 		case SDLK_F9:			return "f9";
   351 		case SDLK_F10:			return "f10";
   368 		case SDLK_F10:			return "f10";
   352 		case SDLK_F11:			return "f11";
   369 		case SDLK_F11:			return "f11";
   353 		case SDLK_F12:			return "f12";
   370 		case SDLK_F12:			return "f12";
       
   371 		case SDLK_PRINT:		return "print";
       
   372 		case SDLK_SCROLLOCK:	return "scrllock";
       
   373 		case SDLK_PAUSE:	    return "pause";
   354 		default: return NULL;
   374 		default: return NULL;
   355 	}
   375 	}
   356 }
   376 }
   357 
   377