diff options
author | Olivier Gayot <duskcoder@gmail.com> | 2015-01-10 19:47:32 +0100 |
---|---|---|
committer | Olivier Gayot <duskcoder@gmail.com> | 2015-01-10 20:01:52 +0100 |
commit | f508e7191bd2f3eb7616e315e7e0d4a4b94c7914 (patch) | |
tree | 7bc1ed6498b3e2b7393ce791667bb9b50037e5fd /rpg.c | |
parent | 5ab5f72ba931e1d29a18a6b42e2cc2d73e291c4e (diff) |
cleaned the initialization / shutdown a little
The initialized surfaces are converted to display format so that they
are ready for fastblit.
Signed-off-by: Olivier Gayot <duskcoder@gmail.com>
Diffstat (limited to 'rpg.c')
-rw-r--r-- | rpg.c | 456 |
1 files changed, 456 insertions, 0 deletions
@@ -0,0 +1,456 @@ +#include <stdlib.h> +#include <stdio.h> +#include <SDL/SDL.h> +#include "structures.h" +#include "constantes.h" +#include <SDL/SDL_image.h> +#include <SDL/SDL_ttf.h> +#include "prototypes.h" +#include <time.h> + +#include "rpg.h" + +struct rpg_t rpg_g; + +static void colorize_surface(SDL_Surface *surf, const SDL_PixelFormat *fmt, Uint32 incr) +{ + int buffer = 0; + Uint8 r, g, b; + Uint8 rincr, gincr, bincr; /* delta */ + + SDL_GetRGB(incr, fmt, &rincr, &gincr, &bincr); + + SDL_LockSurface(surf); + + for (int y = 0; y < surf->h; ++y) { + for (int x = 0; x < surf->w; ++x) { + Uint32 pixel = obtenirPixel(surf, x, y); + + SDL_GetRGB(pixel, fmt, &r, &g, &b); + + /* red increment */ + buffer = (int)r + rincr; + if (buffer > 0xff) buffer = 0xff; + else if (buffer < 0x0) buffer = 0; + r = buffer; + + /* green increment */ + buffer = (int)g + gincr; + if (buffer > 0xff) buffer = 0xff; + else if (buffer < 0x0) buffer = 0; + g = buffer; + + /* blue increment */ + buffer = (int)b + bincr; + if (buffer > 0xff) buffer = 0xff; + else if (buffer < 0x0) buffer = 0; + b = buffer; + + pixel = SDL_MapRGB(fmt, r, g, b); + definirPixel(surf, x, y, pixel); + } + } + + SDL_UnlockSurface(surf); + SDL_SetColorKey(surf, SDL_SRCCOLORKEY, SDL_MapRGB(fmt, r, g, b)); +} + +static void colorize_every_red_surface(SURFACES *surfaces) +{ + const SDL_PixelFormat *fmt = surfaces->Pecran->format; + Uint32 red = SDL_MapRGB(fmt, 30, 0, 0); + + colorize_surface(surfaces->red_paladin, fmt, red); + colorize_surface(surfaces->red_priest, fmt, red); + colorize_surface(surfaces->red_thief, fmt, red); + + colorize_surface(surfaces->red_warrior_gobelin, fmt, red); +} + +static int rpg_load_images(SURFACES *surfaces) +{ +#define LOAD_IMAGE(_name, _path) \ + if ((surfaces->_name = IMG_Load(_path)) == NULL) { \ + fprintf(stderr, "Impossible d'ouvrir " _path); \ + return -1; \ + } + + LOAD_IMAGE(Pgobelin, "images/gobelin.bmp"); + LOAD_IMAGE(red_warrior_gobelin, "images/gobelin.bmp"); + LOAD_IMAGE(Ppaladin, "images/paladin.bmp"); + LOAD_IMAGE(Ppretre, "images/pretre.bmp"); + LOAD_IMAGE(Pvoleur, "images/voleur.bmp"); + LOAD_IMAGE(red_thief, "images/voleur.bmp"); + LOAD_IMAGE(red_paladin, "images/paladin.bmp"); + LOAD_IMAGE(red_priest, "images/pretre.bmp"); + LOAD_IMAGE(Pmenujouer, "images/menu_principal/jouer.bmp"); + LOAD_IMAGE(Pmenuoptions, "images/menu_principal/options.bmp"); + LOAD_IMAGE(Pmenuquitter, "images/menu_principal/quitter.bmp"); + LOAD_IMAGE(Pchoixvoleur, "images/menu_choix_classe/voleur.bmp"); + LOAD_IMAGE(Pchoixpretre, "images/menu_choix_classe/pretre.bmp"); + LOAD_IMAGE(Pchoixpaladin, "images/menu_choix_classe/paladin.bmp"); + LOAD_IMAGE(Pcurseurennemis, "images/jeu/curseur.bmp"); + LOAD_IMAGE(Pcurseurallies, "images/jeu/curseurpersos.bmp"); + LOAD_IMAGE(Pcadrecible, "images/jeu/cadre_cible.bmp"); + LOAD_IMAGE(Pactive, "images/jeu/active.bmp"); + LOAD_IMAGE(Pdesactive, "images/jeu/desactive.bmp"); + LOAD_IMAGE(Pcadreactions, "images/jeu/cadre_actions.bmp"); + LOAD_IMAGE(Pactionselectionnee, "images/jeu/cadre_actions_select.bmp"); + LOAD_IMAGE(Pactiondesactivee, "images/jeu/cadre_actions_unactive.bmp"); + LOAD_IMAGE(Pmort, "images/jeu/mort.bmp"); + LOAD_IMAGE(background, "images/jeu/textures/background.jpg"); + +#undef LOAD_IMAGE + return 0; +} + +static int rpg_initialize_sprites(void) +{ +#define set_color_key(surf_, r_, g_, b_) \ + SDL_SetColorKey((surf_), SDL_SRCCOLORKEY, SDL_MapRGB(rpg_g.surfaces.screen->format, (r_), (g_), (b_))) + +#define load_sprite(surf_) \ + tmp = SDL_DisplayFormat((surf_)); \ + if (tmp == NULL) return -1; \ + SDL_FreeSurface((surf_)); \ + (surf_) = tmp; + + SDL_Surface *tmp; + + set_color_key(rpg_g.surfaces.Pgobelin, 0, 255, 18); + set_color_key(rpg_g.surfaces.Ppretre, 39, 189, 31); + set_color_key(rpg_g.surfaces.Ppaladin, 189, 31, 31); + set_color_key(rpg_g.surfaces.Pvoleur, 39, 189, 31); + set_color_key(rpg_g.surfaces.red_priest, 39, 189, 31); + set_color_key(rpg_g.surfaces.red_paladin, 189, 31, 31); + set_color_key(rpg_g.surfaces.red_thief, 39, 189, 31); + + set_color_key(rpg_g.surfaces.Pcurseurennemis, 255, 255, 255); + set_color_key(rpg_g.surfaces.Pcurseurallies, 255, 255, 255); + set_color_key(rpg_g.surfaces.Pactive, 255, 255, 255); + set_color_key(rpg_g.surfaces.Pdesactive, 255, 255, 255); + set_color_key(rpg_g.surfaces.Pmort, 255, 255, 255); + + load_sprite(rpg_g.surfaces.Pgobelin); + load_sprite(rpg_g.surfaces.Ppretre); + load_sprite(rpg_g.surfaces.Ppaladin); + load_sprite(rpg_g.surfaces.Pvoleur); + + load_sprite(rpg_g.surfaces.Pmenuoptions); + load_sprite(rpg_g.surfaces.Pmenujouer); + load_sprite(rpg_g.surfaces.Pmenuquitter); + + load_sprite(rpg_g.surfaces.Pchoixpaladin); + load_sprite(rpg_g.surfaces.Pchoixpretre); + load_sprite(rpg_g.surfaces.Pchoixvoleur); + load_sprite(rpg_g.surfaces.Pcurseurallies); + load_sprite(rpg_g.surfaces.Pcurseurennemis); + + load_sprite(rpg_g.surfaces.Pcadrecible); + load_sprite(rpg_g.surfaces.Pactive); + load_sprite(rpg_g.surfaces.Pdesactive); + load_sprite(rpg_g.surfaces.Pcadreactions); + load_sprite(rpg_g.surfaces.Pactionselectionnee); + load_sprite(rpg_g.surfaces.Pactiondesactivee); + load_sprite(rpg_g.surfaces.Pmort); + + load_sprite(rpg_g.surfaces.background); + rpg_g.surfaces.Pfondjeu = rpg_g.surfaces.background; + + rpg_g.surfaces.red_warrior_gobelin = SDL_DisplayFormat(rpg_g.surfaces.Pgobelin); + if (rpg_g.surfaces.red_warrior_gobelin == NULL) + return -1; + + rpg_g.surfaces.red_priest = SDL_DisplayFormat(rpg_g.surfaces.Ppretre); + if (rpg_g.surfaces.red_priest == NULL) + return -1; + + rpg_g.surfaces.red_thief = SDL_DisplayFormat(rpg_g.surfaces.Pvoleur); + if (rpg_g.surfaces.red_thief == NULL) + return -1; + + colorize_every_red_surface(&rpg_g.surfaces); + +#undef load_sprite +#undef set_color_key + return 0; +} + +static void Finitialiserpositions (POSITIONS *positions, const SURFACES *surfaces) +{ + int i,y=0,z=0; + positions->Vpositionmenu.x = 0; + positions->Vpositionmenu.y = 0; + positions->Vpositionmenupretre.x = XWIN/2 - surfaces->Ppretre->w/2; + positions->Vpositionmenupretre.y = YWIN - 20 - surfaces->Ppretre->h; + positions->Vpositionmenupaladin.x = positions->Vpositionmenupretre.x/2 - surfaces->Ppaladin->w/2; + positions->Vpositionmenupaladin.y = YWIN - 20 - surfaces->Ppaladin->h; + positions->Vpositionmenuvoleur.x = XWIN/4*3 - surfaces->Pvoleur->w/2; + positions->Vpositionmenuvoleur.y = YWIN - 20 - surfaces->Pvoleur->h; + positions->Vpositiontextemenu.y = 362; + positions->Vpositioncurseurennemis.x=1024; + positions->Vpositioncurseurennemis.y=768; + positions->Vpositioncurseurallies.x=1024; + positions->Vpositioncurseurallies.y=768; + positions->Vpositioncurseurennemis.w = surfaces->Pcurseurennemis->w; + positions->Vpositioncurseurennemis.h = surfaces->Pcurseurennemis->h; + positions->Vpositioncadrecible.y = 15; + positions->Vpositioncadrecible.x = XWIN/2-50-surfaces->Pcadrecible->w/2; + positions->Vpositioncadrecible.w = surfaces->Pcadrecible->w; + positions->Vpositioncadrecible.h = surfaces->Pcadrecible->h; + positions->Vpositioncadreactions.y = YWIN-surfaces->Pcadreactions->h; + positions->Vpositioncadreactions.x = XWIN/2-50-surfaces->Pcadreactions->w/2; + positions->Vpositioncadreactions.w = surfaces->Pcadreactions->w; + positions->Vpositioncadreactions.h = surfaces->Pcadreactions->h; + positions->Vpositionpvcible.x = 380; + positions->Vpositionpvcible.y = 185; + positions->Vpositionpmcible.x = 545; + positions->Vpositionpmcible.y = 185; + positions->Vpositiondegats.x=1024; + positions->Vpositiondegats.y=768; + for(i=0;i<3;i++) + { + positions->Vpositionactionselectionnee[i].x=positions->Vpositioncadreactions.x+5; + positions->Vpositionactionselectionnee[i].y=positions->Vpositioncadreactions.y+5+44*i; + positions->Vpositionnomactions[i].x=positions->Vpositioncadreactions.x+15; + positions->Vpositionnomactions[i].y=positions->Vpositioncadreactions.y+12+44*i; + positions->Vpositionquantite[i].y=positions->Vpositionnomactions[i].y; + positions->Vpositionquantite[i].x=positions->Vpositioncadreactions.x+surfaces->Pcadreactions->w-45; + } + for (i=0;i < 16;i++) + { + positions->Vpositionactivedesactive[i].x = 471+51*y; + positions->Vpositionactivedesactive[i].y = 101+19*z; + if (y < 3) + y++; + else + { + y=0; + z++; + } + } + + positions->last_cursor = (SDL_Rect){0, 0, 0, 0}; +} + +static int rpg_init(void) +{ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); + return -1; + } + + /* avoid the need of closing the SDL library manually */ + atexit(SDL_Quit); + + if (TTF_Init() < 0) { + fprintf(stderr, "TTF_Init: %s\n", TTF_GetError()); + return -1; + } + + /* avoid the need of closing the SDL_ttf library manually */ + atexit(TTF_Quit); + + rpg_g.font = TTF_OpenFont("fonts/default.ttf", 20); + if (rpg_g.font == NULL) { + fprintf(stderr, "TTF_OpenFont: %s\n", TTF_GetError()); + return -1; + } + + if (rpg_load_images(&rpg_g.surfaces) < 0) { + return -1; + } + + rpg_g.screen = SDL_SetVideoMode(XWIN, YWIN, 0, SDL_HWSURFACE | SDL_DOUBLEBUF); + + if (rpg_g.screen == NULL) { + fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError()); + return -1; + } + + /* set the deprecated pointers to screen */ + rpg_g.surfaces.screen = rpg_g.surfaces.Pecran = rpg_g.screen; + + rpg_initialize_sprites(); + + Finitialiserpositions(&rpg_g.positions, &rpg_g.surfaces); + + /* XXX not sure this is useful */ + SDL_EnableUNICODE (1); + + SDL_WM_SetCaption ("RPG", NULL); + SDL_ShowCursor(SDL_DISABLE); + + return 0; +} + +static void Fdechargerimages(SURFACES *surfaces) +{ + int i; + + SDL_FreeSurface (surfaces->Pgobelin); + SDL_FreeSurface(surfaces->red_warrior_gobelin); + + SDL_FreeSurface (surfaces->Ppaladin); + SDL_FreeSurface (surfaces->Ppretre); + SDL_FreeSurface (surfaces->Pvoleur); + + SDL_FreeSurface(surfaces->red_paladin); + SDL_FreeSurface(surfaces->red_priest); + SDL_FreeSurface(surfaces->red_thief); + + SDL_FreeSurface (surfaces->Pmenujouer); + SDL_FreeSurface (surfaces->Pmenuoptions); + SDL_FreeSurface (surfaces->Pmenuquitter); + SDL_FreeSurface (surfaces->Pchoixpretre); + SDL_FreeSurface (surfaces->Pchoixpaladin); + SDL_FreeSurface (surfaces->Pchoixvoleur); + SDL_FreeSurface (surfaces->Pcurseurennemis); + SDL_FreeSurface (surfaces->Pcurseurallies); + SDL_FreeSurface (surfaces->Pcadrecible); + SDL_FreeSurface (surfaces->Pactive); + SDL_FreeSurface (surfaces->Pdesactive); + SDL_FreeSurface (surfaces->Pcadreactions); + SDL_FreeSurface (surfaces->Pactionselectionnee); + SDL_FreeSurface (surfaces->Pactiondesactivee); + SDL_FreeSurface (surfaces->Pmort); + SDL_FreeSurface (surfaces->Pfondjeu); + SDL_FreeSurface(surfaces->Ptextechoixmenu); + SDL_FreeSurface(surfaces->Pnbdegats); + SDL_FreeSurface(surfaces->Pnomcible); + SDL_FreeSurface(surfaces->Ppvcible); + SDL_FreeSurface(surfaces->Ppmcible); + SDL_FreeSurface(surfaces->Ppvpersos); + SDL_FreeSurface(surfaces->Ppmpersos); + + for(i=0;i<3;i++) + { + SDL_FreeSurface (surfaces->Pnomactions[i]); + } + for(i=0;i<3;i++) + { + SDL_FreeSurface (surfaces->Pquantite[i]); + } +} + +static void rpg_shutdown(void) +{ + Fdechargerimages(&rpg_g.surfaces); + + if (TTF_WasInit()) { + TTF_CloseFont(rpg_g.font); + } +} + +int main (int argc, char *argv[]) +{ + /* XXX argc and argv are required in some implementations of the SDL library */ + (void) argc; + (void) argv; + + srand(time(NULL)); + + if (rpg_init() >= 0) { + Fmenuprincipal(&rpg_g.surfaces, &rpg_g.positions); + } + + rpg_shutdown(); + + return 0; +} + + +/* ********************************************************************* */ +/*obtenirPixel : permet de récupérer la couleur d'un pixel +Paramètres d'entrée/sortie : +SDL_Surface *surface : la surface sur laquelle on va récupérer la couleur d'un pixel +int x : la coordonnée en x du pixel à récupérer +int y : la coordonnée en y du pixel à récupérer + +Uint32 resultat : la fonction renvoie le pixel aux coordonnées (x,y) dans la surface +*/ +Uint32 obtenirPixel(SDL_Surface *surface, int x, int y) +{ + /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. + En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur + de l'image : 8, 16, 24 ou 32 bits.*/ + int nbOctetsParPixel = surface->format->BytesPerPixel; + /* Ici p est l'adresse du pixel que l'on veut connaitre */ + /*surface->pixels contient l'adresse du premier pixel de l'image*/ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel; + + /*Gestion différente suivant le nombre d'octets par pixel de l'image*/ + switch(nbOctetsParPixel) + { + case 1: + return *p; + + case 2: + return *(Uint16 *)p; + + case 3: + /*Suivant l'architecture de la machine*/ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + return p[0] << 16 | p[1] << 8 | p[2]; + else + return p[0] | p[1] << 8 | p[2] << 16; + + case 4: + return *(Uint32 *)p; + + /*Ne devrait pas arriver, mais évite les erreurs*/ + default: + return 0; + } +} + +/* ********************************************************************* */ +/*definirPixel : permet de modifier la couleur d'un pixel +Paramètres d'entrée/sortie : +SDL_Surface *surface : la surface sur laquelle on va modifier la couleur d'un pixel +int x : la coordonnée en x du pixel à modifier +int y : la coordonnée en y du pixel à modifier +Uint32 pixel : le pixel à insérer +*/ +void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) +{ + /*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel. + En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur + de l'image : 8, 16, 24 ou 32 bits.*/ + int nbOctetsParPixel = surface->format->BytesPerPixel; + /*Ici p est l'adresse du pixel que l'on veut modifier*/ + /*surface->pixels contient l'adresse du premier pixel de l'image*/ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel; + + /*Gestion différente suivant le nombre d'octets par pixel de l'image*/ + switch(nbOctetsParPixel) + { + case 1: + *p = pixel; + break; + + case 2: + *(Uint16 *)p = pixel; + break; + + case 3: + /*Suivant l'architecture de la machine*/ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } + else + { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + break; + + case 4: + *(Uint32 *)p = pixel; + break; + } +} |