#include #include #include #include "structures.h" #include "constantes.h" #include #include #include "prototypes.h" #include #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 = surfaces->screen->w / 2 - surfaces->Ppretre->w / 2; positions->Vpositionmenupretre.y = surfaces->screen->h - 20 - surfaces->Ppretre->h; positions->Vpositionmenupaladin.x = positions->Vpositionmenupretre.x/2 - surfaces->Ppaladin->w/2; positions->Vpositionmenupaladin.y = surfaces->screen->h - 20 - surfaces->Ppaladin->h; positions->Vpositionmenuvoleur.x = surfaces->screen->w / 4 * 3 - surfaces->Pvoleur->w / 2; positions->Vpositionmenuvoleur.y = surfaces->screen->h - 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 = surfaces->screen->w / 2 - 50 - surfaces->Pcadrecible->w / 2; positions->Vpositioncadrecible.w = surfaces->Pcadrecible->w; positions->Vpositioncadrecible.h = surfaces->Pcadrecible->h; positions->Vpositioncadreactions.y = surfaces->screen->h - surfaces->Pcadreactions->h; positions->Vpositioncadreactions.x = surfaces->screen->w / 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(int width, int height) { 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(width, height, 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[]) { int width = DEFAULT_WIDTH; int height = DEFAULT_HEIGHT; /* TODO handle arguments properly */ if (argc >= 3) { width = atoi(argv[1]); height = atoi(argv[2]); } srand(time(NULL)); if (rpg_init(width, height) >= 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; } }