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

main.c

/*  Castle Combat: build a castle and defeat your enemy!
    Copyright (C) 2003 Karl Bartel

    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 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   
                                                            
    Karl Bartel                                                         
    Cecilienstr. 14                                                    
    12307 Berlin                                                  
    GERMANY
    karlb@gmx.net                                                      
*/                                                                            
#include <string.h>
#include "main.h"
#include "options.h"
#include "time.h"
#include "SDL_net/SDL_net.h"
#include "server.h"

    int fullscreen=1, CityDestroyed[6]={0,0,0,0,0,0},
      CannonDestroyed[3]={0,0,0}, Score=0, HWCursor=0, NetworkOpen=0;
// images
    SDL_Surface *WaterPic,*LandPic,*Font,*CannonPic[30],*CrosshairPic,*ShotPic,*CastleSelectPic,*WallPic,*CastlePic,*NotReadyPic,*CannonDestroyedPic[5],*BigCannonPic[30],*BigCannonDestroyedPic[5],*GarbagePic,*HousePic,*TankPic[4],*BigCastlePic,*Back,*WaitBlockPic,*SelectPic,*CantBuildPic,*GradientPic,*RedFontSurface,*GroundPic;
    
// font stuff
    SFont_FontInfo RedFontData;
    SFont_FontInfo *RedFont = &RedFontData;
    
// event handling  
    SDL_Event event;
    
// other
    char text[200],ServerName[200];
    int Quit=0, Loaded=0, Server=0;
    Uint32 WaitStart=0;

void LoadImages()
{
    int i;

    Back = LoadImage("back.png",0);
    WaterPic = LoadImage("water.png",0);
    LandPic = LoadImage("land.png",0);
    CrosshairPic = LoadImage("crosshair.png",3);
    NotReadyPic = LoadImage("notready.png",3);
    ShotPic = LoadImage("shot.png",3);
    BigCastlePic = LoadImage("bigcastle.png",3);
    CastlePic = LoadImage("castle.png",3);
    WallPic = LoadImage("wall.png",3);
    SelectPic = LoadImage("select.png",3);
    GarbagePic = LoadImage("garbage.png",2);
    HousePic = LoadImage("house.png",3);
    GroundPic = LoadImage("ground.png",3);
    WaitBlockPic = LoadImage("waitblock.png",3);
    CastleSelectPic = LoadImage("castleselect.png",3);
    TankPic[0] = LoadImage("tank1.png",3);
    TankPic[1] = LoadImage("tank2.png",3);
    TankPic[2] = LoadImage("tank3.png",3);
    TankPic[3] = LoadImage("tank4.png",3);
    CantBuildPic = LoadImage("cantbuild.png",3);
    GradientPic = LoadImage("gradient.png",0);
      
    for (i=0;i<30;i++) { 
      sprintf(text,"cannon%04d.png",i+1);
      CannonPic[i] = LoadImage(text,3);
    }
    for (i=0;i<30;i++) { 
      sprintf(text,"bigcannon%04d.png",i+1);
      BigCannonPic[i] = LoadImage(text,3);
    }

    for (i=0;i<5;i++) { 
      sprintf(text,"destroyed-cannon%d.png",i+1);
      CannonDestroyedPic[i] = LoadImage(text,3);
    }
    for (i=0;i<5;i++) { 
      sprintf(text,"destroyed-bigcannon%d.png",i+1);
      BigCannonDestroyedPic[i] = LoadImage(text,3);
    }
}

int Button(int x, int y, char *String, int prev)
{
    SDL_Rect rect;
    int MouseX,MouseY;
    
    rect.x=x;
    rect.y=y;
    rect.w=TextWidth(String)+20;
    rect.h=Font->h;
    
    SDL_GetMouseState(&MouseX, &MouseY);
    if ((MouseX>x)&&(MouseY>y)
      &&(MouseX<x+TextWidth(String))
      &&(MouseY<y+Font->h))
    {
      if (prev!=1) {
          // clear
          SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
          // draw
          PutString2(Screen, RedFont, x, y, String);
          AddThisRect(rect);
          SDL_BlitSurface(Screen, &rect, BackBuffer, &rect);
          SDL_SetAlpha(TempBuffer,0,0);
      }
      return 1;
    } else if (prev!=0) {
      // clear
      SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
      // draw
        PutString(Screen, x, y, String);
      AddThisRect(rect);
    }
    
    return 0;
}
/*
void ShowCredits()
{
    float anim=0,MusicDown=10;
    SDL_Rect rect;

    Blit(0,0,BackPic);
    XCenteredString(Screen,10,"<Penguin Command Credits>");
    PutString(Screen,20,60,"Code: Karl Bartel <karlb@gmx.net>");
    PutString(Screen,20,100,"Graphics: Karl Bartel");
    PutString(Screen,20,130+MusicDown,"Music:");
    PutString(Screen,20,170+MusicDown,"Sami I Saarnio");
    PutString(Screen,100,200+MusicDown,"Vanished Dreams");
    PutString(Screen,100,230+MusicDown,"Choose don't loose");
    PutString(Screen,100,260+MusicDown,"No!Inhinbitions");
    PutString(Screen,20,290+MusicDown,"Seth Peelle");
    PutString(Screen,100,320+MusicDown,"Penguin Night");
    XCenteredString(Screen,550+MusicDown,"http://www.linuxstart.com/~karlb/");
    Update();
    SDL_BlitSurface(Screen,NULL,BackBuffer,NULL);
    Now=SDL_GetTicks();
    while (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {SDL_PollEvent(&event);}
    while ((event.type!=SDL_KEYDOWN)&&(event.type!=SDL_MOUSEBUTTONDOWN)) {
      SDL_PollEvent(&event);
      UndrawMouse();
      DrawMouse();
      Update();
    }
}
*/

void TextBlock(int x, int y, int w, char *text)
{
    char line[200] = "";
    int t = 0, l = 0;
    
    while (text[t] != '\0') {
      while ((TextWidth(line) < w) && (text[t] != '\0') && (text[t] != '\n')) {
          line[l++] = text[t++];
          line[l] = '\0';
      }
      if (text[t] == '\n') {
          line[l] = text[t];
      }
      if (text[t] == '\0') {
          line[l] = ' ';
      } else {
          t++;
      }
      while ((line[l] != ' ') && (line[l] != '\n') && (l != 0)) {
          l--;
          t--;
      }
      line[l+1] = '\0';
      PutString(Screen, x, y, line);
      y += Font->h;
      l = 0;
      line[0] = '\0';
    }
}

void Rules()
{
    int page = 0, exit = 0;
    int next, back, prev;

    while (!exit) {
      next = 3;
      prev = 3;
      back = 3;
      Blit(0,0,Back);
      switch (page) {
          case 1:
            XCenteredString(Screen,10,"< 1st Phase: Build >");
            TextBlock(10, 210, 790,
            "Try to build walls arounds as many castles as possible. "
            "If have not completely surrounded any castle, you lose."
            "\n1st button: Place the current block"
            "\n2nd button: Turn the block by 90 degree");
          break;
          case 2:
            XCenteredString(Screen,10,"< 2nd Phase: Place Cannons >");
            TextBlock(10, 210, 790,
            "Now you can place cannons equal to the number of castles you "
            "have surrounded. Your home castle earns you one extra cannon. "
            "Instead of placing three normal cannons you can place one big"
            "cannon that causes additional trouble for you enemys."
            "\n1st button: Place selected cannon"
            "\n2nd button: Change between small/big cannon");
          break;
          case 3:
            XCenteredString(Screen,10,"< 3rd Phase: Fight! >");
            TextBlock(10, 210, 790,
            "It's time to fight! Aim at your opponent's walls with your "
            "crosshair and shoot them down. You can also destroy enemy "
            "cannons, but they can take a lot of shots before they are "
            "destroyed. You can have only one shot per cannon at a time."
            "\n1st button: Shoot"
            "\n2nd button: Faster movement");
          break;
          default:
            page = 0;
          case 0:
            XCenteredString(Screen,10,"< Castle-Combat Rules >");
            TextBlock(10, 210, 790,
            "You have to build castle walls, which allows you to place "
            "cannons inside these walls. Your goal is to destroy the enemy's' "
            "castles by shooting down the castle walls with your cannons. "
            "The game is seperated into three phases. You can perform different. "
            "actions in each of the phases.");
          break;
      }
        while (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {SDL_PollEvent(&event);}
      while ((event.type!=SDL_KEYDOWN)&&(event.type!=SDL_MOUSEBUTTONDOWN)) {
          SDL_PollEvent(&event);
          if (page > 0)
            prev = Button(620, 550,"prev", prev);
          else
            prev = 0;
          if (page < 3)
            next = Button(710, 550,"next", next);
          else
            next = 0;
          back = Button(50, 550, "Back", back);
          Update();
          SDL_Delay(10);
      }
      if ( back ) {
          exit = 1;
      }
      if ( next ) {
          page++;
      }
      if ( prev ) {
          page--;
      }
    }
}

void wait_for_mouse()
{
    SDL_Event event;

    while (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {SDL_PollEvent(&event);}
}

int GetKey(char *text)
{
    SDL_Rect rect;
    
    rect.x=0;
    rect.y=450;
    rect.w=Screen->w;
    rect.h=Font->h;
    XCenteredString(Screen, 450, text);
    AddThisRect(rect);
    Update();
    
    while ((!SDL_PollEvent(&event))||(event.type!=SDL_KEYDOWN)) {};
    SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
    AddThisRect(rect);
    Update();
    return event.key.keysym.sym;
}

void KeyConf(int i)
{
    BPlayer[i].Left=GetKey("Left");
    BPlayer[i].Right=GetKey("Right");
    BPlayer[i].Up=GetKey("Up");
    BPlayer[i].Down=GetKey("Down");
    BPlayer[i].Button1=GetKey("1st Button");
    BPlayer[i].Button2=GetKey("2nd Button");
}

void Setup()
{
    int quit=3,exit=0,p1=3,p2=3,p1name=3,p2name=3;
    char text[100];
    int YOffset=90;
    SDL_Rect rect;

    ReadOptions();
    SDL_BlitSurface(TempBuffer, NULL, Screen, NULL);
    PutString(Screen,90,100+YOffset,"Player 1");
    PutString(Screen,490,100+YOffset,"Player 2");
    SDL_UpdateRect(Screen,0,0,0,0);
    while (!exit) {
      quit=Button(50,550,"Back",quit);
      p1=Button(50,190+YOffset,"Select Keys",p1);
      p2=Button(450,190+YOffset,"Select Keys",p2);
      sprintf(text,"Name: %s",BPlayer[0].Name);
      p1name=Button(50,150+YOffset,text,p1name);
      sprintf(text,"Name: %s",BPlayer[1].Name);
      p2name=Button(450,150+YOffset,text,p2name);
      SDL_PollEvent(&event);
      if (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {
          if (quit) exit = 1;
          if (p1) KeyConf(0);
          if (p2) KeyConf(1);
          if (p1name) {
            SDL_UpdateRect(Screen,0,0,0,0);         
            rect.x=50+TextWidth("Name:");
            rect.y=150+YOffset;
            rect.w=TextWidth(BPlayer[0].Name)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            Update();
            SFont_Input( Screen, 50+TextWidth("Name: "), 150+YOffset, 350-TextWidth("Name: "), BPlayer[0].Name);
            rect.x=50+TextWidth("Name:");
            rect.y=150+YOffset;
            rect.w=TextWidth(BPlayer[0].Name)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            sprintf(text,"Name: %s",BPlayer[0].Name);
            p1name=Button(50,150+YOffset,text,3);
            Update();
            wait_for_mouse();
          }
          if (p2name) {
            SDL_UpdateRect(Screen,0,0,0,0);
            rect.x=450+TextWidth("Name:");
            rect.y=150+YOffset;
            rect.w=TextWidth(BPlayer[1].Name)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            Update();
            SFont_Input( Screen, 450+TextWidth("Name: "), 150+YOffset, 350-TextWidth("Name: "), BPlayer[1].Name);
            rect.x=450+TextWidth("Name:");
            rect.y=150+YOffset;
            rect.w=TextWidth(BPlayer[1].Name)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            sprintf(text,"Name: %s",BPlayer[1].Name);
            p2name=Button(450,150+YOffset,text,3);
            Update();
            wait_for_mouse();
          }
      }
      Update();
      SDL_Delay(5);
    }
    WriteOptions();
}


int ServerMenu()
{
    int quit=3,start=3,delay=1,playernum=3,gamemode=3,localplayernum=3;
    char text[200];

    ReadOptions();
    while (!Quit) {
      if (delay) {
          SDL_BlitSurface(Back,NULL,TempBuffer,NULL);
          SDL_BlitSurface(TempBuffer, NULL, Screen, NULL);
          start=3;quit=3;delay=0;playernum=3;gamemode=3;localplayernum=3;
          SDL_UpdateRect(Screen,0,0,0,0);
      }
      quit=Button(50,550,"Cancel",quit);
      start=Button(150,240,"Create Multiplayer Game Now!",start);
      sprintf(text,"No. of Players: %d ", PlayerNum);
      playernum=Button(50,380,text,playernum);
      sprintf(text,"Local Players: %d", LocalPlayerNum);
      localplayernum=Button(50,420,text,localplayernum);
      if (Conquer) {
          sprintf(text,"Game Mode: Conquer");
      } else {
          sprintf(text,"Game Mode: River     ");
      }
      gamemode=Button(50,460,text,gamemode);
        SDL_UpdateRect(Screen,0,0,0,0);
        wait_for_mouse();
      SDL_PollEvent(&event);
      if (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {
          if (quit) {
            return 0;
          }
          if (start){
            break;
          }
          if (playernum) {
            PlayerNum++;
            if (PlayerNum>4)
                PlayerNum=2;
            sprintf(text,"No. of Players: %d", PlayerNum);
            playernum=Button(50,380,text,3);
            wait_for_mouse();
          }
          if (localplayernum) {
            LocalPlayerNum++;
            if (LocalPlayerNum>2)
                LocalPlayerNum=1;
            localplayernum=3;
            sprintf(text,"Local Players: %d", LocalPlayerNum);
            localplayernum=Button(50,420,text,localplayernum);
            wait_for_mouse();
          }
          if (gamemode) {
            Conquer = 1-Conquer;
            if (Conquer) {
                sprintf(text,"Game Mode: Conquer");
            } else {
                sprintf(text,"Game Mode: River     ");
            }
            gamemode=Button(50,460,text,3);
            wait_for_mouse();
          }
      }
      Update();
      SDL_Delay(5);
    }
    WriteOptions();
    return 1;
}

int JoinMenu()
{
    int quit=3,start=3,delay=1,server=3,localplayernum=3;
    char text[200];

    ReadOptions();
    while (!Quit) {
      if (delay) {
          SDL_BlitSurface(Back,NULL,TempBuffer,NULL);
          SDL_BlitSurface(TempBuffer, NULL, Screen, NULL);
          start=3;quit=3;delay=0;server=3;localplayernum=3;
          SDL_UpdateRect(Screen,0,0,0,0);
      }
      quit=Button(50,550,"Cancel",quit);
      start=Button(160,240,"Join Multiplayer Game Now!",start);
      sprintf(text,"Local Players: %d", LocalPlayerNum);
      localplayernum=Button(50,380,text,localplayernum);
      sprintf(text,"Server: %s", ServerName);
      server=Button(50,420,text,server);
        SDL_UpdateRect(Screen,0,0,0,0);
        wait_for_mouse();
      SDL_PollEvent(&event);
      if (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {
          if (quit) {
            return 0;
          }
          if (start){
            Connected=0;
            PlayerNum=2;
            Connect(ServerName);
            if (Connected) break;
          }
          if (localplayernum) {
            LocalPlayerNum++;
            if (LocalPlayerNum>2)
                LocalPlayerNum=1;
            localplayernum=3;
            sprintf(text,"Local Players: %d", LocalPlayerNum);
            localplayernum=Button(50,380,text,localplayernum);
            wait_for_mouse();
          }
          if (server) {
            SDL_Rect rect;
            
            rect.x=50+TextWidth("Server:");
            rect.y=420;
            rect.w=TextWidth(ServerName)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            Update();
            SFont_Input( Screen, 50+TextWidth("Server: "), 420, 740-TextWidth("Server: "), ServerName);
            rect.x=50+TextWidth("Server:");
            rect.y=420;
            rect.w=TextWidth(BPlayer[1].Name)+20;
            rect.h=Font->h;
            SDL_BlitSurface(TempBuffer, &rect, Screen, &rect);
            AddThisRect(rect);
            sprintf(text,"Server: %s",ServerName);
            server=Button(50,420,text,3);
            Update();
            wait_for_mouse();
          }
      }
      Update();
      SDL_Delay(5);
    }
    WriteOptions();
    return 1;
}

int LocalMenu()
{
    int quit=3,start=3,delay=1,gamemode=3;
    char text[200];

    ReadOptions();
    while (!Quit) {
      if (delay) {
          SDL_BlitSurface(Back,NULL,TempBuffer,NULL);
          SDL_BlitSurface(TempBuffer, NULL, Screen, NULL);
          start=3;quit=3;delay=0;gamemode=3;
          SDL_UpdateRect(Screen,0,0,0,0);
      }
      quit=Button(50,550,"Cancel",quit);
      start=Button(170,240,"Start Two Player Game Now!",start);
      if (Conquer) {
          sprintf(text,"Game Mode: Conquer");
      } else {
          sprintf(text,"Game Mode: River     ");
      }
      gamemode = Button(45,400,text,gamemode);
        SDL_UpdateRect(Screen,0,0,0,0);
        wait_for_mouse();
      SDL_PollEvent(&event);
      if (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {
          if (quit) {
            return 0;
          }
          if (start){
            Connected = 0;
            break;
          }
          if (gamemode) {
            Conquer = 1-Conquer;
            if (Conquer) {
                sprintf(text,"Game Mode: Conquer");
            } else {
                sprintf(text,"Game Mode: River     ");
            }
            gamemode=Button(45,400,text,3);
            wait_for_mouse();
          }
      }
      Update();
      SDL_Delay(5);
    }
    WriteOptions();
    return 1;
}


void ShowTitle()
{
    int quit=3,start=3,keys=3,delay=1,join=3,create=3,rules=3;

    while (!Quit) {
      if (delay) {
          SDL_BlitSurface(Back,NULL,TempBuffer,NULL);
          SDL_BlitSurface(TempBuffer, NULL, Screen, NULL);
          start=3;quit=3;keys=3;delay=0;create=3;join=3;rules=3;
          SDL_UpdateRect(Screen,0,0,0,0);
      }
      quit = Button(50,550,"Quit",quit);
      start = Button(50,380,"Start Local Game",start);
      join = Button(50,420,"Join Network Game",join);
      create = Button(50,460,"Create Network Game",create);
      rules = Button(750-TextWidth("Help"),510,"Help",rules);
      keys = Button(750-TextWidth("Setup"),550,"Setup",keys);
        SDL_UpdateRect(Screen,0,0,0,0);
        wait_for_mouse();
      SDL_PollEvent(&event);
      if (SDL_GetMouseState(NULL,NULL)==SDL_BUTTON(1)) {
          if (quit) Quit=1;
          if (start){
            Connected=0;
            if (LocalMenu()) {
                PlayerNum = 2;
                // Single Player: PlayerNum = 1;
                break;
            } else {
                delay=1;
            }
          }
          if (join) {
            if (JoinMenu()) {
                break;
            } else {
                delay=1;
            }
          }
          if (create) {
            Server=1;
            if (ServerMenu()) {
                break;
            } else {
                delay=1;
            }
          }
          if (keys) {Setup();delay=1;}
          if (rules) {Rules();delay=1;}
      }
      Update();
      SDL_Delay(5);
    }
}

void ReadCommandLine(char *argv[])
{
    int i;
    for ( i=1;argv[i];i++ ) {
      if ((strcmp(argv[i],"--windowed")==0)||(strcmp(argv[i],"-w")==0)) fullscreen=0;
      else if ((strcmp(argv[i],"--nosound")==0)||(strcmp(argv[i],"-s")==0)) sound=0;
      else printf("Unknown parameter: \"%s\" \n", argv[i]);
    }
}

int main(int argc, char *argv[])
{
// intialisation
    ReadCommandLine(argv);
    printf("** Setting Video Mode **\n");
    InitSDL( 800, 600 );
    SDL_WM_SetCaption("Castle Combat","Castle Combat");
    srand((unsigned)time(NULL));
    ReadOptions();
    SDL_EnableUNICODE(1);
    printf("** Loading Graphics **\n");
    LoadImages();
    printf("** Loading Sounds **\n");
    InitSound();
    printf("** Generating Sine Table **\n");
    GenerateSine();
    printf("** Playing Music **\n");
    PlayMusic();
    printf("** Loading Font **\n");
    InitFont( Font = LoadImage("Font.png",3) );
    RedFontSurface = SDL_DisplayFormatAlpha(Font);
    RedFont->Surface = RedFontSurface;
    InitFont2(RedFont);
    ChangeColorAlpha( RedFontSurface, SDL_MapRGB(Screen->format, 150, 150, 150) );
    printf("** Starting Game **\n");
    while (!Quit) {
      SDL_SetEventFilter(&NormalEvents);
      ShowTitle();
      if (Quit) break;
      StartGame();
      Resize( 800, 600 );
      Quit=0;
      SDL_EventState(SDL_KEYDOWN, SDL_ENABLE);
    }
// user wants to quit
#ifdef USE_SOUND
    Mix_FadeOutMusic(1000);
#endif
    if (NetworkOpen) {
      ServerCleanUp();
      cleanup();
      SDLNet_Quit();
      NetworkOpen=0;
    }
    printf("Awaiting SDL_Quit()\n");
    SDL_Quit();
    printf("SDL_Quit() finished.\n");
    
    return 0;
}

Generated by  Doxygen 1.6.0   Back to index