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

cwdata.cpp

// ------------------------------------------------------------------
// cwdata.cpp
// ------------------------------------------------------------------
// This is a wrapper over a datafile.
// Basically, it wraps a datafile in resources like bitmaps,
// sound and fonts in a way that can be requested
// and used by the program, just requesting them by name
// ------------------------------------------------------------------
// By Kronoman
// In loving memory of my father
// Copyright (c) 2003-2004, Kronoman
// ------------------------------------------------------------------
// Upgraded in January 2004, based on skin.cpp of my simple GUI manager
// ------------------------------------------------------------------

#include "cwdata.h"
#include "gerror.h" // error manager
#include "filehelp.h" // to find the datafile

bool CWDatafile::die_on_failure = true; // default = die on failure

// ------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------
CWDatafile::CWDatafile()
{
      datafile = NULL;
      datafile_cache_map.clear();
}

// ------------------------------------------------------------------
// This inits the datafile with a file
// ------------------------------------------------------------------
CWDatafile::CWDatafile(const char *filename)
{
      CWDatafile::CWDatafile();

      this->load_datafile(filename);
}

// ------------------------------------------------------------------
// Destructor, free the datafile RAM...
// ------------------------------------------------------------------
CWDatafile::~CWDatafile()
{
      this->nuke_datafile();
}

// ------------------------------------------------------------------
// Free the memory of the datafile
// ------------------------------------------------------------------
void CWDatafile::nuke_datafile()
{
      if (datafile != NULL)
      {
            unload_datafile(this->datafile);
            datafile = NULL;
      }

      datafile_cache_map.clear();
}

// ------------------------------------------------------------------
// Load a datafile from a disk datafile
// ------------------------------------------------------------------
bool CWDatafile::load_datafile(const char *filename)
{
      char tmp_file_buf[2048];
      this->nuke_datafile(); // old datafile goes to hell

      datafile = ::load_datafile(where_is_the_filename(tmp_file_buf, filename)); // note: the '::' before load_datafile means 'call the Allegro's load_datafile, not this->load_datafile

      if (datafile == NULL)
      {
            if (die_on_failure)
                  raise_error("FATAL ERROR\nCWDatafile::load_datafile(\"%s\") failed\nFile not found or can't be loaded", filename);

            return true; // error d00d
      }
      else
      {
            // the data is loaded, cache it!
            this->do_cache();
      }

      return false;
}

// ------------------------------------------------------------------
// This caches the data, is automatically done in data file load
// ------------------------------------------------------------------
void CWDatafile::do_cache()
{

      if (datafile == NULL)
            return ; // no data to cache!

      datafile_cache_map.clear(); // cache start from zero

      // walk the datafile, and cache key->data pairs
      for (int pos = 0; datafile[pos].type != DAT_END; pos++)
      {
            datafile_cache_map[get_datafile_property(datafile + pos, DAT_NAME)] = (DATAFILE *)datafile + pos;
      }

      // cache ready =) God bless STL
}

// ------------------------------------------------------------------
// Overloaded function, just calls void *CWDatafile::get_resource_dat(string resource_name)
// ------------------------------------------------------------------

void *CWDatafile::get_resource_dat(const char *resource_name)
{
      return this->get_resource_dat(string(resource_name));
}

// ------------------------------------------------------------------
// This returns a resource by name, or NULL on error
// Notice, the pointer returned IS THE DATA itself
// So is safe to do things like this:
//          bmp = (BITMAP *)(this->datafile->get_resource_dat(string("WINDOW_BASE_BMP")));
//          if (bmp != NULL) blah blah
// ------------------------------------------------------------------
void *CWDatafile::get_resource_dat(const string resource_name)
{
      DATAFILE *p;

      p = this->get_resource(resource_name);

      if (p == NULL)
      {
            if (die_on_failure)
                  raise_error("FATAL ERROR!\nCWDatafile::get_resource_dat(\"%s\")\nCan't find resource.", resource_name.c_str());

            return NULL;
      }
      else
      {
            return p->dat;
      }
}

// ------------------------------------------------------------------
// Overloaded, just calls DATAFILE *CWDatafile::get_resource(const string resource_name)
// ------------------------------------------------------------------
DATAFILE *CWDatafile::get_resource(const char *resource_name)
{
      return this->get_resource(string(resource_name));
}

// ------------------------------------------------------------------
// This returns a resource by name, or NULL on error
// Notice,  the pointer returned is a DATAFILE *
// You should add ->dat to get the data itself
// Like this (for example):
//          bmp = (BITMAP *)((this->datafile->get_resource(string("WINDOW_BASE_BMP"))->dat));
// NOTICE: if you check bmp != NULL like this, you will get a seg fault, because ->dat != NULL
// ------------------------------------------------------------------
DATAFILE *CWDatafile::get_resource(const string resource_name)
{
      DatafileCacheMap::iterator pos;

      pos = datafile_cache_map.find(resource_name);

      if (pos != datafile_cache_map.end() )
      {
            return pos->second; // return the value (a *DATAFILE)
      }
      else
      {
            if (die_on_failure)
                  raise_error("FATAL ERROR!\nCWDatafile::get_resource(\"%s\")\nCan't find resource.", resource_name.c_str());

            return NULL; // error
      }

}

// ------------------------------------------------------------------
// This returns a pointer to the whole loaded DATAFILE (in case that you need it for something)
// All coredumps using this are YOUR responsability :P
// ------------------------------------------------------------------

DATAFILE *CWDatafile::get_whole_datafile()
{
      return this->datafile; // all seg faults are YOUR responsability from here, don't screw my nice pointer! =^)
}

// ------------------------------------------------------------------
// This is a debug function, dumps the data loaded on the console
// ------------------------------------------------------------------

void CWDatafile::dump_debug_datafile_data()
{
      DatafileCacheMap::iterator pos;

      cout << "CWDatafile::dump_debug_datafile_data() called " << endl  ;

      for (pos = datafile_cache_map.begin(); pos != datafile_cache_map.end(); ++pos)
      {
            cout << "resource name: '" << pos->first << "'\t"
            << "pointer: " << pos->second << endl;
      }
}

Generated by  Doxygen 1.6.0   Back to index