SVideo.h
Código
/** SVideo.h **/ #ifndef __S_VIDEO_H__ #define __S_VIDEO_H__ #define SVIDEO_DEBUG #include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <SDL/SDL_ttf.h> #ifdef SVIDEO_DEBUG #include <iostream> #endif #include <vector> #include <string> class SVideo { public : SVideo(int width, int height, int depth, bool fullscreen, bool initialize = true); ~SVideo(); // Gestión de fuentes int CreateFont(std::string font, int size); static int GetWidth(TTF_Font *font, std::string text); static int GetHeight(TTF_Font *font, std::string text); void DrawText(TTF_Font *font, std::string text, SDL_Color color, int x, int y); TTF_Font *GetFont(unsigned int index); // Gestión de superficies int CreateSurface(std::string image); void DrawSurface(SDL_Surface *surface, int x, int y); void DrawSurface(SDL_Surface *surface, SDL_Rect rect); SDL_Surface *GetSurface(unsigned int index); // Gestión del sistema de video void FlipScreen(); void Wait(int milliseconds); void CleanScreen(SDL_Color color); int Initialize(int width, int height, int depth, bool fullscreen); bool IsInitialized() const; SDL_Surface *GetScreen(); private : SDL_Surface *m_screen; SDL_Rect m_rectScreen; bool m_initialized; // Fuentes std::vector<TTF_Font *> m_font; // Superficies std::vector<SDL_Surface *> m_surface; }; #endif /* __S_VIDEO_H__ */
SVideo.cpp
Código
#include "SVideo.h" SVideo::SVideo(int width, int height, int depth, bool fullscreen, bool initialize /*= true*/) : m_screen(NULL) , m_initialized(false) { if ( initialize ) { if ( Initialize(width, height, depth, fullscreen) < 0 ) { #ifdef SVIDEO_DEBUG std::cerr << "SVideo::SVideo() -> SDL Error: " << SDL_GetError() << "." << std::endl; #endif return; } } } SVideo::~SVideo() { for ( unsigned int i = 0; i < m_font.size(); i++ ) { if ( m_font[i] ) { TTF_CloseFont( m_font[i] ); } } for ( unsigned int i = 0; i < m_surface.size(); i++ ) { if ( m_surface[i] ) { SDL_FreeSurface( m_surface[i] ); } } if ( m_screen ) { SDL_FreeSurface(m_screen); } } /** A partir de una cadena que indica el nombre de la fuente y el tamaño, crea un TTF_Font en la clase SVideo. Devuelve el índice de la fuente guardada en el vector. Devuelve -1 si a habido un error. @font: Cadena de la ruta de la fuente. @size: Tamaño de la fuente. **/ int SVideo::CreateFont(std::string font, int size) { m_font.push_back(TTF_OpenFont(font.c_str(), size)); unsigned int index = m_font.size() - 1; if ( m_font[index] == NULL ) { // No se creó bien, se borra y devuelve error. #ifdef SVIDEO_DEBUG std::cerr << "SVideo::CreateFont() -> SDL Error: " << SDL_GetError() << "." << std::endl; #endif m_font.erase(m_font.begin() + index); return -1; } // Si se crea bien, se devuelve su índice. return index; } /** Devuelve el ancho en píxeles de un texto. @font: Fuente de tipo TTF_Font. @text: Texto que se quiere medir. **/ int SVideo::GetWidth(TTF_Font *font, std::string text) { if ( font == NULL ) { return -1; } int w, h; TTF_SizeUTF8(font, text.c_str(), &w, &h); return w; } /** Devuelve el alto en píxeles de un texto. Devuelve -1 si hay fallo. @font: Fuente de tipo TTF_Font. @text: Texto que se quiere medir. **/ int SVideo::GetHeight(TTF_Font *font, std::string text) { if ( font == NULL ) { return -1; } int w, h; TTF_SizeUTF8(font, text.c_str(), &w, &h); return h; } /** Dibuja un texto. @font: Fuente de tipo TTF_Font. @text: Texto que se quiere escribir. @color: Color del texto @x: Posición horizontal. @y: Posición vertical. **/ void SVideo::DrawText(TTF_Font *font, std::string text, SDL_Color color, int x, int y) { if ( font == NULL ) { return; } SDL_Surface *textSurface; textSurface = TTF_RenderText_Blended(font, text.c_str(), color); SDL_Rect dest; dest.x = x; dest.y = y; dest.h = textSurface->h; dest.w = textSurface->w; if (SDL_BlitSurface(textSurface, NULL, m_screen, &dest) < 0 ) { #ifdef SVIDEO_DEBUG std::cerr << "SVideo::DrawText() -> SDL Error: " << SDL_GetError() << "." << std::endl; #endif return; } SDL_FreeSurface(textSurface); } /** Devuelve una fuente guardada en el vector. @index: Índice de la fuente en el vector. **/ TTF_Font *SVideo::GetFont(unsigned int index) { if ( index < m_font.size() ) { return m_font[index]; } return NULL; } /** crea una superficie en el vector de superficies. Devuelve el índice de la superficie. @image: Ruta de la imagen. **/ int SVideo::CreateSurface(std::string image) { m_surface.push_back(IMG_Load(image.c_str())); unsigned int index = m_surface.size() - 1; if ( m_surface[index] == NULL ) { // No se creó bien, se borra y devuelve error. #ifdef SVIDEO_DEBUG std::cerr << "SVideo::CreateSurface() -> SDL Error: " << SDL_GetError() << "." << std::endl; #endif m_surface.erase(m_surface.begin() + index); return -1; } // Si se crea bien, se devuelve su índice. return index; } /** Dibuja una superficie en la pantalla principal. @surface: Superficie a dibujar. @x: Posición horizontal. @y: Posición vertical. **/ void SVideo::DrawSurface(SDL_Surface *surface, int x, int y) { SDL_Rect _rect = { x, y, surface->w, surface->h }; SDL_BlitSurface(surface, NULL, m_screen, &_rect); } /** Dibuja una superficie en la pantalla principal. @surface: Superficie a dibujar. @rect: Rectángulo **/ void SVideo::DrawSurface(SDL_Surface *surface, SDL_Rect rect) { SDL_BlitSurface(surface, NULL, m_screen, &rect); } /** Devuelve una superficie creada. @index: Índice de la superficie en el vector. **/ SDL_Surface *SVideo::GetSurface(unsigned int index) { if ( index < m_surface.size() ) { return m_surface[index]; } return NULL; } /** Muestra el buffer escondido. **/ void SVideo::FlipScreen() { SDL_Flip(m_screen); } /** Hace una pausa. @milliseconds: Milisegundos de pausa. **/ void SVideo::Wait(int milliseconds) { SDL_Delay(milliseconds); } /** Limpia la pantalla con un color. @color: Color de borrado. **/ void SVideo::CleanScreen(SDL_Color color) { SDL_FillRect(m_screen, &m_rectScreen, SDL_MapRGB(m_screen->format, color.r, color.g, color.b)); } /** Inicia todo el sistema de video. Devuelve: < 0 Si hay error. 0 Si ha ido bien. **/ int SVideo::Initialize(int width, int height, int depth, bool fullscreen) { m_initialized = false; /** Video **/ if ( SDL_Init(SDL_INIT_VIDEO) == -1 ) { return -1; } atexit(SDL_Quit); if ( fullscreen ) m_screen = SDL_SetVideoMode(width, height, depth, SDL_SWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN); else m_screen = SDL_SetVideoMode(width, height, depth, SDL_SWSURFACE | SDL_DOUBLEBUF); if (m_screen == NULL) { return -2; } m_rectScreen.x = 0; m_rectScreen.y = 0; m_rectScreen.w = width; m_rectScreen.h = height; /** Textos **/ if (TTF_Init() == -1) { return -3; } atexit(TTF_Quit); m_initialized = true; return 0; } /** Devuelve si el sistema está inicializado. **/ bool SVideo::IsInitialized() const { return ( m_screen != NULL && m_initialized ); } /** Devuelve la pantalla principal. **/ SDL_Surface *SVideo::GetScreen() { return m_screen; }
Por supuesto le falta infinidad de cosas. Sugerencias, etc.
Aplicación con SDL pura.
Código
#include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <SDL/SDL_ttf.h> using namespace std; int main(int arc, char *argv[]) { SDL_Event evento; bool salida = false; SDL_Rect rectPantalla; SDL_Surface *pantalla; SDL_Color _blanco = { 255, 255, 255 }; SDL_Color _negro = { 0, 0, 0 }; if ( SDL_Init(SDL_INIT_VIDEO) == -1 ) { return -1; } atexit(SDL_Quit); if ((pantalla = SDL_SetVideoMode(600, 200, 16, SDL_SWSURFACE | SDL_DOUBLEBUF)) == NULL) { return -1; } rectPantalla.x = 0; rectPantalla.y = 0; rectPantalla.w = 600; rectPantalla.h = 200; if (TTF_Init() == -1) { return -1; } atexit(TTF_Quit); TTF_Font *miFuente = TTF_OpenFont("verdana.ttf", 50); if ( miFuente == NULL ) { return -1; } SDL_Surface *miGrafico = IMG_Load("grafico.png"); if ( miGrafico == NULL ) { return -1; } while ( !salida ) { while (SDL_PollEvent(&evento)) { if ( evento.type == SDL_QUIT ) salida = true; } int w, h; TTF_SizeUTF8(miFuente, "Mi Texto.", &w, &h); SDL_Surface *textoSurface = TTF_RenderText_Blended(miFuente, "Mi Texto.", _blanco); SDL_Rect rectTexto; rectTexto.x = 600 / 2 - w / 2; rectTexto.y = 20; rectTexto.h = textoSurface->h; rectTexto.w = textoSurface->w; SDL_BlitSurface(textoSurface, NULL, pantalla, &rectTexto); SDL_FreeSurface(textoSurface); SDL_Rect rectGrafico; rectGrafico.x = 3; rectGrafico.y = 3; rectGrafico.w = miGrafico->w; rectGrafico.h = miGrafico->h; SDL_BlitSurface(miGrafico, NULL, pantalla, &rectGrafico); SDL_Flip(pantalla); SDL_Delay(30); } TTF_CloseFont(miFuente); SDL_FreeSurface(miGrafico); SDL_FreeSurface(pantalla); return EXIT_SUCCESS;
Aplicación con SVideo
Código
#include "SVideo.h" using namespace std; typedef int FUENTE; typedef int GRAFICO; int main(int arc, char *argv[]) { SDL_Event evento; bool salida = false; SDL_Color _blanco = { 255, 255, 255 }; SDL_Color _negro = { 0, 0, 0 }; SVideo *video = new SVideo(600, 200, 16, false); if ( !video->IsInitialized() ) { std::cout << "Error iniciando." << std::endl; return -1; } FUENTE miFuente; if ((miFuente = video->CreateFont("verdana.ttf", 50)) == -1) { std::cout << "Error creando fuente." << std::endl; delete video; return -1; } GRAFICO miGrafico; if ((miGrafico = video->CreateSurface("grafico.png")) == -1) { std::cout << "Error creando gráfico." << std::endl; delete video; return -1; } while ( !salida ) { while (SDL_PollEvent(&evento)) { if ( evento.type == SDL_QUIT ) salida = true; } video->DrawText(video->GetFont(miFuente), "Mi Texto.", _blanco, (600 / 2)-(video->GetWidth(video->GetFont(miFuente), "Mi Texto.") / 2), 20); video->DrawSurface(video->GetSurface(miGrafico), 3, 3); video->FlipScreen(); video->Wait(30); } delete video; return EXIT_SUCCESS; }