Librería sobre SDL

Iniciado por Kropt32, 6 Octubre 2010, 18:05 PM

0 Miembros y 1 Visitante están viendo este tema.

Kropt32

Bueno, aquí dejo una parte de una librería sobre SDL para acelerar el proceso de crear una aplicación con SDL. Es un poco patatera y no tiene demasiadas cosas. Espero que sirva de algo y de pie a seguirla.

SVideo.h
Código (cpp) [Seleccionar]


/**
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 (cpp) [Seleccionar]


#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 (cpp) [Seleccionar]


#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 (cpp) [Seleccionar]


#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;
}

En las pistolas, fíjense, a cada disparo el cañon recula, como asustado por lo que acaba de hacer.