00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "paragui.h"
00030
00031 #include <iostream>
00032 #include <cstring>
00033 #include <string>
00034 #include <cassert>
00035
00036 #include "pgsurfacecache.h"
00037 #include "pglog.h"
00038
00039 #ifdef HASH_MAP_INC
00040 #include HASH_MAP_INC
00041 #else
00042 #include <map>
00043 #endif
00044
00045 #define MY_SURFACEMAP ((pg_surfacemap_t*)my_surfacemap)
00046 #define MY_SURFACEINDEX ((pg_surfacemap_index_t*)my_surfacemap_index)
00047
00048 #ifdef HASH_MAP_INC
00049
00050 struct pg_surface_hash {
00051 size_t operator()(std::string s1) const {
00052 unsigned long hash = 0;
00053 for(Uint32 i = 0; i < s1.length(); i++) {
00054 hash = 5*hash + s1[i];
00055 }
00056 return hash;
00057 }
00058 };
00059
00060
00061 typedef STL_MAP<std::string, pg_surface_cache_t*, pg_surface_hash> pg_surfacemap_t;
00062
00063 typedef STL_MAP<unsigned long, pg_surface_cache_t* > pg_surfacemap_index_t;
00064
00065 typedef pg_surfacemap_t::iterator pg_surfacemap_iter_t;
00066 typedef pg_surfacemap_index_t::iterator pg_surfacemap_index_iter_t;
00067 #else
00068
00069 typedef std::map<std::string, pg_surface_cache_t*> pg_surfacemap_t;
00070
00071 typedef std::map<unsigned long, pg_surface_cache_t*> pg_surfacemap_index_t;
00072
00073 typedef pg_surfacemap_t::iterator pg_surfacemap_iter_t;
00074 typedef pg_surfacemap_index_t::iterator pg_surfacemap_index_iter_t;
00075 #endif
00076
00077 PG_SurfaceCache::PG_SurfaceCache() {
00078 my_surfacemap = (void*)new(pg_surfacemap_t);
00079 my_surfacemap_index = (void*)new(pg_surfacemap_index_t);
00080 }
00081
00082 PG_SurfaceCache::~PG_SurfaceCache() {
00083 Cleanup();
00084
00085 delete MY_SURFACEMAP;
00086 delete MY_SURFACEINDEX;
00087
00088 my_surfacemap = NULL;
00089 my_surfacemap_index = NULL;
00090 }
00091
00092 void PG_SurfaceCache::Cleanup() {
00093
00094 if(my_surfacemap == NULL) {
00095 return;
00096 }
00097
00098 pg_surfacemap_iter_t i = MY_SURFACEMAP->begin();
00099 while(i != MY_SURFACEMAP->end()) {
00100 pg_surface_cache_t* t = (*i).second;
00101 if(t != NULL) {
00102 SDL_FreeSurface(t->surface);
00103 delete t;
00104 }
00105 MY_SURFACEMAP->erase(i);
00106 i = MY_SURFACEMAP->begin();
00107 }
00108
00109 MY_SURFACEMAP->clear();
00110 MY_SURFACEINDEX->clear();
00111 }
00112
00113 void PG_SurfaceCache::CreateKey(std::string &key, Uint16 w, Uint16 h,
00114 PG_Gradient* gradient, SDL_Surface* background,
00115 PG_Draw::BkMode bkmode, Uint8 blend) {
00116 char tmpkey[256];
00117 char colorkey[10];
00118 int i=0;
00119
00120 assert(w != 0 && h != 0);
00121
00122 sprintf(tmpkey, "%04x%04x%08lx%01i%01i",
00123 w, h,
00124 reinterpret_cast<unsigned long>(background),
00125 bkmode,
00126 blend);
00127
00128 if(gradient != NULL) {
00129 for(i=0; i<4; i++) {
00130 sprintf(colorkey, "%02x%02x%02x",
00131 gradient->colors[i].r,
00132 gradient->colors[i].g,
00133 gradient->colors[i].b
00134 );
00135
00136 strcat(tmpkey, colorkey);
00137 }
00138 }
00139
00140 key = tmpkey;
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 }
00171
00172 pg_surface_cache_t* PG_SurfaceCache::FindByKey(const std::string &key) {
00173 pg_surfacemap_t::iterator i = MY_SURFACEMAP->find(key);
00174 if(i == MY_SURFACEMAP->end()) {
00175 return NULL;
00176 }
00177 return (*i).second;
00178
00179 }
00180
00181 pg_surface_cache_t* PG_SurfaceCache::FindBySurface(SDL_Surface* surface) {
00182 return (*MY_SURFACEINDEX)[reinterpret_cast<unsigned long>(surface)];
00183 }
00184
00185 SDL_Surface* PG_SurfaceCache::FindSurface(const std::string &key) {
00186 pg_surfacemap_t::iterator i = MY_SURFACEMAP->find(key);
00187 if(i == MY_SURFACEMAP->end()) {
00188 return NULL;
00189 }
00190 return (*i).second->surface;
00191
00192
00193
00194
00195
00196
00197
00198 }
00199
00200 SDL_Surface* PG_SurfaceCache::AddSurface(const std::string &key, SDL_Surface* surface) {
00201 pg_surface_cache_t* t = NULL;
00202
00203 if(surface == NULL) {
00204 return NULL;
00205 }
00206
00207
00208 t = FindByKey(key);
00209
00210
00211 if(t != NULL) {
00212 PG_LogDBG("Trying to add surface with existing key!");
00213
00214
00215 if(t->surface != surface) {
00216 PG_LogDBG("New and existing surfacepointers are NOT equal !!!");
00217
00218 SDL_FreeSurface(surface);
00219 }
00220
00221
00222 t->refcount++;
00223 return t->surface;
00224 }
00225
00226 pg_surface_cache_t* item = new pg_surface_cache_t;
00227 item->refcount = 1;
00228 item->surface = surface;
00229 item->key = key;
00230 (*MY_SURFACEMAP)[key] = item;
00231 (*MY_SURFACEINDEX)[reinterpret_cast<unsigned long>(surface)] = item;
00232
00233 return surface;
00234 }
00235
00236 void PG_SurfaceCache::DeleteSurface(SDL_Surface* surface, bool bDeleteIfNotExists) {
00237
00238 if(!surface) {
00239 return;
00240 }
00241
00242 pg_surface_cache_t* t = FindBySurface(surface);
00243
00244
00245 if(t == NULL) {
00246 if(bDeleteIfNotExists) {
00247 SDL_FreeSurface(surface);
00248 }
00249 return;
00250 }
00251
00252
00253 t->refcount--;
00254
00255
00256 if(t->refcount > 0) {
00257 return;
00258 }
00259
00260 MY_SURFACEMAP->erase(t->key);
00261 MY_SURFACEINDEX->erase(reinterpret_cast<unsigned long>(surface));
00262
00263 SDL_FreeSurface(t->surface);
00264 delete t;
00265 }
00266
00267 void PG_SurfaceCache::IncRef(const std::string &key) {
00268 pg_surface_cache_t* t = FindByKey(key);
00269
00270 if(t == NULL) {
00271 return;
00272 }
00273
00274 t->refcount++;
00275 }
00276
00277
00278
00279
00280
00281
00282