From 7c996e3296555664a79a968ae5b8325950be2179 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 1 Jul 2011 23:13:55 +0000 Subject: [PATCH] - added percentage support for min / map hp on damage particles - bugfixes for png support for pixmap3d (water textures) --- source/glest_game/type_instances/unit.cpp | 20 ++- .../shared_lib/include/graphics/FileReader.h | 9 +- .../shared_lib/include/graphics/PNGReader.h | 7 + .../shared_lib/include/graphics/TGAReader.h | 6 + source/shared_lib/include/graphics/pixmap.h | 4 +- .../sources/graphics/ImageReaders.cpp | 2 + .../shared_lib/sources/graphics/PNGReader.cpp | 142 ++++++++++++++++++ .../shared_lib/sources/graphics/TGAReader.cpp | 95 ++++++++++++ source/shared_lib/sources/graphics/pixmap.cpp | 73 +++++++-- 9 files changed, 334 insertions(+), 24 deletions(-) diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 65a797f6..26aa78ad 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -2191,9 +2191,17 @@ void Unit::checkCustomizedParticleTriggers(bool force) { if(force == true || (pst != NULL && pst->getMinmaxEnabled() == true)) { bool stopParticle = force; - if(force == false && pst->getMinmaxIsPercent() == false) { - if(hp < pst->getMinHp() || hp > pst->getMaxHp()) { - stopParticle = true; + if(force == false) { + if(pst->getMinmaxIsPercent() == false) { + if(hp < pst->getMinHp() || hp > pst->getMaxHp()) { + stopParticle = true; + } + } + else { + int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if(hpPercent < pst->getMinHp() || hpPercent > pst->getMaxHp()) { + stopParticle = true; + } } } @@ -2222,6 +2230,12 @@ void Unit::checkCustomizedParticleTriggers(bool force) { showParticle = true; } } + else { + int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if(hpPercent >= pst->getMinHp() && hpPercent <= pst->getMaxHp()) { + showParticle = true; + } + } //printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle); diff --git a/source/shared_lib/include/graphics/FileReader.h b/source/shared_lib/include/graphics/FileReader.h index 06bce0b1..06affa4e 100644 --- a/source/shared_lib/include/graphics/FileReader.h +++ b/source/shared_lib/include/graphics/FileReader.h @@ -158,7 +158,8 @@ static inline T* readFromFileReaders(vector const *>* readers, con try { FileReader const * reader = *i; ret = reader->read(file, filepath); //It is guaranteed that at least the filepath matches ... - } catch (...) { //TODO: Specific exceptions + } + catch (...) { //TODO: Specific exceptions continue; } if (ret != NULL) { @@ -237,8 +238,8 @@ T* FileReader::readPath(const string& filepath) { } T* ret = readFromFileReaders(&(getFileReaders()), filepath); //Try all other if (ret == NULL) { - std::cerr << "Could not parse filepath: " << filepath << std::endl; - ret = readFromFileReaders(&(getLowPriorityFileReaders()), filepath); //Try to get dummy file + std::cerr << "ERROR #1 - Could not parse filepath: " << filepath << std::endl; + throw runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); } return ret; } @@ -260,7 +261,7 @@ T* FileReader::readPath(const string& filepath, T* object) { } T* ret = readFromFileReaders(&(getFileReaders()), filepath, object); //Try all other if (ret == NULL) { - std::cerr << "Could not parse filepath: " << filepath << std::endl; + std::cerr << "ERROR #2 - Could not parse filepath: " << filepath << std::endl; ret = readFromFileReaders(&(getLowPriorityFileReaders()), filepath); //Try to get dummy file if (ret == NULL) { throw runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); diff --git a/source/shared_lib/include/graphics/PNGReader.h b/source/shared_lib/include/graphics/PNGReader.h index cfc6a968..c3987d3b 100644 --- a/source/shared_lib/include/graphics/PNGReader.h +++ b/source/shared_lib/include/graphics/PNGReader.h @@ -29,6 +29,13 @@ public: Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; }; +class PNGReader3D: FileReader { +public: + PNGReader3D(); + + Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; +}; + }} //end namespace diff --git a/source/shared_lib/include/graphics/TGAReader.h b/source/shared_lib/include/graphics/TGAReader.h index 51bdb047..c45bbd12 100644 --- a/source/shared_lib/include/graphics/TGAReader.h +++ b/source/shared_lib/include/graphics/TGAReader.h @@ -29,6 +29,12 @@ public: Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; }; +class TGAReader3D: FileReader { +public: + TGAReader3D(); + + Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; +}; }} //end namespace diff --git a/source/shared_lib/include/graphics/pixmap.h b/source/shared_lib/include/graphics/pixmap.h index 55c16b0d..b069e703 100644 --- a/source/shared_lib/include/graphics/pixmap.h +++ b/source/shared_lib/include/graphics/pixmap.h @@ -303,6 +303,7 @@ protected: int w; int d; int components; + int slice; uint8 *pixels; string path; @@ -322,7 +323,8 @@ public: void loadSliceTga(const string &path, int slice); void loadSlicePng(const string &path, int slice); - //get + //get + int getSlice() const { return slice; } int getW() const {return w;} int getH() const {return h;} int getD() const {return d;} diff --git a/source/shared_lib/sources/graphics/ImageReaders.cpp b/source/shared_lib/sources/graphics/ImageReaders.cpp index 46d3191a..cd8fc6a2 100644 --- a/source/shared_lib/sources/graphics/ImageReaders.cpp +++ b/source/shared_lib/sources/graphics/ImageReaders.cpp @@ -23,7 +23,9 @@ bool ImageRegisterer::registerImageReaders() { static BMPReader imageReaderBmp; static JPGReader imageReaderJpg; static PNGReader imageReaderPng; + static PNGReader3D imageReader3DPng; static TGAReader imageReaderTga; + static TGAReader3D imageReader3DTga; return true; } diff --git a/source/shared_lib/sources/graphics/PNGReader.cpp b/source/shared_lib/sources/graphics/PNGReader.cpp index 8833a2d8..d3deafef 100644 --- a/source/shared_lib/sources/graphics/PNGReader.cpp +++ b/source/shared_lib/sources/graphics/PNGReader.cpp @@ -192,4 +192,146 @@ Pixmap2D* PNGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const return ret; } + + +PNGReader3D::PNGReader3D(): FileReader(getExtensionsPng()) {} + +Pixmap3D* PNGReader3D::read(ifstream& is, const string& path, Pixmap3D* ret) const { + //Read file + is.seekg(0, ios::end); + size_t length = is.tellg(); + is.seekg(0, ios::beg); + uint8 *buffer = new uint8[8]; + is.read((char*)buffer, 8); + + if (png_sig_cmp(buffer, 0, 8) != 0) { + delete [] buffer; + return NULL; //This is not a PNG file - could be used for fast checking whether file is supported or not + } + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + delete [] buffer; + return NULL; + } + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL,(png_infopp)NULL); + delete [] buffer; + return NULL; + } + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL); + delete [] buffer; + return NULL; //Error during init_io + } + png_set_read_fn(png_ptr, &is, user_read_data); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + int width = info_ptr->width; + int height = info_ptr->height; + int color_type = info_ptr->color_type; + int bit_depth = info_ptr->bit_depth; + + //We want RGB, 24 bit + if (color_type == PNG_COLOR_TYPE_PALETTE || (color_type == PNG_COLOR_TYPE_GRAY && info_ptr->bit_depth < 8) || (info_ptr->valid & PNG_INFO_tRNS)) { + png_set_expand(png_ptr); + } + + if (color_type == PNG_COLOR_TYPE_GRAY) { + png_set_gray_to_rgb(png_ptr); + } + + int number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + png_bytep* row_pointers = new png_bytep[height]; + + if (setjmp(png_jmpbuf(png_ptr))) { + delete[] row_pointers; + delete [] buffer; + return NULL; //error during read_image + } + for (int y = 0; y < height; ++y) { + row_pointers[y] = new png_byte[info_ptr->rowbytes]; + } + png_read_image(png_ptr, row_pointers); + size_t fileComponents = info_ptr->rowbytes/info_ptr->width; + size_t picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); + //std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; + //picComponents = 4; + //Copy image + //printf("pixmap3d loading path [%s] w = %d h = %d d = %d comp = %d\n",path.c_str(),width,height,ret->getD(),picComponents); + ret->init(width,height,ret->getD(),(int)picComponents); + uint8* pixels = ret->getPixels(); + if(ret->getSlice() > 0) { + pixels = &pixels[ret->getSlice()*width*height*picComponents]; + } + + const size_t rowbytes = info_ptr->rowbytes; + size_t location = 0; + for (int y = height-1; y >= 0; --y) { //you have to somehow invert the lines + if (picComponents == fileComponents) { + memcpy(pixels+location,row_pointers[y],rowbytes); + } else { + int r,g,b,a,l; + for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic+= picComponents, xFile+= fileComponents) { + switch(fileComponents) { + case 3: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile+1]; + b = row_pointers[y][xFile+2]; + l = (r+g+b+2)/3; + a = 255; + break; + case 4: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile+1]; + b = row_pointers[y][xFile+2]; + l = (r+g+b+2)/3; + a = row_pointers[y][xFile+3]; + break; + default: + //TODO: Error + case 1: + r = g = b = l = row_pointers[y][xFile]; + a = 255; + break; + } + switch (picComponents) { + case 1: + pixels[location+xPic] = l; + break; + case 4: + pixels[location+xPic+3] = a; //Next case + case 3: + pixels[location+xPic] = r; + pixels[location+xPic+1] = g; + pixels[location+xPic+2] = b; + break; + default: + //just so at least something works + for (unsigned int i = 0; i < picComponents; ++i) { + pixels[location+xPic+i] = l; + } + //TODO: Error + } + } + } + location += picComponents * width; + } + + for (int y = 0; y < height; ++y) { + delete [] row_pointers[y]; + } + delete[] row_pointers; + + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + + delete [] buffer; + + return ret; +} + + }} //end namespace diff --git a/source/shared_lib/sources/graphics/TGAReader.cpp b/source/shared_lib/sources/graphics/TGAReader.cpp index 98eeaf1e..b7f519fc 100644 --- a/source/shared_lib/sources/graphics/TGAReader.cpp +++ b/source/shared_lib/sources/graphics/TGAReader.cpp @@ -63,6 +63,101 @@ static inline std::vector getExtensionStrings() { return extensions; } +TGAReader3D::TGAReader3D(): FileReader(getExtensionStrings()) {} + +Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) const { + //read header + TargaFileHeader fileHeader; + in.read((char*)&fileHeader, sizeof(TargaFileHeader)); + if (!in.good()) { + throw runtime_error(path + " could not be read"); + } + + //check that we can load this tga file + if(fileHeader.idLength!=0){ + throw runtime_error(path + ": id field is not 0"); + } + + if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){ + throw runtime_error(path + ": only uncompressed BW and RGB targa images are supported"); + } + + //check bits per pixel + if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){ + throw runtime_error(path + ": only 8, 24 and 32 bit targa images are supported"); + } + + const int h = fileHeader.height; + const int w = fileHeader.width; + const int fileComponents= fileHeader.bitsPerPixel/8; + const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); + //std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << " slice:" << ret->getSlice() << std::endl; + ret->init(w,h,ret->getD(), picComponents); + uint8* pixels = ret->getPixels(); + if(ret->getSlice() > 0) { + pixels = &pixels[ret->getSlice()*w*h*picComponents]; + } + //read file + for(int i=0; i(getExtensionStrings()) {} Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const { diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index b2598ccd..0e584f2b 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -1215,15 +1215,18 @@ Pixmap3D::Pixmap3D() { d= -1; components= -1; pixels = NULL; + slice=0; } Pixmap3D::Pixmap3D(int w, int h, int d, int components){ pixels = NULL; + slice=0; init(w, h, d, components); } Pixmap3D::Pixmap3D(int d, int components){ pixels = NULL; + slice=0; init(d, components); } @@ -1265,6 +1268,7 @@ Pixmap3D::~Pixmap3D() { } void Pixmap3D::loadSlice(const string &path, int slice) { + this->slice = slice; string extension= path.substr(path.find_last_of('.') + 1); if(extension == "png") { loadSlicePng(path, slice); @@ -1284,24 +1288,28 @@ void Pixmap3D::loadSlice(const string &path, int slice) { void Pixmap3D::loadSlicePng(const string &path, int slice) { this->path = path; - Pixmap3D *pixmap = FileReader::readPath(path); - if(pixmap != NULL) { - this->path = path; + deletePixels(); - w= pixmap->getW(); - h= pixmap->getH(); - if(components==-1){ - components= pixmap->getComponents(); - } + Pixmap3D *pixmap = FileReader::readPath(path,this); + //printf("Loading 3D pixmap PNG [%s] pixmap [%p] this [%p]\n",path.c_str(),pixmap, this); - if(pixels==NULL) { - pixels= new uint8[(std::size_t)pixmap->getPixelByteCount()]; - } - - for(unsigned int i = 0; i < pixmap->getPixelByteCount(); ++i) { - pixels[i] = pixmap->getPixels()[i]; - } - } +// if(pixmap != NULL) { +// this->path = path; +// +// w= pixmap->getW(); +// h= pixmap->getH(); +// if(components==-1){ +// components= pixmap->getComponents(); +// } +// +// if(pixels==NULL) { +// pixels= new uint8[(std::size_t)pixmap->getPixelByteCount()]; +// } +// +// for(unsigned int i = 0; i < pixmap->getPixelByteCount(); ++i) { +// pixels[i] = pixmap->getPixels()[i]; +// } +// } // PixmapIoP plt; // plt.openRead(path); @@ -1346,6 +1354,38 @@ void Pixmap3D::loadSliceBmp(const string &path, int slice){ void Pixmap3D::loadSliceTga(const string &path, int slice){ this->path = path; + deletePixels(); + FileReader::readPath(path,this); + //printf("Loading 3D pixmap TGA [%s] this [%p]\n",path.c_str(),this); + + +// Pixmap3D *pixmap = new Pixmap3D(); +// pixmap->h = this->h; +// pixmap->w = this->w; +// pixmap->d = this->d; +// pixmap->components = this->components; +// pixmap->slice = this->slice; +// FileReader::readPath(path,pixmap); +// printf("Loading 3D pixmap TGA [%s] pixmap [%p] this [%p]\n",path.c_str(),pixmap, this); +// +// //init +// w= pixmap->getW(); +// h= pixmap->getH(); +// if(components==-1){ +// components= pixmap->getComponents(); +// } +// if(pixels==NULL){ +// pixels= new uint8[(std::size_t)getPixelByteCount()]; +// } +// +// //read data +// for(unsigned int i = slice*w*h*components; i < h*w*components; ++i) { +// pixels[i] = pixmap->getPixels()[i]; +// } +// +// delete pixmap; + +/* PixmapIoTga plt; plt.openRead(path); @@ -1364,6 +1404,7 @@ void Pixmap3D::loadSliceTga(const string &path, int slice){ //read data plt.read(&pixels[slice*w*h*components], components); +*/ } // =====================================================