Logo Search packages:      
Sourcecode: castle-combat version File versions

gfx.c

#include <string.h>
#include <main.h>
#include "IMG.h"

#define PATHNUM 5
#define BPP 0
#define RECTS_NUM 4000
char DATAPATH[200]=DATADIR;
const char PATH[PATHNUM][200]={DATADIR,".","data","../data",DATADIR};
SDL_Surface *Screen,*BackBuffer,*FadeBuffer,*TempBuffer;
SDL_Rect blitrect,blitrects[RECTS_NUM];
int blitrects_num=0;

void ComplainAndExit(void)
{
        fprintf(stderr, "Problem: %s\n", SDL_GetError());
        exit(1);
}

int abrand(int a,int b)  //random number between a and b (inclusive)
{
  return(a+(rand() % (b-a+1)));
}

int (*_PutPixel)(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color);

int fast_putpixel1(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
  if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h) 
    return -1;

  *((Uint8 *)Surface->pixels + Y * Surface->pitch + X) = Color;

  return 0;
}

int fast_putpixel2(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
  if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h) 
    return -1;

 *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X) = Color;

  return 0;
}

int fast_putpixel3(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
  Uint8 *pix;
  int shift;

  if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h) 
    return -1;

  /* Gack - slow, but endian correct */
  pix = (Uint8 *)Surface->pixels + Y * Surface->pitch + X*3;
  shift = Surface->format->Rshift;
  *(pix+shift/8) = Color>>shift;
  shift = Surface->format->Gshift;
  *(pix+shift/8) = Color>>shift;
  shift = Surface->format->Bshift;
  *(pix+shift/8) = Color>>shift;

  return 0;
}

int fast_putpixel4(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
  if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h) 
    return -1;

  *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X) = Color;

  return 0;
}

SDL_Surface *GetThis(SDL_Surface *Source, int x, int y, int w, int h)
{
    SDL_Rect rect;
    SDL_Surface *surf;

    surf = SDL_AllocSurface(Screen->flags,
                                  w,
                                  h,
                                  Screen->format->BitsPerPixel,
                                  Screen->format->Rmask,
                                  Screen->format->Gmask,
                                  Screen->format->Bmask, 0);
    
    rect.x = x;
    rect.y = y;
    rect.w = w;
    rect.h = h;
    
    SDL_BlitSurface( Source, &rect, surf, NULL);
    
    return surf;
}

void InitSDL( int ScreenX, int ScreenY)  // sets the video mode
{
  if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0 ) {ComplainAndExit();}
  atexit(SDL_Quit);
// Set the video mode (ScreenXxScreenY at 16-bit depth)  
  if (fullscreen)  
    Screen = SDL_SetVideoMode(ScreenX, ScreenY, BPP, SDL_FULLSCREEN | SDL_SWSURFACE);
  else 
    { Screen = SDL_SetVideoMode(ScreenX, ScreenY, BPP, SDL_SWSURFACE); }
  if ( Screen == NULL ) {ComplainAndExit();}
// create BackBuffer
  BackBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (BackBuffer == NULL)
  printf("ERROR: Couldn't create BackBuffer: %s\n", SDL_GetError());
  FadeBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (FadeBuffer == NULL)
  printf("ERROR: Couldn't create FadeBuffer: %s\n", SDL_GetError());
  TempBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (TempBuffer == NULL)
  printf("ERROR: Couldn't create TempBuffer: %s\n", SDL_GetError());
// Figure out what putpixel routine to use
   switch (Screen->format->BytesPerPixel)
   {
    case 1:
      _PutPixel = fast_putpixel1;
      break;
    case 2:
      _PutPixel = fast_putpixel2;
      break;
    case 3:
      _PutPixel = fast_putpixel3;
      break;
    case 4:
      _PutPixel = fast_putpixel4;
      break;
   }
}

void Resize( int ScreenX, int ScreenY)  // sets the video mode
{
    SDL_FreeSurface(Screen);
    SDL_FreeSurface(BackBuffer);
    SDL_FreeSurface(FadeBuffer);
    SDL_FreeSurface(TempBuffer);
    
// Set the video mode (ScreenXxScreenY at 16-bit depth)  
  if (fullscreen)  
    Screen = SDL_SetVideoMode(ScreenX, ScreenY, BPP, SDL_FULLSCREEN | SDL_SWSURFACE);
  else 
    { Screen = SDL_SetVideoMode(ScreenX, ScreenY, BPP, SDL_SWSURFACE); }
  if ( Screen == NULL ) {ComplainAndExit();}
// create BackBuffer
  BackBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (BackBuffer == NULL)
  printf("ERROR: Couldn't create BackBuffer: %s\n", SDL_GetError());
  FadeBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (FadeBuffer == NULL)
  printf("ERROR: Couldn't create FadeBuffer: %s\n", SDL_GetError());
  TempBuffer = SDL_AllocSurface(Screen->flags,
                               ScreenX,
                               ScreenY,
                               Screen->format->BitsPerPixel,
                               Screen->format->Rmask,
                               Screen->format->Gmask,
                               Screen->format->Bmask, 0);
  if (TempBuffer == NULL)
  printf("ERROR: Couldn't create TempBuffer: %s\n", SDL_GetError());
}

void lock()
{
        if ( SDL_MUSTLOCK(Screen) ) {
                if ( SDL_LockSurface(Screen) < 0 )
            return;        }                                                                       
}

void unlock()
{
        if ( SDL_MUSTLOCK(Screen) ) {                                           
                      SDL_UnlockSurface(Screen); }                                                                       
}

// Performs Callback at each line point. This came straight from the
// asphyxia vga trainers
int DoLine (SDL_Surface *Surface, Sint32 X1, Sint32 Y1, Sint32 X2, Sint32 Y2, Uint32 Color, int Callback (SDL_Surface *Surf, Sint32 X, Sint32 Y, Uint32 Color))
{ 
  Sint32 dx, dy, sdx, sdy, x, y, px, py; 
 
  dx = X2 - X1; 
  dy = Y2 - Y1; 
 
  sdx = (dx < 0) ? -1 : 1; 
  sdy = (dy < 0) ? -1 : 1; 
 
  dx = sdx * dx + 1; 
  dy = sdy * dy + 1; 
 
  x = y = 0; 
 
  px = X1; 
  py = Y1; 
 
  if (dx >= dy) 
    { 
      for (x = 0; x < dx; x++) 
      { 
          Callback(Surface, px, py, Color);
       
        y += dy; 
        if (y >= dx) 
          { 
            y -= dx; 
            py += sdy; 
          } 
        px += sdx; 
      } 
    } 
  else 
    { 
      for (y = 0; y < dy; y++) 
      { 
 
          Callback(Surface, px, py, Color);
 
        x += dx; 
        if (x >= dy) 
          { 
            x -= dy; 
            px += sdx; 
          } 
        py += sdy; 
      } 
    } 
   return 0;
}

// The user's line drawing function
void Line(Sint32 X1, Sint32 Y1, Sint32 X2, Sint32 Y2, Uint32 Color)
{
   lock(Screen);

   /* Draw the line */
   DoLine(Screen, X1, Y1, X2, Y2, Color, &PutPixel);
   unlock(Screen);
}

void Update()
{
  SDL_UpdateRects(Screen,blitrects_num,blitrects);
  blitrects_num=0;
}

void AddRect(int x1, int y1, int x2, int y2)
{
  int temp;
   /* Make sure X1 is before X2 */
   if (x2 < x1){
      temp = x2;
      x2 = x1;
      x1 = temp;
   }
   /* Make sure Y1 is before Y2 */
   if (y2 < y1){
      temp = y2;
      y2 = y1;
      y1 = temp;
   }
  blitrect.x = x1;
  blitrect.y = y1;
  blitrect.w = x2-x1+1;
  blitrect.h = y2-y1+1;
  if (x1<0) printf("x is too small in function AddRect!\n");else
  if (y1<0) printf("y is too small in function AddRect!\n");else
  if (x2>=Screen->w) printf("x is too big in function AddRect!\n");else
  if (y2>=Screen->h) printf("y is too big in function AddRect!\n");else {
      blitrects[blitrects_num]=blitrect;
      if (++blitrects_num>=RECTS_NUM-1)
      {printf("Too many blits!\n");blitrects_num--;Update();}
  }
}

void AddThisRect(SDL_Rect blitrect)
{
  if (blitrect.x<0) printf("x is too small in function AddRect!\n");else
  if (blitrect.y<0) printf("y is too small in function AddRect!\n");else
  if (blitrect.x+blitrect.w>Screen->w) printf("x is too big in function AddRect!\n");else
  if (blitrect.y+blitrect.h>Screen->h) printf("y is too big in function AddRect!\n");else {
    blitrects[blitrects_num]=blitrect;
    if (++blitrects_num>=RECTS_NUM-1)
        {printf("Too many blits!\n");blitrects_num--;Update();}
  }
}

void Blit(int Xpos,int Ypos,SDL_Surface *image)
{
  blitrect.x = Xpos;
  blitrect.y = Ypos;
  blitrect.w = image->w;
  blitrect.h = image->h;

  if (Xpos<-image->w) printf("WRONG BLIT: Xpos is too small! - %d\n",Xpos); else
  if (Xpos>=Screen->w) printf("WRONG BLIT: Xpos is too big! - %d\n",Xpos); else
  if (Ypos<-image->h) printf("WRONG BLIT: Ypos is too small!\n - %d",Ypos); else
  if (Ypos>=Screen->h) printf("WRONG BLIT: Ypos is too big! - %d\n",Ypos); else {
      if ( SDL_BlitSurface(image, NULL, Screen, &blitrect) < 0 ) 
      {
        SDL_FreeSurface(image);
        ComplainAndExit();
      }
      blitrects[blitrects_num]=blitrect;
      blitrects_num++;
  }
}

void BlitTo ( SDL_Surface *Dest, int Xpos,int Ypos,SDL_Surface *image)
{
  blitrect.x = Xpos;
  blitrect.y = Ypos;
  blitrect.w = image->w;
  blitrect.h = image->h;

  if (Xpos<-image->w) printf("WRONG BLIT: Xpos is too small! - %d\n",Xpos); else
  if (Xpos>=Screen->w) printf("WRONG BLIT: Xpos is too big! - %d\n",Xpos); else
  if (Ypos<-image->h) printf("WRONG BLIT: Ypos is too small!\n - %d",Ypos); else
  if (Ypos>=Screen->h) printf("WRONG BLIT: Ypos is too big! - %d\n",Ypos); else {
  if ( SDL_BlitSurface(image, NULL, Dest, &blitrect) < 0 ) 
  {
    SDL_FreeSurface(image);
    ComplainAndExit();
  }
  blitrects[blitrects_num]=blitrect;
  blitrects_num++;
  }
}

SDL_Surface *LoadImage(char *datafile, int transparent)   // reads one png into the memory
{
  SDL_Surface *pic,*pic2;
  char filename[200];
  int i=0;

  sprintf(filename,"%s/gfx/%s",DATAPATH,datafile);
  pic=IMG_Load(filename);
  while ( pic == NULL ) {
    strcpy(DATAPATH,PATH[i]);
    sprintf(filename,"%s/gfx/%s",DATAPATH,datafile);
    pic=IMG_Load(filename);
    i++;
    
    if (i>=PATHNUM)
    {
      fprintf(stderr,"Couldn't load %s: %s\n", filename, SDL_GetError());
      exit(2);
    }
  }
  if (transparent==3) {
      pic2 = SDL_DisplayFormatAlpha(pic);
      SDL_FreeSurface(pic);
  } else {
      pic2 = SDL_DisplayFormat(pic);
      SDL_FreeSurface(pic);
      if (transparent==1)
      SDL_SetColorKey(pic2,SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(pic2->format,0xFF,0xFF,0xFF));
      if (transparent==2)
      SDL_SetColorKey(pic2,SDL_SRCCOLORKEY|SDL_RLEACCEL,0);
  }
//  blit(0,0,pic2);
//  SDL_UpdateRect(screen,0,0,0,0);
  return (pic2);
}

void BlitToBB(int Xpos,int Ypos,SDL_Surface *image)  //blits one GIF or BMP from the memory to the screen
{
  blitrect.x = Xpos;
  blitrect.y = Ypos;
  blitrect.w = image->w;
  blitrect.h = image->h;
  if ( SDL_BlitSurface(image, NULL, BackBuffer, &blitrect) < 0 )
  {
    SDL_FreeSurface(image);
    ComplainAndExit();
  }
}

void BlitPart(int Xpos,int Ypos,SDL_Surface *image, SDL_Rect srcrect)
{
  blitrect.x = srcrect.x;                                                                 
  blitrect.y = srcrect.y;                                                                 
  blitrect.w = srcrect.w;                                                                 
  blitrect.h = srcrect.h;
  if ( SDL_BlitSurface(image, &srcrect , Screen, &blitrect) < 0 )
  {
    SDL_FreeSurface(image);
    ComplainAndExit();
  }
  blitrects[blitrects_num]=blitrect;
  blitrects_num++;
}

void FadeScreen(float speed)
{
  Sint32 now,i;

  SDL_BlitSurface(Screen,NULL,FadeBuffer,NULL);
  now=SDL_GetTicks();
  for (i=255*speed;i>=0;i-=SDL_GetTicks()-now)
  {
    now=SDL_GetTicks();
    SDL_BlitSurface(FadeBuffer,&blitrect,Screen,&blitrect);
    SDL_SetAlpha(BackBuffer,SDL_SRCALPHA,255-(int)(i/speed));
    Blit(0,0,BackBuffer);
    SDL_UpdateRects(Screen,1,&blitrect);
  }
}

int PutPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
    if (X<0) printf("X < 0 in function PutPixel! - %d\n",X); else
    if (X>=Surface->w) printf("X >= Surface->w in function PutPixel! - %d\n",X); else
    if (Y<0) printf("Y < 0 in function PutPixel! - %d\n",Y); else
    if (Y>=Surface->h) printf("Y >= Surface->h in function PutPixel! - %d\n",Y); else
    {
        _PutPixel(Surface,X,Y,Color);
        //AddRect(X,Y,X,Y);
    }
    return 0;
}

int PutBackPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
{
    SDL_Rect rect;
    
    rect.w=1;
    rect.h=1;
    rect.x=X;
    rect.y=Y;
    SDL_BlitSurface(BackBuffer, &rect, Surface, &rect);
    AddRect(rect.x,rect.y,rect.x,rect.y);

    return 0;    
}

void UndrawLine(Sint32 X1, Sint32 Y1, Sint32 X2, Sint32 Y2, Uint32 Color)
{
   /* Draw the line */
   DoLine(Screen, X1, Y1, X2, Y2, Color, &PutBackPixel);
}

Generated by  Doxygen 1.6.0   Back to index