413 lines
9.5 KiB
C++
413 lines
9.5 KiB
C++
|
/* [CONSTRUCTOR] Constructeur de la classe
|
||
|
=========================================================*/
|
||
|
xManager::xManager(const char *t, int w, int h){
|
||
|
// default values
|
||
|
_lasttick = SDL_GetTicks();
|
||
|
_fpstime = 1000/60;
|
||
|
_window = NULL;
|
||
|
_renderer = NULL;
|
||
|
_texture = NULL;
|
||
|
|
||
|
// Initialisation des sous-sys. SDL
|
||
|
SDL_Init( SDL_INIT_EVERYTHING );
|
||
|
|
||
|
|
||
|
// Creation de la fenetre
|
||
|
_window = SDL_CreateWindow(
|
||
|
t,
|
||
|
SDL_WINDOWPOS_CENTERED,
|
||
|
SDL_WINDOWPOS_CENTERED,
|
||
|
w,
|
||
|
h,
|
||
|
SDL_WINDOW_SHOWN
|
||
|
);
|
||
|
|
||
|
// Gestion erreur
|
||
|
if( _window == NULL )
|
||
|
return;
|
||
|
|
||
|
|
||
|
// On enregistre les dimensions de la fenetre
|
||
|
_winrect.x = _winrect.y = 0;
|
||
|
SDL_GetWindowSize(_window, &_winrect.w, &_winrect.h);
|
||
|
|
||
|
// Creation du renderer
|
||
|
_renderer = SDL_CreateRenderer(
|
||
|
_window,
|
||
|
-1,
|
||
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
/* [DESTROYER] Destructeur de la classe
|
||
|
=========================================================*/
|
||
|
xManager::~xManager(){
|
||
|
SDL_DestroyTexture(_texture);
|
||
|
SDL_DestroyRenderer(_renderer);
|
||
|
SDL_DestroyWindow( _window );
|
||
|
SDL_Quit();
|
||
|
}
|
||
|
|
||
|
/* [STATUS] Retourne le status
|
||
|
=========================================================*/
|
||
|
bool xManager::status(){
|
||
|
return _window != NULL && _renderer != NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [WINDOW] Retourne la fenetre
|
||
|
=========================================================*/
|
||
|
SDL_Window* xManager::window(){ return _window; }
|
||
|
|
||
|
|
||
|
/* [SCREEN] Retourne la fenetre
|
||
|
=========================================================*/
|
||
|
SDL_Renderer* xManager::renderer(){ return _renderer; }
|
||
|
|
||
|
|
||
|
/* [SETBACKGROUND] Modifie la couleur de fond
|
||
|
=========================================================*/
|
||
|
bool xManager::setBackground(Uint8 r, Uint8 g, Uint8 b, Uint8 a){
|
||
|
|
||
|
SDL_SetRenderDrawColor( _renderer, r, g, b, a );
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* [SETIMAGE] Met une image en fond
|
||
|
=========================================================*/
|
||
|
bool xManager::setImage(const char *url){
|
||
|
|
||
|
// On cree la texture associee
|
||
|
_texture = IMG_LoadTexture( _renderer, url );
|
||
|
|
||
|
return _texture != NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [HIT] Retourne si une texture est en collision avec une autre
|
||
|
=========================================================*/
|
||
|
bool xManager::hit(string current, int movex, int movey){
|
||
|
// Anti conflit inter-thread
|
||
|
_mutex_hit.lock();
|
||
|
|
||
|
/* (1) On recupere le SDL_Rect destination du sprite courant */
|
||
|
SDL_Rect *cRect = this->getDst(current);
|
||
|
|
||
|
// Gestion erreur
|
||
|
if( cRect == NULL ){
|
||
|
_mutex_hit.unlock();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
SDL_Rect r = (SDL_Rect){
|
||
|
(*cRect).x+movex,
|
||
|
(*cRect).y+movey,
|
||
|
(*cRect).w,
|
||
|
(*cRect).h
|
||
|
};
|
||
|
SDL_Rect c;
|
||
|
|
||
|
/* (2) On regarde si en dehors de la fenetre */
|
||
|
for( int y = r.y ; y < r.y+r.h ; y++ )
|
||
|
for( int x = r.x ; x < r.x+r.w ; x++ )
|
||
|
if( x < _winrect.x || x > _winrect.x+_winrect.w || y < _winrect.y || y>_winrect.y+_winrect.h ){
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* (3) On compare avec toutes les autres textures */
|
||
|
for( int i = 0 ; i < _indexes.size() ; i++ ){
|
||
|
|
||
|
// Si c'est pas le sprite courant
|
||
|
if( _indexes[i] != current ){
|
||
|
|
||
|
// taille du sprite en cours
|
||
|
c.x = (*_dst[i]).x;
|
||
|
c.y = (*_dst[i]).y;
|
||
|
c.w = (*_dst[i]).w;
|
||
|
c.h = (*_dst[i]).h;
|
||
|
|
||
|
for( int y = r.y ; y < r.y+r.h ; y++ )
|
||
|
for( int x = r.x ; x < r.x+r.w ; x++ )
|
||
|
if( x>=c.x && x<=c.x+c.w && y>=c.y && y<=c.y+c.h ){
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
|
||
|
return false;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* [HIT] Retourne si une texture est en collision avec une autre
|
||
|
=========================================================*/
|
||
|
bool xManager::hit(SDL_Texture *current, int movex, int movey){
|
||
|
// Anti conflit inter-thread
|
||
|
_mutex_hit.lock();
|
||
|
|
||
|
|
||
|
/* (1) On recupere le SDL_Rect destination du sprite courant */
|
||
|
int xIndex = -1;
|
||
|
for( int i = 0 ; i < _sprites.size() ; i++ )
|
||
|
if( _sprites[i] == current )
|
||
|
xIndex = i;
|
||
|
|
||
|
if( xIndex == -1 ){
|
||
|
_mutex_hit.unlock();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
SDL_Rect r = (SDL_Rect){
|
||
|
(*_dst[xIndex]).x+movex,
|
||
|
(*_dst[xIndex]).y+movey,
|
||
|
(*_dst[xIndex]).w,
|
||
|
(*_dst[xIndex]).h
|
||
|
};
|
||
|
SDL_Rect c;
|
||
|
|
||
|
/* (2) On regarde si en dehors de la fenetre */
|
||
|
for( int y = r.y ; y < r.y+r.h ; y++ )
|
||
|
for( int x = r.x ; x < r.x+r.w ; x++ )
|
||
|
if( x < _winrect.x || x > _winrect.x+_winrect.w || y < _winrect.y || y>_winrect.y+_winrect.h ){
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* (3) On compare avec toutes les autres textures */
|
||
|
for( int i = 0 ; i < _sprites.size() ; i++ ){
|
||
|
|
||
|
// Si c'est pas le sprite courant
|
||
|
if( _sprites[i] != current ){
|
||
|
|
||
|
// taille du sprite en cours
|
||
|
c.x = (*_dst[i]).x;
|
||
|
c.y = (*_dst[i]).y;
|
||
|
c.w = (*_dst[i]).w;
|
||
|
c.h = (*_dst[i]).h;
|
||
|
|
||
|
for( int y = r.y ; y < r.y+r.h ; y++ )
|
||
|
for( int x = r.x ; x < r.x+r.w ; x++ )
|
||
|
if( x>=c.x && x<=c.x+c.w && y>=c.y && y<=c.y+c.h ){
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// On debloque la ressource
|
||
|
_mutex_hit.unlock();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* [GETTEXTURE] Renvoie la texture
|
||
|
=========================================================*/
|
||
|
SDL_Texture *xManager::getTexture(string index){
|
||
|
|
||
|
// On cherche la texture avec l'index
|
||
|
for( int i = 0 ; i < _indexes.size() ; i++ )
|
||
|
if( _indexes[i] == index )
|
||
|
return _sprites[i];
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [GETSRC] Renvoie le SDL_Rect source
|
||
|
=========================================================*/
|
||
|
SDL_Rect *xManager::getSrc(string index){
|
||
|
|
||
|
// On cherche la texture avec l'index
|
||
|
for( int i = 0 ; i < _indexes.size() ; i++ )
|
||
|
if( _indexes[i] == index )
|
||
|
return _src[i];
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [GETDST] Renvoie le SDL_Rect destination
|
||
|
=========================================================*/
|
||
|
SDL_Rect *xManager::getDst(string index){
|
||
|
|
||
|
// On cherche la texture avec l'index
|
||
|
for( int i = 0 ; i < _indexes.size() ; i++ )
|
||
|
if( _indexes[i] == index )
|
||
|
return _dst[i];
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* [PUSH] Ajoute une texture au rendu principal
|
||
|
=========================================================*/
|
||
|
void xManager::push(string index, SDL_Texture *t, SDL_Rect *src, SDL_Rect *dst){
|
||
|
// On bloque l'acces inter-thread
|
||
|
_mutex_push.lock();
|
||
|
|
||
|
_indexes.push_back( index );
|
||
|
_sprites.push_back( t );
|
||
|
_src.push_back( src );
|
||
|
_dst.push_back( dst );
|
||
|
|
||
|
// On debloque l'acces
|
||
|
_mutex_push.unlock();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [PULL] Retire une texture du rendu principal
|
||
|
=========================================================*/
|
||
|
void xManager::pull(string index){
|
||
|
// On bloque l'acces inter-thread
|
||
|
_mutex_pull.lock();
|
||
|
|
||
|
// On cherche l'indice de la texture
|
||
|
int xIndex = -1;
|
||
|
|
||
|
for( int i = 0 ; i < _indexes.size() ; i++ )
|
||
|
if( _indexes[i] == index ) xIndex = i;
|
||
|
|
||
|
// Si on a rien trouve
|
||
|
if( xIndex == -1 )
|
||
|
return;
|
||
|
|
||
|
// On supprime la texture et ses dimensions
|
||
|
_indexes.erase( _indexes.begin() + xIndex );
|
||
|
_sprites.erase( _sprites.begin() + xIndex );
|
||
|
_src.erase( _src.begin() + xIndex );
|
||
|
_dst.erase( _dst.begin() + xIndex );
|
||
|
|
||
|
// On debloque l'acces
|
||
|
_mutex_pull.unlock();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* [PULL] Retire une texture du rendu principal
|
||
|
=========================================================*/
|
||
|
void xManager::pull(SDL_Texture *t){
|
||
|
// On bloque l'acces inter-thread
|
||
|
_mutex_pull.lock();
|
||
|
|
||
|
// On cherche l'indice de la texture
|
||
|
int xIndex = -1;
|
||
|
|
||
|
for( int i = 0 ; i < _sprites.size() ; i++ )
|
||
|
if( _sprites[i] == t ) xIndex = i;
|
||
|
|
||
|
// Si on a rien trouve
|
||
|
if( xIndex == -1 )
|
||
|
return;
|
||
|
|
||
|
// On supprime la texture et ses dimensions
|
||
|
_indexes.erase( _indexes.begin() + xIndex );
|
||
|
_sprites.erase( _sprites.begin() + xIndex );
|
||
|
_src.erase( _src.begin() + xIndex );
|
||
|
_dst.erase( _dst.begin() + xIndex );
|
||
|
|
||
|
// On debloque l'acces
|
||
|
_mutex_pull.unlock();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* [MANAGEFTP] Gestion de la vitesse de boucle
|
||
|
=========================================================*/
|
||
|
void xManager::manageFps(const int fps){
|
||
|
/* (1) Definition de fps */
|
||
|
if( fps != 0 )
|
||
|
_fpstime = 1000/fps;
|
||
|
|
||
|
if( _lasttick == 0 )
|
||
|
_lasttick = SDL_GetTicks()-_fpstime;
|
||
|
|
||
|
/* (2) Utilisation en fin de boucle */
|
||
|
|
||
|
// 1 > Si trop rapide, on attends
|
||
|
if( SDL_GetTicks()-_lasttick < _fpstime )
|
||
|
SDL_Delay( _fpstime - (SDL_GetTicks()-_lasttick) );
|
||
|
|
||
|
// On enregistre le temps actuel
|
||
|
_lasttick = SDL_GetTicks();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* [UPDATE] Mise a jour du rendu
|
||
|
=========================================================*/
|
||
|
void xManager::update(){
|
||
|
// cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl;
|
||
|
// On bloque l'acces inter-thread
|
||
|
_mutex_update.lock();
|
||
|
|
||
|
/* (1) On efface le rendu */
|
||
|
SDL_RenderClear(_renderer);
|
||
|
|
||
|
|
||
|
/* (2) On applique la couleur de fond */
|
||
|
SDL_RenderDrawRect(_renderer, &_winrect);
|
||
|
|
||
|
|
||
|
/* (3) On ajoute le rendu principal (si existe) */
|
||
|
if( _texture != NULL)
|
||
|
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
|
||
|
|
||
|
|
||
|
/* (4) On ajoute toutes les textures pushees */
|
||
|
for( int i = 0 ; i < _sprites.size() ; i++ )
|
||
|
SDL_RenderCopy(_renderer, _sprites[i], _src[i], _dst[i]);
|
||
|
|
||
|
|
||
|
/* (n) On affiche le resultat */
|
||
|
SDL_RenderPresent(_renderer);
|
||
|
|
||
|
// On debloque l'acces
|
||
|
_mutex_update.unlock();
|
||
|
}
|
||
|
|
||
|
/* [ATTACHEVENT] Ajoute une fonction a un type d'evenement
|
||
|
=========================================================*/
|
||
|
void xManager::attachEvent(SDL_EventType t, void(*handler)(SDL_Event*)){
|
||
|
|
||
|
// On attache le type d'evenement a la fonction
|
||
|
_events.push_back( t );
|
||
|
_handlers.push_back( handler );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* [MANAGEEVENTS] Gestion des evenements
|
||
|
=========================================================*/
|
||
|
void xManager::manageEvents(SDL_Event *event){
|
||
|
// On lance les evenements en fonction de leur type
|
||
|
for( int i = 0 ; i < _events.size() ; i ++ )
|
||
|
if( event->type == _events[i] ) // si type ok
|
||
|
(*_handlers[i])(event); // on execute le handler
|
||
|
}
|