MegaGlest/source/glest_game/world/minimap.cpp

329 lines
10 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "minimap.h"
#include <cassert>
#include "world.h"
#include "vec.h"
#include "renderer.h"
#include "config.h"
#include "object.h"
#include "game_settings.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
namespace Glest{ namespace Game{
// =====================================================
// class Minimap
// =====================================================
const float Minimap::exploredAlpha= 0.5f;
Minimap::Minimap() {
fowPixmap0= NULL;
fowPixmap1= NULL;
fowPixmap1_default=NULL;
fowPixmap0Copy = NULL;
fowPixmap1Copy = NULL;
fowPixmap1Copy_default = NULL;
fogOfWar= true;
gameSettings= NULL;
tex=NULL;
fowTex=NULL;
}
void Minimap::init(int w, int h, const World *world, bool fogOfWar) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
int scaledW= w/Map::cellScale;
int scaledH= h/Map::cellScale;
int potW = next2Power(scaledW);
int potH = next2Power(scaledH);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n",__FILE__,__FUNCTION__,__LINE__,scaledW,scaledH,potW,potH);
this->fogOfWar = fogOfWar;
this->gameSettings = world->getGameSettings();
Renderer &renderer= Renderer::getInstance();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//fow pixmaps
float f= 0.f;
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
fowPixmap0 = new Pixmap2D(potW, potH, 1);
fowPixmap0Copy = new Pixmap2D(potW, potH, 1);
fowPixmap1 = new Pixmap2D(potW, potH, 1);
fowPixmap1_default = new Pixmap2D(potW, potH, 1);
fowPixmap1Copy = new Pixmap2D(potW, potH, 1);
fowPixmap1Copy_default = new Pixmap2D(potW, potH, 1);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
fowPixmap0->setPixels(&f,1);
if((this->gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) {
f = 0.f;
fowPixmap1->setPixels(&f,1);
f = 0.5f;
for (int y=1; y < scaledH - 1; ++y) {
for (int x=1; x < scaledW - 1; ++x) {
fowPixmap1->setPixel(x, y, &f,1);
}
}
}
else {
fowPixmap1->setPixels(&f,1);
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//fow tex
fowTex= renderer.newTexture2D(rsGame);
if(fowTex) {
fowTex->setMipmap(false);
fowTex->setPixmapInit(false);
fowTex->setFormat(Texture::fAlpha);
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n",__FILE__,__FUNCTION__,__LINE__,scaledW,scaledH,potW,potH);
fowTex->getPixmap()->init(potW, potH, 1);
fowTex->getPixmap()->setPixels(&f,1);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//tex
tex= renderer.newTexture2D(rsGame);
if(tex) {
tex->getPixmap()->init(scaledW, scaledH, 3);
tex->setMipmap(false);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
computeTexture(world);
}
Minimap::~Minimap() {
Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMiniMap","",true), true);
delete fowPixmap0;
fowPixmap0=NULL;
delete fowPixmap0Copy;
fowPixmap0Copy = NULL;
delete fowPixmap1;
fowPixmap1=NULL;
delete fowPixmap1_default;
fowPixmap1_default = NULL;
delete fowPixmap1Copy;
fowPixmap1Copy=NULL;
delete fowPixmap1Copy_default;
fowPixmap1Copy_default = NULL;
}
// ==================== set ====================
void Minimap::incFowTextureAlphaSurface(const Vec2i sPos, float alpha,
bool isIncrementalUpdate) {
if(fowPixmap1) {
assert(sPos.x < fowPixmap1->getW() && sPos.y < fowPixmap1->getH());
if(fowPixmap1->getPixelf(sPos.x, sPos.y) < alpha){
fowPixmap1->setPixel(sPos.x, sPos.y, alpha);
}
if(fowPixmap1Copy != NULL && isIncrementalUpdate == true) {
if(fowPixmap1Copy->getPixelf(sPos.x, sPos.y) < alpha){
fowPixmap1Copy->setPixel(sPos.x, sPos.y, alpha);
}
}
}
}
void Minimap::copyFowTexAlphaSurface() {
if(fowPixmap1_default != NULL && fowPixmap1 != NULL) {
fowPixmap1_default->copy(fowPixmap1);
}
if(fowPixmap1Copy_default != NULL && fowPixmap1Copy != NULL) {
fowPixmap1Copy_default->copy(fowPixmap1Copy);
}
}
void Minimap::restoreFowTexAlphaSurface() {
if(fowPixmap1 != NULL && fowPixmap1_default != NULL) {
fowPixmap1->copy(fowPixmap1_default);
}
if(fowPixmap1Copy != NULL && fowPixmap1Copy_default != NULL) {
fowPixmap1Copy->copy(fowPixmap1Copy_default);
}
}
void Minimap::setFogOfWar(bool value) {
fogOfWar = value;
resetFowTex();
}
void Minimap::copyFowTex() {
if(fowPixmap0Copy != NULL && fowPixmap0 != NULL) {
fowPixmap0Copy->copy(fowPixmap0);
}
if(fowPixmap1Copy != NULL && fowPixmap1 != NULL) {
fowPixmap1Copy->copy(fowPixmap1);
}
}
void Minimap::restoreFowTex() {
if(fowPixmap0 != NULL && fowPixmap0Copy != NULL) {
fowPixmap0->copy(fowPixmap0Copy);
}
if(fowPixmap1 != NULL && fowPixmap1Copy != NULL) {
fowPixmap1->copy(fowPixmap1Copy);
}
}
void Minimap::resetFowTex() {
if(fowTex && fowPixmap0 && fowPixmap1) {
Pixmap2D *tmpPixmap= fowPixmap0;
fowPixmap0= fowPixmap1;
fowPixmap1= tmpPixmap;
// Could turn off ONLY fog of war by setting below to false
bool overridefogOfWarValue = fogOfWar;
for(int indexPixelWidth = 0;
indexPixelWidth < fowTex->getPixmap()->getW();
++indexPixelWidth){
for(int indexPixelHeight = 0;
indexPixelHeight < fowTex->getPixmap()->getH();
++indexPixelHeight){
if ((fogOfWar == false && overridefogOfWarValue == false)) {
//(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) {
//printf("Line: %d\n",__LINE__);
float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight);
float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight);
if (p0 > p1) {
fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0);
}
else {
fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p1);
}
}
else if((fogOfWar && overridefogOfWarValue) ||
(gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) {
//printf("Line: %d\n",__LINE__);
float p0= fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight);
float p1= fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight);
if(p1 > exploredAlpha) {
fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, exploredAlpha);
}
if(p0 > p1) {
fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0);
}
}
else {
//printf("Line: %d\n",__LINE__);
fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, 1.f);
}
}
}
}
}
void Minimap::updateFowTex(float t) {
if(fowTex && fowPixmap0 && fowPixmap1) {
for(int indexPixelWidth = 0;
indexPixelWidth < fowPixmap0->getW();
++indexPixelWidth){
for(int indexPixelHeight = 0;
indexPixelHeight < fowPixmap0->getH();
++indexPixelHeight){
float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight);
float p2 = fowTex->getPixmap()->getPixelf(indexPixelWidth, indexPixelHeight);
if(p1 != p2) {
float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight);
fowTex->getPixmap()->setPixel(indexPixelWidth, indexPixelHeight, p0+(t*(p1-p0)));
}
}
}
}
}
// ==================== PRIVATE ====================
void Minimap::computeTexture(const World *world) {
Vec3f color;
const Map *map= world->getMap();
if(tex) {
tex->getPixmap()->setPixels(Vec4f(1.f, 1.f, 1.f, 0.1f).ptr(),tex->getPixmap()->getComponents());
for(int j=0; j<tex->getPixmap()->getH(); ++j){
for(int i=0; i<tex->getPixmap()->getW(); ++i){
SurfaceCell *sc= map->getSurfaceCell(i, j);
if(sc->getObject()==NULL || sc->getObject()->getType()==NULL){
const Pixmap2D *p= world->getTileset()->getSurfPixmap(sc->getSurfaceType(), 0);
color= p->getPixel3f(p->getW()/2, p->getH()/2);
color= color * static_cast<float>(sc->getVertex().y/6.f);
if(sc->getVertex().y<= world->getMap()->getWaterLevel()){
color+= Vec3f(0.5f, 0.5f, 1.0f);
}
if(color.x>1.f) color.x=1.f;
if(color.y>1.f) color.y=1.f;
if(color.z>1.f) color.z=1.f;
}
else{
color= sc->getObject()->getType()->getColor();
}
tex->getPixmap()->setPixel(i, j, color);
}
}
}
}
void Minimap::saveGame(XmlNode *rootNode) {
std::map<string,string> mapTagReplacements;
XmlNode *minimapNode = rootNode->addChild("Minimap");
if(fowPixmap1 != NULL) {
for(std::size_t index = 0; index < fowPixmap1->getPixelByteCount(); ++index) {
if(fowPixmap1->getPixels()[index] != 0) {
XmlNode *fowPixmap1Node = minimapNode->addChild("fowPixmap1");
fowPixmap1Node->addAttribute("index",intToStr(index), mapTagReplacements);
fowPixmap1Node->addAttribute("pixel",intToStr(fowPixmap1->getPixels()[index]), mapTagReplacements);
}
}
}
}
void Minimap::loadGame(const XmlNode *rootNode) {
const XmlNode *minimapNode = rootNode->getChild("Minimap");
if(minimapNode->hasChild("fowPixmap1") == true) {
vector<XmlNode *> fowPixmap1NodeList = minimapNode->getChildList("fowPixmap1");
for(unsigned int i = 0; i < fowPixmap1NodeList.size(); ++i) {
XmlNode *fowPixmap1Node = fowPixmap1NodeList[i];
int pixelIndex = fowPixmap1Node->getAttribute("index")->getIntValue();
fowPixmap1->getPixels()[pixelIndex] = fowPixmap1Node->getAttribute("pixel")->getIntValue();
}
}
}
}}//end namespace