Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

restype_surface.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: restype_surface.cpp,v 1.1 2001/03/06 15:09:17 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 #include <Core/precomp.h>
00015 
00016 #ifdef BORLAND
00017 #pragma hdrstop
00018 #endif
00019 
00020 #include <API/Display/Display/palette.h>
00021 #include <API/Display/SurfaceProviders/sprite.h>
00022 #include <API/Display/SurfaceProviders/sprite_subarray_provider.h>
00023 #include <API/Display/SurfaceProviders/sprite_subsection_provider.h>
00024 #include <API/Core/System/clanstring.h>
00025 #include <API/Core/System/cl_assert.h>
00026 #include <API/Core/System/error.h>
00027 #include "restype_surface.h"
00028 
00029 /******************************************************************************
00030                                                 class CL_ResourceType_Surface
00031 ******************************************************************************/
00032 
00033 std::list<CL_ResourceSource_Surface*> CL_Res_Surface::surface_sources;
00034 
00035 CL_Res_Surface::CL_Res_Surface() : CL_ResourceType("surface")
00036 {
00037 }
00038 
00039 CL_Resource *CL_Res_Surface::create_from_location(
00040         std::string name,
00041         std::string location,
00042         CL_ResourceOptions *options,
00043         CL_ResourceManager *parent)
00044 {
00045         CL_String ext = CL_String(name).right(4);
00046         ext.to_lower();
00047 
00048         bool is_surface_type = false;
00049         if (options->exists("type"))
00050         {
00051                 if (options->get_value("type") != "surface") return NULL;
00052                 is_surface_type = true;
00053         }
00054 
00055         for (
00056                 std::list<CL_ResourceSource_Surface*>::iterator it = surface_sources.begin();
00057                 it != surface_sources.end();
00058                 it++)
00059         {
00060                 if ((*it)->can_create(ext, options))
00061                 {
00062                         is_surface_type = true;
00063                         break;
00064                 }
00065         }
00066         
00067         if (is_surface_type)
00068         {
00069                 return new CL_SurfaceFileResource(name, location, options, parent);
00070         }
00071 
00072         return NULL;
00073 }
00074 
00075 CL_Resource *CL_Res_Surface::create_from_serialization(
00076         std::string name,
00077         CL_ResourceManager *parent)
00078 {
00079         return new CL_SurfaceDatafileResource(name, parent);
00080 }
00081 
00082 /******************************************************************************
00083                                                 class CL_WritableSurfaceResource
00084 ******************************************************************************/
00085 
00086 CL_WritableSurfaceResource::CL_WritableSurfaceResource(std::string name)
00087 : CL_Resource("surface", name)
00088 {
00089         loaded = false;
00090         loaded_surface = NULL;
00091         load_count = 0;
00092 }
00093 
00094 void CL_WritableSurfaceResource::serialize_save(CL_OutputSource *output)
00095 {
00096         CL_SurfaceProvider *provider = create_provider();
00097         cl_assert(provider != NULL);
00098 
00099         provider->lock();
00100 
00101         int width = provider->get_width();
00102         int height = provider->get_height();
00103         int no_sprs = provider->get_num_frames();
00104         int bytes_per_pixel = (provider->get_depth()+7)/8;
00105         int transcol = provider->uses_src_colorkey() ? (int) provider->get_src_colorkey() : -1;
00106         int red_mask = provider->get_red_mask();
00107         int green_mask = provider->get_green_mask();
00108         int blue_mask = provider->get_blue_mask();
00109         int alpha_mask = provider->get_alpha_mask();
00110         int depth = provider->get_depth();
00111 //      int format = provider->get_pixel_format();
00112         int translate_x = provider->get_translate_x();
00113         int translate_y = provider->get_translate_y();
00114         int pitch = provider->get_pitch();
00115 
00116         CL_Palette *pal = provider->get_palette();
00117         unsigned char *data = (unsigned char *) provider->get_data();
00118         cl_assert(data != NULL);
00119 
00120         output->write_int32(width);
00121         output->write_int32(height);
00122         output->write_int32(no_sprs);
00123         output->write_int32(transcol);
00124         
00125         char palette_bool = (pal != NULL) ? 1 : 0;
00126         output->write_char8(palette_bool);
00127         
00128         if (palette_bool) output->write(pal->palette, 256*3);
00129 
00130         char indexed_bool = (provider->is_indexed()) ? 1 : 0;
00131         output->write_char8(indexed_bool);
00132         
00133 //      output->write_int32(format);
00134         output->write_int32(red_mask);
00135         output->write_int32(green_mask);
00136         output->write_int32(blue_mask);
00137         output->write_int32(alpha_mask);
00138         output->write_int32(depth);
00139 
00140         if (!provider->uses_src_colorkey())
00141         {
00142                 int bytes_pr_line = width*bytes_per_pixel;
00143                 for (int y=0; y<height*no_sprs; y++)
00144                 {
00145                         int img_y = y+translate_y;
00146 
00147                         output->write(
00148                                 data+translate_x*bytes_per_pixel+img_y*pitch,
00149                                 bytes_pr_line);
00150                 }
00151         }
00152         else
00153         {
00154                 for (int y=0; y<height*no_sprs; y++)
00155                 {
00156                         int img_y = y+translate_y;
00157 
00158                         output->write(data+translate_x*bytes_per_pixel+img_y*pitch, bytes_per_pixel*width);
00159                 }
00160         }
00161 
00162         provider->unlock();
00163 
00164         delete provider;
00165 }
00166 
00167 void CL_WritableSurfaceResource::load()
00168 {
00169         load_count++;
00170         if (loaded) return;
00171 
00172         CL_SurfaceProvider *provider = create_provider();
00173 
00174         cl_assert(provider != NULL);
00175         
00176         loaded_surface = new CL_Surface(provider, true, false, this);
00177         loaded = true;
00178 }
00179 
00180 void CL_WritableSurfaceResource::unload()
00181 {
00182         load_count--;
00183         if (load_count == 0)
00184         {
00185                 delete loaded_surface;
00186                 loaded = false;
00187         }
00188 }
00189 
00190 CL_Surface *CL_WritableSurfaceResource::create_surface()
00191 {
00192         if (!loaded) load();
00193 
00194         return loaded_surface;
00195 }
00196 
00197 /******************************************************************************
00198                                                 class CL_SurfaceFileResource
00199 ******************************************************************************/
00200 
00201 CL_SurfaceFileResource::CL_SurfaceFileResource(
00202         std::string name,
00203         std::string location,
00204         CL_ResourceOptions *_options,
00205         CL_ResourceManager *_parent)
00206 : CL_WritableSurfaceResource(name)
00207 {
00208         surface_location = location;
00209         options = _options;
00210         parent = _parent;
00211 }
00212 
00213 CL_SurfaceFileResource::~CL_SurfaceFileResource()
00214 {
00215         delete options;
00216 }
00217 
00218 CL_SurfaceProvider *CL_SurfaceFileResource::create_provider()
00219 {
00220         CL_SurfaceProvider *ret_provider = NULL;
00221 
00222         CL_String ext = CL_String(surface_location).right(4);
00223         ext.to_lower();
00224 
00225         for (
00226                 std::list<CL_ResourceSource_Surface*>::iterator it = CL_Res_Surface::surface_sources.begin();
00227                 it != CL_Res_Surface::surface_sources.end();
00228                 it++)
00229         {
00230                 if (options->exists((*it)->get_name()))
00231                 {
00232                         if ((*it)->can_create(ext, options))
00233                         {
00234                                 ret_provider = (*it)->create(surface_location, options, parent);
00235                                 break;
00236                         }
00237                         else
00238                         {
00239                                 CL_String err;
00240                                 err << "Surface provider " << (*it)->get_name() << " cannot handle input format!";
00241                                 throw CL_Error(err.get_string());
00242                         }
00243                 }
00244         }
00245         
00246         if (ret_provider == NULL)
00247         {
00248                 for (
00249                         std::list<CL_ResourceSource_Surface*>::iterator it = CL_Res_Surface::surface_sources.begin();
00250                         it != CL_Res_Surface::surface_sources.end();
00251                         it++)
00252                 {
00253                         if ((*it)->can_create(ext, options))
00254                         {
00255                                 ret_provider = (*it)->create(surface_location, options, parent);
00256                                 break;
00257                         }
00258                 }
00259         }
00260         if (ret_provider == NULL) return NULL;
00261 
00262 /*
00263         if (options->exists("tga") ||  ext == ".tga")
00264         {
00265                 ret_provider = new CL_TargaProvider(surface_location, NULL);
00266         }
00267         else if (options->exists("pcx") || ext == ".pcx")
00268         {
00269                 ret_provider = new CL_PCXProvider(surface_location, NULL);
00270         }
00271         else if (options->exists("png") || ext == ".png")
00272         {
00273                 ret_provider = new CL_PNGProvider(surface_location, NULL);
00274         }
00275         else
00276         {
00277                 return NULL;
00278         }
00279 */
00280 
00281         if (options->exists("x") && options->exists("y") &&
00282                 options->exists("width") && options->exists("height"))
00283         {
00284                 if (options->exists("array"))
00285                 {
00286                         int sep = options->get_value("array").find('x');
00287                         if (sep == -1) return NULL;
00288 
00289                         ret_provider = new CL_SpriteSubarrayProvider(
00290                                 ret_provider,
00291                                 CL_String(options->get_value("x")).get_as_int(),
00292                                 CL_String(options->get_value("y")).get_as_int(),
00293                                 CL_String(options->get_value("width")).get_as_int(),
00294                                 CL_String(options->get_value("height")).get_as_int(),
00295                                 CL_String(options->get_value("array")).mid(0, sep).get_as_int(),
00296                                 CL_String(options->get_value("array")).mid(sep+1).get_as_int());
00297                 }
00298                 else
00299                 {
00300                         ret_provider = new CL_SpriteSubsectionProvider(
00301                                 ret_provider,
00302                                 CL_String(options->get_value("x")).get_as_int(),
00303                                 CL_String(options->get_value("y")).get_as_int(),
00304                                 CL_String(options->get_value("width")).get_as_int(),
00305                                 CL_String(options->get_value("height")).get_as_int());
00306                 }
00307         }
00308 
00309         CL_ResourceOption *tcol_option = options->get_option("tcol");
00310         if (tcol_option != NULL)
00311         {
00312                 if (tcol_option->multi_valued())
00313                 {
00314                         std::list<std::string> *tcol_list = tcol_option->get_all_values();
00315                         unsigned int *trans_table = new unsigned int[tcol_list->size()];
00316 
00317                         int pos = 0;
00318                         for (
00319                                 std::list<std::string>::iterator it = tcol_list->begin();
00320                                 it != tcol_list->end();
00321                                 it++)
00322                         {
00323                                 int tval = CL_String(*it).get_as_int();
00324                                 {
00325                                         trans_table[pos++] = tval;
00326                                 }
00327                         }
00328 
00329                         ret_provider = new CL_MaskTranscolProvider(
00330                                         ret_provider,
00331                                         true,
00332                                         trans_table,
00333                                         tcol_list->size());
00334                         delete[] trans_table;
00335                 }
00336                 else
00337                 {
00338                         CL_String tcol = tcol_option->get_value();
00339                         int tval = tcol.get_as_int();
00340                         if (tval >= 0 && tval < 256)
00341                         {
00342                                 unsigned int v = tval;
00343                                 ret_provider = new CL_MaskTranscolProvider(
00344                                                 ret_provider,
00345                                                 true,
00346                                                 &v,
00347                                                 1);
00348                         }
00349                 }
00350         }
00351 
00352         return ret_provider;
00353 }
00354 
00355 /******************************************************************************
00356                                                 class CL_SurfaceDatafileResource
00357 ******************************************************************************/
00358 
00359 CL_SurfaceDatafileResource::CL_SurfaceDatafileResource(
00360         std::string name,
00361         CL_ResourceManager *_parent)
00362 : CL_WritableSurfaceResource(name)
00363 {
00364         surface_location = "";
00365         options = NULL;
00366         parent = _parent;
00367 }
00368 
00369 CL_SurfaceDatafileResource::~CL_SurfaceDatafileResource()
00370 {
00371         delete options;
00372 }
00373 
00374 CL_SurfaceProvider *CL_SurfaceDatafileResource::create_provider()
00375 {
00376         return new CL_SpriteProvider(get_name().c_str(), parent->get_resource_provider());
00377 }
00378 
00379 /******************************************************************************
00380                                                 class CL_MaskTranscolProvider
00381 ******************************************************************************/
00382 
00383 CL_MaskTranscolProvider::CL_MaskTranscolProvider(
00384         CL_SurfaceProvider *_parent,
00385         bool _delete_provider,
00386         const unsigned int * _mask_indices,
00387         int _num_mask_indices)
00388 {
00389         parent = _parent;
00390         cl_assert(parent != NULL);
00391         //cl_assert(parent->get_depth() == 8);
00392 
00393         delete_provider = _delete_provider;
00394         num_mask_indices = _num_mask_indices;
00395         mask_indices = new unsigned int[num_mask_indices];
00396         memcpy(mask_indices, _mask_indices, num_mask_indices*sizeof(unsigned int));
00397 }
00398 
00399 CL_MaskTranscolProvider::~CL_MaskTranscolProvider()
00400 {
00401         if (delete_provider) delete parent;
00402         delete[] mask_indices;
00403 }
00404 
00405 unsigned int CL_MaskTranscolProvider::get_pitch() const
00406 {
00407         return parent->get_pitch();
00408 }
00409 
00410 int CL_MaskTranscolProvider::get_translate_x() const
00411 {
00412         return parent->get_translate_x();
00413 }
00414 
00415 int CL_MaskTranscolProvider::get_translate_y() const
00416 {
00417         return parent->get_translate_y();
00418 }
00419 
00420 unsigned int CL_MaskTranscolProvider::get_depth() const
00421 {
00422         return parent->get_depth();
00423 }
00424 
00425 bool CL_MaskTranscolProvider::is_indexed() const
00426 {
00427         return parent->is_indexed();
00428 }
00429 
00430 unsigned int CL_MaskTranscolProvider::get_width() const
00431 {
00432         return parent->get_width();
00433 }
00434 
00435 unsigned int CL_MaskTranscolProvider::get_height() const
00436 {
00437         return parent->get_height();
00438 }
00439 
00440 unsigned int CL_MaskTranscolProvider::get_num_frames() const
00441 {
00442         return parent->get_num_frames();
00443 }
00444 
00445 unsigned int CL_MaskTranscolProvider::get_red_mask() const
00446 {
00447         return parent->get_red_mask();
00448 }
00449 
00450 unsigned int CL_MaskTranscolProvider::get_green_mask() const
00451 {
00452         return parent->get_green_mask();
00453 }
00454 
00455 unsigned int CL_MaskTranscolProvider::get_blue_mask() const
00456 {
00457         return parent->get_blue_mask();
00458 }
00459 
00460 unsigned int CL_MaskTranscolProvider::get_alpha_mask() const
00461 {
00462         return parent->get_alpha_mask();
00463 }
00464 
00465 CL_Palette *CL_MaskTranscolProvider::get_palette() const
00466 {
00467         return parent->get_palette();
00468 }
00469 
00470 unsigned int CL_MaskTranscolProvider::get_src_colorkey() const
00471 {
00472         return mask_indices[0];
00473 }
00474 
00475 bool CL_MaskTranscolProvider::uses_src_colorkey() const
00476 {
00477 //      return parent->uses_src_colorkey();
00478         return true;
00479 }
00480 
00481 void *CL_MaskTranscolProvider::get_data() const
00482 {
00483         return parent->get_data();
00484 }
00485 
00486 void CL_MaskTranscolProvider::perform_lock()
00487 {
00488         parent->lock();
00489 
00490         switch (get_depth())
00491         {
00492         case 8:
00493                 {
00494                         int i;
00495                         bool trans_table[256];
00496                         for (i=0;i<256;i++) trans_table[i] = false;
00497                         if (parent->uses_src_colorkey()) trans_table[parent->get_src_colorkey()] = true;
00498                         for (i=0;i<num_mask_indices;i++) trans_table[mask_indices[i]] = true;
00499 
00500                         unsigned char *pdata = (unsigned char *) parent->get_data();
00501                         for (unsigned int s=0;s<parent->get_num_frames();s++)
00502                         {
00503                                 for (unsigned int y=0;y<parent->get_height();y++)
00504                                 {
00505                                         for (unsigned int x=0;x<parent->get_width();x++)
00506                                         {
00507                                                 if (trans_table[*pdata]) *pdata = mask_indices[0];
00508                                                 pdata++;
00509                                         }
00510                                         pdata += parent->get_pitch()-parent->get_width();
00511                                 }
00512                         }
00513                 }
00514                 break;
00515 
00516         case 15:
00517         case 16:
00518                 {
00519                         unsigned int frames = parent->get_num_frames();
00520                         unsigned int height = parent->get_height();
00521                         unsigned int width = parent->get_width();
00522                         unsigned int pitch = parent->get_pitch();
00523 
00524                         for (unsigned int s=0;s<frames;s++)
00525                         {
00526                                 for (unsigned int y=0;y<height;y++)
00527                                 {
00528                                         unsigned char *data =
00529                                                 ((unsigned char *) parent->get_data()) + (y+s*height)*pitch;
00530 
00531                                         unsigned short *pdata = (unsigned short *) data;
00532 
00533                                         for (unsigned int x=0;x<width;x++)
00534                                         {
00535                                                 for (int i=0; i<num_mask_indices; i++)
00536                                                 {
00537                                                         if (pdata[x] == mask_indices[i])
00538                                                         {
00539                                                                 // Set the whole pixel to 0 (Even if we should only set the alpha value
00540                                                                 pdata[x] = 0;
00541                                                         }
00542                                                 }
00543                                         }
00544                                 }
00545                         }
00546                 }
00547                 break;
00548 
00549         case 24:
00550                 cl_assert(false); // not implemented in 24 bpp. That depth SUCKS! :-(
00551                 break;
00552 
00553         case 32:
00554                 {
00555                         unsigned int frames = parent->get_num_frames();
00556                         unsigned int height = parent->get_height();
00557                         unsigned int width = parent->get_width();
00558                         unsigned int pitch = parent->get_pitch();
00559 
00560                         for (unsigned int s=0;s<frames;s++)
00561                         {
00562                                 for (unsigned int y=0;y<height;y++)
00563                                 {
00564                                         unsigned char *data =
00565                                                 ((unsigned char *) parent->get_data()) + (y+s*height)*pitch;
00566 
00567                                         unsigned int *pdata = (unsigned int *) data;
00568 
00569                                         for (unsigned int x=0;x<width;x++)
00570                                         {
00571                                                 for (int i=0; i<num_mask_indices; i++)
00572                                                 {
00573                                                         if (pdata[x] == mask_indices[i])
00574                                                         {
00575                                                                 // Set the whole pixel to 0 (Even if we should only set the alpha value
00576                                                                 pdata[x] = 0;
00577                                                         }
00578                                                 }
00579                                         }
00580                                 }
00581                         }
00582                 }
00583                 break;
00584         }
00585 }
00586 
00587 void CL_MaskTranscolProvider::perform_unlock()
00588 {
00589         parent->unlock();
00590 }

Generated at Wed Apr 4 19:54:03 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001