00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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
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
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
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
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
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
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
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
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
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
00540 pdata[x] = 0;
00541 }
00542 }
00543 }
00544 }
00545 }
00546 }
00547 break;
00548
00549 case 24:
00550 cl_assert(false);
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
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 }