TextureEffects.cpp 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692
  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. #include "stdh.h"
  13. #include <Engine/Graphics/Texture.h>
  14. #include <Engine/Graphics/TextureEffects.h>
  15. #include <Engine/Math/Functions.h>
  16. #include <Engine/Base/Timer.h>
  17. #include <Engine/Base/Statistics_internal.h>
  18. #include <Engine/Templates/DynamicArray.cpp>
  19. #include <Engine/Templates/Stock_CtextureData.h>
  20. #include <Engine/Templates/StaticArray.cpp>
  21. // asm shortcuts
  22. #define O offset
  23. #define Q qword ptr
  24. #define D dword ptr
  25. #define W word ptr
  26. #define B byte ptr
  27. #define ASMOPT 1
  28. static const __int64 mm1LO = 0x0000000000000001;
  29. static const __int64 mm1HI = 0x0000000100000000;
  30. static const __int64 mm1HILO = 0x0000000100000001;
  31. static const __int64 mm0001 = 0x0000000000000001;
  32. static const __int64 mm0010 = 0x0000000000010000;
  33. static const __int64 mm00M0 = 0x00000000FFFF0000;
  34. static __int64 mmBaseWidthShift=0, mmBaseWidth=0, mmBaseWidthMask=0, mmBaseHeightMask=0, mmBaseMasks=0, mmShift=0;
  35. // speed table
  36. static SBYTE asbMod3Sub1Table[256];
  37. static BOOL bTableSet = FALSE;
  38. static CTextureData *_ptdEffect, *_ptdBase;
  39. static PIX _pixTexWidth, _pixTexHeight;
  40. static PIX _pixBufferWidth, _pixBufferHeight;
  41. static ULONG _ulBufferMask;
  42. static INDEX _iWantedMipLevel;
  43. static UBYTE *_pubDrawBuffer;
  44. static SWORD *_pswDrawBuffer;
  45. // randomizer
  46. static ULONG ulRNDSeed;
  47. inline void Randomize( ULONG ulSeed)
  48. {
  49. if( ulSeed==0) ulSeed = 0x87654321;
  50. ulRNDSeed = ulSeed*262147;
  51. };
  52. inline ULONG Rnd(void)
  53. {
  54. ulRNDSeed = ulRNDSeed*262147;
  55. return ulRNDSeed;
  56. };
  57. #define RNDW (Rnd()>>16)
  58. // Initialize the texture effect source.
  59. void CTextureEffectSource::Initialize( class CTextureEffectGlobal *ptegGlobalEffect,
  60. ULONG ulEffectSourceType, PIX pixU0, PIX pixV0,
  61. PIX pixU1, PIX pixV1)
  62. { // remember global effect for cross linking
  63. tes_ptegGlobalEffect = ptegGlobalEffect;
  64. tes_ulEffectSourceType = ulEffectSourceType;
  65. // obtain effect source table for current effect class
  66. struct TextureEffectSourceType *patestSourceEffectTypes =
  67. _ategtTextureEffectGlobalPresets[ ptegGlobalEffect->teg_ulEffectType].tet_atestEffectSourceTypes;
  68. // init for animating
  69. patestSourceEffectTypes[ulEffectSourceType].test_Initialize(this, pixU0, pixV0, pixU1, pixV1);
  70. }
  71. // Animate the texture effect source.
  72. void CTextureEffectSource::Animate(void)
  73. {
  74. // obtain effect source table for current effect class
  75. struct TextureEffectSourceType *patestSourceEffectTypes =
  76. _ategtTextureEffectGlobalPresets[ tes_ptegGlobalEffect->teg_ulEffectType]
  77. .tet_atestEffectSourceTypes;
  78. // animating it
  79. patestSourceEffectTypes[tes_ulEffectSourceType].test_Animate(this);
  80. }
  81. // ----------------------------------------
  82. // SLONG WATER
  83. // ----------------------------------------
  84. inline void PutPixelSLONG_WATER( PIX pixU, PIX pixV, INDEX iHeight)
  85. {
  86. _pswDrawBuffer[(pixV*_pixBufferWidth+pixU)&_ulBufferMask] += iHeight;
  87. }
  88. inline void PutPixel9SLONG_WATER( PIX pixU, PIX pixV, INDEX iHeightMid)
  89. {
  90. INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
  91. INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
  92. PutPixelSLONG_WATER( pixU-1, pixV-1, iHeightDiag);
  93. PutPixelSLONG_WATER( pixU, pixV-1, iHeightSide);
  94. PutPixelSLONG_WATER( pixU+1, pixV-1, iHeightDiag);
  95. PutPixelSLONG_WATER( pixU-1, pixV, iHeightSide);
  96. PutPixelSLONG_WATER( pixU, pixV, iHeightMid);
  97. PutPixelSLONG_WATER( pixU+1, pixV, iHeightSide);
  98. PutPixelSLONG_WATER( pixU-1, pixV+1, iHeightDiag);
  99. PutPixelSLONG_WATER( pixU, pixV+1, iHeightSide);
  100. PutPixelSLONG_WATER( pixU+1, pixV+1, iHeightDiag);
  101. }
  102. // ----------------------------------------
  103. // UBYTE FIRE
  104. // ----------------------------------------
  105. inline void PutPixelUBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeight)
  106. {
  107. PIX pixLoc = (pixV*_pixBufferWidth+pixU) & _ulBufferMask;
  108. _pubDrawBuffer[pixLoc] = Clamp( _pubDrawBuffer[pixLoc] +iHeight, 0L, 255L);
  109. }
  110. inline void PutPixel9UBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeightMid)
  111. {
  112. INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
  113. INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
  114. PutPixelUBYTE_FIRE( pixU-1, pixV-1, iHeightDiag);
  115. PutPixelUBYTE_FIRE( pixU, pixV-1, iHeightSide);
  116. PutPixelUBYTE_FIRE( pixU+1, pixV-1, iHeightDiag);
  117. PutPixelUBYTE_FIRE( pixU-1, pixV, iHeightSide);
  118. PutPixelUBYTE_FIRE( pixU, pixV, iHeightMid);
  119. PutPixelUBYTE_FIRE( pixU+1, pixV, iHeightSide);
  120. PutPixelUBYTE_FIRE( pixU-1, pixV+1, iHeightDiag);
  121. PutPixelUBYTE_FIRE( pixU, pixV+1, iHeightSide);
  122. PutPixelUBYTE_FIRE( pixU+1, pixV+1, iHeightDiag);
  123. }
  124. inline void PutPixel25UBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeightMid)
  125. {
  126. INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
  127. INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
  128. PutPixelUBYTE_FIRE( pixU-2, pixV-2, iHeightDiag);
  129. PutPixelUBYTE_FIRE( pixU-1, pixV-2, iHeightSide);
  130. PutPixelUBYTE_FIRE( pixU, pixV-2, iHeightSide);
  131. PutPixelUBYTE_FIRE( pixU+1, pixV-2, iHeightSide);
  132. PutPixelUBYTE_FIRE( pixU+2, pixV-2, iHeightDiag);
  133. PutPixelUBYTE_FIRE( pixU-2, pixV-1, iHeightSide);
  134. PutPixelUBYTE_FIRE( pixU-1, pixV-1, iHeightSide);
  135. PutPixelUBYTE_FIRE( pixU, pixV-1, iHeightMid);
  136. PutPixelUBYTE_FIRE( pixU+1, pixV-1, iHeightSide);
  137. PutPixelUBYTE_FIRE( pixU+2, pixV-1, iHeightSide);
  138. PutPixelUBYTE_FIRE( pixU-2, pixV, iHeightSide);
  139. PutPixelUBYTE_FIRE( pixU-1, pixV, iHeightMid);
  140. PutPixelUBYTE_FIRE( pixU, pixV, iHeightMid);
  141. PutPixelUBYTE_FIRE( pixU+1, pixV, iHeightMid);
  142. PutPixelUBYTE_FIRE( pixU+2, pixV, iHeightSide);
  143. PutPixelUBYTE_FIRE( pixU-2, pixV+1, iHeightSide);
  144. PutPixelUBYTE_FIRE( pixU-1, pixV+1, iHeightSide);
  145. PutPixelUBYTE_FIRE( pixU, pixV+1, iHeightMid);
  146. PutPixelUBYTE_FIRE( pixU+1, pixV+1, iHeightSide);
  147. PutPixelUBYTE_FIRE( pixU+2, pixV+1, iHeightSide);
  148. PutPixelUBYTE_FIRE( pixU+2, pixV+2, iHeightDiag);
  149. PutPixelUBYTE_FIRE( pixU-1, pixV+2, iHeightSide);
  150. PutPixelUBYTE_FIRE( pixU, pixV+2, iHeightSide);
  151. PutPixelUBYTE_FIRE( pixU+1, pixV+2, iHeightSide);
  152. PutPixelUBYTE_FIRE( pixU-2, pixV+2, iHeightDiag);
  153. }
  154. /////////////////////////////////////////////////////////////////////
  155. // WATER EFFECTS
  156. /////////////////////////////////////////////////////////////////////
  157. #define DISTORSION 3 //3
  158. ///////////////// random surfer
  159. struct Surfer {
  160. FLOAT fU;
  161. FLOAT fV;
  162. FLOAT fAngle;
  163. };
  164. void InitializeRandomSurfer(CTextureEffectSource *ptes,
  165. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  166. {
  167. Surfer &sf =
  168. ((Surfer&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  169. sf.fU = pixU0;
  170. sf.fV = pixV0;
  171. sf.fAngle = RNDW&7;
  172. }
  173. void AnimateRandomSurfer(CTextureEffectSource *ptes)
  174. {
  175. Surfer &sf =
  176. ((Surfer&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  177. PutPixel9SLONG_WATER(sf.fU, sf.fV, 125);
  178. sf.fU += 2*sin(sf.fAngle);
  179. sf.fV += 2*cos(sf.fAngle);
  180. PutPixel9SLONG_WATER(sf.fU, sf.fV, 250);
  181. if((RNDW&15)==0) {
  182. sf.fAngle += 3.14f/7.0f;
  183. }
  184. if((RNDW&15)==0) {
  185. sf.fAngle -= 3.14f/5.0f;
  186. }
  187. }
  188. ///////////////// raindrops
  189. struct Raindrop {
  190. UBYTE pixU;
  191. UBYTE pixV;
  192. SWORD iHeight;
  193. SWORD iIndex;
  194. };
  195. void InitializeRaindrops(CTextureEffectSource *ptes,
  196. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1, int iHeight)
  197. {
  198. for (int iIndex=0; iIndex<5; iIndex++) {
  199. Raindrop &rd =
  200. ((Raindrop&) ptes->tes_tespEffectSourceProperties.tesp_achDummy[iIndex*sizeof(Raindrop)]);
  201. rd.pixU = RNDW&(_pixBufferWidth -1);
  202. rd.pixV = RNDW&(_pixBufferHeight-1);
  203. rd.iHeight = RNDW&iHeight;
  204. rd.iIndex = iIndex*8;
  205. }
  206. }
  207. void InitializeRaindropsStandard(CTextureEffectSource *ptes,
  208. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
  209. InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 255);
  210. }
  211. void InitializeRaindropsBig(CTextureEffectSource *ptes,
  212. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
  213. InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 1023);
  214. }
  215. void InitializeRaindropsSmall(CTextureEffectSource *ptes,
  216. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
  217. InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 31);
  218. }
  219. void AnimateRaindrops(CTextureEffectSource *ptes, int iHeight)
  220. {
  221. for (int iIndex=0; iIndex<5; iIndex++) {
  222. Raindrop &rd =
  223. ((Raindrop&) ptes->tes_tespEffectSourceProperties.tesp_achDummy[iIndex*sizeof(Raindrop)]);
  224. if (rd.iIndex < 48) {
  225. rd.iIndex++;
  226. if (rd.iIndex < 8) {
  227. PutPixel9SLONG_WATER(rd.pixU, rd.pixV, sin(rd.iIndex/4.0f*(-3.14f))*rd.iHeight);
  228. }
  229. } else {
  230. rd.pixU = RNDW&(_pixBufferWidth -1);
  231. rd.pixV = RNDW&(_pixBufferHeight-1);
  232. rd.iHeight = RNDW&iHeight;
  233. rd.iIndex = 0;
  234. }
  235. }
  236. }
  237. void AnimateRaindropsStandard(CTextureEffectSource *ptes) {
  238. AnimateRaindrops(ptes, 255);
  239. }
  240. void AnimateRaindropsBig(CTextureEffectSource *ptes) {
  241. AnimateRaindrops(ptes, 1023);
  242. }
  243. void AnimateRaindropsSmall(CTextureEffectSource *ptes) {
  244. AnimateRaindrops(ptes, 31);
  245. }
  246. ///////////////// oscilator
  247. struct Oscilator {
  248. UBYTE pixU;
  249. UBYTE pixV;
  250. FLOAT fAngle;
  251. };
  252. void InitializeOscilator(CTextureEffectSource *ptes,
  253. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  254. {
  255. Oscilator &os =
  256. ((Oscilator&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  257. os.pixU = pixU0;
  258. os.pixV = pixV0;
  259. os.fAngle = -3.14f;
  260. }
  261. void AnimateOscilator(CTextureEffectSource *ptes)
  262. {
  263. Oscilator &os =
  264. ((Oscilator&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  265. PutPixel9SLONG_WATER(os.pixU, os.pixV, sin(os.fAngle)*150);
  266. os.fAngle += (3.14f/6);
  267. }
  268. ///////////////// Vertical Line
  269. struct VertLine{
  270. UBYTE pixU;
  271. UBYTE pixV;
  272. UWORD uwSize;
  273. FLOAT fAngle;
  274. };
  275. void InitializeVertLine(CTextureEffectSource *ptes,
  276. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  277. {
  278. VertLine &vl =
  279. ((VertLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  280. vl.pixU = pixU0;
  281. vl.pixV = pixV0;
  282. vl.fAngle = -3.14f;
  283. if (pixV0==pixV1) {
  284. vl.uwSize = 16;
  285. } else {
  286. vl.uwSize = abs(pixV1-pixV0);
  287. }
  288. }
  289. void AnimateVertLine(CTextureEffectSource *ptes)
  290. {
  291. VertLine &vl =
  292. ((VertLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  293. PIX pixV = vl.pixV;
  294. for (int iCnt=0; iCnt<vl.uwSize; iCnt++) {
  295. PutPixelSLONG_WATER(vl.pixU, pixV, sin(vl.fAngle)*25);
  296. pixV = (pixV+1)&(_pixBufferHeight-1);
  297. }
  298. vl.fAngle += (3.14f/6);
  299. }
  300. ///////////////// Horizontal Line
  301. struct HortLine{
  302. UBYTE pixU;
  303. UBYTE pixV;
  304. UWORD uwSize;
  305. FLOAT fAngle;
  306. };
  307. void InitializeHortLine(CTextureEffectSource *ptes,
  308. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  309. {
  310. HortLine &hl =
  311. ((HortLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  312. hl.pixU = pixU0;
  313. hl.pixV = pixV0;
  314. hl.fAngle = -3.14f;
  315. if (pixU0==pixU1) {
  316. hl.uwSize = 16;
  317. } else {
  318. hl.uwSize = abs(pixU1-pixU0);
  319. }
  320. }
  321. void AnimateHortLine(CTextureEffectSource *ptes)
  322. {
  323. HortLine &hl =
  324. ((HortLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  325. PIX pixU = hl.pixU;
  326. for (int iCnt=0; iCnt<hl.uwSize; iCnt++) {
  327. PutPixelSLONG_WATER(pixU, hl.pixV, sin(hl.fAngle)*25);
  328. pixU = (pixU+1)&(_pixBufferWidth-1);
  329. }
  330. hl.fAngle += (3.14f/6);
  331. }
  332. /////////////////////////////////////////////////////////////////////
  333. // FIRE EFFECTS
  334. /////////////////////////////////////////////////////////////////////
  335. ///////////////// Fire Point
  336. struct FirePoint{
  337. UBYTE pixU;
  338. UBYTE pixV;
  339. };
  340. void InitializeFirePoint(CTextureEffectSource *ptes,
  341. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  342. {
  343. FirePoint &ft =
  344. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  345. ft.pixU = pixU0;
  346. ft.pixV = pixV0;
  347. }
  348. void AnimateFirePoint(CTextureEffectSource *ptes)
  349. {
  350. FirePoint &ft =
  351. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  352. PutPixel9UBYTE_FIRE(ft.pixU, ft.pixV, 255);
  353. }
  354. void InitializeRandomFirePoint(CTextureEffectSource *ptes,
  355. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  356. {
  357. FirePoint &ft =
  358. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  359. ft.pixU = pixU0;
  360. ft.pixV = pixV0;
  361. }
  362. void AnimateRandomFirePoint(CTextureEffectSource *ptes)
  363. {
  364. FirePoint &ft =
  365. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  366. PutPixel9UBYTE_FIRE(ft.pixU, ft.pixV, RNDW&255);
  367. }
  368. void InitializeFireShakePoint(CTextureEffectSource *ptes,
  369. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  370. {
  371. FirePoint &ft =
  372. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  373. ft.pixU = pixU0;
  374. ft.pixV = pixV0;
  375. }
  376. void AnimateFireShakePoint(CTextureEffectSource *ptes)
  377. {
  378. FirePoint &ft =
  379. ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  380. UBYTE pixU, pixV;
  381. pixU = RNDW%3 - 1;
  382. pixV = RNDW%3 - 1;
  383. PutPixel9UBYTE_FIRE(ft.pixU+pixU, ft.pixV+pixV, 255);
  384. }
  385. ///////////////// Fire Place
  386. #define FIREPLACE_SIZE 60
  387. struct FirePlace{
  388. UBYTE pixU;
  389. UBYTE pixV;
  390. UBYTE ubWidth;
  391. UBYTE aubFire[FIREPLACE_SIZE];
  392. };
  393. void InitializeFirePlace(CTextureEffectSource *ptes,
  394. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  395. {
  396. FirePlace &fp =
  397. ((FirePlace&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  398. fp.pixU = pixU0;
  399. fp.pixV = pixV0;
  400. fp.ubWidth = abs(pixU1-pixU0);
  401. if (fp.ubWidth>FIREPLACE_SIZE) fp.ubWidth=FIREPLACE_SIZE;
  402. if (fp.ubWidth<10) fp.ubWidth = 10;
  403. // clear fire array
  404. for (int iCnt=0; iCnt<fp.ubWidth; iCnt++) {
  405. fp.aubFire[iCnt] = 0;
  406. }
  407. }
  408. void AnimateFirePlace(CTextureEffectSource *ptes)
  409. {
  410. INDEX iIndex;
  411. FirePlace &fp =
  412. ((FirePlace&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  413. ULONG ulRND = RNDW&255;
  414. // match
  415. if (ulRND>200) {
  416. ULONG ulMatchIndex = ulRND%(fp.ubWidth-5);
  417. for (iIndex=0; iIndex<5; iIndex++) {
  418. fp.aubFire[ulMatchIndex+iIndex] = 255;
  419. }
  420. // water
  421. } else if (ulRND<50) {
  422. for (iIndex=0; iIndex<10; iIndex++) {
  423. fp.aubFire[RNDW%fp.ubWidth] = 0;
  424. }
  425. }
  426. // fix fire place
  427. for (iIndex=0; iIndex<fp.ubWidth; iIndex++) {
  428. UBYTE ubFlame = fp.aubFire[iIndex];
  429. // flame is fading ?
  430. if (ubFlame < 50) {
  431. // starting to burn
  432. if (ubFlame > 10) {
  433. ubFlame += RNDW%30; //30
  434. // give more fire
  435. } else {
  436. ubFlame += RNDW%30+30; //30,30
  437. }
  438. }
  439. fp.aubFire[iIndex] = ubFlame;
  440. }
  441. // water on edges
  442. for (iIndex=0; iIndex<4; iIndex++) {
  443. INDEX iWater = RNDW%4;
  444. fp.aubFire[iWater] = 0;
  445. fp.aubFire[fp.ubWidth-1-iWater] = 0;
  446. }
  447. // smooth fire place
  448. for (iIndex=1; iIndex<(fp.ubWidth-1); iIndex++) {
  449. fp.aubFire[iIndex] = (fp.aubFire[iIndex-1]+fp.aubFire[iIndex]+fp.aubFire[iIndex+1])/3;
  450. }
  451. // draw fire place in buffer
  452. for (iIndex=0; iIndex<fp.ubWidth; iIndex++) {
  453. PutPixel9UBYTE_FIRE(fp.pixU+iIndex, fp.pixV, fp.aubFire[iIndex]);
  454. }
  455. }
  456. ///////////////// Fire Roler
  457. struct FireRoler{
  458. UBYTE pixU;
  459. UBYTE pixV;
  460. //FLOAT fRadius;
  461. FLOAT fRadiusU;
  462. FLOAT fRadiusV;
  463. FLOAT fAngle;
  464. FLOAT fAngleAdd;
  465. };
  466. void InitializeFireRoler(CTextureEffectSource *ptes,
  467. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  468. {
  469. FireRoler &fr =
  470. ((FireRoler&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  471. fr.pixU = pixU0;
  472. fr.pixV = pixV0;
  473. if (pixU0==pixU1 && pixV0==pixV1) {
  474. //fr.fRadius = 3;
  475. fr.fRadiusU = 3;
  476. fr.fRadiusV = 3;
  477. fr.fAngleAdd = (3.14f/6);
  478. } else {
  479. //fr.fRadius = sqrt((pixU1-pixU0)*(pixU1-pixU0) + (pixV1-pixV0)*(pixV1-pixV0));
  480. fr.fRadiusU = pixU1-pixU0;
  481. fr.fRadiusV = pixV1-pixV0;
  482. //fr.fAngleAdd = (3.14f/((fr.fRadius)*2));
  483. fr.fAngleAdd = (3.14f/(Abs(fr.fRadiusU)+Abs(fr.fRadiusV)));
  484. }
  485. fr.fAngle = 0;
  486. }
  487. void AnimateFireRoler(CTextureEffectSource *ptes)
  488. {
  489. FireRoler &fr =
  490. ((FireRoler&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  491. PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
  492. sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 255);
  493. fr.fAngle += fr.fAngleAdd;
  494. PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
  495. sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 200);
  496. fr.fAngle += fr.fAngleAdd;
  497. PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
  498. sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 150);
  499. fr.fAngle += fr.fAngleAdd;
  500. }
  501. ///////////////// Fire Fall
  502. #define FIREFALL_POINTS 100
  503. struct FireFall{
  504. UBYTE pixU;
  505. UBYTE pixV;
  506. ULONG ulWidth;
  507. ULONG ulPointToReinitialize;
  508. };
  509. struct FireFallPixel{
  510. UBYTE pixU;
  511. UBYTE pixV;
  512. UBYTE ubSpeed;
  513. };
  514. void InitializeFireFall(CTextureEffectSource *ptes,
  515. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  516. {
  517. FireFall &ff =
  518. ((FireFall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  519. ff.pixU = pixU0;
  520. ff.pixV = pixV0;
  521. if (pixU0==pixU1) {
  522. ff.ulWidth = 15;
  523. } else {
  524. ff.ulWidth = abs(pixU1-pixU0);
  525. }
  526. // initialize fall points
  527. ptes->tes_atepPixels.New(FIREFALL_POINTS);
  528. ff.ulPointToReinitialize = 0;
  529. for (INDEX iIndex=0; iIndex<FIREFALL_POINTS; iIndex++) {
  530. FireFallPixel &ffp = ((FireFallPixel&) ptes->tes_atepPixels[iIndex]);
  531. ffp.pixU = ff.pixU+(RNDW%ff.ulWidth);
  532. ffp.pixV = ff.pixV+(RNDW%_pixBufferHeight);
  533. ffp.ubSpeed = (RNDW&1)+2;
  534. }
  535. }
  536. void AnimateFireFall(CTextureEffectSource *ptes)
  537. {
  538. FireFall &ff =
  539. ((FireFall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  540. // animate fall points
  541. for (INDEX iIndex=0; iIndex<FIREFALL_POINTS; iIndex++) {
  542. FireFallPixel &ffp = ((FireFallPixel&) ptes->tes_atepPixels[iIndex]);
  543. // fall from fall
  544. int iHeight = (RNDW&3)*64 + 40;
  545. if (ffp.ubSpeed == 2) {
  546. PutPixelUBYTE_FIRE(ffp.pixU+(RNDW%3)-1, ffp.pixV, iHeight);
  547. PutPixelUBYTE_FIRE(ffp.pixU+(RNDW%3)-1, ffp.pixV+1, iHeight-40);
  548. } else {
  549. PutPixelUBYTE_FIRE(ffp.pixU, ffp.pixV, iHeight);
  550. PutPixelUBYTE_FIRE(ffp.pixU, ffp.pixV+1, iHeight-40);
  551. }
  552. ffp.pixV+=ffp.ubSpeed;
  553. // when falled down reinitialize
  554. if (ffp.pixV >= _pixBufferHeight) {
  555. if (ff.ulPointToReinitialize == iIndex) {
  556. ff.ulPointToReinitialize++;
  557. if (ff.ulPointToReinitialize >= FIREFALL_POINTS) ff.ulPointToReinitialize = 0;
  558. ffp.pixU = ff.pixU+(RNDW%ff.ulWidth);
  559. ffp.pixV -= _pixBufferHeight;
  560. ffp.ubSpeed = (RNDW&1)+2;
  561. } else {
  562. ffp.pixV -= _pixBufferHeight;
  563. }
  564. }
  565. }
  566. }
  567. ///////////////// Fire Fountain
  568. #define FIREFOUNTAIN_POINTS 100
  569. struct FireFountain{
  570. UBYTE pixU;
  571. UBYTE pixV;
  572. ULONG ulWidth;
  573. ULONG ulBaseHeight;
  574. ULONG ulRandomHeight;
  575. };
  576. struct FireFountainPixel{
  577. SWORD pixU;
  578. SWORD pixV;
  579. UBYTE pixLastU;
  580. UBYTE pixLastV;
  581. SWORD sbSpeedU;
  582. SWORD sbSpeedV;
  583. };
  584. void InitializeFireFountain(CTextureEffectSource *ptes,
  585. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  586. {
  587. FireFountain &ff =
  588. ((FireFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  589. ff.pixU = pixU0;
  590. ff.pixV = pixV0;
  591. // fountain width
  592. if (pixU0==pixU1) {
  593. ff.ulWidth = 31;
  594. } else {
  595. ff.ulWidth = abs(pixU1-pixU0)*2;
  596. }
  597. // fountain height
  598. if (pixV0==pixV1) {
  599. ff.ulBaseHeight = 120;
  600. ff.ulRandomHeight = 40;
  601. } else {
  602. ff.ulBaseHeight = abs(pixV1-pixV0)*3;
  603. ff.ulRandomHeight = abs(pixV1-pixV0);
  604. }
  605. // initialize fountain points
  606. ptes->tes_atepPixels.New(FIREFOUNTAIN_POINTS*2);
  607. for (INDEX iIndex=0; iIndex<FIREFOUNTAIN_POINTS*2; iIndex+=2) {
  608. FireFountainPixel &ffp = ((FireFountainPixel&) ptes->tes_atepPixels[iIndex]);
  609. ffp.pixU = (ff.pixU)<<6;
  610. ffp.pixV = (RNDW%(_pixBufferHeight-(_pixBufferHeight>>3))+(_pixBufferHeight>>3))<<6;
  611. ffp.pixLastU = (ffp.pixU)>>6;
  612. ffp.pixLastV = (ffp.pixV)>>6;
  613. ffp.sbSpeedU = 0;
  614. ffp.sbSpeedV = 0;
  615. }
  616. }
  617. void AnimateFireFountain(CTextureEffectSource *ptes)
  618. {
  619. FireFountain &ff =
  620. ((FireFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  621. // animate fountain points
  622. for (INDEX iIndex=0; iIndex<FIREFOUNTAIN_POINTS*2; iIndex+=2) {
  623. FireFountainPixel &ffp = ((FireFountainPixel&) ptes->tes_atepPixels[iIndex]);
  624. // fall from fountain
  625. PutPixelUBYTE_FIRE((ffp.pixU)>>6, (ffp.pixV)>>6, 200);
  626. PutPixelUBYTE_FIRE(ffp.pixLastU, ffp.pixLastV, 150);
  627. // move pixel
  628. ffp.pixLastU = (ffp.pixU)>>6;
  629. ffp.pixLastV = (ffp.pixV)>>6;
  630. ffp.pixU+=ffp.sbSpeedU;
  631. ffp.pixV-=ffp.sbSpeedV;
  632. ffp.sbSpeedV-=8;
  633. // when falled down reinitialize
  634. if ((ffp.pixV>>6) >= (_pixBufferHeight-5)) {
  635. ffp.pixU = (ff.pixU)<<6;
  636. ffp.pixV = (ff.pixV)<<6;
  637. ffp.pixLastU = (ffp.pixU)>>6;
  638. ffp.pixLastV = (ffp.pixV)>>6;
  639. ffp.sbSpeedU = (RNDW%ff.ulWidth)-(ff.ulWidth/2-1);
  640. ffp.sbSpeedV = (RNDW%ff.ulRandomHeight)+ff.ulBaseHeight;
  641. }
  642. }
  643. }
  644. ///////////////// Fire Fountain
  645. #define FIRESIDEFOUNTAIN_POINTS 100
  646. struct FireSideFountain{
  647. UBYTE pixU;
  648. UBYTE pixV;
  649. ULONG ulBaseWidth;
  650. ULONG ulRandomWidth;
  651. ULONG ulSide;
  652. };
  653. struct FireSideFountainPixel{
  654. SWORD pixU;
  655. SWORD pixV;
  656. UBYTE pixLastU;
  657. UBYTE pixLastV;
  658. SWORD sbSpeedU;
  659. SWORD sbSpeedV;
  660. };
  661. void InitializeFireSideFountain(CTextureEffectSource *ptes,
  662. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  663. {
  664. FireSideFountain &fsf =
  665. ((FireSideFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  666. fsf.pixU = pixU0;
  667. fsf.pixV = pixV0;
  668. // fountain width
  669. if (pixU0==pixU1) {
  670. fsf.ulBaseWidth = 80;
  671. fsf.ulRandomWidth = 40;
  672. fsf.ulSide = (pixU0>(_pixBufferWidth/2));
  673. } else {
  674. fsf.ulBaseWidth = abs(pixU1-pixU0)*2;
  675. fsf.ulRandomWidth = abs(pixU1-pixU0);
  676. fsf.ulSide = (pixU1<pixU0);
  677. }
  678. // initialize fountain points
  679. ptes->tes_atepPixels.New(FIRESIDEFOUNTAIN_POINTS*2);
  680. for (INDEX iIndex=0; iIndex<FIRESIDEFOUNTAIN_POINTS*2; iIndex+=2) {
  681. FireSideFountainPixel &fsfp = ((FireSideFountainPixel&) ptes->tes_atepPixels[iIndex]);
  682. fsfp.pixU = (fsf.pixU)<<6;
  683. fsfp.pixV = (RNDW%(_pixBufferHeight-(_pixBufferHeight>>3))+(_pixBufferHeight>>3))<<6;
  684. fsfp.pixLastU = (fsfp.pixU)>>6;
  685. fsfp.pixLastV = (fsfp.pixV)>>6;
  686. fsfp.sbSpeedU = 0;
  687. fsfp.sbSpeedV = 0;
  688. }
  689. }
  690. void AnimateFireSideFountain(CTextureEffectSource *ptes)
  691. {
  692. FireSideFountain &fsf =
  693. ((FireSideFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  694. // animate fountain points
  695. for (INDEX iIndex=0; iIndex<FIRESIDEFOUNTAIN_POINTS*2; iIndex+=2) {
  696. FireSideFountainPixel &fsfp = ((FireSideFountainPixel&) ptes->tes_atepPixels[iIndex]);
  697. // fall from fountain
  698. PutPixelUBYTE_FIRE((fsfp.pixU)>>6, (fsfp.pixV)>>6, 200);
  699. PutPixelUBYTE_FIRE(fsfp.pixLastU, fsfp.pixLastV, 150);
  700. // move pixel
  701. fsfp.pixLastU = (fsfp.pixU)>>6;
  702. fsfp.pixLastV = (fsfp.pixV)>>6;
  703. fsfp.pixU+=fsfp.sbSpeedU;
  704. fsfp.pixV-=fsfp.sbSpeedV;
  705. fsfp.sbSpeedV-=8;
  706. // when falled down reinitialize
  707. if ((fsfp.pixV>>6) >= (_pixBufferHeight-5)) {
  708. fsfp.pixU = (fsf.pixU)<<6;
  709. fsfp.pixV = (fsf.pixV)<<6;
  710. fsfp.pixLastU = (fsfp.pixU)>>6;
  711. fsfp.pixLastV = (fsfp.pixV)>>6;
  712. fsfp.sbSpeedU = (RNDW%fsf.ulRandomWidth)+fsf.ulBaseWidth;
  713. if (fsf.ulSide) {
  714. fsfp.sbSpeedU = -fsfp.sbSpeedU;
  715. }
  716. fsfp.sbSpeedV = 0;
  717. }
  718. }
  719. }
  720. ///////////////// Fire Lightning
  721. struct FireLightning{
  722. FLOAT fpixUFrom;
  723. FLOAT fpixVFrom;
  724. FLOAT fpixUTo;
  725. FLOAT fpixVTo;
  726. FLOAT fvU;
  727. FLOAT fvV;
  728. FLOAT fvNormalU;
  729. FLOAT fvNormalV;
  730. FLOAT fDistance;
  731. SLONG slCnt;
  732. };
  733. void InitializeFireLightning(CTextureEffectSource *ptes,
  734. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  735. {
  736. FireLightning &fl =
  737. ((FireLightning&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  738. fl.fpixUFrom = (FLOAT) pixU0;
  739. fl.fpixVFrom = (FLOAT) pixV0;
  740. if (pixU0==pixU1 && pixV0==pixV1) {
  741. fl.fpixUTo = Abs((FLOAT)_pixBufferWidth -fl.fpixUFrom);
  742. fl.fpixVTo = Abs((FLOAT)_pixBufferHeight-fl.fpixVFrom);
  743. } else {
  744. fl.fpixUTo = (FLOAT) pixU1;
  745. fl.fpixVTo = (FLOAT) pixV1;
  746. }
  747. fl.fDistance = sqrt((fl.fpixUTo-fl.fpixUFrom)*(fl.fpixUTo-fl.fpixUFrom)+
  748. (fl.fpixVTo-fl.fpixVFrom)*(fl.fpixVTo-fl.fpixVFrom));
  749. // vector
  750. fl.fvU = (fl.fpixUTo-fl.fpixUFrom)/fl.fDistance;
  751. fl.fvV = (fl.fpixVTo-fl.fpixVFrom)/fl.fDistance;
  752. // normal vector
  753. fl.fvNormalU = -fl.fvV;
  754. fl.fvNormalV = fl.fvU;
  755. // frame counter
  756. fl.slCnt = 2;
  757. }
  758. void AnimateFireLightning(CTextureEffectSource *ptes)
  759. {
  760. FLOAT fU, fV, fLastU, fLastV;
  761. FLOAT fDU, fDV, fCnt;
  762. SLONG slRND;
  763. ULONG ulDist;
  764. FireLightning &fl =
  765. ((FireLightning&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  766. // last point -> starting point
  767. fLastU = fl.fpixUFrom;
  768. fLastV = fl.fpixVFrom;
  769. fl.slCnt--;
  770. if (fl.slCnt == 0) {
  771. ulDist = 0;
  772. while ((FLOAT)ulDist<fl.fDistance) {
  773. // go away from source point to destination point
  774. ulDist += (RNDW%5)+5;
  775. if ((FLOAT)ulDist>=fl.fDistance) {
  776. // move point to line end
  777. fU = fl.fpixUTo;
  778. fV = fl.fpixVTo;
  779. } else {
  780. // move point on line
  781. fU = fl.fpixUFrom + fl.fvU*(FLOAT)ulDist;
  782. fV = fl.fpixVFrom + fl.fvV*(FLOAT)ulDist;
  783. // move point offset on normal line
  784. slRND = (SLONG) (RNDW%11)-5;
  785. fU += fl.fvNormalU*(FLOAT)slRND;
  786. fV += fl.fvNormalV*(FLOAT)slRND;
  787. }
  788. // draw line
  789. fDU = fU-fLastU;
  790. fDV = fV-fLastV;
  791. if (Abs(fDU)>Abs(fDV)) fCnt = Abs(fDU);
  792. else fCnt = Abs(fDV);
  793. fDU = fDU/fCnt;
  794. fDV = fDV/fCnt;
  795. while (fCnt>0.0f) {
  796. PutPixelUBYTE_FIRE((PIX) fLastU, (PIX) fLastV, 255);
  797. fLastU += fDU;
  798. fLastV += fDV;
  799. fCnt -= 1;
  800. }
  801. // store last point
  802. fLastU = fU;
  803. fLastV = fV;
  804. }
  805. fl.slCnt = 2;
  806. }
  807. }
  808. ///////////////// Fire Lightning Ball
  809. #define FIREBALL_LIGHTNINGS 2
  810. struct FireLightningBall{
  811. FLOAT fpixU;
  812. FLOAT fpixV;
  813. FLOAT fRadiusU;
  814. FLOAT fRadiusV;
  815. };
  816. void InitializeFireLightningBall(CTextureEffectSource *ptes,
  817. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  818. {
  819. FireLightningBall &flb =
  820. ((FireLightningBall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  821. flb.fpixU = (FLOAT) pixU0;
  822. flb.fpixV = (FLOAT) pixV0;
  823. if (pixU0==pixU1 && pixV0==pixV1) {
  824. flb.fRadiusU = 20;
  825. flb.fRadiusV = 20;
  826. } else {
  827. flb.fRadiusU = pixU1-pixU0;
  828. flb.fRadiusV = pixV1-pixV0;
  829. }
  830. }
  831. void AnimateFireLightningBall(CTextureEffectSource *ptes)
  832. {
  833. FLOAT fU, fV, fLastU, fLastV, fvU, fvV, fvNormalU, fvNormalV;
  834. FLOAT fDU, fDV, fCnt, fDistance;
  835. FLOAT fDestU, fDestV, fAngle;
  836. SLONG slRND;
  837. ULONG ulDist;
  838. FireLightningBall &flb =
  839. ((FireLightningBall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  840. for (int iBalls=0; iBalls<FIREBALL_LIGHTNINGS; iBalls++) {
  841. // last point -> starting point
  842. fLastU = flb.fpixU;
  843. fLastV = flb.fpixV;
  844. // destination point
  845. fAngle = (FLOAT) RNDW/10000;
  846. fDestU = flb.fpixU + flb.fRadiusU*cos(fAngle);
  847. fDestV = flb.fpixV + flb.fRadiusV*sin(fAngle);
  848. fDistance = sqrt((fDestU-fLastU)*(fDestU-fLastU)+
  849. (fDestV-fLastV)*(fDestV-fLastV));
  850. // vector
  851. fvU = (fDestU-fLastU)/fDistance;
  852. fvV = (fDestV-fLastV)/fDistance;
  853. // normal vector
  854. fvNormalU = -fvV;
  855. fvNormalV = fvU;
  856. ulDist = 0;
  857. while ((FLOAT)ulDist<fDistance) {
  858. // go away from source point to destination point
  859. ulDist += (RNDW%5)+5;
  860. if ((FLOAT)ulDist>=fDistance) {
  861. // move point on line
  862. fU = fDestU;
  863. fV = fDestV;
  864. } else {
  865. // move point on line
  866. fU = flb.fpixU + fvU*(FLOAT)ulDist;
  867. fV = flb.fpixV + fvV*(FLOAT)ulDist;
  868. // move point offset on normal line
  869. slRND = (SLONG) (RNDW%11)-5;
  870. fU += fvNormalU*(FLOAT)slRND;
  871. fV += fvNormalV*(FLOAT)slRND;
  872. }
  873. // draw line
  874. fDU = fU-fLastU;
  875. fDV = fV-fLastV;
  876. // counter
  877. if (Abs(fDU)>Abs(fDV)) fCnt = Abs(fDU);
  878. else fCnt = Abs(fDV);
  879. fDU = fDU/fCnt;
  880. fDV = fDV/fCnt;
  881. while (fCnt>0.0f) {
  882. PutPixelUBYTE_FIRE((PIX) fLastU, (PIX) fLastV, 255);
  883. fLastU += fDU;
  884. fLastV += fDV;
  885. fCnt -= 1;
  886. }
  887. // store last point
  888. fLastU = fU;
  889. fLastV = fV;
  890. }
  891. }
  892. }
  893. ///////////////// Fire Smoke
  894. #define SMOKE_POINTS 50
  895. struct FireSmoke{
  896. FLOAT fpixU;
  897. FLOAT fpixV;
  898. };
  899. struct FireSmokePoint{
  900. FLOAT fpixU;
  901. FLOAT fpixV;
  902. FLOAT fSpeedV;
  903. };
  904. void InitializeFireSmoke(CTextureEffectSource *ptes,
  905. PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
  906. {
  907. FireSmoke &fs =
  908. ((FireSmoke&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  909. fs.fpixU = (FLOAT) pixU0;
  910. fs.fpixV = (FLOAT) pixV0;
  911. if (pixU0==pixU1 && pixV0==pixV1) {
  912. } else {
  913. }
  914. // initialize smoke points
  915. ptes->tes_atepPixels.New(SMOKE_POINTS*2);
  916. for (INDEX iIndex=0; iIndex<SMOKE_POINTS*2; iIndex+=2) {
  917. FireSmokePoint &fsp = ((FireSmokePoint&) ptes->tes_atepPixels[iIndex]);
  918. fsp.fpixU = FLOAT (pixU0 + (iIndex-(SMOKE_POINTS))/8);
  919. fsp.fpixV = FLOAT (pixV0);
  920. fsp.fSpeedV = 0.0f;
  921. }
  922. }
  923. void AnimateFireSmoke(CTextureEffectSource *ptes)
  924. {
  925. int iHeat;
  926. FLOAT fRatio = 32.0f / (FLOAT)_pixBufferHeight;
  927. UBYTE pixU, pixV;
  928. FireSmoke &fs =
  929. ((FireSmoke&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
  930. // animate smoke points
  931. for (INDEX iIndex=0; iIndex<SMOKE_POINTS*2; iIndex+=2) {
  932. FireSmokePoint &fsp = ((FireSmokePoint&) ptes->tes_atepPixels[iIndex]);
  933. pixU = RNDW%3 - 1;
  934. pixV = RNDW%3 - 1;
  935. if (fsp.fSpeedV<0.1f) {
  936. PutPixelUBYTE_FIRE((PIX) fsp.fpixU, (PIX) fsp.fpixV, RNDW%128);
  937. } else {
  938. iHeat = int(fsp.fpixV*fRatio+1);
  939. PutPixel25UBYTE_FIRE((PIX) fsp.fpixU+pixU, (PIX) fsp.fpixV+pixV, RNDW%iHeat);
  940. }
  941. // start moving up
  942. if (fsp.fSpeedV<0.1f && (RNDW&255)==0) {
  943. fsp.fSpeedV = 1.0f;
  944. }
  945. // move up
  946. fsp.fpixV -= fsp.fSpeedV;
  947. // at the end of texture go on bottom
  948. if (fsp.fpixV<=(FLOAT)_pixBufferHeight) {
  949. fsp.fpixV = fs.fpixV;
  950. fsp.fSpeedV = 0.0f;
  951. }
  952. }
  953. }
  954. ///////////////// Water
  955. void InitializeWater(void)
  956. {
  957. Randomize( (ULONG)(_pTimer->GetHighPrecisionTimer().GetMilliseconds()));
  958. }
  959. /*******************************
  960. Water Animation
  961. ********************************/
  962. static void AnimateWater( SLONG slDensity)
  963. {
  964. _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
  965. /////////////////////////////////// move water
  966. SWORD *pNew = (SWORD*)_ptdEffect->td_pubBuffer1;
  967. SWORD *pOld = (SWORD*)_ptdEffect->td_pubBuffer2;
  968. PIX pixV, pixU;
  969. PIX pixOffset, iNew;
  970. SLONG slLineAbove, slLineBelow, slLineLeft, slLineRight;
  971. // inner rectangle (without 1 pixel top and bottom line)
  972. pixOffset = _pixBufferWidth + 1;
  973. for( pixV=_pixBufferHeight-2; pixV>0; pixV--) {
  974. for( pixU=_pixBufferWidth; pixU>0; pixU--) {
  975. iNew = (( (SLONG)pOld[pixOffset - _pixBufferWidth]
  976. + (SLONG)pOld[pixOffset + _pixBufferWidth]
  977. + (SLONG)pOld[pixOffset - 1]
  978. + (SLONG)pOld[pixOffset + 1]
  979. ) >> 1)
  980. - (SLONG)pNew[pixOffset];
  981. pNew[pixOffset] = iNew - (iNew >> slDensity);
  982. pixOffset++;
  983. }
  984. }
  985. // upper horizontal border (without corners)
  986. slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  987. slLineBelow = _pixBufferWidth + 1;
  988. slLineLeft = 0;
  989. slLineRight = 2;
  990. pixOffset = 1;
  991. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  992. iNew = (( (SLONG)pOld[slLineAbove]
  993. + (SLONG)pOld[slLineBelow]
  994. + (SLONG)pOld[slLineLeft]
  995. + (SLONG)pOld[slLineRight]
  996. ) >> 1)
  997. - (SLONG)pNew[pixOffset];
  998. pNew[pixOffset] = iNew - (iNew >> slDensity);
  999. slLineAbove++;
  1000. slLineBelow++;
  1001. slLineLeft++;
  1002. slLineRight++;
  1003. pixOffset++;
  1004. }
  1005. // lower horizontal border (without corners)
  1006. slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
  1007. slLineBelow = 1;
  1008. slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
  1009. slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
  1010. pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1011. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1012. iNew = (( (SLONG)pOld[slLineAbove]
  1013. + (SLONG)pOld[slLineBelow]
  1014. + (SLONG)pOld[slLineLeft]
  1015. + (SLONG)pOld[slLineRight]
  1016. ) >> 1)
  1017. - (SLONG)pNew[pixOffset];
  1018. pNew[pixOffset] = iNew - (iNew >> slDensity);
  1019. slLineAbove++;
  1020. slLineBelow++;
  1021. slLineLeft++;
  1022. slLineRight++;
  1023. pixOffset++;
  1024. }
  1025. // corner ( 0, 0)
  1026. iNew = (( (SLONG)pOld[_pixBufferWidth]
  1027. + (SLONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
  1028. + (SLONG)pOld[1]
  1029. + (SLONG)pOld[_pixBufferWidth-1]
  1030. ) >> 1)
  1031. - (SLONG)pNew[0];
  1032. pNew[0] = iNew - (iNew >> slDensity);
  1033. // corner ( 0, _pixBufferWidth)
  1034. iNew = (( (SLONG)pOld[(2*_pixBufferWidth) - 1]
  1035. + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1036. + (SLONG)pOld[0]
  1037. + (SLONG)pOld[_pixBufferWidth-2]
  1038. ) >> 1)
  1039. - (SLONG)pNew[_pixBufferWidth-1];
  1040. pNew[_pixBufferWidth-1] = iNew - (iNew >> slDensity);
  1041. // corner ( _pixBufferHeight, 0)
  1042. iNew = (( (SLONG)pOld[0]
  1043. + (SLONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth]
  1044. + (SLONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1]
  1045. + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1046. ) >> 1)
  1047. - (SLONG)pNew[(_pixBufferHeight-1)*_pixBufferWidth];
  1048. pNew[(_pixBufferHeight-1)*_pixBufferWidth] = iNew - (iNew >> slDensity);
  1049. // corner ( _pixBufferHeight, _pixBufferWidth)
  1050. iNew = (( (SLONG)pOld[_pixBufferWidth-1]
  1051. + (SLONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1]
  1052. + (SLONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
  1053. + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
  1054. ) >> 1)
  1055. - (SLONG)pNew[(_pixBufferHeight*_pixBufferWidth) - 1];
  1056. pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = iNew - (iNew >> slDensity);
  1057. // swap buffers
  1058. Swap( _ptdEffect->td_pubBuffer1, _ptdEffect->td_pubBuffer2);
  1059. _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
  1060. }
  1061. //////////////////////////// displace texture
  1062. #define PIXEL(u,v) pulTextureBase[ ((u)&(SLONG&)mmBaseWidthMask) + ((v)&(SLONG&)mmBaseHeightMask) *pixBaseWidth]
  1063. #pragma warning(disable: 4731)
  1064. static void RenderWater(void)
  1065. {
  1066. _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
  1067. // get textures' parameters
  1068. ULONG *pulTexture = _ptdEffect->td_pulFrames;
  1069. PIX pixBaseWidth = _ptdBase->GetPixWidth();
  1070. PIX pixBaseHeight = _ptdBase->GetPixHeight();
  1071. ULONG *pulTextureBase = _ptdBase->td_pulFrames
  1072. + GetMipmapOffset( _iWantedMipLevel, pixBaseWidth, pixBaseHeight);
  1073. pixBaseWidth >>= _iWantedMipLevel;
  1074. pixBaseHeight >>= _iWantedMipLevel;
  1075. mmBaseWidthMask = pixBaseWidth -1;
  1076. mmBaseHeightMask = pixBaseHeight-1;
  1077. ASSERT( _ptdEffect->td_pulFrames!=NULL && _ptdBase->td_pulFrames!=NULL);
  1078. SWORD *pswHeightMap = (SWORD*)_ptdEffect->td_pubBuffer1; // height map pointer
  1079. // copy top 2 lines from height map to bottom (so no mask offset will be needed)
  1080. memcpy( (void*)(pswHeightMap+(_pixBufferHeight*_pixBufferWidth)), (void*)pswHeightMap,
  1081. _pixBufferWidth*sizeof(SWORD)*2);
  1082. // execute corresponding displace routine
  1083. if( _pixBufferWidth >= _pixTexWidth)
  1084. { // SUB-SAMPLING
  1085. SLONG slHeightMapStep, slHeightRowStep;
  1086. #if ASMOPT == 1
  1087. __asm {
  1088. push ebx
  1089. bsf ecx,D [_pixTexWidth]
  1090. dec ecx
  1091. mov eax,D [_pixBufferWidth]
  1092. sar eax,cl
  1093. mov D [slHeightMapStep],eax
  1094. bsf edx,eax
  1095. add edx,DISTORSION+2-1
  1096. mov D [mmShift],edx
  1097. sub eax,2
  1098. imul eax,D [_pixBufferWidth]
  1099. mov D [slHeightRowStep],eax
  1100. mov eax,D [pixBaseWidth]
  1101. mov edx,D [pixBaseHeight]
  1102. shl edx,16
  1103. or eax,edx
  1104. sub eax,0x00010001
  1105. mov D [mmBaseMasks],eax
  1106. mov eax,D [pixBaseWidth]
  1107. shl eax,16
  1108. or eax,1
  1109. mov D [mmBaseWidth],eax
  1110. mov ebx,D [pswHeightMap]
  1111. mov esi,D [pulTextureBase]
  1112. mov edi,D [pulTexture]
  1113. pxor mm6,mm6 // MM5 = 0 | 0 || pixV | pixU
  1114. mov eax,D [_pixBufferWidth]
  1115. mov edx,D [_pixTexHeight]
  1116. rowLoop:
  1117. push edx
  1118. mov ecx,D [_pixTexWidth]
  1119. pixLoop:
  1120. movd mm1,D [ebx]
  1121. movd mm3,D [ebx+ eax*2]
  1122. movq mm2,mm1
  1123. psubw mm3,mm1
  1124. pslld mm1,16
  1125. psubw mm2,mm1
  1126. pand mm2,Q [mm00M0]
  1127. por mm2,mm3
  1128. psraw mm2,Q [mmShift]
  1129. paddw mm2,mm6
  1130. pand mm2,Q [mmBaseMasks]
  1131. pmaddwd mm2,Q [mmBaseWidth]
  1132. movd edx,mm2
  1133. mov edx,D [esi+ edx*4]
  1134. mov D [edi],edx
  1135. // advance to next texture pixel
  1136. add ebx,D [slHeightMapStep]
  1137. add edi,4
  1138. paddd mm6,Q [mm0001]
  1139. dec ecx
  1140. jnz pixLoop
  1141. // advance to next texture row
  1142. pop edx
  1143. add ebx,D [slHeightRowStep]
  1144. paddd mm6,Q [mm0010]
  1145. dec edx
  1146. jnz rowLoop
  1147. emms
  1148. pop ebx
  1149. }
  1150. #else
  1151. PIX pixPos, pixDU, pixDV;
  1152. slHeightMapStep = _pixBufferWidth/pixBaseWidth
  1153. slHeightRowStep = (slHeightMapStep-1)*_pixBufferWidth;
  1154. mmShift = DISTORSION+ FastLog2(slHeightMapStep) +2;
  1155. for( PIX pixV=0; pixV<_pixTexHeight; pixV++)
  1156. { // row loop
  1157. for( PIX pixU=0; pixU<_pixTexWidth; pixU++)
  1158. { // texel loop
  1159. pixPos = pswHeightMap[0];
  1160. pixDU = (pswHeightMap[1] - pixPos) >>(SLONG&)mmShift;
  1161. pixDV = (pswHeightMap[_pixBufferWidth] - pixPos) >>(SLONG&)mmShift;
  1162. pixDU = (pixU +pixDU) & (SLONG&)mmBaseWidthMask;
  1163. pixDV = (pixV +pixDV) & (SLONG&)mmBaseHeightMask;
  1164. *pulTexture++ = pulTextureBase[pixDV*pixBaseWidth + pixDU];
  1165. // advance to next texel in height map
  1166. pswHeightMap += slHeightMapStep;
  1167. }
  1168. pswHeightMap += slHeightRowStep;
  1169. }
  1170. #endif
  1171. }
  1172. else if( _pixBufferWidth*2 == _pixTexWidth)
  1173. { // BILINEAR SUPER-SAMPLING 2
  1174. #if ASMOPT == 1
  1175. __asm {
  1176. push ebx
  1177. bsf eax,D [pixBaseWidth]
  1178. mov edx,32
  1179. sub edx,eax
  1180. mov D [mmBaseWidthShift],edx
  1181. movq mm0,Q [mmBaseHeightMask]
  1182. psllq mm0,32
  1183. por mm0,Q [mmBaseWidthMask]
  1184. movq Q [mmBaseMasks],mm0
  1185. pxor mm6,mm6 // MM6 = pixV|pixU
  1186. mov ebx,D [pswHeightMap]
  1187. mov esi,D [pulTextureBase]
  1188. mov edi,D [pulTexture]
  1189. mov edx,D [_pixBufferHeight]
  1190. rowLoop2:
  1191. push edx
  1192. mov edx,D [_pixTexWidth]
  1193. mov ecx,D [_pixBufferWidth]
  1194. pixLoop2:
  1195. mov eax,D [_pixBufferWidth]
  1196. movd mm1,D [ebx+ 2]
  1197. movd mm0,D [ebx+ eax*2]
  1198. psllq mm0,32
  1199. por mm1,mm0
  1200. movd mm0,D [ebx]
  1201. punpckldq mm0,mm0
  1202. psubd mm1,mm0
  1203. movq mm0,mm6
  1204. pslld mm0,DISTORSION+1+1
  1205. paddd mm1,mm0 // MM1 = slV_00 | slU_00
  1206. movd mm2,D [ebx+ 4]
  1207. movd mm0,D [ebx+ eax*2 +2]
  1208. psllq mm0,32
  1209. por mm2,mm0
  1210. movd mm0,D [ebx+ 2]
  1211. punpckldq mm0,mm0
  1212. psubd mm2,mm0
  1213. movq mm0,mm6
  1214. paddd mm0,Q [mm1LO]
  1215. pslld mm0,DISTORSION+1+1
  1216. paddd mm2,mm0 // MM2 = slV_01 | slU_01
  1217. movd mm3,D [ebx+ eax*2 +2]
  1218. movd mm0,D [ebx+ eax*4]
  1219. psllq mm0,32
  1220. por mm3,mm0
  1221. movd mm0,D [ebx+ eax*2]
  1222. punpckldq mm0,mm0
  1223. psubd mm3,mm0
  1224. movq mm0,mm6
  1225. paddd mm0,Q [mm1HI]
  1226. pslld mm0,DISTORSION+1+1
  1227. paddd mm3,mm0 // MM3 = slV_10 | slU_10
  1228. movd mm4,D [ebx+ eax*2 +4]
  1229. movd mm0,D [ebx+ eax*4 +2]
  1230. psllq mm0,32
  1231. por mm4,mm0
  1232. movd mm0,D [ebx+ eax*2 +2]
  1233. punpckldq mm0,mm0
  1234. psubd mm4,mm0
  1235. movq mm0,mm6
  1236. paddd mm0,Q [mm1HILO]
  1237. pslld mm0,DISTORSION+1+1
  1238. paddd mm4,mm0 // MM4 = slV_11 | slU_11
  1239. movq mm0,mm1
  1240. psrad mm0,DISTORSION+1+0
  1241. pand mm0,Q [mmBaseMasks]
  1242. movq mm7,mm0
  1243. psrlq mm7,Q [mmBaseWidthShift]
  1244. paddd mm0,mm7
  1245. movd eax,mm0
  1246. mov eax,D [esi+ eax*4]
  1247. mov D [edi],eax
  1248. movq mm0,mm1
  1249. paddd mm0,mm2
  1250. psrad mm0,DISTORSION+1+1
  1251. pand mm0,Q [mmBaseMasks]
  1252. movq mm7,mm0
  1253. psrlq mm7,Q [mmBaseWidthShift]
  1254. paddd mm0,mm7
  1255. movd eax,mm0
  1256. mov eax,D [esi+ eax*4]
  1257. mov D [edi+ 4],eax
  1258. movq mm0,mm1
  1259. paddd mm0,mm3
  1260. psrad mm0,DISTORSION+1+1
  1261. pand mm0,Q [mmBaseMasks]
  1262. movq mm7,mm0
  1263. psrlq mm7,Q [mmBaseWidthShift]
  1264. paddd mm0,mm7
  1265. movd eax,mm0
  1266. mov eax,D [esi+ eax*4]
  1267. mov D [edi+ edx*4],eax
  1268. paddd mm1,mm2
  1269. paddd mm1,mm3
  1270. paddd mm1,mm4
  1271. psrad mm1,DISTORSION+1+2
  1272. pand mm1,Q [mmBaseMasks]
  1273. movq mm7,mm1
  1274. psrlq mm7,Q [mmBaseWidthShift]
  1275. paddd mm1,mm7
  1276. movd eax,mm1
  1277. mov eax,D [esi+ eax*4]
  1278. mov D [edi+ edx*4 +4],eax
  1279. // advance to next texture pixels
  1280. paddd mm6,Q [mm1LO]
  1281. add edi,8
  1282. add ebx,2
  1283. dec ecx
  1284. jnz pixLoop2
  1285. // advance to next texture row
  1286. lea edi,[edi+ edx*4]
  1287. pop edx
  1288. paddd mm6,Q [mm1HI]
  1289. dec edx
  1290. jnz rowLoop2
  1291. emms
  1292. pop ebx
  1293. }
  1294. #else
  1295. SLONG slU_00, slU_01, slU_10, slU_11;
  1296. SLONG slV_00, slV_01, slV_10, slV_11;
  1297. for( PIX pixV=0; pixV<_pixBufferHeight; pixV++)
  1298. { // row loop
  1299. for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
  1300. { // texel loop
  1301. slU_00 = pswHeightMap[_pixBufferWidth*0+1] - pswHeightMap[_pixBufferWidth*0+0] + ((pixU+0)<<(DISTORSION+1+1));
  1302. slV_00 = pswHeightMap[_pixBufferWidth*1+0] - pswHeightMap[_pixBufferWidth*0+0] + ((pixV+0)<<(DISTORSION+1+1));
  1303. slU_01 = pswHeightMap[_pixBufferWidth*0+2] - pswHeightMap[_pixBufferWidth*0+1] + ((pixU+1)<<(DISTORSION+1+1));
  1304. slV_01 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*0+1] + ((pixV+0)<<(DISTORSION+1+1));
  1305. slU_10 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*1+0] + ((pixU+0)<<(DISTORSION+1+1));
  1306. slV_10 = pswHeightMap[_pixBufferWidth*2+0] - pswHeightMap[_pixBufferWidth*1+0] + ((pixV+1)<<(DISTORSION+1+1));
  1307. slU_11 = pswHeightMap[_pixBufferWidth*1+2] - pswHeightMap[_pixBufferWidth*1+1] + ((pixU+1)<<(DISTORSION+1+1));
  1308. slV_11 = pswHeightMap[_pixBufferWidth*2+1] - pswHeightMap[_pixBufferWidth*1+1] + ((pixV+1)<<(DISTORSION+1+1));
  1309. pulTexture[_pixTexWidth*0+0] = PIXEL( (slU_00 ) >>(DISTORSION+1 ), (slV_00 ) >>(DISTORSION+1 ) );
  1310. pulTexture[_pixTexWidth*0+1] = PIXEL( (slU_00+slU_01 ) >>(DISTORSION+1+1), (slV_00+slV_01 ) >>(DISTORSION+1+1) );
  1311. pulTexture[_pixTexWidth*1+0] = PIXEL( (slU_00 +slU_10 ) >>(DISTORSION+1+1), (slV_00 +slV_10 ) >>(DISTORSION+1+1) );
  1312. pulTexture[_pixTexWidth*1+1] = PIXEL( (slU_00+slU_01+slU_10+slU_11) >>(DISTORSION+1+2), (slV_00+slV_01+slV_10+slV_11) >>(DISTORSION+1+2) );
  1313. // advance to next texel
  1314. pulTexture+=2;
  1315. pswHeightMap++;
  1316. }
  1317. pulTexture+=_pixTexWidth;
  1318. }
  1319. #endif
  1320. }
  1321. else if( _pixBufferWidth*4 == _pixTexWidth)
  1322. { // BILINEAR SUPER-SAMPLING 4
  1323. #if ASMOPT == 1
  1324. __asm {
  1325. push ebx
  1326. bsf eax,D [pixBaseWidth]
  1327. mov edx,32
  1328. sub edx,eax
  1329. mov D [mmBaseWidthShift],edx
  1330. movq mm0,Q [mmBaseHeightMask]
  1331. psllq mm0,32
  1332. por mm0,Q [mmBaseWidthMask]
  1333. movq Q [mmBaseMasks],mm0
  1334. pxor mm6,mm6 // MM6 = pixV|pixU
  1335. mov ebx,D [pswHeightMap]
  1336. mov esi,D [pulTextureBase]
  1337. mov edi,D [pulTexture]
  1338. mov edx,D [_pixBufferHeight]
  1339. rowLoop4:
  1340. push edx
  1341. mov ecx,D [_pixBufferWidth]
  1342. pixLoop4:
  1343. mov eax,D [_pixBufferWidth]
  1344. mov edx,D [_pixTexWidth]
  1345. movd mm1,D [ebx+ 2]
  1346. movd mm0,D [ebx+ eax*2]
  1347. psllq mm0,32
  1348. por mm1,mm0
  1349. movd mm0,D [ebx]
  1350. punpckldq mm0,mm0
  1351. psubd mm1,mm0
  1352. movq mm0,mm6
  1353. pslld mm0,DISTORSION+1+1
  1354. paddd mm1,mm0 // MM1 = slV_00 | slU_00
  1355. movd mm2,D [ebx+ 4]
  1356. movd mm0,D [ebx+ eax*2 +2]
  1357. psllq mm0,32
  1358. por mm2,mm0
  1359. movd mm0,D [ebx+ 2]
  1360. punpckldq mm0,mm0
  1361. psubd mm2,mm0
  1362. movq mm0,mm6
  1363. paddd mm0,Q [mm1LO]
  1364. pslld mm0,DISTORSION+1+1
  1365. paddd mm2,mm0 // MM2 = slV_01 | slU_01
  1366. movd mm3,D [ebx+ eax*2 +2]
  1367. movd mm0,D [ebx+ eax*4]
  1368. psllq mm0,32
  1369. por mm3,mm0
  1370. movd mm0,D [ebx+ eax*2]
  1371. punpckldq mm0,mm0
  1372. psubd mm3,mm0
  1373. movq mm0,mm6
  1374. paddd mm0,Q [mm1HI]
  1375. pslld mm0,DISTORSION+1+1
  1376. paddd mm3,mm0 // MM3 = slV_10 | slU_10
  1377. movd mm4,D [ebx+ eax*2 +4]
  1378. movd mm0,D [ebx+ eax*4 +2]
  1379. psllq mm0,32
  1380. por mm4,mm0
  1381. movd mm0,D [ebx+ eax*2 +2]
  1382. punpckldq mm0,mm0
  1383. psubd mm4,mm0
  1384. movq mm0,mm6
  1385. paddd mm0,Q [mm1HILO]
  1386. pslld mm0,DISTORSION+1+1
  1387. paddd mm4,mm0 // MM4 = slV_11 | slU_11
  1388. // texel 00
  1389. movq mm0,mm1
  1390. psrad mm0,DISTORSION
  1391. pand mm0,Q [mmBaseMasks]
  1392. movq mm7,mm0
  1393. psrlq mm7,Q [mmBaseWidthShift]
  1394. paddd mm0,mm7
  1395. movd eax,mm0
  1396. mov eax,D [esi+ eax*4]
  1397. mov D [edi],eax
  1398. // texel 01
  1399. movq mm0,mm1
  1400. paddd mm0,mm1
  1401. paddd mm0,mm1
  1402. paddd mm0,mm2
  1403. psrad mm0,DISTORSION+2
  1404. pand mm0,Q [mmBaseMasks]
  1405. movq mm7,mm0
  1406. psrlq mm7,Q [mmBaseWidthShift]
  1407. paddd mm0,mm7
  1408. movd eax,mm0
  1409. mov eax,D [esi+ eax*4]
  1410. mov D [edi +4],eax
  1411. // texel 02
  1412. movq mm0,mm1
  1413. paddd mm0,mm2
  1414. psrad mm0,DISTORSION+1
  1415. pand mm0,Q [mmBaseMasks]
  1416. movq mm7,mm0
  1417. psrlq mm7,Q [mmBaseWidthShift]
  1418. paddd mm0,mm7
  1419. movd eax,mm0
  1420. mov eax,D [esi+ eax*4]
  1421. mov D [edi +8],eax
  1422. // texel 03
  1423. movq mm0,mm1
  1424. paddd mm0,mm2
  1425. paddd mm0,mm2
  1426. paddd mm0,mm2
  1427. psrad mm0,DISTORSION+2
  1428. pand mm0,Q [mmBaseMasks]
  1429. movq mm7,mm0
  1430. psrlq mm7,Q [mmBaseWidthShift]
  1431. paddd mm0,mm7
  1432. movd eax,mm0
  1433. mov eax,D [esi+ eax*4]
  1434. mov D [edi +12],eax
  1435. // texel 10
  1436. movq mm0,mm1
  1437. paddd mm0,mm1
  1438. paddd mm0,mm1
  1439. paddd mm0,mm3
  1440. psrad mm0,DISTORSION+2
  1441. pand mm0,Q [mmBaseMasks]
  1442. movq mm7,mm0
  1443. psrlq mm7,Q [mmBaseWidthShift]
  1444. paddd mm0,mm7
  1445. movd eax,mm0
  1446. mov eax,D [esi+ eax*4]
  1447. mov D [edi+ edx*4],eax
  1448. // texel 11
  1449. movq mm0,mm1
  1450. pslld mm0,3
  1451. paddd mm0,mm1
  1452. paddd mm0,mm2
  1453. paddd mm0,mm2
  1454. paddd mm0,mm2
  1455. paddd mm0,mm3
  1456. paddd mm0,mm3
  1457. paddd mm0,mm3
  1458. paddd mm0,mm4
  1459. psrad mm0,DISTORSION+4
  1460. pand mm0,Q [mmBaseMasks]
  1461. movq mm7,mm0
  1462. psrlq mm7,Q [mmBaseWidthShift]
  1463. paddd mm0,mm7
  1464. movd eax,mm0
  1465. mov eax,D [esi+ eax*4]
  1466. mov D [edi+ edx*4 +4],eax
  1467. // texel 12
  1468. movq mm0,mm1
  1469. paddd mm0,mm0
  1470. paddd mm0,mm1
  1471. paddd mm0,mm2
  1472. paddd mm0,mm2
  1473. paddd mm0,mm2
  1474. paddd mm0,mm3
  1475. paddd mm0,mm4
  1476. psrad mm0,DISTORSION+3
  1477. pand mm0,Q [mmBaseMasks]
  1478. movq mm7,mm0
  1479. psrlq mm7,Q [mmBaseWidthShift]
  1480. paddd mm0,mm7
  1481. movd eax,mm0
  1482. mov eax,D [esi+ eax*4]
  1483. mov D [edi+ edx*4 +8],eax
  1484. // texel 13
  1485. movq mm0,mm2
  1486. pslld mm0,3
  1487. paddd mm0,mm2
  1488. paddd mm0,mm1
  1489. paddd mm0,mm1
  1490. paddd mm0,mm1
  1491. paddd mm0,mm3
  1492. paddd mm0,mm4
  1493. paddd mm0,mm4
  1494. paddd mm0,mm4
  1495. psrad mm0,DISTORSION+4
  1496. pand mm0,Q [mmBaseMasks]
  1497. movq mm7,mm0
  1498. psrlq mm7,Q [mmBaseWidthShift]
  1499. paddd mm0,mm7
  1500. movd eax,mm0
  1501. mov eax,D [esi+ eax*4]
  1502. mov D [edi+ edx*4 +12],eax
  1503. // texel 20
  1504. movq mm0,mm1
  1505. paddd mm0,mm3
  1506. psrad mm0,DISTORSION+1
  1507. pand mm0,Q [mmBaseMasks]
  1508. movq mm7,mm0
  1509. psrlq mm7,Q [mmBaseWidthShift]
  1510. paddd mm0,mm7
  1511. movd eax,mm0
  1512. mov eax,D [esi+ eax*4]
  1513. mov D [edi+ edx*8],eax
  1514. // texel 21
  1515. movq mm0,mm1
  1516. paddd mm0,mm1
  1517. paddd mm0,mm1
  1518. paddd mm0,mm2
  1519. paddd mm0,mm3
  1520. paddd mm0,mm3
  1521. paddd mm0,mm3
  1522. paddd mm0,mm4
  1523. psrad mm0,DISTORSION+3
  1524. pand mm0,Q [mmBaseMasks]
  1525. movq mm7,mm0
  1526. psrlq mm7,Q [mmBaseWidthShift]
  1527. paddd mm0,mm7
  1528. movd eax,mm0
  1529. mov eax,D [esi+ eax*4]
  1530. mov D [edi+ edx*8 +4],eax
  1531. // texel 22
  1532. movq mm0,mm1
  1533. paddd mm0,mm2
  1534. paddd mm0,mm3
  1535. paddd mm0,mm4
  1536. psrad mm0,DISTORSION+2
  1537. pand mm0,Q [mmBaseMasks]
  1538. movq mm7,mm0
  1539. psrlq mm7,Q [mmBaseWidthShift]
  1540. paddd mm0,mm7
  1541. movd eax,mm0
  1542. mov eax,D [esi+ eax*4]
  1543. mov D [edi+ edx*8 +8],eax
  1544. // texel 23
  1545. movq mm0,mm1
  1546. paddd mm0,mm2
  1547. paddd mm0,mm2
  1548. paddd mm0,mm2
  1549. paddd mm0,mm3
  1550. paddd mm0,mm4
  1551. paddd mm0,mm4
  1552. paddd mm0,mm4
  1553. psrad mm0,DISTORSION+3
  1554. pand mm0,Q [mmBaseMasks]
  1555. movq mm7,mm0
  1556. psrlq mm7,Q [mmBaseWidthShift]
  1557. paddd mm0,mm7
  1558. movd eax,mm0
  1559. mov eax,D [esi+ eax*4]
  1560. mov D [edi+ edx*8 +12],eax
  1561. imul edx,3 // _pixTexWidth*=3
  1562. // texel 30
  1563. movq mm0,mm1
  1564. paddd mm0,mm3
  1565. paddd mm0,mm3
  1566. paddd mm0,mm3
  1567. psrad mm0,DISTORSION+2
  1568. pand mm0,Q [mmBaseMasks]
  1569. movq mm7,mm0
  1570. psrlq mm7,Q [mmBaseWidthShift]
  1571. paddd mm0,mm7
  1572. movd eax,mm0
  1573. mov eax,D [esi+ eax*4]
  1574. mov D [edi+ edx*4],eax
  1575. // texel 31
  1576. movq mm0,mm3
  1577. pslld mm0,3
  1578. paddd mm0,mm3
  1579. paddd mm0,mm1
  1580. paddd mm0,mm1
  1581. paddd mm0,mm1
  1582. paddd mm0,mm2
  1583. paddd mm0,mm4
  1584. paddd mm0,mm4
  1585. paddd mm0,mm4
  1586. psrad mm0,DISTORSION+4
  1587. pand mm0,Q [mmBaseMasks]
  1588. movq mm7,mm0
  1589. psrlq mm7,Q [mmBaseWidthShift]
  1590. paddd mm0,mm7
  1591. movd eax,mm0
  1592. mov eax,D [esi+ eax*4]
  1593. mov D [edi+ edx*4 +4],eax
  1594. // texel 32
  1595. movq mm0,mm4
  1596. paddd mm0,mm0
  1597. paddd mm0,mm4
  1598. paddd mm0,mm3
  1599. paddd mm0,mm3
  1600. paddd mm0,mm3
  1601. paddd mm0,mm2
  1602. paddd mm0,mm1
  1603. psrad mm0,DISTORSION+3
  1604. pand mm0,Q [mmBaseMasks]
  1605. movq mm7,mm0
  1606. psrlq mm7,Q [mmBaseWidthShift]
  1607. paddd mm0,mm7
  1608. movd eax,mm0
  1609. mov eax,D [esi+ eax*4]
  1610. mov D [edi+ edx*4 +8],eax
  1611. // texel 33
  1612. movq mm0,mm4
  1613. pslld mm0,3
  1614. paddd mm0,mm4
  1615. paddd mm0,mm1
  1616. paddd mm0,mm2
  1617. paddd mm0,mm2
  1618. paddd mm0,mm2
  1619. paddd mm0,mm3
  1620. paddd mm0,mm3
  1621. paddd mm0,mm3
  1622. psrad mm0,DISTORSION+4
  1623. pand mm0,Q [mmBaseMasks]
  1624. movq mm7,mm0
  1625. psrlq mm7,Q [mmBaseWidthShift]
  1626. paddd mm0,mm7
  1627. movd eax,mm0
  1628. mov eax,D [esi+ eax*4]
  1629. mov D [edi+ edx*4 +12],eax
  1630. // advance to next texture pixels
  1631. paddd mm6,Q [mm1LO]
  1632. add edi,16
  1633. add ebx,2
  1634. dec ecx
  1635. jnz pixLoop4
  1636. // advance to next texture row
  1637. lea edi,[edi+ edx*4] // +=[_pixTexWidth]*3
  1638. pop edx
  1639. paddd mm6,Q [mm1HI]
  1640. dec edx
  1641. jnz rowLoop4
  1642. emms
  1643. pop ebx
  1644. }
  1645. #else
  1646. SLONG slU_00, slU_01, slU_10, slU_11;
  1647. SLONG slV_00, slV_01, slV_10, slV_11;
  1648. mmBaseWidthShift = FastLog2( pixBaseWidth); // faster multiplying with shift
  1649. for( PIX pixV=0; pixV<_pixBufferHeight; pixV++)
  1650. { // row loop
  1651. for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
  1652. { // texel loop
  1653. slU_00 = pswHeightMap[_pixBufferWidth*0+1] - pswHeightMap[_pixBufferWidth*0+0] + ((pixU+0)<<(DISTORSION+2));
  1654. slV_00 = pswHeightMap[_pixBufferWidth*1+0] - pswHeightMap[_pixBufferWidth*0+0] + ((pixV+0)<<(DISTORSION+2));
  1655. slU_01 = pswHeightMap[_pixBufferWidth*0+2] - pswHeightMap[_pixBufferWidth*0+1] + ((pixU+1)<<(DISTORSION+2));
  1656. slV_01 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*0+1] + ((pixV+0)<<(DISTORSION+2));
  1657. slU_10 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*1+0] + ((pixU+0)<<(DISTORSION+2));
  1658. slV_10 = pswHeightMap[_pixBufferWidth*2+0] - pswHeightMap[_pixBufferWidth*1+0] + ((pixV+1)<<(DISTORSION+2));
  1659. slU_11 = pswHeightMap[_pixBufferWidth*1+2] - pswHeightMap[_pixBufferWidth*1+1] + ((pixU+1)<<(DISTORSION+2));
  1660. slV_11 = pswHeightMap[_pixBufferWidth*2+1] - pswHeightMap[_pixBufferWidth*1+1] + ((pixV+1)<<(DISTORSION+2));
  1661. pulTexture[_pixTexWidth*0+0] = PIXEL( (slU_00 ) >>(DISTORSION ), (slV_00 ) >>(DISTORSION ) );
  1662. pulTexture[_pixTexWidth*0+1] = PIXEL( (slU_00* 3+slU_01* 1 ) >>(DISTORSION+2), (slV_00* 3+slV_01* 1 ) >>(DISTORSION+2) );
  1663. pulTexture[_pixTexWidth*0+2] = PIXEL( (slU_00 +slU_01 ) >>(DISTORSION+1), (slV_00 +slV_01 ) >>(DISTORSION+1) );
  1664. pulTexture[_pixTexWidth*0+3] = PIXEL( (slU_00* 1+slU_01* 3 ) >>(DISTORSION+2), (slV_00* 1+slV_01* 3 ) >>(DISTORSION+2) );
  1665. pulTexture[_pixTexWidth*1+0] = PIXEL( (slU_00* 3 +slU_10* 1 ) >>(DISTORSION+2), (slV_00* 3 +slV_10 ) >>(DISTORSION+2) );
  1666. pulTexture[_pixTexWidth*1+1] = PIXEL( (slU_00* 9+slU_01* 3+slU_10* 3+slU_11* 1) >>(DISTORSION+4), (slV_00* 9+slV_01* 3+slV_10* 3+slV_11* 1) >>(DISTORSION+4) );
  1667. pulTexture[_pixTexWidth*1+2] = PIXEL( (slU_00* 3+slU_01* 3+slU_10* 1+slU_11* 1) >>(DISTORSION+3), (slV_00* 3+slV_01* 3+slV_10* 1+slV_11* 1) >>(DISTORSION+3) );
  1668. pulTexture[_pixTexWidth*1+3] = PIXEL( (slU_00* 3+slU_01* 9+slU_10* 1+slU_11* 3) >>(DISTORSION+4), (slV_00* 3+slV_01* 9+slV_10* 1+slV_11* 3) >>(DISTORSION+4) );
  1669. pulTexture[_pixTexWidth*2+0] = PIXEL( (slU_00 +slU_10 ) >>(DISTORSION+1), (slV_00 +slV_10 ) >>(DISTORSION+1) );
  1670. pulTexture[_pixTexWidth*2+1] = PIXEL( (slU_00* 3+slU_01* 1+slU_10* 3+slU_11* 1) >>(DISTORSION+3), (slV_00* 3+slV_01* 1+slV_10* 3+slV_11* 1) >>(DISTORSION+3) );
  1671. pulTexture[_pixTexWidth*2+2] = PIXEL( (slU_00 +slU_01 +slU_10 +slU_11 ) >>(DISTORSION+2), (slV_00 +slV_01 +slV_10 +slV_11 ) >>(DISTORSION+2) );
  1672. pulTexture[_pixTexWidth*2+3] = PIXEL( (slU_00* 1+slU_01* 3+slU_10* 1+slU_11* 3) >>(DISTORSION+3), (slV_00* 1+slV_01* 3+slV_10* 1+slV_11* 3) >>(DISTORSION+3) );
  1673. pulTexture[_pixTexWidth*3+0] = PIXEL( (slU_00* 1 +slU_10* 3 ) >>(DISTORSION+2), (slV_00* 1 +slV_10* 3 ) >>(DISTORSION+2) );
  1674. pulTexture[_pixTexWidth*3+1] = PIXEL( (slU_00* 3+slU_01* 1+slU_10* 9+slU_11* 3) >>(DISTORSION+4), (slV_00* 3+slV_01* 1+slV_10* 9+slV_11* 3) >>(DISTORSION+4) );
  1675. pulTexture[_pixTexWidth*3+2] = PIXEL( (slU_00* 1+slU_01* 1+slU_10* 3+slU_11* 3) >>(DISTORSION+3), (slV_00* 1+slV_01* 1+slV_10* 3+slV_11* 3) >>(DISTORSION+3) );
  1676. pulTexture[_pixTexWidth*3+3] = PIXEL( (slU_00* 1+slU_01* 3+slU_10* 3+slU_11* 9) >>(DISTORSION+4), (slV_00* 1+slV_01* 3+slV_10* 3+slV_11* 9) >>(DISTORSION+4) );
  1677. // advance to next texel
  1678. pulTexture+=4;
  1679. pHeightMap++;
  1680. }
  1681. pulTexture+=_pixTexWidth*3;
  1682. }
  1683. #endif
  1684. }
  1685. else
  1686. { // DO NOTHING
  1687. ASSERTALWAYS( "Effect textures larger than 256 pixels aren't supported");
  1688. }
  1689. _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
  1690. }
  1691. #pragma warning(default: 4731)
  1692. ///////////////// Fire
  1693. void InitializeFire(void)
  1694. {
  1695. Randomize( (ULONG)(_pTimer->GetHighPrecisionTimer().GetMilliseconds()));
  1696. }
  1697. enum PlasmaType {
  1698. ptNormal = 0,
  1699. ptUp,
  1700. ptUpTile,
  1701. ptDown,
  1702. ptDownTile
  1703. };
  1704. /*******************************
  1705. Plasma Animation
  1706. ********************************/
  1707. static void AnimatePlasma( SLONG slDensity, PlasmaType eType)
  1708. {
  1709. _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
  1710. /////////////////////////////////// move plasma
  1711. UBYTE *pNew = (UBYTE*)_ptdEffect->td_pubBuffer1;
  1712. UBYTE *pOld = (UBYTE*)_ptdEffect->td_pubBuffer2;
  1713. PIX pixV, pixU;
  1714. PIX pixOffset;
  1715. SLONG slLineAbove, slLineBelow, slLineLeft, slLineRight;
  1716. ULONG ulNew;
  1717. // --------------------------
  1718. // Normal plasma
  1719. // --------------------------
  1720. if (eType == ptNormal) {
  1721. // inner rectangle (without 1 pixel border)
  1722. pixOffset = _pixBufferWidth;
  1723. for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
  1724. for( pixU=0; pixU<_pixBufferWidth; pixU++) {
  1725. ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
  1726. (ULONG)pOld[pixOffset + _pixBufferWidth] +
  1727. (ULONG)pOld[pixOffset - 1] +
  1728. (ULONG)pOld[pixOffset + 1]
  1729. )>>2) +
  1730. (ULONG)pOld[pixOffset]
  1731. )>>1;
  1732. pNew[pixOffset] = ulNew - (ulNew >> slDensity);
  1733. pixOffset++;
  1734. }
  1735. }
  1736. // upper horizontal border (without corners)
  1737. slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1738. slLineBelow = _pixBufferWidth + 1;
  1739. slLineLeft = 0;
  1740. slLineRight = 2;
  1741. pixOffset = 1;
  1742. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1743. ulNew = ((((ULONG)pOld[slLineAbove] +
  1744. (ULONG)pOld[slLineBelow] +
  1745. (ULONG)pOld[slLineLeft] +
  1746. (ULONG)pOld[slLineRight]
  1747. )>>2) +
  1748. (ULONG)pOld[pixOffset]
  1749. )>>1;
  1750. pNew[pixOffset] = ulNew - (ulNew >> slDensity);
  1751. slLineAbove++;
  1752. slLineBelow++;
  1753. slLineLeft++;
  1754. slLineRight++;
  1755. pixOffset++;
  1756. }
  1757. // lower horizontal border (without corners)
  1758. slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
  1759. slLineBelow = 1;
  1760. slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
  1761. slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
  1762. pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1763. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1764. ulNew = ((((ULONG)pOld[slLineAbove] +
  1765. (ULONG)pOld[slLineBelow] +
  1766. (ULONG)pOld[slLineLeft] +
  1767. (ULONG)pOld[slLineRight]
  1768. )>>2) +
  1769. (ULONG)pOld[pixOffset]
  1770. )>>1;
  1771. pNew[pixOffset] = ulNew - (ulNew >> slDensity);
  1772. slLineAbove++;
  1773. slLineBelow++;
  1774. slLineLeft++;
  1775. slLineRight++;
  1776. pixOffset++;
  1777. }
  1778. // corner ( 0, 0)
  1779. ulNew = ((((ULONG)pOld[_pixBufferWidth] +
  1780. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  1781. (ULONG)pOld[1] +
  1782. (ULONG)pOld[_pixBufferWidth-1]
  1783. )>>2) +
  1784. (ULONG)pOld[0]
  1785. )>>1;
  1786. pNew[0] = ulNew - (ulNew >> slDensity);
  1787. // corner ( 0, _pixBufferWidth)
  1788. ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
  1789. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
  1790. (ULONG)pOld[0] +
  1791. (ULONG)pOld[_pixBufferWidth-2]
  1792. )>>2) +
  1793. (ULONG)pOld[_pixBufferWidth-1]
  1794. )>>1;
  1795. pNew[_pixBufferWidth-1] = ulNew - (ulNew >> slDensity);
  1796. // corner ( _pixBufferHeight, 0)
  1797. ulNew = ((((ULONG)pOld[0] +
  1798. (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
  1799. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
  1800. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1801. )>>2) +
  1802. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
  1803. )>>1;
  1804. pNew[(_pixBufferHeight-1)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1805. // corner ( _pixBufferHeight, _pixBufferWidth)
  1806. ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
  1807. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
  1808. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  1809. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
  1810. )>>2) +
  1811. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1812. )>>1;
  1813. pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
  1814. // --------------------------
  1815. // Plasma going up
  1816. // --------------------------
  1817. } else if (eType==ptUp || eType==ptUpTile) {
  1818. // inner rectangle (without 1 pixel border)
  1819. pixOffset = _pixBufferWidth;
  1820. for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
  1821. for( pixU=0; pixU<_pixBufferWidth; pixU++) {
  1822. ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
  1823. (ULONG)pOld[pixOffset + _pixBufferWidth] +
  1824. (ULONG)pOld[pixOffset - 1] +
  1825. (ULONG)pOld[pixOffset + 1]
  1826. )>>2) +
  1827. (ULONG)pOld[pixOffset]
  1828. )>>1;
  1829. pNew[pixOffset-_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1830. pixOffset++;
  1831. }
  1832. }
  1833. // tile
  1834. if (eType==ptUpTile) {
  1835. // upper horizontal border (without corners)
  1836. slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1837. slLineBelow = _pixBufferWidth + 1;
  1838. slLineLeft = 0;
  1839. slLineRight = 2;
  1840. pixOffset = 1;
  1841. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1842. ulNew = ((((ULONG)pOld[slLineAbove] +
  1843. (ULONG)pOld[slLineBelow] +
  1844. (ULONG)pOld[slLineLeft] +
  1845. (ULONG)pOld[slLineRight]
  1846. )>>2) +
  1847. (ULONG)pOld[pixOffset]
  1848. )>>1;
  1849. pNew[slLineAbove] = ulNew - (ulNew >> slDensity);
  1850. slLineAbove++;
  1851. slLineBelow++;
  1852. slLineLeft++;
  1853. slLineRight++;
  1854. pixOffset++;
  1855. }
  1856. // lower horizontal border (without corners)
  1857. slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
  1858. slLineBelow = 1;
  1859. slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
  1860. slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
  1861. pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1862. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1863. ulNew = ((((ULONG)pOld[slLineAbove] +
  1864. (ULONG)pOld[slLineBelow] +
  1865. (ULONG)pOld[slLineLeft] +
  1866. (ULONG)pOld[slLineRight]
  1867. )>>2) +
  1868. (ULONG)pOld[pixOffset]
  1869. )>>1;
  1870. pNew[slLineAbove] = ulNew - (ulNew >> slDensity);
  1871. slLineAbove++;
  1872. slLineBelow++;
  1873. slLineLeft++;
  1874. slLineRight++;
  1875. pixOffset++;
  1876. }
  1877. // corner ( 0, 0)
  1878. ulNew = ((((ULONG)pOld[_pixBufferWidth] +
  1879. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  1880. (ULONG)pOld[1] +
  1881. (ULONG)pOld[_pixBufferWidth-1]
  1882. )>>2) +
  1883. (ULONG)pOld[0]
  1884. )>>1;
  1885. pNew[(_pixBufferHeight-1)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1886. // corner ( 0, _pixBufferWidth)
  1887. ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
  1888. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
  1889. (ULONG)pOld[0] +
  1890. (ULONG)pOld[_pixBufferWidth-2]
  1891. )>>2) +
  1892. (ULONG)pOld[_pixBufferWidth-1]
  1893. )>>1;
  1894. pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
  1895. // corner ( _pixBufferHeight, 0)
  1896. ulNew = ((((ULONG)pOld[0] +
  1897. (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
  1898. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
  1899. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1900. )>>2) +
  1901. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
  1902. )>>1;
  1903. pNew[(_pixBufferHeight-2)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1904. // corner ( _pixBufferHeight, _pixBufferWidth)
  1905. ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
  1906. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
  1907. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  1908. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
  1909. )>>2) +
  1910. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  1911. )>>1;
  1912. pNew[((_pixBufferHeight-1)*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
  1913. }
  1914. // --------------------------
  1915. // Plasma going down
  1916. // --------------------------
  1917. } else if (eType==ptDown || eType==ptDownTile) {
  1918. // inner rectangle (without 1 pixel border)
  1919. pixOffset = _pixBufferWidth;
  1920. for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
  1921. for( pixU=0; pixU<_pixBufferWidth; pixU++) {
  1922. ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
  1923. (ULONG)pOld[pixOffset + _pixBufferWidth] +
  1924. (ULONG)pOld[pixOffset - 1] +
  1925. (ULONG)pOld[pixOffset + 1]
  1926. )>>2) +
  1927. (ULONG)pOld[pixOffset]
  1928. )>>1;
  1929. pNew[pixOffset+_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1930. pixOffset++;
  1931. }
  1932. }
  1933. // tile
  1934. if (eType==ptDownTile) {
  1935. // upper horizontal border (without corners)
  1936. slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1937. slLineBelow = _pixBufferWidth + 1;
  1938. slLineLeft = 0;
  1939. slLineRight = 2;
  1940. pixOffset = 1;
  1941. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1942. ulNew = ((((ULONG)pOld[slLineAbove] +
  1943. (ULONG)pOld[slLineBelow] +
  1944. (ULONG)pOld[slLineLeft] +
  1945. (ULONG)pOld[slLineRight]
  1946. )>>2) +
  1947. (ULONG)pOld[pixOffset]
  1948. )>>1;
  1949. pNew[slLineBelow] = ulNew - (ulNew >> slDensity);
  1950. slLineAbove++;
  1951. slLineBelow++;
  1952. slLineLeft++;
  1953. slLineRight++;
  1954. pixOffset++;
  1955. }
  1956. // lower horizontal border (without corners)
  1957. slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
  1958. slLineBelow = 1;
  1959. slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
  1960. slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
  1961. pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
  1962. for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
  1963. ulNew = ((((ULONG)pOld[slLineAbove] +
  1964. (ULONG)pOld[slLineBelow] +
  1965. (ULONG)pOld[slLineLeft] +
  1966. (ULONG)pOld[slLineRight]
  1967. )>>2) +
  1968. (ULONG)pOld[pixOffset]
  1969. )>>1;
  1970. pNew[slLineBelow] = ulNew - (ulNew >> slDensity);
  1971. slLineAbove++;
  1972. slLineBelow++;
  1973. slLineLeft++;
  1974. slLineRight++;
  1975. pixOffset++;
  1976. }
  1977. // corner ( 0, 0)
  1978. ulNew = ((((ULONG)pOld[_pixBufferWidth] +
  1979. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  1980. (ULONG)pOld[1] +
  1981. (ULONG)pOld[_pixBufferWidth-1]
  1982. )>>2) +
  1983. (ULONG)pOld[0]
  1984. )>>1;
  1985. pNew[_pixBufferWidth] = ulNew - (ulNew >> slDensity);
  1986. // corner ( 0, _pixBufferWidth)
  1987. ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
  1988. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
  1989. (ULONG)pOld[0] +
  1990. (ULONG)pOld[_pixBufferWidth-2]
  1991. )>>2) +
  1992. (ULONG)pOld[_pixBufferWidth-1]
  1993. )>>1;
  1994. pNew[(2*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
  1995. // corner ( _pixBufferHeight, 0)
  1996. ulNew = ((((ULONG)pOld[0] +
  1997. (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
  1998. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
  1999. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  2000. )>>2) +
  2001. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
  2002. )>>1;
  2003. pNew[0] = ulNew - (ulNew >> slDensity);
  2004. // corner ( _pixBufferHeight, _pixBufferWidth)
  2005. ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
  2006. (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
  2007. (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
  2008. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
  2009. )>>2) +
  2010. (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
  2011. )>>1;
  2012. pNew[_pixBufferWidth-1] = ulNew - (ulNew >> slDensity);
  2013. }
  2014. }
  2015. // swap buffers
  2016. Swap( _ptdEffect->td_pubBuffer1, _ptdEffect->td_pubBuffer2);
  2017. _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
  2018. }
  2019. /*******************************
  2020. Fire Animation
  2021. ********************************/
  2022. static void AnimateFire( SLONG slDensity)
  2023. {
  2024. // _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
  2025. /////////////////////////////////// move fire
  2026. // use only one buffer (otherwise it's not working)
  2027. UBYTE *pubNew = (UBYTE*)_ptdEffect->td_pubBuffer2;
  2028. SLONG slBufferMask = _pixBufferWidth*_pixBufferHeight -1;
  2029. SLONG slColumnModulo = _pixBufferWidth*(_pixBufferHeight-2) -1;
  2030. #if ASMOPT == 1
  2031. __asm {
  2032. push ebx
  2033. mov edi,D [ulRNDSeed] ;// EDI = randomizer
  2034. mov esi,D [pubNew]
  2035. xor ebx,ebx
  2036. colLoopFM:
  2037. mov ecx,D [_pixBufferHeight]
  2038. sub ecx,2
  2039. rowLoopFM:
  2040. mov edx,D [_pixBufferWidth]
  2041. add edx,esi
  2042. movzx eax,B [ebx+ edx]
  2043. add edx,D [_pixBufferWidth]
  2044. movzx edx,B [ebx+ edx]
  2045. add eax,edx
  2046. shr eax,1
  2047. cmp eax,D [slDensity]
  2048. jg doCalc
  2049. mov B [esi+ebx],0
  2050. jmp pixDone
  2051. doCalc:
  2052. mov edx,edi
  2053. sar edx,16
  2054. and edx,D [slDensity]
  2055. sub eax,edx
  2056. movsx edx,B [asbMod3Sub1Table +edx]
  2057. add edx,ebx
  2058. and edx,D [slBufferMask]
  2059. mov B [esi+edx],al
  2060. imul edi,262147
  2061. pixDone:
  2062. // advance to next row
  2063. add ebx,D [_pixBufferWidth]
  2064. dec ecx
  2065. jnz rowLoopFM
  2066. // advance to next column
  2067. sub ebx,D [slColumnModulo]
  2068. cmp ebx,D [_pixBufferWidth]
  2069. jl colLoopFM
  2070. // all done
  2071. mov D [ulRNDSeed],edi
  2072. pop ebx
  2073. }
  2074. #else
  2075. // inner rectangle (without 1 pixel border)
  2076. for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
  2077. {
  2078. SLONG slOffset = pixU;
  2079. for( PIX pixV=1; pixV<_pixBufferHeight-1; pixV++)
  2080. {
  2081. ULONG ulNew = ((ULONG)pubNew[_pixBufferWidth+slOffset] + (ULONG)pubNew[_pixBufferWidth*2+slOffset]) >>1;
  2082. if( ulNew>slDensity) {
  2083. ULONG ulNewDensity = RNDW&slDensity;
  2084. ulNew -= ulNewDensity;
  2085. SLONG slDifusion = (SLONG)asbMod3Sub1Table[ulNewDensity]; // (SLONG)(ulNewDensity%3-1);
  2086. SLONG slPos = (slDifusion+slOffset) & slBufferMask;
  2087. pubNew[slPos] = ulNew;
  2088. } else {
  2089. pubNew[slOffset] = 0;
  2090. }
  2091. slOffset += _pixBufferWidth;
  2092. }
  2093. }
  2094. #endif
  2095. // _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
  2096. }
  2097. //////////////////////////// displace texture
  2098. static void RenderPlasmaFire(void)
  2099. {
  2100. // _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
  2101. // get and adjust textures' parameters
  2102. PIX pixBaseWidth = _ptdBase->GetPixWidth();
  2103. ULONG *pulTextureBase = _ptdBase->td_pulFrames;
  2104. ULONG *pulTexture = _ptdEffect->td_pulFrames;
  2105. ASSERT( _ptdEffect->td_pulFrames!=NULL && _ptdBase->td_pulFrames!=NULL && pixBaseWidth<=256);
  2106. UBYTE *pubHeat = (UBYTE*)_ptdEffect->td_pubBuffer2; // heat map pointer
  2107. SLONG slHeatMapStep = _pixBufferWidth/_pixTexWidth;
  2108. SLONG slHeatRowStep = (slHeatMapStep-1)*_pixBufferWidth;
  2109. SLONG slBaseMipShift = 8 - FastLog2(pixBaseWidth);
  2110. #if ASMOPT == 1
  2111. __asm {
  2112. push ebx
  2113. mov ebx,D [pubHeat]
  2114. mov esi,D [pulTextureBase]
  2115. mov edi,D [pulTexture]
  2116. mov ecx,D [_pixTexHeight]
  2117. rowLoopF:
  2118. push ecx
  2119. mov edx,D [_pixTexWidth]
  2120. mov ecx,D [slBaseMipShift]
  2121. pixLoopF:
  2122. movzx eax,B [ebx]
  2123. shr eax,cl
  2124. mov eax,D [esi+ eax*4]
  2125. mov D [edi],eax
  2126. // advance to next pixel
  2127. add ebx,D [slHeatMapStep]
  2128. add edi,4
  2129. dec edx
  2130. jnz pixLoopF
  2131. // advance to next row
  2132. pop ecx
  2133. add ebx,D [slHeatRowStep]
  2134. dec ecx
  2135. jnz rowLoopF
  2136. pop ebx
  2137. }
  2138. #else
  2139. INDEX iPalette;
  2140. for( INDEX pixV=0; pixV<_pixTexHeight; pixV++) {
  2141. // for every pixel in horizontal line
  2142. for( INDEX pixU=0; pixU<_pixTexWidth; pixU++) {
  2143. iPalette = (*pubHeat)>>slBaseMipShift;
  2144. *pulTexture++ = pulTextureBase[iPalette];
  2145. pubHeat += slHeatMapStep;
  2146. }
  2147. pubHeat += slHeatRowStep;
  2148. }
  2149. #endif
  2150. // _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
  2151. }
  2152. /////////////////////////////////////////////////////////////////////
  2153. // EFFECT TABLES
  2154. /////////////////////////////////////////////////////////////////////
  2155. struct TextureEffectSourceType atestWater[] = {
  2156. {
  2157. "Raindrops",
  2158. InitializeRaindropsStandard,
  2159. AnimateRaindropsStandard
  2160. },
  2161. {
  2162. "RaindropsBig",
  2163. InitializeRaindropsBig,
  2164. AnimateRaindropsBig
  2165. },
  2166. {
  2167. "RaindropsSmall",
  2168. InitializeRaindropsSmall,
  2169. AnimateRaindropsSmall
  2170. },
  2171. {
  2172. "Random Surfer",
  2173. InitializeRandomSurfer,
  2174. AnimateRandomSurfer
  2175. },
  2176. {
  2177. "Oscilator",
  2178. InitializeOscilator,
  2179. AnimateOscilator
  2180. },
  2181. {
  2182. "Vertical Line",
  2183. InitializeVertLine,
  2184. AnimateVertLine
  2185. },
  2186. {
  2187. "Horizontal Line",
  2188. InitializeHortLine,
  2189. AnimateHortLine
  2190. },
  2191. };
  2192. struct TextureEffectSourceType atestFire[] = {
  2193. {
  2194. "Point",
  2195. InitializeFirePoint,
  2196. AnimateFirePoint
  2197. },
  2198. {
  2199. "Random Point",
  2200. InitializeRandomFirePoint,
  2201. AnimateRandomFirePoint
  2202. },
  2203. {
  2204. "Shake Point",
  2205. InitializeFireShakePoint,
  2206. AnimateFireShakePoint
  2207. },
  2208. {
  2209. "Fire Place",
  2210. InitializeFirePlace,
  2211. AnimateFirePlace
  2212. },
  2213. {
  2214. "Roler",
  2215. InitializeFireRoler,
  2216. AnimateFireRoler
  2217. },
  2218. {
  2219. "Fall",
  2220. InitializeFireFall,
  2221. AnimateFireFall
  2222. },
  2223. {
  2224. "Fountain",
  2225. InitializeFireFountain,
  2226. AnimateFireFountain
  2227. },
  2228. {
  2229. "Side Fountain",
  2230. InitializeFireSideFountain,
  2231. AnimateFireSideFountain
  2232. },
  2233. {
  2234. "Lightning",
  2235. InitializeFireLightning,
  2236. AnimateFireLightning
  2237. },
  2238. {
  2239. "Lightning Ball",
  2240. InitializeFireLightningBall,
  2241. AnimateFireLightningBall
  2242. },
  2243. {
  2244. "Smoke",
  2245. InitializeFireSmoke,
  2246. AnimateFireSmoke
  2247. },
  2248. };
  2249. void AWaterFast(void) { AnimateWater(2); };
  2250. void AWaterMedium(void) { AnimateWater(3); };
  2251. void AWaterSlow(void) { AnimateWater(5); };
  2252. void APlasma(void) { AnimatePlasma(4, ptNormal); };
  2253. void APlasmaUp(void) { AnimatePlasma(4, ptUp); };
  2254. void APlasmaUpTile(void) { AnimatePlasma(4, ptUpTile); };
  2255. void APlasmaDown(void) { AnimatePlasma(5, ptDown); };
  2256. void APlasmaDownTile(void) { AnimatePlasma(5, ptDownTile); };
  2257. void APlasmaUpSlow(void) { AnimatePlasma(6, ptUp); };
  2258. void AFire(void) { AnimateFire(15); };
  2259. struct TextureEffectGlobalType _ategtTextureEffectGlobalPresets[] = {
  2260. {
  2261. "Water Fast",
  2262. InitializeWater,
  2263. AWaterFast,
  2264. sizeof(atestWater)/sizeof(atestWater[0]),
  2265. atestWater
  2266. },
  2267. {
  2268. "Water Medium",
  2269. InitializeWater,
  2270. AWaterMedium,
  2271. sizeof(atestWater)/sizeof(atestWater[0]),
  2272. atestWater
  2273. },
  2274. {
  2275. "Water Slow",
  2276. InitializeWater,
  2277. AWaterSlow,
  2278. sizeof(atestWater)/sizeof(atestWater[0]),
  2279. atestWater
  2280. },
  2281. {
  2282. "",
  2283. InitializeWater,
  2284. AWaterSlow,
  2285. sizeof(atestWater)/sizeof(atestWater[0]),
  2286. atestWater
  2287. },
  2288. {
  2289. "Plasma Tile",
  2290. InitializeFire,
  2291. APlasma,
  2292. sizeof(atestFire)/sizeof(atestFire[0]),
  2293. atestFire
  2294. },
  2295. {
  2296. "Plasma Up",
  2297. InitializeFire,
  2298. APlasmaUp,
  2299. sizeof(atestFire)/sizeof(atestFire[0]),
  2300. atestFire
  2301. },
  2302. {
  2303. "Plasma Up Tile",
  2304. InitializeFire,
  2305. APlasmaUpTile,
  2306. sizeof(atestFire)/sizeof(atestFire[0]),
  2307. atestFire
  2308. },
  2309. {
  2310. "Plasma Down",
  2311. InitializeFire,
  2312. APlasmaDown,
  2313. sizeof(atestFire)/sizeof(atestFire[0]),
  2314. atestFire
  2315. },
  2316. {
  2317. "Plasma Down Tile",
  2318. InitializeFire,
  2319. APlasmaDownTile,
  2320. sizeof(atestFire)/sizeof(atestFire[0]),
  2321. atestFire
  2322. },
  2323. {
  2324. "Plasma Up Slow",
  2325. InitializeFire,
  2326. APlasmaUpSlow,
  2327. sizeof(atestFire)/sizeof(atestFire[0]),
  2328. atestFire
  2329. },
  2330. {
  2331. "Fire",
  2332. InitializeFire,
  2333. AFire,
  2334. sizeof(atestFire)/sizeof(atestFire[0]),
  2335. atestFire
  2336. },
  2337. };
  2338. INDEX _ctTextureEffectGlobalPresets = sizeof(_ategtTextureEffectGlobalPresets)
  2339. / sizeof(_ategtTextureEffectGlobalPresets[0]);
  2340. // get effect type (TRUE if water type effect, FALSE if plasma or fire effect)
  2341. BOOL CTextureEffectGlobal::IsWater(void)
  2342. {
  2343. return( _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Initialize == InitializeWater);
  2344. }
  2345. // default constructor
  2346. CTextureEffectGlobal::CTextureEffectGlobal(CTextureData *ptdTexture, ULONG ulGlobalEffect)
  2347. {
  2348. // remember global effect's texture data for cross linking
  2349. teg_ptdTexture = ptdTexture;
  2350. teg_ulEffectType = ulGlobalEffect;
  2351. // init for animating
  2352. _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Initialize();
  2353. // make sure the texture will be updated next time when used
  2354. teg_updTexture.Invalidate();
  2355. }
  2356. // add new effect source.
  2357. void CTextureEffectGlobal::AddEffectSource( ULONG ulEffectSourceType, PIX pixU0, PIX pixV0,
  2358. PIX pixU1, PIX pixV1)
  2359. {
  2360. CTextureEffectSource* ptesNew = teg_atesEffectSources.New(1);
  2361. ptesNew->Initialize(this, ulEffectSourceType, pixU0, pixV0, pixU1, pixV1);
  2362. }
  2363. // animate effect texture
  2364. void CTextureEffectGlobal::Animate(void)
  2365. {
  2366. // if not set yet (funny word construction:)
  2367. if( !bTableSet) {
  2368. // set table for fast modulo 3 minus 1
  2369. for( INDEX i=0; i<256; i++) asbMod3Sub1Table[i]=(SBYTE)((i%3)-1);
  2370. bTableSet = TRUE;
  2371. }
  2372. // setup some internal vars
  2373. _ptdEffect = teg_ptdTexture;
  2374. _pixBufferWidth = _ptdEffect->td_pixBufferWidth;
  2375. _pixBufferHeight = _ptdEffect->td_pixBufferHeight;
  2376. _ulBufferMask = _pixBufferHeight*_pixBufferWidth -1;
  2377. // remember buffer pointers
  2378. _pubDrawBuffer=(UBYTE*)_ptdEffect->td_pubBuffer2;
  2379. _pswDrawBuffer=(SWORD*)_ptdEffect->td_pubBuffer2;
  2380. // for each effect source
  2381. FOREACHINDYNAMICARRAY( teg_atesEffectSources, CTextureEffectSource, itEffectSource) {
  2382. // let it animate itself
  2383. itEffectSource->Animate();
  2384. }
  2385. // use animation function for this global effect type
  2386. _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Animate();
  2387. // remember that it was calculated
  2388. teg_updTexture.MarkUpdated();
  2389. }
  2390. #pragma warning(disable: 4731)
  2391. // render effect texture
  2392. void CTextureEffectGlobal::Render( INDEX iWantedMipLevel, PIX pixTexWidth, PIX pixTexHeight)
  2393. {
  2394. // setup some internal vars
  2395. _ptdEffect = teg_ptdTexture;
  2396. _ptdBase = teg_ptdTexture->td_ptdBaseTexture;
  2397. _pixBufferWidth = _ptdEffect->td_pixBufferWidth;
  2398. _pixBufferHeight = _ptdEffect->td_pixBufferHeight;
  2399. if( IsWater()) {
  2400. // use water rendering routine
  2401. _pixTexWidth = pixTexWidth;
  2402. _pixTexHeight = pixTexHeight;
  2403. _iWantedMipLevel = iWantedMipLevel;
  2404. RenderWater();
  2405. } else {
  2406. // use plasma & fire rendering routine
  2407. _pixTexWidth = _ptdEffect->GetWidth() >>iWantedMipLevel;
  2408. _pixTexHeight = _ptdEffect->GetHeight() >>iWantedMipLevel;
  2409. RenderPlasmaFire();
  2410. }
  2411. }
  2412. #pragma warning(default: 4731)
  2413. // returns number of second it took to render effect texture
  2414. DOUBLE CTextureEffectGlobal::GetRenderingTime(void)
  2415. {
  2416. return( _sfStats.sf_astTimers[CStatForm::STI_EFFECTRENDER].st_tvElapsed.GetSeconds());
  2417. }