Logo Search packages:      
Sourcecode: tecnoballz version File versions  Download package

lesBriques.cc

//******************************************************************************
// copyright (c) 1991-2004 TLK Games all rights reserved
//-----------------------------------------------------------------------------
// file           : "lesBriques.cc"
// created        : 1996-11-13
// updates        : 2004-10-27
// fonction : manage the bricks
//-----------------------------------------------------------------------------
// 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.
//******************************************************************************
#include "../include/lesBriques.h"
#include "../include/ressources.h"
#include "../include/RAM_killer.h"
#include "../include/ecran_hard.h"

//-----------------------------------------------------------------------------
// create the object
//-----------------------------------------------------------------------------
lesBriques::lesBriques()
{
      mentatInit();
      brique_pnt = (brickClear *)NULL;
      brikTampon = (char *)NULL;
      mega_table = (brickInfos *)NULL;
      GFX_brique = (GIF_bitMap *)NULL;
      briqueSave = 0;
      brique_clr = 0;
      less_brick = 0;
      less_count = 10;
      pageBrickH = 112 * resolution;
      pageBrickV = 63 * resolution;
      brickWidth = BRICKWIDTH * resolution;
      brickHeigh = BRICKHEIGH * resolution;
      brick_size = brickWidth * brickHeigh;
      brkyoffset = BRKYOFFSET * resolution;
      brickIndus = 8 * brickHeigh * pageBrickH;

      ombre_deca = 3 * resolution;
      ombre_left = (BRICKHEIGH * resolution) - ombre_deca;
      ombre_yoff = (BRKYOFFSET - BRICKHEIGH) * resolution;
      ombre_top1 = ombre_deca - ombre_yoff;
      
}

//-------------------------------------------------------------------------------
// release the object
//-------------------------------------------------------------------------------
lesBriques::~lesBriques()
{
      if(brique_pnt)
            memGestion->liberation((char *)brique_pnt);
      if(mega_table)
            memGestion->liberation((char *)mega_table);
      if(brikTampon)
            memGestion->liberation((char *)brikTampon);
      if(GFX_brique)
            delete GFX_brique;
      mentatKill();
}

//-------------------------------------------------------------------------------
// first initialization
//-------------------------------------------------------------------------------
Sint32 lesBriques::first_init(barreScore *barre, zeCapsules *capsu, ze_gadgets *gadge)
{
      barreObjet = barre;
      caps_objet = capsu;
      gads_objet = gadge;

      // allocate memory for the redraw bricks table
      if(!brique_pnt)
      {     brique_pnt = (brickClear *) memGestion->reserveMem
                  (MAXBRIKCLR * sizeof(brickClear), 0x54425249);
            error_init(memGestion->retour_err());
            if(erreur_num) return erreur_num;
      }

      // allocate memory to save background under bricks
      if(!brikTampon)
      {     brikTampon = memGestion->reserveMem
                  (brick_size * NB_BRICKST, 0x54425249 );
            error_init(memGestion->retour_err());
            if(erreur_num) return erreur_num;
      }

      // allocate memory for current brick level
      if(!mega_table)
      {     mega_table = (brickInfos *) memGestion->reserveMem
                  (sizeof(brickInfos) * NB_BRICKST, 0x4D454741);
            error_init(memGestion->retour_err());
      }

      return erreur_num;
}

// -----------------------------------------------------------------------------
// initialize new level and draw bricks 
// input    => areaN: number of the area (1 to 5)
//                => tablo: number of the level (1 to 12)
//                => lbrik: 1 = bonus "less brick" (bought into the shop)
// -----------------------------------------------------------------------------
Sint32 lesBriques::initialise(Sint32 areaN, Sint32 tablo, Sint32 lbrik)
{ 
      if(!GFX_brique)
      {     
            less_brick = lbrik;

      //###################################################################
      // reset restauration list
      //###################################################################
      briqueSave = 0; 
      brique_clr = 0;
      brickClear *briPT = brique_pnt;
      for(Sint32 j = 0; j < MAXBRIKCLR; j++, briPT++)
      {     briPT->balle_posX = 0;
            briPT->balle_posY = 0;
            briPT->raquettePT = (tecno_bump *) 0x0;
            briPT->brique_num = 0;
            briPT->briqueFlag = 0;
            briPT->adresseAff = 0;
            briPT->adresseTab = (brickInfos *) 0x0;
      }

      //###################################################################
      // Initialize current brick level
      //###################################################################
      brickInfos *megaT = mega_table;
      Sint32 c = 0;
      Sint32 vacol = 239;
      for(Sint32 j = 0; j < NB_BRICKSV * brkyoffset; j += brkyoffset)
      {     for(Sint32 i = 0; i < NB_BRICKSH * brickWidth; i += brickWidth)
            {     megaT->brique_rel = 0;
                  megaT->brique_aff = 0;
                  megaT->adresseAff = ecran_gere->buffer_rel(i, j);
                  megaT->briquePosX = 0;
                  megaT->briquePosY = 0;
                  megaT->brique_num = c++;
                  megaT->brickcolor = vacol;
                  megaT++;
            }
            if(++vacol > 255)
                  vacol = 239;
      }

      //###################################################################
      // select one of 10 sets of bricks
      //###################################################################
      GFXbriques = new GIF_bitMap();
      error_init(GFXbriques->decompacte(ressources::RESZEBRICK));
      if(erreur_num)
            return (erreur_num);
      Sint32 i = hasard_val & 0x0F;
      //i = 7;
      if(i >= 10)
            i = i - 10;
      Sint32 bposy = 0;
      Sint32 bposx = 0;
      if(i >= 5)
      {     bposy = 63 * resolution;
            i = i - 5;
      }
      bposx = i * 112 * resolution;
      
      bposx = 0 * 112 * resolution; //test only
      bposy = 1 * 63 * resolution; //test only
      
      if(is_verbose)
            printf("lesBriques::initialise()  bposx=%i / bposy=%i \n", bposx, bposy);
      GFX_brique = GFXbriques->coupe_page(bposx, bposy, pageBrickH, pageBrickV);
      if(!GFX_brique)
      {     error_init(GFXbriques->retour_err());
            return (erreur_num);
      }
      delete GFXbriques;

      //###################################################################
      // read one bricks level from the file "tableau.data"
      //###################################################################
      error_init(tabNouveau(areaN, tablo)); 
      if(erreur_num)
            return (erreur_num);

      //###################################################################
      // read somes values for the graphic routine
      //###################################################################
      offsSource = GFX_brique->GFX_modulo(brickWidth);
      offsDestin = ecran_gere->buffer_mod(brickWidth);
      adr_source = (Sint32 *)GFX_brique->GFXadresse();
      adr_desti1 = (Sint32 *)ecran_gere->buffer_adr();
      adr_desti2 = (Sint32 *)ecran_gere->tampon_adr();

      initpalett();
}
      sauve_fond();                 // save background under bricks     
      bricksShad();                 // display bricks shadows
      bricks_aff();                 // display bricks
      return (erreur_num);
}

// -----------------------------------------------------------------------------
// return the number of bricks
// -----------------------------------------------------------------------------
Sint32 lesBriques::getbrikCnt()
{ 
      return brickCount;
}

// -----------------------------------------------------------------------------
// recopie un nouveau tableau dans "mega_table"
// input    => areaN : Numero de l'area (1 a 5) / number of the area (1 to 5)
//                => tablo : Numero du tableau (1 a 12) / number of the table (1 to 12)
// -----------------------------------------------------------------------------
Sint32 lesBriques::tabNouveau(Sint32 areaN, Sint32 tablo)
{
      // un tableau fait 17 lignes sur 10 colonnes = 170 * 2 = 340 octets  
      // a table makes 17 lines out of 10 columns 
      brickCount = 0;   //reset the number of bricks of the level 
      brickDestr = 0;   //reset the number of destroyed bricks 

      //###################################################################
      // load bricks levels (34000 bytes => 100 levels)
      //###################################################################
      char *tabHd  = pRessource->getResData(ressources::RESBLEVELS);
      if(!tabHd)
      {     error_init(E_NORESOUR);
            return (erreur_num);
      }
      if(tablo >= 6) tablo--;
      char *tabPT = tabHd + (SIZEOFAREA * 2 * (areaN - 1)) +
            (LEVEL_SIZE * 2 * (tablo - 1));

      //###################################################################
      // select a level randomly (2 possible levels for a level)
      //###################################################################
      if((hasard_val & 0x001))
            tabPT = tabPT + LEVEL_SIZE * 2 * 50;

      //###################################################################
      // copy all bricks of the level in the structure "mega_table"
      //###################################################################
      brickInfos *megaT = mega_table;
      megaT += (6 * NB_BRICKSH);    // 6 first lines are always empty
      for(Sint32 j = 0; j < LEVELHEIGH; j++, megaT += 3)
      {     megaT += 3; // the first 3 columns are always empty 
            for(Sint32 i = 0; i < LEVELWIDTH; i++, megaT++)
            {     Sint32 adres = 0;
                  char pos_y = *(tabPT++);      // position y dans page brique de 0 a 8
                  char pos_x = *(tabPT++);      // position x dans page brique de 0 a 12 (step 2) 12*8*2=192
                  if(pos_x || pos_y)
                  {     //pos_x = 12;     // test only
                        //pos_y = 1;      // test only
                        megaT->briquePosX = pos_x;    // save X-coordinate into mega_table
                        megaT->briquePosY = pos_y;    // save Y-coordinate into mega_table
                        adres = GFX_brique->GFXrelatif(pos_x * 8 * resolution, pos_y * brickHeigh);
                        if(adres < brickIndus)  // it's a indestructible brick?
                              brickCount++;           // not, counter's incremented
                  }
                  megaT->brique_rel = adres;
                  megaT->brique_aff = adres;
                  //printf("%i ", megaT->brique_rel);
            }
            //printf("\n");
      }
      if(tabHd)
            memGestion->liberation((char*)tabHd);

      //###################################################################
      // Initialize the number of total bricks to destroy 
      //###################################################################
      barreObjet->scoreBrick(brickCount);
      return (erreur_num);
}

// -----------------------------------------------------------------------------
// display bricks shadows
// -----------------------------------------------------------------------------
void lesBriques::bricksShad()
{
      brickInfos *megaT = mega_table;
      for(Sint32 j = ombre_deca; j < NB_BRICKSV * brkyoffset + ombre_deca; j += brkyoffset)
      {     for(Sint32 i = -ombre_deca; i < NB_BRICKSH * brickWidth - ombre_deca; i += brickWidth)
            {     if(megaT->brique_rel)
                        ecran_gere->rectShadow(i, j, brickWidth, brickHeigh);
                  megaT++;
            }
      }
}

//------------------------------------------------------------------------------
// display all bricks
//------------------------------------------------------------------------------
void lesBriques::bricks_aff()
{
      brickInfos *megaT = mega_table;
      for(Sint32 j = 0; j < NB_BRICKSV * brkyoffset; j += brkyoffset)
      {     for(Sint32 i = 0; i < NB_BRICKSH * brickWidth; i += brickWidth, megaT++)
             {    Sint32 pos_x = megaT->briquePosX;   // x >= 0 and x < 14
                  Sint32 pos_y = megaT->briquePosY;   // y >= 0 and y < 9
                  if(pos_x || pos_y)
                  {     pos_x *= 8 * resolution;                        // planar -> chunky
                        pos_y *= brickHeigh;
                        char *srcPT = GFX_brique->GFXadresse(pos_x, pos_y);
                        dsplybrick(srcPT, megaT->adresseAff, megaT->brickcolor);
                  }
            }
      }
}

// -----------------------------------------------------------------------------
// display one brick
//    input => srcPT : pointer on the graphics of the brick
//                => adres : relative pointer on the graphics of the "buffer"
//                => colbr : colormap number (239 to 255)
// -----------------------------------------------------------------------------
void lesBriques::dsplybrick(char *srcPT, Sint32 adres, Sint32 colbr)
{
      Sint32 line1 = offsSource;
      Sint32 line2 = offsDestin;
      char *desP1 = (char *)adr_desti1;   // pointer to the "buffer"
      char *desP2 = (char *)adr_desti2;   // pointer to the "tampon"
      desP1 = desP1 + adres;
      desP2 = desP2 + adres;
      for (Sint32 j = 0 ; j < brickHeigh ; j++)
      {     for (Sint32 i = 0 ; i<brickWidth ; i++ )
            {     char p = *(srcPT++);
                  if(p == 0)        // color 0 ?
                        p = colbr;  // yes, replace
                  *(desP1++) = p;
                  *(desP2++) = p;
            }
            srcPT = srcPT + line1;
            desP1 = desP1 + line2;
            desP2 = desP2 + line2;
      }
}
// -----------------------------------------------------------------------------
// initialize the 17 colors of the bricks
// -----------------------------------------------------------------------------
void lesBriques::initpalett()
{
      SDL_Color *palPT = ecran_gere->paletteAdr();
      SDL_Color *palP1 = palPT + 239;
      Sint32 i = hasard_val;
      i &= 0x0f;
      //Sint32 i = hasard_val & 0x0F;
      if(i >= 10)
            i = i - 10;
      const Uint32 *ptpal = (ressources::tabledegas + i * 18);
      for(i = 0; i < 17; i++)
      {     Uint32 vacol = ptpal[i];
            Uint32 vablu = vacol & 0x000000ff;
            Uint32 vagre = vacol & 0x0000ff00;
            vagre = vagre >> 8;
            Uint32 vared = vacol & 0x00ff0000;
            vared = vared >> 16;
            palP1->r = vared;
            palP1->g = vagre;
            palP1->b = vablu;
            palP1++;
      }
      ecran_gere->palette_go(palPT);
}
//------------------------------------------------------------------------------
// save background under bricks     
//------------------------------------------------------------------------------
void lesBriques::sauve_fond()
{
      Sint32 *bufPT = (Sint32 *)brikTampon;
      brickInfos *megaT = mega_table;
      Sint32 offs = ecran_gere->bufferNext() - brickWidth;
      for(Sint32 j = 0; j < NB_BRICKSV * brkyoffset; j += brkyoffset)
      {     for(Sint32 i = 0; i < NB_BRICKSH * brickWidth; i += brickWidth, megaT++)
            {     Sint32 *monPT = (Sint32 *)ecran_gere->tampon_pos(i, j);
                  megaT->briqueFond = bufPT;
                  for(Sint32 k = 0; k < brickHeigh; k++, monPT = (Sint32*)((char *)monPT + offs))
                  {     for(Sint32 l = 0; l < brickWidth / 4; l++)
                        *(bufPT++) = *(monPT++);
                  }
            }
      }
}


// -----------------------------------------------------------------------------
// handle "less bricks"
// -----------------------------------------------------------------------------
void lesBriques::lessbricks()
{ 
      if(less_brick > 0)
      {     if(--less_count <= 0)
            {     less_count = 10;
                  less_brick--;
                  barreObjet->brickMoins(1);
#ifndef SOUNDISOFF
                  ptAudiomix->sound_play(S_TOUBRIK1);
#endif
            }
      }
}

//------------------------------------------------------------------------------
// display a brick or restore the background under the brick
//------------------------------------------------------------------------------
Sint32 lesBriques::brickRemap()
{
      brickClear *briPT = brique_pnt + brique_clr;
      Sint32 adres = briPT->adresseAff;   // adresse affichage relative
      if(!adres) return 0;
      {     brique_clr += 1;                    // augmente le pointeur sur la table brique a effacer
            brique_clr &= (MAXBRIKCLR - 1);     // limite le compte a 512 (de 0 a 511)
            briPT->adresseAff = 0;
            brickInfos *megaT = briPT->adresseTab;

            //###############################################################
            // restaure background
            //###############################################################
            if(briPT->briqueFlag)   // 0 = redraw brick / 1 = restore background
            {     Sint32 line2 = offsDestin;
                  Sint32 *desP1 = adr_desti1;
                  Sint32 *desP2 = adr_desti2;
                  desP1 = (Sint32*)((char *)desP1 + adres);
                  desP2 = (Sint32*)((char *)desP2 + adres);
                  Sint32 *srcPT = megaT->briqueFond;


                  megaT->brique_aff = 0;
                  for(Sint32 j = 0; j < brickHeigh; j++)
                  {     for(Sint32 i = 0; i < brickWidth / 4; i++)
                        {     *(desP1++) = *srcPT; 
                              *(desP2++) = *(srcPT++);
                        }
                        desP1 = (Sint32*)((char *)desP1 + line2);
                        desP2 = (Sint32*)((char *)desP2 + line2);
                  }
                  Sint32 j;

                  //##########################################################
                  // clear drop shadow (if needed)
                  //##########################################################

                  // 1. bottom
                  if((megaT + offBri_BB)->brique_aff)
                        j = ombre_yoff;   // brique en bas (2 lignes)
                  else
                        j = ombre_deca;   // pas de brique en bas (6 lignes)
                  Sint32 decal = ecran_gere->ecran_next(adres, 0, brickHeigh);
                  ecran_gere->clr_shadow(decal, brickWidth - ombre_deca, j);

                  // 2. left-bottom
                  if((megaT + offBri_BG)->brique_aff)
                        j = ombre_yoff;
                  else
                        j = ombre_deca;
                  decal = ecran_gere->ecran_next(adres, -ombre_deca, brickHeigh);
                  ecran_gere->clr_shadow(decal, ombre_deca, j);

                  // 3. left        
                  if(!(megaT + offBri_GG)->brique_aff)
                  {     decal = ecran_gere->ecran_next(adres, -ombre_deca, ombre_deca);
                        ecran_gere->clr_shadow(decal, ombre_deca, ombre_left);
                  }

                  //##########################################################
                  // redraw drop shadow (if needed)
                  //##########################################################
                  
                  // 1. exist top brick ? 
                  if((megaT + offBri_HH)->brique_aff)
                        ecran_gere->set_shadow(adres, brickWidth - ombre_deca, ombre_top1);

                  // Il existe une brique en haut a droite ?
                  if((megaT + offBri_HD)->brique_aff)
                  {     decal = ecran_gere->ecran_next(adres, brickWidth - ombre_deca, 0);
                        ecran_gere->set_shadow(decal, ombre_deca, ombre_top1);
                  }
                  
                  // Il existe une brique a droite ?
                  if((megaT + offBri_DD)->brique_aff)
                  {     decal = ecran_gere->ecran_next(adres, brickWidth - ombre_deca, ombre_deca);
                        ecran_gere->set_shadow(decal, ombre_deca, ombre_left);
                  }

                  // destroyed indestructible brick
                  if(briPT->balle_posX < 0) 
                  {     barreObjet->scoreAjout(100);
#ifndef SOUNDISOFF
                        ptAudiomix->sound_play(S_CASSEIND);
#endif
                  }
                  else
                  {     barreObjet->scoreAjout(20);
                        barreObjet->brickMoins(1);
                        brickDestr++;
#ifndef SOUNDISOFF
                        ptAudiomix->sound_play(S_TOUBRIK1);
#endif
                        if(briPT->balle_posX != 512)
                        {     caps_objet->envoieFric(briPT);
                              gads_objet->envoieGads(briPT);
                        }
                  }

            }

            //###############################################################
      // redraw a new brick
            //###############################################################
      else
            {     char *gfxad = GFX_brique->GFXadresse();
                  brickInfos *megaT = briPT->adresseTab;
                  dsplybrick(gfxad + briPT->brique_num, adres, megaT->brickcolor);
                  barreObjet->scoreAjout(10);
#ifndef SOUNDISOFF
                  ptAudiomix->sound_play(S_TOUBRIK1);
#endif
                  caps_objet->envoieFric(briPT);
      }
      } // (adresseAff!=0)
      return 1;
}

//------------------------------------------------------------------------------
// clear all bricks (Game Over)
//------------------------------------------------------------------------------
void lesBriques::clr_bricks()
{
      Sint32 save = briqueSave;
      brickClear *briPT = brique_pnt;
      brickInfos *tMega = mega_table;
      tMega += (6 * NB_BRICKSH);    // 6 first lines are always empty
      for(Sint32 j = 0; j < LEVELHEIGH; j++, tMega += 3)
      {     tMega += 3; // the first 3 columns are always empty 
            for(Sint32 i = 0; i < LEVELWIDTH; i++, tMega++)
            {     brickInfos *megaT = tMega;
                  brickClear *briP2 = briPT + save;
                  Sint32 v = megaT->brique_rel;
                  if(v)
                  {     briP2->balle_posX = 512;      // flag brick blitz destroy
                        briP2->adresseAff = megaT->adresseAff;
                        briP2->adresseTab = megaT;
                        megaT->briquePosX = -1;
                        megaT->brique_rel = 0;                          //RAZ brick code
                        briP2->brique_num = megaT->brique_num;    //brick number
                        briP2->briqueFlag = 1;                          //flag restore background
                        save += 1;                                      // inc. pt restaure table
                        save &= (MAXBRIKCLR - 1);
                  }
            }
      }
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
Sint32      lesBriques::getBkWidth()
{
      return brickWidth;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
Sint32      lesBriques::getBkHeigh()
{
      return brickHeigh;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
Sint32      lesBriques::getBkIndus()
{
      return brickIndus;
}

//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
Sint32      lesBriques::getYOffset()
{
      return brkyoffset;
}

Generated by  Doxygen 1.6.0   Back to index