sdlterm/src/sdlterm.cc
changeset 48 1f00e90fd72a
parent 47 537d7c6b48a2
child 49 1611c462c3e3
equal deleted inserted replaced
47:537d7c6b48a2 48:1f00e90fd72a
     1 #include "sdlterm.h"
     1 #include "sdlterm.h"
     2 
     2 
     3 #include <stdexcept>
     3 #include <stdexcept>
       
     4 
       
     5 
       
     6 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch)
       
     7 {
       
     8 	auto iter = _glyph_map.find(ch);
       
     9 	if (iter == _glyph_map.end())
       
    10 	{
       
    11 		return NULL;
       
    12 	}
       
    13 	return iter->second;
       
    14 }
       
    15 
       
    16 
       
    17 void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf)
       
    18 {
       
    19 	_glyph_map[ch] = srf;
       
    20 }
       
    21 
       
    22 
       
    23 void GlyphCache::flush()
       
    24 {
       
    25 	for (auto iter = _glyph_map.begin(); iter != _glyph_map.end(); iter++)
       
    26 	{
       
    27 		SDL_FreeSurface(iter->second);
       
    28 	}
       
    29 	_glyph_map.clear();
       
    30 }
     4 
    31 
     5 
    32 
     6 GlyphRenderer::GlyphRenderer()
    33 GlyphRenderer::GlyphRenderer()
     7  : _font_regular(NULL), _font_bold(NULL)
    34  : _font_regular(NULL), _font_bold(NULL)
     8 {
    35 {
    14 }
    41 }
    15 
    42 
    16 
    43 
    17 GlyphRenderer::~GlyphRenderer()
    44 GlyphRenderer::~GlyphRenderer()
    18 {
    45 {
       
    46 	_cache.flush();
    19 	close_font();
    47 	close_font();
    20 	TTF_Quit();
    48 	TTF_Quit();
    21 }
    49 }
    22 
    50 
    23 
    51 
    82 }
   110 }
    83 
   111 
    84 
   112 
    85 SDL_Surface *GlyphRenderer::render_glyph(Uint16 ch)
   113 SDL_Surface *GlyphRenderer::render_glyph(Uint16 ch)
    86 {
   114 {
       
   115 	SDL_Surface *cell_surface;
       
   116 
       
   117 	// try cache
       
   118 	cell_surface = _cache.lookup_glyph(ch);
       
   119 	if (cell_surface)
       
   120 	{
       
   121 		return cell_surface;
       
   122 	}
       
   123 
    87 	TTF_Font *font = _font_regular;
   124 	TTF_Font *font = _font_regular;
    88 	SDL_Color color={0xff,0xff,0xff}, bgcolor={0,100,100};
   125 	SDL_Color color={0xff,0xff,0xff}, bgcolor={0,100,100};
    89 	if (ch != 'W')
   126 	if (ch != 'W')
    90 	{
   127 	{
    91 		bgcolor.g = 0;
   128 		bgcolor.g = 0;
    92 		bgcolor.b = 0;
   129 		bgcolor.b = 0;
    93 	}
   130 	}
    94 
   131 
    95 	// create surface for whole cell and fill it with bg color
   132 	// create surface for whole cell and fill it with bg color
    96 	SDL_Surface *cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
   133 	cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
    97 			_cell_width, _cell_height, 32, 0, 0, 0, 0);
   134 			_cell_width, _cell_height, 32, 0, 0, 0, 0);
    98 	SDL_Rect dst_rect;
   135 	SDL_Rect dst_rect;
    99 	dst_rect.x = 0;
   136 	dst_rect.x = 0;
   100 	dst_rect.y = 0;
   137 	dst_rect.y = 0;
   101 	dst_rect.w = _cell_width;
   138 	dst_rect.w = _cell_width;
   110 	dst_rect.x = minx;
   147 	dst_rect.x = minx;
   111 	dst_rect.y = TTF_FontAscent(font) - maxy;
   148 	dst_rect.y = TTF_FontAscent(font) - maxy;
   112 	SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
   149 	SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
   113 	SDL_FreeSurface(glyph_surface);
   150 	SDL_FreeSurface(glyph_surface);
   114 
   151 
       
   152 	_cache.put_glyph(ch, cell_surface);
   115 	return cell_surface;
   153 	return cell_surface;
   116 }
   154 }
   117 
   155 
   118 
   156 
   119 TerminalScreen::~TerminalScreen()
   157 TerminalScreen::~TerminalScreen()
   131 	_reset_cells();
   169 	_reset_cells();
   132 }
   170 }
   133 
   171 
   134 void TerminalScreen::resize(int pxwidth, int pxheight)
   172 void TerminalScreen::resize(int pxwidth, int pxheight)
   135 {
   173 {
   136     _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 8, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
   174     _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 32, SDL_HWSURFACE|SDL_RESIZABLE);
   137 
   175 
   138     if (_screen_surface == NULL)
   176     if (_screen_surface == NULL)
   139     {
   177     {
   140 		fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
   178 		fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
   141 		throw std::exception();
   179 		throw std::exception();
   181 		{
   219 		{
   182 			dst_rect.x = x * _cell_width;
   220 			dst_rect.x = x * _cell_width;
   183 			dst_rect.y = y * _cell_height;
   221 			dst_rect.y = y * _cell_height;
   184 			glyph_surface = _render.render_glyph(cell->ch);
   222 			glyph_surface = _render.render_glyph(cell->ch);
   185 			SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect);
   223 			SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect);
   186 			SDL_FreeSurface(glyph_surface);
       
   187 			cell++;
   224 			cell++;
   188 		}
   225 		}
   189 	}
   226 	}
   190 
   227 
   191 	SDL_UpdateRect(_screen_surface, 0, 0, 0, 0);
   228 	SDL_UpdateRect(_screen_surface, 0, 0, 0, 0);
   216     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   253     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   217     {
   254     {
   218 		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   255 		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   219 		throw std::exception();
   256 		throw std::exception();
   220     }
   257     }
       
   258     SDL_EnableUNICODE(1);
   221 }
   259 }
   222 
   260 
   223 
   261 
   224 Terminal::~Terminal()
   262 Terminal::~Terminal()
   225 {
   263 {
   234 	while (SDL_WaitEvent(&sdl_event))
   272 	while (SDL_WaitEvent(&sdl_event))
   235 	{
   273 	{
   236 		switch (sdl_event.type)
   274 		switch (sdl_event.type)
   237 		{
   275 		{
   238 			case SDL_QUIT:
   276 			case SDL_QUIT:
   239 				event.type = EventType::quit;
   277 				event.type = Event::QUIT;
   240 				return;
   278 				return;
   241 
   279 
   242 			case SDL_KEYDOWN:
   280 			case SDL_KEYDOWN:
   243 				//switch(event.key.keysym.sym)
   281 				//switch(event.key.keysym.sym)
   244 				event.type = EventType::keypress;
   282 				event.type = Event::KEYPRESS;
       
   283 				event.key.unicode = sdl_event.key.keysym.unicode;
       
   284 				strncpy(event.key.keyname, _translate_keyname(sdl_event.key.keysym.sym), 10);
       
   285 				return;
       
   286 
       
   287 			case SDL_MOUSEBUTTONDOWN:
       
   288 			case SDL_MOUSEBUTTONUP:
       
   289 				event.type = (sdl_event.type == SDL_MOUSEBUTTONDOWN) ? Event::MOUSEDOWN : Event::MOUSEUP;
       
   290 				event.mouse.x = sdl_event.button.x / _screen.get_cell_width();
       
   291 				event.mouse.y = sdl_event.button.y / _screen.get_cell_height();
       
   292 				event.mouse.button = sdl_event.button.button;
       
   293 				return;
       
   294 
       
   295 			case SDL_MOUSEMOTION:
       
   296 				event.type = Event::MOUSEMOVE;
       
   297 				event.mouse.x = sdl_event.motion.x / _screen.get_cell_width();
       
   298 				event.mouse.y = sdl_event.motion.y / _screen.get_cell_height();
   245 				return;
   299 				return;
   246 
   300 
   247 			default:
   301 			default:
   248 				break; // continue loop
   302 				break; // continue loop
   249 		}
   303 		}
   250 	}
   304 	}
   251 }
   305 }
       
   306 
       
   307 
       
   308 const char *Terminal::_translate_keyname(SDLKey sym)
       
   309 {
       
   310 	switch (sym)
       
   311 	{
       
   312 		case SDLK_BACKSPACE: 	return "backspace";
       
   313 		case SDLK_TAB:			return "tab";
       
   314 		case SDLK_RETURN:		return "enter";
       
   315 		case SDLK_KP_ENTER:		return "enter";
       
   316 		case SDLK_PAUSE:	    return "pause";
       
   317 		case SDLK_ESCAPE:		return "escape";
       
   318 		case SDLK_DELETE:		return "delete";
       
   319 		case SDLK_INSERT:		return "insert";
       
   320 		case SDLK_UP:			return "up";
       
   321 		case SDLK_DOWN:			return "down";
       
   322 		case SDLK_LEFT:			return "left";
       
   323 		case SDLK_RIGHT:		return "right";
       
   324 		case SDLK_HOME:			return "home";
       
   325 		case SDLK_END:			return "end";
       
   326 		case SDLK_PAGEUP:		return "pageup";
       
   327 		case SDLK_PAGEDOWN:		return "pagedown";
       
   328 		case SDLK_F1:			return "f1";
       
   329 		case SDLK_F2:			return "f2";
       
   330 		case SDLK_F3:			return "f3";
       
   331 		case SDLK_F4:			return "f4";
       
   332 		case SDLK_F5:			return "f5";
       
   333 		case SDLK_F6:			return "f6";
       
   334 		case SDLK_F7:			return "f7";
       
   335 		case SDLK_F8:			return "f8";
       
   336 		case SDLK_F9:			return "f9";
       
   337 		case SDLK_F10:			return "f10";
       
   338 		case SDLK_F11:			return "f11";
       
   339 		case SDLK_F12:			return "f12";
       
   340 		default: return "";
       
   341 	}
       
   342 }
       
   343