Store user data in $HOME
[kball.git] / src / cwdata.cpp
blob62e8ccadf01170b4c632fa9fe2ac37937b545ca1
1 // ------------------------------------------------------------------
2 // cwdata.cpp
3 // ------------------------------------------------------------------
4 // This is a wrapper over a datafile.
5 // Basically, it wraps a datafile in resources like bitmaps,
6 // sound and fonts in a way that can be requested
7 // and used by the program, just requesting them by name
8 // ------------------------------------------------------------------
9 // By Kronoman
10 // In loving memory of my father
11 // Copyright (c) 2003-2004, Kronoman
12 // ------------------------------------------------------------------
13 // Upgraded in January 2004, based on skin.cpp of my simple GUI manager
14 // ------------------------------------------------------------------
16 #include "cwdata.h"
17 #include "gerror.h" // error manager
18 #include "filehelp.h" // to find the datafile
20 bool CWDatafile::die_on_failure = true; // default = die on failure
22 // ------------------------------------------------------------------
23 // Constructor
24 // ------------------------------------------------------------------
25 CWDatafile::CWDatafile()
27 datafile = NULL;
28 datafile_cache_map.clear();
31 // ------------------------------------------------------------------
32 // This inits the datafile with a file
33 // ------------------------------------------------------------------
34 CWDatafile::CWDatafile(const char *filename)
36 CWDatafile::CWDatafile();
38 this->load_datafile(filename);
41 // ------------------------------------------------------------------
42 // Destructor, free the datafile RAM...
43 // ------------------------------------------------------------------
44 CWDatafile::~CWDatafile()
46 this->nuke_datafile();
49 // ------------------------------------------------------------------
50 // Free the memory of the datafile
51 // ------------------------------------------------------------------
52 void CWDatafile::nuke_datafile()
54 if (datafile != NULL)
56 unload_datafile(this->datafile);
57 datafile = NULL;
60 datafile_cache_map.clear();
63 // ------------------------------------------------------------------
64 // Load a datafile from a disk datafile
65 // ------------------------------------------------------------------
66 bool CWDatafile::load_datafile(const char *filename)
68 char tmp_file_buf[2048];
69 this->nuke_datafile(); // old datafile goes to hell
71 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
73 if (datafile == NULL)
75 if (die_on_failure)
76 raise_error("FATAL ERROR\nCWDatafile::load_datafile(\"%s\") failed\nFile not found or can't be loaded", filename);
78 return true; // error d00d
80 else
82 // the data is loaded, cache it!
83 this->do_cache();
86 return false;
89 // ------------------------------------------------------------------
90 // This caches the data, is automatically done in data file load
91 // ------------------------------------------------------------------
92 void CWDatafile::do_cache()
95 if (datafile == NULL)
96 return ; // no data to cache!
98 datafile_cache_map.clear(); // cache start from zero
100 // walk the datafile, and cache key->data pairs
101 for (int pos = 0; datafile[pos].type != DAT_END; pos++)
103 datafile_cache_map[get_datafile_property(datafile + pos, DAT_NAME)] = (DATAFILE *)datafile + pos;
106 // cache ready =) God bless STL
109 // ------------------------------------------------------------------
110 // Overloaded function, just calls void *CWDatafile::get_resource_dat(string resource_name)
111 // ------------------------------------------------------------------
113 void *CWDatafile::get_resource_dat(const char *resource_name)
115 return this->get_resource_dat(string(resource_name));
118 // ------------------------------------------------------------------
119 // This returns a resource by name, or NULL on error
120 // Notice, the pointer returned IS THE DATA itself
121 // So is safe to do things like this:
122 // bmp = (BITMAP *)(this->datafile->get_resource_dat(string("WINDOW_BASE_BMP")));
123 // if (bmp != NULL) blah blah
124 // ------------------------------------------------------------------
125 void *CWDatafile::get_resource_dat(const string resource_name)
127 DATAFILE *p;
129 p = this->get_resource(resource_name);
131 if (p == NULL)
133 if (die_on_failure)
134 raise_error("FATAL ERROR!\nCWDatafile::get_resource_dat(\"%s\")\nCan't find resource.", resource_name.c_str());
136 return NULL;
138 else
140 return p->dat;
144 // ------------------------------------------------------------------
145 // Overloaded, just calls DATAFILE *CWDatafile::get_resource(const string resource_name)
146 // ------------------------------------------------------------------
147 DATAFILE *CWDatafile::get_resource(const char *resource_name)
149 return this->get_resource(string(resource_name));
152 // ------------------------------------------------------------------
153 // This returns a resource by name, or NULL on error
154 // Notice, the pointer returned is a DATAFILE *
155 // You should add ->dat to get the data itself
156 // Like this (for example):
157 // bmp = (BITMAP *)((this->datafile->get_resource(string("WINDOW_BASE_BMP"))->dat));
158 // NOTICE: if you check bmp != NULL like this, you will get a seg fault, because ->dat != NULL
159 // ------------------------------------------------------------------
160 DATAFILE *CWDatafile::get_resource(const string resource_name)
162 DatafileCacheMap::iterator pos;
164 pos = datafile_cache_map.find(resource_name);
166 if (pos != datafile_cache_map.end() )
168 return pos->second; // return the value (a *DATAFILE)
170 else
172 if (die_on_failure)
173 raise_error("FATAL ERROR!\nCWDatafile::get_resource(\"%s\")\nCan't find resource.", resource_name.c_str());
175 return NULL; // error
180 // ------------------------------------------------------------------
181 // This returns a pointer to the whole loaded DATAFILE (in case that you need it for something)
182 // All coredumps using this are YOUR responsability :P
183 // ------------------------------------------------------------------
185 DATAFILE *CWDatafile::get_whole_datafile()
187 return this->datafile; // all seg faults are YOUR responsability from here, don't screw my nice pointer! =^)
190 // ------------------------------------------------------------------
191 // This is a debug function, dumps the data loaded on the console
192 // ------------------------------------------------------------------
194 void CWDatafile::dump_debug_datafile_data()
196 DatafileCacheMap::iterator pos;
198 cout << "CWDatafile::dump_debug_datafile_data() called " << endl ;
200 for (pos = datafile_cache_map.begin(); pos != datafile_cache_map.end(); ++pos)
202 cout << "resource name: '" << pos->first << "'\t"
203 << "pointer: " << pos->second << endl;