diff -r 1f00e90fd72a -r 1611c462c3e3 sdlterm/src/sdlterm.cc --- a/sdlterm/src/sdlterm.cc Sat Jan 05 12:40:32 2013 +0100 +++ b/sdlterm/src/sdlterm.cc Sat Jan 05 16:47:30 2013 +0100 @@ -1,6 +1,7 @@ #include "sdlterm.h" -#include +#include +#include SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) @@ -122,12 +123,7 @@ } TTF_Font *font = _font_regular; - SDL_Color color={0xff,0xff,0xff}, bgcolor={0,100,100}; - if (ch != 'W') - { - bgcolor.g = 0; - bgcolor.b = 0; - } + SDL_Color color={0xff,0xff,0xff}, bgcolor={0,0,0}; // create surface for whole cell and fill it with bg color cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, @@ -141,28 +137,29 @@ SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); // render glyph, blit it onto cell surface - SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor); - int minx, maxy; - TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); - dst_rect.x = minx; - dst_rect.y = TTF_FontAscent(font) - maxy; - SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); - SDL_FreeSurface(glyph_surface); + if (ch) + { + SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor); + int minx, maxy; + TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); + dst_rect.x = minx; + dst_rect.y = TTF_FontAscent(font) - maxy; + SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); + SDL_FreeSurface(glyph_surface); + } + // convert to display format + SDL_Surface *tmp_surface = cell_surface; + cell_surface = SDL_DisplayFormat(tmp_surface); + SDL_FreeSurface(tmp_surface); + + // put to cache _cache.put_glyph(ch, cell_surface); + return cell_surface; } -TerminalScreen::~TerminalScreen() -{ - if (_cells) - { - delete[] _cells; - } -} - - void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) { _render.open_font(fname_regular, fname_bold, ptsize); @@ -171,7 +168,7 @@ void TerminalScreen::resize(int pxwidth, int pxheight) { - _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 32, SDL_HWSURFACE|SDL_RESIZABLE); + _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 0, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE); if (_screen_surface == NULL) { @@ -190,19 +187,13 @@ void TerminalScreen::erase() { - TerminalCell * cell = _cells; - for (int i = 0; i < _width * _height; i++) - { - cell->ch = ' '; - cell->attr = 0; - cell++; - } + std::fill(_cells_front.begin(), _cells_front.end(), TerminalCell()); } void TerminalScreen::putch(int x, int y, Uint16 ch, Uint16 attr) { - TerminalCell &cell = _cells[y * _width + x]; + TerminalCell &cell = _cells_front[y * _width + x]; cell.ch = ch; cell.attr = attr; } @@ -210,18 +201,24 @@ void TerminalScreen::commit() { - TerminalCell * cell = _cells; + auto front_iter = _cells_front.begin(); + auto back_iter = _cells_back.begin(); SDL_Surface *glyph_surface; SDL_Rect dst_rect; for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { - dst_rect.x = x * _cell_width; - dst_rect.y = y * _cell_height; - glyph_surface = _render.render_glyph(cell->ch); - SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect); - cell++; + if (*front_iter != *back_iter) + { + dst_rect.x = x * _cell_width; + dst_rect.y = y * _cell_height; + glyph_surface = _render.render_glyph(front_iter->ch); + SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect); + *back_iter = *front_iter; + } + front_iter++; + back_iter++; } } @@ -231,24 +228,19 @@ void TerminalScreen::_reset_cells() { - if (_cells) - { - delete[] _cells; - _cells = NULL; - } - _cell_width = _render.get_cell_width(); _cell_height = _render.get_cell_height(); _width = _pixel_width / _cell_width; _height = _pixel_height / _cell_height; int num_cells = _width * _height; - _cells = new TerminalCell[num_cells]; + _cells_front.resize(num_cells); + _cells_back.resize(num_cells); } Terminal::Terminal() - : _screen() + : _screen(), _mousemove_last_x(-1) { if (SDL_Init(SDL_INIT_VIDEO) == -1) { @@ -267,7 +259,7 @@ void Terminal::get_next_event(Event &event) { - SDL_Event sdl_event; + static SDL_Event sdl_event; while (SDL_WaitEvent(&sdl_event)) { @@ -278,11 +270,25 @@ return; case SDL_KEYDOWN: + { //switch(event.key.keysym.sym) event.type = Event::KEYPRESS; - event.key.unicode = sdl_event.key.keysym.unicode; - strncpy(event.key.keyname, _translate_keyname(sdl_event.key.keysym.sym), 10); + const char *keyname = _translate_keyname(sdl_event.key.keysym.sym); + // return only keyname or unicode, never both + if (keyname) + { + strncpy(event.key.keyname, keyname, 10); + event.key.unicode = 0; + } + else + { + event.key.keyname[0] = 0; + event.key.unicode = sdl_event.key.keysym.unicode; + if (!event.key.unicode) + break; // continue loop (unknown key) + } return; + } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: @@ -290,13 +296,21 @@ event.mouse.x = sdl_event.button.x / _screen.get_cell_width(); event.mouse.y = sdl_event.button.y / _screen.get_cell_height(); event.mouse.button = sdl_event.button.button; + _mousemove_last_x = -1; return; case SDL_MOUSEMOTION: event.type = Event::MOUSEMOVE; event.mouse.x = sdl_event.motion.x / _screen.get_cell_width(); event.mouse.y = sdl_event.motion.y / _screen.get_cell_height(); - return; + if (_mousemove_last_x != event.mouse.x || + _mousemove_last_y != event.mouse.y) + { + _mousemove_last_x = event.mouse.x; + _mousemove_last_y = event.mouse.y; + return; + } + break; // continue loop when mouse position did not change default: break; // continue loop @@ -337,7 +351,7 @@ case SDLK_F10: return "f10"; case SDLK_F11: return "f11"; case SDLK_F12: return "f12"; - default: return ""; + default: return NULL; } }