1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692 |
- /* Copyright (c) 2002-2012 Croteam Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as published by
- the Free Software Foundation
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
- #include "stdh.h"
- #include <Engine/Graphics/Texture.h>
- #include <Engine/Graphics/TextureEffects.h>
- #include <Engine/Math/Functions.h>
- #include <Engine/Base/Timer.h>
- #include <Engine/Base/Statistics_internal.h>
- #include <Engine/Templates/DynamicArray.cpp>
- #include <Engine/Templates/Stock_CtextureData.h>
- #include <Engine/Templates/StaticArray.cpp>
- // asm shortcuts
- #define O offset
- #define Q qword ptr
- #define D dword ptr
- #define W word ptr
- #define B byte ptr
- #define ASMOPT 1
- static const __int64 mm1LO = 0x0000000000000001;
- static const __int64 mm1HI = 0x0000000100000000;
- static const __int64 mm1HILO = 0x0000000100000001;
- static const __int64 mm0001 = 0x0000000000000001;
- static const __int64 mm0010 = 0x0000000000010000;
- static const __int64 mm00M0 = 0x00000000FFFF0000;
- static __int64 mmBaseWidthShift=0, mmBaseWidth=0, mmBaseWidthMask=0, mmBaseHeightMask=0, mmBaseMasks=0, mmShift=0;
- // speed table
- static SBYTE asbMod3Sub1Table[256];
- static BOOL bTableSet = FALSE;
- static CTextureData *_ptdEffect, *_ptdBase;
- static PIX _pixTexWidth, _pixTexHeight;
- static PIX _pixBufferWidth, _pixBufferHeight;
- static ULONG _ulBufferMask;
- static INDEX _iWantedMipLevel;
- static UBYTE *_pubDrawBuffer;
- static SWORD *_pswDrawBuffer;
- // randomizer
- static ULONG ulRNDSeed;
- inline void Randomize( ULONG ulSeed)
- {
- if( ulSeed==0) ulSeed = 0x87654321;
- ulRNDSeed = ulSeed*262147;
- };
- inline ULONG Rnd(void)
- {
- ulRNDSeed = ulRNDSeed*262147;
- return ulRNDSeed;
- };
- #define RNDW (Rnd()>>16)
- // Initialize the texture effect source.
- void CTextureEffectSource::Initialize( class CTextureEffectGlobal *ptegGlobalEffect,
- ULONG ulEffectSourceType, PIX pixU0, PIX pixV0,
- PIX pixU1, PIX pixV1)
- { // remember global effect for cross linking
- tes_ptegGlobalEffect = ptegGlobalEffect;
- tes_ulEffectSourceType = ulEffectSourceType;
- // obtain effect source table for current effect class
- struct TextureEffectSourceType *patestSourceEffectTypes =
- _ategtTextureEffectGlobalPresets[ ptegGlobalEffect->teg_ulEffectType].tet_atestEffectSourceTypes;
- // init for animating
- patestSourceEffectTypes[ulEffectSourceType].test_Initialize(this, pixU0, pixV0, pixU1, pixV1);
- }
- // Animate the texture effect source.
- void CTextureEffectSource::Animate(void)
- {
- // obtain effect source table for current effect class
- struct TextureEffectSourceType *patestSourceEffectTypes =
- _ategtTextureEffectGlobalPresets[ tes_ptegGlobalEffect->teg_ulEffectType]
- .tet_atestEffectSourceTypes;
- // animating it
- patestSourceEffectTypes[tes_ulEffectSourceType].test_Animate(this);
- }
- // ----------------------------------------
- // SLONG WATER
- // ----------------------------------------
- inline void PutPixelSLONG_WATER( PIX pixU, PIX pixV, INDEX iHeight)
- {
- _pswDrawBuffer[(pixV*_pixBufferWidth+pixU)&_ulBufferMask] += iHeight;
- }
- inline void PutPixel9SLONG_WATER( PIX pixU, PIX pixV, INDEX iHeightMid)
- {
- INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
- INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
- PutPixelSLONG_WATER( pixU-1, pixV-1, iHeightDiag);
- PutPixelSLONG_WATER( pixU, pixV-1, iHeightSide);
- PutPixelSLONG_WATER( pixU+1, pixV-1, iHeightDiag);
- PutPixelSLONG_WATER( pixU-1, pixV, iHeightSide);
- PutPixelSLONG_WATER( pixU, pixV, iHeightMid);
- PutPixelSLONG_WATER( pixU+1, pixV, iHeightSide);
- PutPixelSLONG_WATER( pixU-1, pixV+1, iHeightDiag);
- PutPixelSLONG_WATER( pixU, pixV+1, iHeightSide);
- PutPixelSLONG_WATER( pixU+1, pixV+1, iHeightDiag);
- }
- // ----------------------------------------
- // UBYTE FIRE
- // ----------------------------------------
- inline void PutPixelUBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeight)
- {
- PIX pixLoc = (pixV*_pixBufferWidth+pixU) & _ulBufferMask;
- _pubDrawBuffer[pixLoc] = Clamp( _pubDrawBuffer[pixLoc] +iHeight, 0L, 255L);
- }
- inline void PutPixel9UBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeightMid)
- {
- INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
- INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
- PutPixelUBYTE_FIRE( pixU-1, pixV-1, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU, pixV-1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+1, pixV-1, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU-1, pixV, iHeightSide);
- PutPixelUBYTE_FIRE( pixU, pixV, iHeightMid);
- PutPixelUBYTE_FIRE( pixU+1, pixV, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-1, pixV+1, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU, pixV+1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+1, pixV+1, iHeightDiag);
- }
- inline void PutPixel25UBYTE_FIRE( PIX pixU, PIX pixV, INDEX iHeightMid)
- {
- INDEX iHeightSide = (iHeightMid*28053) >>16; // iHeight /0.851120 *0.364326;
- INDEX iHeightDiag = (iHeightMid*12008) >>16; // iHeight /0.851120 *0.155951;
- PutPixelUBYTE_FIRE( pixU-2, pixV-2, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU-1, pixV-2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU, pixV-2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+1, pixV-2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+2, pixV-2, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU-2, pixV-1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-1, pixV-1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU, pixV-1, iHeightMid);
- PutPixelUBYTE_FIRE( pixU+1, pixV-1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+2, pixV-1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-2, pixV, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-1, pixV, iHeightMid);
- PutPixelUBYTE_FIRE( pixU, pixV, iHeightMid);
- PutPixelUBYTE_FIRE( pixU+1, pixV, iHeightMid);
- PutPixelUBYTE_FIRE( pixU+2, pixV, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-2, pixV+1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-1, pixV+1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU, pixV+1, iHeightMid);
- PutPixelUBYTE_FIRE( pixU+1, pixV+1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+2, pixV+1, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+2, pixV+2, iHeightDiag);
- PutPixelUBYTE_FIRE( pixU-1, pixV+2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU, pixV+2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU+1, pixV+2, iHeightSide);
- PutPixelUBYTE_FIRE( pixU-2, pixV+2, iHeightDiag);
- }
- /////////////////////////////////////////////////////////////////////
- // WATER EFFECTS
- /////////////////////////////////////////////////////////////////////
- #define DISTORSION 3 //3
- ///////////////// random surfer
- struct Surfer {
- FLOAT fU;
- FLOAT fV;
- FLOAT fAngle;
- };
- void InitializeRandomSurfer(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- Surfer &sf =
- ((Surfer&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- sf.fU = pixU0;
- sf.fV = pixV0;
- sf.fAngle = RNDW&7;
- }
- void AnimateRandomSurfer(CTextureEffectSource *ptes)
- {
- Surfer &sf =
- ((Surfer&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PutPixel9SLONG_WATER(sf.fU, sf.fV, 125);
- sf.fU += 2*sin(sf.fAngle);
- sf.fV += 2*cos(sf.fAngle);
- PutPixel9SLONG_WATER(sf.fU, sf.fV, 250);
- if((RNDW&15)==0) {
- sf.fAngle += 3.14f/7.0f;
- }
- if((RNDW&15)==0) {
- sf.fAngle -= 3.14f/5.0f;
- }
- }
- ///////////////// raindrops
- struct Raindrop {
- UBYTE pixU;
- UBYTE pixV;
- SWORD iHeight;
- SWORD iIndex;
- };
- void InitializeRaindrops(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1, int iHeight)
- {
- for (int iIndex=0; iIndex<5; iIndex++) {
- Raindrop &rd =
- ((Raindrop&) ptes->tes_tespEffectSourceProperties.tesp_achDummy[iIndex*sizeof(Raindrop)]);
- rd.pixU = RNDW&(_pixBufferWidth -1);
- rd.pixV = RNDW&(_pixBufferHeight-1);
- rd.iHeight = RNDW&iHeight;
- rd.iIndex = iIndex*8;
- }
- }
- void InitializeRaindropsStandard(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
- InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 255);
- }
- void InitializeRaindropsBig(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
- InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 1023);
- }
- void InitializeRaindropsSmall(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1) {
- InitializeRaindrops(ptes, pixU0, pixV0, pixU1, pixV1, 31);
- }
- void AnimateRaindrops(CTextureEffectSource *ptes, int iHeight)
- {
- for (int iIndex=0; iIndex<5; iIndex++) {
- Raindrop &rd =
- ((Raindrop&) ptes->tes_tespEffectSourceProperties.tesp_achDummy[iIndex*sizeof(Raindrop)]);
- if (rd.iIndex < 48) {
- rd.iIndex++;
- if (rd.iIndex < 8) {
- PutPixel9SLONG_WATER(rd.pixU, rd.pixV, sin(rd.iIndex/4.0f*(-3.14f))*rd.iHeight);
- }
- } else {
- rd.pixU = RNDW&(_pixBufferWidth -1);
- rd.pixV = RNDW&(_pixBufferHeight-1);
- rd.iHeight = RNDW&iHeight;
- rd.iIndex = 0;
- }
- }
- }
- void AnimateRaindropsStandard(CTextureEffectSource *ptes) {
- AnimateRaindrops(ptes, 255);
- }
- void AnimateRaindropsBig(CTextureEffectSource *ptes) {
- AnimateRaindrops(ptes, 1023);
- }
- void AnimateRaindropsSmall(CTextureEffectSource *ptes) {
- AnimateRaindrops(ptes, 31);
- }
- ///////////////// oscilator
- struct Oscilator {
- UBYTE pixU;
- UBYTE pixV;
- FLOAT fAngle;
- };
- void InitializeOscilator(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- Oscilator &os =
- ((Oscilator&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- os.pixU = pixU0;
- os.pixV = pixV0;
- os.fAngle = -3.14f;
- }
- void AnimateOscilator(CTextureEffectSource *ptes)
- {
- Oscilator &os =
- ((Oscilator&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PutPixel9SLONG_WATER(os.pixU, os.pixV, sin(os.fAngle)*150);
- os.fAngle += (3.14f/6);
- }
- ///////////////// Vertical Line
- struct VertLine{
- UBYTE pixU;
- UBYTE pixV;
- UWORD uwSize;
- FLOAT fAngle;
- };
- void InitializeVertLine(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- VertLine &vl =
- ((VertLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- vl.pixU = pixU0;
- vl.pixV = pixV0;
- vl.fAngle = -3.14f;
- if (pixV0==pixV1) {
- vl.uwSize = 16;
- } else {
- vl.uwSize = abs(pixV1-pixV0);
- }
- }
- void AnimateVertLine(CTextureEffectSource *ptes)
- {
- VertLine &vl =
- ((VertLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PIX pixV = vl.pixV;
- for (int iCnt=0; iCnt<vl.uwSize; iCnt++) {
- PutPixelSLONG_WATER(vl.pixU, pixV, sin(vl.fAngle)*25);
- pixV = (pixV+1)&(_pixBufferHeight-1);
- }
- vl.fAngle += (3.14f/6);
- }
- ///////////////// Horizontal Line
- struct HortLine{
- UBYTE pixU;
- UBYTE pixV;
- UWORD uwSize;
- FLOAT fAngle;
- };
- void InitializeHortLine(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- HortLine &hl =
- ((HortLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- hl.pixU = pixU0;
- hl.pixV = pixV0;
- hl.fAngle = -3.14f;
- if (pixU0==pixU1) {
- hl.uwSize = 16;
- } else {
- hl.uwSize = abs(pixU1-pixU0);
- }
- }
- void AnimateHortLine(CTextureEffectSource *ptes)
- {
- HortLine &hl =
- ((HortLine&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PIX pixU = hl.pixU;
- for (int iCnt=0; iCnt<hl.uwSize; iCnt++) {
- PutPixelSLONG_WATER(pixU, hl.pixV, sin(hl.fAngle)*25);
- pixU = (pixU+1)&(_pixBufferWidth-1);
- }
- hl.fAngle += (3.14f/6);
- }
- /////////////////////////////////////////////////////////////////////
- // FIRE EFFECTS
- /////////////////////////////////////////////////////////////////////
- ///////////////// Fire Point
- struct FirePoint{
- UBYTE pixU;
- UBYTE pixV;
- };
- void InitializeFirePoint(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ft.pixU = pixU0;
- ft.pixV = pixV0;
- }
- void AnimateFirePoint(CTextureEffectSource *ptes)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PutPixel9UBYTE_FIRE(ft.pixU, ft.pixV, 255);
- }
- void InitializeRandomFirePoint(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ft.pixU = pixU0;
- ft.pixV = pixV0;
- }
- void AnimateRandomFirePoint(CTextureEffectSource *ptes)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PutPixel9UBYTE_FIRE(ft.pixU, ft.pixV, RNDW&255);
- }
- void InitializeFireShakePoint(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ft.pixU = pixU0;
- ft.pixV = pixV0;
- }
- void AnimateFireShakePoint(CTextureEffectSource *ptes)
- {
- FirePoint &ft =
- ((FirePoint&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- UBYTE pixU, pixV;
- pixU = RNDW%3 - 1;
- pixV = RNDW%3 - 1;
- PutPixel9UBYTE_FIRE(ft.pixU+pixU, ft.pixV+pixV, 255);
- }
- ///////////////// Fire Place
- #define FIREPLACE_SIZE 60
- struct FirePlace{
- UBYTE pixU;
- UBYTE pixV;
- UBYTE ubWidth;
- UBYTE aubFire[FIREPLACE_SIZE];
- };
- void InitializeFirePlace(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FirePlace &fp =
- ((FirePlace&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- fp.pixU = pixU0;
- fp.pixV = pixV0;
- fp.ubWidth = abs(pixU1-pixU0);
- if (fp.ubWidth>FIREPLACE_SIZE) fp.ubWidth=FIREPLACE_SIZE;
- if (fp.ubWidth<10) fp.ubWidth = 10;
- // clear fire array
- for (int iCnt=0; iCnt<fp.ubWidth; iCnt++) {
- fp.aubFire[iCnt] = 0;
- }
- }
- void AnimateFirePlace(CTextureEffectSource *ptes)
- {
- INDEX iIndex;
- FirePlace &fp =
- ((FirePlace&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ULONG ulRND = RNDW&255;
- // match
- if (ulRND>200) {
- ULONG ulMatchIndex = ulRND%(fp.ubWidth-5);
- for (iIndex=0; iIndex<5; iIndex++) {
- fp.aubFire[ulMatchIndex+iIndex] = 255;
- }
- // water
- } else if (ulRND<50) {
- for (iIndex=0; iIndex<10; iIndex++) {
- fp.aubFire[RNDW%fp.ubWidth] = 0;
- }
- }
- // fix fire place
- for (iIndex=0; iIndex<fp.ubWidth; iIndex++) {
- UBYTE ubFlame = fp.aubFire[iIndex];
- // flame is fading ?
- if (ubFlame < 50) {
- // starting to burn
- if (ubFlame > 10) {
- ubFlame += RNDW%30; //30
- // give more fire
- } else {
- ubFlame += RNDW%30+30; //30,30
- }
- }
- fp.aubFire[iIndex] = ubFlame;
- }
- // water on edges
- for (iIndex=0; iIndex<4; iIndex++) {
- INDEX iWater = RNDW%4;
- fp.aubFire[iWater] = 0;
- fp.aubFire[fp.ubWidth-1-iWater] = 0;
- }
- // smooth fire place
- for (iIndex=1; iIndex<(fp.ubWidth-1); iIndex++) {
- fp.aubFire[iIndex] = (fp.aubFire[iIndex-1]+fp.aubFire[iIndex]+fp.aubFire[iIndex+1])/3;
- }
- // draw fire place in buffer
- for (iIndex=0; iIndex<fp.ubWidth; iIndex++) {
- PutPixel9UBYTE_FIRE(fp.pixU+iIndex, fp.pixV, fp.aubFire[iIndex]);
- }
- }
- ///////////////// Fire Roler
- struct FireRoler{
- UBYTE pixU;
- UBYTE pixV;
- //FLOAT fRadius;
- FLOAT fRadiusU;
- FLOAT fRadiusV;
- FLOAT fAngle;
- FLOAT fAngleAdd;
- };
- void InitializeFireRoler(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireRoler &fr =
- ((FireRoler&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- fr.pixU = pixU0;
- fr.pixV = pixV0;
- if (pixU0==pixU1 && pixV0==pixV1) {
- //fr.fRadius = 3;
- fr.fRadiusU = 3;
- fr.fRadiusV = 3;
- fr.fAngleAdd = (3.14f/6);
- } else {
- //fr.fRadius = sqrt((pixU1-pixU0)*(pixU1-pixU0) + (pixV1-pixV0)*(pixV1-pixV0));
- fr.fRadiusU = pixU1-pixU0;
- fr.fRadiusV = pixV1-pixV0;
- //fr.fAngleAdd = (3.14f/((fr.fRadius)*2));
- fr.fAngleAdd = (3.14f/(Abs(fr.fRadiusU)+Abs(fr.fRadiusV)));
- }
- fr.fAngle = 0;
- }
- void AnimateFireRoler(CTextureEffectSource *ptes)
- {
- FireRoler &fr =
- ((FireRoler&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
- sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 255);
- fr.fAngle += fr.fAngleAdd;
- PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
- sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 200);
- fr.fAngle += fr.fAngleAdd;
- PutPixel9UBYTE_FIRE(cos(fr.fAngle)*fr.fRadiusU + fr.pixU,
- sin(fr.fAngle)*fr.fRadiusV + fr.pixV, 150);
- fr.fAngle += fr.fAngleAdd;
- }
- ///////////////// Fire Fall
- #define FIREFALL_POINTS 100
- struct FireFall{
- UBYTE pixU;
- UBYTE pixV;
- ULONG ulWidth;
- ULONG ulPointToReinitialize;
- };
- struct FireFallPixel{
- UBYTE pixU;
- UBYTE pixV;
- UBYTE ubSpeed;
- };
- void InitializeFireFall(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireFall &ff =
- ((FireFall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ff.pixU = pixU0;
- ff.pixV = pixV0;
- if (pixU0==pixU1) {
- ff.ulWidth = 15;
- } else {
- ff.ulWidth = abs(pixU1-pixU0);
- }
- // initialize fall points
- ptes->tes_atepPixels.New(FIREFALL_POINTS);
- ff.ulPointToReinitialize = 0;
- for (INDEX iIndex=0; iIndex<FIREFALL_POINTS; iIndex++) {
- FireFallPixel &ffp = ((FireFallPixel&) ptes->tes_atepPixels[iIndex]);
- ffp.pixU = ff.pixU+(RNDW%ff.ulWidth);
- ffp.pixV = ff.pixV+(RNDW%_pixBufferHeight);
- ffp.ubSpeed = (RNDW&1)+2;
- }
- }
- void AnimateFireFall(CTextureEffectSource *ptes)
- {
- FireFall &ff =
- ((FireFall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- // animate fall points
- for (INDEX iIndex=0; iIndex<FIREFALL_POINTS; iIndex++) {
- FireFallPixel &ffp = ((FireFallPixel&) ptes->tes_atepPixels[iIndex]);
- // fall from fall
- int iHeight = (RNDW&3)*64 + 40;
- if (ffp.ubSpeed == 2) {
- PutPixelUBYTE_FIRE(ffp.pixU+(RNDW%3)-1, ffp.pixV, iHeight);
- PutPixelUBYTE_FIRE(ffp.pixU+(RNDW%3)-1, ffp.pixV+1, iHeight-40);
- } else {
- PutPixelUBYTE_FIRE(ffp.pixU, ffp.pixV, iHeight);
- PutPixelUBYTE_FIRE(ffp.pixU, ffp.pixV+1, iHeight-40);
- }
- ffp.pixV+=ffp.ubSpeed;
- // when falled down reinitialize
- if (ffp.pixV >= _pixBufferHeight) {
- if (ff.ulPointToReinitialize == iIndex) {
- ff.ulPointToReinitialize++;
- if (ff.ulPointToReinitialize >= FIREFALL_POINTS) ff.ulPointToReinitialize = 0;
- ffp.pixU = ff.pixU+(RNDW%ff.ulWidth);
- ffp.pixV -= _pixBufferHeight;
- ffp.ubSpeed = (RNDW&1)+2;
- } else {
- ffp.pixV -= _pixBufferHeight;
- }
- }
- }
- }
- ///////////////// Fire Fountain
- #define FIREFOUNTAIN_POINTS 100
- struct FireFountain{
- UBYTE pixU;
- UBYTE pixV;
- ULONG ulWidth;
- ULONG ulBaseHeight;
- ULONG ulRandomHeight;
- };
- struct FireFountainPixel{
- SWORD pixU;
- SWORD pixV;
- UBYTE pixLastU;
- UBYTE pixLastV;
- SWORD sbSpeedU;
- SWORD sbSpeedV;
- };
- void InitializeFireFountain(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireFountain &ff =
- ((FireFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- ff.pixU = pixU0;
- ff.pixV = pixV0;
- // fountain width
- if (pixU0==pixU1) {
- ff.ulWidth = 31;
- } else {
- ff.ulWidth = abs(pixU1-pixU0)*2;
- }
- // fountain height
- if (pixV0==pixV1) {
- ff.ulBaseHeight = 120;
- ff.ulRandomHeight = 40;
- } else {
- ff.ulBaseHeight = abs(pixV1-pixV0)*3;
- ff.ulRandomHeight = abs(pixV1-pixV0);
- }
- // initialize fountain points
- ptes->tes_atepPixels.New(FIREFOUNTAIN_POINTS*2);
- for (INDEX iIndex=0; iIndex<FIREFOUNTAIN_POINTS*2; iIndex+=2) {
- FireFountainPixel &ffp = ((FireFountainPixel&) ptes->tes_atepPixels[iIndex]);
- ffp.pixU = (ff.pixU)<<6;
- ffp.pixV = (RNDW%(_pixBufferHeight-(_pixBufferHeight>>3))+(_pixBufferHeight>>3))<<6;
- ffp.pixLastU = (ffp.pixU)>>6;
- ffp.pixLastV = (ffp.pixV)>>6;
- ffp.sbSpeedU = 0;
- ffp.sbSpeedV = 0;
- }
- }
- void AnimateFireFountain(CTextureEffectSource *ptes)
- {
- FireFountain &ff =
- ((FireFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- // animate fountain points
- for (INDEX iIndex=0; iIndex<FIREFOUNTAIN_POINTS*2; iIndex+=2) {
- FireFountainPixel &ffp = ((FireFountainPixel&) ptes->tes_atepPixels[iIndex]);
- // fall from fountain
- PutPixelUBYTE_FIRE((ffp.pixU)>>6, (ffp.pixV)>>6, 200);
- PutPixelUBYTE_FIRE(ffp.pixLastU, ffp.pixLastV, 150);
- // move pixel
- ffp.pixLastU = (ffp.pixU)>>6;
- ffp.pixLastV = (ffp.pixV)>>6;
- ffp.pixU+=ffp.sbSpeedU;
- ffp.pixV-=ffp.sbSpeedV;
- ffp.sbSpeedV-=8;
- // when falled down reinitialize
- if ((ffp.pixV>>6) >= (_pixBufferHeight-5)) {
- ffp.pixU = (ff.pixU)<<6;
- ffp.pixV = (ff.pixV)<<6;
- ffp.pixLastU = (ffp.pixU)>>6;
- ffp.pixLastV = (ffp.pixV)>>6;
- ffp.sbSpeedU = (RNDW%ff.ulWidth)-(ff.ulWidth/2-1);
- ffp.sbSpeedV = (RNDW%ff.ulRandomHeight)+ff.ulBaseHeight;
- }
- }
- }
- ///////////////// Fire Fountain
- #define FIRESIDEFOUNTAIN_POINTS 100
- struct FireSideFountain{
- UBYTE pixU;
- UBYTE pixV;
- ULONG ulBaseWidth;
- ULONG ulRandomWidth;
- ULONG ulSide;
- };
- struct FireSideFountainPixel{
- SWORD pixU;
- SWORD pixV;
- UBYTE pixLastU;
- UBYTE pixLastV;
- SWORD sbSpeedU;
- SWORD sbSpeedV;
- };
- void InitializeFireSideFountain(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireSideFountain &fsf =
- ((FireSideFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- fsf.pixU = pixU0;
- fsf.pixV = pixV0;
- // fountain width
- if (pixU0==pixU1) {
- fsf.ulBaseWidth = 80;
- fsf.ulRandomWidth = 40;
- fsf.ulSide = (pixU0>(_pixBufferWidth/2));
- } else {
- fsf.ulBaseWidth = abs(pixU1-pixU0)*2;
- fsf.ulRandomWidth = abs(pixU1-pixU0);
- fsf.ulSide = (pixU1<pixU0);
- }
- // initialize fountain points
- ptes->tes_atepPixels.New(FIRESIDEFOUNTAIN_POINTS*2);
- for (INDEX iIndex=0; iIndex<FIRESIDEFOUNTAIN_POINTS*2; iIndex+=2) {
- FireSideFountainPixel &fsfp = ((FireSideFountainPixel&) ptes->tes_atepPixels[iIndex]);
- fsfp.pixU = (fsf.pixU)<<6;
- fsfp.pixV = (RNDW%(_pixBufferHeight-(_pixBufferHeight>>3))+(_pixBufferHeight>>3))<<6;
- fsfp.pixLastU = (fsfp.pixU)>>6;
- fsfp.pixLastV = (fsfp.pixV)>>6;
- fsfp.sbSpeedU = 0;
- fsfp.sbSpeedV = 0;
- }
- }
- void AnimateFireSideFountain(CTextureEffectSource *ptes)
- {
- FireSideFountain &fsf =
- ((FireSideFountain&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- // animate fountain points
- for (INDEX iIndex=0; iIndex<FIRESIDEFOUNTAIN_POINTS*2; iIndex+=2) {
- FireSideFountainPixel &fsfp = ((FireSideFountainPixel&) ptes->tes_atepPixels[iIndex]);
- // fall from fountain
- PutPixelUBYTE_FIRE((fsfp.pixU)>>6, (fsfp.pixV)>>6, 200);
- PutPixelUBYTE_FIRE(fsfp.pixLastU, fsfp.pixLastV, 150);
- // move pixel
- fsfp.pixLastU = (fsfp.pixU)>>6;
- fsfp.pixLastV = (fsfp.pixV)>>6;
- fsfp.pixU+=fsfp.sbSpeedU;
- fsfp.pixV-=fsfp.sbSpeedV;
- fsfp.sbSpeedV-=8;
- // when falled down reinitialize
- if ((fsfp.pixV>>6) >= (_pixBufferHeight-5)) {
- fsfp.pixU = (fsf.pixU)<<6;
- fsfp.pixV = (fsf.pixV)<<6;
- fsfp.pixLastU = (fsfp.pixU)>>6;
- fsfp.pixLastV = (fsfp.pixV)>>6;
- fsfp.sbSpeedU = (RNDW%fsf.ulRandomWidth)+fsf.ulBaseWidth;
- if (fsf.ulSide) {
- fsfp.sbSpeedU = -fsfp.sbSpeedU;
- }
- fsfp.sbSpeedV = 0;
- }
- }
- }
- ///////////////// Fire Lightning
- struct FireLightning{
- FLOAT fpixUFrom;
- FLOAT fpixVFrom;
- FLOAT fpixUTo;
- FLOAT fpixVTo;
- FLOAT fvU;
- FLOAT fvV;
- FLOAT fvNormalU;
- FLOAT fvNormalV;
- FLOAT fDistance;
- SLONG slCnt;
- };
- void InitializeFireLightning(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireLightning &fl =
- ((FireLightning&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- fl.fpixUFrom = (FLOAT) pixU0;
- fl.fpixVFrom = (FLOAT) pixV0;
- if (pixU0==pixU1 && pixV0==pixV1) {
- fl.fpixUTo = Abs((FLOAT)_pixBufferWidth -fl.fpixUFrom);
- fl.fpixVTo = Abs((FLOAT)_pixBufferHeight-fl.fpixVFrom);
- } else {
- fl.fpixUTo = (FLOAT) pixU1;
- fl.fpixVTo = (FLOAT) pixV1;
- }
- fl.fDistance = sqrt((fl.fpixUTo-fl.fpixUFrom)*(fl.fpixUTo-fl.fpixUFrom)+
- (fl.fpixVTo-fl.fpixVFrom)*(fl.fpixVTo-fl.fpixVFrom));
- // vector
- fl.fvU = (fl.fpixUTo-fl.fpixUFrom)/fl.fDistance;
- fl.fvV = (fl.fpixVTo-fl.fpixVFrom)/fl.fDistance;
- // normal vector
- fl.fvNormalU = -fl.fvV;
- fl.fvNormalV = fl.fvU;
- // frame counter
- fl.slCnt = 2;
- }
- void AnimateFireLightning(CTextureEffectSource *ptes)
- {
- FLOAT fU, fV, fLastU, fLastV;
- FLOAT fDU, fDV, fCnt;
- SLONG slRND;
- ULONG ulDist;
- FireLightning &fl =
- ((FireLightning&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- // last point -> starting point
- fLastU = fl.fpixUFrom;
- fLastV = fl.fpixVFrom;
- fl.slCnt--;
- if (fl.slCnt == 0) {
- ulDist = 0;
- while ((FLOAT)ulDist<fl.fDistance) {
- // go away from source point to destination point
- ulDist += (RNDW%5)+5;
- if ((FLOAT)ulDist>=fl.fDistance) {
- // move point to line end
- fU = fl.fpixUTo;
- fV = fl.fpixVTo;
- } else {
- // move point on line
- fU = fl.fpixUFrom + fl.fvU*(FLOAT)ulDist;
- fV = fl.fpixVFrom + fl.fvV*(FLOAT)ulDist;
- // move point offset on normal line
- slRND = (SLONG) (RNDW%11)-5;
- fU += fl.fvNormalU*(FLOAT)slRND;
- fV += fl.fvNormalV*(FLOAT)slRND;
- }
- // draw line
- fDU = fU-fLastU;
- fDV = fV-fLastV;
- if (Abs(fDU)>Abs(fDV)) fCnt = Abs(fDU);
- else fCnt = Abs(fDV);
- fDU = fDU/fCnt;
- fDV = fDV/fCnt;
- while (fCnt>0.0f) {
- PutPixelUBYTE_FIRE((PIX) fLastU, (PIX) fLastV, 255);
- fLastU += fDU;
- fLastV += fDV;
- fCnt -= 1;
- }
- // store last point
- fLastU = fU;
- fLastV = fV;
- }
- fl.slCnt = 2;
- }
- }
- ///////////////// Fire Lightning Ball
- #define FIREBALL_LIGHTNINGS 2
- struct FireLightningBall{
- FLOAT fpixU;
- FLOAT fpixV;
- FLOAT fRadiusU;
- FLOAT fRadiusV;
- };
- void InitializeFireLightningBall(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireLightningBall &flb =
- ((FireLightningBall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- flb.fpixU = (FLOAT) pixU0;
- flb.fpixV = (FLOAT) pixV0;
- if (pixU0==pixU1 && pixV0==pixV1) {
- flb.fRadiusU = 20;
- flb.fRadiusV = 20;
- } else {
- flb.fRadiusU = pixU1-pixU0;
- flb.fRadiusV = pixV1-pixV0;
- }
- }
- void AnimateFireLightningBall(CTextureEffectSource *ptes)
- {
- FLOAT fU, fV, fLastU, fLastV, fvU, fvV, fvNormalU, fvNormalV;
- FLOAT fDU, fDV, fCnt, fDistance;
- FLOAT fDestU, fDestV, fAngle;
- SLONG slRND;
- ULONG ulDist;
- FireLightningBall &flb =
- ((FireLightningBall&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- for (int iBalls=0; iBalls<FIREBALL_LIGHTNINGS; iBalls++) {
- // last point -> starting point
- fLastU = flb.fpixU;
- fLastV = flb.fpixV;
- // destination point
- fAngle = (FLOAT) RNDW/10000;
- fDestU = flb.fpixU + flb.fRadiusU*cos(fAngle);
- fDestV = flb.fpixV + flb.fRadiusV*sin(fAngle);
- fDistance = sqrt((fDestU-fLastU)*(fDestU-fLastU)+
- (fDestV-fLastV)*(fDestV-fLastV));
- // vector
- fvU = (fDestU-fLastU)/fDistance;
- fvV = (fDestV-fLastV)/fDistance;
- // normal vector
- fvNormalU = -fvV;
- fvNormalV = fvU;
- ulDist = 0;
- while ((FLOAT)ulDist<fDistance) {
- // go away from source point to destination point
- ulDist += (RNDW%5)+5;
- if ((FLOAT)ulDist>=fDistance) {
- // move point on line
- fU = fDestU;
- fV = fDestV;
- } else {
- // move point on line
- fU = flb.fpixU + fvU*(FLOAT)ulDist;
- fV = flb.fpixV + fvV*(FLOAT)ulDist;
- // move point offset on normal line
- slRND = (SLONG) (RNDW%11)-5;
- fU += fvNormalU*(FLOAT)slRND;
- fV += fvNormalV*(FLOAT)slRND;
- }
- // draw line
- fDU = fU-fLastU;
- fDV = fV-fLastV;
- // counter
- if (Abs(fDU)>Abs(fDV)) fCnt = Abs(fDU);
- else fCnt = Abs(fDV);
- fDU = fDU/fCnt;
- fDV = fDV/fCnt;
- while (fCnt>0.0f) {
- PutPixelUBYTE_FIRE((PIX) fLastU, (PIX) fLastV, 255);
- fLastU += fDU;
- fLastV += fDV;
- fCnt -= 1;
- }
- // store last point
- fLastU = fU;
- fLastV = fV;
- }
- }
- }
- ///////////////// Fire Smoke
- #define SMOKE_POINTS 50
- struct FireSmoke{
- FLOAT fpixU;
- FLOAT fpixV;
- };
- struct FireSmokePoint{
- FLOAT fpixU;
- FLOAT fpixV;
- FLOAT fSpeedV;
- };
- void InitializeFireSmoke(CTextureEffectSource *ptes,
- PIX pixU0, PIX pixV0, PIX pixU1, PIX pixV1)
- {
- FireSmoke &fs =
- ((FireSmoke&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- fs.fpixU = (FLOAT) pixU0;
- fs.fpixV = (FLOAT) pixV0;
- if (pixU0==pixU1 && pixV0==pixV1) {
- } else {
- }
- // initialize smoke points
- ptes->tes_atepPixels.New(SMOKE_POINTS*2);
- for (INDEX iIndex=0; iIndex<SMOKE_POINTS*2; iIndex+=2) {
- FireSmokePoint &fsp = ((FireSmokePoint&) ptes->tes_atepPixels[iIndex]);
- fsp.fpixU = FLOAT (pixU0 + (iIndex-(SMOKE_POINTS))/8);
- fsp.fpixV = FLOAT (pixV0);
- fsp.fSpeedV = 0.0f;
- }
- }
- void AnimateFireSmoke(CTextureEffectSource *ptes)
- {
- int iHeat;
- FLOAT fRatio = 32.0f / (FLOAT)_pixBufferHeight;
- UBYTE pixU, pixV;
- FireSmoke &fs =
- ((FireSmoke&) ptes->tes_tespEffectSourceProperties.tesp_achDummy);
- // animate smoke points
- for (INDEX iIndex=0; iIndex<SMOKE_POINTS*2; iIndex+=2) {
- FireSmokePoint &fsp = ((FireSmokePoint&) ptes->tes_atepPixels[iIndex]);
- pixU = RNDW%3 - 1;
- pixV = RNDW%3 - 1;
- if (fsp.fSpeedV<0.1f) {
- PutPixelUBYTE_FIRE((PIX) fsp.fpixU, (PIX) fsp.fpixV, RNDW%128);
- } else {
- iHeat = int(fsp.fpixV*fRatio+1);
- PutPixel25UBYTE_FIRE((PIX) fsp.fpixU+pixU, (PIX) fsp.fpixV+pixV, RNDW%iHeat);
- }
- // start moving up
- if (fsp.fSpeedV<0.1f && (RNDW&255)==0) {
- fsp.fSpeedV = 1.0f;
- }
- // move up
- fsp.fpixV -= fsp.fSpeedV;
- // at the end of texture go on bottom
- if (fsp.fpixV<=(FLOAT)_pixBufferHeight) {
- fsp.fpixV = fs.fpixV;
- fsp.fSpeedV = 0.0f;
- }
- }
- }
- ///////////////// Water
- void InitializeWater(void)
- {
- Randomize( (ULONG)(_pTimer->GetHighPrecisionTimer().GetMilliseconds()));
- }
- /*******************************
- Water Animation
- ********************************/
- static void AnimateWater( SLONG slDensity)
- {
- _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
- /////////////////////////////////// move water
- SWORD *pNew = (SWORD*)_ptdEffect->td_pubBuffer1;
- SWORD *pOld = (SWORD*)_ptdEffect->td_pubBuffer2;
- PIX pixV, pixU;
- PIX pixOffset, iNew;
- SLONG slLineAbove, slLineBelow, slLineLeft, slLineRight;
- // inner rectangle (without 1 pixel top and bottom line)
- pixOffset = _pixBufferWidth + 1;
- for( pixV=_pixBufferHeight-2; pixV>0; pixV--) {
- for( pixU=_pixBufferWidth; pixU>0; pixU--) {
- iNew = (( (SLONG)pOld[pixOffset - _pixBufferWidth]
- + (SLONG)pOld[pixOffset + _pixBufferWidth]
- + (SLONG)pOld[pixOffset - 1]
- + (SLONG)pOld[pixOffset + 1]
- ) >> 1)
- - (SLONG)pNew[pixOffset];
- pNew[pixOffset] = iNew - (iNew >> slDensity);
- pixOffset++;
- }
- }
- // upper horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- slLineBelow = _pixBufferWidth + 1;
- slLineLeft = 0;
- slLineRight = 2;
- pixOffset = 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- iNew = (( (SLONG)pOld[slLineAbove]
- + (SLONG)pOld[slLineBelow]
- + (SLONG)pOld[slLineLeft]
- + (SLONG)pOld[slLineRight]
- ) >> 1)
- - (SLONG)pNew[pixOffset];
- pNew[pixOffset] = iNew - (iNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // lower horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
- slLineBelow = 1;
- slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
- slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
- pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- iNew = (( (SLONG)pOld[slLineAbove]
- + (SLONG)pOld[slLineBelow]
- + (SLONG)pOld[slLineLeft]
- + (SLONG)pOld[slLineRight]
- ) >> 1)
- - (SLONG)pNew[pixOffset];
- pNew[pixOffset] = iNew - (iNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // corner ( 0, 0)
- iNew = (( (SLONG)pOld[_pixBufferWidth]
- + (SLONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
- + (SLONG)pOld[1]
- + (SLONG)pOld[_pixBufferWidth-1]
- ) >> 1)
- - (SLONG)pNew[0];
- pNew[0] = iNew - (iNew >> slDensity);
- // corner ( 0, _pixBufferWidth)
- iNew = (( (SLONG)pOld[(2*_pixBufferWidth) - 1]
- + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- + (SLONG)pOld[0]
- + (SLONG)pOld[_pixBufferWidth-2]
- ) >> 1)
- - (SLONG)pNew[_pixBufferWidth-1];
- pNew[_pixBufferWidth-1] = iNew - (iNew >> slDensity);
- // corner ( _pixBufferHeight, 0)
- iNew = (( (SLONG)pOld[0]
- + (SLONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth]
- + (SLONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1]
- + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- ) >> 1)
- - (SLONG)pNew[(_pixBufferHeight-1)*_pixBufferWidth];
- pNew[(_pixBufferHeight-1)*_pixBufferWidth] = iNew - (iNew >> slDensity);
- // corner ( _pixBufferHeight, _pixBufferWidth)
- iNew = (( (SLONG)pOld[_pixBufferWidth-1]
- + (SLONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1]
- + (SLONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
- + (SLONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
- ) >> 1)
- - (SLONG)pNew[(_pixBufferHeight*_pixBufferWidth) - 1];
- pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = iNew - (iNew >> slDensity);
- // swap buffers
- Swap( _ptdEffect->td_pubBuffer1, _ptdEffect->td_pubBuffer2);
- _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
- }
- //////////////////////////// displace texture
- #define PIXEL(u,v) pulTextureBase[ ((u)&(SLONG&)mmBaseWidthMask) + ((v)&(SLONG&)mmBaseHeightMask) *pixBaseWidth]
- #pragma warning(disable: 4731)
- static void RenderWater(void)
- {
- _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
- // get textures' parameters
- ULONG *pulTexture = _ptdEffect->td_pulFrames;
- PIX pixBaseWidth = _ptdBase->GetPixWidth();
- PIX pixBaseHeight = _ptdBase->GetPixHeight();
- ULONG *pulTextureBase = _ptdBase->td_pulFrames
- + GetMipmapOffset( _iWantedMipLevel, pixBaseWidth, pixBaseHeight);
- pixBaseWidth >>= _iWantedMipLevel;
- pixBaseHeight >>= _iWantedMipLevel;
- mmBaseWidthMask = pixBaseWidth -1;
- mmBaseHeightMask = pixBaseHeight-1;
- ASSERT( _ptdEffect->td_pulFrames!=NULL && _ptdBase->td_pulFrames!=NULL);
- SWORD *pswHeightMap = (SWORD*)_ptdEffect->td_pubBuffer1; // height map pointer
- // copy top 2 lines from height map to bottom (so no mask offset will be needed)
- memcpy( (void*)(pswHeightMap+(_pixBufferHeight*_pixBufferWidth)), (void*)pswHeightMap,
- _pixBufferWidth*sizeof(SWORD)*2);
- // execute corresponding displace routine
- if( _pixBufferWidth >= _pixTexWidth)
- { // SUB-SAMPLING
- SLONG slHeightMapStep, slHeightRowStep;
- #if ASMOPT == 1
- __asm {
- push ebx
- bsf ecx,D [_pixTexWidth]
- dec ecx
- mov eax,D [_pixBufferWidth]
- sar eax,cl
- mov D [slHeightMapStep],eax
- bsf edx,eax
- add edx,DISTORSION+2-1
- mov D [mmShift],edx
- sub eax,2
- imul eax,D [_pixBufferWidth]
- mov D [slHeightRowStep],eax
- mov eax,D [pixBaseWidth]
- mov edx,D [pixBaseHeight]
- shl edx,16
- or eax,edx
- sub eax,0x00010001
- mov D [mmBaseMasks],eax
- mov eax,D [pixBaseWidth]
- shl eax,16
- or eax,1
- mov D [mmBaseWidth],eax
- mov ebx,D [pswHeightMap]
- mov esi,D [pulTextureBase]
- mov edi,D [pulTexture]
- pxor mm6,mm6 // MM5 = 0 | 0 || pixV | pixU
- mov eax,D [_pixBufferWidth]
- mov edx,D [_pixTexHeight]
- rowLoop:
- push edx
- mov ecx,D [_pixTexWidth]
- pixLoop:
- movd mm1,D [ebx]
- movd mm3,D [ebx+ eax*2]
- movq mm2,mm1
- psubw mm3,mm1
- pslld mm1,16
- psubw mm2,mm1
- pand mm2,Q [mm00M0]
- por mm2,mm3
- psraw mm2,Q [mmShift]
- paddw mm2,mm6
- pand mm2,Q [mmBaseMasks]
- pmaddwd mm2,Q [mmBaseWidth]
- movd edx,mm2
- mov edx,D [esi+ edx*4]
- mov D [edi],edx
- // advance to next texture pixel
- add ebx,D [slHeightMapStep]
- add edi,4
- paddd mm6,Q [mm0001]
- dec ecx
- jnz pixLoop
- // advance to next texture row
- pop edx
- add ebx,D [slHeightRowStep]
- paddd mm6,Q [mm0010]
- dec edx
- jnz rowLoop
- emms
- pop ebx
- }
- #else
- PIX pixPos, pixDU, pixDV;
- slHeightMapStep = _pixBufferWidth/pixBaseWidth
- slHeightRowStep = (slHeightMapStep-1)*_pixBufferWidth;
- mmShift = DISTORSION+ FastLog2(slHeightMapStep) +2;
- for( PIX pixV=0; pixV<_pixTexHeight; pixV++)
- { // row loop
- for( PIX pixU=0; pixU<_pixTexWidth; pixU++)
- { // texel loop
- pixPos = pswHeightMap[0];
- pixDU = (pswHeightMap[1] - pixPos) >>(SLONG&)mmShift;
- pixDV = (pswHeightMap[_pixBufferWidth] - pixPos) >>(SLONG&)mmShift;
- pixDU = (pixU +pixDU) & (SLONG&)mmBaseWidthMask;
- pixDV = (pixV +pixDV) & (SLONG&)mmBaseHeightMask;
- *pulTexture++ = pulTextureBase[pixDV*pixBaseWidth + pixDU];
- // advance to next texel in height map
- pswHeightMap += slHeightMapStep;
- }
- pswHeightMap += slHeightRowStep;
- }
- #endif
- }
- else if( _pixBufferWidth*2 == _pixTexWidth)
- { // BILINEAR SUPER-SAMPLING 2
- #if ASMOPT == 1
- __asm {
- push ebx
- bsf eax,D [pixBaseWidth]
- mov edx,32
- sub edx,eax
- mov D [mmBaseWidthShift],edx
- movq mm0,Q [mmBaseHeightMask]
- psllq mm0,32
- por mm0,Q [mmBaseWidthMask]
- movq Q [mmBaseMasks],mm0
- pxor mm6,mm6 // MM6 = pixV|pixU
- mov ebx,D [pswHeightMap]
- mov esi,D [pulTextureBase]
- mov edi,D [pulTexture]
- mov edx,D [_pixBufferHeight]
- rowLoop2:
- push edx
- mov edx,D [_pixTexWidth]
- mov ecx,D [_pixBufferWidth]
- pixLoop2:
- mov eax,D [_pixBufferWidth]
- movd mm1,D [ebx+ 2]
- movd mm0,D [ebx+ eax*2]
- psllq mm0,32
- por mm1,mm0
- movd mm0,D [ebx]
- punpckldq mm0,mm0
- psubd mm1,mm0
- movq mm0,mm6
- pslld mm0,DISTORSION+1+1
- paddd mm1,mm0 // MM1 = slV_00 | slU_00
- movd mm2,D [ebx+ 4]
- movd mm0,D [ebx+ eax*2 +2]
- psllq mm0,32
- por mm2,mm0
- movd mm0,D [ebx+ 2]
- punpckldq mm0,mm0
- psubd mm2,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1LO]
- pslld mm0,DISTORSION+1+1
- paddd mm2,mm0 // MM2 = slV_01 | slU_01
- movd mm3,D [ebx+ eax*2 +2]
- movd mm0,D [ebx+ eax*4]
- psllq mm0,32
- por mm3,mm0
- movd mm0,D [ebx+ eax*2]
- punpckldq mm0,mm0
- psubd mm3,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1HI]
- pslld mm0,DISTORSION+1+1
- paddd mm3,mm0 // MM3 = slV_10 | slU_10
- movd mm4,D [ebx+ eax*2 +4]
- movd mm0,D [ebx+ eax*4 +2]
- psllq mm0,32
- por mm4,mm0
- movd mm0,D [ebx+ eax*2 +2]
- punpckldq mm0,mm0
- psubd mm4,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1HILO]
- pslld mm0,DISTORSION+1+1
- paddd mm4,mm0 // MM4 = slV_11 | slU_11
- movq mm0,mm1
- psrad mm0,DISTORSION+1+0
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi],eax
- movq mm0,mm1
- paddd mm0,mm2
- psrad mm0,DISTORSION+1+1
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ 4],eax
- movq mm0,mm1
- paddd mm0,mm3
- psrad mm0,DISTORSION+1+1
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4],eax
- paddd mm1,mm2
- paddd mm1,mm3
- paddd mm1,mm4
- psrad mm1,DISTORSION+1+2
- pand mm1,Q [mmBaseMasks]
- movq mm7,mm1
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm1,mm7
- movd eax,mm1
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +4],eax
- // advance to next texture pixels
- paddd mm6,Q [mm1LO]
- add edi,8
- add ebx,2
- dec ecx
- jnz pixLoop2
- // advance to next texture row
- lea edi,[edi+ edx*4]
- pop edx
- paddd mm6,Q [mm1HI]
- dec edx
- jnz rowLoop2
- emms
- pop ebx
- }
- #else
- SLONG slU_00, slU_01, slU_10, slU_11;
- SLONG slV_00, slV_01, slV_10, slV_11;
- for( PIX pixV=0; pixV<_pixBufferHeight; pixV++)
- { // row loop
- for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
- { // texel loop
- slU_00 = pswHeightMap[_pixBufferWidth*0+1] - pswHeightMap[_pixBufferWidth*0+0] + ((pixU+0)<<(DISTORSION+1+1));
- slV_00 = pswHeightMap[_pixBufferWidth*1+0] - pswHeightMap[_pixBufferWidth*0+0] + ((pixV+0)<<(DISTORSION+1+1));
- slU_01 = pswHeightMap[_pixBufferWidth*0+2] - pswHeightMap[_pixBufferWidth*0+1] + ((pixU+1)<<(DISTORSION+1+1));
- slV_01 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*0+1] + ((pixV+0)<<(DISTORSION+1+1));
- slU_10 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*1+0] + ((pixU+0)<<(DISTORSION+1+1));
- slV_10 = pswHeightMap[_pixBufferWidth*2+0] - pswHeightMap[_pixBufferWidth*1+0] + ((pixV+1)<<(DISTORSION+1+1));
- slU_11 = pswHeightMap[_pixBufferWidth*1+2] - pswHeightMap[_pixBufferWidth*1+1] + ((pixU+1)<<(DISTORSION+1+1));
- slV_11 = pswHeightMap[_pixBufferWidth*2+1] - pswHeightMap[_pixBufferWidth*1+1] + ((pixV+1)<<(DISTORSION+1+1));
- pulTexture[_pixTexWidth*0+0] = PIXEL( (slU_00 ) >>(DISTORSION+1 ), (slV_00 ) >>(DISTORSION+1 ) );
- pulTexture[_pixTexWidth*0+1] = PIXEL( (slU_00+slU_01 ) >>(DISTORSION+1+1), (slV_00+slV_01 ) >>(DISTORSION+1+1) );
- pulTexture[_pixTexWidth*1+0] = PIXEL( (slU_00 +slU_10 ) >>(DISTORSION+1+1), (slV_00 +slV_10 ) >>(DISTORSION+1+1) );
- 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) );
- // advance to next texel
- pulTexture+=2;
- pswHeightMap++;
- }
- pulTexture+=_pixTexWidth;
- }
- #endif
- }
- else if( _pixBufferWidth*4 == _pixTexWidth)
- { // BILINEAR SUPER-SAMPLING 4
- #if ASMOPT == 1
- __asm {
- push ebx
- bsf eax,D [pixBaseWidth]
- mov edx,32
- sub edx,eax
- mov D [mmBaseWidthShift],edx
- movq mm0,Q [mmBaseHeightMask]
- psllq mm0,32
- por mm0,Q [mmBaseWidthMask]
- movq Q [mmBaseMasks],mm0
- pxor mm6,mm6 // MM6 = pixV|pixU
- mov ebx,D [pswHeightMap]
- mov esi,D [pulTextureBase]
- mov edi,D [pulTexture]
- mov edx,D [_pixBufferHeight]
- rowLoop4:
- push edx
- mov ecx,D [_pixBufferWidth]
- pixLoop4:
- mov eax,D [_pixBufferWidth]
- mov edx,D [_pixTexWidth]
- movd mm1,D [ebx+ 2]
- movd mm0,D [ebx+ eax*2]
- psllq mm0,32
- por mm1,mm0
- movd mm0,D [ebx]
- punpckldq mm0,mm0
- psubd mm1,mm0
- movq mm0,mm6
- pslld mm0,DISTORSION+1+1
- paddd mm1,mm0 // MM1 = slV_00 | slU_00
- movd mm2,D [ebx+ 4]
- movd mm0,D [ebx+ eax*2 +2]
- psllq mm0,32
- por mm2,mm0
- movd mm0,D [ebx+ 2]
- punpckldq mm0,mm0
- psubd mm2,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1LO]
- pslld mm0,DISTORSION+1+1
- paddd mm2,mm0 // MM2 = slV_01 | slU_01
- movd mm3,D [ebx+ eax*2 +2]
- movd mm0,D [ebx+ eax*4]
- psllq mm0,32
- por mm3,mm0
- movd mm0,D [ebx+ eax*2]
- punpckldq mm0,mm0
- psubd mm3,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1HI]
- pslld mm0,DISTORSION+1+1
- paddd mm3,mm0 // MM3 = slV_10 | slU_10
- movd mm4,D [ebx+ eax*2 +4]
- movd mm0,D [ebx+ eax*4 +2]
- psllq mm0,32
- por mm4,mm0
- movd mm0,D [ebx+ eax*2 +2]
- punpckldq mm0,mm0
- psubd mm4,mm0
- movq mm0,mm6
- paddd mm0,Q [mm1HILO]
- pslld mm0,DISTORSION+1+1
- paddd mm4,mm0 // MM4 = slV_11 | slU_11
- // texel 00
- movq mm0,mm1
- psrad mm0,DISTORSION
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi],eax
- // texel 01
- movq mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm2
- psrad mm0,DISTORSION+2
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi +4],eax
- // texel 02
- movq mm0,mm1
- paddd mm0,mm2
- psrad mm0,DISTORSION+1
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi +8],eax
- // texel 03
- movq mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm2
- psrad mm0,DISTORSION+2
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi +12],eax
- // texel 10
- movq mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm3
- psrad mm0,DISTORSION+2
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4],eax
- // texel 11
- movq mm0,mm1
- pslld mm0,3
- paddd mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm4
- psrad mm0,DISTORSION+4
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +4],eax
- // texel 12
- movq mm0,mm1
- paddd mm0,mm0
- paddd mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm4
- psrad mm0,DISTORSION+3
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +8],eax
- // texel 13
- movq mm0,mm2
- pslld mm0,3
- paddd mm0,mm2
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm3
- paddd mm0,mm4
- paddd mm0,mm4
- paddd mm0,mm4
- psrad mm0,DISTORSION+4
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +12],eax
- // texel 20
- movq mm0,mm1
- paddd mm0,mm3
- psrad mm0,DISTORSION+1
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*8],eax
- // texel 21
- movq mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm4
- psrad mm0,DISTORSION+3
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*8 +4],eax
- // texel 22
- movq mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm4
- psrad mm0,DISTORSION+2
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*8 +8],eax
- // texel 23
- movq mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm4
- paddd mm0,mm4
- paddd mm0,mm4
- psrad mm0,DISTORSION+3
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*8 +12],eax
- imul edx,3 // _pixTexWidth*=3
- // texel 30
- movq mm0,mm1
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm3
- psrad mm0,DISTORSION+2
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4],eax
- // texel 31
- movq mm0,mm3
- pslld mm0,3
- paddd mm0,mm3
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm4
- paddd mm0,mm4
- paddd mm0,mm4
- psrad mm0,DISTORSION+4
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +4],eax
- // texel 32
- movq mm0,mm4
- paddd mm0,mm0
- paddd mm0,mm4
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm2
- paddd mm0,mm1
- psrad mm0,DISTORSION+3
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +8],eax
- // texel 33
- movq mm0,mm4
- pslld mm0,3
- paddd mm0,mm4
- paddd mm0,mm1
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm2
- paddd mm0,mm3
- paddd mm0,mm3
- paddd mm0,mm3
- psrad mm0,DISTORSION+4
- pand mm0,Q [mmBaseMasks]
- movq mm7,mm0
- psrlq mm7,Q [mmBaseWidthShift]
- paddd mm0,mm7
- movd eax,mm0
- mov eax,D [esi+ eax*4]
- mov D [edi+ edx*4 +12],eax
- // advance to next texture pixels
- paddd mm6,Q [mm1LO]
- add edi,16
- add ebx,2
- dec ecx
- jnz pixLoop4
- // advance to next texture row
- lea edi,[edi+ edx*4] // +=[_pixTexWidth]*3
- pop edx
- paddd mm6,Q [mm1HI]
- dec edx
- jnz rowLoop4
- emms
- pop ebx
- }
- #else
- SLONG slU_00, slU_01, slU_10, slU_11;
- SLONG slV_00, slV_01, slV_10, slV_11;
- mmBaseWidthShift = FastLog2( pixBaseWidth); // faster multiplying with shift
- for( PIX pixV=0; pixV<_pixBufferHeight; pixV++)
- { // row loop
- for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
- { // texel loop
- slU_00 = pswHeightMap[_pixBufferWidth*0+1] - pswHeightMap[_pixBufferWidth*0+0] + ((pixU+0)<<(DISTORSION+2));
- slV_00 = pswHeightMap[_pixBufferWidth*1+0] - pswHeightMap[_pixBufferWidth*0+0] + ((pixV+0)<<(DISTORSION+2));
- slU_01 = pswHeightMap[_pixBufferWidth*0+2] - pswHeightMap[_pixBufferWidth*0+1] + ((pixU+1)<<(DISTORSION+2));
- slV_01 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*0+1] + ((pixV+0)<<(DISTORSION+2));
- slU_10 = pswHeightMap[_pixBufferWidth*1+1] - pswHeightMap[_pixBufferWidth*1+0] + ((pixU+0)<<(DISTORSION+2));
- slV_10 = pswHeightMap[_pixBufferWidth*2+0] - pswHeightMap[_pixBufferWidth*1+0] + ((pixV+1)<<(DISTORSION+2));
- slU_11 = pswHeightMap[_pixBufferWidth*1+2] - pswHeightMap[_pixBufferWidth*1+1] + ((pixU+1)<<(DISTORSION+2));
- slV_11 = pswHeightMap[_pixBufferWidth*2+1] - pswHeightMap[_pixBufferWidth*1+1] + ((pixV+1)<<(DISTORSION+2));
- pulTexture[_pixTexWidth*0+0] = PIXEL( (slU_00 ) >>(DISTORSION ), (slV_00 ) >>(DISTORSION ) );
- pulTexture[_pixTexWidth*0+1] = PIXEL( (slU_00* 3+slU_01* 1 ) >>(DISTORSION+2), (slV_00* 3+slV_01* 1 ) >>(DISTORSION+2) );
- pulTexture[_pixTexWidth*0+2] = PIXEL( (slU_00 +slU_01 ) >>(DISTORSION+1), (slV_00 +slV_01 ) >>(DISTORSION+1) );
- pulTexture[_pixTexWidth*0+3] = PIXEL( (slU_00* 1+slU_01* 3 ) >>(DISTORSION+2), (slV_00* 1+slV_01* 3 ) >>(DISTORSION+2) );
- pulTexture[_pixTexWidth*1+0] = PIXEL( (slU_00* 3 +slU_10* 1 ) >>(DISTORSION+2), (slV_00* 3 +slV_10 ) >>(DISTORSION+2) );
- 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) );
- 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) );
- 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) );
- pulTexture[_pixTexWidth*2+0] = PIXEL( (slU_00 +slU_10 ) >>(DISTORSION+1), (slV_00 +slV_10 ) >>(DISTORSION+1) );
- 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) );
- 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) );
- 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) );
- pulTexture[_pixTexWidth*3+0] = PIXEL( (slU_00* 1 +slU_10* 3 ) >>(DISTORSION+2), (slV_00* 1 +slV_10* 3 ) >>(DISTORSION+2) );
- 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) );
- 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) );
- 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) );
- // advance to next texel
- pulTexture+=4;
- pHeightMap++;
- }
- pulTexture+=_pixTexWidth*3;
- }
- #endif
- }
- else
- { // DO NOTHING
- ASSERTALWAYS( "Effect textures larger than 256 pixels aren't supported");
- }
- _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
- }
- #pragma warning(default: 4731)
- ///////////////// Fire
- void InitializeFire(void)
- {
- Randomize( (ULONG)(_pTimer->GetHighPrecisionTimer().GetMilliseconds()));
- }
-
- enum PlasmaType {
- ptNormal = 0,
- ptUp,
- ptUpTile,
- ptDown,
- ptDownTile
- };
- /*******************************
- Plasma Animation
- ********************************/
- static void AnimatePlasma( SLONG slDensity, PlasmaType eType)
- {
- _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
- /////////////////////////////////// move plasma
- UBYTE *pNew = (UBYTE*)_ptdEffect->td_pubBuffer1;
- UBYTE *pOld = (UBYTE*)_ptdEffect->td_pubBuffer2;
- PIX pixV, pixU;
- PIX pixOffset;
- SLONG slLineAbove, slLineBelow, slLineLeft, slLineRight;
- ULONG ulNew;
- // --------------------------
- // Normal plasma
- // --------------------------
- if (eType == ptNormal) {
- // inner rectangle (without 1 pixel border)
- pixOffset = _pixBufferWidth;
- for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
- for( pixU=0; pixU<_pixBufferWidth; pixU++) {
- ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
- (ULONG)pOld[pixOffset + _pixBufferWidth] +
- (ULONG)pOld[pixOffset - 1] +
- (ULONG)pOld[pixOffset + 1]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[pixOffset] = ulNew - (ulNew >> slDensity);
- pixOffset++;
- }
- }
- // upper horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- slLineBelow = _pixBufferWidth + 1;
- slLineLeft = 0;
- slLineRight = 2;
- pixOffset = 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[pixOffset] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // lower horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
- slLineBelow = 1;
- slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
- slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
- pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[pixOffset] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // corner ( 0, 0)
- ulNew = ((((ULONG)pOld[_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[1] +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>2) +
- (ULONG)pOld[0]
- )>>1;
- pNew[0] = ulNew - (ulNew >> slDensity);
- // corner ( 0, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
- (ULONG)pOld[0] +
- (ULONG)pOld[_pixBufferWidth-2]
- )>>2) +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>1;
- pNew[_pixBufferWidth-1] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, 0)
- ulNew = ((((ULONG)pOld[0] +
- (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
- )>>1;
- pNew[(_pixBufferHeight-1)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>1;
- pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
- // --------------------------
- // Plasma going up
- // --------------------------
- } else if (eType==ptUp || eType==ptUpTile) {
- // inner rectangle (without 1 pixel border)
- pixOffset = _pixBufferWidth;
- for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
- for( pixU=0; pixU<_pixBufferWidth; pixU++) {
- ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
- (ULONG)pOld[pixOffset + _pixBufferWidth] +
- (ULONG)pOld[pixOffset - 1] +
- (ULONG)pOld[pixOffset + 1]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[pixOffset-_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- pixOffset++;
- }
- }
- // tile
- if (eType==ptUpTile) {
- // upper horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- slLineBelow = _pixBufferWidth + 1;
- slLineLeft = 0;
- slLineRight = 2;
- pixOffset = 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[slLineAbove] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // lower horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
- slLineBelow = 1;
- slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
- slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
- pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[slLineAbove] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // corner ( 0, 0)
- ulNew = ((((ULONG)pOld[_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[1] +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>2) +
- (ULONG)pOld[0]
- )>>1;
- pNew[(_pixBufferHeight-1)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- // corner ( 0, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
- (ULONG)pOld[0] +
- (ULONG)pOld[_pixBufferWidth-2]
- )>>2) +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>1;
- pNew[(_pixBufferHeight*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, 0)
- ulNew = ((((ULONG)pOld[0] +
- (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
- )>>1;
- pNew[(_pixBufferHeight-2)*_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>1;
- pNew[((_pixBufferHeight-1)*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
- }
- // --------------------------
- // Plasma going down
- // --------------------------
- } else if (eType==ptDown || eType==ptDownTile) {
- // inner rectangle (without 1 pixel border)
- pixOffset = _pixBufferWidth;
- for( pixV=1; pixV<_pixBufferHeight-1; pixV++) {
- for( pixU=0; pixU<_pixBufferWidth; pixU++) {
- ulNew = ((((ULONG)pOld[pixOffset - _pixBufferWidth] +
- (ULONG)pOld[pixOffset + _pixBufferWidth] +
- (ULONG)pOld[pixOffset - 1] +
- (ULONG)pOld[pixOffset + 1]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[pixOffset+_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- pixOffset++;
- }
- }
- // tile
- if (eType==ptDownTile) {
- // upper horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- slLineBelow = _pixBufferWidth + 1;
- slLineLeft = 0;
- slLineRight = 2;
- pixOffset = 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[slLineBelow] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // lower horizontal border (without corners)
- slLineAbove = ((_pixBufferHeight-2)*_pixBufferWidth) + 1;
- slLineBelow = 1;
- slLineLeft = (_pixBufferHeight-1)*_pixBufferWidth;
- slLineRight = ((_pixBufferHeight-1)*_pixBufferWidth) + 2;
- pixOffset = ((_pixBufferHeight-1)*_pixBufferWidth) + 1;
- for( pixU=_pixBufferWidth-2; pixU>0; pixU--) {
- ulNew = ((((ULONG)pOld[slLineAbove] +
- (ULONG)pOld[slLineBelow] +
- (ULONG)pOld[slLineLeft] +
- (ULONG)pOld[slLineRight]
- )>>2) +
- (ULONG)pOld[pixOffset]
- )>>1;
- pNew[slLineBelow] = ulNew - (ulNew >> slDensity);
- slLineAbove++;
- slLineBelow++;
- slLineLeft++;
- slLineRight++;
- pixOffset++;
- }
- // corner ( 0, 0)
- ulNew = ((((ULONG)pOld[_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[1] +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>2) +
- (ULONG)pOld[0]
- )>>1;
- pNew[_pixBufferWidth] = ulNew - (ulNew >> slDensity);
- // corner ( 0, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[(2*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1] +
- (ULONG)pOld[0] +
- (ULONG)pOld[_pixBufferWidth-2]
- )>>2) +
- (ULONG)pOld[_pixBufferWidth-1]
- )>>1;
- pNew[(2*_pixBufferWidth) - 1] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, 0)
- ulNew = ((((ULONG)pOld[0] +
- (ULONG)pOld[(_pixBufferHeight-2)*_pixBufferWidth] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) + 1] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth]
- )>>1;
- pNew[0] = ulNew - (ulNew >> slDensity);
- // corner ( _pixBufferHeight, _pixBufferWidth)
- ulNew = ((((ULONG)pOld[_pixBufferWidth-1] +
- (ULONG)pOld[((_pixBufferHeight-1)*_pixBufferWidth) - 1] +
- (ULONG)pOld[(_pixBufferHeight-1)*_pixBufferWidth] +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 2]
- )>>2) +
- (ULONG)pOld[(_pixBufferHeight*_pixBufferWidth) - 1]
- )>>1;
- pNew[_pixBufferWidth-1] = ulNew - (ulNew >> slDensity);
- }
- }
- // swap buffers
- Swap( _ptdEffect->td_pubBuffer1, _ptdEffect->td_pubBuffer2);
- _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
- }
- /*******************************
- Fire Animation
- ********************************/
- static void AnimateFire( SLONG slDensity)
- {
- // _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
- /////////////////////////////////// move fire
- // use only one buffer (otherwise it's not working)
- UBYTE *pubNew = (UBYTE*)_ptdEffect->td_pubBuffer2;
- SLONG slBufferMask = _pixBufferWidth*_pixBufferHeight -1;
- SLONG slColumnModulo = _pixBufferWidth*(_pixBufferHeight-2) -1;
- #if ASMOPT == 1
- __asm {
- push ebx
- mov edi,D [ulRNDSeed] ;// EDI = randomizer
- mov esi,D [pubNew]
- xor ebx,ebx
- colLoopFM:
- mov ecx,D [_pixBufferHeight]
- sub ecx,2
- rowLoopFM:
- mov edx,D [_pixBufferWidth]
- add edx,esi
- movzx eax,B [ebx+ edx]
- add edx,D [_pixBufferWidth]
- movzx edx,B [ebx+ edx]
- add eax,edx
- shr eax,1
- cmp eax,D [slDensity]
- jg doCalc
- mov B [esi+ebx],0
- jmp pixDone
- doCalc:
- mov edx,edi
- sar edx,16
- and edx,D [slDensity]
- sub eax,edx
- movsx edx,B [asbMod3Sub1Table +edx]
- add edx,ebx
- and edx,D [slBufferMask]
- mov B [esi+edx],al
- imul edi,262147
- pixDone:
- // advance to next row
- add ebx,D [_pixBufferWidth]
- dec ecx
- jnz rowLoopFM
- // advance to next column
- sub ebx,D [slColumnModulo]
- cmp ebx,D [_pixBufferWidth]
- jl colLoopFM
- // all done
- mov D [ulRNDSeed],edi
- pop ebx
- }
- #else
- // inner rectangle (without 1 pixel border)
- for( PIX pixU=0; pixU<_pixBufferWidth; pixU++)
- {
- SLONG slOffset = pixU;
- for( PIX pixV=1; pixV<_pixBufferHeight-1; pixV++)
- {
- ULONG ulNew = ((ULONG)pubNew[_pixBufferWidth+slOffset] + (ULONG)pubNew[_pixBufferWidth*2+slOffset]) >>1;
- if( ulNew>slDensity) {
- ULONG ulNewDensity = RNDW&slDensity;
- ulNew -= ulNewDensity;
- SLONG slDifusion = (SLONG)asbMod3Sub1Table[ulNewDensity]; // (SLONG)(ulNewDensity%3-1);
- SLONG slPos = (slDifusion+slOffset) & slBufferMask;
- pubNew[slPos] = ulNew;
- } else {
- pubNew[slOffset] = 0;
- }
- slOffset += _pixBufferWidth;
- }
- }
- #endif
- // _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
- }
- //////////////////////////// displace texture
- static void RenderPlasmaFire(void)
- {
- // _sfStats.StartTimer(CStatForm::STI_EFFECTRENDER);
- // get and adjust textures' parameters
- PIX pixBaseWidth = _ptdBase->GetPixWidth();
- ULONG *pulTextureBase = _ptdBase->td_pulFrames;
- ULONG *pulTexture = _ptdEffect->td_pulFrames;
- ASSERT( _ptdEffect->td_pulFrames!=NULL && _ptdBase->td_pulFrames!=NULL && pixBaseWidth<=256);
- UBYTE *pubHeat = (UBYTE*)_ptdEffect->td_pubBuffer2; // heat map pointer
- SLONG slHeatMapStep = _pixBufferWidth/_pixTexWidth;
- SLONG slHeatRowStep = (slHeatMapStep-1)*_pixBufferWidth;
- SLONG slBaseMipShift = 8 - FastLog2(pixBaseWidth);
- #if ASMOPT == 1
- __asm {
- push ebx
- mov ebx,D [pubHeat]
- mov esi,D [pulTextureBase]
- mov edi,D [pulTexture]
- mov ecx,D [_pixTexHeight]
- rowLoopF:
- push ecx
- mov edx,D [_pixTexWidth]
- mov ecx,D [slBaseMipShift]
- pixLoopF:
- movzx eax,B [ebx]
- shr eax,cl
- mov eax,D [esi+ eax*4]
- mov D [edi],eax
- // advance to next pixel
- add ebx,D [slHeatMapStep]
- add edi,4
- dec edx
- jnz pixLoopF
- // advance to next row
- pop ecx
- add ebx,D [slHeatRowStep]
- dec ecx
- jnz rowLoopF
- pop ebx
- }
- #else
- INDEX iPalette;
- for( INDEX pixV=0; pixV<_pixTexHeight; pixV++) {
- // for every pixel in horizontal line
- for( INDEX pixU=0; pixU<_pixTexWidth; pixU++) {
- iPalette = (*pubHeat)>>slBaseMipShift;
- *pulTexture++ = pulTextureBase[iPalette];
- pubHeat += slHeatMapStep;
- }
- pubHeat += slHeatRowStep;
- }
- #endif
- // _sfStats.StopTimer(CStatForm::STI_EFFECTRENDER);
- }
- /////////////////////////////////////////////////////////////////////
- // EFFECT TABLES
- /////////////////////////////////////////////////////////////////////
- struct TextureEffectSourceType atestWater[] = {
- {
- "Raindrops",
- InitializeRaindropsStandard,
- AnimateRaindropsStandard
- },
- {
- "RaindropsBig",
- InitializeRaindropsBig,
- AnimateRaindropsBig
- },
- {
- "RaindropsSmall",
- InitializeRaindropsSmall,
- AnimateRaindropsSmall
- },
- {
- "Random Surfer",
- InitializeRandomSurfer,
- AnimateRandomSurfer
- },
- {
- "Oscilator",
- InitializeOscilator,
- AnimateOscilator
- },
- {
- "Vertical Line",
- InitializeVertLine,
- AnimateVertLine
- },
- {
- "Horizontal Line",
- InitializeHortLine,
- AnimateHortLine
- },
- };
- struct TextureEffectSourceType atestFire[] = {
- {
- "Point",
- InitializeFirePoint,
- AnimateFirePoint
- },
- {
- "Random Point",
- InitializeRandomFirePoint,
- AnimateRandomFirePoint
- },
- {
- "Shake Point",
- InitializeFireShakePoint,
- AnimateFireShakePoint
- },
- {
- "Fire Place",
- InitializeFirePlace,
- AnimateFirePlace
- },
- {
- "Roler",
- InitializeFireRoler,
- AnimateFireRoler
- },
- {
- "Fall",
- InitializeFireFall,
- AnimateFireFall
- },
- {
- "Fountain",
- InitializeFireFountain,
- AnimateFireFountain
- },
- {
- "Side Fountain",
- InitializeFireSideFountain,
- AnimateFireSideFountain
- },
- {
- "Lightning",
- InitializeFireLightning,
- AnimateFireLightning
- },
- {
- "Lightning Ball",
- InitializeFireLightningBall,
- AnimateFireLightningBall
- },
- {
- "Smoke",
- InitializeFireSmoke,
- AnimateFireSmoke
- },
- };
- void AWaterFast(void) { AnimateWater(2); };
- void AWaterMedium(void) { AnimateWater(3); };
- void AWaterSlow(void) { AnimateWater(5); };
- void APlasma(void) { AnimatePlasma(4, ptNormal); };
- void APlasmaUp(void) { AnimatePlasma(4, ptUp); };
- void APlasmaUpTile(void) { AnimatePlasma(4, ptUpTile); };
- void APlasmaDown(void) { AnimatePlasma(5, ptDown); };
- void APlasmaDownTile(void) { AnimatePlasma(5, ptDownTile); };
- void APlasmaUpSlow(void) { AnimatePlasma(6, ptUp); };
- void AFire(void) { AnimateFire(15); };
- struct TextureEffectGlobalType _ategtTextureEffectGlobalPresets[] = {
- {
- "Water Fast",
- InitializeWater,
- AWaterFast,
- sizeof(atestWater)/sizeof(atestWater[0]),
- atestWater
- },
- {
- "Water Medium",
- InitializeWater,
- AWaterMedium,
- sizeof(atestWater)/sizeof(atestWater[0]),
- atestWater
- },
- {
- "Water Slow",
- InitializeWater,
- AWaterSlow,
- sizeof(atestWater)/sizeof(atestWater[0]),
- atestWater
- },
- {
- "",
- InitializeWater,
- AWaterSlow,
- sizeof(atestWater)/sizeof(atestWater[0]),
- atestWater
- },
- {
- "Plasma Tile",
- InitializeFire,
- APlasma,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Plasma Up",
- InitializeFire,
- APlasmaUp,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Plasma Up Tile",
- InitializeFire,
- APlasmaUpTile,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Plasma Down",
- InitializeFire,
- APlasmaDown,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Plasma Down Tile",
- InitializeFire,
- APlasmaDownTile,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Plasma Up Slow",
- InitializeFire,
- APlasmaUpSlow,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- {
- "Fire",
- InitializeFire,
- AFire,
- sizeof(atestFire)/sizeof(atestFire[0]),
- atestFire
- },
- };
- INDEX _ctTextureEffectGlobalPresets = sizeof(_ategtTextureEffectGlobalPresets)
- / sizeof(_ategtTextureEffectGlobalPresets[0]);
- // get effect type (TRUE if water type effect, FALSE if plasma or fire effect)
- BOOL CTextureEffectGlobal::IsWater(void)
- {
- return( _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Initialize == InitializeWater);
- }
- // default constructor
- CTextureEffectGlobal::CTextureEffectGlobal(CTextureData *ptdTexture, ULONG ulGlobalEffect)
- {
- // remember global effect's texture data for cross linking
- teg_ptdTexture = ptdTexture;
- teg_ulEffectType = ulGlobalEffect;
- // init for animating
- _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Initialize();
- // make sure the texture will be updated next time when used
- teg_updTexture.Invalidate();
- }
- // add new effect source.
- void CTextureEffectGlobal::AddEffectSource( ULONG ulEffectSourceType, PIX pixU0, PIX pixV0,
- PIX pixU1, PIX pixV1)
- {
- CTextureEffectSource* ptesNew = teg_atesEffectSources.New(1);
- ptesNew->Initialize(this, ulEffectSourceType, pixU0, pixV0, pixU1, pixV1);
- }
- // animate effect texture
- void CTextureEffectGlobal::Animate(void)
- {
- // if not set yet (funny word construction:)
- if( !bTableSet) {
- // set table for fast modulo 3 minus 1
- for( INDEX i=0; i<256; i++) asbMod3Sub1Table[i]=(SBYTE)((i%3)-1);
- bTableSet = TRUE;
- }
- // setup some internal vars
- _ptdEffect = teg_ptdTexture;
- _pixBufferWidth = _ptdEffect->td_pixBufferWidth;
- _pixBufferHeight = _ptdEffect->td_pixBufferHeight;
- _ulBufferMask = _pixBufferHeight*_pixBufferWidth -1;
- // remember buffer pointers
- _pubDrawBuffer=(UBYTE*)_ptdEffect->td_pubBuffer2;
- _pswDrawBuffer=(SWORD*)_ptdEffect->td_pubBuffer2;
-
- // for each effect source
- FOREACHINDYNAMICARRAY( teg_atesEffectSources, CTextureEffectSource, itEffectSource) {
- // let it animate itself
- itEffectSource->Animate();
- }
- // use animation function for this global effect type
- _ategtTextureEffectGlobalPresets[teg_ulEffectType].tegt_Animate();
- // remember that it was calculated
- teg_updTexture.MarkUpdated();
- }
- #pragma warning(disable: 4731)
- // render effect texture
- void CTextureEffectGlobal::Render( INDEX iWantedMipLevel, PIX pixTexWidth, PIX pixTexHeight)
- {
- // setup some internal vars
- _ptdEffect = teg_ptdTexture;
- _ptdBase = teg_ptdTexture->td_ptdBaseTexture;
- _pixBufferWidth = _ptdEffect->td_pixBufferWidth;
- _pixBufferHeight = _ptdEffect->td_pixBufferHeight;
- if( IsWater()) {
- // use water rendering routine
- _pixTexWidth = pixTexWidth;
- _pixTexHeight = pixTexHeight;
- _iWantedMipLevel = iWantedMipLevel;
- RenderWater();
- } else {
- // use plasma & fire rendering routine
- _pixTexWidth = _ptdEffect->GetWidth() >>iWantedMipLevel;
- _pixTexHeight = _ptdEffect->GetHeight() >>iWantedMipLevel;
- RenderPlasmaFire();
- }
- }
- #pragma warning(default: 4731)
- // returns number of second it took to render effect texture
- DOUBLE CTextureEffectGlobal::GetRenderingTime(void)
- {
- return( _sfStats.sf_astTimers[CStatForm::STI_EFFECTRENDER].st_tvElapsed.GetSeconds());
- }
|