root/trunk/Mask.cpp

Revision 14, 6.6 kB (checked in by sagrer, 4 months ago)

Поковырял код на предмет понять "где что есть". Заодно добавил везде шапку и вбил дополнительно в конфиг проекта те модули, которые вбиты не были - чтобы можно было быстро открыть любой файл через окно менеджера проекта.

Line 
1 ///////////////////////////////////////////////////////////
2 //                        TexGen                         //
3 //          утилита для подготовки текстур рельефа       //
4 //               для игры Проклятые Земли                //
5 //           Copyright (C) 2007-2008 Gipat Group         //
6 //              Распространяется на условиях             //
7 //    Gipat Group's opened EI-editor-utility license     //
8 //                      версии 1.0                       //
9 //                                                       //
10 //                  www.gipatgroup.org                   //
11 ///////////////////////////////////////////////////////////
12
13 //К работе над данным файлом приложили руки, ноги.... короче аффтары:
14 // 1) Снайпер (sniper-rifle@rambler.ru)
15
16 ////////////////////////////////////////////////////////////////////////
17 //---------------------------------------------------------------------------
18 #include <VCL.h>
19
20 #include "Mask.h"
21 //---------------------------------------------------------------------------
22 void CTileMask::LoadMask(AnsiString FN)
23 {
24   if(FileExists(FN))
25   {
26     int h = FileOpen(FN,fmOpenRead);
27     if(h)
28     {
29       Clear();
30       BufLen = FileSeek(h,0,SEEK_END);
31       FileSeek(h,0,SEEK_SET);
32       buf = new byte[BufLen];
33       FileRead(h,buf,BufLen);
34       FileClose(h);
35       //Теперь проверяем файл %)
36       AnsiString Head="**";
37       memcpy(&Head[1],buf,2);      // Заголовок 2 байта - "TM"
38       if(Head == "TM")             // Bce OK, файл нашего типа
39       {
40         byte Version;
41         memcpy(&Version,buf+2,1);
42         //switch - будет потом наверное если надо)))
43         if(Version == MaskVersion) // Версия совпала %)
44         {
45           memcpy(&W,buf+3,4);
46           memcpy(&H,buf+7,4);
47           Uncompress();
48         }
49         else Clear();     // {
50       }                   //   Зачищаем последствия неудачной загрузки
51       else Clear();       // }
52     }
53   }
54 }
55 //---------------------------------------------------------------------------
56 void CTileMask::SaveMask(AnsiString FN)
57 {
58   int h = FileCreate(FN, fmOpenWrite);
59   if(h)
60   {
61     Compress();
62     //Normalize(); // А то мало ли что %) //Маразм =(
63     FileWrite(h,buf,BufLen);
64     FileClose(h);
65   }
66 }
67 //---------------------------------------------------------------------------
68 void CTileMask::GetPoint(int X, int Y, byte *dwDest)
69 {
70   byte A, B, C, D;
71   memcpy(&A,buf+HeadLen+Y*W*3+X*3+0,1);
72   memcpy(&B,buf+HeadLen+Y*W*3+X*3+1,1);
73   memcpy(&C,buf+HeadLen+Y*W*3+X*3+2,1);
74   D = 0;
75   //Считали - теперь формируем А, B, C и D
76   if(A & 0x40)
77   {
78     A -= 0x40;
79     D += 0x01;
80   }
81   if(A & 0x80)
82   {
83     A -= 0x80;
84     D += 0x02;
85   }
86   if(B & 0x40)
87   {
88     B -= 0x40;
89     D += 0x04;
90   }
91   if(B & 0x80)
92   {
93     B -= 0x80;
94     D += 0x08;
95   }
96   if(C & 0x40)
97   {
98     C -= 0x40;
99     D += 0x10;
100   }
101   if(C & 0x80)
102   {
103     C -= 0x80;
104     D += 0x20;
105   }
106   // Заполнили - теперь возвращаем результат
107
108   memcpy(dwDest+0,&A,1);
109   memcpy(dwDest+1,&B,1);
110   memcpy(dwDest+2,&C,1);
111   memcpy(dwDest+3,&D,1);
112   //Готово! %)
113 }
114 //---------------------------------------------------------------------------
115 void CTileMask::SetPoint(int X, int Y, byte *dwSrc)
116 {
117   byte A, B, C, D;
118   memcpy(&A,dwSrc+0,1);
119   memcpy(&B,dwSrc+1,1);
120   memcpy(&C,dwSrc+2,1);
121   memcpy(&D,dwSrc+3,1);
122   //Теперь перегоняем инфу из D в A,B и C.
123   A += (D & 0x01)?0x40:0;
124   A += (D & 0x02)?0x80:0;
125   B += (D & 0x04)?0x40:0;
126   B += (D & 0x08)?0x80:0;
127   C += (D & 0x10)?0x40:0;
128   C += (D & 0x20)?0x80:0;
129   //Перегоняем в буфер %)
130   memcpy(buf+HeadLen+Y*W*3+X*3+0,&A,1);
131   memcpy(buf+HeadLen+Y*W*3+X*3+1,&B,1);
132   memcpy(buf+HeadLen+Y*W*3+X*3+2,&C,1);
133   //Я тут подумал - а фигли я вы@#$!аюсь? Экономлю, понимаешь ли, 1 байт, запутываю код, теряю скорость
134
135   //Ответ прост: комары тут кусают, и спать пора. Вот и фигею помаленьку %)))
136 }
137 //---------------------------------------------------------------------------
138 void CTileMask::NewMask(int szW, int szH, bool F)
139 {
140   AnsiString Header="TM";
141   Clear();
142   W = szW;
143   H = szH;
144   BufLen = HeadLen+W*H*3;
145   buf = new byte[BufLen];
146   memcpy(buf,&Header[1],2);
147   memcpy(buf+2,&MaskVersion,1);
148   memcpy(buf+3,&W,4);
149   memcpy(buf+7,&H,4);
150   if(F)
151   {
152     //А теперь заполняем массив "4х16"
153     byte A=16,B=16,C=16,D=15, *dwTmp = new byte[4];
154     memcpy(dwTmp  , &A, 1);
155     memcpy(dwTmp+1, &B, 1);
156     memcpy(dwTmp+2, &C, 1);
157     memcpy(dwTmp+3, &D, 1);
158     for(int X=0; X<W;X++)
159       for(int Y=0;Y<H;Y++)
160       {
161         SetPoint(X,Y,dwTmp);
162       }
163     Uncompress();
164     //Прошу любить и жаловать %)
165     delete [] dwTmp;
166   }
167 }
168 //---------------------------------------------------------------------------
169 void CTileMask::NormalizeW(int X, int Y)
170 {
171   byte A,B,C,D, *dwTmp=new byte[4];
172   GetPointW(X,Y,dwTmp);
173   A = dwTmp[0];
174   B = dwTmp[1];
175   C = dwTmp[2];
176   D = dwTmp[3];
177   while(A+B+C+D>=63)
178   {
179     if(A>0)A--;
180     if(B>0)B--;
181     if(C>0)C--;
182     if(D>0)D--;
183   }
184   dwTmp[0]=A;
185   dwTmp[1]=B;
186   dwTmp[2]=C;
187   dwTmp[3]=D;
188   SetPointW(X,Y,dwTmp);
189   delete [] dwTmp;
190 }
191 //---------------------------------------------------------------------------
192 void CTileMask::Uncompress()
193 {
194   ClearW();//Потрём данные, если они каким-то чудом остались целы
195   if(BufLen>0)
196   {
197     byte *dwTmp=new byte[4];
198     Buf2Len = W*H*4;
199     WorkData = new byte[Buf2Len];
200     for(int X=0; X<W; X++)
201       for(int Y=0; Y<H; Y++)
202       {
203         GetPoint(X,Y,dwTmp);
204         SetPointW(X,Y,dwTmp);
205       }
206     int A=W,B=H;
207     W=A;H=B;
208     delete [] dwTmp;
209   }
210 }
211 //---------------------------------------------------------------------------
212 void CTileMask::Compress()
213 {
214   int A=W,B=H;
215   Clear();
216   if(Buf2Len>0)
217   {
218     byte *dwTmp=new byte[4];
219     W=A;
220     H=B;
221     NewMask(W,H,false);
222     for(int X=0; X<W; X++)
223       for(int Y=0; Y<H; Y++)
224       {
225         GetPointW(X,Y,dwTmp);
226         SetPoint(X,Y,dwTmp);
227       }
228     delete [] dwTmp;
229   }
230 }
231 //---------------------------------------------------------------------------
232 void CTileMask::GetPointW(int X, int Y, byte *dwDest)
233 {
234   memcpy(dwDest,WorkData+Y*W*4+X*4,4);
235 }
236 //---------------------------------------------------------------------------
237 void CTileMask::SetPointW(int X, int Y, byte *dwSrc)
238 {
239   memcpy(WorkData+Y*W*4+X*4,dwSrc,4);
240 }
241 //---------------------------------------------------------------------------
242 int CTileMask::CheckSumW(int X, int Y)
243 {
244 //Проверяем сумму мощностей материалов в точке, чтобы не было глюков.
245 //Нормальная сумма равна 64.
246   byte *dwTmp=new byte[4];
247   GetPointW(X,Y,dwTmp);
248   int Rez = dwTmp[0]+dwTmp[1]+dwTmp[2]+dwTmp[3];
249   delete [] dwTmp;
250   return Rez;
251 }
Note: See TracBrowser for help on using the browser.