PLM Software Multimedia Tools and Games
PLMBase

PLMBase Component :
Resources and Archives

Overview

The goal of the classes in this part is to simplify data access to the application. The first mean is by using a Resource manager that will find and load the files for you, and maintain a list of loaded resources. The second mean is by creating archives, that a big file that contains all the resource files needed by an application such as images, fonts, text files, sounds, ... The last mean is to use the PLMResFile class to easily handle files (read / write with automatic conversion in little endian format).


Classes
Resource classes
  • PLMResource : A simple virtual class that defines the interface of all resources, in other words Load() and Save() methods. Most "loadable" classes in PLM derives from it so that it can be used with the resource manager.
  • PLMResMgr : The main class of this part, designed to be simple to use. You can define multiple sources (standard directories or archives), then just ask to load a file.
  • PLMResFile : A File class designed to ease the data conversions (little/big endian), to precisely read or write any integer size, and most of all to simulate small files inside bigger ones (when used to load data from archives).
  • PLMFileProvider : A virtual class implemented here by PLMArchiveLoader and in the Base section by PLMDir. Gives a uniform way to PLMResMgr to find files.
  • PLMArchiveLoader : Read-only part of the archive interface. Allow to load (extract) data from archives. Standard applications usually only need this interface.
  • PLMArchiveMaker : Read-Write part of the archive interface. Allows to create and modify archives (add, remove and update files). Only used by archives managers.
  • PLMArchiveHandler : A virtual class to give a uniform access to archives. The two previous classes use an object of this class. Real archives are implemented by the following classes, that derives from this one.
  • PLMAH_PLM : Implementation of the PLM archive file format.
  • PLMAH_PAK : Implementation of the PAK archive file format (Quake 1 and 2, and other games relative to Quake engine).

Examples

First, let's see an example about PLMResFile :

  // try to open the file toto in read-only mode
  PLMResFile f ("toto");
  // check that all is ok
  if (! f.Good())
    { cerr << "Can not open file toto\n"; return; }
  // compute the length of the file (in bytes)
  f.SeekEnd ();
  u32 size = f.GetPos ();
  f.SeekStart ();
  cout << "File size = " << size << " bytes.\n";
  // read some data
  u8 Char = f.Read8 ();        // read 1 byte
  u16 Short = f.Read16 ();     // read 2 bytes (little endian conversion)
  u32 Int = f.Read32 ();       // read 4 bytes (little endian conversion)
  // close the file (optional, done by the destructor)
  f.Close ();

Note that PLMResFiles are automatically closed when the object is deleted, but you may need to close it before, to delete or rename it for example.

A classical example of PLMResMgr use :

  // simple creation
  PLMResMgr resmgr;
  
  // then add some sources (should test return value)
  resmgr.AddSource ("./data");               // add "data" directory
  resmgr.AddSource ("./data/sprites.dat");   // add sprites.dat archive file
  // later in the program
  PLMImage *sprite1 = (PLMImage*) resmgr.Load ("spr1.pcx", ORES_PCX);
  if (sprite1 == NULL) ... error
  PLMSound *sound1  = (PLMSound*) resmgr.Load ("snd1.wav", ORES_WAV);
  if (sound1 == NULL) ... error

Notes:

  • The files spr1.pcx and snd1.wav can be anywhere in the sources (in the data directory or in the data/sprites.dat archive file).
  • The first instance found is returned.
  • A common error is to use the current working directory as a source instead of the executable directory.
  • You do not have to delete a resource loaded by the resource manager, since it can be used by other objects.
  • They are automatically deleted when the manager's destructor is called. If you must delete one absolutly, simply call its Remove() method (and make sure no objects use it before).
  • A 3D version of the manager exists, able to load the same resource types, plus 3D fonts and textures.

The next example shows how to open and print the content of a PLMFileProvider (can be a directory or an archive) :

  // create an archive loader as file provider
  // we could have used a PLMDir object instead
  PLMFileProvider *source = new PLMArchiveLoader;
  ASSERT (source);
  // try to open an archive
  if (! source->Open ("sprites.dat"))
    { delete source; cerr << "Can not open sprites.dat\n"; return; }
  // sort its content by name, case sensitive and directories first
  source->Sort (PLM::SORT_NAME | PLM::SORT_CASE | PLM::SORT_DIRS);
  // use an iterator to print every entry
  PLMFileProvider::SortedIterator it = source->GetSortedIterator ();
  for (; it.IsNotEnd (); it.Next ())
    {
      cout.setf (ios::left, ios::adjustfield);
      cout << " - " << setw(40) << it.Name() << ' ';
      cout.setf (ios::right, ios::adjustfield);
      cout << setw(10) << it.Size() << '\t';
      if (it.IsDir()) cout << "/ ";
      if (it.IsHidden()) cout << "H ";
      if (it.IsLink()) cout << "->";
      cout << endl;
    }

Copyright 2001-2004 PLMSoft All rights reserved. (last mod.: 15 Oct 2004)