shapevga.cc

Go to the documentation of this file.
00001 /*
00002  *  shapevga.cc - Handle the 'shapes.vga' file and associated info.
00003  *
00004  *  Copyright (C) 1999  Jeffrey S. Freedman
00005  *  Copyright (C) 2000-2001  The Exult Team
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #  include <config.h>
00024 #endif
00025 
00026 #include <iomanip>      /* For debugging only. */
00027 #include "shapevga.h"
00028 #include "monstinf.h"
00029 #include "utils.h"
00030 #include "exceptions.h"
00031 
00032 using std::ifstream;
00033 using std::ios;
00034 
00035 // For convienience
00036 #define patch_exists(p) (have_patch_path && U7exists(p))
00037 #define patch_name(p) (patch_exists(p) ? (p) : 0)
00038 
00039 /*
00040  *  Open, but don't quit if editing.  We first try the patch name if it's
00041  *  given.
00042  */
00043 
00044 static bool U7open2
00045   (
00046   ifstream& in,     // Stream to open.
00047   const char *pname,    // Patch name, or null.
00048   const char *fname,    // File name.
00049   bool editing
00050   )
00051   {
00052   if (pname)
00053     {
00054     U7open(in, pname);
00055     return true;
00056     }
00057   try
00058     {
00059     U7open(in, fname);
00060     }
00061   catch(const file_exception & f)
00062     {
00063     if (editing)
00064       return false;
00065     throw f;
00066     }
00067   return true;
00068   }
00069 
00070 /*
00071  *  Read in data files about shapes.
00072  *
00073  *  Output: 0 if error.
00074  */
00075 
00076 void Shapes_vga_file::read_info
00077   (
00078   bool bg,      // True if BlackGate.
00079   bool editing      // True to allow files to not exist.
00080   )
00081   {
00082   if (info_read)
00083     return;
00084   info_read = true;
00085   int i, cnt;
00086   bool have_patch_path = is_system_path_defined("<PATCH>");
00087 
00088   // ShapeDims
00089 
00090   // Starts at 0x96'th shape.
00091   ifstream shpdims;
00092   if (U7open2(shpdims, patch_name(PATCH_SHPDIMS), SHPDIMS, editing))
00093     for (i = 0x96; i < num_shapes && !shpdims.eof(); i++)
00094       {
00095       shpdims.get((char&) info[i].shpdims[0]);
00096       shpdims.get((char&) info[i].shpdims[1]);
00097       }
00098 
00099   // WGTVOL
00100   ifstream wgtvol;
00101   if (U7open2(wgtvol, patch_name(PATCH_WGTVOL), WGTVOL, editing))
00102     for (i = 0; i < num_shapes && !wgtvol.eof(); i++)
00103       {
00104       wgtvol.get((char&) info[i].weight);
00105       wgtvol.get((char&) info[i].volume);
00106       }
00107 
00108   // TFA
00109   ifstream tfa;
00110   if (U7open2(tfa, patch_name(PATCH_TFA), TFA, editing))
00111     for (i = 0; i < num_shapes && !tfa.eof(); i++)
00112       {
00113       tfa.read((char*)&info[i].tfa[0], 3);
00114       info[i].set_tfa_data();
00115       }
00116 
00117   ifstream ready;
00118   if (U7open2(ready, patch_name(PATCH_READY), READY, editing))
00119     {
00120     cnt = Read1(ready);   // Get # entries.
00121     for (i = 0; i < cnt; i++)
00122       {
00123       unsigned short shapenum = Read2(ready);
00124       unsigned char type = Read1(ready);
00125       info[shapenum].ready_type = type;
00126       ready.seekg(6, ios::cur);// Skip 9 bytes.
00127       }
00128     ready.close();
00129     }
00130   ifstream armor;
00131   if (U7open2(armor, patch_name(PATCH_ARMOR), ARMOR, editing))
00132     {
00133     cnt = Read1(armor);
00134     for (i = 0; i < cnt; i++)
00135       {
00136       Armor_info *ainf = new Armor_info();
00137       unsigned short shapenum = ainf->read(armor);
00138       info[shapenum].armor = ainf;
00139       }
00140     armor.close();
00141     }
00142   ifstream weapon;
00143   if (U7open2(weapon, patch_name(PATCH_WEAPONS), WEAPONS, editing))
00144     {
00145     cnt = Read1(weapon);
00146     for (i = 0; i < cnt; i++)
00147       {
00148       Weapon_info *winf = new Weapon_info();
00149       unsigned short shapenum = winf->read(weapon, bg);
00150       info[shapenum].weapon = winf;
00151       }
00152     weapon.close(); 
00153     }
00154   ifstream ammo;
00155   if (U7open2(ammo, patch_name(PATCH_AMMO), AMMO, editing))
00156     {
00157     cnt = Read1(ammo);
00158     for (i = 0; i < cnt; i++)
00159       {
00160       Ammo_info *ainf = new Ammo_info();
00161       unsigned short shapenum = ainf->read(ammo);
00162       info[shapenum].ammo = ainf;
00163       }
00164     ammo.close();
00165     }
00166   // Load data about drawing the weapon in an actor's hand
00167   ifstream wihh;
00168   unsigned short offsets[1024];
00169   if (U7open2(wihh, patch_name(PATCH_WIHH), WIHH, editing))
00170     cnt = num_shapes <= 1024 ? num_shapes : 1024;
00171   else
00172     cnt = 0;
00173   for (i = 0; i < cnt; i++)
00174     offsets[i] = Read2(wihh);
00175   for (i = 0; i < cnt; i++)
00176     // A zero offset means there is no record
00177     if(offsets[i] == 0)
00178       info[i].weapon_offsets = 0;
00179     else
00180       {
00181       wihh.seekg(offsets[i]);
00182       // There are two bytes per frame: 64 total
00183       info[i].weapon_offsets = new unsigned char[64];
00184       for(int j = 0; j < 32; j++)
00185         {
00186         unsigned char x = Read1(wihh);
00187         unsigned char y = Read1(wihh);
00188         // Set x/y to 255 if weapon is not to be drawn
00189         // In the file x/y are either 64 or 255:
00190         // I am assuming that they mean the same
00191         if(x > 63 || y > 63)
00192           x = y = 255;
00193         info[i].weapon_offsets[j * 2] = x;
00194         info[i].weapon_offsets[j * 2 + 1] = y;
00195         }
00196       }
00197   if (cnt)
00198     wihh.close();
00199   ifstream mfile;     // Now get monster info.
00200   if (U7open2(mfile, patch_name(PATCH_MONSTERS), MONSTERS, editing))
00201     {
00202     int num_monsters = Read1(mfile);
00203     for (i = 0; i < num_monsters; i++)
00204       {
00205       Monster_info *minf = new Monster_info();
00206       int shnum = minf->read(mfile);
00207       info[shnum].monstinf = minf;
00208       }
00209     mfile.close();
00210     }
00211           // Get 'equip.dat'.
00212   if (U7open2(mfile, patch_name(PATCH_EQUIP), EQUIP, editing))
00213     {
00214     int num_recs = Read1(mfile);
00215     Equip_record *equip = new Equip_record[num_recs];
00216     for (i = 0; i < num_recs; i++)
00217       {
00218       Equip_record& rec = equip[i];
00219           // 10 elements/record.
00220       for (int elem = 0; elem < 10; elem++)
00221         {
00222         int shnum = Read2(mfile);
00223         unsigned prob = Read1(mfile);
00224         unsigned quant = Read1(mfile);
00225         Read2(mfile);
00226         rec.set(elem, shnum, prob, quant);
00227         }
00228       }
00229           // Monster_info owns this.
00230     Monster_info::set_equip(equip, num_recs);
00231     mfile.close();
00232     }
00233   ifstream(occ);      // Read flags from occlude.dat.
00234   if (U7open2(occ, patch_name(PATCH_OCCLUDE), OCCLUDE, editing))
00235     {
00236     unsigned char occbits[128]; // 1024 bit flags.
00237     occ.read((char *)occbits, sizeof(occbits));
00238     for (i = 0; i < sizeof(occbits); i++)
00239       {
00240       unsigned char bits = occbits[i];
00241       int shnum = i*8;  // Check each bit.
00242       for (int b = 0; bits; b++, bits = bits>>1)
00243         if (bits&1)
00244           {
00245           info[shnum + b].occludes_flag = true;
00246           }
00247       }
00248     }
00249   }
00250 
00251 /*
00252  *  Open/close file.
00253  */
00254 
00255 Shapes_vga_file::Shapes_vga_file
00256   (
00257   const char *nm,     // Path to file.
00258   int u7drag,     // # from u7drag.h, or -1.
00259   const char *nm2     // Path to patch version, or 0.
00260   ) : Vga_file(nm, u7drag, nm2), info_read(false)
00261   {
00262   info.set_size(num_shapes);
00263   }
00264 
00265 Shapes_vga_file::~Shapes_vga_file()
00266   {
00267   }
00268 
00269 
00270 void Shapes_vga_file::init()
00271 {
00272   if (is_system_path_defined("<PATCH>") && U7exists(PATCH_SHAPES))
00273     load(SHAPES_VGA, PATCH_SHAPES);
00274   else
00275     load(SHAPES_VGA);
00276 
00277   info.set_size(num_shapes);
00278 }

Generated on Mon Jul 9 14:42:50 2007 for ExultEngine by  doxygen 1.5.1