/*************************************************************************** * image.c * * Sat May 14 00:31:45 2005 * Copyright 2005 Vamps * vamps@alterinet.org ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "include/image.h" #include "include/main.h" #include "include/time.h" #include "include/level.h" #define MAX_BUF 300 #define MIN_BUF 10 void *bullet(void *arg); SDL_Surface * AfficherBMP (char *file, SDL_Surface * screen, int x, int y) { SDL_Surface *image; SDL_Rect dest; image = SDL_LoadBMP (file); if (image == NULL) { printf("Impossible de charger %s: %s\n", file, SDL_GetError ()); return image; } dest.x = x; dest.y = y; dest.w = image->w; dest.h = image->h; SDL_SetColorKey (image, SDL_SRCCOLORKEY, SDL_MapRGB (image->format, 255, 0, 0)); SDL_BlitSurface (image, NULL, screen, &dest); SDL_UpdateRects (screen, 1, &dest); return image; } SDL_Surface * AfficherBMP_menu (char *file, SDL_Surface * screen, int x, int y) { SDL_Surface *image; SDL_Rect dest; image = SDL_LoadBMP (file); if (image == NULL) { printf("Impossible de charger %s: %s\n", file, SDL_GetError ()); return image; } dest.x = x; dest.y = y; dest.w = image->w; dest.h = image->h; SDL_SetColorKey (image, SDL_SRCCOLORKEY, SDL_MapRGB (image->format, 255, 0, 0)); SDL_BlitSurface (image, NULL, screen, &dest); SDL_UpdateRects (screen, 1, &dest); return image; } unsigned short CreateSprite (char *file, struct sprite *sprite_t, void *(*func)(void *arg), SDL_Surface *ptr_surface) { int i,a; int anim = 0; int y_tmp; SDL_Rect TmpRect; SDL_Surface *surface; FILE *sfile; // char buffer[MAX_BUF]; char byte; char file_buffer[MAX_BUF]; char nb_buffer[MIN_BUF]; sfile = fopen(file, "r"); while (feof (sfile) == 0 && anim < MAX_ANIM) { memset(file_buffer, 0, MAX_BUF); for(i = 0, a = 0; i < MAX_BUF; i++, a++) { fread(&byte, 1, 1, sfile); if(byte == ',' || byte == ';') { i++; break; } else file_buffer[a] = byte; } if(strcmp(file_buffer, "END_ANIM") == 0) break; surface = SDL_LoadBMP (file_buffer); if (surface == NULL) { printf ("Impossible de charger %s: %s\n", file_buffer, SDL_GetError ()); return 1; } memset(nb_buffer, 0, MAX_BUF); for(a = 0; i < MAX_BUF; i++, a++) { fread(&byte, 1, 1, sfile); if(byte == ',') { i++; break; } else nb_buffer[a] = byte; } sprite_t->nb[anim] = strtoul(nb_buffer, '\0', 10); printf("nb[%d] = %d\n", anim, sprite_t->nb[anim]); memset(nb_buffer, 0, MAX_BUF); for(a = 0; i < MAX_BUF; i++, a++) { fread(&byte, 1, 1, sfile); if(byte == ',') { i++; break; } else nb_buffer[a] = byte; } sprite_t->sprite_rect[anim].w = strtoul(nb_buffer, '\0', 10); sprite_t->w[anim] = strtoul(nb_buffer, '\0', 10); printf("w[%d] = %d\n", anim, sprite_t->w[anim]); memset(nb_buffer, 0, MAX_BUF); for(a = 0; i < MAX_BUF; i++, a++) { fread(&byte, 1, 1, sfile); if(byte == ';') { while(byte == ';' && byte != '\r' && byte != '\n') fread(&byte, 1, 1, sfile); break; } else nb_buffer[a] = byte; } sprite_t->sprite_rect[anim].h = strtoul(nb_buffer, '\0', 10); sprite_t->h[anim] = strtoul(nb_buffer, '\0', 10); printf("h[%d] = %d\n", anim, sprite_t->h[anim]); printf("Chargement du sprite %s\n",file_buffer); sprite_t->sprite_surface[anim] = ptr_surface; sprite_t->sprite_rect[anim].x = 0; sprite_t->sprite_rect[anim].y = 0; sprite_t->h[anim] = strtoul(nb_buffer, '\0', 10); sprite_t->surf_active[anim] = 0; //allocation dynamique des sprites for(i = 0;i < sprite_t->nb[anim]; i++) { sprite_t->sprite_surf[anim][i] = SDL_AllocSurface(SDL_HWSURFACE, sprite_t->sprite_rect[anim].h, sprite_t->sprite_rect[anim].w,24,0xFF0000,0xFF00,0xFF,0); SDL_SetColorKey (sprite_t->sprite_surf[anim][i], SDL_SRCCOLORKEY, SDL_MapRGB (sprite_t->sprite_surf[anim][i]->format, 255, 0, 0)); } //if(sprite_t->sprite_surf == NULL) exit(1); //on va decomposer chaque image y_tmp = 0; TmpRect.h = sprite_t->sprite_rect[anim].h; TmpRect.w = sprite_t->sprite_rect[anim].w; TmpRect.x = 0; for(i = 0;i < sprite_t->nb[anim]; i++) { TmpRect.y = y_tmp; if(SDL_BlitSurface(surface, &TmpRect, sprite_t->sprite_surf[anim][i], NULL) != 0) printf("SDL_BlitSurface : Failed\n"); printf("Chargement de sprite_t->sprite_surf[%d]\n",i); printf("\tTmpRect.y = %d\n",TmpRect.y); y_tmp = (y_tmp + sprite_t->sprite_rect[anim].h); } anim++; } sprite_t->anim_active = 0; sprite_t->nb_anim = anim; sprite_t->func = func; if(func != NULL) { if(pthread_create(&sprite_t->tsprite, NULL, func, sprite_t) == 0) { printf("Thread lance !\n"); } else printf("Erreur : pthread_create\n"); } return 0; } unsigned short DestroySprite (struct sprite *sprite_t) { int i; int a; sprite_t->exe = 0; SDL_FreeSurface (sprite_t->sprite_surface[sprite_t->anim_active]); for(a = 0; a < sprite_t->nb_anim; a++) { for(i = 0;i < sprite_t->nb[a];i++) SDL_FreeSurface (sprite_t->sprite_surf[a][i]); } sprite_t = NULL; printf ("Sprite detruit avec succes !\n"); return 0; } /*void InfoSprite (struct sprite *sprite_t) { printf ("Dimension :\n\tLargeur : %d\n\tHauteur : %d\n", sprite_t->sprite_rect.w, sprite_t->sprite_rect.h); printf ("Coordonnes :\n\tX : %d\n\tY : %d\n", sprite_t->sprite_rect.x, sprite_t->sprite_rect.y); } */ int ModifSprite (struct sprite *sprite_t, int x, int y, int num_active) { if((x <= (display_.zone.x)) || (y <= (display_.zone.y))) { return 1; } if((x >= (display_.zone.w - sprite_t->sprite_rect[sprite_t->anim_active].w)) || (y >= (display_.zone.h - sprite_t->sprite_rect[sprite_t->anim_active].h))) { return 1; } else { sprite_t->sprite_rect[sprite_t->anim_active].x = x; sprite_t->sprite_rect[sprite_t->anim_active].y = y; if(num_active != -1) sprite_t->surf_active[sprite_t->anim_active] = num_active; SDL_SetColorKey (sprite_t->sprite_surf[sprite_t->anim_active][sprite_t->surf_active[sprite_t->anim_active]], SDL_SRCCOLORKEY, SDL_MapRGB (sprite_t->sprite_surf[sprite_t->anim_active][sprite_t->surf_active[sprite_t->anim_active]]->format, 255, 0, 0)); SDL_BlitSurface(sprite_t->sprite_surf[sprite_t->anim_active][sprite_t->surf_active[sprite_t->anim_active]], NULL,display_.screen,&sprite_t->sprite_rect[sprite_t->anim_active]); SDL_UpdateRect(display_.screen, sprite_t->sprite_rect[sprite_t->anim_active].x, sprite_t->sprite_rect[sprite_t->anim_active].y, sprite_t->sprite_rect[sprite_t->anim_active].w, sprite_t->sprite_rect[sprite_t->anim_active].h); return 0; } } void ChangeAnim(struct sprite *sprite_t, int anim, int num_active) { SDL_SetColorKey (sprite_t->sprite_surf[anim][num_active], SDL_SRCCOLORKEY, SDL_MapRGB (sprite_t->sprite_surf[anim][num_active]->format, 255, 0, 0)); sprite_t->sprite_rect[num_active].x = sprite_t->sprite_rect[sprite_t->anim_active].x; sprite_t->sprite_rect[num_active].y = sprite_t->sprite_rect[sprite_t->anim_active].y; SDL_BlitSurface(sprite_t->sprite_surf[anim][num_active], NULL, display_.screen, &sprite_t->sprite_rect[num_active]); SDL_UpdateRect(display_.screen, sprite_t->sprite_rect[num_active].x, sprite_t->sprite_rect[num_active].y, sprite_t->sprite_rect[num_active].w, sprite_t->sprite_rect[num_active].h); sprite_t->anim_active = anim; sprite_t->surf_active[anim] = num_active; } void SetPixel(struct window *window_t, int x, int y, Uint32 depth) { *((Uint32*)(window_t->screen->pixels) + x + y * window_t->screen->w) = depth; } void AddSpriteDisplay(struct sprite *sprite_t) { int i; i = display_.nb_sprites + 1; if(display_.nb_sprites >= MAX_SPRITE) { printf("Trop de sprite chargé !\n"); } else { display_.sprite_all[i] = sprite_t; sprite_t->numero = i; printf("Sprite numero %d\n", i); display_.nb_sprites ++ ; } } void DelSpriteDisplay(struct sprite *sprite_t) { int i; for(i = sprite_t->numero; i < display_.nb_sprites; i++) { display_.sprite_all[i] = display_.sprite_all[(i+1)]; display_.sprite_all[(i+1)]->numero--; printf("Decalage des sprites %d a %d\n",i,(i+1)); } if(display_.nb_sprites != 0) display_.nb_sprites--; } void RunSpriteDisplay(struct window *window_t, struct level *lvl) { display_.screen = window_t->screen; display_.lvl = lvl; display_.zone.x = 0; display_.zone.y = 0; display_.zone.w = window_t->taille_x; display_.zone.h = window_t->taille_y; display_.mutex = SDL_CreateMutex(); pthread_create(&display_.tdisplay, NULL, RunSpriteDisplay_t, NULL); } void * RunSpriteDisplay_t(void * arg) { int i; display_.exe = 1; Uint32 timer1, timer2; int frames_per_second = 0; printf("Routine de redessin des sprites...\n"); time_init(); timer1 = SDL_GetTicks(); UpdateLevel(display_.lvl, &display_.zone); while(display_.exe == 1) { time_update(); for(i = 1; i <= display_.nb_sprites; i++) { //SDL_mutexP( if(display_.sprite_all[i]->nb[display_.sprite_all[i]->anim_active] > 1) { if((display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active] + 1) >= display_.sprite_all[i]->nb[display_.sprite_all[i]->anim_active]) display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active] = 0; else display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active]++; } UpdateLevel(display_.lvl, &display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active]); SDL_SetColorKey (display_.sprite_all[i]->sprite_surf[display_.sprite_all[i]->anim_active][display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active]], SDL_SRCCOLORKEY, SDL_MapRGB (display_.sprite_all[i]->sprite_surf[display_.sprite_all[i]->anim_active][display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active]]->format, 255, 0, 0)); SDL_BlitSurface (display_.sprite_all[i]->sprite_surf[display_.sprite_all[i]->anim_active][display_.sprite_all[i]->surf_active[display_.sprite_all[i]->anim_active]], NULL,display_.screen,&display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active]); SDL_UpdateRect(display_.screen,display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active].x, display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active].y, display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active].w, display_.sprite_all[i]->sprite_rect[display_.sprite_all[i]->anim_active].h); } frames_per_second++; timer2 = SDL_GetTicks(); if (timer2 - timer1 > 1000) { timer1 = timer2; frames_per_second = 0; } } printf("Arret du dessin des sprites\n"); pthread_exit(0); } void StopSpriteDisplay() { display_.exe = 0; SDL_DestroyMutex(display_.mutex); } void WaitSpriteDisplay() { pthread_join(display_.tdisplay, NULL); printf("End of loop Display\n"); } void CreateBullet(int type, int x, int y, float alpha, int direction, int distance, int dammage, int speed) { struct sprite sprite_t; CreateSprite("ressources/sprites/bullet.sprite", &sprite_t, bullet, display_.screen); ModifSprite(&sprite_t, x, y, 0); AddSpriteDisplay(&sprite_t); sprite_t.alpha = alpha; sprite_t.distance = distance; sprite_t.dammage = dammage; sprite_t.speed = speed; sprite_t.anim_active = 0; printf("End of bullet\n"); DelSpriteDisplay(&sprite_t); DestroySprite(&sprite_t); } void *bullet(void *arg) { struct sprite *sprite_t = arg; int i; printf("x = %d\n", sprite_t->sprite_rect->x); for(i = sprite_t->sprite_rect->x; i < 600; i++) { ModifSprite(sprite_t, i, sprite_t->sprite_rect->y, 0); SDL_Delay(200); printf("boucle\n"); } pthread_exit(0); }