root/trunk/Main.cpp

Revision 18, 16.4 kB (checked in by sagrer, 4 months ago)

Заменил [Main]->TileSetDir? на [Main]->TileSetsDir? в конфиге. Ибо у меня будет так - во избежание несовместимости на уровне конфигов со Снайповским вариантом.

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 //---------------------------------------------------------------------------
19
20 #include <vcl.h>
21 #pragma hdrstop
22
23 #include "Main.h"
24
25 #include "BMP.cpp"
26 #include "Selector.cpp"
27 //---------------------------------------------------------------------------
28 #pragma package(smart_init)
29 #pragma resource "*.dfm"
30
31
32 TG *G;
33 //---------------------------------------------------------------------------
34 __fastcall TG::TG(TComponent* Owner)
35         : TForm(Owner)
36 {
37 }
38 //---------------------------------------------------------------------------
39 void __fastcall TG::mnuExitClick(TObject *Sender)
40 {
41   Close(); //Самая умная кнопка %)
42 }
43 //---------------------------------------------------------------------------
44
45 void __fastcall TG::mnuAboutClick(TObject *Sender)
46 {
47   ShowMessage("TexGen v1.05\r\nТретья переписка %)))\r\nИ ниволнует.");
48 }
49 //---------------------------------------------------------------------------
50
51 void __fastcall TG::btnExitClick(TObject *Sender)
52 {
53   mnuExitClick(NULL);       
54 }
55 //---------------------------------------------------------------------------
56
57
58 void __fastcall TG::btnAllowDenyClick(TObject *Sender)
59 {
60   TFromAllowDeny *F = new TFromAllowDeny(this);
61   F->ShowModal();
62   delete F;
63 }
64 //---------------------------------------------------------------------------
65  //Работа с конфигом
66 void TG::LoadIni(AnsiString Path)
67 {
68   //Загрузим файл в память
69   Config->LoadConfig(Path);
70   InitDirectories(Config);
71 //2. Собстно, - всё. Осталось запустить функцию выбора всех террейнов набора.
72   //Все сделанные в процессе изменения запишем.
73   SaveIni(Path);
74 }
75 //---------------------------------------------------------------------------
76 void TG::RefreshTileSets()
77 {
78   FList->Directory = DList->Directory;
79   SDir = DList->Directory;
80   //Если был предыдущий набор тайлов - надо его отметить
81   AnsiString Tmp = Config->GetValueEx("Main","LastTileSet","");
82   //Заполняем список наборов тайлов
83   TileSets->Items->Clear();
84   for(int i=DList->ItemIndex+1;i<DList->Items->Count;i++)
85   {
86     TileSets->Items->Add(DList->Items->operator [](i));
87     if(Tmp.LowerCase() == DList->Items->operator [](i).LowerCase())
88       TileSets->Text = Tmp;
89   }
90 }
91 //---------------------------------------------------------------------------
92 void TG::ApplyTileLayer(AnsiString Terrain, AnsiString Layer)
93 {
94   //Сдезь ми далжны удолидь фсе тайлы, каторыи ни принодлЕжад слойу Layer
95   //При этом считаем, что список файлов настроен на нужный набор - иначе пипец.
96   AnsiString N,T, Dir=FList->Directory+"\\";//Собстно, вот.
97   bool b;
98   Terrain = Terrain.LowerCase();
99   FList->Refresh();
100   for(int i=1; i<FList->Items->Count; i++)
101   {
102     N = FList->Items->Strings[i].LowerCase();
103     T = GetNext(&N);
104     T = GetNext(&N); //Для верности %)
105     if(T!=Layer) //Считаем, что слои заданы в виде "01" и т.д - регистра нет.
106     {
107       b=false;//Отметим, если мы удалили нужный файл
108       for(int j=0;(j<4)&&(!b);j++)
109       {
110         T = GetNext(&N);
111         if(T == Terrain)
112         {
113           b = true;
114           N = FList->Items->Strings[i].LowerCase();
115           if(FileExists(Dir+N))
116           {
117             //Брутально трём файл, ибо нефиг тут нам мозги пудридь
118             DeleteFile(Dir+N);
119           }
120         }
121       }
122     }
123   }
124 }
125 //---------------------------------------------------------------------------
126 void TG::SaveIni(AnsiString Path)
127 {
128   //ХЗ зачем эта хрень, но наверное для удобства при вызове.
129   Config->SaveConfig(Path);
130 }
131 //---------------------------------------------------------------------------
132 void TG::UpgradeIni(AnsiString P)
133 {
134 }
135 //---------------------------------------------------------------------------
136 //Работа с проектом
137 void TG::LoadProject(AnsiString Path)
138 {
139         CConfigFile *C = new CConfigFile();
140         C->LoadConfig(Path);
141         Name = C->GetValueEx("Main","Name","Project");
142         TileSet = C->GetValueEx("Main","TileSet","Gipat");
143         TileSize = StrToInt(C->GetValueEx("Main","TileSize","64"));
144         TerrList = C->GetValueEx("Terrains","Terr_List","");
145         //Поcле сего многомудрого действа, нужные нам террейны должны быть
146         //воодружены в дерево на главной странице
147        
148         TileList = C->GetValueEx("Last_Build","Tile_List","");
149         delete C;
150 }
151 //---------------------------------------------------------------------------
152 void TG::SaveProject(AnsiString Path)
153 {
154 }
155 //---------------------------------------------------------------------------
156 void TG::BuildTerrains(AnsiString TileSet)
157 {
158   FList->Hint = SDir+"\\"+TileSet;
159   listAllTerrains->Clear();
160   AnsiString Tile, Terr;
161   if(DirectoryExists(FList->Hint))
162   {
163     FList->Directory = FList->Hint;
164     for(int i=0;i<FList->Items->Count;i++)
165     {
166       Tile = FList->Items->Strings[i];     //Вообще, кусок выбирает из списка файлов тайлы
167       if(IsTile(Tile))
168       {
169         GetNext(&Tile);
170         GetNext(&Tile);
171         for(int j=0;j<=3;j++) //Просто чтоб не писать 4 раза подряд одно и то же
172         {
173           Terr = GetNext(&Tile);
174           if(!TerrainInCollection(Terr))
175           {
176             listAllTerrains->Items->Add(Terr);
177           }
178         }
179       }
180     }
181   }
182 }
183 //---------------------------------------------------------------------------
184 bool TG::TileSetExists(AnsiString Terrain)
185 {
186   bool Result = false;
187   for(int i=0;(i<TileSets->Items->Count)&&(!Result);i++)
188   {
189     if(TileSets->Items->operator [](i).LowerCase() == Terrain.LowerCase() )
190       Result = true;
191   }
192   return Result;
193 }
194 //---------------------------------------------------------------------------
195 //Дополнительные окна проекта
196 void TG::WndPermissions()        //Окошко по кнопке "разрешения"
197 {
198 }
199 //---------------------------------------------------------------------------
200 void TG::WndGenerateWTF()        //Окно с выбором, чего же мы будем генерировать
201 {
202 }
203 //---------------------------------------------------------------------------
204 void TG::WndEditOptions()        //Редактор файла проекта, некоторые переменные
205 {
206 }
207 //---------------------------------------------------------------------------
208 void TG::WndAddTerrains()        //Выбираем добавляемые террейны из списка в наборе тайлов
209 {
210 }
211 //---------------------------------------------------------------------------
212 //Спецфункции
213 void TG::CutTextures(AnsiString Name)
214 {
215 }
216 //---------------------------------------------------------------------------
217 void TG::MaskEditor ()
218 {
219 }
220 //---------------------------------------------------------------------------
221 void TG::TestFunction()
222 {
223 }
224 //---------------------------------------------------------------------------
225 //Различные инфошки
226 void TG::WillBe()
227 {
228 }
229 //---------------------------------------------------------------------------
230 void TG::ProgHelp()
231 {
232 }
233 //---------------------------------------------------------------------------
234 /*
235   ---Texgen.ini---
236
237   [Main]
238   IniVer=1.0
239   FirstLoad=1
240   TileSetsDir=...
241   MasksDir=...
242   OutputDir=...
243   LastTileSet=...
244   LastProject=...
245
246   ---*.tpr---
247
248   [Main]
249   Name=...
250   TileSet=...
251   Terrains=...
252   [TilesList]
253   Tile0=...
254   Tile1=...
255   ...
256   TileN=...
257
258 --------------
259 Имя террайна:
260    T_[layer]_Ter_Ter_Ter_Ter_00.bmp
261 */
262
263 void __fastcall TG::FormCreate(TObject *Sender)
264 {
265   //Начинаем нашу работу
266   ProgDir = ExtractFilePath(Application->ExeName);
267   Config = new CConfigFile();
268   LoadIni(ProgDir+"TexGen.ini");
269 }
270 //---------------------------------------------------------------------------
271 AnsiString TG::GetNext(AnsiString *Src, AnsiString Sep)
272 {
273   AnsiString Rez="";
274   if(AnsiPos(Sep,*Src)>0)
275   {
276     Rez = LeftStr(*Src,AnsiPos(Sep,*Src)-1);
277     *Src = RightStr(*Src,Src->Length() - AnsiPos(Sep,*Src));
278   }
279   else
280   {
281     Rez = *Src;
282     *Src = "";
283   }
284   return Rez;
285 }
286 //---------------------------------------------------------------------------
287 bool TG::IsTile(AnsiString Tile)
288 {
289   bool Rez = true;
290   if(GetNext(&Tile).LowerCase() == "t") //Header of name: T_
291   {
292     AnsiString N = GetNext(&Tile);
293     for(int i=1;i<=N.Length();i++)      //Number
294     {
295       if((N.operator [](i)<'0')||(N.operator [](i)>'9'))
296       {
297         Rez = false;
298       }
299     }
300     for(int i=0;(i<4)&&(Rez);i++)       //4 not-null terrain names
301     {
302       N = GetNext(&Tile);
303       if(N=="")Rez=false;
304     }
305     N = GetNext(&Tile,".");
306     for(int i=1;i<=N.Length();i++)      //Number
307     {
308       if((N.operator [](i) <'0')||(N.operator [](i) >'9'))
309       {
310         Rez = false;
311       }
312     }
313     if(Tile=="")Rez=false;                 //.bmp
314   }
315   else
316   {
317     Rez = false;
318   }
319   return Rez;
320 }
321 //---------------------------------------------------------------------------
322
323 void __fastcall TG::PagesChange(TObject *Sender)
324 {
325   RefreshTileSets();
326 }
327 //---------------------------------------------------------------------------
328 //172.17.175.83
329 void __fastcall TG::FormDestroy(TObject *Sender)
330 {
331   delete Config;       
332 }
333 //---------------------------------------------------------------------------
334 bool TG::TerrainInCollection(AnsiString Terrain)
335 {
336   bool Rez=false;
337   Terrain = Terrain.LowerCase();
338   for(int i=0; (i<listAllTerrains->Items->Count)&&(!Rez); i++)
339   {
340     if(listAllTerrains->Items->Strings[i].LowerCase() == Terrain)
341       Rez = true;
342   }
343   return Rez;
344 }
345
346 void __fastcall TG::mnuTestClick(TObject *Sender)
347 {
348   //Tests :)
349 }
350 //---------------------------------------------------------------------------
351
352 void __fastcall TG::TileSetsChange(TObject *Sender)
353 {
354   BuildTerrains(TileSets->Items->Strings[TileSets->ItemIndex]);       
355 }
356 //---------------------------------------------------------------------------
357
358 void __fastcall TG::LayerKeyPress(TObject *Sender, char &Key)
359 {
360   if(Key==13)
361   {
362     //Тут типа надо сохранить слой, и переделать все террейны такого типа :)
363     Layer->Font->Color = 0x000000;
364   }
365 }
366 //---------------------------------------------------------------------------
367
368 void __fastcall TG::LayerChange(TObject *Sender)
369 {
370   //Показываем, что инфа изменена
371   Layer->Font->Color = 0x0000FF;
372   Layer->ShowHint = true;
373   for(int i=0;i<2;i++)
374     if((Layer->Text.c_str()[i] < '0')||(Layer->Text.c_str()[i]>'9'))
375     {
376       Layer->Text = "00";
377     }
378 }
379 //---------------------------------------------------------------------------
380
381 void __fastcall TG::listAllTerrainsClick(TObject *Sender)
382 {
383   //По идее, нужно вывести информацию о выбраном терейне :)
384   AnsiString N="", N1, Dir, TmpLayer, TmpNum, Layers="";
385   bool Found, NotFound;
386   if(listAllTerrains->ItemIndex >= 0)
387   {
388     N = listAllTerrains->Items->Strings[listAllTerrains->ItemIndex];
389     N1 = N+"_"+N+"_"+N+"_"+N;
390     Dir = FList->Directory;
391     if(RightStr(Dir,1)!="\\")Dir+="\\";
392     //Идем по всем слоям, в поисках существующего базового тайла
393     for(int L = 0; L<99; L++)
394     {
395       Found = false;
396       NotFound = false;
397       for(int Ind=0; (Ind<99)&&(!Found)&&(!NotFound); Ind++)
398       {
399         if(FileExists(Dir + "T_"+FormatNumber(L,2)+"_"+N1+"_"+FormatNumber(Ind,2)+".bmp"))
400         {
401           Found = true;
402           Layers += FormatNumber(L,2)+"\r\n";
403         }
404         if((Ind==0)&&(!Found))NotFound = true;
405       }
406     }
407     //Теперь, если найдено больше 1 слоя - предлагаем юзеру выбрать%)
408     if(Layers == "")Layers = "??";
409     if(Layers.Length() > 4)
410     {
411       int Lr = WndSelect("Нусь, и какой слой будем\r\nсчитать родным для этого материала? %)", Layers);
412       Layers = RightStr(Layers,Layers.Length() - Lr*4);
413     }
414     Layers = LeftStr(Layers, 2);
415     //А теперь запишем значение слоя в поле и удалим лишние файлы
416     Layer->Text = Layers;
417     ApplyTileLayer(N,Layers);
418     if(FileExists(Dir+"T_"+Layers+"_"+N1+"_00.bmp"))
419     {
420       //Базовый тайл =)
421       baseTile->Picture->LoadFromFile(Dir+"T_"+Layers+"_"+N1+"_00.bmp");
422       baseTile->Repaint();
423       baseTile->Refresh();
424     }
425     else
426     {
427       Images->GetBitmap(0,baseTile->Picture->Bitmap);
428       baseTile->Repaint();
429       baseTile->Refresh();
430     }
431   }
432 }
433 //---------------------------------------------------------------------------
434 AnsiString TG::FormatNumber(int N, byte Size)
435 {
436   AnsiString Rez=IntToStr(N);
437   for(;Rez.Length() < Size;Rez="0"+Rez);
438   return Rez;
439 }
440 //===========================================================================
441 int  TG::WndSelect(AnsiString Desc, AnsiString Vars)
442 {
443   //Создать новую спрашивалку:
444   TSelectVariant *SelVar;
445   Application->CreateForm(__classid(TSelectVariant), &SelVar);
446   SelVar->FillListEx(Vars);
447   SelVar->Desc->Caption = Desc;
448   SelVar->ShowModal();
449   int Rez = SelVar->Result;
450   return Rez;
451 }
452
453 void __fastcall TG::btnBaseMaskClick(TObject *Sender)
454 {
455   WillBe();       
456 }
457 //---------------------------------------------------------------------------
458 bool TG::AskUser(AnsiString Q)
459 {
460   TSelectVariant *SV=new TSelectVariant(this);
461   SV->Caption = "Быть или не быть?";
462   SV->Desc->Caption = Q;
463   SV->FillListEx("Быть\r\nНе быть\r\n");
464   SV->ShowModal();
465   bool b=(SV->Result==0)||(SV->Result==-1);
466   return b;
467 }
468 //---------------------------------------------------------------------------
469 void TG::InitDirectories(CConfigFile *C)
470 {
471 //1. "Найдём" инормацию по коллекциям тайлов
472   DList->Hint = EnsureDir(C->GetValueEx("Main","TileSetsDir",ProgDir+"Collections\\"),"Collections\\");
473   C->SetValue("Main","TileSetsDir",DList->Hint);
474   DList->Directory = DList->Hint;
475   RefreshTileSets();
476 //2. Директория с масками
477   DList->Hint = EnsureDir(C->GetValueEx("Main","MasksDir",ProgDir+"Masks\\"),"Masks\\");
478   C->SetValue("Main","MasksDir",DList->Hint);
479 //3. Директория для результата генерации
480   DList->Hint = EnsureDir(C->GetValueEx("Main","OutputDir",ProgDir+"Output\\"),"Output\\");
481   C->SetValue("Main","OutputDir",DList->Hint);
482 }
483 //---------------------------------------------------------------------------
484 AnsiString TG::EnsureDir(AnsiString P, AnsiString N)
485 {
486   if(!DirectoryExists(P))
487   {
488     //Не существует нужная нам директория! Алярм! Ахтунг! Паника нах!
489     AnsiString D=LeftStr(P,AnsiPos("\\",P));
490     if(DirectoryExists(D))//Диск существует
491     {
492       //Спросить у юзера разрешения создать цепь директорий
493       if(AskUser("Директория не существует. Создать?\r\n"+P))
494       {
495         if(!CreateDirChain(P))
496         {
497           CreateDirChain(ProgDir+N);
498           P = ProgDir+N;
499         }
500       }
501       else
502       {
503         CreateDirChain(ProgDir+N);
504         P = ProgDir+N;
505       }
506     }
507     else
508     {
509       CreateDirChain(ProgDir+N);
510       P = ProgDir+N;
511     }
512   }
513   return P;
514 }
515 //---------------------------------------------------------------------------
516 bool TG::CreateDirChain(AnsiString Path)
517 {
518   AnsiString Prefix=LeftStr(Path,AnsiPos("\\",Path)), Temp;
519   Path = RightStr(Path, Path.Length() - AnsiPos("\\",Path));
520   if(RightStr(Path,1)!="\\")Path+="\\";
521   bool Normal=true;
522   while((Path!="")&&(Normal))
523   {
524     Temp = LeftStr(Path,AnsiPos("\\",Path)-1);
525     Path = RightStr(Path, Path.Length() - AnsiPos("\\",Path));
526     if(NormalDirName(Temp))
527     {
528       Prefix+=Temp+"\\";
529       if(!DirectoryExists(Prefix))CreateDir(Prefix);
530     }
531     else
532     {
533       Normal=false;
534     }
535   }
536   return Normal;
537 }
538 //--------------------------------------------------------------------------
539 bool TG::NormalDirName(AnsiString Name)
540 {
541   bool b= Name!="";
542   if(b)b=!AnsiContainsStr(Name,"\\");
543   if(b)b=!AnsiContainsStr(Name,"/");
544   if(b)b=!AnsiContainsStr(Name,":");
545   if(b)b=!AnsiContainsStr(Name,"?");
546   if(b)b=!AnsiContainsStr(Name,"*");
547   if(b)b=!AnsiContainsStr(Name,"\"");
548   if(b)b=!AnsiContainsStr(Name,"<");
549   if(b)b=!AnsiContainsStr(Name,">");
550   if(b)b=!AnsiContainsStr(Name,"|");
551   return b;
552 }
Note: See TracBrowser for help on using the browser.