TerrainInterface.cpp 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. // TerrainInterface.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include "WorldEditor.h"
  16. #include "TerrainInterface.h"
  17. #include <Engine/Templates/Stock_CTextureData.h>
  18. #ifdef _DEBUG
  19. #undef new
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. #define RENDERED_BRUSH_SIZE_IN_METERS 32.0f
  25. #define CHANGE_ANGLE_SENSITIVITY (1.0f/1.0f)
  26. #define CHANGE_INDEX_SENSITIVITY (1.0f/16.0f)
  27. #define CHANGE_NORMALIZED_SENSITIVITY (1.0f/100.0f)
  28. #define CHANGE_PREASSURE_SENSITIVITY (1.0f)
  29. #define CHANGE_OFFSET_SENSITIVITY 0.1f
  30. #define CHANGE_STRETCH_SENSITIVITY 1.0f
  31. #define LAYER_START_X 48
  32. #define LAYER_HEIGHT 48
  33. #define LAYER_SPACING_V PIX(4)
  34. #define COL_ODD_LAYERS (RGBToColor(25,25,30)|CT_OPAQUE)
  35. #define COL_EVEN_LAYERS (RGBToColor(40,40,50)|CT_OPAQUE)
  36. COLOR _colSelectedLayerBcg=0x500000FF;
  37. #define COL_SELECTED_LAYER _colSelectedLayerBcg
  38. #define SLIDER_WIDTH 12
  39. #define SLIDER_HOLDER_HEIGHT 32
  40. #define COL_DEFAULT_ITEM (C_YELLOW|CT_OPAQUE)
  41. #define COL_SETTINGS (C_vlBLUE|CT_OPAQUE)
  42. #define COL_SEPARATOR (C_WHITE|CT_OPAQUE)
  43. static FLOAT _fScrollLayers=0;
  44. INDEX _iGenerateForLayer;
  45. Rect _rectInvalid;
  46. CUpdateableRT _udAutoGenerateDistribution;
  47. CChangeableRT _chAutoGenerateDistribution;
  48. CTerrain *_ptrLastEditedTerrain=NULL;
  49. CTerrainEditBrush atebDefaultEditBrushValues[]=
  50. {
  51. {0,1}, {0,2}, {0,4}, {0,6},
  52. {0,8}, {0,12}, {0,16}, {0,24},
  53. {0,32}, {0,40}, {0,52}, {0,63},
  54. {1,1}, {2,2}, {4,4}, {6,6},
  55. {8,8}, {12,12}, {16,16}, {24,24},
  56. {32,32}, {40,40}, {52,52}, {63,63},
  57. {2,4}, {3,6}, {4,8}, {6,12},
  58. {8,16}, {12,24}, {16,32}, {32,63},
  59. };
  60. CTerrainEditBrush atebCustomEditBrushes[CT_BRUSHES];
  61. static CTextureObject _toIcons;
  62. static CDynamicContainer<CTIButton> dcButtons;
  63. void GenerateTerrainBrushTexture( INDEX iBrush, FLOAT fHotSpot, FLOAT fFallOff);
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CTerrainInterface
  66. static CTString _strToolTip;
  67. static void GetToolTipText(void *pTerrainInterface, char *pToolTipText)
  68. {
  69. pToolTipText+= sprintf(pToolTipText, "%s", _strToolTip);
  70. }
  71. CTFileName GetBrushTextureName(INDEX iBrush)
  72. {
  73. CTString strBrushFile;
  74. strBrushFile.PrintF("Textures\\Editor\\TerrainBrush%02d.tex", iBrush);
  75. return strBrushFile;
  76. }
  77. void CTerrainInterface::HideCursor(void)
  78. {
  79. RECT rect;
  80. GetClientRect( &rect);
  81. ClientToScreen( &rect);
  82. ClipCursor(&rect);
  83. while (ShowCursor(FALSE)>=0);
  84. }
  85. void CTerrainInterface::UnhideCursor(void)
  86. {
  87. ClipCursor(NULL);
  88. while (ShowCursor(TRUE)<0);
  89. }
  90. void GetButtonOffset(CTIButton &tib, PIX &pixOffsetX, PIX &pixOffsetY)
  91. {
  92. if(tib.tib_iLayer!=-1)
  93. {
  94. CTerrain *ptrTerrain=GetTerrain();
  95. if( ptrTerrain==NULL) return;
  96. pixOffsetX=LAYER_START_X;
  97. pixOffsetY=(ptrTerrain->tr_atlLayers.Count()-1-tib.tib_iLayer)*LAYER_HEIGHT-_fScrollLayers;
  98. }
  99. }
  100. #define TERRAIN_SURFACE_VER "V002"
  101. void LoadSurface(CTFileName fnSurface)
  102. {
  103. CTerrain *ptrTerrain=GetTerrain();
  104. if( ptrTerrain==NULL) return;
  105. try
  106. {
  107. CTFileStream strmFile;
  108. strmFile.Open_t( fnSurface);
  109. strmFile.ExpectID_t( CChunkID( "TRSF")); // terrain surface
  110. // check version number
  111. if( !( CChunkID(TERRAIN_SURFACE_VER) == strmFile.GetID_t()) )
  112. {
  113. throw( "Invalid version of terrain surface file. Unable to load");
  114. }
  115. INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
  116. for(INDEX iDelLayer=0; iDelLayer<ctLayers-1; iDelLayer++)
  117. {
  118. ptrTerrain->RemoveLayer(0, FALSE);
  119. }
  120. ptrTerrain->tr_atlLayers[0].ResetLayerMask(0xFF);
  121. ctLayers=0;
  122. strmFile>>ctLayers;
  123. for( INDEX iLayer=0; iLayer<ctLayers; iLayer++)
  124. {
  125. CTFileName fnTexture;
  126. strmFile>>fnTexture;
  127. // check if texture exists
  128. if(!FileExists( fnTexture))
  129. {
  130. fnTexture=CTFILENAME("Textures\\Editor\\Default.tex");
  131. }
  132. CTerrainLayer *ptlLayer=&ptrTerrain->tr_atlLayers[0];
  133. if( iLayer!=0)
  134. {
  135. ptlLayer=&ptrTerrain->AddLayer_t(fnTexture, LT_NORMAL, FALSE);
  136. }
  137. else
  138. {
  139. ptlLayer->SetLayerTexture_t(fnTexture);
  140. }
  141. // load surface
  142. strmFile>>ptlLayer->tl_fRotateX;
  143. strmFile>>ptlLayer->tl_fRotateY;
  144. strmFile>>ptlLayer->tl_fStretchX;
  145. strmFile>>ptlLayer->tl_fStretchY;
  146. strmFile>>ptlLayer->tl_fOffsetX;
  147. strmFile>>ptlLayer->tl_fOffsetY;
  148. strmFile>>ptlLayer->tl_bAutoRegenerated;
  149. strmFile>>ptlLayer->tl_fCoverage;
  150. strmFile>>ptlLayer->tl_fCoverageNoise;
  151. strmFile>>ptlLayer->tl_fCoverageRandom;
  152. strmFile>>ptlLayer->tl_bApplyMinAltitude;
  153. strmFile>>ptlLayer->tl_fMinAltitude;
  154. strmFile>>ptlLayer->tl_fMinAltitudeFade;
  155. strmFile>>ptlLayer->tl_fMinAltitudeNoise;
  156. strmFile>>ptlLayer->tl_fMinAltitudeRandom;
  157. strmFile>>ptlLayer->tl_bApplyMaxAltitude;
  158. strmFile>>ptlLayer->tl_fMaxAltitude;
  159. strmFile>>ptlLayer->tl_fMaxAltitudeFade;
  160. strmFile>>ptlLayer->tl_fMaxAltitudeNoise;
  161. strmFile>>ptlLayer->tl_fMaxAltitudeRandom;
  162. strmFile>>ptlLayer->tl_bApplyMinSlope;
  163. strmFile>>ptlLayer->tl_fMinSlope;
  164. strmFile>>ptlLayer->tl_fMinSlopeFade;
  165. strmFile>>ptlLayer->tl_fMinSlopeNoise;
  166. strmFile>>ptlLayer->tl_fMinSlopeRandom;
  167. strmFile>>ptlLayer->tl_bApplyMaxSlope;
  168. strmFile>>ptlLayer->tl_fMaxSlope;
  169. strmFile>>ptlLayer->tl_fMaxSlopeFade;
  170. strmFile>>ptlLayer->tl_fMaxSlopeNoise;
  171. strmFile>>ptlLayer->tl_fMaxSlopeRandom;
  172. strmFile>>ptlLayer->tl_colMultiply;
  173. }
  174. strmFile.Close();
  175. }
  176. catch( char *strError)
  177. {
  178. WarningMessage(strError);
  179. return;
  180. }
  181. GenerateLayerDistribution(-1);
  182. theApp.m_ctTerrainPage.MarkChanged();
  183. ptrTerrain->RefreshTerrain();
  184. }
  185. void SaveSurface(CTFileName fnSurface)
  186. {
  187. CTerrain *ptrTerrain=GetTerrain();
  188. if( ptrTerrain==NULL) return;
  189. try
  190. {
  191. CTFileStream strmFile;
  192. strmFile.Create_t( fnSurface);
  193. strmFile.WriteID_t( CChunkID( "TRSF")); // terrain surface
  194. // write version number
  195. strmFile.WriteID_t(TERRAIN_SURFACE_VER);
  196. INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
  197. strmFile<<ctLayers;
  198. for( INDEX iLayer=0; iLayer<ctLayers; iLayer++)
  199. {
  200. CTerrainLayer *ptlLayer=&ptrTerrain->tr_atlLayers[iLayer];
  201. if(ptlLayer->tl_ptdTexture==NULL) continue;
  202. CTFileName fnTexture=ptlLayer->tl_ptdTexture->GetName();
  203. strmFile<<fnTexture;
  204. // save surface
  205. strmFile<<ptlLayer->tl_fRotateX;
  206. strmFile<<ptlLayer->tl_fRotateY;
  207. strmFile<<ptlLayer->tl_fStretchX;
  208. strmFile<<ptlLayer->tl_fStretchY;
  209. strmFile<<ptlLayer->tl_fOffsetX;
  210. strmFile<<ptlLayer->tl_fOffsetY;
  211. strmFile<<ptlLayer->tl_bAutoRegenerated;
  212. strmFile<<ptlLayer->tl_fCoverage;
  213. strmFile<<ptlLayer->tl_fCoverageNoise;
  214. strmFile<<ptlLayer->tl_fCoverageRandom;
  215. strmFile<<ptlLayer->tl_bApplyMinAltitude;
  216. strmFile<<ptlLayer->tl_fMinAltitude;
  217. strmFile<<ptlLayer->tl_fMinAltitudeFade;
  218. strmFile<<ptlLayer->tl_fMinAltitudeNoise;
  219. strmFile<<ptlLayer->tl_fMinAltitudeRandom;
  220. strmFile<<ptlLayer->tl_bApplyMaxAltitude;
  221. strmFile<<ptlLayer->tl_fMaxAltitude;
  222. strmFile<<ptlLayer->tl_fMaxAltitudeFade;
  223. strmFile<<ptlLayer->tl_fMaxAltitudeNoise;
  224. strmFile<<ptlLayer->tl_fMaxAltitudeRandom;
  225. strmFile<<ptlLayer->tl_bApplyMinSlope;
  226. strmFile<<ptlLayer->tl_fMinSlope;
  227. strmFile<<ptlLayer->tl_fMinSlopeFade;
  228. strmFile<<ptlLayer->tl_fMinSlopeNoise;
  229. strmFile<<ptlLayer->tl_fMinSlopeRandom;
  230. strmFile<<ptlLayer->tl_bApplyMaxSlope;
  231. strmFile<<ptlLayer->tl_fMaxSlope;
  232. strmFile<<ptlLayer->tl_fMaxSlopeFade;
  233. strmFile<<ptlLayer->tl_fMaxSlopeNoise;
  234. strmFile<<ptlLayer->tl_fMaxSlopeRandom;
  235. strmFile<<ptlLayer->tl_colMultiply;
  236. }
  237. strmFile.Close();
  238. }
  239. catch( char *strError)
  240. {
  241. WarningMessage(strError);
  242. return;
  243. }
  244. }
  245. void PointToIconSpace(CPoint &pt, CTIButton *ptib)
  246. {
  247. PIX pixOffsetX=0;
  248. PIX pixOffsetY=0;
  249. GetButtonOffset(*ptib, pixOffsetX, pixOffsetY);
  250. PIX x=ptib->tib_fx+pixOffsetX;
  251. PIX y=ptib->tib_fy+pixOffsetY;
  252. pt.x=Clamp(pt.x-x, INDEX(0), INDEX(ptib->tib_fdx));
  253. pt.y=Clamp(pt.y-y, INDEX(0), INDEX(ptib->tib_fdy));
  254. }
  255. void PointToScreenSpace(CPoint &pt, CDrawPort *pdp)
  256. {
  257. HWND hWnd=pdp->dp_Raster->ra_pvpViewPort->vp_hWnd;
  258. ClientToScreen(hWnd, &pt);
  259. }
  260. PIXaabbox2D GetButtonScreenBox(CTIButton &tib)
  261. {
  262. PIX pixOffsetX=0;
  263. PIX pixOffsetY=0;
  264. GetButtonOffset(tib, pixOffsetX, pixOffsetY);
  265. PIX x=tib.tib_fx+pixOffsetX;
  266. PIX y=tib.tib_fy+pixOffsetY;
  267. PIX dx=tib.tib_fdx;
  268. PIX dy=tib.tib_fdy;
  269. PIXaabbox2D boxScreen=PIXaabbox2D( PIX2D(x,y), PIX2D(x+dx, y+dy));
  270. return boxScreen;
  271. }
  272. void GenerateDefaultBrush(INDEX iBrush)
  273. {
  274. atebCustomEditBrushes[iBrush].teb_fHotSpot=atebDefaultEditBrushValues[iBrush].teb_fHotSpot;
  275. atebCustomEditBrushes[iBrush].teb_fFallOff=atebDefaultEditBrushValues[iBrush].teb_fFallOff;
  276. GenerateTerrainBrushTexture( iBrush,
  277. atebCustomEditBrushes[iBrush].teb_fHotSpot-0.1f, atebCustomEditBrushes[iBrush].teb_fFallOff-0.1f);
  278. }
  279. void SetDefaultEditBrushes(void)
  280. {
  281. for(INDEX iBrush=0; iBrush<CT_BRUSHES; iBrush++)
  282. {
  283. GenerateDefaultBrush(iBrush);
  284. }
  285. }
  286. void GenerateNonExistingTerrainEditBrushes(void)
  287. {
  288. for(INDEX iBrush=0; iBrush<CT_BRUSHES; iBrush++)
  289. {
  290. // copy default values as custom ones
  291. atebCustomEditBrushes[iBrush].teb_fHotSpot=atebDefaultEditBrushValues[iBrush].teb_fHotSpot;
  292. atebCustomEditBrushes[iBrush].teb_fFallOff=atebDefaultEditBrushValues[iBrush].teb_fFallOff;
  293. CTFileName fnBrush=GetBrushTextureName(iBrush);
  294. if(!FileExists(fnBrush))
  295. {
  296. GenerateDefaultBrush(iBrush);
  297. }
  298. else
  299. {
  300. // precache existing brushes
  301. try
  302. {
  303. _pTextureStock->Obtain_t(fnBrush);
  304. }
  305. catch(char *strError)
  306. {
  307. (void) strError;
  308. }
  309. }
  310. }
  311. }
  312. CTerrainInterface::CTerrainInterface()
  313. {
  314. m_pDrawPort = NULL;
  315. m_pViewPort = NULL;
  316. _fScrollLayers=0;
  317. _udAutoGenerateDistribution.MarkUpdated();
  318. }
  319. CTerrainInterface::~CTerrainInterface()
  320. {
  321. }
  322. BEGIN_MESSAGE_MAP(CTerrainInterface, CWnd)
  323. //{{AFX_MSG_MAP(CTerrainInterface)
  324. ON_WM_PAINT()
  325. ON_WM_DESTROY()
  326. ON_WM_LBUTTONDOWN()
  327. ON_WM_MOUSEMOVE()
  328. ON_WM_LBUTTONUP()
  329. ON_WM_RBUTTONDOWN()
  330. ON_WM_RBUTTONUP()
  331. ON_WM_LBUTTONDBLCLK()
  332. ON_WM_DROPFILES()
  333. ON_WM_CREATE()
  334. //}}AFX_MSG_MAP
  335. END_MESSAGE_MAP()
  336. /////////////////////////////////////////////////////////////////////////////
  337. // CTerrainInterface message handlers
  338. void CTerrainInterface::OnPaint()
  339. {
  340. #if ALLOW_TERRAINS
  341. {
  342. CPaintDC dc(this);
  343. }
  344. if( (m_pViewPort == NULL) && (m_pDrawPort == NULL) )
  345. {
  346. // initialize canvas for active texture button
  347. _pGfx->CreateWindowCanvas( m_hWnd, &m_pViewPort, &m_pDrawPort);
  348. }
  349. // if there is a valid drawport, and the drawport can be locked
  350. if( (m_pDrawPort != NULL) && (m_pDrawPort->Lock()) )
  351. {
  352. if(dcButtons.Count()==0 || GetTerrain()!=_ptrLastEditedTerrain)
  353. {
  354. InitializeInterface(m_pDrawPort);
  355. _ptrLastEditedTerrain=GetTerrain();
  356. }
  357. PIXaabbox2D rectPict;
  358. rectPict = PIXaabbox2D( PIX2D(0, 0),
  359. PIX2D(m_pDrawPort->GetWidth(), m_pDrawPort->GetHeight()));
  360. // clear texture area to black
  361. m_pDrawPort->Fill( C_BLACK | CT_OPAQUE);
  362. // erase z-buffer
  363. m_pDrawPort->FillZBuffer(ZBUF_BACK);
  364. RenderInterface(m_pDrawPort);
  365. // unlock the drawport
  366. m_pDrawPort->Unlock();
  367. if (m_pViewPort!=NULL)
  368. {
  369. m_pViewPort->SwapBuffers();
  370. }
  371. }
  372. #endif
  373. }
  374. void CTerrainInterface::RenderInterface(CDrawPort *pdp)
  375. {
  376. #if ALLOW_TERRAINS
  377. // render terrain interface buttons
  378. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  379. {
  380. CTIButton &tib=*ittib;
  381. PIX pixOffsetX=0;
  382. PIX pixOffsetY=0;
  383. GetButtonOffset(tib, pixOffsetX, pixOffsetY);
  384. if( tib.tib_pPreRender!=NULL) tib.tib_pPreRender(&tib, pdp);
  385. PIX x=tib.tib_fx+pixOffsetX;
  386. PIX y=tib.tib_fy+pixOffsetY;
  387. PIX dx=tib.tib_fdx;
  388. PIX dy=tib.tib_fdy;
  389. // bcg icon fill
  390. if( tib.tib_colFill&0xFF)
  391. {
  392. if(pdp->Lock())
  393. {
  394. pdp->Fill(x,y,dx,dy, tib.tib_colFill);
  395. pdp->Unlock();
  396. }
  397. }
  398. // icon texture
  399. if( tib.tib_iIcon!=-1)
  400. {
  401. PIXaabbox2D boxScreen=PIXaabbox2D( PIX2D(x,y), PIX2D(x+dx, y+dy));
  402. MEXaabbox2D boxTexture=MEXaabbox2D( MEX2D(16*tib.tib_iIcon,0), MEX2D(16*tib.tib_iIcon+16,16));
  403. COLOR colMultiply=C_WHITE|CT_OPAQUE;
  404. if(tib.tib_pIsEnabled!=NULL && !tib.tib_pIsEnabled(&tib))
  405. {
  406. colMultiply=C_dGRAY|CT_OPAQUE;
  407. }
  408. pdp->PutTexture( &_toIcons, boxScreen, boxTexture, colMultiply);
  409. }
  410. // custom render
  411. if(tib.tib_pOnRender!=NULL) tib.tib_pOnRender(&tib, pdp);
  412. // icon border
  413. if( tib.tib_colBorderColor&0xFF)
  414. {
  415. if(pdp->Lock())
  416. {
  417. pdp->DrawBorder(x,y,dx,dy, tib.tib_colBorderColor);
  418. pdp->Unlock();
  419. }
  420. }
  421. }
  422. #endif
  423. }
  424. PIXaabbox2D GetLayersBox(CDrawPort *pdp)
  425. {
  426. return PIXaabbox2D( PIX2D(LAYER_START_X,0), PIX2D(pdp->GetWidth()-LAYER_START_X, pdp->GetHeight()));
  427. }
  428. PIX2D GetLayerSize(CDrawPort *pdp)
  429. {
  430. return PIX2D(pdp->GetWidth()-LAYER_START_X, LAYER_HEIGHT);
  431. }
  432. void CTerrainInterface::OnDestroy()
  433. {
  434. CWnd::OnDestroy();
  435. if( m_pViewPort != NULL)
  436. {
  437. _pGfx->DestroyWindowCanvas( m_pViewPort);
  438. m_pViewPort = NULL;
  439. }
  440. m_pViewPort = NULL;
  441. m_pDrawPort = NULL;
  442. }
  443. void GenerateTerrainBrushTexture( INDEX iBrush, FLOAT fHotSpot, FLOAT fFallOff)
  444. {
  445. #if ALLOW_TERRAINS
  446. INDEX iLog2=INDEX(ceil(Log2(fFallOff*2+2)));
  447. PIX pixSize=1UL<<(iLog2+1);
  448. FLOAT fcx=pixSize/2.0f;
  449. FLOAT fcy=pixSize/2.0f;
  450. CImageInfo ii;
  451. ii.ii_Width=pixSize;
  452. ii.ii_Height=pixSize;
  453. ii.ii_BitsPerPixel=32;
  454. ii.ii_Picture=(UBYTE*) AllocMemory(ii.ii_Width*ii.ii_Height*ii.ii_BitsPerPixel/8);
  455. COLOR *pcol=(COLOR *)ii.ii_Picture;
  456. for(INDEX iy=0; iy<ii.ii_Height; iy++)
  457. {
  458. for(INDEX ix=0; ix<ii.ii_Width; ix++)
  459. {
  460. FLOAT fDist=sqrt((fcx-ix)*(fcx-ix)+(fcy-iy)*(fcy-iy));
  461. FLOAT fcolPower=1.0f;
  462. if(fDist>fFallOff) fcolPower=0.0f;
  463. else if(fDist>fHotSpot)
  464. {
  465. fcolPower=CalculateRatio(fDist, fHotSpot, fFallOff, 0.0f, 1.0f);
  466. fcolPower=1.0f-(1.0f-fcolPower)*(1.0f-fcolPower);
  467. }
  468. UBYTE ubCol=fcolPower*255.0f;
  469. COLOR col=RGBToColor(ubCol,ubCol,ubCol)|CT_OPAQUE;
  470. *pcol=ByteSwap(col);
  471. pcol++;
  472. }
  473. }
  474. CTextureData tdBrush;
  475. try
  476. {
  477. tdBrush.Create_t( &ii, pixSize, 16, TRUE);
  478. CTString strBrushFile;
  479. strBrushFile.PrintF("Textures\\Editor\\TerrainBrush%02d.tex", iBrush);
  480. tdBrush.Save_t( strBrushFile);
  481. tdBrush.Reload();
  482. }
  483. catch( char *strError)
  484. {
  485. (void) strError;
  486. WarningMessage("Unable to create terrain brush texture!");
  487. }
  488. #endif
  489. }
  490. CTIButton::CTIButton()
  491. {
  492. tib_fx=0.0f;
  493. tib_fy=0.0f;
  494. tib_fdx=0.0f;
  495. tib_fdy=0.0f;
  496. tib_iIcon=-1;
  497. tib_colBorderColor=0;
  498. tib_fDataMin=0.0f;
  499. tib_fDataMax=0.0f;
  500. tib_bWrapData=TRUE;
  501. tib_fDataDelta=0.0f;
  502. tib_pfData1=NULL;
  503. tib_pfData2=NULL;
  504. tib_iLayer=-1;
  505. tib_strToolTip="Unknown tool tip";
  506. tib_pPreRender=NULL;
  507. tib_pOnRender=NULL;
  508. tib_pOnLeftClick=NULL;
  509. tib_pOnLeftClickMove=NULL;
  510. tib_pOnRightClick=NULL;
  511. tib_pOnRightClickMove=NULL;
  512. tib_pOnDropFiles=NULL;
  513. tib_pGetClickMoveData=NULL;
  514. tib_pIsEnabled=NULL;
  515. tib_bMouseTrapForMove=TRUE;
  516. tib_bContinueTesting=FALSE;
  517. }
  518. CTIButton *AddButton(CDynamicContainer<CTIButton> &dc, FLOAT x, FLOAT y, FLOAT dx, FLOAT dy, INDEX iLayer, INDEX iIcon,
  519. CTString strToolTip, COLOR colBorder=C_RED|CT_TRANSPARENT, COLOR colFill=C_BLACK|CT_TRANSPARENT)
  520. {
  521. CTIButton &tib=*(new CTIButton);
  522. tib.tib_fx=x;
  523. tib.tib_fy=y;
  524. tib.tib_fdx=dx;
  525. tib.tib_fdy=dy;
  526. tib.tib_iLayer=iLayer;
  527. tib.tib_iIcon=iIcon;
  528. tib.tib_strToolTip=strToolTip;
  529. tib.tib_colBorderColor=colBorder;
  530. tib.tib_colFill=colFill;
  531. dc.Add(&tib);
  532. return &tib;
  533. }
  534. void CTIButton::SetData( FLOAT fDataMin, FLOAT fDataMax, FLOAT fDataDelta, BOOL bWrap/*=FALSE*/, FLOAT *pfData1/*=NULL*/, FLOAT *pfData2/*=NULL*/)
  535. {
  536. tib_fDataMin=fDataMin;
  537. tib_fDataMax=fDataMax;
  538. tib_fDataDelta=fDataDelta;
  539. tib_bWrapData=bWrap;
  540. tib_pfData1=pfData1;
  541. tib_pfData2=pfData2;
  542. }
  543. void CTIButton::SetFunctions(
  544. void (*pOnRender)(CTIButton *ptib, CDrawPort *pdp)/*=NULL*/,
  545. void (*pOnLeftClick)(CTIButton *ptib, CPoint pt, CDrawPort *pdp)/*=NULL*/,
  546. void (*pOnLeftClickMove)(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)/*=NULL*/,
  547. void (*pOnRightClick)(CTIButton *ptib, CPoint pt, CDrawPort *pdp)/*=NULL*/,
  548. void (*pOnRightClickMove)(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)/*=NULL*/,
  549. void (*pPreRender)(CTIButton *ptib, CDrawPort *pdp)/*=NULL*/)
  550. {
  551. tib_pOnRender=pOnRender;
  552. tib_pOnLeftClick=pOnLeftClick;
  553. tib_pOnLeftClickMove=pOnLeftClickMove;
  554. tib_pOnRightClick=pOnRightClick;
  555. tib_pOnRightClickMove=pOnRightClickMove;
  556. tib_pPreRender=pPreRender;
  557. }
  558. void RenderBrushNo(CTIButton *ptib, CDrawPort *pdp)
  559. {
  560. pdp->SetFont( _pfdConsoleFont);
  561. pdp->SetTextAspect( 1.0f);
  562. pdp->SetTextScaling( 1.0f);
  563. CTString strText;
  564. strText.PrintF("%d", INDEX(theApp.m_fCurrentTerrainBrush));
  565. pdp->PutTextC( strText, ptib->tib_fx+ptib->tib_fdx/2, ptib->tib_fy+4, C_YELLOW|CT_OPAQUE);
  566. }
  567. void RenderBrushShape( INDEX iBrush, PIXaabbox2D rect, CDrawPort *pdp)
  568. {
  569. CDrawPort dpBrush=CDrawPort(pdp, rect);
  570. CTextureObject to;
  571. CTString strBrushFile;
  572. strBrushFile.PrintF("Textures\\Editor\\TerrainBrush%02d.tex", iBrush);
  573. try
  574. {
  575. to.SetData_t(strBrushFile);
  576. CTextureData *ptd=(CTextureData *)to.GetData();
  577. if( dpBrush.Lock())
  578. {
  579. dpBrush.Fill(C_BLACK|CT_OPAQUE);
  580. PIX pixTexW=ptd->GetPixWidth();
  581. PIX pixTexH=ptd->GetPixHeight();
  582. FLOAT fScreenW=dpBrush.GetWidth()*pixTexW/RENDERED_BRUSH_SIZE_IN_METERS;
  583. FLOAT fScreenH=dpBrush.GetHeight()*pixTexH/RENDERED_BRUSH_SIZE_IN_METERS;
  584. PIXaabbox2D rectPic;
  585. rectPic = PIXaabbox2D(
  586. PIX2D(dpBrush.GetWidth()/2.0f-fScreenW/2.0f, dpBrush.GetHeight()/2.0f-fScreenH/2.0f),
  587. PIX2D(dpBrush.GetWidth()/2.0f-fScreenW/2.0f+fScreenW, dpBrush.GetHeight()/2.0f-fScreenH/2.0f+fScreenH));
  588. dpBrush.PutTexture( &to, rectPic);
  589. dpBrush.Unlock();
  590. }
  591. }
  592. catch( char *strError)
  593. {
  594. (void) strError;
  595. }
  596. }
  597. void RenderBrushShape(CTIButton *ptib, CDrawPort *pdp)
  598. {
  599. INDEX iBrush=INDEX(theApp.m_fCurrentTerrainBrush);
  600. CTerrainEditBrush &teb=atebCustomEditBrushes[iBrush];
  601. PIXaabbox2D rectButton = PIXaabbox2D(
  602. PIX2D(ptib->tib_fx, ptib->tib_fy),
  603. PIX2D(ptib->tib_fx+ptib->tib_fdx, ptib->tib_fy+ptib->tib_fdy));
  604. RenderBrushShape(iBrush,rectButton,pdp);
  605. }
  606. void RenderBrushPressure(CTIButton *ptib, CDrawPort *pdp)
  607. {
  608. pdp->SetFont( _pfdConsoleFont);
  609. pdp->SetTextAspect( 1.0f);
  610. pdp->SetTextScaling( 1.0f);
  611. CTString strText;
  612. strText.PrintF("%d%%", INDEX(theApp.m_fTerrainBrushPressure/1024.0f*100.0f));
  613. pdp->PutTextC( strText, ptib->tib_fx+ptib->tib_fdx/2, ptib->tib_fy, C_YELLOW|CT_OPAQUE);
  614. }
  615. void RenderLayerTexture(CTIButton *ptib, CDrawPort *pdp)
  616. {
  617. INDEX iLayer=ptib->tib_iLayer;
  618. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  619. if(ptlLayer!=NULL && ptlLayer->tl_ptdTexture!=NULL)
  620. {
  621. CTextureObject to;
  622. to.SetData(ptlLayer->tl_ptdTexture);
  623. PIXaabbox2D boxScreen=GetButtonScreenBox(*ptib);
  624. pdp->PutTexture( &to, boxScreen);
  625. }
  626. }
  627. void RenderLayerBcg(CTIButton *ptib, CDrawPort *pdp)
  628. {
  629. INDEX iLayer=ptib->tib_iLayer;
  630. CTIButton &tib=*ptib;
  631. PIX pixOffsetX=0;
  632. PIX pixOffsetY=0;
  633. GetButtonOffset(tib, pixOffsetX, pixOffsetY);
  634. if( tib.tib_pPreRender!=NULL) tib.tib_pPreRender(&tib, pdp);
  635. PIX x=tib.tib_fx+pixOffsetX;
  636. PIX y=tib.tib_fy+pixOffsetY;
  637. PIX dx=tib.tib_fdx;
  638. PIX dy=tib.tib_fdy;
  639. COLOR colBcg=C_WHITE|CT_OPAQUE;
  640. if( tib.tib_iLayer==GetLayerIndex()) colBcg=COL_SELECTED_LAYER;
  641. else if( iLayer&1) colBcg=COL_ODD_LAYERS;
  642. else colBcg=COL_EVEN_LAYERS;
  643. if(pdp->Lock())
  644. {
  645. pdp->Fill(x,y,dx,dy, colBcg);
  646. pdp->Unlock();
  647. }
  648. }
  649. void RenderLayerMask(CTIButton *ptib, CDrawPort *pdp)
  650. {
  651. INDEX iLayer=ptib->tib_iLayer;
  652. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  653. if(ptlLayer!=NULL && ptlLayer->tl_ptdTexture!=NULL)
  654. {
  655. CTextureObject to;
  656. CTextureData *ptd=ptlLayer->GetThumbnail(64,64);
  657. to.SetData(ptd);
  658. PIXaabbox2D boxScreen=GetButtonScreenBox(*ptib);
  659. pdp->PutTexture( &to, boxScreen);
  660. }
  661. }
  662. void GetBrushModeInfo(INDEX iMode, INDEX &iIcon, CTString &strText)
  663. {
  664. strText="Unknown";
  665. iIcon=0;
  666. switch(INDEX (iMode))
  667. {
  668. case TBM_PAINT:
  669. {
  670. strText="Paint (J)";
  671. if(INDEX(theApp.m_iTerrainEditMode)==TEM_HEIGHTMAP) iIcon=12;
  672. else iIcon=8;
  673. break;
  674. }
  675. case TBM_SMOOTH: strText="Smooth tool (O)"; iIcon=10; break;
  676. case TBM_FILTER: strText="Filter tool (F)"; iIcon=30; break;
  677. case TBM_MINIMUM: strText="Limit down (M)"; iIcon=27; break;
  678. case TBM_MAXIMUM: strText="Limit up (X)"; iIcon=11; break;
  679. case TBM_FLATTEN: strText="Flatten (=)"; iIcon=18; break;
  680. case TBM_POSTERIZE: strText="Posterize (;)"; iIcon=28; break;
  681. case TBM_RND_NOISE: strText="Random noise (K)"; iIcon=21; break;
  682. case TBM_CONTINOUS_NOISE: strText="Texture noise (Y)"; iIcon=31; break;
  683. case TBM_ERASE: strText="Erase (D)"; iIcon=9; break;
  684. }
  685. }
  686. void UpdateEditModeIcon(CTIButton *ptib, CDrawPort *pdp)
  687. {
  688. if(INDEX(theApp.m_iTerrainEditMode)==TEM_HEIGHTMAP) ptib->tib_iIcon=20;
  689. else ptib->tib_iIcon=19;
  690. }
  691. void UpdateBrushModeIcon(CTIButton *ptib, CDrawPort *pdp)
  692. {
  693. INDEX iIcon;
  694. CTString strText;
  695. GetBrushModeInfo(INDEX(theApp.m_iTerrainBrushMode), iIcon, strText);
  696. ptib->tib_iIcon=iIcon;
  697. }
  698. void UpdateLayerVisibleFlag(CTIButton *ptib, CDrawPort *pdp)
  699. {
  700. INDEX iLayer=ptib->tib_iLayer;
  701. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  702. if(ptlLayer!=NULL)
  703. {
  704. if( ptlLayer->tl_bVisible) ptib->tib_iIcon=3;
  705. else ptib->tib_iIcon=4;
  706. }
  707. }
  708. void UpdatePressure(CTIButton *ptib, CDrawPort *pdp)
  709. {
  710. if(theApp.m_fTerrainBrushPressureEnum>=0)
  711. {
  712. theApp.m_fTerrainBrushPressure=(theApp.m_fTerrainBrushPressureEnum+1)/10.0f*1024.0f+1;
  713. theApp.m_fTerrainBrushPressureEnum=-1;
  714. }
  715. }
  716. void SetAsActiveLayer(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  717. {
  718. SelectLayer(ptib->tib_iLayer);
  719. CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
  720. if(pDoc!=NULL)
  721. {
  722. pDoc->m_chSelections.MarkChanged();
  723. }
  724. }
  725. void ApplyLayerCommand(INDEX iSelectedItem)
  726. {
  727. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  728. CTerrain *ptrTerrain=GetTerrain();
  729. if( ptrTerrain==NULL) return;
  730. CTerrainLayer *ptlLayer=GetLayer();
  731. INDEX iLayer=GetLayerIndex();
  732. if(ptlLayer!=NULL)
  733. {
  734. switch( iSelectedItem)
  735. {
  736. case 0: // "Delete layer"
  737. {
  738. if(ptrTerrain->tr_atlLayers.Count()>1)
  739. {
  740. if( ::MessageBoxA( pMainFrame->m_hWnd, "Are you sure that you want to delete this layer?",
  741. "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1| MB_SYSTEMMODAL | MB_TOPMOST) == IDYES)
  742. {
  743. ptrTerrain->RemoveLayer(iLayer);
  744. if(GetLayerIndex()>=ptrTerrain->tr_atlLayers.Count())
  745. {
  746. SelectLayer(ptrTerrain->tr_atlLayers.Count()-1);
  747. }
  748. }
  749. }
  750. break;
  751. }
  752. case 1: // "Insert texture layer"
  753. {
  754. try
  755. {
  756. ptrTerrain->AddLayer_t( CTFILENAME("Textures\\Editor\\Default.tex"));
  757. SelectLayer( ptrTerrain->tr_atlLayers.Count()-1);
  758. }
  759. catch(char *strError)
  760. {
  761. WarningMessage("Unable to obtain default texture for new texture layer!\nError: %s", strError);
  762. }
  763. break;
  764. }
  765. case 4: // "Insert tile layer"
  766. {
  767. try
  768. {
  769. ptrTerrain->AddLayer_t( CTFILENAME("Textures\\Editor\\Default.tex"), LT_TILE);
  770. SelectLayer( ptrTerrain->tr_atlLayers.Count()-1);
  771. }
  772. catch(char *strError)
  773. {
  774. WarningMessage("Unable to obtain default texture for new tile layer!\nError: %s", strError);
  775. }
  776. break;
  777. }
  778. case 2: // "Move up"
  779. {
  780. if(iLayer<ptrTerrain->tr_atlLayers.Count()-1)
  781. {
  782. ptrTerrain->SetLayerIndex( iLayer, iLayer+1);
  783. SelectLayer(iLayer+1);
  784. }
  785. break;
  786. }
  787. case 3: // "Move down"
  788. {
  789. if(iLayer>0)
  790. {
  791. ptrTerrain->SetLayerIndex( iLayer, iLayer-1);
  792. SelectLayer(iLayer-1);
  793. }
  794. break;
  795. }
  796. }
  797. }
  798. theApp.m_ctTerrainPage.MarkChanged();
  799. }
  800. void DisplayLayerTexture(INDEX iLayer)
  801. {
  802. CWndDisplayTexture *pDisplay=new CWndDisplayTexture;
  803. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  804. if(ptlLayer!=NULL && ptlLayer->tl_ptdTexture!=NULL)
  805. {
  806. POINT pt;
  807. GetCursorPos(&pt);
  808. CTString strText1=ptlLayer->tl_ptdTexture->GetName();
  809. CTString strText2=ptlLayer->tl_ptdTexture->GetDescription();
  810. pDisplay->Initialize(pt.x, pt.y, ptlLayer->tl_ptdTexture, strText1, strText2);
  811. }
  812. }
  813. void ApplyLayerTextureCommand(INDEX iSelectedItem)
  814. {
  815. CTerrain *ptrTerrain=GetTerrain();
  816. if( ptrTerrain==NULL) return;
  817. CTerrainLayer *ptlLayer=GetLayer();
  818. INDEX iLayer=GetLayerIndex();
  819. if(ptlLayer!=NULL)
  820. {
  821. switch( iSelectedItem)
  822. {
  823. case 0: // "Create izohipse textutre"
  824. {
  825. CTFileName fnGradient=_EngineGUI.FileRequester(
  826. "Select izohipse gradient", FILTER_TEX FILTER_ALL FILTER_END,
  827. "Texture directory", "Textures\\");
  828. if( fnGradient=="") return;
  829. CTextureData *ptdGradient;
  830. try
  831. {
  832. ptdGradient=_pTextureStock->Obtain_t( fnGradient);
  833. ptdGradient->Force(TEX_STATIC|TEX_CONSTANT);
  834. }
  835. catch( char *strError)
  836. {
  837. (void) strError;
  838. WarningMessage("Unable to obtain izohipse gradient texture!");
  839. return;
  840. }
  841. CTFileName fnIzohipseTexture=_EngineGUI.FileRequester(
  842. "Choose name for izohipse texture", FILTER_TEX FILTER_ALL FILTER_END,
  843. "Texture directory", "Textures\\");
  844. if( fnIzohipseTexture=="") return;
  845. INDEX iHMWidth=ptrTerrain->tr_pixHeightMapWidth;
  846. INDEX iHMHeight=ptrTerrain->tr_pixHeightMapHeight;
  847. CImageInfo ii;
  848. ii.ii_Width=iHMWidth-1;
  849. ii.ii_Height=iHMHeight-1;
  850. ii.ii_BitsPerPixel=32;
  851. ii.ii_Picture=(UBYTE*) AllocMemory(ii.ii_Width*ii.ii_Height*ii.ii_BitsPerPixel/8);
  852. COLOR *pcol=(COLOR *)ii.ii_Picture;
  853. INDEX iGradientHeight=ptdGradient->GetPixHeight();
  854. UWORD *puw=ptrTerrain->tr_auwHeightMap;
  855. if(puw==NULL) return;
  856. for( INDEX iy=0; iy<ii.ii_Height; iy++)
  857. {
  858. for( INDEX ix=0; ix<ii.ii_Width; ix++)
  859. {
  860. UWORD uwHeight=*(puw+iy*iHMWidth+ix);
  861. FLOAT fHeightRatio=uwHeight/65535.0f;
  862. INDEX iGradPix1=iGradientHeight*fHeightRatio;
  863. INDEX iGradPix2=ClampUp(iGradPix1+1,iGradientHeight-1);
  864. COLOR colPix1=ptdGradient->GetTexel(0,iGradPix1);
  865. COLOR colPix2=ptdGradient->GetTexel(0,iGradPix2);
  866. FLOAT fLerpFactor=iGradientHeight*fHeightRatio-INDEX(iGradientHeight*fHeightRatio);
  867. COLOR colResult=LerpColor(colPix1,colPix2,fLerpFactor);
  868. *(pcol+iy*ii.ii_Width+ix)=ByteSwap(colResult);
  869. }
  870. }
  871. _pTextureStock->Release(ptdGradient);
  872. CTextureData tdIzohipse;
  873. try
  874. {
  875. tdIzohipse.Create_t( &ii, 1024, 16, TRUE);
  876. tdIzohipse.Save_t( fnIzohipseTexture);
  877. ptlLayer->SetLayerTexture_t(fnIzohipseTexture);
  878. ptlLayer->tl_fStretchX=1.0f/ptrTerrain->tr_vTerrainSize(1);
  879. ptlLayer->tl_fStretchY=1.0f/ptrTerrain->tr_vTerrainSize(2);
  880. }
  881. catch( char *strError)
  882. {
  883. (void) strError;
  884. WarningMessage("Unable to save izohipse texture!");
  885. return;
  886. }
  887. ptrTerrain->RefreshTerrain();
  888. theApp.m_ctTerrainPage.MarkChanged();
  889. break;
  890. }
  891. case 1: // "Browse texture"
  892. {
  893. CTFileName fnTexture=_EngineGUI.FileRequester(
  894. "Browse texture", FILTER_TEX FILTER_ALL FILTER_END,
  895. "Texture directory", "Textures\\");
  896. if( fnTexture=="") return;
  897. try
  898. {
  899. ptlLayer->SetLayerTexture_t(fnTexture);
  900. theApp.m_ctTerrainPageCanvas.MarkChanged();
  901. ptrTerrain->RefreshTerrain();
  902. }
  903. catch(char *strError)
  904. {
  905. (void) strError;
  906. }
  907. break;
  908. }
  909. case 2: // "View layer texture"
  910. {
  911. DisplayLayerTexture(iLayer);
  912. }
  913. }
  914. }
  915. }
  916. void DisplayLayerMask(INDEX iLayer)
  917. {
  918. CWndDisplayTexture *pDisplay=new CWndDisplayTexture;
  919. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  920. if(ptlLayer!=NULL && ptlLayer->tl_ptdTexture!=NULL)
  921. {
  922. CTextureData *ptd=ptlLayer->GetThumbnail(ptlLayer->tl_iMaskWidth-1,ptlLayer->tl_iMaskHeight-1);
  923. POINT pt;
  924. GetCursorPos(&pt);
  925. CTString strText1;
  926. strText1.PrintF("%dx%d",ptlLayer->tl_iMaskWidth-1, ptlLayer->tl_iMaskHeight-1);
  927. pDisplay->Initialize(pt.x, pt.y, ptd, strText1);
  928. }
  929. }
  930. void ApplyLayerMaskCommand(INDEX iSelectedItem)
  931. {
  932. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  933. CTerrain *ptrTerrain=GetTerrain();
  934. if( ptrTerrain==NULL) return;
  935. CTerrainLayer *ptlLayer=GetLayer();
  936. INDEX iLayer=GetLayerIndex();
  937. if(ptlLayer!=NULL)
  938. {
  939. switch( iSelectedItem)
  940. {
  941. case 0: // "Fill mask"
  942. {
  943. if( ::MessageBoxA( pMainFrame->m_hWnd, "Are you sure that you want to fill this layer's mask?",
  944. "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1| MB_SYSTEMMODAL | MB_TOPMOST) == IDYES)
  945. {
  946. EditTerrain(NULL, FLOAT3D(0,0,0), 1.0f, TE_FILL_LAYER_MASK);
  947. }
  948. break;
  949. }
  950. case 1: // "Clear mask"
  951. {
  952. if( ::MessageBoxA( pMainFrame->m_hWnd, "Are you sure that you want to clear this layer's mask?",
  953. "Warning !", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1| MB_SYSTEMMODAL | MB_TOPMOST) == IDYES)
  954. {
  955. EditTerrain(NULL, FLOAT3D(0,0,0), 1.0f, TE_CLEAR_LAYER_MASK);
  956. }
  957. break;
  958. }
  959. case 2: // "Import mask"
  960. {
  961. CTFileName fnMaskMap=_EngineGUI.FileRequester(
  962. "Import layer mask", FILTER_TGA FILTER_PCX FILTER_ALL FILTER_END,
  963. "Layer mask directory", "Textures\\");
  964. if( fnMaskMap=="") return;
  965. try
  966. {
  967. ptlLayer->ImportLayerMask_t(fnMaskMap);
  968. ptrTerrain->RefreshTerrain();
  969. pMainFrame->Invalidate(FALSE);
  970. theApp.GetActiveDocument()->SetModifiedFlag( TRUE);
  971. }
  972. catch(char *strError)
  973. {
  974. AfxMessageBox( CString(strError));
  975. }
  976. break;
  977. }
  978. case 3: // "Export mask"
  979. {
  980. CTFileName fnMaskMap=_EngineGUI.FileRequester(
  981. "Export layer mask", FILTER_TGA FILTER_PCX FILTER_ALL FILTER_END,
  982. "Layer mask directory", "Textures\\");
  983. if( fnMaskMap=="") return;
  984. try
  985. {
  986. ptlLayer->ExportLayerMask_t(fnMaskMap);
  987. ptrTerrain->RefreshTerrain();
  988. pMainFrame->Invalidate(FALSE);
  989. }
  990. catch(char *strError)
  991. {
  992. AfxMessageBox( CString(strError));
  993. }
  994. break;
  995. }
  996. case 4: // noise
  997. {
  998. EditTerrain(NULL, FLOAT3D(0,0,0), 1.0f, TE_LAYER_RND_NOISE);
  999. break;
  1000. }
  1001. case 5: // "View mask"
  1002. {
  1003. DisplayLayerMask(iLayer);
  1004. }
  1005. }
  1006. theApp.m_ctTerrainPageCanvas.MarkChanged();
  1007. }
  1008. }
  1009. void PickLayerColor(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1010. {
  1011. INDEX iLayer=ptib->tib_iLayer;
  1012. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1013. if(ptlLayer==NULL) return;
  1014. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  1015. COLORREF colMfc=CLRF_CLR( ptlLayer->tl_colMultiply);
  1016. if( MyChooseColor( colMfc, *pMainFrame))
  1017. {
  1018. ptlLayer->tl_colMultiply=CLR_CLRF( colMfc) | ptlLayer->tl_colMultiply&0x000000FF;
  1019. }
  1020. }
  1021. void NumericAlpha(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1022. {
  1023. INDEX iLayer=ptib->tib_iLayer;
  1024. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1025. if(ptlLayer==NULL) return;
  1026. CDlgNumericAlpha dlgNumericAlpha( ptlLayer->tl_colMultiply&0xFF);
  1027. if( dlgNumericAlpha.DoModal() == IDOK)
  1028. {
  1029. ptlLayer->tl_colMultiply&=0xFFFFFF00;
  1030. ptlLayer->tl_colMultiply|=(dlgNumericAlpha.m_iAlpha&0xFF);
  1031. }
  1032. }
  1033. void InvokeLayerOptions(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1034. {
  1035. INDEX iLayer=ptib->tib_iLayer;
  1036. if(iLayer==-1) return;
  1037. CDlgEditTerrainLayer dlg;
  1038. if( dlg.DoModal()==IDOK)
  1039. {
  1040. GenerateLayerDistribution(iLayer);
  1041. }
  1042. }
  1043. void PickSelectedLayerBcgColor(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1044. {
  1045. PointToScreenSpace(pt, pdp);
  1046. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  1047. pMainFrame->CustomColorPicker( pt.x-50, pt.y);
  1048. COLORREF TmpColor = CLRF_CLR( _colSelectedLayerBcg);
  1049. if( MyChooseColor( TmpColor, *pMainFrame))
  1050. {
  1051. _colSelectedLayerBcg = CLR_CLRF( TmpColor)|CT_OPAQUE;
  1052. }
  1053. theApp.m_ctTerrainPageCanvas.MarkChanged();
  1054. }
  1055. INDEX InsertItemMacro( CCustomComboWnd *pCC, CTString strText, INDEX iIcon=-1, INDEX iValue=-1, COLOR col=COL_DEFAULT_ITEM)
  1056. {
  1057. INDEX iItem;
  1058. if(iIcon!=-1)
  1059. {
  1060. MEXaabbox2D boxIcon=MEXaabbox2D( MEX2D(16*iIcon,0), MEX2D(16*iIcon+16,16));
  1061. DECLARE_CTFILENAME( fnTerrainEditIcons, "Textures\\Editor\\TerrainEditingIcons.tex");
  1062. iItem=pCC->InsertItem( strText, fnTerrainEditIcons, boxIcon);
  1063. }
  1064. else
  1065. {
  1066. iItem=pCC->InsertItem( strText);
  1067. }
  1068. if(iValue!=-1)
  1069. {
  1070. pCC->SetItemValue(iItem, iValue);
  1071. }
  1072. pCC->SetItemColor( iItem, col);
  1073. return iItem;
  1074. }
  1075. void InvokeLayerPopup(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1076. {
  1077. CTerrain *ptrTerrain=GetTerrain();
  1078. if( ptrTerrain==NULL) return;
  1079. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1080. InsertItemMacro( pCombo, "Delete layer", -1, 0);
  1081. InsertItemMacro( pCombo, "Insert texture layer", -1, 1);
  1082. InsertItemMacro( pCombo, "Insert tile layer", -1, 4);
  1083. InsertItemMacro( pCombo, "Move up", -1, 2);
  1084. InsertItemMacro( pCombo, "Move down", -1, 3);
  1085. PointToScreenSpace(pt, pdp);
  1086. pCombo->Initialize(NULL, ApplyLayerCommand, pt.x, pt.y);
  1087. }
  1088. void InvokeLayerTexturePopup(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1089. {
  1090. CTerrain *ptrTerrain=GetTerrain();
  1091. if( ptrTerrain==NULL) return;
  1092. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1093. InsertItemMacro( pCombo, "Create izohipse texture", 22, 0);
  1094. InsertItemMacro( pCombo, "Browse texture", 22, 1);
  1095. InsertItemMacro( pCombo, "View layer texture", 3, 2);
  1096. PointToScreenSpace(pt, pdp);
  1097. pCombo->Initialize(NULL, ApplyLayerTextureCommand, pt.x, pt.y);
  1098. }
  1099. void InvokeLayerMaskPopup(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1100. {
  1101. CTerrain *ptrTerrain=GetTerrain();
  1102. if( ptrTerrain==NULL) return;
  1103. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1104. InsertItemMacro( pCombo, "Fill mask", 17, 0);
  1105. InsertItemMacro( pCombo, "Clear mask", 9, 1);
  1106. InsertItemMacro( pCombo, "Noise", 12, 4);
  1107. InsertItemMacro( pCombo, "--------------",-1,-1);
  1108. InsertItemMacro( pCombo, "Import mask", 22, 2);
  1109. InsertItemMacro( pCombo, "Export mask", 22, 3);
  1110. InsertItemMacro( pCombo, "--------------",-1,-1);
  1111. InsertItemMacro( pCombo, "View mask", 3, 5);
  1112. PointToScreenSpace(pt, pdp);
  1113. pCombo->Initialize(NULL, ApplyLayerMaskCommand, pt.x, pt.y);
  1114. }
  1115. CTString GetStretchInfo(CTIButton *ptib, CPoint pt, CDrawPort *pdp, BOOL bLmb)
  1116. {
  1117. CTString strInfo;
  1118. INDEX iLayer=ptib->tib_iLayer;
  1119. if( iLayer!=-1)
  1120. {
  1121. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1122. CTerrain *ptrTerrain=GetTerrain();
  1123. if(ptlLayer!=NULL && ptrTerrain!=NULL)
  1124. {
  1125. strInfo.PrintF("Texture stretch: %g", ptlLayer->tl_fStretchX);
  1126. return strInfo;
  1127. }
  1128. }
  1129. return strInfo;
  1130. }
  1131. CTString GetEditedData(CTIButton *ptib, CPoint pt, CDrawPort *pdp, BOOL bLmb)
  1132. {
  1133. CTString strInfo;
  1134. if(ptib->tib_pfData1!=NULL) strInfo.PrintF("%f", ptib->tib_pfData1);
  1135. return strInfo;
  1136. }
  1137. void OnDropIntoLayerTexture(CTIButton *ptib, CPoint pt, CDrawPort *pdp, CTFileName fnDropped)
  1138. {
  1139. // if it is not texture, report error
  1140. if( fnDropped.FileExt() != ".tex" )
  1141. {
  1142. AfxMessageBox( L"You can only drop textures here.");
  1143. return;
  1144. }
  1145. INDEX iLayer=ptib->tib_iLayer;
  1146. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1147. CTerrain *ptrTerrain=GetTerrain();
  1148. if(ptlLayer!=NULL && ptrTerrain!=NULL)
  1149. {
  1150. ASSERT(ptlLayer->tl_ptdTexture!=NULL);
  1151. CTFileName fnOldTexture=CTFILENAME("Textures\\Editor\\Default.tex");
  1152. if(ptlLayer->tl_ptdTexture!=NULL)
  1153. {
  1154. fnOldTexture=ptlLayer->tl_ptdTexture->GetName();
  1155. }
  1156. BOOL bSetOldTexture=TRUE;
  1157. try
  1158. {
  1159. fnDropped.RemoveApplicationPath_t();
  1160. ptlLayer->SetLayerTexture_t(fnDropped);
  1161. bSetOldTexture=FALSE;
  1162. theApp.m_ctTerrainPageCanvas.MarkChanged();
  1163. ptrTerrain->RefreshTerrain();
  1164. }
  1165. catch(char *strError)
  1166. {
  1167. (void) strError;
  1168. }
  1169. // if should restore old texture
  1170. if(bSetOldTexture)
  1171. {
  1172. try
  1173. {
  1174. ptlLayer->SetLayerTexture_t(fnOldTexture);
  1175. }
  1176. catch(char *strError)
  1177. {
  1178. (void) strError;
  1179. }
  1180. }
  1181. }
  1182. }
  1183. void ToggleLayerVisibleFlag(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1184. {
  1185. INDEX iLayer=ptib->tib_iLayer;
  1186. if( iLayer!=-1)
  1187. {
  1188. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1189. if(ptlLayer!=NULL)
  1190. {
  1191. ptlLayer->tl_bVisible=!ptlLayer->tl_bVisible;
  1192. CTerrain *ptrTerrain=GetTerrain();
  1193. ptrTerrain->RefreshTerrain();
  1194. }
  1195. }
  1196. }
  1197. void ToggleFlag(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1198. {
  1199. INDEX iLayer=ptib->tib_iLayer;
  1200. if( iLayer!=-1)
  1201. {
  1202. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1203. if(ptlLayer!=NULL)
  1204. {
  1205. BOOL bOldValue=*(BOOL*)((UBYTE*)ptlLayer+(ULONG)ptib->tib_pfData1);
  1206. bOldValue=!bOldValue;
  1207. *(BOOL*)((UBYTE*)ptlLayer+(ULONG)ptib->tib_pfData1)=bOldValue;
  1208. }
  1209. }
  1210. }
  1211. BOOL DisableIfNoTerrainSelected(CTIButton *ptib)
  1212. {
  1213. CTerrain *ptrTerrain=GetTerrain();
  1214. return ptrTerrain!=NULL;
  1215. }
  1216. CTString GetNormalizedPercentageInfo(CTIButton *ptib, CPoint pt, CDrawPort *pdp, BOOL bLmb)
  1217. {
  1218. CTString strInfo;
  1219. INDEX iLayer=ptib->tib_iLayer;
  1220. if( iLayer!=-1)
  1221. {
  1222. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1223. if(ptlLayer!=NULL)
  1224. {
  1225. FLOAT *pfNormalized=(FLOAT *)((UBYTE*)ptlLayer+(ULONG)ptib->tib_pfData1);
  1226. FLOAT fValue=*pfNormalized;
  1227. strInfo.PrintF("%s: %d%%", ptib->tib_strToolTip, INDEX(floor(fValue*100.0f+0.5f)));
  1228. return strInfo;
  1229. }
  1230. }
  1231. return strInfo;
  1232. }
  1233. void ChangeLayerDistributionData(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)
  1234. {
  1235. if( ptib->tib_pfData1==NULL) return;
  1236. INDEX iLayer=ptib->tib_iLayer;
  1237. if( iLayer==-1) return;
  1238. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1239. if(ptlLayer==NULL) return;
  1240. FLOAT *pfNormalized=(FLOAT *)((UBYTE*)ptlLayer+(ULONG)ptib->tib_pfData1);
  1241. FLOAT fOldValue=*pfNormalized;
  1242. FLOAT fAddX=ptib->tib_fDataDelta*fdx;
  1243. FLOAT fNewValue=Clamp( fOldValue+fAddX, 0.0f, 1.0f);
  1244. *pfNormalized=fNewValue;
  1245. _iGenerateForLayer=iLayer;
  1246. _chAutoGenerateDistribution.MarkChanged();
  1247. }
  1248. void ChangeData(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)
  1249. {
  1250. if( ptib->tib_pfData1!=NULL)
  1251. {
  1252. FLOAT fData=*ptib->tib_pfData1;
  1253. FLOAT fAdd=ptib->tib_fDataDelta*fdx;
  1254. if((fData+fAdd)>=ptib->tib_fDataMax)
  1255. {
  1256. if(ptib->tib_bWrapData)
  1257. {
  1258. fData=ptib->tib_fDataMin+((fData+fAdd)-ptib->tib_fDataMax);
  1259. }
  1260. else
  1261. {
  1262. fData=ptib->tib_fDataMax;
  1263. }
  1264. }
  1265. else if((fData+fAdd)<=ptib->tib_fDataMin)
  1266. {
  1267. if(ptib->tib_bWrapData)
  1268. {
  1269. fData=ptib->tib_fDataMax+(fData+fAdd);
  1270. }
  1271. else
  1272. {
  1273. fData=ptib->tib_fDataMin;
  1274. }
  1275. }
  1276. else
  1277. {
  1278. fData=fData+fAdd;
  1279. }
  1280. *ptib->tib_pfData1=fData;
  1281. }
  1282. }
  1283. void ChangeTextureRotation(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)
  1284. {
  1285. INDEX iLayer=ptib->tib_iLayer;
  1286. if( iLayer!=-1)
  1287. {
  1288. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1289. if(ptlLayer!=NULL)
  1290. {
  1291. FLOAT fAdd=CHANGE_ANGLE_SENSITIVITY*fdx;
  1292. ptlLayer->tl_fRotateX+=fAdd;
  1293. ptlLayer->tl_fRotateY+=fAdd;
  1294. }
  1295. }
  1296. }
  1297. void ChangeTextureOffset(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)
  1298. {
  1299. INDEX iLayer=ptib->tib_iLayer;
  1300. if( iLayer!=-1)
  1301. {
  1302. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1303. if(ptlLayer!=NULL)
  1304. {
  1305. FLOAT fAddX=CHANGE_OFFSET_SENSITIVITY*fdx;
  1306. FLOAT fAddY=CHANGE_OFFSET_SENSITIVITY*fdy;
  1307. ptlLayer->tl_fOffsetX+=fAddX;
  1308. ptlLayer->tl_fOffsetY+=fAddY;
  1309. }
  1310. }
  1311. }
  1312. void ChangeTextureStretch(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp)
  1313. {
  1314. INDEX iLayer=ptib->tib_iLayer;
  1315. if( iLayer!=-1)
  1316. {
  1317. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1318. CTerrain *ptrTerrain=GetTerrain();
  1319. if(ptlLayer!=NULL && ptrTerrain!=NULL)
  1320. {
  1321. if(fdx>=CHANGE_STRETCH_SENSITIVITY)
  1322. {
  1323. ptlLayer->tl_fStretchX/=2;
  1324. ptlLayer->tl_fStretchY/=2;
  1325. ptrTerrain->RefreshTerrain();
  1326. }
  1327. else if(fdx<=-CHANGE_STRETCH_SENSITIVITY)
  1328. {
  1329. ptlLayer->tl_fStretchX*=2;
  1330. ptlLayer->tl_fStretchY*=2;
  1331. ptrTerrain->RefreshTerrain();
  1332. }
  1333. }
  1334. }
  1335. }
  1336. void OnSelectBrush(INDEX iSelectedItem)
  1337. {
  1338. if( iSelectedItem>=0 && iSelectedItem<CT_BRUSH_MODES)
  1339. {
  1340. theApp.m_iTerrainBrushMode=iSelectedItem;
  1341. theApp.m_ctTerrainPageCanvas.MarkChanged();
  1342. theApp.GetDocument()->SetStatusLineModeInfoMessage();
  1343. }
  1344. else if(iSelectedItem==-1)
  1345. {
  1346. CTerrain *ptrTerrain=GetTerrain();
  1347. if( ptrTerrain==NULL) return;
  1348. CDlgEditFloat dlg;
  1349. dlg.m_fEditFloat=theApp.m_fPosterizeStep;
  1350. dlg.m_strVarName = "Posterize step (m)";
  1351. dlg.m_strTitle = "Enter posterize step";
  1352. if(dlg.DoModal()!=IDOK) return;
  1353. theApp.m_fPosterizeStep=dlg.m_fEditFloat;
  1354. }
  1355. // auto update terrain distribution flag
  1356. else if(iSelectedItem==50)
  1357. {
  1358. theApp.m_Preferences.ap_bAutoUpdateTerrainDistribution=!theApp.m_Preferences.ap_bAutoUpdateTerrainDistribution;
  1359. }
  1360. // settings
  1361. else if(iSelectedItem==100)
  1362. {
  1363. CDlgTEOperationSettings dlg;
  1364. dlg.DoModal();
  1365. }
  1366. }
  1367. void InvokeBrushModeCombo(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1368. {
  1369. PointToScreenSpace(pt, pdp);
  1370. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1371. INDEX iFlag=6;
  1372. if(theApp.m_Preferences.ap_bAutoUpdateTerrainDistribution)
  1373. {
  1374. iFlag=7;
  1375. }
  1376. InsertItemMacro( pCombo, "Auto update layer distribution", iFlag, 50, COL_SETTINGS);
  1377. InsertItemMacro( pCombo, "---------------------------------", -1, -1, COL_SEPARATOR);
  1378. for(INDEX iMode=0; iMode<CT_BRUSH_MODES; iMode++)
  1379. {
  1380. INDEX iIcon;
  1381. CTString strText;
  1382. GetBrushModeInfo(iMode, iIcon, strText);
  1383. InsertItemMacro( pCombo, strText, iIcon, iMode);
  1384. }
  1385. InsertItemMacro( pCombo, "---------------------------------", -1, -1, COL_SEPARATOR);
  1386. InsertItemMacro( pCombo, "Operation settings (Ctrl+Shift+P)", 26, 100, COL_SETTINGS);
  1387. pCombo->Initialize(NULL, OnSelectBrush, pt.x, pt.y);
  1388. }
  1389. void InvokePercentageCombo(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1390. {
  1391. PointToScreenSpace(pt, pdp);
  1392. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1393. for( INDEX i=1; i<11; i++)
  1394. {
  1395. CTString strText;
  1396. strText.PrintF("%d", i*10);
  1397. pCombo->InsertItem( strText);
  1398. }
  1399. pCombo->Initialize(&theApp.m_fTerrainBrushPressureEnum, NULL, pt.x, pt.y);
  1400. }
  1401. void InvokeEditModeCombo(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1402. {
  1403. PointToScreenSpace(pt, pdp);
  1404. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1405. InsertItemMacro( pCombo, "Altitude (U)", 20);
  1406. InsertItemMacro( pCombo, "Texture (L)", 19);
  1407. pCombo->Initialize(&theApp.m_iTerrainEditMode, NULL, pt.x, pt.y);
  1408. }
  1409. void NextEnum(CTIButton *ptib, CPoint pt)
  1410. {
  1411. ChangeData(ptib, 1, 0, NULL);
  1412. }
  1413. FLOAT GetMaxSliderPos(CDrawPort *pdp)
  1414. {
  1415. CTerrain *ptrTerrain=GetTerrain();
  1416. if( ptrTerrain==NULL) return 0;
  1417. FLOAT fMaxPos=ClampDn(ptrTerrain->tr_atlLayers.Count()*LAYER_HEIGHT-pdp->GetHeight(),PIX(0));
  1418. return fMaxPos;
  1419. }
  1420. void OnSliderArrowUp(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1421. {
  1422. _fScrollLayers=ClampDn(_fScrollLayers-PIX(LAYER_HEIGHT),0.0f);
  1423. }
  1424. void OnSliderArrowDown(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1425. {
  1426. _fScrollLayers=ClampUp(_fScrollLayers+PIX(LAYER_HEIGHT),GetMaxSliderPos(pdp));
  1427. }
  1428. void RenderLayerColor(CTIButton *ptib, CDrawPort *pdp)
  1429. {
  1430. INDEX iLayer=ptib->tib_iLayer;
  1431. CTerrainLayer *ptlLayer=GetLayer(iLayer);
  1432. if(ptlLayer==NULL) return;
  1433. PIXaabbox2D box=GetButtonScreenBox(*ptib);
  1434. pdp->Fill(box.Min()(1), box.Min()(2), box.Size()(1), box.Size()(2), ptlLayer->tl_colMultiply);
  1435. }
  1436. void RenderSlider(CTIButton *ptib, CDrawPort *pdp)
  1437. {
  1438. FLOAT fMaxPos=GetMaxSliderPos(pdp);
  1439. PIX pixSliderY=FLOAT(ptib->tib_fdy-SLIDER_HOLDER_HEIGHT/2)/fMaxPos*_fScrollLayers;
  1440. pixSliderY=ClampDn<PIX>(pixSliderY-SLIDER_HOLDER_HEIGHT/2, 0);
  1441. pdp->Fill(ptib->tib_fx, ptib->tib_fy+pixSliderY, ptib->tib_fdx-2, SLIDER_HOLDER_HEIGHT, C_mlGRAY|CT_OPAQUE);
  1442. }
  1443. void OnSliderClick(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1444. {
  1445. FLOAT fMaxPos=GetMaxSliderPos(pdp);
  1446. PointToIconSpace(pt, ptib);
  1447. pt.y=ClampUp( pt.y, INDEX(ptib->tib_fdy-SLIDER_HOLDER_HEIGHT/2));
  1448. if(pt.y<SLIDER_HOLDER_HEIGHT/2) pt.y=0;
  1449. FLOAT fRemapFactor=fMaxPos/(ptib->tib_fdy-SLIDER_HOLDER_HEIGHT);
  1450. FLOAT fSetPos=pt.y*fRemapFactor;
  1451. _fScrollLayers=ClampUp(fSetPos,fMaxPos);
  1452. }
  1453. void DragSlider(CTIButton *ptib, FLOAT fdx, FLOAT fdy, CDrawPort *pdp/*=NULL*/)
  1454. {
  1455. FLOAT fMaxPos=GetMaxSliderPos(pdp);
  1456. FLOAT fRemapFactor=FLOAT(fMaxPos)/(ptib->tib_fdy-SLIDER_HOLDER_HEIGHT);
  1457. FLOAT fNewPos=_fScrollLayers+fdy*fRemapFactor;
  1458. _fScrollLayers=Clamp( fNewPos, 0.0f, fMaxPos);
  1459. }
  1460. void RecalculateShadows(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1461. {
  1462. RecalculateShadows();
  1463. }
  1464. void DisplayHeightMap(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1465. {
  1466. PointToScreenSpace(pt, pdp);
  1467. DisplayHeightMapWindow( pt);
  1468. }
  1469. void ApplyTerrainOptions(INDEX iSelectedItem)
  1470. {
  1471. CTerrain *ptrTerrain=GetTerrain();
  1472. if( ptrTerrain==NULL) return;
  1473. switch(iSelectedItem)
  1474. {
  1475. // invoke properties
  1476. case 0:
  1477. {
  1478. CDlgTerrainProperties dlg;
  1479. dlg.DoModal();
  1480. break;
  1481. }
  1482. // generate terrain
  1483. case 3:
  1484. {
  1485. ApplyGenerateTerrain();
  1486. break;
  1487. }
  1488. // smooth
  1489. case 4:
  1490. {
  1491. ApplySmoothOntoTerrain();
  1492. break;
  1493. }
  1494. // filter
  1495. case 5:
  1496. {
  1497. ApplyFilterOntoTerrain();
  1498. break;
  1499. }
  1500. // add noise
  1501. case 6:
  1502. {
  1503. ApplyRndNoiseOntoTerrain();
  1504. break;
  1505. }
  1506. // equalize
  1507. case 7:
  1508. {
  1509. ApplyEqualizeOntoTerrain();
  1510. break;
  1511. }
  1512. // operation settings
  1513. case 8:
  1514. {
  1515. // option settings
  1516. CDlgTEOperationSettings dlg;
  1517. dlg.DoModal();
  1518. break;
  1519. }
  1520. // posterize
  1521. case 9:
  1522. {
  1523. ApplyPosterizeOntoTerrain();
  1524. break;
  1525. }
  1526. // add continous noise
  1527. case 11:
  1528. {
  1529. ApplyContinousNoiseOntoTerrain();
  1530. break;
  1531. }
  1532. // limit down
  1533. case 12:
  1534. {
  1535. ApplyMinimumOntoTerrain();
  1536. break;
  1537. }
  1538. // limit up
  1539. case 13:
  1540. {
  1541. ApplyMaximumOntoTerrain();
  1542. break;
  1543. }
  1544. // flatten
  1545. case 14:
  1546. {
  1547. ApplyFlattenOntoTerrain();
  1548. break;
  1549. }
  1550. // recalcualte shadows
  1551. case 15:
  1552. {
  1553. ptrTerrain->UpdateShadowMap();
  1554. }
  1555. // generate layer distribution
  1556. case 16:
  1557. {
  1558. GenerateLayerDistribution(-1);
  1559. }
  1560. // optimize layers
  1561. case 17:
  1562. {
  1563. OptimizeLayers();
  1564. }
  1565. // view heightmap
  1566. case 50:
  1567. {
  1568. CPoint pt;
  1569. GetCursorPos( &pt);
  1570. DisplayHeightMapWindow( pt);
  1571. }
  1572. }
  1573. }
  1574. void InvokeTerrainOptions(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1575. {
  1576. CTerrain *ptrTerrain=GetTerrain();
  1577. if( ptrTerrain==NULL) return;
  1578. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1579. INDEX iItem=0;
  1580. InsertItemMacro( pCombo, "Terrain properties (Ctrl+Shift+T)",2,0);
  1581. InsertItemMacro( pCombo, "------------------------------------", -1, -1, COL_SEPARATOR);
  1582. InsertItemMacro( pCombo, "Generate terrain (Ctrl+Shift+G)",25, 3);
  1583. InsertItemMacro( pCombo, "Equalize (Ctrl+Shift+E)",1,7);
  1584. InsertItemMacro( pCombo, "------------------------------------", -1, -1, COL_SEPARATOR);
  1585. InsertItemMacro( pCombo, "Recalculate shadows (Ctrl+Shift+R)",5, 15);
  1586. InsertItemMacro( pCombo, "Generate layer distribution (Ctrl+G)",19, 16);
  1587. InsertItemMacro( pCombo, "Optimize layers (Ctrl+Shift+Z)",25, 17);
  1588. InsertItemMacro( pCombo, "------------------------------------", -1, -1, COL_SEPARATOR);
  1589. InsertItemMacro( pCombo, "Smooth (Ctrl+Shift+O)",10,4);
  1590. InsertItemMacro( pCombo, "Filter (Ctrl+Shift+F)",30,5);
  1591. InsertItemMacro( pCombo, "Limit down (Ctrl+Shift+M)",27,12);
  1592. InsertItemMacro( pCombo, "Limit up (Ctrl+Shift+X)",11,13);
  1593. InsertItemMacro( pCombo, "Flatten (Ctrl+Shift+N)",18,14);
  1594. InsertItemMacro( pCombo, "Posterize",28,9);
  1595. InsertItemMacro( pCombo, "Random noise (Ctrl+Shift+K)",21,6);
  1596. InsertItemMacro( pCombo, "Texture noise (Ctrl+Shift+Y)",31,11);
  1597. InsertItemMacro( pCombo, "------------------------------------", -1, -1,COL_SEPARATOR);
  1598. InsertItemMacro( pCombo, "View height map ", 26, 50);
  1599. InsertItemMacro( pCombo, "Operation settings (Ctrl+Shift+P)", 26, 8, COL_SETTINGS);
  1600. PointToScreenSpace(pt, pdp);
  1601. pCombo->Initialize(NULL, ApplyTerrainOptions, pt.x, pt.y);
  1602. }
  1603. void DisplayHeightMapWindow(CPoint pt)
  1604. {
  1605. CTextureData tdHeightMap;
  1606. CImageInfo ii;
  1607. CTerrain *ptrTerrain=GetTerrain();
  1608. if( ptrTerrain==NULL) return;
  1609. PIX pixW=ptrTerrain->tr_pixHeightMapWidth;
  1610. PIX pixH=ptrTerrain->tr_pixHeightMapHeight;
  1611. if(ptrTerrain->tr_auwHeightMap==NULL) return;
  1612. ii.ii_BitsPerPixel=32;
  1613. ii.ii_Width=pixW-1;
  1614. ii.ii_Height=pixH-1;
  1615. ii.ii_Picture=(UBYTE*)AllocMemory((pixW-1)*(pixH-1)*sizeof(COLOR));
  1616. COLOR *pcol=(COLOR *)ii.ii_Picture;
  1617. for( INDEX iy=0; iy<pixH-1; iy++)
  1618. {
  1619. for( INDEX ix=0; ix<pixW-1; ix++)
  1620. {
  1621. UWORD *pdest=ptrTerrain->tr_auwHeightMap+iy*pixW+ix;
  1622. UWORD uw=*pdest;
  1623. FLOAT fPix=uw/256.0f;
  1624. UBYTE ubR=UBYTE(fPix);
  1625. COLOR col=RGBToColor(ubR,ubR,ubR)|CT_OPAQUE;
  1626. col=RGBToColor(ubR,ubR,ubR)|CT_OPAQUE;
  1627. *(pcol+iy*(pixW-1)+ix)=ByteSwap(col);
  1628. }
  1629. }
  1630. try
  1631. {
  1632. tdHeightMap.Create_t( &ii, pixW-1, 16, TRUE);
  1633. CTString strHeightMap="Temp\\ViewHeightMap.tex";
  1634. tdHeightMap.Save_t( strHeightMap);
  1635. CTextureData *ptd;
  1636. ptd=_pTextureStock->Obtain_t( strHeightMap);
  1637. ptd->Reload();
  1638. CWndDisplayTexture *pDisplay=new CWndDisplayTexture;
  1639. pDisplay->Initialize(pt.x, pt.y, ptd);
  1640. }
  1641. catch( char *strError)
  1642. {
  1643. (void) strError;
  1644. WarningMessage("Unable to display height map!");
  1645. }
  1646. }
  1647. void OnSelectLoadSave(INDEX iSelectedItem)
  1648. {
  1649. switch( iSelectedItem)
  1650. {
  1651. case 0:
  1652. case 1:
  1653. case 2:
  1654. case 3:
  1655. {
  1656. ApplyImportExport(iSelectedItem);
  1657. }
  1658. case 4: // "Load surface"
  1659. {
  1660. CTFileName fnSurface=_EngineGUI.FileRequester(
  1661. "Load surface", "Surfaces (*.sfc)\0*.sfc\0" FILTER_ALL FILTER_END,
  1662. "Surface directory", "Surfaces\\");
  1663. if( fnSurface=="") return;
  1664. LoadSurface(fnSurface);
  1665. break;
  1666. }
  1667. case 5: // "Save surface"
  1668. {
  1669. CTFileName fnSurface=_EngineGUI.FileRequester(
  1670. "Save surface", "Surfaces (*.sfc)\0*.sfc\0" FILTER_ALL FILTER_END,
  1671. "Surface directory", "Surfaces\\");
  1672. if( fnSurface=="") return;
  1673. SaveSurface(fnSurface);
  1674. break;
  1675. }
  1676. }
  1677. }
  1678. void ApplyImportExport(INDEX iOperation)
  1679. {
  1680. CTerrain *ptrTerrain=GetTerrain();
  1681. if( ptrTerrain==NULL) return;
  1682. CTFileName fnHeightmap;
  1683. if(iOperation<2)
  1684. {
  1685. fnHeightmap=_EngineGUI.FileRequester(
  1686. "Import heightmap", FILTER_TGA FILTER_PCX FILTER_ALL FILTER_END,
  1687. "Terrain heightmap directory", "Textures\\");
  1688. if( fnHeightmap=="") return;
  1689. }
  1690. else
  1691. {
  1692. fnHeightmap=_EngineGUI.FileRequester(
  1693. "Export heightmap", FILTER_TGA FILTER_PCX FILTER_ALL FILTER_END,
  1694. "Terrain heightmap directory", "Textures\\");
  1695. if( fnHeightmap=="") return;
  1696. }
  1697. try
  1698. {
  1699. switch( iOperation)
  1700. {
  1701. // import 8 bit
  1702. case 0:
  1703. {
  1704. ptrTerrain->ImportHeightMap_t(fnHeightmap, FALSE);
  1705. theApp.m_ctTerrainPage.MarkChanged();
  1706. break;
  1707. }
  1708. // import 16 bit
  1709. case 1:
  1710. {
  1711. ptrTerrain->ImportHeightMap_t(fnHeightmap, TRUE);
  1712. theApp.m_ctTerrainPage.MarkChanged();
  1713. break;
  1714. }
  1715. // export 8 bit
  1716. case 2:
  1717. {
  1718. ptrTerrain->ExportHeightMap_t(fnHeightmap, FALSE);
  1719. break;
  1720. }
  1721. // export 16 bit
  1722. case 3:
  1723. {
  1724. ptrTerrain->ExportHeightMap_t(fnHeightmap, TRUE);
  1725. break;
  1726. }
  1727. }
  1728. }
  1729. catch(char *strError)
  1730. {
  1731. AfxMessageBox( CString(strError));
  1732. }
  1733. }
  1734. void GenerateLayerDistribution(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1735. {
  1736. GenerateLayerDistribution(-1);
  1737. }
  1738. void InvokeImportExportCombo(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1739. {
  1740. CTerrain *ptrTerrain=GetTerrain();
  1741. if( ptrTerrain==NULL) return;
  1742. CCustomComboWnd *pCombo=new CCustomComboWnd;
  1743. InsertItemMacro( pCombo, "Import 8-bit", 22, 0);
  1744. InsertItemMacro( pCombo, "Import 16-bit", 22, 1);
  1745. InsertItemMacro( pCombo, "Export 8-bit", 22, 2);
  1746. InsertItemMacro( pCombo, "Export 16-bit", 22, 3);
  1747. InsertItemMacro( pCombo, "----------------", -1, -1, COL_SEPARATOR);
  1748. InsertItemMacro( pCombo, "Load surface", 22, 4);
  1749. InsertItemMacro( pCombo, "Save surface", 22, 5);
  1750. PointToScreenSpace(pt, pdp);
  1751. pCombo->Initialize(NULL, OnSelectLoadSave, pt.x, pt.y);
  1752. }
  1753. void InvokeTerrainTilePalette( PIX pixX, PIX pixY)
  1754. {
  1755. CWndTerrainTilePalette *pDisplay=new CWndTerrainTilePalette;
  1756. CTerrainLayer *ptlLayer=GetLayer();
  1757. if(ptlLayer!=NULL && ptlLayer->tl_ptdTexture!=NULL)
  1758. {
  1759. pDisplay->Initialize(pixX, pixY, ptlLayer->tl_ptdTexture, TRUE);
  1760. }
  1761. }
  1762. CBrushPaletteWnd *_pBrushPalette=NULL;
  1763. void InvokeTerrainBrushPalette( PIX pixX, PIX pixY)
  1764. {
  1765. // calculate palette window's rectangle
  1766. CRect rectWindow;
  1767. rectWindow.left = pixX;
  1768. rectWindow.bottom = pixY;
  1769. rectWindow.right = rectWindow.left + BRUSH_PALETTE_WIDTH;
  1770. rectWindow.top = rectWindow.bottom - BRUSH_PALETTE_HEIGHT;
  1771. if( _pBrushPalette == NULL)
  1772. {
  1773. // instantiate new choose color palette window
  1774. _pBrushPalette = new CBrushPaletteWnd;
  1775. // create window
  1776. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  1777. BOOL bResult = _pBrushPalette->CreateEx( WS_EX_TOOLWINDOW,
  1778. NULL, L"Brush palette", WS_CHILD|WS_POPUP|WS_VISIBLE,
  1779. rectWindow.left, rectWindow.top, rectWindow.Width(), rectWindow.Height(),
  1780. pMainFrame->m_hWnd, NULL, NULL);
  1781. _pBrushPalette->SetFocus();
  1782. if( !bResult)
  1783. {
  1784. AfxMessageBox( L"Error: Failed to create brush palette");
  1785. return;
  1786. }
  1787. // initialize canvas for active texture button
  1788. _pGfx->CreateWindowCanvas( _pBrushPalette->m_hWnd, &_pBrushPalette->m_pViewPort,
  1789. &_pBrushPalette->m_pDrawPort);
  1790. }
  1791. else
  1792. {
  1793. _pBrushPalette->ShowWindow(SW_SHOW);
  1794. _pBrushPalette->SetFocus();
  1795. }
  1796. }
  1797. void InvokeBrushPalette(CTIButton *ptib, CPoint pt, CDrawPort *pdp)
  1798. {
  1799. PointToScreenSpace(pt, pdp);
  1800. InvokeTerrainBrushPalette( pt.x, pt.y);
  1801. }
  1802. BOOL CTerrainInterface::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  1803. {
  1804. return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  1805. }
  1806. BOOL CTerrainInterface::IsClicked(CTIButton &tib, CPoint pt) const
  1807. {
  1808. PIX pixOffsetX=0;
  1809. PIX pixOffsetY=0;
  1810. GetButtonOffset(tib, pixOffsetX, pixOffsetY);
  1811. PIX x=tib.tib_fx+pixOffsetX;
  1812. PIX y=tib.tib_fy+pixOffsetY;
  1813. PIX dx=tib.tib_fdx;
  1814. PIX dy=tib.tib_fdy;
  1815. return( (pt.x>x) && (pt.x<x+dx) && (pt.y>y) && (pt.y<y+dy) );
  1816. }
  1817. BOOL _bDummyMouseMove=FALSE;
  1818. BOOL _bMouseTrapInProgress=FALSE;
  1819. void CTerrainInterface::OnLButtonDown(UINT nFlags, CPoint point)
  1820. {
  1821. CWnd::OnLButtonDown(nFlags, point);
  1822. SetFocus();
  1823. m_ptMouseDown=point;
  1824. m_ptMouse=point;
  1825. m_ptMouseDownScreen=point;
  1826. ClientToScreen(&m_ptMouseDownScreen);
  1827. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  1828. {
  1829. CTIButton &tib=*ittib;
  1830. if( IsClicked(tib, point))
  1831. {
  1832. if(tib.tib_pOnLeftClick!=NULL)
  1833. {
  1834. tib.tib_pOnLeftClick(&tib, m_ptMouse, m_pDrawPort);
  1835. _bMouseTrapInProgress=FALSE;
  1836. UnhideCursor();
  1837. Invalidate(FALSE);
  1838. if(!tib.tib_bContinueTesting) break;
  1839. }
  1840. if(tib.tib_pOnLeftClickMove!=NULL)
  1841. {
  1842. // display tool tip
  1843. if( tib.tib_pGetClickMoveData!=NULL)
  1844. {
  1845. CTString strInfo=tib.tib_pGetClickMoveData(&tib, point, m_pDrawPort, TRUE);
  1846. _strToolTip=strInfo;
  1847. SetCapture();
  1848. theApp.m_cttToolTips.ManualOn( m_ptMouseDownScreen.x, m_ptMouseDownScreen.y, &::GetToolTipText, this);
  1849. }
  1850. // if should trap the mouse
  1851. if(tib.tib_bMouseTrapForMove)
  1852. {
  1853. m_ptMouseCenter.x=m_pDrawPort->GetWidth()/2;
  1854. m_ptMouseCenter.y=m_pDrawPort->GetHeight()/2;
  1855. m_ptMouseCenterScreen=m_ptMouseCenter;
  1856. ClientToScreen(&m_ptMouseCenterScreen);
  1857. _bDummyMouseMove=TRUE;
  1858. SetCursorPos(m_ptMouseCenterScreen.x, m_ptMouseCenterScreen.y);
  1859. HideCursor();
  1860. _bMouseTrapInProgress=TRUE;
  1861. }
  1862. if(!tib.tib_bContinueTesting) break;
  1863. }
  1864. }
  1865. }
  1866. }
  1867. void CTerrainInterface::OnLButtonDblClk(UINT nFlags, CPoint point)
  1868. {
  1869. OnLButtonDown(nFlags, point);
  1870. }
  1871. void CTerrainInterface::OnMouseMove(UINT nFlags, CPoint point)
  1872. {
  1873. theApp.m_cttToolTips.MouseMoveNotify( m_hWnd, 500, &::GetToolTipText, this);
  1874. BOOL bLMB = nFlags & MK_LBUTTON;
  1875. BOOL bRMB = nFlags & MK_RBUTTON;
  1876. FLOAT fdx=point.x-m_ptMouseCenter.x;
  1877. FLOAT fdy=point.y-m_ptMouseCenter.y;
  1878. FLOAT fdxNotLocked=point.x-m_ptMouse.x;
  1879. FLOAT fdyNotLocked=point.y-m_ptMouse.y;
  1880. fdx=fdxNotLocked;
  1881. fdy=fdyNotLocked;
  1882. m_ptMouse=point;
  1883. if( _bDummyMouseMove)
  1884. {
  1885. _bDummyMouseMove=FALSE;
  1886. return;
  1887. }
  1888. if( bLMB)
  1889. {
  1890. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  1891. {
  1892. CTIButton &tib=*ittib;
  1893. if( IsClicked(tib, m_ptMouseDown) && tib.tib_pOnLeftClickMove!=NULL)
  1894. {
  1895. if(tib.tib_bMouseTrapForMove)
  1896. {
  1897. tib.tib_pOnLeftClickMove(&tib, fdx, fdy, m_pDrawPort);
  1898. _bDummyMouseMove=TRUE;
  1899. SetCursorPos(m_ptMouseCenterScreen.x, m_ptMouseCenterScreen.y);
  1900. }
  1901. else
  1902. {
  1903. tib.tib_pOnLeftClickMove(&tib, fdxNotLocked, fdyNotLocked, m_pDrawPort);
  1904. }
  1905. Invalidate(FALSE);
  1906. // update tool tip
  1907. if( tib.tib_pGetClickMoveData!=NULL)
  1908. {
  1909. _strToolTip=tib.tib_pGetClickMoveData(&tib, point, m_pDrawPort, TRUE);
  1910. theApp.m_cttToolTips.ManualUpdate();
  1911. }
  1912. if(!tib.tib_bContinueTesting) break;
  1913. }
  1914. }
  1915. }
  1916. else if( bRMB)
  1917. {
  1918. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  1919. {
  1920. CTIButton &tib=*ittib;
  1921. if( IsClicked(tib, m_ptMouseDown) && tib.tib_pOnRightClickMove!=NULL)
  1922. {
  1923. if(tib.tib_bMouseTrapForMove)
  1924. {
  1925. tib.tib_pOnRightClickMove(&tib, fdx, fdy, m_pDrawPort);
  1926. _bDummyMouseMove=TRUE;
  1927. SetCursorPos(m_ptMouseCenterScreen.x, m_ptMouseCenterScreen.y);
  1928. }
  1929. else
  1930. {
  1931. tib.tib_pOnRightClickMove(&tib, fdxNotLocked, fdyNotLocked, m_pDrawPort);
  1932. }
  1933. Invalidate(FALSE);
  1934. // update tool tip
  1935. if( tib.tib_pGetClickMoveData!=NULL)
  1936. {
  1937. _strToolTip=tib.tib_pGetClickMoveData(&tib, point, m_pDrawPort, FALSE);
  1938. theApp.m_cttToolTips.ManualUpdate();
  1939. }
  1940. if(!tib.tib_bContinueTesting) break;
  1941. }
  1942. }
  1943. }
  1944. CWnd::OnMouseMove(nFlags, point);
  1945. }
  1946. void CTerrainInterface::OnLButtonUp(UINT nFlags, CPoint point)
  1947. {
  1948. theApp.m_cttToolTips.ManualOff();
  1949. ReleaseCapture();
  1950. _bDummyMouseMove=TRUE;
  1951. if( _bMouseTrapInProgress)
  1952. {
  1953. SetCursorPos(m_ptMouseDownScreen.x, m_ptMouseDownScreen.y);
  1954. _bMouseTrapInProgress=FALSE;
  1955. UnhideCursor();
  1956. m_ptMouseDown.x=-1;
  1957. m_ptMouseDown.y=-1;
  1958. }
  1959. CWnd::OnLButtonUp(nFlags, point);
  1960. }
  1961. BOOL CTerrainInterface::PreTranslateMessage(MSG* pMsg)
  1962. {
  1963. return CWnd::PreTranslateMessage(pMsg);
  1964. }
  1965. void CTerrainInterface::OnRButtonDown(UINT nFlags, CPoint point)
  1966. {
  1967. CWnd::OnRButtonDown(nFlags, point);
  1968. SetFocus();
  1969. m_ptMouseDown=point;
  1970. m_ptMouse=point;
  1971. m_ptMouseDownScreen=point;
  1972. ClientToScreen(&m_ptMouseDownScreen);
  1973. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  1974. {
  1975. CTIButton &tib=*ittib;
  1976. if( IsClicked(tib, point))
  1977. {
  1978. if(tib.tib_pOnRightClick!=NULL)
  1979. {
  1980. tib.tib_pOnRightClick(&tib, m_ptMouse, m_pDrawPort);
  1981. _bMouseTrapInProgress=FALSE;
  1982. UnhideCursor();
  1983. Invalidate(FALSE);
  1984. if(!tib.tib_bContinueTesting) break;
  1985. }
  1986. if(tib.tib_pOnRightClickMove!=NULL)
  1987. {
  1988. // display tool tip
  1989. if( tib.tib_pGetClickMoveData!=NULL)
  1990. {
  1991. CTString strInfo=tib.tib_pGetClickMoveData(&tib, point, m_pDrawPort, TRUE);
  1992. _strToolTip=strInfo;
  1993. theApp.m_cttToolTips.ManualOn( m_ptMouseDownScreen.x, m_ptMouseDownScreen.y, &::GetToolTipText, this);
  1994. SetCapture();
  1995. }
  1996. // if should trap the mouse
  1997. if(tib.tib_bMouseTrapForMove)
  1998. {
  1999. m_ptMouseCenter.x=m_pDrawPort->GetWidth()/2;
  2000. m_ptMouseCenter.y=m_pDrawPort->GetHeight()/2;
  2001. m_ptMouseCenterScreen=m_ptMouseCenter;
  2002. ClientToScreen(&m_ptMouseCenterScreen);
  2003. _bDummyMouseMove=TRUE;
  2004. SetCursorPos(m_ptMouseCenterScreen.x, m_ptMouseCenterScreen.y);
  2005. HideCursor();
  2006. _bMouseTrapInProgress=TRUE;
  2007. }
  2008. if(!tib.tib_bContinueTesting) break;
  2009. }
  2010. }
  2011. }
  2012. }
  2013. void CTerrainInterface::OnRButtonUp(UINT nFlags, CPoint point)
  2014. {
  2015. theApp.m_cttToolTips.ManualOff();
  2016. ReleaseCapture();
  2017. _bDummyMouseMove=TRUE;
  2018. if( _bMouseTrapInProgress)
  2019. {
  2020. SetCursorPos(m_ptMouseDownScreen.x, m_ptMouseDownScreen.y);
  2021. _bMouseTrapInProgress=FALSE;
  2022. UnhideCursor();
  2023. m_ptMouseDown.x=-1;
  2024. m_ptMouseDown.y=-1;
  2025. }
  2026. CWnd::OnRButtonUp(nFlags, point);
  2027. }
  2028. void CTerrainInterface::OnIdle(void)
  2029. {
  2030. CWorldEditorDoc *pDoc = theApp.GetDocument();
  2031. if(!_chAutoGenerateDistribution.IsUpToDate( _udAutoGenerateDistribution))
  2032. {
  2033. GenerateLayerDistribution(_iGenerateForLayer);
  2034. _udAutoGenerateDistribution.MarkUpdated();
  2035. }
  2036. CTerrain *ptrTerrain=GetTerrain();
  2037. if(ptrTerrain!=NULL)
  2038. {
  2039. if(GetLayerIndex()>=ptrTerrain->tr_atlLayers.Count())
  2040. {
  2041. SelectLayer(0);
  2042. }
  2043. }
  2044. BOOL bLMB = (GetKeyState( VK_LBUTTON)&0x8000) != 0;
  2045. BOOL bRMB = (GetKeyState( VK_RBUTTON)&0x8000) != 0;
  2046. if(!bLMB && !bRMB && _bMouseTrapInProgress)
  2047. {
  2048. _bMouseTrapInProgress=FALSE;
  2049. UnhideCursor();
  2050. theApp.m_cttToolTips.ManualOff();
  2051. }
  2052. // if should re-initialize interface
  2053. if(pDoc!=NULL && !pDoc->m_chSelections.IsUpToDate( m_udTerrainPage) ||
  2054. !theApp.m_ctTerrainPage.IsUpToDate( m_udTerrainPage) )
  2055. {
  2056. if(m_pDrawPort!=NULL)
  2057. {
  2058. InitializeInterface(m_pDrawPort);
  2059. Invalidate(FALSE);
  2060. m_udTerrainPage.MarkUpdated();
  2061. }
  2062. }
  2063. // if should just redraw interface
  2064. if(!theApp.m_ctTerrainPageCanvas.IsUpToDate( m_udTerrainPageCanvas) )
  2065. {
  2066. Invalidate(FALSE);
  2067. m_udTerrainPageCanvas.MarkUpdated();
  2068. }
  2069. }
  2070. void CTerrainInterface::OnDropFiles(HDROP hDropInfo)
  2071. {
  2072. INDEX iNoOfFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0);
  2073. if( iNoOfFiles != 1)
  2074. {
  2075. AfxMessageBox( L"You can drop only one file at a time.");
  2076. return;
  2077. }
  2078. // buffer for dropped file name
  2079. wchar_t chrFile[ 256];
  2080. // place dropped file name into buffer
  2081. DragQueryFile( hDropInfo, 0, chrFile, 256);
  2082. // create file name from buffer
  2083. CTFileName fnDropped = CTString(CStringA(chrFile));
  2084. CPoint ptMouse;
  2085. GetCursorPos( &ptMouse);
  2086. ScreenToClient(&ptMouse);
  2087. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  2088. {
  2089. CTIButton &tib=*ittib;
  2090. if( IsClicked(tib, ptMouse) && tib.tib_pOnDropFiles!=NULL)
  2091. {
  2092. tib.tib_pOnDropFiles(&tib, ptMouse, m_pDrawPort, fnDropped);
  2093. }
  2094. }
  2095. CWnd::OnDropFiles(hDropInfo);
  2096. }
  2097. int CTerrainInterface::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2098. {
  2099. if (CWnd::OnCreate(lpCreateStruct) == -1)
  2100. return -1;
  2101. DragAcceptFiles();
  2102. EnableToolTips( TRUE);
  2103. return 0;
  2104. }
  2105. int CTerrainInterface::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
  2106. {
  2107. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  2108. {
  2109. CTIButton &tib=*ittib;
  2110. _strToolTip="";
  2111. if( IsClicked(tib, point))
  2112. {
  2113. if( tib.tib_strToolTip!="" && tib.tib_strToolTip[0]!='_')
  2114. {
  2115. _strToolTip=tib.tib_strToolTip;
  2116. return 1;
  2117. }
  2118. }
  2119. }
  2120. return 0;
  2121. }
  2122. void CTerrainInterface::InitializeInterface(CDrawPort *pdp)
  2123. {
  2124. try
  2125. {
  2126. DECLARE_CTFILENAME( fnTerrainEditIcons, "Textures\\Editor\\TerrainEditingIcons.tex");
  2127. _toIcons.SetData_t(fnTerrainEditIcons);
  2128. }
  2129. catch(char *strError)
  2130. {
  2131. (void)strError;
  2132. return;
  2133. }
  2134. FOREACHINDYNAMICCONTAINER( dcButtons, CTIButton, ittib)
  2135. {
  2136. delete &*ittib;
  2137. }
  2138. dcButtons.Clear();
  2139. CTIButton *ptib;
  2140. COLOR colBcg=RGBToColor(45,45,60)|CT_OPAQUE;
  2141. ptib=AddButton(dcButtons,0,0,LAYER_START_X,pdp->GetHeight(),-1,-1, "_Terrain options area fill", C_dGRAY|CT_TRANSPARENT, colBcg);
  2142. ptib=AddButton(dcButtons,1,1,45,45,-1,-1, "Current brush (\\)", C_lGRAY|CT_OPAQUE);
  2143. ptib->SetData(0, CT_BRUSHES, CHANGE_INDEX_SENSITIVITY, FALSE, &theApp.m_fCurrentTerrainBrush, NULL);
  2144. ptib->SetFunctions( RenderBrushShape, NULL, ChangeData, InvokeBrushPalette);
  2145. ptib=AddButton(dcButtons,0,52,LAYER_START_X,8,-1,-1, "Brush pressure (keys 0-10)");
  2146. ptib->SetData(0, 1024.0f, CHANGE_PREASSURE_SENSITIVITY, FALSE, &theApp.m_fTerrainBrushPressure, NULL);
  2147. ptib->SetFunctions( RenderBrushPressure, NULL, ChangeData, InvokePercentageCombo, NULL, UpdatePressure);
  2148. ptib=AddButton(dcButtons,6,64,16,16,-1,19, "Edit mode");
  2149. ptib->SetData(0, CT_EDIT_MODES, CHANGE_INDEX_SENSITIVITY, FALSE, &theApp.m_iTerrainEditMode, NULL);
  2150. UpdateEditModeIcon(ptib, NULL);
  2151. ptib->SetFunctions( NULL, NULL, ChangeData, InvokeEditModeCombo, NULL, UpdateEditModeIcon);
  2152. ptib=AddButton(dcButtons,28,64,16,16,-1,-1, "Brush mode");
  2153. ptib->SetData(0, CT_BRUSH_MODES-0.5f, CHANGE_INDEX_SENSITIVITY, FALSE, &theApp.m_iTerrainBrushMode, NULL);
  2154. UpdateBrushModeIcon(ptib, NULL);
  2155. ptib->SetFunctions( NULL, NULL, ChangeData, InvokeBrushModeCombo, NULL, UpdateBrushModeIcon);
  2156. /*
  2157. ptib=AddButton(dcButtons,6,84,16,16,-1,5, "Recalculate shadows (Ctrl+R)");
  2158. ptib->SetFunctions( NULL, RecalculateShadows);
  2159. ptib->tib_pIsEnabled=DisableIfNoTerrainSelected;
  2160. */
  2161. ptib=AddButton(dcButtons,28,84,16,16,-1,25, "Terrain options");
  2162. ptib->SetFunctions( NULL, NULL, NULL, InvokeTerrainOptions);
  2163. ptib->tib_pIsEnabled=DisableIfNoTerrainSelected;
  2164. /*
  2165. ptib=AddButton(dcButtons,6,104,16,16,-1,6, "Generate layer distribution (Ctrl+G)");
  2166. ptib->SetFunctions( NULL, GenerateLayerDistribution);
  2167. ptib->tib_pIsEnabled=DisableIfNoTerrainSelected;
  2168. */
  2169. ptib=AddButton(dcButtons,6,84,16,16,-1,22, "Import/Export");
  2170. ptib->SetFunctions( NULL, NULL, NULL, InvokeImportExportCombo);
  2171. ptib->tib_pIsEnabled=DisableIfNoTerrainSelected;
  2172. CTerrain *ptrTerrain=GetTerrain();
  2173. if( ptrTerrain!=NULL)
  2174. {
  2175. for(INDEX iLayer=0; iLayer<ptrTerrain->tr_atlLayers.Count(); iLayer++)
  2176. {
  2177. CTerrainLayer &tlLayer=ptrTerrain->tr_atlLayers[iLayer];
  2178. ptib=AddButton(dcButtons,0,0,GetLayerSize(pdp)(1)-SLIDER_WIDTH,
  2179. GetLayerSize(pdp)(2),iLayer,-1, "_Layer options area bcg");
  2180. ptib->SetFunctions( RenderLayerBcg, SetAsActiveLayer, NULL, SetAsActiveLayer);
  2181. ptib->tib_bContinueTesting=TRUE;
  2182. ptib=AddButton(dcButtons,
  2183. LAYER_SPACING_V/2, LAYER_SPACING_V/2,
  2184. LAYER_HEIGHT-LAYER_SPACING_V/2-1, LAYER_HEIGHT-LAYER_SPACING_V/2-1, iLayer,-1, "Layer texture",
  2185. C_BLACK|CT_OPAQUE);
  2186. ptib->SetFunctions( RenderLayerTexture, NULL, NULL, InvokeLayerTexturePopup);
  2187. ptib->tib_pOnDropFiles=OnDropIntoLayerTexture;
  2188. ptib=AddButton(dcButtons, LAYER_SPACING_V/2, LAYER_SPACING_V/2, 16, 16, iLayer, -1, "Layer visibility");
  2189. UpdateLayerVisibleFlag(ptib, NULL);
  2190. ptib->tib_pfData1=(FLOAT*)offsetof(CTerrainLayer, tl_bVisible);
  2191. ptib->SetFunctions( NULL, ToggleLayerVisibleFlag, NULL, NULL, NULL, UpdateLayerVisibleFlag);
  2192. ptib=AddButton(dcButtons,
  2193. LAYER_HEIGHT, LAYER_SPACING_V/2,
  2194. LAYER_HEIGHT-LAYER_SPACING_V/2-1, LAYER_HEIGHT-LAYER_SPACING_V/2-1, iLayer,-1, "Layer mask",
  2195. C_BLACK|CT_OPAQUE);
  2196. ptib->SetFunctions( RenderLayerMask, NULL, NULL, InvokeLayerMaskPopup);
  2197. if(tlLayer.tl_ltType==LT_NORMAL)
  2198. {
  2199. ptib=AddButton(dcButtons, LAYER_HEIGHT*2,2,16,16,iLayer,0, "Rotate texture");
  2200. ptib->SetFunctions( NULL, NULL, ChangeTextureRotation);
  2201. ptib=AddButton(dcButtons, LAYER_HEIGHT*2,16,16,16,iLayer,2, "Stretch texture");
  2202. ptib->SetFunctions( NULL, NULL, ChangeTextureStretch);
  2203. ptib->tib_pGetClickMoveData=GetStretchInfo;
  2204. ptib=AddButton(dcButtons, LAYER_HEIGHT*2,30,16,16,iLayer,1, "Offset texture");
  2205. ptib->SetFunctions( NULL, NULL, ChangeTextureOffset);
  2206. #define ICON_COVERAGE_X (LAYER_HEIGHT*2+16)
  2207. #define ICON_FILTER_X (LAYER_HEIGHT*2+40)
  2208. #define ICON_FADE_X (ICON_FILTER_X+16)
  2209. #define ICON_NOISE_X (ICON_FADE_X+16)
  2210. #define ICON_SLOPE_OFFSET 56
  2211. #define ICON_LINE1_Y 6
  2212. #define ICON_LINE2_Y 26
  2213. ptib=AddButton(dcButtons, ICON_COVERAGE_X,ICON_LINE1_Y,16,16,iLayer,17, "Layer coverage");
  2214. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fCoverage));
  2215. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2216. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2217. ptib=AddButton(dcButtons, ICON_COVERAGE_X,ICON_LINE2_Y,16,16,iLayer,21, "Layer coverage noise");
  2218. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fCoverageNoise));
  2219. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2220. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2221. ptib=AddButton(dcButtons, ICON_FILTER_X, ICON_LINE1_Y,16,16,iLayer,14, "Max altitude");
  2222. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxAltitude));
  2223. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2224. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2225. ptib=AddButton(dcButtons, ICON_FADE_X, ICON_LINE1_Y,16,16,iLayer,29, "Max altitude fade");
  2226. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2227. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2228. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxAltitudeFade));
  2229. ptib=AddButton(dcButtons, ICON_NOISE_X, ICON_LINE1_Y,16,16,iLayer,21, "Max altitude noise");
  2230. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxAltitudeNoise));
  2231. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2232. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2233. ptib=AddButton(dcButtons, ICON_FILTER_X, ICON_LINE2_Y,16,16,iLayer,13, "Min altitude");
  2234. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinAltitude));
  2235. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2236. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2237. ptib=AddButton(dcButtons, ICON_FADE_X, ICON_LINE2_Y,16,16,iLayer,29, "Min altitude fade");
  2238. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinAltitudeFade));
  2239. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2240. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2241. ptib=AddButton(dcButtons, ICON_NOISE_X, ICON_LINE2_Y,16,16,iLayer,21, "Min altitude noise");
  2242. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinAltitudeNoise));
  2243. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2244. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2245. ptib=AddButton(dcButtons, ICON_FILTER_X+ICON_SLOPE_OFFSET, ICON_LINE1_Y,16,16,iLayer,16, "Max slope");
  2246. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxSlope));
  2247. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2248. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2249. ptib=AddButton(dcButtons, ICON_FADE_X+ICON_SLOPE_OFFSET, ICON_LINE1_Y,16,16,iLayer,29, "Max slope fade");
  2250. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxSlopeFade));
  2251. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2252. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2253. ptib=AddButton(dcButtons, ICON_NOISE_X+ICON_SLOPE_OFFSET, ICON_LINE1_Y,16,16,iLayer,21, "Max slope noise");
  2254. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMaxSlopeNoise));
  2255. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2256. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2257. ptib=AddButton(dcButtons, ICON_FILTER_X+ICON_SLOPE_OFFSET, ICON_LINE2_Y,16,16,iLayer,15, "Min slope");
  2258. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinSlope));
  2259. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2260. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2261. ptib=AddButton(dcButtons, ICON_FADE_X+ICON_SLOPE_OFFSET, ICON_LINE2_Y,16,16,iLayer,29, "Min slope fade");
  2262. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinSlopeFade));
  2263. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2264. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2265. ptib=AddButton(dcButtons, ICON_NOISE_X+ICON_SLOPE_OFFSET, ICON_LINE2_Y,16,16,iLayer,21, "Min slope noise");
  2266. ptib->SetData(0, 1, CHANGE_NORMALIZED_SENSITIVITY, FALSE, (FLOAT*)offsetof(CTerrainLayer, tl_fMinSlopeFade));
  2267. ptib->SetFunctions( NULL, NULL, ChangeLayerDistributionData);
  2268. ptib->tib_pGetClickMoveData=GetNormalizedPercentageInfo;
  2269. ptib=AddButton(dcButtons, GetLayerSize(pdp)(1)-12-SLIDER_WIDTH-1-2,2,12,12,iLayer,-1, "Multiply color", C_BLACK|CT_OPAQUE);
  2270. ptib->SetFunctions( RenderLayerColor, PickLayerColor, NULL, NumericAlpha);
  2271. ptib=AddButton(dcButtons, GetLayerSize(pdp)(1)-16-SLIDER_WIDTH-1,GetLayerSize(pdp)(2)-20,16,16,iLayer,26, "Layer options (Ctrl+Shift+L)");
  2272. ptib->SetFunctions( NULL, InvokeLayerOptions);
  2273. }
  2274. else if(tlLayer.tl_ltType==LT_TILE)
  2275. {
  2276. }
  2277. ptib=AddButton(dcButtons,0,0,GetLayerSize(pdp)(1)-SLIDER_WIDTH-1,GetLayerSize(pdp)(2),iLayer,-1, "_Layer options area border", C_GRAY|CT_OPAQUE);
  2278. // _Layer click detector
  2279. ptib=AddButton(dcButtons,0,0,GetLayerSize(pdp)(1)-SLIDER_WIDTH,
  2280. GetLayerSize(pdp)(2),iLayer,-1, "_Layer click detector");
  2281. ptib->SetFunctions( NULL, NULL, NULL, InvokeLayerPopup);
  2282. }
  2283. }
  2284. //slider
  2285. ptib=AddButton(dcButtons,pdp->GetWidth()-SLIDER_WIDTH, 0, SLIDER_WIDTH, SLIDER_WIDTH, -1, 23, "_Slider arrow up", C_GRAY|CT_OPAQUE, C_mdGRAY|CT_OPAQUE);
  2286. ptib->SetFunctions(NULL,OnSliderArrowUp);
  2287. ptib=AddButton(dcButtons,pdp->GetWidth()-SLIDER_WIDTH, pdp->GetHeight()-SLIDER_WIDTH, SLIDER_WIDTH, SLIDER_WIDTH, -1, 24, "_Slider arrow down", C_GRAY|CT_OPAQUE, C_mdGRAY|CT_OPAQUE);
  2288. ptib->SetFunctions(NULL,OnSliderArrowDown);
  2289. ptib=AddButton(dcButtons,pdp->GetWidth()-SLIDER_WIDTH, SLIDER_WIDTH, SLIDER_WIDTH, pdp->GetHeight()-SLIDER_WIDTH*2, -1,-1, "_Slider rect", C_dGRAY|CT_OPAQUE, colBcg);
  2290. ptib->SetFunctions(RenderSlider,OnSliderClick, DragSlider);
  2291. ptib->tib_bMouseTrapForMove=FALSE;
  2292. }