Add infos into target window
[ryzomcore.git] / ryzom / server / src / ai_share / 16x16_layer.cpp
blob0924be5d076266908ac7223c600997d4304e86ed
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "stdpch.h"
23 #include "16x16_layer.h"
25 using namespace std;
26 using namespace NLMISC;
29 * Loads a 16x16Layer and returns a pointer to it. Layer is automatically allocated.
31 I16x16Layer *I16x16Layer::load(NLMISC::IStream &f)
33 uint8 type = 0;
34 f.serial(type);
36 I16x16Layer *layer = NULL;
38 switch (type)
40 case 1: layer = new CFull16x16Layer(); break;
41 case 2: layer = new C8Bits16x16Layer(); break;
42 case 3: layer = new C4Bits16x16Layer(); break;
43 case 4: layer = new C2Bits16x16Layer(); break;
44 case 5: layer = new C1Bit16x16Layer(); break;
45 case 6: layer = new CWhite16x16Layer(); break;
48 if (layer != NULL)
49 layer->serial(f);
51 return layer;
55 * Saves a 16x16Layer.
57 void I16x16Layer::save(NLMISC::IStream &f, I16x16Layer *layer)
59 uint8 type = 0;
61 if (dynamic_cast<CFull16x16Layer*>(layer)) type = 1;
62 else if (dynamic_cast<C8Bits16x16Layer*>(layer)) type = 2;
63 else if (dynamic_cast<C4Bits16x16Layer*>(layer)) type = 3;
64 else if (dynamic_cast<C2Bits16x16Layer*>(layer)) type = 4;
65 else if (dynamic_cast<C1Bit16x16Layer*>(layer)) type = 5;
66 else if (dynamic_cast<CWhite16x16Layer*>(layer)) type = 6;
68 f.serial(type);
69 if (type != 0)
70 layer->serial(f);
71 else if (layer != NULL)
72 nlwarning("Unknown 16x16 layer type %s, aborted", typeid(*layer).name());
77 * Compresses a 16x16Layer. Returns a new layer if compression was successful, otherwise returns same layer.
78 * If compression was successful, previous layer is deleted.
80 I16x16Layer *I16x16Layer::compress(I16x16Layer *layer, sint32 blank)
82 CFull16x16Layer *flayer = dynamic_cast<CFull16x16Layer*>(layer);
83 if (flayer == NULL)
85 nlwarning("Can't compressed layer, already compressed");
86 return layer;
89 sint32 min = 0x7fffffff, max = 0x80000000;
90 uint i, j;
92 map<sint32, uint> count;
94 for (i=0; i<16; ++i) for (j=0;j<16;++j)
96 sint32 val = flayer->Array[i][j];
98 if (val == blank)
99 continue;
101 if (val < min) min = val;
102 if (val > max) max = val;
104 map<sint32, uint>::iterator it = count.find(val);
105 if (it == count.end())
106 count.insert(std::pair<sint32, uint>(val, 1));
107 else
108 ++((*it).second);
111 uint msize = (uint)count.size();
113 if (msize == 1)
115 // white 16x16 layer
116 CWhite16x16Layer *nlayer = new CWhite16x16Layer();
117 nlayer->set(0, 0, min);
118 delete layer;
119 return nlayer;
121 else if (msize == 2)
123 // 1 bit 16x16 layer, 2 values
124 C1Bit16x16Layer *nlayer = new C1Bit16x16Layer();
125 nlayer->Values[0] = min;
126 nlayer->Values[1] = max;
127 for (i=0; i<16; ++i)
128 for (j=0; j<16; ++j)
129 nlayer->set(i, j, flayer->get(i, j));
131 compare(layer, nlayer, 0x7fffffff);
132 delete layer;
133 return nlayer;
135 else if (msize <= 4)
137 // 2 bits 16x16 layer, 4 values
138 C2Bits16x16Layer *nlayer = new C2Bits16x16Layer();
139 map<sint32, uint>::iterator it;
140 i=0;
141 for (it=count.begin(); it!=count.end(); ++it)
142 nlayer->Values[i++] = (*it).first;
143 for (i=0; i<16; ++i)
144 for (j=0; j<16; ++j)
145 nlayer->set(i, j, flayer->get(i, j));
147 compare(layer, nlayer, 0x7fffffff);
148 delete layer;
149 return nlayer;
151 else if (max-min < 16)
153 // 4 bits 16x16 layer, 16 values in range
154 C4Bits16x16Layer *nlayer = new C4Bits16x16Layer();
155 nlayer->Mean = min;
156 for (i=0; i<16; ++i)
157 for (j=0; j<16; ++j)
158 nlayer->set(i, j, flayer->get(i, j));
160 compare(layer, nlayer, 0x7fffffff);
161 delete layer;
162 return nlayer;
164 else if (max-min < 256)
166 // 8 bits 16x16 layer, 256 values in range
167 C8Bits16x16Layer *nlayer = new C8Bits16x16Layer();
168 nlayer->Mean = min;
169 for (i=0; i<16; ++i)
170 for (j=0; j<16; ++j)
171 nlayer->set(i, j, flayer->get(i, j));
173 compare(layer, nlayer, 0x7fffffff);
174 delete layer;
175 return nlayer;
178 return layer;
181 bool I16x16Layer::compare(I16x16Layer *original, I16x16Layer *copy, sint32 avoid)
183 uint i, j;
184 bool failed = false;
185 for (i=0; i<16; ++i)
187 for (j=0; j<16; ++j)
189 if (original->get(i, j) != avoid && original->get(i, j) != copy->get(i, j))
191 nlwarning("Different values !");
192 failed = true;
197 return failed;