00001
00002
00003
00004
00005
00006
00007
00009
00010 #include "utils.h"
00011 #include <cassert>
00012 #include <cstdarg>
00013 #include "video.h"
00014 #include <math.h>
00015 #include "gui.h"
00016
00017 using namespace std;
00018 using namespace hoa_video::private_video;
00019 using namespace hoa_video;
00020 using namespace hoa_utils;
00021
00022 namespace hoa_video {
00023
00024 namespace private_video {
00025
00026
00027
00028
00029
00030 Image::Image(const std::string &fname, const std::string &tags_, int32 w, int32 h, bool grayscale_) :
00031 filename(fname),
00032 tags(tags_),
00033 width(w),
00034 height(h),
00035 grayscale(grayscale_)
00036 {
00037 texture_sheet = NULL;
00038 x = 0;
00039 y = 0;
00040 u1 = 0.0f;
00041 v1 = 0.0f;
00042 u2 = 1.0f;
00043 v2 = 1.0f;
00044 ref_count = 0;
00045 }
00046
00047
00048
00049 Image::Image(TexSheet *sheet, const std::string &tags_, const std::string &fname, int32 x_, int32 y_, float u1_, float v1_,
00050 float u2_, float v2_, int32 w, int32 h, bool grayscale_) :
00051 texture_sheet(sheet),
00052 filename(fname),
00053 tags(tags_),
00054 x(x_),
00055 y(y_),
00056 u1(u1_),
00057 v1(v1_),
00058 u2(u2_),
00059 v2(v2_),
00060 width(w),
00061 height(h),
00062 grayscale(grayscale_)
00063 {
00064 ref_count = 0;
00065 }
00066
00067
00068
00069
00070
00071 ImageElement::ImageElement(Image *image_, float x_offset_, float y_offset_, float u1_, float v1_,
00072 float u2_, float v2_, float width_, float height_) :
00073 image(image_),
00074 x_offset(x_offset_),
00075 y_offset(y_offset_),
00076 u1(u1_),
00077 v1(v1_),
00078 u2(u2_),
00079 v2(v2_),
00080 width(width_),
00081 height(height_)
00082 {
00083 white = true;
00084 one_color = true;
00085 blend = false;
00086 color[0] = Color::white;
00087 }
00088
00089
00090
00091 ImageElement::ImageElement(Image *image_, float x_offset_, float y_offset_, float u1_, float v1_,
00092 float u2_, float v2_, float width_, float height_, Color color_[4]) :
00093 image(image_),
00094 x_offset(x_offset_),
00095 y_offset(y_offset_),
00096 u1(u1_),
00097 v1(v1_),
00098 u2(u2_),
00099 v2(v2_),
00100 width(width_),
00101 height(height_)
00102 {
00103 color[0] = color_[0];
00104
00105
00106 if (color_[1] == color[0] && color_[2] == color[0] && color_[3] == color[0]) {
00107 one_color = true;
00108
00109
00110 if (color[0] == Color::white) {
00111 white = true;
00112 blend = false;
00113 }
00114
00115 else {
00116 blend = (color[0][3] < 1.0f);
00117 }
00118 }
00119 else {
00120 color[0] = color_[0];
00121 color[1] = color_[1];
00122 color[2] = color_[2];
00123 color[3] = color_[3];
00124
00125 blend = (color[0][3] < 1.0f || color[1][3] < 1.0f || color[2][3] < 1.0f || color[3][3] < 1.0f);
00126 }
00127 }
00128
00129
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 ImageDescriptor::ImageDescriptor() :
00140 _width (0.0f),
00141 _height (0.0f),
00142 _is_static (false),
00143 _grayscale (false),
00144 _animated (false),
00145 _loaded (false)
00146 {
00147 _color[0] = _color[1] = _color[2] = _color[3] = Color::white;
00148 }
00149
00150
00151 bool ImageDescriptor::Load()
00152 {
00153 return VideoManager->LoadImage(*this);
00154 }
00155
00156
00157 void ImageDescriptor::Draw()
00158 {
00159 VideoManager->DrawImage(*this);
00160 }
00161
00162
00163 bool ImageDescriptor::Save(const std::string filename) const
00164 {
00165 if (_animated)
00166 return VideoManager->SaveImage(filename, dynamic_cast<const AnimatedImage &>(*this));
00167 else
00168 return VideoManager->SaveImage(filename, dynamic_cast<const StillImage &>(*this));
00169 }
00170
00171
00172 void ImageDescriptor::_Clear()
00173 {
00174 _width = 0.0f;
00175 _height = 0.0f;
00176 _is_static = false;
00177 _grayscale = false;
00178 _color[0] = _color[1] = _color[2] = _color[3] = Color::white;
00179
00180 _loaded = false;
00181 }
00182
00183
00184
00185
00186
00187
00188 StillImage::StillImage(const bool grayscale) {
00189 Clear();
00190 _animated = false;
00191 _grayscale = grayscale;
00192 }
00193
00194
00195
00196 void StillImage::Clear() {
00197 _Clear();
00198 _filename.clear();
00199 _elements.clear();
00200
00201 SetColor(Color::white);
00202 }
00203
00204
00205 void StillImage::SetWidth (const float width)
00206 {
00207 _width = width;
00208
00209 for (std::vector <private_video::ImageElement>::iterator it=_elements.begin(); it<_elements.end(); ++it)
00210 {
00211 it->width = width;
00212 }
00213 }
00214
00215
00216 void StillImage::SetHeight (const float height)
00217 {
00218 _height = height;
00219
00220 for (std::vector <private_video::ImageElement>::iterator it=_elements.begin(); it<_elements.end(); ++it)
00221 {
00222 it->height = height;
00223 }
00224 }
00225
00226
00227 void StillImage::SetDimensions (const float width, const float height)
00228 {
00229 _width = width;
00230 _height = height;
00231
00232 for (std::vector <private_video::ImageElement>::iterator it=_elements.begin(); it<_elements.end(); ++it)
00233 {
00234 it->width = width;
00235 it->height = height;
00236 }
00237 }
00238
00239
00240 void StillImage::EnableGrayScale() {
00241
00242 if (_grayscale)
00243 return;
00244
00245
00246 _grayscale = true;
00247
00248
00249 if (_elements.size() == 0)
00250 return;
00251
00252
00253 for (uint32 i=0; i<_elements.size(); i++)
00254 {
00255 Image *img = _elements[i].image;
00256
00257 if (img == NULL)
00258 {
00259 if (VIDEO_DEBUG)
00260 cerr << "VIDEO ERROR: Attemp to turn to grayscale mode a NULL Image" << endl;
00261 continue;
00262 }
00263
00264
00265 if (VideoManager->_images.find(img->filename + img->tags + "<G>") != VideoManager->_images.end())
00266 {
00267 _elements[i].image = VideoManager->_images[img->filename + img->tags + "<G>"];
00268 ++(_elements[i].image->ref_count);
00269 continue;
00270 }
00271
00272
00273 hoa_video::private_video::ImageLoadInfo buffer;
00274 VideoManager->_GetBufferFromImage (buffer, img);
00275
00276 VideoManager->_ConvertImageToGrayscale (buffer, buffer);
00277
00278 Image* new_image_gray = new Image(img->filename, img->tags+"<G>", buffer.width, buffer.height, true);
00279
00280 TexSheet *sheet = VideoManager->_InsertImageInTexSheet(new_image_gray, buffer, _is_static);
00281
00282 if(!sheet)
00283 {
00284 if(VIDEO_DEBUG)
00285 cerr << "VIDEO_DEBUG: GameVideo::_InsertImageInTexSheet() returned NULL!" << endl;
00286
00287 delete new_image_gray;
00288
00289 if (buffer.pixels)
00290 free (buffer.pixels);
00291
00292 return;
00293 }
00294
00295 new_image_gray->ref_count = 1;
00296 VideoManager->_images[new_image_gray->filename + new_image_gray->tags] = new_image_gray;
00297 _elements[i].image = new_image_gray;
00298 }
00299 }
00300
00301
00302
00303 void StillImage::DisableGrayScale() {
00304
00305 if (!_grayscale)
00306 return;
00307
00308
00309 _grayscale = false;
00310
00311
00312 if (_elements.size() == 0)
00313 return;
00314
00315
00316 for (uint32 i=0; i<_elements.size(); i++)
00317 {
00318 Image *img = _elements[i].image;
00319
00320 if (img == NULL)
00321 {
00322 if (VIDEO_DEBUG)
00323 cerr << "VIDEO ERROR: Attemp to turn to color mode a NULL Image" << endl;
00324 continue;
00325 }
00326
00327
00328 if (VideoManager->_images.find(img->filename + img->tags.substr(0,img->tags.length()-3)) == VideoManager->_images.end())
00329 {
00330 if (VIDEO_DEBUG)
00331 cerr << "VIDEO ERROR: Color image not found in the map, while gray one was in it" << endl;
00332 continue;
00333 }
00334
00335 _elements[i].image = VideoManager->_images[img->filename + img->tags.substr(0,img->tags.length()-3)];
00336 --(img->ref_count);
00337 }
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 bool StillImage::AddImage(const StillImage &id, float x_offset, float y_offset, float u1, float v1, float u2, float v2)
00351 {
00352
00353 if (x_offset < 0.0f || y_offset < 0.0f) {
00354 if (VIDEO_DEBUG)
00355 cerr << "VIDEO ERROR: passed negative offsets to StillImage::AddImage()" << endl;
00356 return false;
00357 }
00358
00359 size_t num_elements = id._elements.size();
00360 if (num_elements == 0) {
00361 if (VIDEO_DEBUG)
00362 cerr << "VIDEO ERROR: passed in an uninitialized image descriptor to StillImage::AddImage()!" << endl;
00363
00364 return false;
00365 }
00366
00367 for (uint32 i = 0; i < num_elements; ++i) {
00368
00369 ImageElement elem = id._elements[i];
00370 elem.x_offset += x_offset;
00371 elem.y_offset += y_offset;
00372 elem.u1 = u1;
00373 elem.v1 = v1;
00374 elem.u2 = u2;
00375 elem.v2 = v2;
00376
00377 elem.width *= (elem.u2 - elem.u1);
00378 elem.height *= (elem.v2 - elem.v1);
00379
00380
00381 if (elem.image) {
00382 ++(elem.image->ref_count);
00383 }
00384 _elements.push_back(elem);
00385
00386
00387 float max_x = elem.x_offset + elem.width;
00388 if (max_x > _width)
00389 _width = max_x;
00390
00391 float max_y = elem.y_offset + elem.height;
00392 if (max_y > _height)
00393 _height = max_y;
00394 }
00395
00396 return true;
00397 }
00398
00399
00400
00401
00402
00403 AnimatedImage::AnimatedImage(const bool grayscale) {
00404 Clear();
00405 _animated = true;
00406 _grayscale = grayscale;
00407 _number_loops = -1;
00408 _loop_counter = 0;
00409 _loops_finished = false;
00410 }
00411
00412
00413
00414 void AnimatedImage::Clear() {
00415 _Clear();
00416 _frame_index = 0;
00417 _frame_counter = 0;
00418 _frames.clear();
00419 _number_loops = -1;
00420 _loop_counter = 0;
00421 _loops_finished = false;
00422
00423 SetColor(Color::white);
00424 }
00425
00426
00427
00428 void AnimatedImage::EnableGrayScale() {
00429
00430 StillImage *img;
00431 for (uint32 i = 0; i < _frames.size(); i++) {
00432 img = GetFrame(i);
00433 img->EnableGrayScale();
00434 }
00435 }
00436
00437
00438
00439 void AnimatedImage::DisableGrayScale() {
00440
00441 StillImage *img;
00442 for (uint32 i = 0; i < _frames.size(); i++) {
00443 img = GetFrame(i);
00444 img->DisableGrayScale();
00445 }
00446 }
00447
00448
00449
00450 void AnimatedImage::Update() {
00451 if (_frames.size() <= 1)
00452 return;
00453
00454 if (_loops_finished)
00455 return;
00456
00457
00458 uint32 frame_change = VideoManager->GetFrameChange();
00459 _frame_counter += frame_change;
00460
00461
00462 while (_frame_counter >= _frames[_frame_index].frame_time) {
00463 frame_change = _frame_counter - _frames[_frame_index].frame_time;
00464 _frame_index++;
00465 if (_frame_index >= _frames.size()) {
00466
00467
00468 if (_number_loops >= 0 && ++_loop_counter >= _number_loops) {
00469 _loops_finished = true;
00470 _frame_counter = 0;
00471 return;
00472 }
00473 _frame_index = 0;
00474 }
00475 _frame_counter = frame_change;
00476 }
00477 }
00478
00479
00480
00481 bool AnimatedImage::AddFrame(const std::string &frame, uint32 frame_time) {
00482 StillImage img;
00483 img.SetFilename(frame);
00484 img.SetDimensions(_width, _height);
00485 img.SetVertexColors(_color[0], _color[1], _color[2], _color[3]);
00486 img.SetStatic(_is_static);
00487
00488 AnimationFrame new_frame;
00489 new_frame.frame_time = frame_time;
00490 new_frame.image = img;
00491 _frames.push_back(new_frame);
00492
00493 return true;
00494 }
00495
00496
00497
00498 bool AnimatedImage::AddFrame(const StillImage &frame, uint32 frame_time) {
00499 AnimationFrame new_frame;
00500 new_frame.image = frame;
00501 new_frame.frame_time = frame_time;
00502
00503
00504
00505 uint32 num_elements = new_frame.image._elements.size();
00506 if (num_elements) {
00507 for (uint32 i = 0; i < num_elements; i++) {
00508 ++(new_frame.image._elements[i].image->ref_count);
00509 }
00510 }
00511
00512 _frames.push_back(new_frame);
00513 return true;
00514 }
00515
00516
00517
00518 void AnimatedImage::SetWidth(const float width) {
00519 _width = width;
00520
00521
00522 StillImage *img;
00523 for (uint32 i = 0; i < _frames.size(); ++i) {
00524 img = GetFrame(i);
00525 img->SetWidth(width);
00526 }
00527 }
00528
00529
00530
00531 void AnimatedImage::SetHeight(const float height) {
00532 _height = height;
00533
00534
00535 StillImage *img;
00536 for (uint32 i = 0; i < _frames.size(); i++) {
00537 img = GetFrame(i);
00538 img->SetHeight(height);
00539 }
00540 }
00541
00542
00543
00544 void AnimatedImage::SetDimensions(const float width, const float height) {
00545 _width = width;
00546 _height = height;
00547
00548
00549 StillImage *img;
00550 for (uint32 i = 0; i < _frames.size(); i++) {
00551 img = GetFrame(i);
00552 img->SetDimensions(width, height);
00553 }
00554 }
00555
00556
00557
00558 void AnimatedImage::SetColor(const Color &color)
00559 {
00560 _color[0] = color;
00561 _color[1] = color;
00562 _color[2] = color;
00563 _color[3] = color;
00564
00565
00566 StillImage *img;
00567 for (uint32 i = 0; i < _frames.size(); i++) {
00568 img = GetFrame(i);
00569 img->SetColor(color);
00570 }
00571 }
00572
00573
00574
00575 void AnimatedImage::SetVertexColors(const Color &tl, const Color &tr, const Color &bl, const Color &br) {
00576 _color[0] = tl;
00577 _color[1] = tr;
00578 _color[2] = bl;
00579 _color[3] = br;
00580
00581
00582 StillImage *img;
00583 for (uint32 i = 0; i < _frames.size(); i++) {
00584 img = GetFrame(i);
00585 img->SetVertexColors(tl, tr, bl, br);
00586 }
00587 }
00588
00589 }