diff --git a/README.md b/README.md index fc12e72..45c7891 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,13 @@ Lab de prog. en C++. [ex5] Surcharge d'operateurs (Duree) [tp2] Surcharge d'operateurs (Fraction) + +[Chess] Jeu d'echec en console (couleurs + unicode) + +[SDL#1] Creation librairie perso pour Sprites + +[SDL#2] Creation librairie perso pour animations + +[SDL#3] Passage de SDL_Surface a SDL_Renderer + + diff --git a/SDL#3/Sprite.cpp b/SDL#3/Sprite.cpp new file mode 100644 index 0000000..4759779 --- /dev/null +++ b/SDL#3/Sprite.cpp @@ -0,0 +1,224 @@ +/* [DESTRUCTOR] Destruction de la surface +=========================================================*/ +Sprite::~Sprite(){ + SDL_FreeSurface( _surface ); +} + + +/* [CONSTRUCTOR] Construction de la surface vide +=========================================================*/ +Sprite::Sprite(SDL_Rect r){ + _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); + + // On definit les dimensions + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){0, 0, r.w, r.h}; + + // On applique les offset + SDL_SetClipRect( _surface, &_rect ); + +} + + + +/* [CONSTRUCTOR] Construction de la surface avec couleur +=========================================================*/ +Sprite::Sprite(const int rgb[], SDL_Rect r){ + cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; + + _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]); + + // On recupere la couleur + Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]); + + // On remplit avec la couleur + SDL_FillRect( _surface, NULL, color ); + + // On definit les dimensions + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){0, 0, r.w, r.h}; + + + // On applique les offset + SDL_SetClipRect( _surface, &_rect ); +} + + + +/* [CONSTRUCTOR] Construction de la surface avec image +=========================================================*/ +Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){ + + /* (1) On cree la surface (avec image) */ + _surface = IMG_Load( url ); + + // Gestion erreur + if( _surface == NULL ) + return; + + // On definit les dimensions + _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; + _origin = (SDL_Rect){clip.x, clip.y, r.w, r.h}; + + // On applique le clip + SDL_SetClipRect( _surface, &clip ); + +} + + + +/* [APPENDTO] Ajoute le Sprite au rendu +=========================================================*/ +void Sprite::appendTo(sdltl *mgr){ + _texture = SDL_CreateTextureFromSurface(mgr->renderer(), _surface); + + mgr->add(_texture, &_origin, &_rect); +} + +/* [REMOVEFROM] Retire une sprite du rendu +=========================================================*/ +void Sprite::removeFrom(sdltl *mgr){ + mgr->remove( _texture ); +} + +/* [SURFACE] Retourne la surface +=========================================================*/ +SDL_Surface *Sprite::surface(){ return _surface; } + + + + + + + + + + + + + + + + +/**********************************/ +/*********** SPRITEGROUP **********/ +/**********************************/ +/* [CONSTRUCTOR] Initialisation de la liste de Sprite +=========================================================*/ +SpriteGroup::SpriteGroup(){ + // _sprites = new vector(0); +} + +/* [ADD] Ajoute un Sprite au groupe +=========================================================*/ +void SpriteGroup::add(Sprite *s){ + _sprites.push_back( s ); +} + +/* [REMOVE] Suppression d'un Sprite du groupe +=========================================================*/ +void SpriteGroup::remove(Sprite *s){ + int index = -1; // on cherche l'indice du sprite + + // On parcours la liste pour trouver l'indice + for( int i = 0 ; i < _sprites.size() ; i++ ) + if( _sprites[i] == s ) index = i; + + // Si on a pas trouve l'indice + if( index == -1 ) return; + + // On supprime le sprite de la liste + _sprites.erase(_sprites.begin() + index ); + +} + +/* [APPENDTO] Ajoute tous les Sprite du groupe a une surface parente +=========================================================*/ +void SpriteGroup::appendTo(sdltl *mgr){ + for( int i = 0 ; i < _sprites.size() ; i++ ) + _sprites[i]->appendTo( mgr ); +} + +/* [REMOVEFROM] Retire une sprite de la surface parents +=========================================================*/ +void SpriteGroup::removeFrom(sdltl *mgr){ + for( int i = 0 ; i < _sprites.size() ; i++ ) + _sprites[i]->removeFrom( mgr ); +} + + +/* [GET] Retourne le Sprite d'index donne +=========================================================*/ +Sprite* SpriteGroup::get(int i){ + return _sprites[i]; +} + + + + +/* [TRHEAD] Process de l'animation +=========================================================*/ +void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){ + int length = sg->_sprites.size(); + int timer = 0; + int step = 1; + int start = 0; + int stop = length; + int lastindex = -1; + + while( flags&SPRITE_ANIM_INFINITE ){ + + /* (1) Pour chaque sprite */ + for( int i = start ; i != stop ; i+=step ){ + timer = SDL_GetTicks(); + + + // On retire le sprite precedent + if( lastindex > -1 ) + sg->_sprites[lastindex]->removeFrom( mgr ); + + // On ajoute le sprite + sg->_sprites[i]->appendTo( mgr ); + + // On met a jour le rendu + // mgr->update(); + + + if( SDL_GetTicks()-timer < t ) + SDL_Delay( t - (SDL_GetTicks()-timer) ); + + lastindex = i; + + } + + /* (2) Gestion des flags */ + + // SPRITE_ANIM_REVERSE + if( flags&SPRITE_ANIM_REVERSE ){ + step *= -1; + start = (step==1) ? 0 : length-1; + stop = (step==1) ? length-1 : 0; + } + + } + + + /* (n) On termine le thread */ + return; +} + + + + +/* [ANIMATE] Modifie le Sprite dans l'ordre du SpriteGroup +=========================================================*/ +thread* SpriteGroup::animate(sdltl *mgr, int t, int flags){ + _animation = new thread(SpriteGroupAnimation, mgr, this, t, flags); + + // On attends pas le thread + _animation->detach(); + + return _animation; +} + + diff --git a/SDL#3/Sprite.h b/SDL#3/Sprite.h new file mode 100644 index 0000000..ef1a182 --- /dev/null +++ b/SDL#3/Sprite.h @@ -0,0 +1,79 @@ +#ifndef DEF_SPRITE_H + + #define DEF_SPRITE_H + + /* [LIBS] Internes + =========================================================*/ + #include "SDL.h" + #include "SDL_image.h" + #include + #include + #include + + /* [LIBS] Externes + =========================================================*/ + #define SPRITE_ANIM_ONCE 0x1 + #define SPRITE_ANIM_INFINITE 0x10 + #define SPRITE_ANIM_REVERSE 0x100 + + /* [NS] Namespaces + =========================================================*/ + using namespace std; + + + class Sprite{ + + public: + Sprite(SDL_Rect r); + Sprite(const int rgb[], SDL_Rect r); + Sprite(const char url[], SDL_Rect r, SDL_Rect clip); + ~Sprite(); + + void setImage(const char url[], int ox=0, int oy=0); + + void appendTo(sdltl *mgr); + void removeFrom(sdltl *mgr); + + // GETTERS + SDL_Surface *surface(); + + private: + SDL_Surface *_surface; + SDL_Texture *_texture; + + SDL_Rect _rect; + SDL_Rect _origin; + + }; + + /* [AGGR] Groupement de Sprite + =========================================================*/ + class SpriteGroup{ + + public: + SpriteGroup(); + void add(Sprite *s); + void remove(Sprite *s); + Sprite* get(int i); + void appendTo(sdltl *mgr); + void removeFrom(sdltl *mgr); + + thread *animate(sdltl *mgr, int t, int flags=0); + + private: + SDL_Renderer *_renderer; + vector _sprites; + thread *_animation; + + + friend void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags=SPRITE_ANIM_ONCE ); + + }; + + + /* [BODY] Inclusion du corps + =========================================================*/ + #include "Sprite.cpp" + + +#endif \ No newline at end of file diff --git a/SDL#3/exe b/SDL#3/exe new file mode 100755 index 0000000..cdfd567 Binary files /dev/null and b/SDL#3/exe differ diff --git a/SDL#3/main.cpp b/SDL#3/main.cpp new file mode 100644 index 0000000..1fbe95b --- /dev/null +++ b/SDL#3/main.cpp @@ -0,0 +1,174 @@ +#include "main.h" + +// On cree un sdl-toplevel statique +static sdltl *mgr = NULL; +static bool running = true; + + + +int main(int argc, char* argv[]) { + srand(time(0)); + + /* [0] Initialisation de SDL + =========================================================*/ + mgr = new sdltl("Ma fenetre SDL", WIN_WIDTH, WIN_HEIGHT); + + /* [1] Creation de la fenetre + =========================================================*/ + if( !mgr->status() ) cout << "Erreur: " << SDL_GetError() << endl; + + + /* [3] On definit le background color + =========================================================*/ + bool bgLoaded = mgr->setBackground(255, 255, 255); + cout << "BG: " << bgLoaded << endl; + // bool imageLoaded = mgr->setImage( "src/1.bmp" ); + + + + /* [4] On ajoute Une animation + =========================================================*/ + /* (1) On cree les fonds pour couvrir les frames en arriere plan */ + int white[] = {255, 255, 255}; + Sprite *mb_background = new Sprite( + white, + (SDL_Rect){0, 0, 20, 20} + ); + + Sprite *gs_background = new Sprite( + white, + (SDL_Rect){100, 0, 20, 20} + ); + + Sprite *rs_background = new Sprite( + white, + (SDL_Rect){150, 0, 20, 20} + ); + + + /* (2) On enregistre les frames de l'animation du bloc mystere */ + SpriteGroup animated_mystery_bloc; + + for( int i = 0 ; i < 4 ; i++ ){ + + animated_mystery_bloc.add( new Sprite( + "src/mario_crop.png", + (SDL_Rect){0, 0, 20, 20}, + (SDL_Rect){4*19+19*i, 2*20, 20, 20} + ) ); + + } + + /* (3) On enregistre les frames de l'animation d'une carapace verte */ + SpriteGroup animated_green_shell; + + for( int i = 0 ; i < 4 ; i++ ){ + + animated_green_shell.add( new Sprite( + "src/mario_crop.png", + (SDL_Rect){100, 0, 20, 20}, + (SDL_Rect){4*19+19*i, 11*19, 20, 20} + ) ); + + } + + /* (4) On enregistre les frames de l'animation d'une carapace rouge */ + SpriteGroup animated_red_shell; + + for( int i = 0 ; i < 4 ; i++ ){ + + animated_red_shell.add( new Sprite( + "src/mario_crop.png", + (SDL_Rect){150, 0, 20, 20}, + (SDL_Rect){2+19*i, 11*19, 20, 20} + ) ); + + } + + + // TEST + int red[] = {255, 0, 0}; + int pink[] = {255, 0, 255}; + SpriteGroup testgroup; + + testgroup.add( new Sprite( + "src/mario_crop.png", + (SDL_Rect){150, 0, 20, 20}, + (SDL_Rect){2+19*1, 11*19, 20, 20} + ) ); + + testgroup.add( new Sprite( + pink, + (SDL_Rect){100, 0, 100, 100} + ) ); + + // testgroup.appendTo(mgr); + testgroup.get(0)->appendTo(mgr); + + + + + + + /* [5] On lance les animation en parallele + =========================================================*/ + vector animations(0); + + + animations.push_back( animated_mystery_bloc.animate( + mgr, // rendu a mettre a jour + 200, // delai entre-frames + SPRITE_ANIM_INFINITE // FLAGS + ) ); + delete animations[0]; // On le supprime ensuite + + + animations.push_back( animated_green_shell.animate( + mgr, // rendu a mettre a jour + 100, // delai entre-frames + SPRITE_ANIM_INFINITE // FLAGS + ) ); + delete animations[1]; // On le supprime ensuite + + + animations.push_back( animated_red_shell.animate( + mgr, // rendu a mettre a jour + 100, // delai entre-frames + SPRITE_ANIM_INFINITE // FLAGS + ) ); + delete animations[2]; // On le supprime ensuite + + + + + /* [n-1] Boucle infinie + =========================================================*/ + mgr->manageFps(FPS); + running = true; + while(running){ + mgr->waitEvent(SDL_QUIT, &quitEventHandler); + + // cout << "Main loop" << endl; + mgr->update(); + + // Gestion des FPS (vitesse de la boucle) + mgr->manageFps(); + } + + + + + + + + /* [n] Fin d'execution + =========================================================*/ + delete mgr; + return 0; +} + + +void quitEventHandler(SDL_Event *e){ + cout << "Ferme" << endl; + running = false; +} \ No newline at end of file diff --git a/SDL#3/main.h b/SDL#3/main.h new file mode 100644 index 0000000..4e050b9 --- /dev/null +++ b/SDL#3/main.h @@ -0,0 +1,31 @@ +#ifndef DEF_MAIN_H + + #define DEF_MAIN_H + + /* [LIB] Internes + =========================================================*/ + #include + #include + #include + + /* [LIB] Externes + =========================================================*/ + #include "sdltl.h" // gestion de la fenetre et SDL + #include "Sprite.h" // gestion des sprites + + /* [NS] Namespace + =========================================================*/ + using namespace std; + + /* [CONST] Constantes et enumerations + =========================================================*/ + #define WIN_WIDTH 600 + #define WIN_HEIGHT 400 + + #define FPS 60 + + /* [FONCTIONS] Fonctions du corps + =========================================================*/ + void quitEventHandler(SDL_Event *e); + +#endif \ No newline at end of file diff --git a/SDL#3/main.o b/SDL#3/main.o new file mode 100644 index 0000000..fa9582f Binary files /dev/null and b/SDL#3/main.o differ diff --git a/SDL#3/makefile b/SDL#3/makefile new file mode 100644 index 0000000..18fbdeb --- /dev/null +++ b/SDL#3/makefile @@ -0,0 +1,41 @@ +.PHONY: init, clean, mrproper +CC=g++ +FLAGS=-pthread -std=c++11 `pkg-config sdl2 --cflags --libs` -l SDL2_image + +# INIT > STRUCTURE DE FICHIERS POUR LES EXECUTABLES +init: clean + mkdir dep.o + + + + + + + + + + +# EXECUTABLE > DEPENDANCES DE L'EXECUTABLE +all: init main.o clean + rm -r dep.o + $(CC) main.o -o exe $(FLAGS) + +# AMORCE > PROGRAMME PRINCIPAL +main.o: main.cpp + $(CC) -c $< -o main.o $(FLAGS) + + + + + + + + +# RESET > SUPPRESSION DES FICHIERS +clean: + touch init.o + rm -r *.o + +# RESET FOR REBUILD > SUPPRESSION DE L'EXECUTABLE +mrproper: + rm exe diff --git a/SDL#3/sdltl.cpp b/SDL#3/sdltl.cpp new file mode 100644 index 0000000..93d387b --- /dev/null +++ b/SDL#3/sdltl.cpp @@ -0,0 +1,217 @@ +/* [CONSTRUCTOR] Constructeur de la classe +=========================================================*/ +sdltl::sdltl(const char *t, int w, int h){ + // default values + _lasttick = 0; + _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; + + + // Creation du renderer + _renderer = SDL_CreateRenderer( + _window, + -1, + SDL_RENDERER_ACCELERATED + ); + +} + +/* [DESTROYER] Destructeur de la classe +=========================================================*/ +sdltl::~sdltl(){ + SDL_DestroyTexture(_texture); + SDL_DestroyRenderer(_renderer); + SDL_DestroyWindow( _window ); + SDL_Quit(); +} + +/* [STATUS] Retourne le status +=========================================================*/ +bool sdltl::status(){ + return _window != NULL && _renderer != NULL; +} + + +/* [WINDOW] Retourne la fenetre +=========================================================*/ +SDL_Window* sdltl::window(){ return _window; } + + +/* [SCREEN] Retourne la fenetre +=========================================================*/ +SDL_Renderer* sdltl::renderer(){ return _renderer; } + + +/* [SETBACKGROUND] Modifie la couleur de fond +=========================================================*/ +bool sdltl::setBackground(int r, int g, int b){ + /*// On cree la surface + SDL_Surface *surf = NULL; + int win[2]; + SDL_GetWindowSize(_window, &win[0], &win[1]); + + // On cree la surface + surf = SDL_CreateRGBSurface(0, win[0], win[1], 32, 0, 0, 0, 0); + + if( surf == NULL ) + return false; + + // On cree la couleur + Uint32 color = SDL_MapRGB(surf->format, r, g, b); + + // On colore la surface + SDL_FillRect(surf, NULL, color); + + + // On applique a la texture + _texture = SDL_CreateTextureFromSurface(_renderer, surf); + + if( _texture == NULL ) + return false; + + + // On libere la memoire + SDL_FreeSurface(surf); + surf = NULL; + */ + + SDL_SetRenderDrawColor( _renderer, 0xFF, 0xFF, 0xFF, 0x00 ); + + return true; +} + +/* [SETIMAGE] Met une image en fond +=========================================================*/ +bool sdltl::setImage(const char *url){ + + SDL_Surface *image = NULL; + image = SDL_LoadBMP( url ); + + // Si erreur de chargement image + if( image == NULL ) + return false; + + // On cree la texture associee + _texture = SDL_CreateTextureFromSurface( + _renderer, + image + ); + + // On libere la surface pour l'image + SDL_FreeSurface(image); + delete image; + + return true; +} + + +/* [ADD] Ajoute une texture au rendu principal +=========================================================*/ +void sdltl::add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest){ + _sprites.push_back( t ); + _origins.push_back( origin ); + _dests.push_back( dest ); +} + + +/* [REMOVE] Retire une texture du rendu principal +=========================================================*/ +void sdltl::remove(SDL_Texture *t){ + // On cherche l'indice de la texture + int index = -1; + + for( int i = 0 ; i < _sprites.size() ; i++ ) + if( _sprites[i] == t ) index = i; + + // Si on a rien trouve + if( index == -1 ) + return; + + // On supprime la texture et ses dimensions + _sprites.erase( _sprites.begin() + index ); + _origins.erase( _origins.begin() + index ); + _dests.erase( _dests.begin() + index ); +} + + + +/* [UPDATE] Mise a jour du rendu +=========================================================*/ +void sdltl::update(){ + // On efface l'ecran + SDL_RenderClear(_renderer); + + // On ajoute le rendu principal au rendu + if( _texture != NULL) + SDL_RenderCopy(_renderer, _texture, NULL, NULL); + + // On ajoute toutes les textures ajoutees + cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl; + // for( int i = _sprites.size()-1 ; i >= 0 ; i-- ) + for( int i = 0 ; i < _sprites.size() ; i++ ) + SDL_RenderCopy(_renderer, _sprites[i], _origins[i], _dests[i]); + + // On affiche le resultat + SDL_RenderPresent(_renderer); +} + +/* [WAITEVENT] Attends un evenement pour executer +=========================================================*/ +void sdltl::waitEvent(SDL_EventType t, void(*handler)(SDL_Event*)){ + SDL_Event event; + + // On attends un evenement + while( SDL_PollEvent(&event) ){ + + // quand evenement, si type = t + if( event.type == t ) + (*handler)(&event); + + } +} + +/* [MANAGEFTP] Gestion de la vitesse de boucle +=========================================================*/ +void sdltl::manageFps(const int fps){ + /* (1) Definition de fps */ + if( fps != 0 ) _fpstime = 1000/fps; + + /* (2) Initialisation timer */ + if( _lasttick == 0 ) + _lasttick = SDL_GetTicks(); + + /* (3) Utilisation en fin de WHILE() */ + + // 1 > Si trop rapide, on attends + definit _lasttick + else if( SDL_GetTicks()-_lasttick < _fpstime ){ + SDL_Delay( _fpstime - (SDL_GetTicks()-_lasttick) ); + + _lasttick = SDL_GetTicks() + _fpstime - (SDL_GetTicks()-_lasttick); + + // 2 > Temps ok + }else + _lasttick = SDL_GetTicks(); + + +} \ No newline at end of file diff --git a/SDL#3/sdltl.h b/SDL#3/sdltl.h new file mode 100644 index 0000000..8641ca5 --- /dev/null +++ b/SDL#3/sdltl.h @@ -0,0 +1,62 @@ +#ifndef DEF_SDLTL_H + + #define DEF_SDLTL_H + + /* [LIBS] Internes + =========================================================*/ + #include "SDL.h" + #include + + /* [LIBS] Externes + =========================================================*/ + + + /* [NS] Namespaces + =========================================================*/ + using namespace std; + + + class sdltl{ + + public: + sdltl(const char *t, int w, int h); + ~sdltl(); + SDL_Window *window(); + SDL_Renderer *renderer(); + bool status(); + bool setBackground(int r=255, int g=255, int b=255); + bool setImage(const char *url); + void waitEvent(SDL_EventType t, void(*handler)(SDL_Event*) ); + + void add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest); + void remove(SDL_Texture *t); + void update(); + + void manageFps(const int fps=0); + + private: + // gestion FPS + Uint32 _lasttick; + Uint32 _fpstime; + + // status de l'initialisation + bool _status; + + // Elements utiles + SDL_Window *_window; + SDL_Renderer *_renderer; + SDL_Texture *_texture; + + vector _sprites; + vector _origins; + vector _dests; + + }; + + + /* [BODY] Inclusion du corps + =========================================================*/ + #include "sdltl.cpp" + + +#endif \ No newline at end of file diff --git a/SDL#3/src/01.jpg b/SDL#3/src/01.jpg new file mode 100644 index 0000000..a286e6c Binary files /dev/null and b/SDL#3/src/01.jpg differ diff --git a/SDL#3/src/1.bmp b/SDL#3/src/1.bmp new file mode 100644 index 0000000..5641e75 Binary files /dev/null and b/SDL#3/src/1.bmp differ diff --git a/SDL#3/src/bloc.png b/SDL#3/src/bloc.png new file mode 100644 index 0000000..6541d57 Binary files /dev/null and b/SDL#3/src/bloc.png differ diff --git a/SDL#3/src/bloc_crop.png b/SDL#3/src/bloc_crop.png new file mode 100644 index 0000000..ed44639 Binary files /dev/null and b/SDL#3/src/bloc_crop.png differ diff --git a/SDL#3/src/coins.jpg b/SDL#3/src/coins.jpg new file mode 100644 index 0000000..db7b8fa Binary files /dev/null and b/SDL#3/src/coins.jpg differ diff --git a/SDL#3/src/mario.jpg b/SDL#3/src/mario.jpg new file mode 100644 index 0000000..d6e7c23 Binary files /dev/null and b/SDL#3/src/mario.jpg differ diff --git a/SDL#3/src/mario_crop.png b/SDL#3/src/mario_crop.png new file mode 100644 index 0000000..da7b81f Binary files /dev/null and b/SDL#3/src/mario_crop.png differ diff --git a/SDL#3/src/walking.png b/SDL#3/src/walking.png new file mode 100644 index 0000000..1938f51 Binary files /dev/null and b/SDL#3/src/walking.png differ