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

game.c

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

int EndGame=0,PlayerNum=2,CastleNum,LocalPlayerNum=1,Width,Height,Phase=0,Conquer=0;
Uint32 Now,TimeStart,FrameCount=0;
double Speed,FramesPerSecond;
Sint8 text[200],Wall[WIDTH][HEIGHT],Landscape[WIDTH][HEIGHT],House[WIDTH][HEIGHT],Garbage[WIDTH][HEIGHT],CursorBlock[PLAYERNUM][3][3];
CastleType Castle[MAX_CASTLENUM];
signed char SelectFinished[PLAYERNUM],Selected[PLAYERNUM];
SDL_Surface *MessageBack = NULL;

int NormalEvents(const SDL_Event *event)
{
    switch (event->type) {
      case SDL_QUIT:
          puts("quitting...");
          exit(0);
      break;
      case SDL_KEYDOWN:
          if ( event->key.keysym.sym == SDLK_ESCAPE )
            Quit=1;
          if ( (event->key.keysym.sym == SDLK_RETURN) && (event->key.keysym.mod & KMOD_ALT) )
            SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
      break;
    }

    return 1;
}

void ShowText(char *text)
{
    SDL_Rect rect;
    float yspeed,speed,y=-Font->h;
    long now=SDL_GetTicks();
    int time=2000;

    void Sub(){
      speed=SDL_GetTicks()-now;
      now=SDL_GetTicks();
      y+=(yspeed*speed*(Screen->h+Font->h))/(time*time);
      rect.x=(Screen->w-TextWidth(text))/2;
      rect.y=y;
      rect.w=TextWidth(text)+5;
      rect.h=Font->h;
      if (y<0) {
          rect.h-=y;
          rect.y=0;
      }
      PutString(Screen,rect.x,y,text);
      AddThisRect(rect);
      Update();
      SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
      AddThisRect(rect);
    }    

    SDL_BlitSurface(Screen, NULL, TempBuffer, NULL);
    for (yspeed=time;yspeed>-time;yspeed-=speed) {
      Sub();
    }
}

void Putpix(SDL_Surface *surf, Sint32 X, Sint32 Y, Uint32 pixel)
{
    Uint8   *bits, bpp;

    /* Calculate the framebuffer offset of the center of the surf */
    if ( SDL_MUSTLOCK(surf) ) {
        if ( SDL_LockSurface(surf) < 0 )
            return;
    }
    bpp = surf->format->BytesPerPixel;
    bits = ((Uint8 *)surf->pixels)+Y*surf->pitch+X*bpp;

    /* Set the pixel */
    switch(bpp) {
        case 1:
            *((Uint8 *)(bits)) = (Uint8)pixel;
            break;
        case 2:
            *((Uint16 *)(bits)) = (Uint16)pixel;
            break;
        case 3: { /* Format/endian independent */
            Uint8 r, g, b;

            r = (pixel>>surf->format->Rshift)&0xFF;
            g = (pixel>>surf->format->Gshift)&0xFF;
            b = (pixel>>surf->format->Bshift)&0xFF;
            *((bits)+surf->format->Rshift/8) = r; 
            *((bits)+surf->format->Gshift/8) = g;
            *((bits)+surf->format->Bshift/8) = b;
            }
            break;
        case 4:
            *((Uint32 *)(bits)) = (Uint32)pixel;
            break;
    }

    /* Update the display */
    if ( SDL_MUSTLOCK(surf) ) {
        SDL_UnlockSurface(surf);
    }
    SDL_UpdateRect(surf, X, Y, 1, 1);

    return;


}

void ChangeColorAlpha( SDL_Surface *surf, Uint32 Color)
{
    Uint8 red,green,blue,alpha,r,g,b;
    Uint32 x,y,pixel;
    float value;

    lock(surf);
    for ( x=0; x<surf->w ; x++) {
      for ( y=0; y<surf->h ; y++) {
          pixel=GetPixel( surf, x, y);
          SDL_GetRGBA( pixel, surf->format, &red, &green, &blue, &alpha);
          SDL_GetRGB( Color, Screen->format, &r, &g, &b);
          value=(float)( red+green+blue )/(255*3);
          pixel=SDL_MapRGBA( surf->format, r*value, g*value, b*value, alpha);
          Putpix( surf, x, y, pixel);
      }
    }
    unlock(surf);
}

void ChangeColor( SDL_Surface *surf, Uint32 Color)
{
    Uint8 red,green,blue,r,g,b;
    Uint32 x,y,pixel;
    float value;

    lock(surf);
    for ( x=0; x<surf->w ; x++) {
      for ( y=0; y<surf->h ; y++) {
          pixel=GetPixel( surf, x, y);
          SDL_GetRGB( pixel, surf->format, &red, &green, &blue);
          SDL_GetRGB( Color, Screen->format, &r, &g, &b);
          value=(float)( red+green+blue )/(255*3);
          pixel=SDL_MapRGB( surf->format, r*value, g*value, b*value);
          Putpix( surf, x, y, pixel);
      }
    }
    unlock(surf);
}

void DrawSelect(int i)
{
    CastleType *This;
    
    This=&Castle[(int)Selected[i]];
    Blit( This->x*BSIZE-4*BSIZE, This->y*BSIZE-4*BSIZE, BPlayer[i].Select);
    if (This->Type==1)
        Blit( This->x*BSIZE, This->y*BSIZE, CastlePic );
    else 
        Blit( This->x*BSIZE, This->y*BSIZE, BigCastlePic);
}

void UndrawSelect(int i)
{
    CastleType *This;
    SDL_Rect rect;
    
    rect.w=rect.h=10*BSIZE;
    This=&Castle[(int)Selected[i]];
    rect.x=(This->x-4)*BSIZE;
    rect.y=(This->y-4)*BSIZE;
//    SDL_BlitSurface(BackBuffer, NULL, Screen, NULL);
    SDL_BlitSurface(BackBuffer, &rect, Screen, &rect);
    AddThisRect(rect);
}

void BuildWallAroundCastle( int i )
{
    int x,y;

    for ( x=Castle[i].x-3; x<=Castle[i].x+4; x++) {
      for ( y=Castle[i].y-3; y<=Castle[i].y+4; y++) {
          if ( ( x==Castle[i].x-3 ) || ( x==Castle[i].x+4 )
             ||( y==Castle[i].y-3 ) || ( y==Castle[i].y+4 ) )
             {
                 DrawSingleBlock( Screen, x, y, Castle[i].Owner, 0);
                 DrawSingleBlock( BackBuffer, x, y, Castle[i].Owner, 0);
               Wall[x][y] = Castle[i].Owner+1;
               Landscape[x][y] = Castle[i].Owner;
             }
      }
    }
    Castle[i].Type=2;
    BlitToBB(Castle[i].x*BSIZE, Castle[i].y*BSIZE, BigCastlePic);
//    UndrawSelect();
//    DrawSelect();    
}

int AnotherPlayerHasThisCastle(int i)
{
    int count=0,player;
    
    for (player=0; player<PlayerNum; player++) {
      if (Selected[player] == i) {
          count++;
      }
    }
    
    if (count>1)
      return 1;
    else
      return 0;
}

void SelectNextCastle(int i) {
    CastleType *This;

    do {
        Selected[i]++;
        if (Selected[i]>=CastleNum)
          Selected[i]=0;
        This=&Castle[(int)Selected[i]];
    } while ( ((This->Owner!=i) && (!Conquer)) || (AnotherPlayerHasThisCastle(Selected[i])) );
}

void SelectPrevCastle(int i) {
    CastleType *This;

    do {
        Selected[i]--;
        if (Selected[i]<0)
          Selected[i]=CastleNum-1;
      This=&Castle[(int)Selected[i]];
    } while ( ((This->Owner!=i) && (!Conquer)) || (AnotherPlayerHasThisCastle(Selected[i])) );
}


int SelectEvents(const SDL_Event *event)
{
    int i;
    char data[5];

    switch (event->type) {
      case SDL_MOUSEBUTTONDOWN:
//        SDL_GetMouseState(&MouseX, &MouseY);
      break;    
      case SDL_KEYDOWN:
          for (i=0;i<PlayerNum;i++) {
            if ( BPlayer[i].Local ) {
                if ( !SelectFinished[i]) {
                  if (
                      ( event->key.keysym.sym == BPlayer[i].Up ) ||
                      ( event->key.keysym.sym == BPlayer[i].Right )                     
                     ) {
                        UndrawSelect(i);
                        SelectNextCastle(i);
                        DrawSelect(i);
                        data[0] = 3;
                        data[1] = NET_OTHER_SELECTION;
                        data[2] = (char)i;
                        data[3] = Selected[i];
                        Net_Send(data);
                      }
                  if (
                      ( event->key.keysym.sym == BPlayer[i].Down ) ||
                      ( event->key.keysym.sym == BPlayer[i].Left )
                     ) {
                        UndrawSelect(i);
                        SelectPrevCastle(i);
                        DrawSelect(i);
                        data[0] = 3;
                        data[1] = NET_OTHER_SELECTION;
                        data[2] = (char)i;
                        data[3] = Selected[i];
                        Net_Send(data);
                      }

                  if ( event->key.keysym.sym == BPlayer[i].Button1 ) {
                      UndrawSelect(i);
                      SelectFinished[i] = 1;
                      Castle[(int)Selected[i]].Owner = i;
                      BuildWallAroundCastle(Selected[i]);
                      DrawSelect(i);
                  
                      data[0] = 3;
                      data[1] = NET_SELECTION_FINISHED;
                      data[2] = (char)i;
                      data[3] = Selected[i];
                      Net_Send(data);
                  }
                }
            }
          }
          Update();

      break;
    }
    
    return NormalEvents(event);
}

void SelectCastle()
{
    int i,finished=0;
    CastleType *This;
    
    InitBuild();
    Net_WaitForStart();
    UndrawBlock();
    for (i=0;i<PlayerNum;i++) {
      SelectFinished[i]=0;
      Selected[i]=0;
      This=&Castle[(int)Selected[i]];
      while (This->Owner!=i)
          This=&Castle[++(int)Selected[i]];
      DrawSelect(i);
    }
    Update();
    SDL_SetEventFilter(&SelectEvents);
    SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
    while ( (!finished) && (!Quit) ) {
      finished=1;
      for (i=0;i<PlayerNum;i++)
          if (!SelectFinished[i]) finished=0;
        SDL_Delay(20);
        SDL_PollEvent(&event);
      Network();
    }
    Update();
    Net_WaitForStart();
}

void SetPlayer(BuildPlayer *dest, BuildPlayer *source)
{
    strcpy(dest->Name, source->Name);
    dest->Up = source->Up;
    dest->Down = source->Down;
    dest->Left = source->Left;
    dest->Right = source->Right;
    dest->Button1 = source->Button1;
    dest->Button2 = source->Button2;
}

void InitGame()
{
    int i;
    char data[200];

    EndGame = 0;
    RoundNum = 0;
    BPlayer[0].Color=SDL_MapRGB(Screen->format,255,0,0);
    BPlayer[1].Color=SDL_MapRGB(Screen->format,0,0,255);
    BPlayer[2].Color=SDL_MapRGB(Screen->format,0,255,0);
    BPlayer[3].Color=SDL_MapRGB(Screen->format,255,0,255);
    for (i=0;i<PLAYERNUM;i++) {
      BPlayer[i].Lost = 1;
    }
    for (i=0;i<PlayerNum;i++) {
        BPlayer[i].Local = 0;
      BPlayer[i].Lost = 0;
      BPlayer[i].Lives = 0;
    }
    if (Connected) {
      int swapped = 0;
      
      for (i=0;i<LocalPlayerNum;i++) {
          data[0] = 2+strlen(BPlayer[i].Name);
          data[1] = NET_NEWPLAYER;
          strcpy(&data[2], BPlayer[i].Name);
          Net_Send(data);
          printf("Getting # for the %d. Player.\n",i+1);
          Net_Get();

          if (GetData[0]!=NET_NEWPLAYER) {
            printf("Getting Player # failed\n");
            exit(1);
          }
          
          printf("\nUsing PlayerNum %d.\n", GetData[1]);
          BPlayer[(int)GetData[1]].Local = 1;
          if ( (LocalPlayerNum == 1) || (GetData[1]>=2) ) {
            SetPlayer(&BPlayer[(int)GetData[1]],&BPlayer[i-swapped]);
            printf("P %d to P %d\n", (int)GetData[1], i-swapped);
          } else {
            if (GetData[1] == i) {
                // do nothing
                printf("P %d stays P %d\n", i, i);
            } else {
                BuildPlayer dummy;
                SetPlayer(&dummy, &BPlayer[0]);
                SetPlayer(&BPlayer[0], &BPlayer[1]);
                SetPlayer(&BPlayer[1], &dummy);
                swapped = 1;
                printf("P1 and P0 swapped\n");
            }
          }
      }
    } else {
      LocalPlayerNum=PLAYERNUM;
      for (i=0;i<LocalPlayerNum;i++) {
          BPlayer[i].Local=1;
      }
    }
    printf("Got all players.\n");
    TankNum=0;
    for (i=0;i<PlayerNum;i++) {
      // Set all values to default
      BPlayer[i].Lost = 0;
      BaPlayer[i].CannonNum = 0;
      SelectFinished[i] = 0;
      Selected[i] = 0;
      // Draw Player's ground
      BPlayer[i].Ground = SDL_DisplayFormatAlpha(GroundPic);
      ChangeColorAlpha( BPlayer[i].Ground, BPlayer[i].Color);
      // Draw Player's Cursor
      BPlayer[i].CursorBlock = SDL_DisplayFormatAlpha(SelectPic);
      ChangeColorAlpha( BPlayer[i].CursorBlock, BPlayer[i].Color);
      // Draw Player's cross hair
      BaPlayer[i].Crosshair = SDL_DisplayFormatAlpha(CrosshairPic);
      ChangeColorAlpha( BaPlayer[i].Crosshair, BPlayer[i].Color);
      // Draw Player's "empty" cross hair
      BaPlayer[i].NotReady = SDL_DisplayFormatAlpha(NotReadyPic);
      ChangeColorAlpha( BaPlayer[i].NotReady, BPlayer[i].Color);
      // Draw Player's castle selection pic
      BPlayer[i].Select = SDL_DisplayFormatAlpha(CastleSelectPic);
      ChangeColorAlpha( BPlayer[i].Select, BPlayer[i].Color);
      // Draw Player's Wall
      BPlayer[i].Wall = SDL_DisplayFormat(WallPic);
      ChangeColor( BPlayer[i].Wall, BPlayer[i].Color);
    }
    Message("Waiting for other Players!");
    Net_WaitForStart();
}

void FreeGame()
{
    int i;

    for (i=0;i<PlayerNum;i++) {
      SDL_FreeSurface(BPlayer[i].CursorBlock);
      SDL_FreeSurface(BPlayer[i].Wall);
      SDL_FreeSurface(BaPlayer[i].Crosshair);
      SDL_FreeSurface(BaPlayer[i].NotReady);
    }
}

void Message(char *text)
{
//    SDL_BlitSurface(Back, NULL, Screen, NULL);
    if (MessageBack != NULL) {
      SDL_FreeSurface(MessageBack);
    }
    MessageBack = GetThis(Screen, 0, 200, Screen->w, Font->h);
    XCenteredString(Screen,200,text);
    SDL_UpdateRect(Screen,0,0,0,0);
    //SDL_Delay(1000);    
}

void RemoveMessage()
{
    SDL_Rect rect;
    
    rect.x = 0;
    rect.y = 200;
    rect.w = Screen->w;
    rect.h = Font->h;

    if (MessageBack != NULL) {
      SDL_BlitSurface( MessageBack, NULL, Screen, &rect);
      SDL_FreeSurface( MessageBack );
      MessageBack = NULL;
    } else {
      puts("ERROR in RemoveMessage!");
    }
}

void StartGame()
{
    if (Server) {
      strcpy(ServerName,"localhost");
      Message("Waiting for socket! (takes about 1 min)");
      printf("** Starting server **\n");
      if ( InitServer(NetworkOpen) ) {
          return;
      }
      Connect(ServerName);
      RemoveMessage();
      if (!Connected) {
          Message("Could not connect!");
          return;
      } else {
          NetworkOpen = 1;
      }
    }
    printf("** Connecting to server **\n");
    InitGame();
    GenerateLand();
    if ((Master)||(!Conquer)) {
      FinishLand();
    }
    AddHouses(40);
    SelectCastle();
    while ((!EndGame)&&(!Quit)) {
      RoundNum++;
      
      Net_Sync();
      Place();
      if (Quit) break;
      AddHouses(4);
      if (PlayerNum == 1)
          AddTanks(30 - RoundNum * 5);
      Net_Sync();
      Battle();
      if (Quit) break;
      Net_Sync();
      Build();
      if (Quit) break;
    }
    FreeGame();
}

Generated by  Doxygen 1.6.0   Back to index