sdlterm/src/sdlterm.cc
changeset 53 c4263588b716
parent 52 50a1857557da
child 54 86b84535726e
equal deleted inserted replaced
52:50a1857557da 53:c4263588b716
   174         {
   174         {
   175             // draw underline
   175             // draw underline
   176             SDL_LockSurface(cell_surface);
   176             SDL_LockSurface(cell_surface);
   177             int y = 1 + TTF_FontAscent(font);
   177             int y = 1 + TTF_FontAscent(font);
   178             Uint32 fgcolor_mapped = SDL_MapRGB(cell_surface->format, fgcolor.r, fgcolor.g, fgcolor.b);
   178             Uint32 fgcolor_mapped = SDL_MapRGB(cell_surface->format, fgcolor.r, fgcolor.g, fgcolor.b);
   179             Uint32 *p = (Uint32 *)(cell_surface->pixels + y * cell_surface->pitch);
   179             Uint32 *p = (Uint32 *)((Uint8 *)cell_surface->pixels + y * cell_surface->pitch);
   180             for (int x = 0; x < _cell_width; x++)
   180             for (int x = 0; x < _cell_width; x++)
   181                 *p++ = fgcolor_mapped;
   181                 *p++ = fgcolor_mapped;
   182             SDL_UnlockSurface(cell_surface);
   182             SDL_UnlockSurface(cell_surface);
   183         }
   183         }
   184     }
   184     }
   223     {
   223     {
   224         fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
   224         fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
   225         throw std::exception();
   225         throw std::exception();
   226     }
   226     }
   227 
   227 
   228     SDL_WM_SetCaption("terminal", NULL);
       
   229 
       
   230     _pixel_width = pxwidth;
   228     _pixel_width = pxwidth;
   231     _pixel_height = pxheight;
   229     _pixel_height = pxheight;
   232 
   230 
   233     _reset_cells();
   231     _reset_cells();
   234 }
   232 }
   243 void TerminalScreen::putch(int x, int y, Uint32 ch, Uint32 attr)
   241 void TerminalScreen::putch(int x, int y, Uint32 ch, Uint32 attr)
   244 {
   242 {
   245     TerminalCell &cell = _cells_front[y * _width + x];
   243     TerminalCell &cell = _cells_front[y * _width + x];
   246     cell.ch = ch;
   244     cell.ch = ch;
   247     cell.attr = attr;
   245     cell.attr = attr;
       
   246 }
       
   247 
       
   248 
       
   249 void TerminalScreen::toggle_cursor(int x, int y)
       
   250 {
       
   251     TerminalCell &cell = _cells_front[y * _width + x];
       
   252     cell.attr ^= (Style::STANDOUT << 24);
   248 }
   253 }
   249 
   254 
   250 
   255 
   251 void TerminalScreen::commit()
   256 void TerminalScreen::commit()
   252 {
   257 {
   273 
   278 
   274     SDL_UpdateRect(_screen_surface, 0, 0, 0, 0);
   279     SDL_UpdateRect(_screen_surface, 0, 0, 0, 0);
   275 }
   280 }
   276 
   281 
   277 
   282 
       
   283 void TerminalScreen::redraw()
       
   284 {
       
   285     // clear back buffer, current screen is considered blank
       
   286     std::fill(_cells_back.begin(), _cells_back.end(), TerminalCell());
       
   287 }
       
   288 
       
   289 
   278 void TerminalScreen::_reset_cells()
   290 void TerminalScreen::_reset_cells()
   279 {
   291 {
   280     _cell_width = _render.get_cell_width();
   292     _cell_width = _render.get_cell_width();
   281     _cell_height = _render.get_cell_height();
   293     _cell_height = _render.get_cell_height();
   282     if (!_cell_width || !_cell_height)
   294     if (!_cell_width || !_cell_height)
   287     if (!_width || !_height)
   299     if (!_width || !_height)
   288         return;
   300         return;
   289 
   301 
   290     int num_cells = _width * _height;
   302     int num_cells = _width * _height;
   291     _cells_front.resize(num_cells, TerminalCell());
   303     _cells_front.resize(num_cells, TerminalCell());
   292     _cells_back.resize(num_cells, TerminalCell());
   304     _cells_back.resize(num_cells);
       
   305     redraw();
   293 }
   306 }
   294 
   307 
   295 
   308 
   296 Terminal::Terminal()
   309 Terminal::Terminal()
   297  : _screen(), _attr(7), _mousemove_last_x(-1)
   310  : _screen(), _attr(7), _cursor_visible(false), _mousemove_last_x(-1)
   298 {
   311 {
   299     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   312     if (SDL_Init(SDL_INIT_VIDEO) == -1)
   300     {
   313     {
   301         fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   314         fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
   302         throw std::exception();
   315         throw std::exception();
   303     }
   316     }
   304     SDL_EnableUNICODE(1);
   317     SDL_EnableUNICODE(1);
       
   318     SDL_WM_SetCaption("terminal", NULL);
   305 }
   319 }
   306 
   320 
   307 
   321 
   308 Terminal::~Terminal()
   322 Terminal::~Terminal()
   309 {
   323 {
   310     SDL_Quit();
   324     SDL_Quit();
   311 }
   325 }
   312 
   326 
       
   327 
       
   328 void Terminal::commit()
       
   329 {
       
   330     if (_cursor_visible)
       
   331     {
       
   332         _screen.toggle_cursor(_cursor_x, _cursor_y);
       
   333         _screen.commit();
       
   334         _screen.toggle_cursor(_cursor_x, _cursor_y);
       
   335     }
       
   336     else
       
   337     {
       
   338         _screen.commit();
       
   339     }
       
   340 }
   313 
   341 
   314 void Terminal::get_next_event(Event &event)
   342 void Terminal::get_next_event(Event &event)
   315 {
   343 {
   316     static SDL_Event sdl_event;
   344     static SDL_Event sdl_event;
   317 
   345 
   320         switch (sdl_event.type)
   348         switch (sdl_event.type)
   321         {
   349         {
   322             case SDL_QUIT:
   350             case SDL_QUIT:
   323                 event.type = Event::QUIT;
   351                 event.type = Event::QUIT;
   324                 return;
   352                 return;
       
   353 
       
   354             case SDL_VIDEORESIZE:
       
   355                 event.type = Event::RESIZE;
       
   356                 _screen.resize(sdl_event.resize.w, sdl_event.resize.h);
       
   357                 return;
       
   358 
       
   359             case SDL_VIDEOEXPOSE:
       
   360                 _screen.redraw();
       
   361                 break;
   325 
   362 
   326             case SDL_KEYDOWN:
   363             case SDL_KEYDOWN:
   327             {
   364             {
   328                 //switch(event.key.keysym.sym)
   365                 //switch(event.key.keysym.sym)
   329                 event.type = Event::KEYPRESS;
   366                 event.type = Event::KEYPRESS;
   352                 event.mouse.button = sdl_event.button.button;
   389                 event.mouse.button = sdl_event.button.button;
   353                 _mousemove_last_x = -1;
   390                 _mousemove_last_x = -1;
   354                 return;
   391                 return;
   355 
   392 
   356             case SDL_MOUSEMOTION:
   393             case SDL_MOUSEMOTION:
       
   394                 if (sdl_event.motion.state == 0)
       
   395                     break; // continue loop, do not report move events when no button is pressed
   357                 event.type = Event::MOUSEMOVE;
   396                 event.type = Event::MOUSEMOVE;
   358                 event.mouse.x = sdl_event.motion.x / _screen.get_cell_width();
   397                 event.mouse.x = sdl_event.motion.x / _screen.get_cell_width();
   359                 event.mouse.y = sdl_event.motion.y / _screen.get_cell_height();
   398                 event.mouse.y = sdl_event.motion.y / _screen.get_cell_height();
   360                 if (_mousemove_last_x != event.mouse.x ||
   399                 if (_mousemove_last_x != event.mouse.x ||
   361                     _mousemove_last_y != event.mouse.y)
   400                     _mousemove_last_y != event.mouse.y)