c2runtime.js 679 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711
  1. // Generated by Construct 2, the HTML5 game and app creator :: http://www.scirra.com
  2. var cr = {};
  3. cr.plugins_ = {};
  4. cr.behaviors = {};
  5. if (typeof Object.getPrototypeOf !== "function")
  6. {
  7. if (typeof "test".__proto__ === "object")
  8. {
  9. Object.getPrototypeOf = function(object) {
  10. return object.__proto__;
  11. };
  12. }
  13. else
  14. {
  15. Object.getPrototypeOf = function(object) {
  16. return object.constructor.prototype;
  17. };
  18. }
  19. }
  20. (function(){
  21. cr.logexport = function (msg)
  22. {
  23. if (window.console && window.console.log)
  24. window.console.log(msg);
  25. };
  26. cr.logerror = function (msg)
  27. {
  28. if (window.console && window.console.error)
  29. window.console.error(msg);
  30. };
  31. cr.seal = function(x)
  32. {
  33. return x;
  34. };
  35. cr.freeze = function(x)
  36. {
  37. return x;
  38. };
  39. cr.is_undefined = function (x)
  40. {
  41. return typeof x === "undefined";
  42. };
  43. cr.is_number = function (x)
  44. {
  45. return typeof x === "number";
  46. };
  47. cr.is_string = function (x)
  48. {
  49. return typeof x === "string";
  50. };
  51. cr.isPOT = function (x)
  52. {
  53. return x > 0 && ((x - 1) & x) === 0;
  54. };
  55. cr.nextHighestPowerOfTwo = function(x) {
  56. --x;
  57. for (var i = 1; i < 32; i <<= 1) {
  58. x = x | x >> i;
  59. }
  60. return x + 1;
  61. }
  62. cr.abs = function (x)
  63. {
  64. return (x < 0 ? -x : x);
  65. };
  66. cr.max = function (a, b)
  67. {
  68. return (a > b ? a : b);
  69. };
  70. cr.min = function (a, b)
  71. {
  72. return (a < b ? a : b);
  73. };
  74. cr.PI = Math.PI;
  75. cr.round = function (x)
  76. {
  77. return (x + 0.5) | 0;
  78. };
  79. cr.floor = function (x)
  80. {
  81. if (x >= 0)
  82. return x | 0;
  83. else
  84. return (x | 0) - 1; // correctly round down when negative
  85. };
  86. cr.ceil = function (x)
  87. {
  88. var f = x | 0;
  89. return (f === x ? f : f + 1);
  90. };
  91. function Vector2(x, y)
  92. {
  93. this.x = x;
  94. this.y = y;
  95. cr.seal(this);
  96. };
  97. Vector2.prototype.offset = function (px, py)
  98. {
  99. this.x += px;
  100. this.y += py;
  101. return this;
  102. };
  103. Vector2.prototype.mul = function (px, py)
  104. {
  105. this.x *= px;
  106. this.y *= py;
  107. return this;
  108. };
  109. cr.vector2 = Vector2;
  110. cr.segments_intersect = function(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)
  111. {
  112. var max_ax, min_ax, max_ay, min_ay, max_bx, min_bx, max_by, min_by;
  113. if (a1x < a2x)
  114. {
  115. min_ax = a1x;
  116. max_ax = a2x;
  117. }
  118. else
  119. {
  120. min_ax = a2x;
  121. max_ax = a1x;
  122. }
  123. if (b1x < b2x)
  124. {
  125. min_bx = b1x;
  126. max_bx = b2x;
  127. }
  128. else
  129. {
  130. min_bx = b2x;
  131. max_bx = b1x;
  132. }
  133. if (max_ax < min_bx || min_ax > max_bx)
  134. return false;
  135. if (a1y < a2y)
  136. {
  137. min_ay = a1y;
  138. max_ay = a2y;
  139. }
  140. else
  141. {
  142. min_ay = a2y;
  143. max_ay = a1y;
  144. }
  145. if (b1y < b2y)
  146. {
  147. min_by = b1y;
  148. max_by = b2y;
  149. }
  150. else
  151. {
  152. min_by = b2y;
  153. max_by = b1y;
  154. }
  155. if (max_ay < min_by || min_ay > max_by)
  156. return false;
  157. var dpx = b1x - a1x + b2x - a2x;
  158. var dpy = b1y - a1y + b2y - a2y;
  159. var qax = a2x - a1x;
  160. var qay = a2y - a1y;
  161. var qbx = b2x - b1x;
  162. var qby = b2y - b1y;
  163. var d = cr.abs(qay * qbx - qby * qax);
  164. var la = qbx * dpy - qby * dpx;
  165. if (cr.abs(la) > d)
  166. return false;
  167. var lb = qax * dpy - qay * dpx;
  168. return cr.abs(lb) <= d;
  169. };
  170. function Rect(left, top, right, bottom)
  171. {
  172. this.set(left, top, right, bottom);
  173. cr.seal(this);
  174. };
  175. Rect.prototype.set = function (left, top, right, bottom)
  176. {
  177. this.left = left;
  178. this.top = top;
  179. this.right = right;
  180. this.bottom = bottom;
  181. };
  182. Rect.prototype.copy = function (r)
  183. {
  184. this.left = r.left;
  185. this.top = r.top;
  186. this.right = r.right;
  187. this.bottom = r.bottom;
  188. };
  189. Rect.prototype.width = function ()
  190. {
  191. return this.right - this.left;
  192. };
  193. Rect.prototype.height = function ()
  194. {
  195. return this.bottom - this.top;
  196. };
  197. Rect.prototype.offset = function (px, py)
  198. {
  199. this.left += px;
  200. this.top += py;
  201. this.right += px;
  202. this.bottom += py;
  203. return this;
  204. };
  205. Rect.prototype.normalize = function ()
  206. {
  207. var temp = 0;
  208. if (this.left > this.right)
  209. {
  210. temp = this.left;
  211. this.left = this.right;
  212. this.right = temp;
  213. }
  214. if (this.top > this.bottom)
  215. {
  216. temp = this.top;
  217. this.top = this.bottom;
  218. this.bottom = temp;
  219. }
  220. };
  221. Rect.prototype.intersects_rect = function (rc)
  222. {
  223. return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom);
  224. };
  225. Rect.prototype.intersects_rect_off = function (rc, ox, oy)
  226. {
  227. return !(rc.right + ox < this.left || rc.bottom + oy < this.top || rc.left + ox > this.right || rc.top + oy > this.bottom);
  228. };
  229. Rect.prototype.contains_pt = function (x, y)
  230. {
  231. return (x >= this.left && x <= this.right) && (y >= this.top && y <= this.bottom);
  232. };
  233. Rect.prototype.equals = function (r)
  234. {
  235. return this.left === r.left && this.top === r.top && this.right === r.right && this.bottom === r.bottom;
  236. };
  237. cr.rect = Rect;
  238. function Quad()
  239. {
  240. this.tlx = 0;
  241. this.tly = 0;
  242. this.trx = 0;
  243. this.try_ = 0; // is a keyword otherwise!
  244. this.brx = 0;
  245. this.bry = 0;
  246. this.blx = 0;
  247. this.bly = 0;
  248. cr.seal(this);
  249. };
  250. Quad.prototype.set_from_rect = function (rc)
  251. {
  252. this.tlx = rc.left;
  253. this.tly = rc.top;
  254. this.trx = rc.right;
  255. this.try_ = rc.top;
  256. this.brx = rc.right;
  257. this.bry = rc.bottom;
  258. this.blx = rc.left;
  259. this.bly = rc.bottom;
  260. };
  261. Quad.prototype.set_from_rotated_rect = function (rc, a)
  262. {
  263. if (a === 0)
  264. {
  265. this.set_from_rect(rc);
  266. }
  267. else
  268. {
  269. var sin_a = Math.sin(a);
  270. var cos_a = Math.cos(a);
  271. var left_sin_a = rc.left * sin_a;
  272. var top_sin_a = rc.top * sin_a;
  273. var right_sin_a = rc.right * sin_a;
  274. var bottom_sin_a = rc.bottom * sin_a;
  275. var left_cos_a = rc.left * cos_a;
  276. var top_cos_a = rc.top * cos_a;
  277. var right_cos_a = rc.right * cos_a;
  278. var bottom_cos_a = rc.bottom * cos_a;
  279. this.tlx = left_cos_a - top_sin_a;
  280. this.tly = top_cos_a + left_sin_a;
  281. this.trx = right_cos_a - top_sin_a;
  282. this.try_ = top_cos_a + right_sin_a;
  283. this.brx = right_cos_a - bottom_sin_a;
  284. this.bry = bottom_cos_a + right_sin_a;
  285. this.blx = left_cos_a - bottom_sin_a;
  286. this.bly = bottom_cos_a + left_sin_a;
  287. }
  288. };
  289. Quad.prototype.offset = function (px, py)
  290. {
  291. this.tlx += px;
  292. this.tly += py;
  293. this.trx += px;
  294. this.try_ += py;
  295. this.brx += px;
  296. this.bry += py;
  297. this.blx += px;
  298. this.bly += py;
  299. return this;
  300. };
  301. var minresult = 0;
  302. var maxresult = 0;
  303. function minmax4(a, b, c, d)
  304. {
  305. if (a < b)
  306. {
  307. if (c < d)
  308. {
  309. if (a < c)
  310. minresult = a;
  311. else
  312. minresult = c;
  313. if (b > d)
  314. maxresult = b;
  315. else
  316. maxresult = d;
  317. }
  318. else
  319. {
  320. if (a < d)
  321. minresult = a;
  322. else
  323. minresult = d;
  324. if (b > c)
  325. maxresult = b;
  326. else
  327. maxresult = c;
  328. }
  329. }
  330. else
  331. {
  332. if (c < d)
  333. {
  334. if (b < c)
  335. minresult = b;
  336. else
  337. minresult = c;
  338. if (a > d)
  339. maxresult = a;
  340. else
  341. maxresult = d;
  342. }
  343. else
  344. {
  345. if (b < d)
  346. minresult = b;
  347. else
  348. minresult = d;
  349. if (a > c)
  350. maxresult = a;
  351. else
  352. maxresult = c;
  353. }
  354. }
  355. };
  356. Quad.prototype.bounding_box = function (rc)
  357. {
  358. minmax4(this.tlx, this.trx, this.brx, this.blx);
  359. rc.left = minresult;
  360. rc.right = maxresult;
  361. minmax4(this.tly, this.try_, this.bry, this.bly);
  362. rc.top = minresult;
  363. rc.bottom = maxresult;
  364. };
  365. Quad.prototype.contains_pt = function (x, y)
  366. {
  367. var tlx = this.tlx;
  368. var tly = this.tly;
  369. var v0x = this.trx - tlx;
  370. var v0y = this.try_ - tly;
  371. var v1x = this.brx - tlx;
  372. var v1y = this.bry - tly;
  373. var v2x = x - tlx;
  374. var v2y = y - tly;
  375. var dot00 = v0x * v0x + v0y * v0y
  376. var dot01 = v0x * v1x + v0y * v1y
  377. var dot02 = v0x * v2x + v0y * v2y
  378. var dot11 = v1x * v1x + v1y * v1y
  379. var dot12 = v1x * v2x + v1y * v2y
  380. var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
  381. var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  382. var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  383. if ((u >= 0.0) && (v > 0.0) && (u + v < 1))
  384. return true;
  385. v0x = this.blx - tlx;
  386. v0y = this.bly - tly;
  387. var dot00 = v0x * v0x + v0y * v0y
  388. var dot01 = v0x * v1x + v0y * v1y
  389. var dot02 = v0x * v2x + v0y * v2y
  390. invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
  391. u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  392. v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  393. return (u >= 0.0) && (v > 0.0) && (u + v < 1);
  394. };
  395. Quad.prototype.at = function (i, xory)
  396. {
  397. if (xory)
  398. {
  399. switch (i)
  400. {
  401. case 0: return this.tlx;
  402. case 1: return this.trx;
  403. case 2: return this.brx;
  404. case 3: return this.blx;
  405. case 4: return this.tlx;
  406. default: return this.tlx;
  407. }
  408. }
  409. else
  410. {
  411. switch (i)
  412. {
  413. case 0: return this.tly;
  414. case 1: return this.try_;
  415. case 2: return this.bry;
  416. case 3: return this.bly;
  417. case 4: return this.tly;
  418. default: return this.tly;
  419. }
  420. }
  421. };
  422. Quad.prototype.midX = function ()
  423. {
  424. return (this.tlx + this.trx + this.brx + this.blx) / 4;
  425. };
  426. Quad.prototype.midY = function ()
  427. {
  428. return (this.tly + this.try_ + this.bry + this.bly) / 4;
  429. };
  430. Quad.prototype.intersects_segment = function (x1, y1, x2, y2)
  431. {
  432. if (this.contains_pt(x1, y1) || this.contains_pt(x2, y2))
  433. return true;
  434. var a1x, a1y, a2x, a2y;
  435. var i;
  436. for (i = 0; i < 4; i++)
  437. {
  438. a1x = this.at(i, true);
  439. a1y = this.at(i, false);
  440. a2x = this.at(i + 1, true);
  441. a2y = this.at(i + 1, false);
  442. if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
  443. return true;
  444. }
  445. return false;
  446. };
  447. Quad.prototype.intersects_quad = function (rhs)
  448. {
  449. var midx = rhs.midX();
  450. var midy = rhs.midY();
  451. if (this.contains_pt(midx, midy))
  452. return true;
  453. midx = this.midX();
  454. midy = this.midY();
  455. if (rhs.contains_pt(midx, midy))
  456. return true;
  457. var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
  458. var i, j;
  459. for (i = 0; i < 4; i++)
  460. {
  461. for (j = 0; j < 4; j++)
  462. {
  463. a1x = this.at(i, true);
  464. a1y = this.at(i, false);
  465. a2x = this.at(i + 1, true);
  466. a2y = this.at(i + 1, false);
  467. b1x = rhs.at(j, true);
  468. b1y = rhs.at(j, false);
  469. b2x = rhs.at(j + 1, true);
  470. b2y = rhs.at(j + 1, false);
  471. if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
  472. return true;
  473. }
  474. }
  475. return false;
  476. };
  477. cr.quad = Quad;
  478. cr.RGB = function (red, green, blue)
  479. {
  480. return Math.max(Math.min(red, 255), 0)
  481. | (Math.max(Math.min(green, 255), 0) << 8)
  482. | (Math.max(Math.min(blue, 255), 0) << 16);
  483. };
  484. cr.GetRValue = function (rgb)
  485. {
  486. return rgb & 0xFF;
  487. };
  488. cr.GetGValue = function (rgb)
  489. {
  490. return (rgb & 0xFF00) >> 8;
  491. };
  492. cr.GetBValue = function (rgb)
  493. {
  494. return (rgb & 0xFF0000) >> 16;
  495. };
  496. cr.shallowCopy = function (a, b, allowOverwrite)
  497. {
  498. var attr;
  499. for (attr in b)
  500. {
  501. if (b.hasOwnProperty(attr))
  502. {
  503. ;
  504. a[attr] = b[attr];
  505. }
  506. }
  507. return a;
  508. };
  509. cr.arrayRemove = function (arr, index)
  510. {
  511. var i, len;
  512. index = cr.floor(index);
  513. if (index < 0 || index >= arr.length)
  514. return; // index out of bounds
  515. for (i = index, len = arr.length - 1; i < len; i++)
  516. arr[i] = arr[i + 1];
  517. cr.truncateArray(arr, len);
  518. };
  519. cr.truncateArray = function (arr, index)
  520. {
  521. arr.length = index;
  522. };
  523. cr.clearArray = function (arr)
  524. {
  525. cr.truncateArray(arr, 0);
  526. };
  527. cr.shallowAssignArray = function (dest, src)
  528. {
  529. cr.clearArray(dest);
  530. var i, len;
  531. for (i = 0, len = src.length; i < len; ++i)
  532. dest[i] = src[i];
  533. };
  534. cr.appendArray = function (a, b)
  535. {
  536. a.push.apply(a, b);
  537. };
  538. cr.fastIndexOf = function (arr, item)
  539. {
  540. var i, len;
  541. for (i = 0, len = arr.length; i < len; ++i)
  542. {
  543. if (arr[i] === item)
  544. return i;
  545. }
  546. return -1;
  547. };
  548. cr.arrayFindRemove = function (arr, item)
  549. {
  550. var index = cr.fastIndexOf(arr, item);
  551. if (index !== -1)
  552. cr.arrayRemove(arr, index);
  553. };
  554. cr.clamp = function(x, a, b)
  555. {
  556. if (x < a)
  557. return a;
  558. else if (x > b)
  559. return b;
  560. else
  561. return x;
  562. };
  563. cr.to_radians = function(x)
  564. {
  565. return x / (180.0 / cr.PI);
  566. };
  567. cr.to_degrees = function(x)
  568. {
  569. return x * (180.0 / cr.PI);
  570. };
  571. cr.clamp_angle_degrees = function (a)
  572. {
  573. a %= 360; // now in (-360, 360) range
  574. if (a < 0)
  575. a += 360; // now in [0, 360) range
  576. return a;
  577. };
  578. cr.clamp_angle = function (a)
  579. {
  580. a %= 2 * cr.PI; // now in (-2pi, 2pi) range
  581. if (a < 0)
  582. a += 2 * cr.PI; // now in [0, 2pi) range
  583. return a;
  584. };
  585. cr.to_clamped_degrees = function (x)
  586. {
  587. return cr.clamp_angle_degrees(cr.to_degrees(x));
  588. };
  589. cr.to_clamped_radians = function (x)
  590. {
  591. return cr.clamp_angle(cr.to_radians(x));
  592. };
  593. cr.angleTo = function(x1, y1, x2, y2)
  594. {
  595. var dx = x2 - x1;
  596. var dy = y2 - y1;
  597. return Math.atan2(dy, dx);
  598. };
  599. cr.angleDiff = function (a1, a2)
  600. {
  601. if (a1 === a2)
  602. return 0;
  603. var s1 = Math.sin(a1);
  604. var c1 = Math.cos(a1);
  605. var s2 = Math.sin(a2);
  606. var c2 = Math.cos(a2);
  607. var n = s1 * s2 + c1 * c2;
  608. if (n >= 1)
  609. return 0;
  610. if (n <= -1)
  611. return cr.PI;
  612. return Math.acos(n);
  613. };
  614. cr.angleRotate = function (start, end, step)
  615. {
  616. var ss = Math.sin(start);
  617. var cs = Math.cos(start);
  618. var se = Math.sin(end);
  619. var ce = Math.cos(end);
  620. if (Math.acos(ss * se + cs * ce) > step)
  621. {
  622. if (cs * se - ss * ce > 0)
  623. return cr.clamp_angle(start + step);
  624. else
  625. return cr.clamp_angle(start - step);
  626. }
  627. else
  628. return cr.clamp_angle(end);
  629. };
  630. cr.angleClockwise = function (a1, a2)
  631. {
  632. var s1 = Math.sin(a1);
  633. var c1 = Math.cos(a1);
  634. var s2 = Math.sin(a2);
  635. var c2 = Math.cos(a2);
  636. return c1 * s2 - s1 * c2 <= 0;
  637. };
  638. cr.rotatePtAround = function (px, py, a, ox, oy, getx)
  639. {
  640. if (a === 0)
  641. return getx ? px : py;
  642. var sin_a = Math.sin(a);
  643. var cos_a = Math.cos(a);
  644. px -= ox;
  645. py -= oy;
  646. var left_sin_a = px * sin_a;
  647. var top_sin_a = py * sin_a;
  648. var left_cos_a = px * cos_a;
  649. var top_cos_a = py * cos_a;
  650. px = left_cos_a - top_sin_a;
  651. py = top_cos_a + left_sin_a;
  652. px += ox;
  653. py += oy;
  654. return getx ? px : py;
  655. }
  656. cr.distanceTo = function(x1, y1, x2, y2)
  657. {
  658. var dx = x2 - x1;
  659. var dy = y2 - y1;
  660. return Math.sqrt(dx*dx + dy*dy);
  661. };
  662. cr.xor = function (x, y)
  663. {
  664. return !x !== !y;
  665. };
  666. cr.lerp = function (a, b, x)
  667. {
  668. return a + (b - a) * x;
  669. };
  670. cr.unlerp = function (a, b, c)
  671. {
  672. if (a === b)
  673. return 0; // avoid divide by 0
  674. return (c - a) / (b - a);
  675. };
  676. cr.anglelerp = function (a, b, x)
  677. {
  678. var diff = cr.angleDiff(a, b);
  679. if (cr.angleClockwise(b, a))
  680. {
  681. return a + diff * x;
  682. }
  683. else
  684. {
  685. return a - diff * x;
  686. }
  687. };
  688. cr.qarp = function (a, b, c, x)
  689. {
  690. return cr.lerp(cr.lerp(a, b, x), cr.lerp(b, c, x), x);
  691. };
  692. cr.cubic = function (a, b, c, d, x)
  693. {
  694. return cr.lerp(cr.qarp(a, b, c, x), cr.qarp(b, c, d, x), x);
  695. };
  696. cr.cosp = function (a, b, x)
  697. {
  698. return (a + b + (a - b) * Math.cos(x * Math.PI)) / 2;
  699. };
  700. cr.hasAnyOwnProperty = function (o)
  701. {
  702. var p;
  703. for (p in o)
  704. {
  705. if (o.hasOwnProperty(p))
  706. return true;
  707. }
  708. return false;
  709. };
  710. cr.wipe = function (obj)
  711. {
  712. var p;
  713. for (p in obj)
  714. {
  715. if (obj.hasOwnProperty(p))
  716. delete obj[p];
  717. }
  718. };
  719. var startup_time = +(new Date());
  720. cr.performance_now = function()
  721. {
  722. if (typeof window["performance"] !== "undefined")
  723. {
  724. var winperf = window["performance"];
  725. if (typeof winperf.now !== "undefined")
  726. return winperf.now();
  727. else if (typeof winperf["webkitNow"] !== "undefined")
  728. return winperf["webkitNow"]();
  729. else if (typeof winperf["mozNow"] !== "undefined")
  730. return winperf["mozNow"]();
  731. else if (typeof winperf["msNow"] !== "undefined")
  732. return winperf["msNow"]();
  733. }
  734. return Date.now() - startup_time;
  735. };
  736. var isChrome = false;
  737. var isSafari = false;
  738. var isiOS = false;
  739. var isEjecta = false;
  740. if (typeof window !== "undefined") // not c2 editor
  741. {
  742. isChrome = /chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent);
  743. isSafari = !isChrome && /safari/i.test(navigator.userAgent);
  744. isiOS = /(iphone|ipod|ipad)/i.test(navigator.userAgent);
  745. isEjecta = window["c2ejecta"];
  746. }
  747. var supports_set = ((!isSafari && !isEjecta && !isiOS) && (typeof Set !== "undefined" && typeof Set.prototype["forEach"] !== "undefined"));
  748. function ObjectSet_()
  749. {
  750. this.s = null;
  751. this.items = null; // lazy allocated (hopefully results in better GC performance)
  752. this.item_count = 0;
  753. if (supports_set)
  754. {
  755. this.s = new Set();
  756. }
  757. this.values_cache = [];
  758. this.cache_valid = true;
  759. cr.seal(this);
  760. };
  761. ObjectSet_.prototype.contains = function (x)
  762. {
  763. if (this.isEmpty())
  764. return false;
  765. if (supports_set)
  766. return this.s["has"](x);
  767. else
  768. return (this.items && this.items.hasOwnProperty(x));
  769. };
  770. ObjectSet_.prototype.add = function (x)
  771. {
  772. if (supports_set)
  773. {
  774. if (!this.s["has"](x))
  775. {
  776. this.s["add"](x);
  777. this.cache_valid = false;
  778. }
  779. }
  780. else
  781. {
  782. var str = x.toString();
  783. var items = this.items;
  784. if (!items)
  785. {
  786. this.items = {};
  787. this.items[str] = x;
  788. this.item_count = 1;
  789. this.cache_valid = false;
  790. }
  791. else if (!items.hasOwnProperty(str))
  792. {
  793. items[str] = x;
  794. this.item_count++;
  795. this.cache_valid = false;
  796. }
  797. }
  798. };
  799. ObjectSet_.prototype.remove = function (x)
  800. {
  801. if (this.isEmpty())
  802. return;
  803. if (supports_set)
  804. {
  805. if (this.s["has"](x))
  806. {
  807. this.s["delete"](x);
  808. this.cache_valid = false;
  809. }
  810. }
  811. else if (this.items)
  812. {
  813. var str = x.toString();
  814. var items = this.items;
  815. if (items.hasOwnProperty(str))
  816. {
  817. delete items[str];
  818. this.item_count--;
  819. this.cache_valid = false;
  820. }
  821. }
  822. };
  823. ObjectSet_.prototype.clear = function (/*wipe_*/)
  824. {
  825. if (this.isEmpty())
  826. return;
  827. if (supports_set)
  828. {
  829. this.s["clear"](); // best!
  830. }
  831. else
  832. {
  833. this.items = null; // creates garbage; will lazy allocate on next add()
  834. this.item_count = 0;
  835. }
  836. cr.clearArray(this.values_cache);
  837. this.cache_valid = true;
  838. };
  839. ObjectSet_.prototype.isEmpty = function ()
  840. {
  841. return this.count() === 0;
  842. };
  843. ObjectSet_.prototype.count = function ()
  844. {
  845. if (supports_set)
  846. return this.s["size"];
  847. else
  848. return this.item_count;
  849. };
  850. var current_arr = null;
  851. var current_index = 0;
  852. function set_append_to_arr(x)
  853. {
  854. current_arr[current_index++] = x;
  855. };
  856. ObjectSet_.prototype.update_cache = function ()
  857. {
  858. if (this.cache_valid)
  859. return;
  860. if (supports_set)
  861. {
  862. cr.clearArray(this.values_cache);
  863. current_arr = this.values_cache;
  864. current_index = 0;
  865. this.s["forEach"](set_append_to_arr);
  866. ;
  867. current_arr = null;
  868. current_index = 0;
  869. }
  870. else
  871. {
  872. var values_cache = this.values_cache;
  873. cr.clearArray(values_cache);
  874. var p, n = 0, items = this.items;
  875. if (items)
  876. {
  877. for (p in items)
  878. {
  879. if (items.hasOwnProperty(p))
  880. values_cache[n++] = items[p];
  881. }
  882. }
  883. ;
  884. }
  885. this.cache_valid = true;
  886. };
  887. ObjectSet_.prototype.valuesRef = function ()
  888. {
  889. this.update_cache();
  890. return this.values_cache;
  891. };
  892. cr.ObjectSet = ObjectSet_;
  893. var tmpSet = new cr.ObjectSet();
  894. cr.removeArrayDuplicates = function (arr)
  895. {
  896. var i, len;
  897. for (i = 0, len = arr.length; i < len; ++i)
  898. {
  899. tmpSet.add(arr[i]);
  900. }
  901. cr.shallowAssignArray(arr, tmpSet.valuesRef());
  902. tmpSet.clear();
  903. };
  904. cr.arrayRemoveAllFromObjectSet = function (arr, remset)
  905. {
  906. if (supports_set)
  907. cr.arrayRemoveAll_set(arr, remset.s);
  908. else
  909. cr.arrayRemoveAll_arr(arr, remset.valuesRef());
  910. };
  911. cr.arrayRemoveAll_set = function (arr, s)
  912. {
  913. var i, j, len, item;
  914. for (i = 0, j = 0, len = arr.length; i < len; ++i)
  915. {
  916. item = arr[i];
  917. if (!s["has"](item)) // not an item to remove
  918. arr[j++] = item; // keep it
  919. }
  920. cr.truncateArray(arr, j);
  921. };
  922. cr.arrayRemoveAll_arr = function (arr, rem)
  923. {
  924. var i, j, len, item;
  925. for (i = 0, j = 0, len = arr.length; i < len; ++i)
  926. {
  927. item = arr[i];
  928. if (cr.fastIndexOf(rem, item) === -1) // not an item to remove
  929. arr[j++] = item; // keep it
  930. }
  931. cr.truncateArray(arr, j);
  932. };
  933. function KahanAdder_()
  934. {
  935. this.c = 0;
  936. this.y = 0;
  937. this.t = 0;
  938. this.sum = 0;
  939. cr.seal(this);
  940. };
  941. KahanAdder_.prototype.add = function (v)
  942. {
  943. this.y = v - this.c;
  944. this.t = this.sum + this.y;
  945. this.c = (this.t - this.sum) - this.y;
  946. this.sum = this.t;
  947. };
  948. KahanAdder_.prototype.reset = function ()
  949. {
  950. this.c = 0;
  951. this.y = 0;
  952. this.t = 0;
  953. this.sum = 0;
  954. };
  955. cr.KahanAdder = KahanAdder_;
  956. cr.regexp_escape = function(text)
  957. {
  958. return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
  959. };
  960. function CollisionPoly_(pts_array_)
  961. {
  962. this.pts_cache = [];
  963. this.bboxLeft = 0;
  964. this.bboxTop = 0;
  965. this.bboxRight = 0;
  966. this.bboxBottom = 0;
  967. this.convexpolys = null; // for physics behavior to cache separated polys
  968. this.set_pts(pts_array_);
  969. cr.seal(this);
  970. };
  971. CollisionPoly_.prototype.set_pts = function(pts_array_)
  972. {
  973. this.pts_array = pts_array_;
  974. this.pts_count = pts_array_.length / 2; // x, y, x, y... in array
  975. this.pts_cache.length = pts_array_.length;
  976. this.cache_width = -1;
  977. this.cache_height = -1;
  978. this.cache_angle = 0;
  979. };
  980. CollisionPoly_.prototype.is_empty = function()
  981. {
  982. return !this.pts_array.length;
  983. };
  984. CollisionPoly_.prototype.update_bbox = function ()
  985. {
  986. var myptscache = this.pts_cache;
  987. var bboxLeft_ = myptscache[0];
  988. var bboxRight_ = bboxLeft_;
  989. var bboxTop_ = myptscache[1];
  990. var bboxBottom_ = bboxTop_;
  991. var x, y, i = 1, i2, len = this.pts_count;
  992. for ( ; i < len; ++i)
  993. {
  994. i2 = i*2;
  995. x = myptscache[i2];
  996. y = myptscache[i2+1];
  997. if (x < bboxLeft_)
  998. bboxLeft_ = x;
  999. if (x > bboxRight_)
  1000. bboxRight_ = x;
  1001. if (y < bboxTop_)
  1002. bboxTop_ = y;
  1003. if (y > bboxBottom_)
  1004. bboxBottom_ = y;
  1005. }
  1006. this.bboxLeft = bboxLeft_;
  1007. this.bboxRight = bboxRight_;
  1008. this.bboxTop = bboxTop_;
  1009. this.bboxBottom = bboxBottom_;
  1010. };
  1011. CollisionPoly_.prototype.set_from_rect = function(rc, offx, offy)
  1012. {
  1013. this.pts_cache.length = 8;
  1014. this.pts_count = 4;
  1015. var myptscache = this.pts_cache;
  1016. myptscache[0] = rc.left - offx;
  1017. myptscache[1] = rc.top - offy;
  1018. myptscache[2] = rc.right - offx;
  1019. myptscache[3] = rc.top - offy;
  1020. myptscache[4] = rc.right - offx;
  1021. myptscache[5] = rc.bottom - offy;
  1022. myptscache[6] = rc.left - offx;
  1023. myptscache[7] = rc.bottom - offy;
  1024. this.cache_width = rc.right - rc.left;
  1025. this.cache_height = rc.bottom - rc.top;
  1026. this.update_bbox();
  1027. };
  1028. CollisionPoly_.prototype.set_from_quad = function(q, offx, offy, w, h)
  1029. {
  1030. this.pts_cache.length = 8;
  1031. this.pts_count = 4;
  1032. var myptscache = this.pts_cache;
  1033. myptscache[0] = q.tlx - offx;
  1034. myptscache[1] = q.tly - offy;
  1035. myptscache[2] = q.trx - offx;
  1036. myptscache[3] = q.try_ - offy;
  1037. myptscache[4] = q.brx - offx;
  1038. myptscache[5] = q.bry - offy;
  1039. myptscache[6] = q.blx - offx;
  1040. myptscache[7] = q.bly - offy;
  1041. this.cache_width = w;
  1042. this.cache_height = h;
  1043. this.update_bbox();
  1044. };
  1045. CollisionPoly_.prototype.set_from_poly = function (r)
  1046. {
  1047. this.pts_count = r.pts_count;
  1048. cr.shallowAssignArray(this.pts_cache, r.pts_cache);
  1049. this.bboxLeft = r.bboxLeft;
  1050. this.bboxTop - r.bboxTop;
  1051. this.bboxRight = r.bboxRight;
  1052. this.bboxBottom = r.bboxBottom;
  1053. };
  1054. CollisionPoly_.prototype.cache_poly = function(w, h, a)
  1055. {
  1056. if (this.cache_width === w && this.cache_height === h && this.cache_angle === a)
  1057. return; // cache up-to-date
  1058. this.cache_width = w;
  1059. this.cache_height = h;
  1060. this.cache_angle = a;
  1061. var i, i2, i21, len, x, y;
  1062. var sina = 0;
  1063. var cosa = 1;
  1064. var myptsarray = this.pts_array;
  1065. var myptscache = this.pts_cache;
  1066. if (a !== 0)
  1067. {
  1068. sina = Math.sin(a);
  1069. cosa = Math.cos(a);
  1070. }
  1071. for (i = 0, len = this.pts_count; i < len; i++)
  1072. {
  1073. i2 = i*2;
  1074. i21 = i2+1;
  1075. x = myptsarray[i2] * w;
  1076. y = myptsarray[i21] * h;
  1077. myptscache[i2] = (x * cosa) - (y * sina);
  1078. myptscache[i21] = (y * cosa) + (x * sina);
  1079. }
  1080. this.update_bbox();
  1081. };
  1082. CollisionPoly_.prototype.contains_pt = function (a2x, a2y)
  1083. {
  1084. var myptscache = this.pts_cache;
  1085. if (a2x === myptscache[0] && a2y === myptscache[1])
  1086. return true;
  1087. var i, i2, imod, len = this.pts_count;
  1088. var a1x = this.bboxLeft - 110;
  1089. var a1y = this.bboxTop - 101;
  1090. var a3x = this.bboxRight + 131
  1091. var a3y = this.bboxBottom + 120;
  1092. var b1x, b1y, b2x, b2y;
  1093. var count1 = 0, count2 = 0;
  1094. for (i = 0; i < len; i++)
  1095. {
  1096. i2 = i*2;
  1097. imod = ((i+1)%len)*2;
  1098. b1x = myptscache[i2];
  1099. b1y = myptscache[i2+1];
  1100. b2x = myptscache[imod];
  1101. b2y = myptscache[imod+1];
  1102. if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
  1103. count1++;
  1104. if (cr.segments_intersect(a3x, a3y, a2x, a2y, b1x, b1y, b2x, b2y))
  1105. count2++;
  1106. }
  1107. return (count1 % 2 === 1) || (count2 % 2 === 1);
  1108. };
  1109. CollisionPoly_.prototype.intersects_poly = function (rhs, offx, offy)
  1110. {
  1111. var rhspts = rhs.pts_cache;
  1112. var mypts = this.pts_cache;
  1113. if (this.contains_pt(rhspts[0] + offx, rhspts[1] + offy))
  1114. return true;
  1115. if (rhs.contains_pt(mypts[0] - offx, mypts[1] - offy))
  1116. return true;
  1117. var i, i2, imod, leni, j, j2, jmod, lenj;
  1118. var a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
  1119. for (i = 0, leni = this.pts_count; i < leni; i++)
  1120. {
  1121. i2 = i*2;
  1122. imod = ((i+1)%leni)*2;
  1123. a1x = mypts[i2];
  1124. a1y = mypts[i2+1];
  1125. a2x = mypts[imod];
  1126. a2y = mypts[imod+1];
  1127. for (j = 0, lenj = rhs.pts_count; j < lenj; j++)
  1128. {
  1129. j2 = j*2;
  1130. jmod = ((j+1)%lenj)*2;
  1131. b1x = rhspts[j2] + offx;
  1132. b1y = rhspts[j2+1] + offy;
  1133. b2x = rhspts[jmod] + offx;
  1134. b2y = rhspts[jmod+1] + offy;
  1135. if (cr.segments_intersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y))
  1136. return true;
  1137. }
  1138. }
  1139. return false;
  1140. };
  1141. CollisionPoly_.prototype.intersects_segment = function (offx, offy, x1, y1, x2, y2)
  1142. {
  1143. var mypts = this.pts_cache;
  1144. if (this.contains_pt(x1 - offx, y1 - offy))
  1145. return true;
  1146. var i, leni, i2, imod;
  1147. var a1x, a1y, a2x, a2y;
  1148. for (i = 0, leni = this.pts_count; i < leni; i++)
  1149. {
  1150. i2 = i*2;
  1151. imod = ((i+1)%leni)*2;
  1152. a1x = mypts[i2] + offx;
  1153. a1y = mypts[i2+1] + offy;
  1154. a2x = mypts[imod] + offx;
  1155. a2y = mypts[imod+1] + offy;
  1156. if (cr.segments_intersect(x1, y1, x2, y2, a1x, a1y, a2x, a2y))
  1157. return true;
  1158. }
  1159. return false;
  1160. };
  1161. CollisionPoly_.prototype.mirror = function (px)
  1162. {
  1163. var i, leni, i2;
  1164. for (i = 0, leni = this.pts_count; i < leni; ++i)
  1165. {
  1166. i2 = i*2;
  1167. this.pts_cache[i2] = px * 2 - this.pts_cache[i2];
  1168. }
  1169. };
  1170. CollisionPoly_.prototype.flip = function (py)
  1171. {
  1172. var i, leni, i21;
  1173. for (i = 0, leni = this.pts_count; i < leni; ++i)
  1174. {
  1175. i21 = i*2+1;
  1176. this.pts_cache[i21] = py * 2 - this.pts_cache[i21];
  1177. }
  1178. };
  1179. CollisionPoly_.prototype.diag = function ()
  1180. {
  1181. var i, leni, i2, i21, temp;
  1182. for (i = 0, leni = this.pts_count; i < leni; ++i)
  1183. {
  1184. i2 = i*2;
  1185. i21 = i2+1;
  1186. temp = this.pts_cache[i2];
  1187. this.pts_cache[i2] = this.pts_cache[i21];
  1188. this.pts_cache[i21] = temp;
  1189. }
  1190. };
  1191. cr.CollisionPoly = CollisionPoly_;
  1192. function SparseGrid_(cellwidth_, cellheight_)
  1193. {
  1194. this.cellwidth = cellwidth_;
  1195. this.cellheight = cellheight_;
  1196. this.cells = {};
  1197. };
  1198. SparseGrid_.prototype.totalCellCount = 0;
  1199. SparseGrid_.prototype.getCell = function (x_, y_, create_if_missing)
  1200. {
  1201. var ret;
  1202. var col = this.cells[x_];
  1203. if (!col)
  1204. {
  1205. if (create_if_missing)
  1206. {
  1207. ret = allocGridCell(this, x_, y_);
  1208. this.cells[x_] = {};
  1209. this.cells[x_][y_] = ret;
  1210. return ret;
  1211. }
  1212. else
  1213. return null;
  1214. }
  1215. ret = col[y_];
  1216. if (ret)
  1217. return ret;
  1218. else if (create_if_missing)
  1219. {
  1220. ret = allocGridCell(this, x_, y_);
  1221. this.cells[x_][y_] = ret;
  1222. return ret;
  1223. }
  1224. else
  1225. return null;
  1226. };
  1227. SparseGrid_.prototype.XToCell = function (x_)
  1228. {
  1229. return cr.floor(x_ / this.cellwidth);
  1230. };
  1231. SparseGrid_.prototype.YToCell = function (y_)
  1232. {
  1233. return cr.floor(y_ / this.cellheight);
  1234. };
  1235. SparseGrid_.prototype.update = function (inst, oldrange, newrange)
  1236. {
  1237. var x, lenx, y, leny, cell;
  1238. if (oldrange)
  1239. {
  1240. for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
  1241. {
  1242. for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
  1243. {
  1244. if (newrange && newrange.contains_pt(x, y))
  1245. continue; // is still in this cell
  1246. cell = this.getCell(x, y, false); // don't create if missing
  1247. if (!cell)
  1248. continue; // cell does not exist yet
  1249. cell.remove(inst);
  1250. if (cell.isEmpty())
  1251. {
  1252. freeGridCell(cell);
  1253. this.cells[x][y] = null;
  1254. }
  1255. }
  1256. }
  1257. }
  1258. if (newrange)
  1259. {
  1260. for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
  1261. {
  1262. for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
  1263. {
  1264. if (oldrange && oldrange.contains_pt(x, y))
  1265. continue; // is still in this cell
  1266. this.getCell(x, y, true).insert(inst);
  1267. }
  1268. }
  1269. }
  1270. };
  1271. SparseGrid_.prototype.queryRange = function (rc, result)
  1272. {
  1273. var x, lenx, ystart, y, leny, cell;
  1274. x = this.XToCell(rc.left);
  1275. ystart = this.YToCell(rc.top);
  1276. lenx = this.XToCell(rc.right);
  1277. leny = this.YToCell(rc.bottom);
  1278. for ( ; x <= lenx; ++x)
  1279. {
  1280. for (y = ystart; y <= leny; ++y)
  1281. {
  1282. cell = this.getCell(x, y, false);
  1283. if (!cell)
  1284. continue;
  1285. cell.dump(result);
  1286. }
  1287. }
  1288. };
  1289. cr.SparseGrid = SparseGrid_;
  1290. function RenderGrid_(cellwidth_, cellheight_)
  1291. {
  1292. this.cellwidth = cellwidth_;
  1293. this.cellheight = cellheight_;
  1294. this.cells = {};
  1295. };
  1296. RenderGrid_.prototype.totalCellCount = 0;
  1297. RenderGrid_.prototype.getCell = function (x_, y_, create_if_missing)
  1298. {
  1299. var ret;
  1300. var col = this.cells[x_];
  1301. if (!col)
  1302. {
  1303. if (create_if_missing)
  1304. {
  1305. ret = allocRenderCell(this, x_, y_);
  1306. this.cells[x_] = {};
  1307. this.cells[x_][y_] = ret;
  1308. return ret;
  1309. }
  1310. else
  1311. return null;
  1312. }
  1313. ret = col[y_];
  1314. if (ret)
  1315. return ret;
  1316. else if (create_if_missing)
  1317. {
  1318. ret = allocRenderCell(this, x_, y_);
  1319. this.cells[x_][y_] = ret;
  1320. return ret;
  1321. }
  1322. else
  1323. return null;
  1324. };
  1325. RenderGrid_.prototype.XToCell = function (x_)
  1326. {
  1327. return cr.floor(x_ / this.cellwidth);
  1328. };
  1329. RenderGrid_.prototype.YToCell = function (y_)
  1330. {
  1331. return cr.floor(y_ / this.cellheight);
  1332. };
  1333. RenderGrid_.prototype.update = function (inst, oldrange, newrange)
  1334. {
  1335. var x, lenx, y, leny, cell;
  1336. if (oldrange)
  1337. {
  1338. for (x = oldrange.left, lenx = oldrange.right; x <= lenx; ++x)
  1339. {
  1340. for (y = oldrange.top, leny = oldrange.bottom; y <= leny; ++y)
  1341. {
  1342. if (newrange && newrange.contains_pt(x, y))
  1343. continue; // is still in this cell
  1344. cell = this.getCell(x, y, false); // don't create if missing
  1345. if (!cell)
  1346. continue; // cell does not exist yet
  1347. cell.remove(inst);
  1348. if (cell.isEmpty())
  1349. {
  1350. freeRenderCell(cell);
  1351. this.cells[x][y] = null;
  1352. }
  1353. }
  1354. }
  1355. }
  1356. if (newrange)
  1357. {
  1358. for (x = newrange.left, lenx = newrange.right; x <= lenx; ++x)
  1359. {
  1360. for (y = newrange.top, leny = newrange.bottom; y <= leny; ++y)
  1361. {
  1362. if (oldrange && oldrange.contains_pt(x, y))
  1363. continue; // is still in this cell
  1364. this.getCell(x, y, true).insert(inst);
  1365. }
  1366. }
  1367. }
  1368. };
  1369. RenderGrid_.prototype.queryRange = function (left, top, right, bottom, result)
  1370. {
  1371. var x, lenx, ystart, y, leny, cell;
  1372. x = this.XToCell(left);
  1373. ystart = this.YToCell(top);
  1374. lenx = this.XToCell(right);
  1375. leny = this.YToCell(bottom);
  1376. for ( ; x <= lenx; ++x)
  1377. {
  1378. for (y = ystart; y <= leny; ++y)
  1379. {
  1380. cell = this.getCell(x, y, false);
  1381. if (!cell)
  1382. continue;
  1383. cell.dump(result);
  1384. }
  1385. }
  1386. };
  1387. RenderGrid_.prototype.markRangeChanged = function (rc)
  1388. {
  1389. var x, lenx, ystart, y, leny, cell;
  1390. x = rc.left;
  1391. ystart = rc.top;
  1392. lenx = rc.right;
  1393. leny = rc.bottom;
  1394. for ( ; x <= lenx; ++x)
  1395. {
  1396. for (y = ystart; y <= leny; ++y)
  1397. {
  1398. cell = this.getCell(x, y, false);
  1399. if (!cell)
  1400. continue;
  1401. cell.is_sorted = false;
  1402. }
  1403. }
  1404. };
  1405. cr.RenderGrid = RenderGrid_;
  1406. var gridcellcache = [];
  1407. function allocGridCell(grid_, x_, y_)
  1408. {
  1409. var ret;
  1410. SparseGrid_.prototype.totalCellCount++;
  1411. if (gridcellcache.length)
  1412. {
  1413. ret = gridcellcache.pop();
  1414. ret.grid = grid_;
  1415. ret.x = x_;
  1416. ret.y = y_;
  1417. return ret;
  1418. }
  1419. else
  1420. return new cr.GridCell(grid_, x_, y_);
  1421. };
  1422. function freeGridCell(c)
  1423. {
  1424. SparseGrid_.prototype.totalCellCount--;
  1425. c.objects.clear();
  1426. if (gridcellcache.length < 1000)
  1427. gridcellcache.push(c);
  1428. };
  1429. function GridCell_(grid_, x_, y_)
  1430. {
  1431. this.grid = grid_;
  1432. this.x = x_;
  1433. this.y = y_;
  1434. this.objects = new cr.ObjectSet();
  1435. };
  1436. GridCell_.prototype.isEmpty = function ()
  1437. {
  1438. return this.objects.isEmpty();
  1439. };
  1440. GridCell_.prototype.insert = function (inst)
  1441. {
  1442. this.objects.add(inst);
  1443. };
  1444. GridCell_.prototype.remove = function (inst)
  1445. {
  1446. this.objects.remove(inst);
  1447. };
  1448. GridCell_.prototype.dump = function (result)
  1449. {
  1450. cr.appendArray(result, this.objects.valuesRef());
  1451. };
  1452. cr.GridCell = GridCell_;
  1453. var rendercellcache = [];
  1454. function allocRenderCell(grid_, x_, y_)
  1455. {
  1456. var ret;
  1457. RenderGrid_.prototype.totalCellCount++;
  1458. if (rendercellcache.length)
  1459. {
  1460. ret = rendercellcache.pop();
  1461. ret.grid = grid_;
  1462. ret.x = x_;
  1463. ret.y = y_;
  1464. return ret;
  1465. }
  1466. else
  1467. return new cr.RenderCell(grid_, x_, y_);
  1468. };
  1469. function freeRenderCell(c)
  1470. {
  1471. RenderGrid_.prototype.totalCellCount--;
  1472. c.reset();
  1473. if (rendercellcache.length < 1000)
  1474. rendercellcache.push(c);
  1475. };
  1476. function RenderCell_(grid_, x_, y_)
  1477. {
  1478. this.grid = grid_;
  1479. this.x = x_;
  1480. this.y = y_;
  1481. this.objects = []; // array which needs to be sorted by Z order
  1482. this.is_sorted = true; // whether array is in correct sort order or not
  1483. this.pending_removal = new cr.ObjectSet();
  1484. this.any_pending_removal = false;
  1485. };
  1486. RenderCell_.prototype.isEmpty = function ()
  1487. {
  1488. if (!this.objects.length)
  1489. {
  1490. ;
  1491. ;
  1492. return true;
  1493. }
  1494. if (this.objects.length > this.pending_removal.count())
  1495. return false;
  1496. ;
  1497. this.flush_pending(); // takes fast path and just resets state
  1498. return true;
  1499. };
  1500. RenderCell_.prototype.insert = function (inst)
  1501. {
  1502. if (this.pending_removal.contains(inst))
  1503. {
  1504. this.pending_removal.remove(inst);
  1505. if (this.pending_removal.isEmpty())
  1506. this.any_pending_removal = false;
  1507. return;
  1508. }
  1509. if (this.objects.length)
  1510. {
  1511. var top = this.objects[this.objects.length - 1];
  1512. if (top.get_zindex() > inst.get_zindex())
  1513. this.is_sorted = false; // 'inst' should be somewhere beneath 'top'
  1514. this.objects.push(inst);
  1515. }
  1516. else
  1517. {
  1518. this.objects.push(inst);
  1519. this.is_sorted = true;
  1520. }
  1521. ;
  1522. };
  1523. RenderCell_.prototype.remove = function (inst)
  1524. {
  1525. this.pending_removal.add(inst);
  1526. this.any_pending_removal = true;
  1527. if (this.pending_removal.count() >= 30)
  1528. this.flush_pending();
  1529. };
  1530. RenderCell_.prototype.flush_pending = function ()
  1531. {
  1532. ;
  1533. if (!this.any_pending_removal)
  1534. return; // not changed
  1535. if (this.pending_removal.count() === this.objects.length)
  1536. {
  1537. this.reset();
  1538. return;
  1539. }
  1540. cr.arrayRemoveAllFromObjectSet(this.objects, this.pending_removal);
  1541. this.pending_removal.clear();
  1542. this.any_pending_removal = false;
  1543. };
  1544. function sortByInstanceZIndex(a, b)
  1545. {
  1546. return a.zindex - b.zindex;
  1547. };
  1548. RenderCell_.prototype.ensure_sorted = function ()
  1549. {
  1550. if (this.is_sorted)
  1551. return; // already sorted
  1552. this.objects.sort(sortByInstanceZIndex);
  1553. this.is_sorted = true;
  1554. };
  1555. RenderCell_.prototype.reset = function ()
  1556. {
  1557. cr.clearArray(this.objects);
  1558. this.is_sorted = true;
  1559. this.pending_removal.clear();
  1560. this.any_pending_removal = false;
  1561. };
  1562. RenderCell_.prototype.dump = function (result)
  1563. {
  1564. this.flush_pending();
  1565. this.ensure_sorted();
  1566. if (this.objects.length)
  1567. result.push(this.objects);
  1568. };
  1569. cr.RenderCell = RenderCell_;
  1570. var fxNames = [ "lighter",
  1571. "xor",
  1572. "copy",
  1573. "destination-over",
  1574. "source-in",
  1575. "destination-in",
  1576. "source-out",
  1577. "destination-out",
  1578. "source-atop",
  1579. "destination-atop"];
  1580. cr.effectToCompositeOp = function(effect)
  1581. {
  1582. if (effect <= 0 || effect >= 11)
  1583. return "source-over";
  1584. return fxNames[effect - 1]; // not including "none" so offset by 1
  1585. };
  1586. cr.setGLBlend = function(this_, effect, gl)
  1587. {
  1588. if (!gl)
  1589. return;
  1590. this_.srcBlend = gl.ONE;
  1591. this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
  1592. switch (effect) {
  1593. case 1: // lighter (additive)
  1594. this_.srcBlend = gl.ONE;
  1595. this_.destBlend = gl.ONE;
  1596. break;
  1597. case 2: // xor
  1598. break; // todo
  1599. case 3: // copy
  1600. this_.srcBlend = gl.ONE;
  1601. this_.destBlend = gl.ZERO;
  1602. break;
  1603. case 4: // destination-over
  1604. this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
  1605. this_.destBlend = gl.ONE;
  1606. break;
  1607. case 5: // source-in
  1608. this_.srcBlend = gl.DST_ALPHA;
  1609. this_.destBlend = gl.ZERO;
  1610. break;
  1611. case 6: // destination-in
  1612. this_.srcBlend = gl.ZERO;
  1613. this_.destBlend = gl.SRC_ALPHA;
  1614. break;
  1615. case 7: // source-out
  1616. this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
  1617. this_.destBlend = gl.ZERO;
  1618. break;
  1619. case 8: // destination-out
  1620. this_.srcBlend = gl.ZERO;
  1621. this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
  1622. break;
  1623. case 9: // source-atop
  1624. this_.srcBlend = gl.DST_ALPHA;
  1625. this_.destBlend = gl.ONE_MINUS_SRC_ALPHA;
  1626. break;
  1627. case 10: // destination-atop
  1628. this_.srcBlend = gl.ONE_MINUS_DST_ALPHA;
  1629. this_.destBlend = gl.SRC_ALPHA;
  1630. break;
  1631. }
  1632. };
  1633. cr.round6dp = function (x)
  1634. {
  1635. return Math.round(x * 1000000) / 1000000;
  1636. };
  1637. /*
  1638. var localeCompare_options = {
  1639. "usage": "search",
  1640. "sensitivity": "accent"
  1641. };
  1642. var has_localeCompare = !!"a".localeCompare;
  1643. var localeCompare_works1 = (has_localeCompare && "a".localeCompare("A", undefined, localeCompare_options) === 0);
  1644. var localeCompare_works2 = (has_localeCompare && "a".localeCompare("á", undefined, localeCompare_options) !== 0);
  1645. var supports_localeCompare = (has_localeCompare && localeCompare_works1 && localeCompare_works2);
  1646. */
  1647. cr.equals_nocase = function (a, b)
  1648. {
  1649. if (typeof a !== "string" || typeof b !== "string")
  1650. return false;
  1651. if (a.length !== b.length)
  1652. return false;
  1653. if (a === b)
  1654. return true;
  1655. /*
  1656. if (supports_localeCompare)
  1657. {
  1658. return (a.localeCompare(b, undefined, localeCompare_options) === 0);
  1659. }
  1660. else
  1661. {
  1662. */
  1663. return a.toLowerCase() === b.toLowerCase();
  1664. };
  1665. cr.isCanvasInputEvent = function (e)
  1666. {
  1667. var target = e.target;
  1668. if (!target)
  1669. return true;
  1670. if (target === document || target === window)
  1671. return true;
  1672. if (document && document.body && target === document.body)
  1673. return true;
  1674. if (cr.equals_nocase(target.tagName, "canvas"))
  1675. return true;
  1676. return false;
  1677. };
  1678. }());
  1679. var MatrixArray=typeof Float32Array!=="undefined"?Float32Array:Array,glMatrixArrayType=MatrixArray,vec3={},mat3={},mat4={},quat4={};vec3.create=function(a){var b=new MatrixArray(3);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2]);return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a===c)return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a;c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c};
  1680. vec3.subtract=function(a,b,c){if(!c||a===c)return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a;c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a===c)return a[0]*=b,a[1]*=b,a[2]*=b,a;c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c};
  1681. vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g===1)return b[0]=c,b[1]=d,b[2]=e,b}else return b[0]=0,b[1]=0,b[2]=0,b;g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1],a=a[2],g=b[0],f=b[1],b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1],a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};
  1682. vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1],a=a[2]-b[2],b=Math.sqrt(d*d+e*e+a*a);if(!b)return c[0]=0,c[1]=0,c[2]=0,c;b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};
  1683. mat3.create=function(a){var b=new MatrixArray(9);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8]);return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a};
  1684. mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[15]=1;b[14]=0;b[13]=0;b[12]=0;b[11]=0;b[10]=a[8];b[9]=a[7];b[8]=a[6];b[7]=0;b[6]=a[5];b[5]=a[4];b[4]=a[3];b[3]=0;b[2]=a[2];b[1]=a[1];b[0]=a[0];return b};
  1685. mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};mat4.create=function(a){var b=new MatrixArray(16);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b[9]=a[9],b[10]=a[10],b[11]=a[11],b[12]=a[12],b[13]=a[13],b[14]=a[14],b[15]=a[15]);return b};
  1686. mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};
  1687. mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b};
  1688. mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],n=a[11],o=a[12],m=a[13],p=a[14],a=a[15];return o*k*h*e-j*m*h*e-o*f*l*e+g*m*l*e+j*f*p*e-g*k*p*e-o*k*d*i+j*m*d*i+o*c*l*i-b*m*l*i-j*c*p*i+b*k*p*i+o*f*d*n-g*m*d*n-o*c*h*n+b*m*h*n+g*c*p*n-b*f*p*n-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a};
  1689. mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],n=a[10],o=a[11],m=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*m,y=k*r-n*m,z=k*s-o*m,C=l*r-n*p,D=l*s-o*p,E=n*s-o*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+n*v-o*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-m*w+r*t-s*B)*q;b[7]=(k*w-n*t+o*B)*q;b[8]=(f*D-h*z+j*x)*q;
  1690. b[9]=(-c*D+d*z-g*x)*q;b[10]=(m*v-p*t+s*A)*q;b[11]=(-k*v+l*t-o*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-m*u+p*B-r*A)*q;b[15]=(k*u-l*B+n*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
  1691. mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,n=-k*g+h*i,o=j*g-f*i,m=c*l+d*n+e*o;if(!m)return null;m=1/m;b||(b=mat3.create());b[0]=l*m;b[1]=(-k*d+e*j)*m;b[2]=(h*d-e*f)*m;b[3]=n*m;b[4]=(k*c-e*i)*m;b[5]=(-h*c+e*g)*m;b[6]=o*m;b[7]=(-j*c+d*i)*m;b[8]=(f*c-d*g)*m;return b};
  1692. mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],n=a[9],o=a[10],m=a[11],p=a[12],r=a[13],s=a[14],a=a[15],A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14],b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*n+u*r;c[2]=A*g+B*j+t*o+u*s;c[3]=A*f+B*k+t*m+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*n+y*r;c[6]=v*g+w*j+x*o+y*s;c[7]=v*f+w*k+x*m+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*n+E*r;c[10]=z*g+C*
  1693. j+D*o+E*s;c[11]=z*f+C*k+D*m+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*n+b*r;c[14]=q*g+F*j+G*o+b*s;c[15]=q*f+F*k+G*m+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c};
  1694. mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c};
  1695. mat4.translate=function(a,b,c){var d=b[0],e=b[1],b=b[2],g,f,h,i,j,k,l,n,o,m,p,r;if(!c||a===c)return a[12]=a[0]*d+a[4]*e+a[8]*b+a[12],a[13]=a[1]*d+a[5]*e+a[9]*b+a[13],a[14]=a[2]*d+a[6]*e+a[10]*b+a[14],a[15]=a[3]*d+a[7]*e+a[11]*b+a[15],a;g=a[0];f=a[1];h=a[2];i=a[3];j=a[4];k=a[5];l=a[6];n=a[7];o=a[8];m=a[9];p=a[10];r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=n;c[8]=o;c[9]=m;c[10]=p;c[11]=r;c[12]=g*d+j*e+o*b+a[12];c[13]=f*d+k*e+m*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+n*e+r*b+a[15];
  1696. return c};mat4.scale=function(a,b,c){var d=b[0],e=b[1],b=b[2];if(!c||a===c)return a[0]*=d,a[1]*=d,a[2]*=d,a[3]*=d,a[4]*=e,a[5]*=e,a[6]*=e,a[7]*=e,a[8]*=b,a[9]*=b,a[10]*=b,a[11]*=b,a;c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c};
  1697. mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1],c=c[2],f=Math.sqrt(e*e+g*g+c*c),h,i,j,k,l,n,o,m,p,r,s,A,B,t,u,v,w,x,y,z;if(!f)return null;f!==1&&(f=1/f,e*=f,g*=f,c*=f);h=Math.sin(b);i=Math.cos(b);j=1-i;b=a[0];f=a[1];k=a[2];l=a[3];n=a[4];o=a[5];m=a[6];p=a[7];r=a[8];s=a[9];A=a[10];B=a[11];t=e*e*j+i;u=g*e*j+c*h;v=c*e*j-g*h;w=e*g*j-c*h;x=g*g*j+i;y=c*g*j+e*h;z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;d?a!==d&&(d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]):d=a;d[0]=b*t+n*u+r*v;d[1]=f*t+o*u+s*v;d[2]=k*t+m*u+A*
  1698. v;d[3]=l*t+p*u+B*v;d[4]=b*w+n*x+r*y;d[5]=f*w+o*x+s*y;d[6]=k*w+m*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+n*e+r*g;d[9]=f*z+o*e+s*g;d[10]=k*z+m*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c};
  1699. mat4.rotateY=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];c?a!==c&&(c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c};
  1700. mat4.rotateZ=function(a,b,c){var d=Math.sin(b),b=Math.cos(b),e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];c?a!==c&&(c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]):c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c};
  1701. mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b*=a;return mat4.frustum(-b,b,-a,a,c,d,e)};
  1702. mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f};
  1703. mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e,g,f,h,i,j,k,l,n=a[0],o=a[1],a=a[2];g=c[0];f=c[1];e=c[2];c=b[1];j=b[2];if(n===b[0]&&o===c&&a===j)return mat4.identity(d);c=n-b[0];j=o-b[1];k=a-b[2];l=1/Math.sqrt(c*c+j*j+k*k);c*=l;j*=l;k*=l;b=f*k-e*j;e=e*c-g*k;g=g*j-f*c;(l=Math.sqrt(b*b+e*e+g*g))?(l=1/l,b*=l,e*=l,g*=l):g=e=b=0;f=j*g-k*e;h=k*b-c*g;i=c*e-j*b;(l=Math.sqrt(f*f+h*h+i*i))?(l=1/l,f*=l,h*=l,i*=l):i=h=f=0;d[0]=b;d[1]=f;d[2]=c;d[3]=0;d[4]=e;d[5]=h;d[6]=j;d[7]=0;d[8]=g;d[9]=i;d[10]=k;d[11]=
  1704. 0;d[12]=-(b*n+e*o+g*a);d[13]=-(f*n+h*o+i*a);d[14]=-(c*n+j*o+k*a);d[15]=1;return d};mat4.fromRotationTranslation=function(a,b,c){c||(c=mat4.create());var d=a[0],e=a[1],g=a[2],f=a[3],h=d+d,i=e+e,j=g+g,a=d*h,k=d*i;d*=j;var l=e*i;e*=j;g*=j;h*=f;i*=f;f*=j;c[0]=1-(l+g);c[1]=k+f;c[2]=d-i;c[3]=0;c[4]=k-f;c[5]=1-(a+g);c[6]=e+h;c[7]=0;c[8]=d+i;c[9]=e-h;c[10]=1-(a+l);c[11]=0;c[12]=b[0];c[13]=b[1];c[14]=b[2];c[15]=1;return c};
  1705. mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4.create=function(a){var b=new MatrixArray(4);a&&(b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3]);return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b};
  1706. quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a===b)return a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e)),a;b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a===b)return a[0]*=-1,a[1]*=-1,a[2]*=-1,a;b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2],a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)};
  1707. quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f===0)return b[0]=0,b[1]=0,b[2]=0,b[3]=0,b;f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],a=a[3],f=b[0],h=b[1],i=b[2],b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c};
  1708. quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2],b=a[0],f=a[1],h=a[2],a=a[3],i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d,d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=k-g;b[4]=1-(j+e);b[5]=d+f;b[6]=c+h;b[7]=d-f;b[8]=1-(j+l);return b};
  1709. quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c*=i;var l=d*h;d*=i;e*=i;f*=g;h*=g;g*=i;b[0]=1-(l+e);b[1]=k+g;b[2]=c-h;b[3]=0;b[4]=k-g;b[5]=1-(j+e);b[6]=d+f;b[7]=0;b[8]=c+h;b[9]=d-f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
  1710. quat4.slerp=function(a,b,c,d){d||(d=a);var e=a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3],g,f;if(Math.abs(e)>=1)return d!==a&&(d[0]=a[0],d[1]=a[1],d[2]=a[2],d[3]=a[3]),d;g=Math.acos(e);f=Math.sqrt(1-e*e);if(Math.abs(f)<0.001)return d[0]=a[0]*0.5+b[0]*0.5,d[1]=a[1]*0.5+b[1]*0.5,d[2]=a[2]*0.5+b[2]*0.5,d[3]=a[3]*0.5+b[3]*0.5,d;e=Math.sin((1-c)*g)/f;c=Math.sin(c*g)/f;d[0]=a[0]*e+b[0]*c;d[1]=a[1]*e+b[1]*c;d[2]=a[2]*e+b[2]*c;d[3]=a[3]*e+b[3]*c;return d};
  1711. quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"};
  1712. (function()
  1713. {
  1714. var MAX_VERTICES = 8000; // equates to 2500 objects being drawn
  1715. var MAX_INDICES = (MAX_VERTICES / 2) * 3; // 6 indices for every 4 vertices
  1716. var MAX_POINTS = 8000;
  1717. var MULTI_BUFFERS = 4; // cycle 4 buffers to try and avoid blocking
  1718. var BATCH_NULL = 0;
  1719. var BATCH_QUAD = 1;
  1720. var BATCH_SETTEXTURE = 2;
  1721. var BATCH_SETOPACITY = 3;
  1722. var BATCH_SETBLEND = 4;
  1723. var BATCH_UPDATEMODELVIEW = 5;
  1724. var BATCH_RENDERTOTEXTURE = 6;
  1725. var BATCH_CLEAR = 7;
  1726. var BATCH_POINTS = 8;
  1727. var BATCH_SETPROGRAM = 9;
  1728. var BATCH_SETPROGRAMPARAMETERS = 10;
  1729. var BATCH_SETTEXTURE1 = 11;
  1730. /*
  1731. var lose_ext = null;
  1732. window.lose_context = function ()
  1733. {
  1734. if (!lose_ext)
  1735. {
  1736. console.log("WEBGL_lose_context not supported");
  1737. return;
  1738. }
  1739. lose_ext.loseContext();
  1740. };
  1741. window.restore_context = function ()
  1742. {
  1743. if (!lose_ext)
  1744. {
  1745. console.log("WEBGL_lose_context not supported");
  1746. return;
  1747. }
  1748. lose_ext.restoreContext();
  1749. };
  1750. */
  1751. function GLWrap_(gl, isMobile)
  1752. {
  1753. this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent);
  1754. this.width = 0; // not yet known, wait for call to setSize()
  1755. this.height = 0;
  1756. this.cam = vec3.create([0, 0, 100]); // camera position
  1757. this.look = vec3.create([0, 0, 0]); // lookat position
  1758. this.up = vec3.create([0, 1, 0]); // up vector
  1759. this.worldScale = vec3.create([1, 1, 1]); // world scaling factor
  1760. this.enable_mipmaps = true;
  1761. this.matP = mat4.create(); // perspective matrix
  1762. this.matMV = mat4.create(); // model view matrix
  1763. this.lastMV = mat4.create();
  1764. this.currentMV = mat4.create();
  1765. this.gl = gl;
  1766. this.initState();
  1767. };
  1768. GLWrap_.prototype.initState = function ()
  1769. {
  1770. var gl = this.gl;
  1771. var i, len;
  1772. this.lastOpacity = 1;
  1773. this.lastTexture0 = null; // last bound to TEXTURE0
  1774. this.lastTexture1 = null; // last bound to TEXTURE1
  1775. this.currentOpacity = 1;
  1776. gl.clearColor(0, 0, 0, 0);
  1777. gl.clear(gl.COLOR_BUFFER_BIT);
  1778. gl.enable(gl.BLEND);
  1779. gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  1780. gl.disable(gl.CULL_FACE);
  1781. gl.disable(gl.DEPTH_TEST);
  1782. this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
  1783. this.lastSrcBlend = gl.ONE;
  1784. this.lastDestBlend = gl.ONE_MINUS_SRC_ALPHA;
  1785. this.vertexData = new Float32Array(MAX_VERTICES * 2);
  1786. this.texcoordData = new Float32Array(MAX_VERTICES * 2);
  1787. this.pointData = new Float32Array(MAX_POINTS * 4);
  1788. this.pointBuffer = gl.createBuffer();
  1789. gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
  1790. gl.bufferData(gl.ARRAY_BUFFER, this.pointData.byteLength, gl.DYNAMIC_DRAW);
  1791. this.vertexBuffers = new Array(MULTI_BUFFERS);
  1792. this.texcoordBuffers = new Array(MULTI_BUFFERS);
  1793. for (i = 0; i < MULTI_BUFFERS; i++)
  1794. {
  1795. this.vertexBuffers[i] = gl.createBuffer();
  1796. gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[i]);
  1797. gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.DYNAMIC_DRAW);
  1798. this.texcoordBuffers[i] = gl.createBuffer();
  1799. gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[i]);
  1800. gl.bufferData(gl.ARRAY_BUFFER, this.texcoordData.byteLength, gl.DYNAMIC_DRAW);
  1801. }
  1802. this.curBuffer = 0;
  1803. this.indexBuffer = gl.createBuffer();
  1804. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  1805. var indexData = new Uint16Array(MAX_INDICES);
  1806. i = 0, len = MAX_INDICES;
  1807. var fv = 0;
  1808. while (i < len)
  1809. {
  1810. indexData[i++] = fv; // top left
  1811. indexData[i++] = fv + 1; // top right
  1812. indexData[i++] = fv + 2; // bottom right (first tri)
  1813. indexData[i++] = fv; // top left
  1814. indexData[i++] = fv + 2; // bottom right
  1815. indexData[i++] = fv + 3; // bottom left
  1816. fv += 4;
  1817. }
  1818. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
  1819. this.vertexPtr = 0;
  1820. this.pointPtr = 0;
  1821. var fsSource, vsSource;
  1822. this.shaderPrograms = [];
  1823. fsSource = [
  1824. "varying mediump vec2 vTex;",
  1825. "uniform lowp float opacity;",
  1826. "uniform lowp sampler2D samplerFront;",
  1827. "void main(void) {",
  1828. " gl_FragColor = texture2D(samplerFront, vTex);",
  1829. " gl_FragColor *= opacity;",
  1830. "}"
  1831. ].join("\n");
  1832. vsSource = [
  1833. "attribute highp vec2 aPos;",
  1834. "attribute mediump vec2 aTex;",
  1835. "varying mediump vec2 vTex;",
  1836. "uniform highp mat4 matP;",
  1837. "uniform highp mat4 matMV;",
  1838. "void main(void) {",
  1839. " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
  1840. " vTex = aTex;",
  1841. "}"
  1842. ].join("\n");
  1843. var shaderProg = this.createShaderProgram({src: fsSource}, vsSource, "<default>");
  1844. ;
  1845. this.shaderPrograms.push(shaderProg); // Default shader is always shader 0
  1846. fsSource = [
  1847. "uniform mediump sampler2D samplerFront;",
  1848. "varying lowp float opacity;",
  1849. "void main(void) {",
  1850. " gl_FragColor = texture2D(samplerFront, gl_PointCoord);",
  1851. " gl_FragColor *= opacity;",
  1852. "}"
  1853. ].join("\n");
  1854. var pointVsSource = [
  1855. "attribute vec4 aPos;",
  1856. "varying float opacity;",
  1857. "uniform mat4 matP;",
  1858. "uniform mat4 matMV;",
  1859. "void main(void) {",
  1860. " gl_Position = matP * matMV * vec4(aPos.x, aPos.y, 0.0, 1.0);",
  1861. " gl_PointSize = aPos.z;",
  1862. " opacity = aPos.w;",
  1863. "}"
  1864. ].join("\n");
  1865. shaderProg = this.createShaderProgram({src: fsSource}, pointVsSource, "<point>");
  1866. ;
  1867. this.shaderPrograms.push(shaderProg); // Point shader is always shader 1
  1868. for (var shader_name in cr.shaders)
  1869. {
  1870. if (cr.shaders.hasOwnProperty(shader_name))
  1871. this.shaderPrograms.push(this.createShaderProgram(cr.shaders[shader_name], vsSource, shader_name));
  1872. }
  1873. gl.activeTexture(gl.TEXTURE0);
  1874. gl.bindTexture(gl.TEXTURE_2D, null);
  1875. this.batch = [];
  1876. this.batchPtr = 0;
  1877. this.hasQuadBatchTop = false;
  1878. this.hasPointBatchTop = false;
  1879. this.lastProgram = -1; // start -1 so first switchProgram can do work
  1880. this.currentProgram = -1; // current program during batch execution
  1881. this.currentShader = null;
  1882. this.fbo = gl.createFramebuffer();
  1883. this.renderToTex = null;
  1884. this.tmpVec3 = vec3.create([0, 0, 0]);
  1885. ;
  1886. var pointsizes = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
  1887. this.minPointSize = pointsizes[0];
  1888. this.maxPointSize = pointsizes[1];
  1889. if (this.maxPointSize > 2048)
  1890. this.maxPointSize = 2048;
  1891. ;
  1892. this.switchProgram(0);
  1893. cr.seal(this);
  1894. };
  1895. function GLShaderProgram(gl, shaderProgram, name)
  1896. {
  1897. this.gl = gl;
  1898. this.shaderProgram = shaderProgram;
  1899. this.name = name;
  1900. this.locAPos = gl.getAttribLocation(shaderProgram, "aPos");
  1901. this.locATex = gl.getAttribLocation(shaderProgram, "aTex");
  1902. this.locMatP = gl.getUniformLocation(shaderProgram, "matP");
  1903. this.locMatMV = gl.getUniformLocation(shaderProgram, "matMV");
  1904. this.locOpacity = gl.getUniformLocation(shaderProgram, "opacity");
  1905. this.locSamplerFront = gl.getUniformLocation(shaderProgram, "samplerFront");
  1906. this.locSamplerBack = gl.getUniformLocation(shaderProgram, "samplerBack");
  1907. this.locDestStart = gl.getUniformLocation(shaderProgram, "destStart");
  1908. this.locDestEnd = gl.getUniformLocation(shaderProgram, "destEnd");
  1909. this.locSeconds = gl.getUniformLocation(shaderProgram, "seconds");
  1910. this.locPixelWidth = gl.getUniformLocation(shaderProgram, "pixelWidth");
  1911. this.locPixelHeight = gl.getUniformLocation(shaderProgram, "pixelHeight");
  1912. this.locLayerScale = gl.getUniformLocation(shaderProgram, "layerScale");
  1913. this.locLayerAngle = gl.getUniformLocation(shaderProgram, "layerAngle");
  1914. this.locViewOrigin = gl.getUniformLocation(shaderProgram, "viewOrigin");
  1915. this.locScrollPos = gl.getUniformLocation(shaderProgram, "scrollPos");
  1916. this.hasAnyOptionalUniforms = !!(this.locPixelWidth || this.locPixelHeight || this.locSeconds || this.locSamplerBack || this.locDestStart || this.locDestEnd || this.locLayerScale || this.locLayerAngle || this.locViewOrigin || this.locScrollPos);
  1917. this.lpPixelWidth = -999; // set to something unlikely so never counts as cached on first set
  1918. this.lpPixelHeight = -999;
  1919. this.lpOpacity = 1;
  1920. this.lpDestStartX = 0.0;
  1921. this.lpDestStartY = 0.0;
  1922. this.lpDestEndX = 1.0;
  1923. this.lpDestEndY = 1.0;
  1924. this.lpLayerScale = 1.0;
  1925. this.lpLayerAngle = 0.0;
  1926. this.lpViewOriginX = 0.0;
  1927. this.lpViewOriginY = 0.0;
  1928. this.lpScrollPosX = 0.0;
  1929. this.lpScrollPosY = 0.0;
  1930. this.lastCustomParams = [];
  1931. this.lpMatMV = mat4.create();
  1932. if (this.locOpacity)
  1933. gl.uniform1f(this.locOpacity, 1);
  1934. if (this.locSamplerFront)
  1935. gl.uniform1i(this.locSamplerFront, 0);
  1936. if (this.locSamplerBack)
  1937. gl.uniform1i(this.locSamplerBack, 1);
  1938. if (this.locDestStart)
  1939. gl.uniform2f(this.locDestStart, 0.0, 0.0);
  1940. if (this.locDestEnd)
  1941. gl.uniform2f(this.locDestEnd, 1.0, 1.0);
  1942. if (this.locLayerScale)
  1943. gl.uniform1f(this.locLayerScale, 1.0);
  1944. if (this.locLayerAngle)
  1945. gl.uniform1f(this.locLayerAngle, 0.0);
  1946. if (this.locViewOrigin)
  1947. gl.uniform2f(this.locViewOrigin, 0.0, 0.0);
  1948. if (this.locScrollPos)
  1949. gl.uniform2f(this.locScrollPos, 0.0, 0.0);
  1950. this.hasCurrentMatMV = false; // matMV needs updating
  1951. };
  1952. function areMat4sEqual(a, b)
  1953. {
  1954. return a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&
  1955. a[4]===b[4]&&a[5]===b[5]&&a[6]===b[6]&&a[7]===b[7]&&
  1956. a[8]===b[8]&&a[9]===b[9]&&a[10]===b[10]&&a[11]===b[11]&&
  1957. a[12]===b[12]&&a[13]===b[13]&&a[14]===b[14]&&a[15]===b[15];
  1958. };
  1959. GLShaderProgram.prototype.updateMatMV = function (mv)
  1960. {
  1961. if (areMat4sEqual(this.lpMatMV, mv))
  1962. return; // no change, save the expensive GL call
  1963. mat4.set(mv, this.lpMatMV);
  1964. this.gl.uniformMatrix4fv(this.locMatMV, false, mv);
  1965. };
  1966. GLWrap_.prototype.createShaderProgram = function(shaderEntry, vsSource, name)
  1967. {
  1968. var gl = this.gl;
  1969. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  1970. gl.shaderSource(fragmentShader, shaderEntry.src);
  1971. gl.compileShader(fragmentShader);
  1972. if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
  1973. {
  1974. ;
  1975. gl.deleteShader(fragmentShader);
  1976. return null;
  1977. }
  1978. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  1979. gl.shaderSource(vertexShader, vsSource);
  1980. gl.compileShader(vertexShader);
  1981. if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
  1982. {
  1983. ;
  1984. gl.deleteShader(fragmentShader);
  1985. gl.deleteShader(vertexShader);
  1986. return null;
  1987. }
  1988. var shaderProgram = gl.createProgram();
  1989. gl.attachShader(shaderProgram, fragmentShader);
  1990. gl.attachShader(shaderProgram, vertexShader);
  1991. gl.linkProgram(shaderProgram);
  1992. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
  1993. {
  1994. ;
  1995. gl.deleteShader(fragmentShader);
  1996. gl.deleteShader(vertexShader);
  1997. gl.deleteProgram(shaderProgram);
  1998. return null;
  1999. }
  2000. gl.useProgram(shaderProgram);
  2001. gl.deleteShader(fragmentShader);
  2002. gl.deleteShader(vertexShader);
  2003. var ret = new GLShaderProgram(gl, shaderProgram, name);
  2004. ret.extendBoxHorizontal = shaderEntry.extendBoxHorizontal || 0;
  2005. ret.extendBoxVertical = shaderEntry.extendBoxVertical || 0;
  2006. ret.crossSampling = !!shaderEntry.crossSampling;
  2007. ret.animated = !!shaderEntry.animated;
  2008. ret.parameters = shaderEntry.parameters || [];
  2009. var i, len;
  2010. for (i = 0, len = ret.parameters.length; i < len; i++)
  2011. {
  2012. ret.parameters[i][1] = gl.getUniformLocation(shaderProgram, ret.parameters[i][0]);
  2013. ret.lastCustomParams.push(0);
  2014. gl.uniform1f(ret.parameters[i][1], 0);
  2015. }
  2016. cr.seal(ret);
  2017. return ret;
  2018. };
  2019. GLWrap_.prototype.getShaderIndex = function(name_)
  2020. {
  2021. var i, len;
  2022. for (i = 0, len = this.shaderPrograms.length; i < len; i++)
  2023. {
  2024. if (this.shaderPrograms[i].name === name_)
  2025. return i;
  2026. }
  2027. return -1;
  2028. };
  2029. GLWrap_.prototype.project = function (x, y, out)
  2030. {
  2031. var mv = this.matMV;
  2032. var proj = this.matP;
  2033. var fTempo = [0, 0, 0, 0, 0, 0, 0, 0];
  2034. fTempo[0] = mv[0]*x+mv[4]*y+mv[12];
  2035. fTempo[1] = mv[1]*x+mv[5]*y+mv[13];
  2036. fTempo[2] = mv[2]*x+mv[6]*y+mv[14];
  2037. fTempo[3] = mv[3]*x+mv[7]*y+mv[15];
  2038. fTempo[4] = proj[0]*fTempo[0]+proj[4]*fTempo[1]+proj[8]*fTempo[2]+proj[12]*fTempo[3];
  2039. fTempo[5] = proj[1]*fTempo[0]+proj[5]*fTempo[1]+proj[9]*fTempo[2]+proj[13]*fTempo[3];
  2040. fTempo[6] = proj[2]*fTempo[0]+proj[6]*fTempo[1]+proj[10]*fTempo[2]+proj[14]*fTempo[3];
  2041. fTempo[7] = -fTempo[2];
  2042. if(fTempo[7]===0.0) //The w value
  2043. return;
  2044. fTempo[7]=1.0/fTempo[7];
  2045. fTempo[4]*=fTempo[7];
  2046. fTempo[5]*=fTempo[7];
  2047. fTempo[6]*=fTempo[7];
  2048. out[0]=(fTempo[4]*0.5+0.5)*this.width;
  2049. out[1]=(fTempo[5]*0.5+0.5)*this.height;
  2050. };
  2051. GLWrap_.prototype.setSize = function(w, h, force)
  2052. {
  2053. if (this.width === w && this.height === h && !force)
  2054. return;
  2055. this.endBatch();
  2056. this.width = w;
  2057. this.height = h;
  2058. this.gl.viewport(0, 0, w, h);
  2059. mat4.perspective(45, w / h, 1, 1000, this.matP);
  2060. mat4.lookAt(this.cam, this.look, this.up, this.matMV);
  2061. var tl = [0, 0];
  2062. var br = [0, 0];
  2063. this.project(0, 0, tl);
  2064. this.project(1, 1, br);
  2065. this.worldScale[0] = 1 / (br[0] - tl[0]);
  2066. this.worldScale[1] = -1 / (br[1] - tl[1]);
  2067. var i, len, s;
  2068. for (i = 0, len = this.shaderPrograms.length; i < len; i++)
  2069. {
  2070. s = this.shaderPrograms[i];
  2071. s.hasCurrentMatMV = false;
  2072. if (s.locMatP)
  2073. {
  2074. this.gl.useProgram(s.shaderProgram);
  2075. this.gl.uniformMatrix4fv(s.locMatP, false, this.matP);
  2076. }
  2077. }
  2078. this.gl.useProgram(this.shaderPrograms[this.lastProgram].shaderProgram);
  2079. this.gl.bindTexture(this.gl.TEXTURE_2D, null);
  2080. this.gl.activeTexture(this.gl.TEXTURE1);
  2081. this.gl.bindTexture(this.gl.TEXTURE_2D, null);
  2082. this.gl.activeTexture(this.gl.TEXTURE0);
  2083. this.lastTexture0 = null;
  2084. this.lastTexture1 = null;
  2085. };
  2086. GLWrap_.prototype.resetModelView = function ()
  2087. {
  2088. mat4.lookAt(this.cam, this.look, this.up, this.matMV);
  2089. mat4.scale(this.matMV, this.worldScale);
  2090. };
  2091. GLWrap_.prototype.translate = function (x, y)
  2092. {
  2093. if (x === 0 && y === 0)
  2094. return;
  2095. this.tmpVec3[0] = x;// * this.worldScale[0];
  2096. this.tmpVec3[1] = y;// * this.worldScale[1];
  2097. this.tmpVec3[2] = 0;
  2098. mat4.translate(this.matMV, this.tmpVec3);
  2099. };
  2100. GLWrap_.prototype.scale = function (x, y)
  2101. {
  2102. if (x === 1 && y === 1)
  2103. return;
  2104. this.tmpVec3[0] = x;
  2105. this.tmpVec3[1] = y;
  2106. this.tmpVec3[2] = 1;
  2107. mat4.scale(this.matMV, this.tmpVec3);
  2108. };
  2109. GLWrap_.prototype.rotateZ = function (a)
  2110. {
  2111. if (a === 0)
  2112. return;
  2113. mat4.rotateZ(this.matMV, a);
  2114. };
  2115. GLWrap_.prototype.updateModelView = function()
  2116. {
  2117. var anydiff = false;
  2118. for (var i = 0; i < 16; i++)
  2119. {
  2120. if (this.lastMV[i] !== this.matMV[i])
  2121. {
  2122. anydiff = true;
  2123. break;
  2124. }
  2125. }
  2126. if (!anydiff)
  2127. return;
  2128. var b = this.pushBatch();
  2129. b.type = BATCH_UPDATEMODELVIEW;
  2130. if (b.mat4param)
  2131. mat4.set(this.matMV, b.mat4param);
  2132. else
  2133. b.mat4param = mat4.create(this.matMV);
  2134. mat4.set(this.matMV, this.lastMV);
  2135. this.hasQuadBatchTop = false;
  2136. this.hasPointBatchTop = false;
  2137. };
  2138. /*
  2139. var debugBatch = false;
  2140. jQuery(document).mousedown(
  2141. function(info) {
  2142. if (info.which === 2)
  2143. debugBatch = true;
  2144. }
  2145. );
  2146. */
  2147. function GLBatchJob(type_, glwrap_)
  2148. {
  2149. this.type = type_;
  2150. this.glwrap = glwrap_;
  2151. this.gl = glwrap_.gl;
  2152. this.opacityParam = 0; // for setOpacity()
  2153. this.startIndex = 0; // for quad()
  2154. this.indexCount = 0; // "
  2155. this.texParam = null; // for setTexture()
  2156. this.mat4param = null; // for updateModelView()
  2157. this.shaderParams = []; // for user parameters
  2158. cr.seal(this);
  2159. };
  2160. GLBatchJob.prototype.doSetTexture = function ()
  2161. {
  2162. this.gl.bindTexture(this.gl.TEXTURE_2D, this.texParam);
  2163. };
  2164. GLBatchJob.prototype.doSetTexture1 = function ()
  2165. {
  2166. var gl = this.gl;
  2167. gl.activeTexture(gl.TEXTURE1);
  2168. gl.bindTexture(gl.TEXTURE_2D, this.texParam);
  2169. gl.activeTexture(gl.TEXTURE0);
  2170. };
  2171. GLBatchJob.prototype.doSetOpacity = function ()
  2172. {
  2173. var o = this.opacityParam;
  2174. var glwrap = this.glwrap;
  2175. glwrap.currentOpacity = o;
  2176. var curProg = glwrap.currentShader;
  2177. if (curProg.locOpacity && curProg.lpOpacity !== o)
  2178. {
  2179. curProg.lpOpacity = o;
  2180. this.gl.uniform1f(curProg.locOpacity, o);
  2181. }
  2182. };
  2183. GLBatchJob.prototype.doQuad = function ()
  2184. {
  2185. this.gl.drawElements(this.gl.TRIANGLES, this.indexCount, this.gl.UNSIGNED_SHORT, this.startIndex * 2);
  2186. };
  2187. GLBatchJob.prototype.doSetBlend = function ()
  2188. {
  2189. this.gl.blendFunc(this.startIndex, this.indexCount);
  2190. };
  2191. GLBatchJob.prototype.doUpdateModelView = function ()
  2192. {
  2193. var i, len, s, shaderPrograms = this.glwrap.shaderPrograms, currentProgram = this.glwrap.currentProgram;
  2194. for (i = 0, len = shaderPrograms.length; i < len; i++)
  2195. {
  2196. s = shaderPrograms[i];
  2197. if (i === currentProgram && s.locMatMV)
  2198. {
  2199. s.updateMatMV(this.mat4param);
  2200. s.hasCurrentMatMV = true;
  2201. }
  2202. else
  2203. s.hasCurrentMatMV = false;
  2204. }
  2205. mat4.set(this.mat4param, this.glwrap.currentMV);
  2206. };
  2207. GLBatchJob.prototype.doRenderToTexture = function ()
  2208. {
  2209. var gl = this.gl;
  2210. var glwrap = this.glwrap;
  2211. if (this.texParam)
  2212. {
  2213. if (glwrap.lastTexture1 === this.texParam)
  2214. {
  2215. gl.activeTexture(gl.TEXTURE1);
  2216. gl.bindTexture(gl.TEXTURE_2D, null);
  2217. glwrap.lastTexture1 = null;
  2218. gl.activeTexture(gl.TEXTURE0);
  2219. }
  2220. gl.bindFramebuffer(gl.FRAMEBUFFER, glwrap.fbo);
  2221. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texParam, 0);
  2222. }
  2223. else
  2224. {
  2225. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
  2226. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  2227. }
  2228. };
  2229. GLBatchJob.prototype.doClear = function ()
  2230. {
  2231. var gl = this.gl;
  2232. if (this.startIndex === 0) // clear whole surface
  2233. {
  2234. gl.clearColor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
  2235. gl.clear(gl.COLOR_BUFFER_BIT);
  2236. }
  2237. else // clear rectangle
  2238. {
  2239. gl.enable(gl.SCISSOR_TEST);
  2240. gl.scissor(this.mat4param[0], this.mat4param[1], this.mat4param[2], this.mat4param[3]);
  2241. gl.clearColor(0, 0, 0, 0);
  2242. gl.clear(this.gl.COLOR_BUFFER_BIT);
  2243. gl.disable(gl.SCISSOR_TEST);
  2244. }
  2245. };
  2246. GLBatchJob.prototype.doPoints = function ()
  2247. {
  2248. var gl = this.gl;
  2249. var glwrap = this.glwrap;
  2250. var s = glwrap.shaderPrograms[1];
  2251. gl.useProgram(s.shaderProgram);
  2252. if (!s.hasCurrentMatMV && s.locMatMV)
  2253. {
  2254. s.updateMatMV(glwrap.currentMV);
  2255. s.hasCurrentMatMV = true;
  2256. }
  2257. gl.enableVertexAttribArray(s.locAPos);
  2258. gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.pointBuffer);
  2259. gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
  2260. gl.drawArrays(gl.POINTS, this.startIndex / 4, this.indexCount);
  2261. s = glwrap.currentShader;
  2262. gl.useProgram(s.shaderProgram);
  2263. if (s.locAPos >= 0)
  2264. {
  2265. gl.enableVertexAttribArray(s.locAPos);
  2266. gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
  2267. gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0);
  2268. }
  2269. if (s.locATex >= 0)
  2270. {
  2271. gl.enableVertexAttribArray(s.locATex);
  2272. gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
  2273. gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
  2274. }
  2275. };
  2276. GLBatchJob.prototype.doSetProgram = function ()
  2277. {
  2278. var gl = this.gl;
  2279. var glwrap = this.glwrap;
  2280. var s = glwrap.shaderPrograms[this.startIndex]; // recycled param to save memory
  2281. glwrap.currentProgram = this.startIndex; // current batch program
  2282. glwrap.currentShader = s;
  2283. gl.useProgram(s.shaderProgram); // switch to
  2284. if (!s.hasCurrentMatMV && s.locMatMV)
  2285. {
  2286. s.updateMatMV(glwrap.currentMV);
  2287. s.hasCurrentMatMV = true;
  2288. }
  2289. if (s.locOpacity && s.lpOpacity !== glwrap.currentOpacity)
  2290. {
  2291. s.lpOpacity = glwrap.currentOpacity;
  2292. gl.uniform1f(s.locOpacity, glwrap.currentOpacity);
  2293. }
  2294. if (s.locAPos >= 0)
  2295. {
  2296. gl.enableVertexAttribArray(s.locAPos);
  2297. gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.vertexBuffers[glwrap.curBuffer]);
  2298. gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0);
  2299. }
  2300. if (s.locATex >= 0)
  2301. {
  2302. gl.enableVertexAttribArray(s.locATex);
  2303. gl.bindBuffer(gl.ARRAY_BUFFER, glwrap.texcoordBuffers[glwrap.curBuffer]);
  2304. gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
  2305. }
  2306. }
  2307. GLBatchJob.prototype.doSetProgramParameters = function ()
  2308. {
  2309. var i, len, s = this.glwrap.currentShader;
  2310. var gl = this.gl;
  2311. var mat4param = this.mat4param;
  2312. if (s.locSamplerBack && this.glwrap.lastTexture1 !== this.texParam)
  2313. {
  2314. gl.activeTexture(gl.TEXTURE1);
  2315. gl.bindTexture(gl.TEXTURE_2D, this.texParam);
  2316. this.glwrap.lastTexture1 = this.texParam;
  2317. gl.activeTexture(gl.TEXTURE0);
  2318. }
  2319. var v = mat4param[0];
  2320. var v2;
  2321. if (s.locPixelWidth && v !== s.lpPixelWidth)
  2322. {
  2323. s.lpPixelWidth = v;
  2324. gl.uniform1f(s.locPixelWidth, v);
  2325. }
  2326. v = mat4param[1];
  2327. if (s.locPixelHeight && v !== s.lpPixelHeight)
  2328. {
  2329. s.lpPixelHeight = v;
  2330. gl.uniform1f(s.locPixelHeight, v);
  2331. }
  2332. v = mat4param[2];
  2333. v2 = mat4param[3];
  2334. if (s.locDestStart && (v !== s.lpDestStartX || v2 !== s.lpDestStartY))
  2335. {
  2336. s.lpDestStartX = v;
  2337. s.lpDestStartY = v2;
  2338. gl.uniform2f(s.locDestStart, v, v2);
  2339. }
  2340. v = mat4param[4];
  2341. v2 = mat4param[5];
  2342. if (s.locDestEnd && (v !== s.lpDestEndX || v2 !== s.lpDestEndY))
  2343. {
  2344. s.lpDestEndX = v;
  2345. s.lpDestEndY = v;
  2346. gl.uniform2f(s.locDestEnd, v, v2);
  2347. }
  2348. v = mat4param[6];
  2349. if (s.locLayerScale && v !== s.lpLayerScale)
  2350. {
  2351. s.lpLayerScale = v;
  2352. gl.uniform1f(s.locLayerScale, v);
  2353. }
  2354. v = mat4param[7];
  2355. if (s.locLayerAngle && v !== s.lpLayerAngle)
  2356. {
  2357. s.lpLayerAngle = v;
  2358. gl.uniform1f(s.locLayerAngle, v);
  2359. }
  2360. v = mat4param[8];
  2361. v2 = mat4param[9];
  2362. if (s.locViewOrigin && (v !== s.lpViewOriginX || v2 !== s.lpViewOriginY))
  2363. {
  2364. s.lpViewOriginX = v;
  2365. s.lpViewOriginY = v2;
  2366. gl.uniform2f(s.locViewOrigin, v, v2);
  2367. }
  2368. v = mat4param[10];
  2369. v2 = mat4param[11];
  2370. if (s.locScrollPos && (v !== s.lpScrollPosX || v2 !== s.lpScrollPosY))
  2371. {
  2372. s.lpScrollPosX = v;
  2373. s.lpScrollPosY = v2;
  2374. gl.uniform2f(s.locScrollPos, v, v2);
  2375. }
  2376. if (s.locSeconds)
  2377. gl.uniform1f(s.locSeconds, cr.performance_now() / 1000.0);
  2378. if (s.parameters.length)
  2379. {
  2380. for (i = 0, len = s.parameters.length; i < len; i++)
  2381. {
  2382. v = this.shaderParams[i];
  2383. if (v !== s.lastCustomParams[i])
  2384. {
  2385. s.lastCustomParams[i] = v;
  2386. gl.uniform1f(s.parameters[i][1], v);
  2387. }
  2388. }
  2389. }
  2390. };
  2391. GLWrap_.prototype.pushBatch = function ()
  2392. {
  2393. if (this.batchPtr === this.batch.length)
  2394. this.batch.push(new GLBatchJob(BATCH_NULL, this));
  2395. return this.batch[this.batchPtr++];
  2396. };
  2397. GLWrap_.prototype.endBatch = function ()
  2398. {
  2399. if (this.batchPtr === 0)
  2400. return;
  2401. if (this.gl.isContextLost())
  2402. return;
  2403. var gl = this.gl;
  2404. if (this.pointPtr > 0)
  2405. {
  2406. gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
  2407. gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.pointData.subarray(0, this.pointPtr));
  2408. if (s && s.locAPos >= 0 && s.name === "<point>")
  2409. gl.vertexAttribPointer(s.locAPos, 4, gl.FLOAT, false, 0, 0);
  2410. }
  2411. if (this.vertexPtr > 0)
  2412. {
  2413. var s = this.currentShader;
  2414. gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffers[this.curBuffer]);
  2415. gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexData.subarray(0, this.vertexPtr));
  2416. if (s && s.locAPos >= 0 && s.name !== "<point>")
  2417. gl.vertexAttribPointer(s.locAPos, 2, gl.FLOAT, false, 0, 0);
  2418. gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffers[this.curBuffer]);
  2419. gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.texcoordData.subarray(0, this.vertexPtr));
  2420. if (s && s.locATex >= 0 && s.name !== "<point>")
  2421. gl.vertexAttribPointer(s.locATex, 2, gl.FLOAT, false, 0, 0);
  2422. }
  2423. var i, len, b;
  2424. for (i = 0, len = this.batchPtr; i < len; i++)
  2425. {
  2426. b = this.batch[i];
  2427. switch (b.type) {
  2428. case 1:
  2429. b.doQuad();
  2430. break;
  2431. case 2:
  2432. b.doSetTexture();
  2433. break;
  2434. case 3:
  2435. b.doSetOpacity();
  2436. break;
  2437. case 4:
  2438. b.doSetBlend();
  2439. break;
  2440. case 5:
  2441. b.doUpdateModelView();
  2442. break;
  2443. case 6:
  2444. b.doRenderToTexture();
  2445. break;
  2446. case 7:
  2447. b.doClear();
  2448. break;
  2449. case 8:
  2450. b.doPoints();
  2451. break;
  2452. case 9:
  2453. b.doSetProgram();
  2454. break;
  2455. case 10:
  2456. b.doSetProgramParameters();
  2457. break;
  2458. case 11:
  2459. b.doSetTexture1();
  2460. break;
  2461. }
  2462. }
  2463. this.batchPtr = 0;
  2464. this.vertexPtr = 0;
  2465. this.pointPtr = 0;
  2466. this.hasQuadBatchTop = false;
  2467. this.hasPointBatchTop = false;
  2468. this.curBuffer++;
  2469. if (this.curBuffer >= MULTI_BUFFERS)
  2470. this.curBuffer = 0;
  2471. };
  2472. GLWrap_.prototype.setOpacity = function (op)
  2473. {
  2474. if (op === this.lastOpacity)
  2475. return;
  2476. var b = this.pushBatch();
  2477. b.type = BATCH_SETOPACITY;
  2478. b.opacityParam = op;
  2479. this.lastOpacity = op;
  2480. this.hasQuadBatchTop = false;
  2481. this.hasPointBatchTop = false;
  2482. };
  2483. GLWrap_.prototype.setTexture = function (tex)
  2484. {
  2485. if (tex === this.lastTexture0)
  2486. return;
  2487. ;
  2488. var b = this.pushBatch();
  2489. b.type = BATCH_SETTEXTURE;
  2490. b.texParam = tex;
  2491. this.lastTexture0 = tex;
  2492. this.hasQuadBatchTop = false;
  2493. this.hasPointBatchTop = false;
  2494. };
  2495. GLWrap_.prototype.setBlend = function (s, d)
  2496. {
  2497. if (s === this.lastSrcBlend && d === this.lastDestBlend)
  2498. return;
  2499. var b = this.pushBatch();
  2500. b.type = BATCH_SETBLEND;
  2501. b.startIndex = s; // recycle params to save memory
  2502. b.indexCount = d;
  2503. this.lastSrcBlend = s;
  2504. this.lastDestBlend = d;
  2505. this.hasQuadBatchTop = false;
  2506. this.hasPointBatchTop = false;
  2507. };
  2508. GLWrap_.prototype.isPremultipliedAlphaBlend = function ()
  2509. {
  2510. return (this.lastSrcBlend === this.gl.ONE && this.lastDestBlend === this.gl.ONE_MINUS_SRC_ALPHA);
  2511. };
  2512. GLWrap_.prototype.setAlphaBlend = function ()
  2513. {
  2514. this.setBlend(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
  2515. };
  2516. GLWrap_.prototype.setNoPremultiplyAlphaBlend = function ()
  2517. {
  2518. this.setBlend(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
  2519. };
  2520. var LAST_VERTEX = MAX_VERTICES * 2 - 8;
  2521. GLWrap_.prototype.quad = function(tlx, tly, trx, try_, brx, bry, blx, bly)
  2522. {
  2523. if (this.vertexPtr >= LAST_VERTEX)
  2524. this.endBatch();
  2525. var v = this.vertexPtr; // vertex cursor
  2526. var vd = this.vertexData; // vertex data array
  2527. var td = this.texcoordData; // texture coord data array
  2528. if (this.hasQuadBatchTop)
  2529. {
  2530. this.batch[this.batchPtr - 1].indexCount += 6;
  2531. }
  2532. else
  2533. {
  2534. var b = this.pushBatch();
  2535. b.type = BATCH_QUAD;
  2536. b.startIndex = (v / 4) * 3;
  2537. b.indexCount = 6;
  2538. this.hasQuadBatchTop = true;
  2539. this.hasPointBatchTop = false;
  2540. }
  2541. vd[v] = tlx;
  2542. td[v++] = 0;
  2543. vd[v] = tly;
  2544. td[v++] = 0;
  2545. vd[v] = trx;
  2546. td[v++] = 1;
  2547. vd[v] = try_;
  2548. td[v++] = 0;
  2549. vd[v] = brx;
  2550. td[v++] = 1;
  2551. vd[v] = bry;
  2552. td[v++] = 1;
  2553. vd[v] = blx;
  2554. td[v++] = 0;
  2555. vd[v] = bly;
  2556. td[v++] = 1;
  2557. this.vertexPtr = v;
  2558. };
  2559. GLWrap_.prototype.quadTex = function(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex)
  2560. {
  2561. if (this.vertexPtr >= LAST_VERTEX)
  2562. this.endBatch();
  2563. var v = this.vertexPtr; // vertex cursor
  2564. var vd = this.vertexData; // vertex data array
  2565. var td = this.texcoordData; // texture coord data array
  2566. if (this.hasQuadBatchTop)
  2567. {
  2568. this.batch[this.batchPtr - 1].indexCount += 6;
  2569. }
  2570. else
  2571. {
  2572. var b = this.pushBatch();
  2573. b.type = BATCH_QUAD;
  2574. b.startIndex = (v / 4) * 3;
  2575. b.indexCount = 6;
  2576. this.hasQuadBatchTop = true;
  2577. this.hasPointBatchTop = false;
  2578. }
  2579. var rc_left = rcTex.left;
  2580. var rc_top = rcTex.top;
  2581. var rc_right = rcTex.right;
  2582. var rc_bottom = rcTex.bottom;
  2583. vd[v] = tlx;
  2584. td[v++] = rc_left;
  2585. vd[v] = tly;
  2586. td[v++] = rc_top;
  2587. vd[v] = trx;
  2588. td[v++] = rc_right;
  2589. vd[v] = try_;
  2590. td[v++] = rc_top;
  2591. vd[v] = brx;
  2592. td[v++] = rc_right;
  2593. vd[v] = bry;
  2594. td[v++] = rc_bottom;
  2595. vd[v] = blx;
  2596. td[v++] = rc_left;
  2597. vd[v] = bly;
  2598. td[v++] = rc_bottom;
  2599. this.vertexPtr = v;
  2600. };
  2601. GLWrap_.prototype.quadTexUV = function(tlx, tly, trx, try_, brx, bry, blx, bly, tlu, tlv, tru, trv, bru, brv, blu, blv)
  2602. {
  2603. if (this.vertexPtr >= LAST_VERTEX)
  2604. this.endBatch();
  2605. var v = this.vertexPtr; // vertex cursor
  2606. var vd = this.vertexData; // vertex data array
  2607. var td = this.texcoordData; // texture coord data array
  2608. if (this.hasQuadBatchTop)
  2609. {
  2610. this.batch[this.batchPtr - 1].indexCount += 6;
  2611. }
  2612. else
  2613. {
  2614. var b = this.pushBatch();
  2615. b.type = BATCH_QUAD;
  2616. b.startIndex = (v / 4) * 3;
  2617. b.indexCount = 6;
  2618. this.hasQuadBatchTop = true;
  2619. this.hasPointBatchTop = false;
  2620. }
  2621. vd[v] = tlx;
  2622. td[v++] = tlu;
  2623. vd[v] = tly;
  2624. td[v++] = tlv;
  2625. vd[v] = trx;
  2626. td[v++] = tru;
  2627. vd[v] = try_;
  2628. td[v++] = trv;
  2629. vd[v] = brx;
  2630. td[v++] = bru;
  2631. vd[v] = bry;
  2632. td[v++] = brv;
  2633. vd[v] = blx;
  2634. td[v++] = blu;
  2635. vd[v] = bly;
  2636. td[v++] = blv;
  2637. this.vertexPtr = v;
  2638. };
  2639. GLWrap_.prototype.convexPoly = function(pts)
  2640. {
  2641. var pts_count = pts.length / 2;
  2642. ;
  2643. var tris = pts_count - 2; // 3 points = 1 tri, 4 points = 2 tris, 5 points = 3 tris etc.
  2644. var last_tri = tris - 1;
  2645. var p0x = pts[0];
  2646. var p0y = pts[1];
  2647. var i, i2, p1x, p1y, p2x, p2y, p3x, p3y;
  2648. for (i = 0; i < tris; i += 2) // draw 2 triangles at a time
  2649. {
  2650. i2 = i * 2;
  2651. p1x = pts[i2 + 2];
  2652. p1y = pts[i2 + 3];
  2653. p2x = pts[i2 + 4];
  2654. p2y = pts[i2 + 5];
  2655. if (i === last_tri)
  2656. {
  2657. this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p2x, p2y);
  2658. }
  2659. else
  2660. {
  2661. p3x = pts[i2 + 6];
  2662. p3y = pts[i2 + 7];
  2663. this.quad(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y);
  2664. }
  2665. }
  2666. };
  2667. var LAST_POINT = MAX_POINTS - 4;
  2668. GLWrap_.prototype.point = function(x_, y_, size_, opacity_)
  2669. {
  2670. if (this.pointPtr >= LAST_POINT)
  2671. this.endBatch();
  2672. var p = this.pointPtr; // point cursor
  2673. var pd = this.pointData; // point data array
  2674. if (this.hasPointBatchTop)
  2675. {
  2676. this.batch[this.batchPtr - 1].indexCount++;
  2677. }
  2678. else
  2679. {
  2680. var b = this.pushBatch();
  2681. b.type = BATCH_POINTS;
  2682. b.startIndex = p;
  2683. b.indexCount = 1;
  2684. this.hasPointBatchTop = true;
  2685. this.hasQuadBatchTop = false;
  2686. }
  2687. pd[p++] = x_;
  2688. pd[p++] = y_;
  2689. pd[p++] = size_;
  2690. pd[p++] = opacity_;
  2691. this.pointPtr = p;
  2692. };
  2693. GLWrap_.prototype.switchProgram = function (progIndex)
  2694. {
  2695. if (this.lastProgram === progIndex)
  2696. return; // no change
  2697. var shaderProg = this.shaderPrograms[progIndex];
  2698. if (!shaderProg)
  2699. {
  2700. if (this.lastProgram === 0)
  2701. return; // already on default shader
  2702. progIndex = 0;
  2703. shaderProg = this.shaderPrograms[0];
  2704. }
  2705. var b = this.pushBatch();
  2706. b.type = BATCH_SETPROGRAM;
  2707. b.startIndex = progIndex;
  2708. this.lastProgram = progIndex;
  2709. this.hasQuadBatchTop = false;
  2710. this.hasPointBatchTop = false;
  2711. };
  2712. GLWrap_.prototype.programUsesDest = function (progIndex)
  2713. {
  2714. var s = this.shaderPrograms[progIndex];
  2715. return !!(s.locDestStart || s.locDestEnd);
  2716. };
  2717. GLWrap_.prototype.programUsesCrossSampling = function (progIndex)
  2718. {
  2719. var s = this.shaderPrograms[progIndex];
  2720. return !!(s.locDestStart || s.locDestEnd || s.crossSampling);
  2721. };
  2722. GLWrap_.prototype.programExtendsBox = function (progIndex)
  2723. {
  2724. var s = this.shaderPrograms[progIndex];
  2725. return s.extendBoxHorizontal !== 0 || s.extendBoxVertical !== 0;
  2726. };
  2727. GLWrap_.prototype.getProgramBoxExtendHorizontal = function (progIndex)
  2728. {
  2729. return this.shaderPrograms[progIndex].extendBoxHorizontal;
  2730. };
  2731. GLWrap_.prototype.getProgramBoxExtendVertical = function (progIndex)
  2732. {
  2733. return this.shaderPrograms[progIndex].extendBoxVertical;
  2734. };
  2735. GLWrap_.prototype.getProgramParameterType = function (progIndex, paramIndex)
  2736. {
  2737. return this.shaderPrograms[progIndex].parameters[paramIndex][2];
  2738. };
  2739. GLWrap_.prototype.programIsAnimated = function (progIndex)
  2740. {
  2741. return this.shaderPrograms[progIndex].animated;
  2742. };
  2743. GLWrap_.prototype.setProgramParameters = function (backTex, pixelWidth, pixelHeight, destStartX, destStartY, destEndX, destEndY, layerScale, layerAngle, viewOriginLeft, viewOriginTop, scrollPosX, scrollPosY, params)
  2744. {
  2745. var i, len;
  2746. var s = this.shaderPrograms[this.lastProgram];
  2747. var b, mat4param, shaderParams;
  2748. if (s.hasAnyOptionalUniforms || params.length)
  2749. {
  2750. b = this.pushBatch();
  2751. b.type = BATCH_SETPROGRAMPARAMETERS;
  2752. if (b.mat4param)
  2753. mat4.set(this.matMV, b.mat4param);
  2754. else
  2755. b.mat4param = mat4.create();
  2756. mat4param = b.mat4param;
  2757. mat4param[0] = pixelWidth;
  2758. mat4param[1] = pixelHeight;
  2759. mat4param[2] = destStartX;
  2760. mat4param[3] = destStartY;
  2761. mat4param[4] = destEndX;
  2762. mat4param[5] = destEndY;
  2763. mat4param[6] = layerScale;
  2764. mat4param[7] = layerAngle;
  2765. mat4param[8] = viewOriginLeft;
  2766. mat4param[9] = viewOriginTop;
  2767. mat4param[10] = scrollPosX;
  2768. mat4param[11] = scrollPosY;
  2769. if (s.locSamplerBack)
  2770. {
  2771. ;
  2772. b.texParam = backTex;
  2773. }
  2774. else
  2775. b.texParam = null;
  2776. if (params.length)
  2777. {
  2778. shaderParams = b.shaderParams;
  2779. shaderParams.length = params.length;
  2780. for (i = 0, len = params.length; i < len; i++)
  2781. shaderParams[i] = params[i];
  2782. }
  2783. this.hasQuadBatchTop = false;
  2784. this.hasPointBatchTop = false;
  2785. }
  2786. };
  2787. GLWrap_.prototype.clear = function (r, g, b_, a)
  2788. {
  2789. var b = this.pushBatch();
  2790. b.type = BATCH_CLEAR;
  2791. b.startIndex = 0; // clear all mode
  2792. if (!b.mat4param)
  2793. b.mat4param = mat4.create();
  2794. b.mat4param[0] = r;
  2795. b.mat4param[1] = g;
  2796. b.mat4param[2] = b_;
  2797. b.mat4param[3] = a;
  2798. this.hasQuadBatchTop = false;
  2799. this.hasPointBatchTop = false;
  2800. };
  2801. GLWrap_.prototype.clearRect = function (x, y, w, h)
  2802. {
  2803. if (w < 0 || h < 0)
  2804. return; // invalid clear area
  2805. var b = this.pushBatch();
  2806. b.type = BATCH_CLEAR;
  2807. b.startIndex = 1; // clear rect mode
  2808. if (!b.mat4param)
  2809. b.mat4param = mat4.create();
  2810. b.mat4param[0] = x;
  2811. b.mat4param[1] = y;
  2812. b.mat4param[2] = w;
  2813. b.mat4param[3] = h;
  2814. this.hasQuadBatchTop = false;
  2815. this.hasPointBatchTop = false;
  2816. };
  2817. GLWrap_.prototype.present = function ()
  2818. {
  2819. this.endBatch();
  2820. this.gl.flush();
  2821. /*
  2822. if (debugBatch)
  2823. {
  2824. ;
  2825. debugBatch = false;
  2826. }
  2827. */
  2828. };
  2829. function nextHighestPowerOfTwo(x) {
  2830. --x;
  2831. for (var i = 1; i < 32; i <<= 1) {
  2832. x = x | x >> i;
  2833. }
  2834. return x + 1;
  2835. }
  2836. var all_textures = [];
  2837. var textures_by_src = {};
  2838. GLWrap_.prototype.contextLost = function ()
  2839. {
  2840. all_textures.length = 0;
  2841. textures_by_src = {};
  2842. };
  2843. var BF_RGBA8 = 0;
  2844. var BF_RGB8 = 1;
  2845. var BF_RGBA4 = 2;
  2846. var BF_RGB5_A1 = 3;
  2847. var BF_RGB565 = 4;
  2848. GLWrap_.prototype.loadTexture = function (img, tiling, linearsampling, pixelformat, tiletype, nomip)
  2849. {
  2850. tiling = !!tiling;
  2851. linearsampling = !!linearsampling;
  2852. var tex_key = img.src + "," + tiling + "," + linearsampling + (tiling ? ("," + tiletype) : "");
  2853. var webGL_texture = null;
  2854. if (typeof img.src !== "undefined" && textures_by_src.hasOwnProperty(tex_key))
  2855. {
  2856. webGL_texture = textures_by_src[tex_key];
  2857. webGL_texture.c2refcount++;
  2858. return webGL_texture;
  2859. }
  2860. this.endBatch();
  2861. ;
  2862. var gl = this.gl;
  2863. var isPOT = (cr.isPOT(img.width) && cr.isPOT(img.height));
  2864. webGL_texture = gl.createTexture();
  2865. gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
  2866. gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
  2867. var internalformat = gl.RGBA;
  2868. var format = gl.RGBA;
  2869. var type = gl.UNSIGNED_BYTE;
  2870. if (pixelformat && !this.isIE)
  2871. {
  2872. switch (pixelformat) {
  2873. case BF_RGB8:
  2874. internalformat = gl.RGB;
  2875. format = gl.RGB;
  2876. break;
  2877. case BF_RGBA4:
  2878. type = gl.UNSIGNED_SHORT_4_4_4_4;
  2879. break;
  2880. case BF_RGB5_A1:
  2881. type = gl.UNSIGNED_SHORT_5_5_5_1;
  2882. break;
  2883. case BF_RGB565:
  2884. internalformat = gl.RGB;
  2885. format = gl.RGB;
  2886. type = gl.UNSIGNED_SHORT_5_6_5;
  2887. break;
  2888. }
  2889. }
  2890. if (!isPOT && tiling)
  2891. {
  2892. var canvas = document.createElement("canvas");
  2893. canvas.width = cr.nextHighestPowerOfTwo(img.width);
  2894. canvas.height = cr.nextHighestPowerOfTwo(img.height);
  2895. var ctx = canvas.getContext("2d");
  2896. ctx["webkitImageSmoothingEnabled"] = linearsampling;
  2897. ctx["mozImageSmoothingEnabled"] = linearsampling;
  2898. ctx["msImageSmoothingEnabled"] = linearsampling;
  2899. ctx["imageSmoothingEnabled"] = linearsampling;
  2900. ctx.drawImage(img,
  2901. 0, 0, img.width, img.height,
  2902. 0, 0, canvas.width, canvas.height);
  2903. gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, canvas);
  2904. }
  2905. else
  2906. gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, format, type, img);
  2907. if (tiling)
  2908. {
  2909. if (tiletype === "repeat-x")
  2910. {
  2911. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  2912. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  2913. }
  2914. else if (tiletype === "repeat-y")
  2915. {
  2916. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  2917. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  2918. }
  2919. else
  2920. {
  2921. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  2922. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  2923. }
  2924. }
  2925. else
  2926. {
  2927. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  2928. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  2929. }
  2930. if (linearsampling)
  2931. {
  2932. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  2933. if (isPOT && this.enable_mipmaps && !nomip)
  2934. {
  2935. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  2936. gl.generateMipmap(gl.TEXTURE_2D);
  2937. }
  2938. else
  2939. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  2940. }
  2941. else
  2942. {
  2943. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  2944. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  2945. }
  2946. gl.bindTexture(gl.TEXTURE_2D, null);
  2947. this.lastTexture0 = null;
  2948. webGL_texture.c2width = img.width;
  2949. webGL_texture.c2height = img.height;
  2950. webGL_texture.c2refcount = 1;
  2951. webGL_texture.c2texkey = tex_key;
  2952. all_textures.push(webGL_texture);
  2953. textures_by_src[tex_key] = webGL_texture;
  2954. return webGL_texture;
  2955. };
  2956. GLWrap_.prototype.createEmptyTexture = function (w, h, linearsampling, _16bit, tiling)
  2957. {
  2958. this.endBatch();
  2959. var gl = this.gl;
  2960. if (this.isIE)
  2961. _16bit = false;
  2962. var webGL_texture = gl.createTexture();
  2963. gl.bindTexture(gl.TEXTURE_2D, webGL_texture);
  2964. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, null);
  2965. if (tiling)
  2966. {
  2967. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  2968. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  2969. }
  2970. else
  2971. {
  2972. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  2973. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  2974. }
  2975. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
  2976. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linearsampling ? gl.LINEAR : gl.NEAREST);
  2977. gl.bindTexture(gl.TEXTURE_2D, null);
  2978. this.lastTexture0 = null;
  2979. webGL_texture.c2width = w;
  2980. webGL_texture.c2height = h;
  2981. all_textures.push(webGL_texture);
  2982. return webGL_texture;
  2983. };
  2984. GLWrap_.prototype.videoToTexture = function (video_, texture_, _16bit)
  2985. {
  2986. this.endBatch();
  2987. var gl = this.gl;
  2988. if (this.isIE)
  2989. _16bit = false;
  2990. gl.bindTexture(gl.TEXTURE_2D, texture_);
  2991. gl.pixelStorei(gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"], true);
  2992. try {
  2993. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, _16bit ? gl.UNSIGNED_SHORT_4_4_4_4 : gl.UNSIGNED_BYTE, video_);
  2994. }
  2995. catch (e)
  2996. {
  2997. if (console && console.error)
  2998. console.error("Error updating WebGL texture: ", e);
  2999. }
  3000. gl.bindTexture(gl.TEXTURE_2D, null);
  3001. this.lastTexture0 = null;
  3002. };
  3003. GLWrap_.prototype.deleteTexture = function (tex)
  3004. {
  3005. if (!tex)
  3006. return;
  3007. if (typeof tex.c2refcount !== "undefined" && tex.c2refcount > 1)
  3008. {
  3009. tex.c2refcount--;
  3010. return;
  3011. }
  3012. this.endBatch();
  3013. if (tex === this.lastTexture0)
  3014. {
  3015. this.gl.bindTexture(this.gl.TEXTURE_2D, null);
  3016. this.lastTexture0 = null;
  3017. }
  3018. if (tex === this.lastTexture1)
  3019. {
  3020. this.gl.activeTexture(this.gl.TEXTURE1);
  3021. this.gl.bindTexture(this.gl.TEXTURE_2D, null);
  3022. this.gl.activeTexture(this.gl.TEXTURE0);
  3023. this.lastTexture1 = null;
  3024. }
  3025. cr.arrayFindRemove(all_textures, tex);
  3026. if (typeof tex.c2texkey !== "undefined")
  3027. delete textures_by_src[tex.c2texkey];
  3028. this.gl.deleteTexture(tex);
  3029. };
  3030. GLWrap_.prototype.estimateVRAM = function ()
  3031. {
  3032. var total = this.width * this.height * 4 * 2;
  3033. var i, len, t;
  3034. for (i = 0, len = all_textures.length; i < len; i++)
  3035. {
  3036. t = all_textures[i];
  3037. total += (t.c2width * t.c2height * 4);
  3038. }
  3039. return total;
  3040. };
  3041. GLWrap_.prototype.textureCount = function ()
  3042. {
  3043. return all_textures.length;
  3044. };
  3045. GLWrap_.prototype.setRenderingToTexture = function (tex)
  3046. {
  3047. if (tex === this.renderToTex)
  3048. return;
  3049. ;
  3050. var b = this.pushBatch();
  3051. b.type = BATCH_RENDERTOTEXTURE;
  3052. b.texParam = tex;
  3053. this.renderToTex = tex;
  3054. this.hasQuadBatchTop = false;
  3055. this.hasPointBatchTop = false;
  3056. };
  3057. cr.GLWrap = GLWrap_;
  3058. }());
  3059. ;
  3060. (function()
  3061. {
  3062. function window_innerWidth()
  3063. {
  3064. if (typeof jQuery !== "undefined")
  3065. return jQuery(window).width();
  3066. else
  3067. return window.innerWidth;
  3068. };
  3069. function window_innerHeight()
  3070. {
  3071. if (typeof jQuery !== "undefined")
  3072. return jQuery(window).height();
  3073. else
  3074. return window.innerHeight;
  3075. };
  3076. function Runtime(canvas)
  3077. {
  3078. if (!canvas || (!canvas.getContext && !canvas["dc"]))
  3079. return;
  3080. if (canvas["c2runtime"])
  3081. return;
  3082. else
  3083. canvas["c2runtime"] = this;
  3084. var self = this;
  3085. this.isCrosswalk = /crosswalk/i.test(navigator.userAgent) || /xwalk/i.test(navigator.userAgent) || !!(typeof window["c2isCrosswalk"] !== "undefined" && window["c2isCrosswalk"]);
  3086. this.isCordova = this.isCrosswalk || (typeof window["device"] !== "undefined" && (typeof window["device"]["cordova"] !== "undefined" || typeof window["device"]["phonegap"] !== "undefined")) || (typeof window["c2iscordova"] !== "undefined" && window["c2iscordova"]);
  3087. this.isPhoneGap = this.isCordova;
  3088. this.isDirectCanvas = !!canvas["dc"];
  3089. this.isAppMobi = (typeof window["AppMobi"] !== "undefined" || this.isDirectCanvas);
  3090. this.isCocoonJs = !!window["c2cocoonjs"];
  3091. this.isEjecta = !!window["c2ejecta"];
  3092. if (this.isCocoonJs)
  3093. {
  3094. CocoonJS["App"]["onSuspended"].addEventListener(function() {
  3095. self["setSuspended"](true);
  3096. });
  3097. CocoonJS["App"]["onActivated"].addEventListener(function () {
  3098. self["setSuspended"](false);
  3099. });
  3100. }
  3101. if (this.isEjecta)
  3102. {
  3103. document.addEventListener("pagehide", function() {
  3104. self["setSuspended"](true);
  3105. });
  3106. document.addEventListener("pageshow", function() {
  3107. self["setSuspended"](false);
  3108. });
  3109. document.addEventListener("resize", function () {
  3110. self["setSize"](window.innerWidth, window.innerHeight);
  3111. });
  3112. }
  3113. this.isDomFree = (this.isDirectCanvas || this.isCocoonJs || this.isEjecta);
  3114. this.isIE = /msie/i.test(navigator.userAgent) || /trident/i.test(navigator.userAgent) || /iemobile/i.test(navigator.userAgent) || /edge\//i.test(navigator.userAgent);
  3115. this.isTizen = /tizen/i.test(navigator.userAgent);
  3116. this.isAndroid = /android/i.test(navigator.userAgent) && !this.isTizen && !this.isIE; // IE mobile and Tizen masquerade as Android
  3117. this.isiPhone = (/iphone/i.test(navigator.userAgent) || /ipod/i.test(navigator.userAgent)) && !this.isIE; // treat ipod as an iphone; IE mobile masquerades as iPhone
  3118. this.isiPad = /ipad/i.test(navigator.userAgent);
  3119. this.isiOS = this.isiPhone || this.isiPad || this.isEjecta;
  3120. this.isiPhoneiOS6 = (this.isiPhone && /os\s6/i.test(navigator.userAgent));
  3121. this.isChrome = (/chrome/i.test(navigator.userAgent) || /chromium/i.test(navigator.userAgent)) && !this.isIE; // note true on Chromium-based webview on Android 4.4+; IE 'Edge' mode also pretends to be Chrome
  3122. this.isAmazonWebApp = /amazonwebappplatform/i.test(navigator.userAgent);
  3123. this.isFirefox = /firefox/i.test(navigator.userAgent);
  3124. this.isSafari = /safari/i.test(navigator.userAgent) && !this.isChrome && !this.isIE; // Chrome and IE Mobile masquerade as Safari
  3125. this.isWindows = /windows/i.test(navigator.userAgent);
  3126. this.isNWjs = (typeof window["c2nodewebkit"] !== "undefined" || typeof window["c2nwjs"] !== "undefined" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent));
  3127. this.isNodeWebkit = this.isNWjs; // old name for backwards compat
  3128. this.isArcade = (typeof window["is_scirra_arcade"] !== "undefined");
  3129. this.isWindows8App = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
  3130. this.isWindows8Capable = !!(typeof window["c2isWindows8Capable"] !== "undefined" && window["c2isWindows8Capable"]);
  3131. this.isWindowsPhone8 = !!(typeof window["c2isWindowsPhone8"] !== "undefined" && window["c2isWindowsPhone8"]);
  3132. this.isWindowsPhone81 = !!(typeof window["c2isWindowsPhone81"] !== "undefined" && window["c2isWindowsPhone81"]);
  3133. this.isWinJS = (this.isWindows8App || this.isWindows8Capable || this.isWindowsPhone81); // note not WP8.0
  3134. this.isBlackberry10 = !!(typeof window["c2isBlackberry10"] !== "undefined" && window["c2isBlackberry10"]);
  3135. this.isAndroidStockBrowser = (this.isAndroid && !this.isChrome && !this.isCrosswalk && !this.isFirefox && !this.isAmazonWebApp && !this.isDomFree);
  3136. this.devicePixelRatio = 1;
  3137. this.isMobile = (this.isCordova || this.isCrosswalk || this.isAppMobi || this.isCocoonJs || this.isAndroid || this.isiOS || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isBlackberry10 || this.isTizen || this.isEjecta);
  3138. if (!this.isMobile)
  3139. {
  3140. this.isMobile = /(blackberry|bb10|playbook|palm|symbian|nokia|windows\s+ce|phone|mobile|tablet|kindle|silk)/i.test(navigator.userAgent);
  3141. }
  3142. if (typeof cr_is_preview !== "undefined" && !this.isNWjs && (window.location.search === "?nw" || /nodewebkit/i.test(navigator.userAgent) || /nwjs/i.test(navigator.userAgent)))
  3143. {
  3144. this.isNWjs = true;
  3145. }
  3146. this.isDebug = (typeof cr_is_preview !== "undefined" && window.location.search.indexOf("debug") > -1);
  3147. this.canvas = canvas;
  3148. this.canvasdiv = document.getElementById("c2canvasdiv");
  3149. this.gl = null;
  3150. this.glwrap = null;
  3151. this.glUnmaskedRenderer = "(unavailable)";
  3152. this.ctx = null;
  3153. this.fullscreenOldMarginCss = "";
  3154. this.firstInFullscreen = false;
  3155. this.oldWidth = 0; // for restoring non-fullscreen canvas after fullscreen
  3156. this.oldHeight = 0;
  3157. this.canvas.oncontextmenu = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
  3158. this.canvas.onselectstart = function (e) { if (e.preventDefault) e.preventDefault(); return false; };
  3159. if (this.isDirectCanvas)
  3160. window["c2runtime"] = this;
  3161. if (this.isNWjs)
  3162. {
  3163. window["ondragover"] = function(e) { e.preventDefault(); return false; };
  3164. window["ondrop"] = function(e) { e.preventDefault(); return false; };
  3165. require("nw.gui")["App"]["clearCache"]();
  3166. }
  3167. if (this.isAndroidStockBrowser && typeof jQuery !== "undefined")
  3168. {
  3169. jQuery("canvas").parents("*").css("overflow", "visible");
  3170. }
  3171. this.width = canvas.width;
  3172. this.height = canvas.height;
  3173. this.draw_width = this.width;
  3174. this.draw_height = this.height;
  3175. this.cssWidth = this.width;
  3176. this.cssHeight = this.height;
  3177. this.lastWindowWidth = window.innerWidth;
  3178. this.lastWindowHeight = window.innerHeight;
  3179. this.forceCanvasAlpha = false; // allow plugins to force the canvas to display with alpha channel
  3180. this.redraw = true;
  3181. this.isSuspended = false;
  3182. if (!Date.now) {
  3183. Date.now = function now() {
  3184. return +new Date();
  3185. };
  3186. }
  3187. this.plugins = [];
  3188. this.types = {};
  3189. this.types_by_index = [];
  3190. this.behaviors = [];
  3191. this.layouts = {};
  3192. this.layouts_by_index = [];
  3193. this.eventsheets = {};
  3194. this.eventsheets_by_index = [];
  3195. this.wait_for_textures = []; // for blocking until textures loaded
  3196. this.triggers_to_postinit = [];
  3197. this.all_global_vars = [];
  3198. this.all_local_vars = [];
  3199. this.solidBehavior = null;
  3200. this.jumpthruBehavior = null;
  3201. this.shadowcasterBehavior = null;
  3202. this.deathRow = {};
  3203. this.hasPendingInstances = false; // true if anything exists in create row or death row
  3204. this.isInClearDeathRow = false;
  3205. this.isInOnDestroy = 0; // needs to support recursion so increments and decrements and is true if > 0
  3206. this.isRunningEvents = false;
  3207. this.createRow = [];
  3208. this.isLoadingState = false;
  3209. this.saveToSlot = "";
  3210. this.loadFromSlot = "";
  3211. this.loadFromJson = "";
  3212. this.lastSaveJson = "";
  3213. this.signalledContinuousPreview = false;
  3214. this.suspendDrawing = false; // for hiding display until continuous preview loads
  3215. this.dt = 0;
  3216. this.dt1 = 0;
  3217. this.logictime = 0; // used to calculate CPUUtilisation
  3218. this.cpuutilisation = 0;
  3219. this.timescale = 1.0;
  3220. this.kahanTime = new cr.KahanAdder();
  3221. this.wallTime = new cr.KahanAdder();
  3222. this.last_tick_time = 0;
  3223. this.fps = 0;
  3224. this.last_fps_time = 0;
  3225. this.tickcount = 0;
  3226. this.execcount = 0;
  3227. this.framecount = 0; // for fps
  3228. this.objectcount = 0;
  3229. this.changelayout = null;
  3230. this.destroycallbacks = [];
  3231. this.event_stack = [];
  3232. this.event_stack_index = -1;
  3233. this.localvar_stack = [[]];
  3234. this.localvar_stack_index = 0;
  3235. this.trigger_depth = 0; // recursion depth for triggers
  3236. this.pushEventStack(null);
  3237. this.loop_stack = [];
  3238. this.loop_stack_index = -1;
  3239. this.next_uid = 0;
  3240. this.next_puid = 0; // permanent unique ids
  3241. this.layout_first_tick = true;
  3242. this.family_count = 0;
  3243. this.suspend_events = [];
  3244. this.raf_id = -1;
  3245. this.timeout_id = -1;
  3246. this.isloading = true;
  3247. this.loadingprogress = 0;
  3248. this.isNodeFullscreen = false;
  3249. this.stackLocalCount = 0; // number of stack-based local vars for recursion
  3250. this.audioInstance = null;
  3251. this.had_a_click = false;
  3252. this.isInUserInputEvent = false;
  3253. this.objects_to_pretick = new cr.ObjectSet();
  3254. this.objects_to_tick = new cr.ObjectSet();
  3255. this.objects_to_tick2 = new cr.ObjectSet();
  3256. this.registered_collisions = [];
  3257. this.temp_poly = new cr.CollisionPoly([]);
  3258. this.temp_poly2 = new cr.CollisionPoly([]);
  3259. this.allGroups = []; // array of all event groups
  3260. this.groups_by_name = {};
  3261. this.cndsBySid = {};
  3262. this.actsBySid = {};
  3263. this.varsBySid = {};
  3264. this.blocksBySid = {};
  3265. this.running_layout = null; // currently running layout
  3266. this.layer_canvas = null; // for layers "render-to-texture"
  3267. this.layer_ctx = null;
  3268. this.layer_tex = null;
  3269. this.layout_tex = null;
  3270. this.layout_canvas = null;
  3271. this.layout_ctx = null;
  3272. this.is_WebGL_context_lost = false;
  3273. this.uses_background_blending = false; // if any shader uses background blending, so entire layout renders to texture
  3274. this.fx_tex = [null, null];
  3275. this.fullscreen_scaling = 0;
  3276. this.files_subfolder = ""; // path with project files
  3277. this.objectsByUid = {}; // maps every in-use UID (as a string) to its instance
  3278. this.loaderlogo = null;
  3279. this.snapshotCanvas = null;
  3280. this.snapshotData = "";
  3281. this.objectRefTable = [];
  3282. this.requestProjectData();
  3283. };
  3284. Runtime.prototype.requestProjectData = function ()
  3285. {
  3286. var self = this;
  3287. var xhr;
  3288. if (this.isWindowsPhone8)
  3289. xhr = new ActiveXObject("Microsoft.XMLHTTP");
  3290. else
  3291. xhr = new XMLHttpRequest();
  3292. var datajs_filename = "data.js";
  3293. if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81)
  3294. datajs_filename = "data.json";
  3295. xhr.open("GET", datajs_filename, true);
  3296. var supportsJsonResponse = false;
  3297. if (!this.isDomFree && ("response" in xhr) && ("responseType" in xhr))
  3298. {
  3299. try {
  3300. xhr["responseType"] = "json";
  3301. supportsJsonResponse = (xhr["responseType"] === "json");
  3302. }
  3303. catch (e) {
  3304. supportsJsonResponse = false;
  3305. }
  3306. }
  3307. if (!supportsJsonResponse && ("responseType" in xhr))
  3308. {
  3309. try {
  3310. xhr["responseType"] = "text";
  3311. }
  3312. catch (e) {}
  3313. }
  3314. if ("overrideMimeType" in xhr)
  3315. {
  3316. try {
  3317. xhr["overrideMimeType"]("application/json; charset=utf-8");
  3318. }
  3319. catch (e) {}
  3320. }
  3321. if (this.isWindowsPhone8)
  3322. {
  3323. xhr.onreadystatechange = function ()
  3324. {
  3325. if (xhr.readyState !== 4)
  3326. return;
  3327. self.loadProject(JSON.parse(xhr["responseText"]));
  3328. };
  3329. }
  3330. else
  3331. {
  3332. xhr.onload = function ()
  3333. {
  3334. if (supportsJsonResponse)
  3335. {
  3336. self.loadProject(xhr["response"]); // already parsed by browser
  3337. }
  3338. else
  3339. {
  3340. if (self.isEjecta)
  3341. {
  3342. var str = xhr["responseText"];
  3343. str = str.substr(str.indexOf("{")); // trim any BOM
  3344. self.loadProject(JSON.parse(str));
  3345. }
  3346. else
  3347. {
  3348. self.loadProject(JSON.parse(xhr["responseText"])); // forced to sync parse JSON
  3349. }
  3350. }
  3351. };
  3352. xhr.onerror = function (e)
  3353. {
  3354. cr.logerror("Error requesting " + datajs_filename + ":");
  3355. cr.logerror(e);
  3356. };
  3357. }
  3358. xhr.send();
  3359. };
  3360. Runtime.prototype.initRendererAndLoader = function ()
  3361. {
  3362. var self = this;
  3363. var i, len, j, lenj, k, lenk, t, s, l, y;
  3364. this.isRetina = ((!this.isDomFree || this.isEjecta) && this.useHighDpi && !this.isAndroidStockBrowser);
  3365. if (this.fullscreen_mode === 0 && this.isiOS)
  3366. this.isRetina = false;
  3367. this.devicePixelRatio = (this.isRetina ? (window["devicePixelRatio"] || window["webkitDevicePixelRatio"] || window["mozDevicePixelRatio"] || window["msDevicePixelRatio"] || 1) : 1);
  3368. this.ClearDeathRow();
  3369. var attribs;
  3370. var alpha_canvas = !!(this.forceCanvasAlpha || (this.alphaBackground && !(this.isNWjs || this.isWinJS || this.isWindowsPhone8 || this.isCrosswalk || this.isCordova || this.isAmazonWebApp)));
  3371. if (this.fullscreen_mode > 0)
  3372. this["setSize"](window_innerWidth(), window_innerHeight(), true);
  3373. try {
  3374. if (this.enableWebGL && (this.isCocoonJs || this.isEjecta || !this.isDomFree))
  3375. {
  3376. attribs = {
  3377. "alpha": alpha_canvas,
  3378. "depth": false,
  3379. "antialias": false,
  3380. "failIfMajorPerformanceCaveat": true
  3381. };
  3382. this.gl = (this.canvas.getContext("webgl", attribs) || this.canvas.getContext("experimental-webgl", attribs));
  3383. }
  3384. }
  3385. catch (e) {
  3386. }
  3387. if (this.gl)
  3388. {
  3389. var debug_ext = this.gl.getExtension("WEBGL_debug_renderer_info");
  3390. if (debug_ext)
  3391. {
  3392. var unmasked_vendor = this.gl.getParameter(debug_ext.UNMASKED_VENDOR_WEBGL);
  3393. var unmasked_renderer = this.gl.getParameter(debug_ext.UNMASKED_RENDERER_WEBGL);
  3394. this.glUnmaskedRenderer = unmasked_renderer + " [" + unmasked_vendor + "]";
  3395. ;
  3396. }
  3397. else
  3398. {
  3399. ;
  3400. }
  3401. if (!this.isDomFree)
  3402. {
  3403. this.overlay_canvas = document.createElement("canvas");
  3404. jQuery(this.overlay_canvas).appendTo(this.canvas.parentNode);
  3405. this.overlay_canvas.oncontextmenu = function (e) { return false; };
  3406. this.overlay_canvas.onselectstart = function (e) { return false; };
  3407. this.overlay_canvas.width = this.cssWidth;
  3408. this.overlay_canvas.height = this.cssHeight;
  3409. jQuery(this.overlay_canvas).css({"width": this.cssWidth + "px",
  3410. "height": this.cssHeight + "px"});
  3411. this.positionOverlayCanvas();
  3412. this.overlay_ctx = this.overlay_canvas.getContext("2d");
  3413. }
  3414. this.glwrap = new cr.GLWrap(this.gl, this.isMobile);
  3415. this.glwrap.setSize(this.canvas.width, this.canvas.height);
  3416. this.glwrap.enable_mipmaps = (this.downscalingQuality !== 0);
  3417. this.ctx = null;
  3418. this.canvas.addEventListener("webglcontextlost", function (ev) {
  3419. ev.preventDefault();
  3420. self.onContextLost();
  3421. cr.logexport("[Construct 2] WebGL context lost");
  3422. window["cr_setSuspended"](true); // stop rendering
  3423. }, false);
  3424. this.canvas.addEventListener("webglcontextrestored", function (ev) {
  3425. self.glwrap.initState();
  3426. self.glwrap.setSize(self.glwrap.width, self.glwrap.height, true);
  3427. self.layer_tex = null;
  3428. self.layout_tex = null;
  3429. self.fx_tex[0] = null;
  3430. self.fx_tex[1] = null;
  3431. self.onContextRestored();
  3432. self.redraw = true;
  3433. cr.logexport("[Construct 2] WebGL context restored");
  3434. window["cr_setSuspended"](false); // resume rendering
  3435. }, false);
  3436. for (i = 0, len = this.types_by_index.length; i < len; i++)
  3437. {
  3438. t = this.types_by_index[i];
  3439. for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
  3440. {
  3441. s = t.effect_types[j];
  3442. s.shaderindex = this.glwrap.getShaderIndex(s.id);
  3443. this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
  3444. }
  3445. }
  3446. for (i = 0, len = this.layouts_by_index.length; i < len; i++)
  3447. {
  3448. l = this.layouts_by_index[i];
  3449. for (j = 0, lenj = l.effect_types.length; j < lenj; j++)
  3450. {
  3451. s = l.effect_types[j];
  3452. s.shaderindex = this.glwrap.getShaderIndex(s.id);
  3453. }
  3454. for (j = 0, lenj = l.layers.length; j < lenj; j++)
  3455. {
  3456. y = l.layers[j];
  3457. for (k = 0, lenk = y.effect_types.length; k < lenk; k++)
  3458. {
  3459. s = y.effect_types[k];
  3460. s.shaderindex = this.glwrap.getShaderIndex(s.id);
  3461. this.uses_background_blending = this.uses_background_blending || this.glwrap.programUsesDest(s.shaderindex);
  3462. }
  3463. }
  3464. }
  3465. }
  3466. else
  3467. {
  3468. if (this.fullscreen_mode > 0 && this.isDirectCanvas)
  3469. {
  3470. ;
  3471. this.canvas = null;
  3472. document.oncontextmenu = function (e) { return false; };
  3473. document.onselectstart = function (e) { return false; };
  3474. this.ctx = AppMobi["canvas"]["getContext"]("2d");
  3475. try {
  3476. this.ctx["samplingMode"] = this.linearSampling ? "smooth" : "sharp";
  3477. this.ctx["globalScale"] = 1;
  3478. this.ctx["HTML5CompatibilityMode"] = true;
  3479. this.ctx["imageSmoothingEnabled"] = this.linearSampling;
  3480. } catch(e){}
  3481. if (this.width !== 0 && this.height !== 0)
  3482. {
  3483. this.ctx.width = this.width;
  3484. this.ctx.height = this.height;
  3485. }
  3486. }
  3487. if (!this.ctx)
  3488. {
  3489. ;
  3490. if (this.isCocoonJs)
  3491. {
  3492. attribs = {
  3493. "antialias": !!this.linearSampling,
  3494. "alpha": alpha_canvas
  3495. };
  3496. this.ctx = this.canvas.getContext("2d", attribs);
  3497. }
  3498. else
  3499. {
  3500. attribs = {
  3501. "alpha": alpha_canvas
  3502. };
  3503. this.ctx = this.canvas.getContext("2d", attribs);
  3504. }
  3505. this.ctx["webkitImageSmoothingEnabled"] = this.linearSampling;
  3506. this.ctx["mozImageSmoothingEnabled"] = this.linearSampling;
  3507. this.ctx["msImageSmoothingEnabled"] = this.linearSampling;
  3508. this.ctx["imageSmoothingEnabled"] = this.linearSampling;
  3509. }
  3510. this.overlay_canvas = null;
  3511. this.overlay_ctx = null;
  3512. }
  3513. this.tickFunc = function (timestamp) { self.tick(false, timestamp); };
  3514. if (window != window.top && !this.isDomFree && !this.isWinJS && !this.isWindowsPhone8)
  3515. {
  3516. document.addEventListener("mousedown", function () {
  3517. window.focus();
  3518. }, true);
  3519. document.addEventListener("touchstart", function () {
  3520. window.focus();
  3521. }, true);
  3522. }
  3523. if (typeof cr_is_preview !== "undefined")
  3524. {
  3525. if (this.isCocoonJs)
  3526. console.log("[Construct 2] In preview-over-wifi via CocoonJS mode");
  3527. if (window.location.search.indexOf("continuous") > -1)
  3528. {
  3529. cr.logexport("Reloading for continuous preview");
  3530. this.loadFromSlot = "__c2_continuouspreview";
  3531. this.suspendDrawing = true;
  3532. }
  3533. if (this.pauseOnBlur && !this.isMobile)
  3534. {
  3535. jQuery(window).focus(function ()
  3536. {
  3537. self["setSuspended"](false);
  3538. });
  3539. jQuery(window).blur(function ()
  3540. {
  3541. self["setSuspended"](true);
  3542. });
  3543. }
  3544. }
  3545. if (!this.isDomFree)
  3546. {
  3547. var unfocusFormControlFunc = function (e) {
  3548. if (cr.isCanvasInputEvent(e) && document["activeElement"] && document["activeElement"] !== document.getElementsByTagName("body")[0] && document["activeElement"].blur)
  3549. {
  3550. try {
  3551. document["activeElement"].blur();
  3552. }
  3553. catch (e) {}
  3554. }
  3555. }
  3556. if (window.navigator["pointerEnabled"])
  3557. {
  3558. document.addEventListener("pointerdown", unfocusFormControlFunc);
  3559. }
  3560. else if (window.navigator["msPointerEnabled"])
  3561. {
  3562. document.addEventListener("MSPointerDown", unfocusFormControlFunc);
  3563. }
  3564. else
  3565. {
  3566. document.addEventListener("touchstart", unfocusFormControlFunc);
  3567. }
  3568. document.addEventListener("mousedown", unfocusFormControlFunc);
  3569. }
  3570. if (this.fullscreen_mode === 0 && this.isRetina && this.devicePixelRatio > 1)
  3571. {
  3572. this["setSize"](this.original_width, this.original_height, true);
  3573. }
  3574. this.tryLockOrientation();
  3575. this.getready(); // determine things to preload
  3576. this.go(); // run loading screen
  3577. this.extra = {};
  3578. cr.seal(this);
  3579. };
  3580. var webkitRepaintFlag = false;
  3581. Runtime.prototype["setSize"] = function (w, h, force)
  3582. {
  3583. var offx = 0, offy = 0;
  3584. var neww = 0, newh = 0, intscale = 0;
  3585. var tryHideAddressBar = (this.isiPhoneiOS6 && this.isSafari && !navigator["standalone"] && !this.isDomFree && !this.isCordova);
  3586. if (tryHideAddressBar)
  3587. h += 60; // height of Safari iPhone iOS 6 address bar
  3588. if (this.lastWindowWidth === w && this.lastWindowHeight === h && !force)
  3589. return;
  3590. this.lastWindowWidth = w;
  3591. this.lastWindowHeight = h;
  3592. var mode = this.fullscreen_mode;
  3593. var orig_aspect, cur_aspect;
  3594. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen) && !this.isCordova;
  3595. if (!isfullscreen && this.fullscreen_mode === 0 && !force)
  3596. return; // ignore size events when not fullscreen and not using a fullscreen-in-browser mode
  3597. if (isfullscreen && this.fullscreen_scaling > 0)
  3598. mode = this.fullscreen_scaling;
  3599. var dpr = this.devicePixelRatio;
  3600. if (mode >= 4)
  3601. {
  3602. orig_aspect = this.original_width / this.original_height;
  3603. cur_aspect = w / h;
  3604. if (cur_aspect > orig_aspect)
  3605. {
  3606. neww = h * orig_aspect;
  3607. if (mode === 5) // integer scaling
  3608. {
  3609. intscale = (neww * dpr) / this.original_width;
  3610. if (intscale > 1)
  3611. intscale = Math.floor(intscale);
  3612. else if (intscale < 1)
  3613. intscale = 1 / Math.ceil(1 / intscale);
  3614. neww = this.original_width * intscale / dpr;
  3615. newh = this.original_height * intscale / dpr;
  3616. offx = (w - neww) / 2;
  3617. offy = (h - newh) / 2;
  3618. w = neww;
  3619. h = newh;
  3620. }
  3621. else
  3622. {
  3623. offx = (w - neww) / 2;
  3624. w = neww;
  3625. }
  3626. }
  3627. else
  3628. {
  3629. newh = w / orig_aspect;
  3630. if (mode === 5) // integer scaling
  3631. {
  3632. intscale = (newh * dpr) / this.original_height;
  3633. if (intscale > 1)
  3634. intscale = Math.floor(intscale);
  3635. else if (intscale < 1)
  3636. intscale = 1 / Math.ceil(1 / intscale);
  3637. neww = this.original_width * intscale / dpr;
  3638. newh = this.original_height * intscale / dpr;
  3639. offx = (w - neww) / 2;
  3640. offy = (h - newh) / 2;
  3641. w = neww;
  3642. h = newh;
  3643. }
  3644. else
  3645. {
  3646. offy = (h - newh) / 2;
  3647. h = newh;
  3648. }
  3649. }
  3650. if (isfullscreen && !this.isNWjs)
  3651. {
  3652. offx = 0;
  3653. offy = 0;
  3654. }
  3655. }
  3656. else if (this.isNWjs && this.isNodeFullscreen && this.fullscreen_mode_set === 0)
  3657. {
  3658. offx = Math.floor((w - this.original_width) / 2);
  3659. offy = Math.floor((h - this.original_height) / 2);
  3660. w = this.original_width;
  3661. h = this.original_height;
  3662. }
  3663. if (mode < 2)
  3664. this.aspect_scale = dpr;
  3665. if (this.isRetina && this.isiPad && dpr > 1) // don't apply to iPad 1-2
  3666. {
  3667. if (w >= 1024)
  3668. w = 1023; // 2046 retina pixels
  3669. if (h >= 1024)
  3670. h = 1023;
  3671. }
  3672. this.cssWidth = Math.round(w);
  3673. this.cssHeight = Math.round(h);
  3674. this.width = Math.round(w * dpr);
  3675. this.height = Math.round(h * dpr);
  3676. this.redraw = true;
  3677. if (this.wantFullscreenScalingQuality)
  3678. {
  3679. this.draw_width = this.width;
  3680. this.draw_height = this.height;
  3681. this.fullscreenScalingQuality = true;
  3682. }
  3683. else
  3684. {
  3685. if ((this.width < this.original_width && this.height < this.original_height) || mode === 1)
  3686. {
  3687. this.draw_width = this.width;
  3688. this.draw_height = this.height;
  3689. this.fullscreenScalingQuality = true;
  3690. }
  3691. else
  3692. {
  3693. this.draw_width = this.original_width;
  3694. this.draw_height = this.original_height;
  3695. this.fullscreenScalingQuality = false;
  3696. /*var orig_aspect = this.original_width / this.original_height;
  3697. var cur_aspect = this.width / this.height;
  3698. if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
  3699. this.aspect_scale = this.height / this.original_height;
  3700. else
  3701. this.aspect_scale = this.width / this.original_width;*/
  3702. if (mode === 2) // scale inner
  3703. {
  3704. orig_aspect = this.original_width / this.original_height;
  3705. cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
  3706. if (cur_aspect < orig_aspect)
  3707. this.draw_width = this.draw_height * cur_aspect;
  3708. else if (cur_aspect > orig_aspect)
  3709. this.draw_height = this.draw_width / cur_aspect;
  3710. }
  3711. else if (mode === 3)
  3712. {
  3713. orig_aspect = this.original_width / this.original_height;
  3714. cur_aspect = this.lastWindowWidth / this.lastWindowHeight;
  3715. if (cur_aspect > orig_aspect)
  3716. this.draw_width = this.draw_height * cur_aspect;
  3717. else if (cur_aspect < orig_aspect)
  3718. this.draw_height = this.draw_width / cur_aspect;
  3719. }
  3720. }
  3721. }
  3722. if (this.canvasdiv && !this.isDomFree)
  3723. {
  3724. jQuery(this.canvasdiv).css({"width": Math.round(w) + "px",
  3725. "height": Math.round(h) + "px",
  3726. "margin-left": Math.floor(offx) + "px",
  3727. "margin-top": Math.floor(offy) + "px"});
  3728. if (typeof cr_is_preview !== "undefined")
  3729. {
  3730. jQuery("#borderwrap").css({"width": Math.round(w) + "px",
  3731. "height": Math.round(h) + "px"});
  3732. }
  3733. }
  3734. if (this.canvas)
  3735. {
  3736. this.canvas.width = Math.round(w * dpr);
  3737. this.canvas.height = Math.round(h * dpr);
  3738. if (this.isEjecta)
  3739. {
  3740. this.canvas.style.left = Math.floor(offx) + "px";
  3741. this.canvas.style.top = Math.floor(offy) + "px";
  3742. this.canvas.style.width = Math.round(w) + "px";
  3743. this.canvas.style.height = Math.round(h) + "px";
  3744. }
  3745. else if (this.isRetina && !this.isDomFree)
  3746. {
  3747. this.canvas.style.width = Math.round(w) + "px";
  3748. this.canvas.style.height = Math.round(h) + "px";
  3749. }
  3750. }
  3751. if (this.overlay_canvas)
  3752. {
  3753. this.overlay_canvas.width = Math.round(w);
  3754. this.overlay_canvas.height = Math.round(h);
  3755. this.overlay_canvas.style.width = Math.round(w) + "px";
  3756. this.overlay_canvas.style.height = Math.round(h) + "px";
  3757. }
  3758. if (this.glwrap)
  3759. {
  3760. this.glwrap.setSize(Math.round(w * dpr), Math.round(h * dpr));
  3761. }
  3762. if (this.isDirectCanvas && this.ctx)
  3763. {
  3764. this.ctx.width = Math.round(w);
  3765. this.ctx.height = Math.round(h);
  3766. }
  3767. if (this.ctx)
  3768. {
  3769. this.ctx["webkitImageSmoothingEnabled"] = this.linearSampling;
  3770. this.ctx["mozImageSmoothingEnabled"] = this.linearSampling;
  3771. this.ctx["msImageSmoothingEnabled"] = this.linearSampling;
  3772. this.ctx["imageSmoothingEnabled"] = this.linearSampling;
  3773. }
  3774. this.tryLockOrientation();
  3775. if (!this.isDomFree && (tryHideAddressBar || this.isiPhone))
  3776. {
  3777. window.setTimeout(function () {
  3778. window.scrollTo(0, 1);
  3779. }, 100);
  3780. }
  3781. };
  3782. Runtime.prototype.tryLockOrientation = function ()
  3783. {
  3784. if (!this.autoLockOrientation || this.orientations === 0)
  3785. return;
  3786. var orientation = "portrait";
  3787. if (this.orientations === 2)
  3788. orientation = "landscape";
  3789. if (screen["orientation"] && screen["orientation"]["lock"])
  3790. screen["orientation"]["lock"](orientation);
  3791. else if (screen["lockOrientation"])
  3792. screen["lockOrientation"](orientation);
  3793. else if (screen["webkitLockOrientation"])
  3794. screen["webkitLockOrientation"](orientation);
  3795. else if (screen["mozLockOrientation"])
  3796. screen["mozLockOrientation"](orientation);
  3797. else if (screen["msLockOrientation"])
  3798. screen["msLockOrientation"](orientation);
  3799. };
  3800. Runtime.prototype.onContextLost = function ()
  3801. {
  3802. this.glwrap.contextLost();
  3803. this.is_WebGL_context_lost = true;
  3804. var i, len, t;
  3805. for (i = 0, len = this.types_by_index.length; i < len; i++)
  3806. {
  3807. t = this.types_by_index[i];
  3808. if (t.onLostWebGLContext)
  3809. t.onLostWebGLContext();
  3810. }
  3811. };
  3812. Runtime.prototype.onContextRestored = function ()
  3813. {
  3814. this.is_WebGL_context_lost = false;
  3815. var i, len, t;
  3816. for (i = 0, len = this.types_by_index.length; i < len; i++)
  3817. {
  3818. t = this.types_by_index[i];
  3819. if (t.onRestoreWebGLContext)
  3820. t.onRestoreWebGLContext();
  3821. }
  3822. };
  3823. Runtime.prototype.positionOverlayCanvas = function()
  3824. {
  3825. if (this.isDomFree)
  3826. return;
  3827. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
  3828. var overlay_position = isfullscreen ? jQuery(this.canvas).offset() : jQuery(this.canvas).position();
  3829. overlay_position.position = "absolute";
  3830. jQuery(this.overlay_canvas).css(overlay_position);
  3831. };
  3832. var caf = window["cancelAnimationFrame"] ||
  3833. window["mozCancelAnimationFrame"] ||
  3834. window["webkitCancelAnimationFrame"] ||
  3835. window["msCancelAnimationFrame"] ||
  3836. window["oCancelAnimationFrame"];
  3837. Runtime.prototype["setSuspended"] = function (s)
  3838. {
  3839. var i, len;
  3840. if (s && !this.isSuspended)
  3841. {
  3842. cr.logexport("[Construct 2] Suspending");
  3843. this.isSuspended = true; // next tick will be last
  3844. if (this.raf_id !== -1 && caf) // note: CocoonJS does not implement cancelAnimationFrame
  3845. caf(this.raf_id);
  3846. if (this.timeout_id !== -1)
  3847. clearTimeout(this.timeout_id);
  3848. for (i = 0, len = this.suspend_events.length; i < len; i++)
  3849. this.suspend_events[i](true);
  3850. }
  3851. else if (!s && this.isSuspended)
  3852. {
  3853. cr.logexport("[Construct 2] Resuming");
  3854. this.isSuspended = false;
  3855. this.last_tick_time = cr.performance_now(); // ensure first tick is a zero-dt one
  3856. this.last_fps_time = cr.performance_now(); // reset FPS counter
  3857. this.framecount = 0;
  3858. this.logictime = 0;
  3859. for (i = 0, len = this.suspend_events.length; i < len; i++)
  3860. this.suspend_events[i](false);
  3861. this.tick(false); // kick off runtime again
  3862. }
  3863. };
  3864. Runtime.prototype.addSuspendCallback = function (f)
  3865. {
  3866. this.suspend_events.push(f);
  3867. };
  3868. Runtime.prototype.GetObjectReference = function (i)
  3869. {
  3870. ;
  3871. return this.objectRefTable[i];
  3872. };
  3873. Runtime.prototype.loadProject = function (data_response)
  3874. {
  3875. ;
  3876. if (!data_response || !data_response["project"])
  3877. cr.logerror("Project model unavailable");
  3878. var pm = data_response["project"];
  3879. this.name = pm[0];
  3880. this.first_layout = pm[1];
  3881. this.fullscreen_mode = pm[12]; // 0 = off, 1 = crop, 2 = scale inner, 3 = scale outer, 4 = letterbox scale, 5 = integer letterbox scale
  3882. this.fullscreen_mode_set = pm[12];
  3883. this.original_width = pm[10];
  3884. this.original_height = pm[11];
  3885. this.parallax_x_origin = this.original_width / 2;
  3886. this.parallax_y_origin = this.original_height / 2;
  3887. if (this.isDomFree && !this.isEjecta && (pm[12] >= 4 || pm[12] === 0))
  3888. {
  3889. cr.logexport("[Construct 2] Letterbox scale fullscreen modes are not supported on this platform - falling back to 'Scale outer'");
  3890. this.fullscreen_mode = 3;
  3891. this.fullscreen_mode_set = 3;
  3892. }
  3893. this.uses_loader_layout = pm[18];
  3894. this.loaderstyle = pm[19];
  3895. if (this.loaderstyle === 0)
  3896. {
  3897. this.loaderlogo = new Image();
  3898. this.loaderlogo.crossOrigin = "anonymous";
  3899. this.loaderlogo.src = "loading-logo.png";
  3900. }
  3901. this.next_uid = pm[21];
  3902. this.objectRefTable = cr.getObjectRefTable();
  3903. this.system = new cr.system_object(this);
  3904. var i, len, j, lenj, k, lenk, idstr, m, b, t, f, p;
  3905. var plugin, plugin_ctor;
  3906. for (i = 0, len = pm[2].length; i < len; i++)
  3907. {
  3908. m = pm[2][i];
  3909. p = this.GetObjectReference(m[0]);
  3910. ;
  3911. cr.add_common_aces(m, p.prototype);
  3912. plugin = new p(this);
  3913. plugin.singleglobal = m[1];
  3914. plugin.is_world = m[2];
  3915. plugin.must_predraw = m[9];
  3916. if (plugin.onCreate)
  3917. plugin.onCreate(); // opportunity to override default ACEs
  3918. cr.seal(plugin);
  3919. this.plugins.push(plugin);
  3920. }
  3921. this.objectRefTable = cr.getObjectRefTable();
  3922. for (i = 0, len = pm[3].length; i < len; i++)
  3923. {
  3924. m = pm[3][i];
  3925. plugin_ctor = this.GetObjectReference(m[1]);
  3926. ;
  3927. plugin = null;
  3928. for (j = 0, lenj = this.plugins.length; j < lenj; j++)
  3929. {
  3930. if (this.plugins[j] instanceof plugin_ctor)
  3931. {
  3932. plugin = this.plugins[j];
  3933. break;
  3934. }
  3935. }
  3936. ;
  3937. ;
  3938. var type_inst = new plugin.Type(plugin);
  3939. ;
  3940. type_inst.name = m[0];
  3941. type_inst.is_family = m[2];
  3942. type_inst.instvar_sids = m[3].slice(0);
  3943. type_inst.vars_count = m[3].length;
  3944. type_inst.behs_count = m[4];
  3945. type_inst.fx_count = m[5];
  3946. type_inst.sid = m[11];
  3947. if (type_inst.is_family)
  3948. {
  3949. type_inst.members = []; // types in this family
  3950. type_inst.family_index = this.family_count++;
  3951. type_inst.families = null;
  3952. }
  3953. else
  3954. {
  3955. type_inst.members = null;
  3956. type_inst.family_index = -1;
  3957. type_inst.families = []; // families this type belongs to
  3958. }
  3959. type_inst.family_var_map = null;
  3960. type_inst.family_beh_map = null;
  3961. type_inst.family_fx_map = null;
  3962. type_inst.is_contained = false;
  3963. type_inst.container = null;
  3964. if (m[6])
  3965. {
  3966. type_inst.texture_file = m[6][0];
  3967. type_inst.texture_filesize = m[6][1];
  3968. type_inst.texture_pixelformat = m[6][2];
  3969. }
  3970. else
  3971. {
  3972. type_inst.texture_file = null;
  3973. type_inst.texture_filesize = 0;
  3974. type_inst.texture_pixelformat = 0; // rgba8
  3975. }
  3976. if (m[7])
  3977. {
  3978. type_inst.animations = m[7];
  3979. }
  3980. else
  3981. {
  3982. type_inst.animations = null;
  3983. }
  3984. type_inst.index = i; // save index in to types array in type
  3985. type_inst.instances = []; // all instances of this type
  3986. type_inst.deadCache = []; // destroyed instances to recycle next create
  3987. type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL
  3988. type_inst.cur_sol = 0;
  3989. type_inst.default_instance = null;
  3990. type_inst.default_layerindex = 0;
  3991. type_inst.stale_iids = true;
  3992. type_inst.updateIIDs = cr.type_updateIIDs;
  3993. type_inst.getFirstPicked = cr.type_getFirstPicked;
  3994. type_inst.getPairedInstance = cr.type_getPairedInstance;
  3995. type_inst.getCurrentSol = cr.type_getCurrentSol;
  3996. type_inst.pushCleanSol = cr.type_pushCleanSol;
  3997. type_inst.pushCopySol = cr.type_pushCopySol;
  3998. type_inst.popSol = cr.type_popSol;
  3999. type_inst.getBehaviorByName = cr.type_getBehaviorByName;
  4000. type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName;
  4001. type_inst.getEffectIndexByName = cr.type_getEffectIndexByName;
  4002. type_inst.applySolToContainer = cr.type_applySolToContainer;
  4003. type_inst.getInstanceByIID = cr.type_getInstanceByIID;
  4004. type_inst.collision_grid = new cr.SparseGrid(this.original_width, this.original_height);
  4005. type_inst.any_cell_changed = true;
  4006. type_inst.any_instance_parallaxed = false;
  4007. type_inst.extra = {};
  4008. type_inst.toString = cr.type_toString;
  4009. type_inst.behaviors = [];
  4010. for (j = 0, lenj = m[8].length; j < lenj; j++)
  4011. {
  4012. b = m[8][j];
  4013. var behavior_ctor = this.GetObjectReference(b[1]);
  4014. var behavior_plugin = null;
  4015. for (k = 0, lenk = this.behaviors.length; k < lenk; k++)
  4016. {
  4017. if (this.behaviors[k] instanceof behavior_ctor)
  4018. {
  4019. behavior_plugin = this.behaviors[k];
  4020. break;
  4021. }
  4022. }
  4023. if (!behavior_plugin)
  4024. {
  4025. behavior_plugin = new behavior_ctor(this);
  4026. behavior_plugin.my_types = []; // types using this behavior
  4027. behavior_plugin.my_instances = new cr.ObjectSet(); // instances of this behavior
  4028. if (behavior_plugin.onCreate)
  4029. behavior_plugin.onCreate();
  4030. cr.seal(behavior_plugin);
  4031. this.behaviors.push(behavior_plugin);
  4032. if (cr.behaviors.solid && behavior_plugin instanceof cr.behaviors.solid)
  4033. this.solidBehavior = behavior_plugin;
  4034. if (cr.behaviors.jumpthru && behavior_plugin instanceof cr.behaviors.jumpthru)
  4035. this.jumpthruBehavior = behavior_plugin;
  4036. if (cr.behaviors.shadowcaster && behavior_plugin instanceof cr.behaviors.shadowcaster)
  4037. this.shadowcasterBehavior = behavior_plugin;
  4038. }
  4039. if (behavior_plugin.my_types.indexOf(type_inst) === -1)
  4040. behavior_plugin.my_types.push(type_inst);
  4041. var behavior_type = new behavior_plugin.Type(behavior_plugin, type_inst);
  4042. behavior_type.name = b[0];
  4043. behavior_type.sid = b[2];
  4044. behavior_type.onCreate();
  4045. cr.seal(behavior_type);
  4046. type_inst.behaviors.push(behavior_type);
  4047. }
  4048. type_inst.global = m[9];
  4049. type_inst.isOnLoaderLayout = m[10];
  4050. type_inst.effect_types = [];
  4051. for (j = 0, lenj = m[12].length; j < lenj; j++)
  4052. {
  4053. type_inst.effect_types.push({
  4054. id: m[12][j][0],
  4055. name: m[12][j][1],
  4056. shaderindex: -1,
  4057. active: true,
  4058. index: j
  4059. });
  4060. }
  4061. type_inst.tile_poly_data = m[13];
  4062. if (!this.uses_loader_layout || type_inst.is_family || type_inst.isOnLoaderLayout || !plugin.is_world)
  4063. {
  4064. type_inst.onCreate();
  4065. cr.seal(type_inst);
  4066. }
  4067. if (type_inst.name)
  4068. this.types[type_inst.name] = type_inst;
  4069. this.types_by_index.push(type_inst);
  4070. if (plugin.singleglobal)
  4071. {
  4072. var instance = new plugin.Instance(type_inst);
  4073. instance.uid = this.next_uid++;
  4074. instance.puid = this.next_puid++;
  4075. instance.iid = 0;
  4076. instance.get_iid = cr.inst_get_iid;
  4077. instance.toString = cr.inst_toString;
  4078. instance.properties = m[14];
  4079. instance.onCreate();
  4080. cr.seal(instance);
  4081. type_inst.instances.push(instance);
  4082. this.objectsByUid[instance.uid.toString()] = instance;
  4083. }
  4084. }
  4085. for (i = 0, len = pm[4].length; i < len; i++)
  4086. {
  4087. var familydata = pm[4][i];
  4088. var familytype = this.types_by_index[familydata[0]];
  4089. var familymember;
  4090. for (j = 1, lenj = familydata.length; j < lenj; j++)
  4091. {
  4092. familymember = this.types_by_index[familydata[j]];
  4093. familymember.families.push(familytype);
  4094. familytype.members.push(familymember);
  4095. }
  4096. }
  4097. for (i = 0, len = pm[27].length; i < len; i++)
  4098. {
  4099. var containerdata = pm[27][i];
  4100. var containertypes = [];
  4101. for (j = 0, lenj = containerdata.length; j < lenj; j++)
  4102. containertypes.push(this.types_by_index[containerdata[j]]);
  4103. for (j = 0, lenj = containertypes.length; j < lenj; j++)
  4104. {
  4105. containertypes[j].is_contained = true;
  4106. containertypes[j].container = containertypes;
  4107. }
  4108. }
  4109. if (this.family_count > 0)
  4110. {
  4111. for (i = 0, len = this.types_by_index.length; i < len; i++)
  4112. {
  4113. t = this.types_by_index[i];
  4114. if (t.is_family || !t.families.length)
  4115. continue;
  4116. t.family_var_map = new Array(this.family_count);
  4117. t.family_beh_map = new Array(this.family_count);
  4118. t.family_fx_map = new Array(this.family_count);
  4119. var all_fx = [];
  4120. var varsum = 0;
  4121. var behsum = 0;
  4122. var fxsum = 0;
  4123. for (j = 0, lenj = t.families.length; j < lenj; j++)
  4124. {
  4125. f = t.families[j];
  4126. t.family_var_map[f.family_index] = varsum;
  4127. varsum += f.vars_count;
  4128. t.family_beh_map[f.family_index] = behsum;
  4129. behsum += f.behs_count;
  4130. t.family_fx_map[f.family_index] = fxsum;
  4131. fxsum += f.fx_count;
  4132. for (k = 0, lenk = f.effect_types.length; k < lenk; k++)
  4133. all_fx.push(cr.shallowCopy({}, f.effect_types[k]));
  4134. }
  4135. t.effect_types = all_fx.concat(t.effect_types);
  4136. for (j = 0, lenj = t.effect_types.length; j < lenj; j++)
  4137. t.effect_types[j].index = j;
  4138. }
  4139. }
  4140. for (i = 0, len = pm[5].length; i < len; i++)
  4141. {
  4142. m = pm[5][i];
  4143. var layout = new cr.layout(this, m);
  4144. cr.seal(layout);
  4145. this.layouts[layout.name] = layout;
  4146. this.layouts_by_index.push(layout);
  4147. }
  4148. for (i = 0, len = pm[6].length; i < len; i++)
  4149. {
  4150. m = pm[6][i];
  4151. var sheet = new cr.eventsheet(this, m);
  4152. cr.seal(sheet);
  4153. this.eventsheets[sheet.name] = sheet;
  4154. this.eventsheets_by_index.push(sheet);
  4155. }
  4156. for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
  4157. this.eventsheets_by_index[i].postInit();
  4158. for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
  4159. this.eventsheets_by_index[i].updateDeepIncludes();
  4160. for (i = 0, len = this.triggers_to_postinit.length; i < len; i++)
  4161. this.triggers_to_postinit[i].postInit();
  4162. this.triggers_to_postinit.length = 0;
  4163. this.audio_to_preload = pm[7];
  4164. this.files_subfolder = pm[8];
  4165. this.pixel_rounding = pm[9];
  4166. this.aspect_scale = 1.0;
  4167. this.enableWebGL = pm[13];
  4168. this.linearSampling = pm[14];
  4169. this.alphaBackground = pm[15];
  4170. this.versionstr = pm[16];
  4171. this.useHighDpi = pm[17];
  4172. this.orientations = pm[20]; // 0 = any, 1 = portrait, 2 = landscape
  4173. this.autoLockOrientation = (this.orientations > 0);
  4174. this.pauseOnBlur = pm[22];
  4175. this.wantFullscreenScalingQuality = pm[23]; // false = low quality, true = high quality
  4176. this.fullscreenScalingQuality = this.wantFullscreenScalingQuality;
  4177. this.downscalingQuality = pm[24]; // 0 = low (mips off), 1 = medium (mips on, dense spritesheet), 2 = high (mips on, sparse spritesheet)
  4178. this.preloadSounds = pm[25]; // 0 = no, 1 = yes
  4179. this.projectName = pm[26];
  4180. this.start_time = Date.now();
  4181. this.objectRefTable.length = 0;
  4182. this.initRendererAndLoader();
  4183. };
  4184. var anyImageHadError = false;
  4185. Runtime.prototype.waitForImageLoad = function (img_, src_)
  4186. {
  4187. img_["cocoonLazyLoad"] = true;
  4188. img_.onerror = function (e)
  4189. {
  4190. img_.c2error = true;
  4191. anyImageHadError = true;
  4192. if (console && console.error)
  4193. console.error("Error loading image '" + img_.src + "': ", e);
  4194. };
  4195. if (this.isEjecta)
  4196. {
  4197. img_.src = src_;
  4198. }
  4199. else if (!img_.src)
  4200. {
  4201. if (typeof XAPKReader !== "undefined")
  4202. {
  4203. XAPKReader.get(src_, function (expanded_url)
  4204. {
  4205. img_.src = expanded_url;
  4206. }, function (e)
  4207. {
  4208. img_.c2error = true;
  4209. anyImageHadError = true;
  4210. if (console && console.error)
  4211. console.error("Error extracting image '" + src_ + "' from expansion file: ", e);
  4212. });
  4213. }
  4214. else
  4215. {
  4216. img_.crossOrigin = "anonymous"; // required for Arcade sandbox compatibility
  4217. img_.src = src_;
  4218. }
  4219. }
  4220. this.wait_for_textures.push(img_);
  4221. };
  4222. Runtime.prototype.findWaitingTexture = function (src_)
  4223. {
  4224. var i, len;
  4225. for (i = 0, len = this.wait_for_textures.length; i < len; i++)
  4226. {
  4227. if (this.wait_for_textures[i].cr_src === src_)
  4228. return this.wait_for_textures[i];
  4229. }
  4230. return null;
  4231. };
  4232. var audio_preload_totalsize = 0;
  4233. var audio_preload_started = false;
  4234. Runtime.prototype.getready = function ()
  4235. {
  4236. if (!this.audioInstance)
  4237. return;
  4238. audio_preload_totalsize = this.audioInstance.setPreloadList(this.audio_to_preload);
  4239. };
  4240. Runtime.prototype.areAllTexturesAndSoundsLoaded = function ()
  4241. {
  4242. var totalsize = audio_preload_totalsize;
  4243. var completedsize = 0;
  4244. var audiocompletedsize = 0;
  4245. var ret = true;
  4246. var i, len, img;
  4247. for (i = 0, len = this.wait_for_textures.length; i < len; i++)
  4248. {
  4249. img = this.wait_for_textures[i];
  4250. var filesize = img.cr_filesize;
  4251. if (!filesize || filesize <= 0)
  4252. filesize = 50000;
  4253. totalsize += filesize;
  4254. if (!!img.src && (img.complete || img["loaded"]) && !img.c2error)
  4255. completedsize += filesize;
  4256. else
  4257. ret = false; // not all textures loaded
  4258. }
  4259. if (ret && this.preloadSounds && this.audioInstance)
  4260. {
  4261. if (!audio_preload_started)
  4262. {
  4263. this.audioInstance.startPreloads();
  4264. audio_preload_started = true;
  4265. }
  4266. audiocompletedsize = this.audioInstance.getPreloadedSize();
  4267. completedsize += audiocompletedsize;
  4268. if (audiocompletedsize < audio_preload_totalsize)
  4269. ret = false; // not done yet
  4270. }
  4271. if (totalsize == 0)
  4272. this.progress = 0;
  4273. else
  4274. this.progress = (completedsize / totalsize);
  4275. return ret;
  4276. };
  4277. Runtime.prototype.go = function ()
  4278. {
  4279. if (!this.ctx && !this.glwrap)
  4280. return;
  4281. var ctx = this.ctx || this.overlay_ctx;
  4282. if (this.overlay_canvas)
  4283. this.positionOverlayCanvas();
  4284. this.progress = 0;
  4285. this.last_progress = -1;
  4286. if (this.areAllTexturesAndSoundsLoaded())
  4287. this.go_loading_finished();
  4288. else
  4289. {
  4290. var ms_elapsed = Date.now() - this.start_time;
  4291. if (ctx)
  4292. {
  4293. var overlay_width = this.width;
  4294. var overlay_height = this.height;
  4295. var multiplier = this.devicePixelRatio;
  4296. if (this.overlay_canvas)
  4297. {
  4298. overlay_width = this.cssWidth;
  4299. overlay_height = this.cssHeight;
  4300. multiplier = 1;
  4301. }
  4302. if (this.loaderstyle !== 3 && (this.isCocoonJs || (ms_elapsed >= 500 && this.last_progress != this.progress)))
  4303. {
  4304. ctx.clearRect(0, 0, overlay_width, overlay_height);
  4305. var mx = overlay_width / 2;
  4306. var my = overlay_height / 2;
  4307. var haslogo = (this.loaderstyle === 0 && this.loaderlogo.complete);
  4308. var hlw = 40 * multiplier;
  4309. var hlh = 0;
  4310. var logowidth = 80 * multiplier;
  4311. var logoheight;
  4312. if (haslogo)
  4313. {
  4314. logowidth = this.loaderlogo.width * multiplier;
  4315. logoheight = this.loaderlogo.height * multiplier;
  4316. hlw = logowidth / 2;
  4317. hlh = logoheight / 2;
  4318. ctx.drawImage(this.loaderlogo, cr.floor(mx - hlw), cr.floor(my - hlh), logowidth, logoheight);
  4319. }
  4320. if (this.loaderstyle <= 1)
  4321. {
  4322. my += hlh + (haslogo ? 12 * multiplier : 0);
  4323. mx -= hlw;
  4324. mx = cr.floor(mx) + 0.5;
  4325. my = cr.floor(my) + 0.5;
  4326. ctx.fillStyle = anyImageHadError ? "red" : "DodgerBlue";
  4327. ctx.fillRect(mx, my, Math.floor(logowidth * this.progress), 6 * multiplier);
  4328. ctx.strokeStyle = "black";
  4329. ctx.strokeRect(mx, my, logowidth, 6 * multiplier);
  4330. ctx.strokeStyle = "white";
  4331. ctx.strokeRect(mx - 1 * multiplier, my - 1 * multiplier, logowidth + 2 * multiplier, 8 * multiplier);
  4332. }
  4333. else if (this.loaderstyle === 2)
  4334. {
  4335. ctx.font = (this.isEjecta ? "12pt ArialMT" : "12pt Arial");
  4336. ctx.fillStyle = anyImageHadError ? "#f00" : "#999";
  4337. ctx.textBaseLine = "middle";
  4338. var percent_text = Math.round(this.progress * 100) + "%";
  4339. var text_dim = ctx.measureText ? ctx.measureText(percent_text) : null;
  4340. var text_width = text_dim ? text_dim.width : 0;
  4341. ctx.fillText(percent_text, mx - (text_width / 2), my);
  4342. }
  4343. }
  4344. this.last_progress = this.progress;
  4345. }
  4346. setTimeout((function (self) { return function () { self.go(); }; })(this), (this.isCocoonJs ? 10 : 100));
  4347. }
  4348. };
  4349. Runtime.prototype.go_loading_finished = function ()
  4350. {
  4351. if (this.overlay_canvas)
  4352. {
  4353. this.canvas.parentNode.removeChild(this.overlay_canvas);
  4354. this.overlay_ctx = null;
  4355. this.overlay_canvas = null;
  4356. }
  4357. this.start_time = Date.now();
  4358. this.last_fps_time = cr.performance_now(); // for counting framerate
  4359. var i, len, t;
  4360. if (this.uses_loader_layout)
  4361. {
  4362. for (i = 0, len = this.types_by_index.length; i < len; i++)
  4363. {
  4364. t = this.types_by_index[i];
  4365. if (!t.is_family && !t.isOnLoaderLayout && t.plugin.is_world)
  4366. {
  4367. t.onCreate();
  4368. cr.seal(t);
  4369. }
  4370. }
  4371. }
  4372. else
  4373. this.isloading = false;
  4374. for (i = 0, len = this.layouts_by_index.length; i < len; i++)
  4375. {
  4376. this.layouts_by_index[i].createGlobalNonWorlds();
  4377. }
  4378. if (this.fullscreen_mode >= 2)
  4379. {
  4380. var orig_aspect = this.original_width / this.original_height;
  4381. var cur_aspect = this.width / this.height;
  4382. if ((this.fullscreen_mode !== 2 && cur_aspect > orig_aspect) || (this.fullscreen_mode === 2 && cur_aspect < orig_aspect))
  4383. this.aspect_scale = this.height / this.original_height;
  4384. else
  4385. this.aspect_scale = this.width / this.original_width;
  4386. }
  4387. if (this.first_layout)
  4388. this.layouts[this.first_layout].startRunning();
  4389. else
  4390. this.layouts_by_index[0].startRunning();
  4391. ;
  4392. if (!this.uses_loader_layout)
  4393. {
  4394. this.loadingprogress = 1;
  4395. this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
  4396. }
  4397. if (navigator["splashscreen"] && navigator["splashscreen"]["hide"])
  4398. navigator["splashscreen"]["hide"]();
  4399. for (i = 0, len = this.types_by_index.length; i < len; i++)
  4400. {
  4401. t = this.types_by_index[i];
  4402. if (t.onAppBegin)
  4403. t.onAppBegin();
  4404. }
  4405. if (document["hidden"] || document["webkitHidden"] || document["mozHidden"] || document["msHidden"])
  4406. {
  4407. window["cr_setSuspended"](true); // stop rendering
  4408. }
  4409. else
  4410. {
  4411. this.tick(false);
  4412. }
  4413. if (this.isDirectCanvas)
  4414. AppMobi["webview"]["execute"]("onGameReady();");
  4415. };
  4416. var raf = window["requestAnimationFrame"] ||
  4417. window["mozRequestAnimationFrame"] ||
  4418. window["webkitRequestAnimationFrame"] ||
  4419. window["msRequestAnimationFrame"] ||
  4420. window["oRequestAnimationFrame"];
  4421. Runtime.prototype.tick = function (background_wake, timestamp, debug_step)
  4422. {
  4423. if (!this.running_layout)
  4424. return;
  4425. var nowtime = cr.performance_now();
  4426. var logic_start = nowtime;
  4427. if (!debug_step && this.isSuspended && !background_wake)
  4428. return;
  4429. if (!background_wake)
  4430. {
  4431. if (raf)
  4432. this.raf_id = raf(this.tickFunc);
  4433. else
  4434. {
  4435. this.timeout_id = setTimeout(this.tickFunc, this.isMobile ? 1 : 16);
  4436. }
  4437. }
  4438. var raf_time = timestamp || nowtime;
  4439. var fsmode = this.fullscreen_mode;
  4440. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"]) && !this.isCordova;
  4441. if ((isfullscreen || this.isNodeFullscreen) && this.fullscreen_scaling > 0)
  4442. fsmode = this.fullscreen_scaling;
  4443. if (fsmode > 0 && (!this.isiOS || window.self !== window.top))
  4444. {
  4445. var curwidth = window.innerWidth;
  4446. var curheight = window.innerHeight;
  4447. if (this.lastWindowWidth !== curwidth || this.lastWindowHeight !== curheight)
  4448. {
  4449. this["setSize"](window_innerWidth(), window_innerHeight());
  4450. }
  4451. }
  4452. if (!this.isDomFree)
  4453. {
  4454. if (isfullscreen)
  4455. {
  4456. if (!this.firstInFullscreen)
  4457. {
  4458. this.fullscreenOldMarginCss = jQuery(this.canvas).css("margin") || "0";
  4459. this.firstInFullscreen = true;
  4460. }
  4461. if (!this.isChrome && !this.isNWjs)
  4462. {
  4463. jQuery(this.canvas).css({
  4464. "margin-left": "" + Math.floor((screen.width - (this.width / this.devicePixelRatio)) / 2) + "px",
  4465. "margin-top": "" + Math.floor((screen.height - (this.height / this.devicePixelRatio)) / 2) + "px"
  4466. });
  4467. }
  4468. }
  4469. else
  4470. {
  4471. if (this.firstInFullscreen)
  4472. {
  4473. if (!this.isChrome && !this.isNWjs)
  4474. {
  4475. jQuery(this.canvas).css("margin", this.fullscreenOldMarginCss);
  4476. }
  4477. this.fullscreenOldMarginCss = "";
  4478. this.firstInFullscreen = false;
  4479. if (this.fullscreen_mode === 0)
  4480. {
  4481. this["setSize"](Math.round(this.oldWidth / this.devicePixelRatio), Math.round(this.oldHeight / this.devicePixelRatio), true);
  4482. }
  4483. }
  4484. else
  4485. {
  4486. this.oldWidth = this.width;
  4487. this.oldHeight = this.height;
  4488. }
  4489. }
  4490. }
  4491. if (this.isloading)
  4492. {
  4493. var done = this.areAllTexturesAndSoundsLoaded(); // updates this.progress
  4494. this.loadingprogress = this.progress;
  4495. if (done)
  4496. {
  4497. this.isloading = false;
  4498. this.progress = 1;
  4499. this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
  4500. }
  4501. }
  4502. this.logic(raf_time);
  4503. if ((this.redraw || this.isCocoonJs) && !this.is_WebGL_context_lost && !this.suspendDrawing && !background_wake)
  4504. {
  4505. this.redraw = false;
  4506. if (this.glwrap)
  4507. this.drawGL();
  4508. else
  4509. this.draw();
  4510. if (this.snapshotCanvas)
  4511. {
  4512. if (this.canvas && this.canvas.toDataURL)
  4513. {
  4514. this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]);
  4515. if (window["cr_onSnapshot"])
  4516. window["cr_onSnapshot"](this.snapshotData);
  4517. this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null);
  4518. }
  4519. this.snapshotCanvas = null;
  4520. }
  4521. }
  4522. if (!this.hit_breakpoint)
  4523. {
  4524. this.tickcount++;
  4525. this.execcount++;
  4526. this.framecount++;
  4527. }
  4528. this.logictime += cr.performance_now() - logic_start;
  4529. };
  4530. Runtime.prototype.logic = function (cur_time)
  4531. {
  4532. var i, leni, j, lenj, k, lenk, type, inst, binst;
  4533. if (cur_time - this.last_fps_time >= 1000) // every 1 second
  4534. {
  4535. this.last_fps_time += 1000;
  4536. if (cur_time - this.last_fps_time >= 1000)
  4537. this.last_fps_time = cur_time;
  4538. this.fps = this.framecount;
  4539. this.framecount = 0;
  4540. this.cpuutilisation = this.logictime;
  4541. this.logictime = 0;
  4542. }
  4543. if (this.last_tick_time !== 0)
  4544. {
  4545. var ms_diff = cur_time - this.last_tick_time;
  4546. if (ms_diff < 0)
  4547. ms_diff = 0;
  4548. this.dt1 = ms_diff / 1000.0; // dt measured in seconds
  4549. if (this.dt1 > 0.5)
  4550. this.dt1 = 0;
  4551. else if (this.dt1 > 0.1)
  4552. this.dt1 = 0.1;
  4553. }
  4554. this.last_tick_time = cur_time;
  4555. this.dt = this.dt1 * this.timescale;
  4556. this.kahanTime.add(this.dt);
  4557. this.wallTime.add(this.dt1);
  4558. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || !!document["msFullscreenElement"] || this.isNodeFullscreen) && !this.isCordova;
  4559. if (this.fullscreen_mode >= 2 /* scale */ || (isfullscreen && this.fullscreen_scaling > 0))
  4560. {
  4561. var orig_aspect = this.original_width / this.original_height;
  4562. var cur_aspect = this.width / this.height;
  4563. var mode = this.fullscreen_mode;
  4564. if (isfullscreen && this.fullscreen_scaling > 0)
  4565. mode = this.fullscreen_scaling;
  4566. if ((mode !== 2 && cur_aspect > orig_aspect) || (mode === 2 && cur_aspect < orig_aspect))
  4567. {
  4568. this.aspect_scale = this.height / this.original_height;
  4569. }
  4570. else
  4571. {
  4572. this.aspect_scale = this.width / this.original_width;
  4573. }
  4574. if (this.running_layout)
  4575. {
  4576. this.running_layout.scrollToX(this.running_layout.scrollX);
  4577. this.running_layout.scrollToY(this.running_layout.scrollY);
  4578. }
  4579. }
  4580. else
  4581. this.aspect_scale = (this.isRetina ? this.devicePixelRatio : 1);
  4582. this.ClearDeathRow();
  4583. this.isInOnDestroy++;
  4584. this.system.runWaits(); // prevent instance list changing
  4585. this.isInOnDestroy--;
  4586. this.ClearDeathRow(); // allow instance list changing
  4587. this.isInOnDestroy++;
  4588. var tickarr = this.objects_to_pretick.valuesRef();
  4589. for (i = 0, leni = tickarr.length; i < leni; i++)
  4590. tickarr[i].pretick();
  4591. for (i = 0, leni = this.types_by_index.length; i < leni; i++)
  4592. {
  4593. type = this.types_by_index[i];
  4594. if (type.is_family || (!type.behaviors.length && !type.families.length))
  4595. continue;
  4596. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  4597. {
  4598. inst = type.instances[j];
  4599. for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
  4600. {
  4601. inst.behavior_insts[k].tick();
  4602. }
  4603. }
  4604. }
  4605. for (i = 0, leni = this.types_by_index.length; i < leni; i++)
  4606. {
  4607. type = this.types_by_index[i];
  4608. if (type.is_family || (!type.behaviors.length && !type.families.length))
  4609. continue; // type doesn't have any behaviors
  4610. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  4611. {
  4612. inst = type.instances[j];
  4613. for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
  4614. {
  4615. binst = inst.behavior_insts[k];
  4616. if (binst.posttick)
  4617. binst.posttick();
  4618. }
  4619. }
  4620. }
  4621. tickarr = this.objects_to_tick.valuesRef();
  4622. for (i = 0, leni = tickarr.length; i < leni; i++)
  4623. tickarr[i].tick();
  4624. this.isInOnDestroy--; // end preventing instance lists from being changed
  4625. this.handleSaveLoad(); // save/load now if queued
  4626. i = 0;
  4627. while (this.changelayout && i++ < 10)
  4628. {
  4629. this.doChangeLayout(this.changelayout);
  4630. }
  4631. for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
  4632. this.eventsheets_by_index[i].hasRun = false;
  4633. if (this.running_layout.event_sheet)
  4634. this.running_layout.event_sheet.run();
  4635. this.registered_collisions.length = 0;
  4636. this.layout_first_tick = false;
  4637. this.isInOnDestroy++; // prevent instance lists from being changed
  4638. for (i = 0, leni = this.types_by_index.length; i < leni; i++)
  4639. {
  4640. type = this.types_by_index[i];
  4641. if (type.is_family || (!type.behaviors.length && !type.families.length))
  4642. continue; // type doesn't have any behaviors
  4643. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  4644. {
  4645. var inst = type.instances[j];
  4646. for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
  4647. {
  4648. binst = inst.behavior_insts[k];
  4649. if (binst.tick2)
  4650. binst.tick2();
  4651. }
  4652. }
  4653. }
  4654. tickarr = this.objects_to_tick2.valuesRef();
  4655. for (i = 0, leni = tickarr.length; i < leni; i++)
  4656. tickarr[i].tick2();
  4657. this.isInOnDestroy--; // end preventing instance lists from being changed
  4658. };
  4659. Runtime.prototype.doChangeLayout = function (changeToLayout)
  4660. {
  4661. ;
  4662. var prev_layout = this.running_layout;
  4663. this.running_layout.stopRunning();
  4664. var i, len, j, lenj, k, lenk, type, inst, binst;
  4665. if (this.glwrap)
  4666. {
  4667. for (i = 0, len = this.types_by_index.length; i < len; i++)
  4668. {
  4669. type = this.types_by_index[i];
  4670. if (type.is_family)
  4671. continue;
  4672. if (type.unloadTextures && (!type.global || type.instances.length === 0) && changeToLayout.initial_types.indexOf(type) === -1)
  4673. {
  4674. type.unloadTextures();
  4675. }
  4676. }
  4677. }
  4678. if (prev_layout == changeToLayout)
  4679. this.system.waits.length = 0;
  4680. this.registered_collisions.length = 0;
  4681. changeToLayout.startRunning();
  4682. for (i = 0, len = this.types_by_index.length; i < len; i++)
  4683. {
  4684. type = this.types_by_index[i];
  4685. if (!type.global && !type.plugin.singleglobal)
  4686. continue;
  4687. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  4688. {
  4689. inst = type.instances[j];
  4690. if (inst.onLayoutChange)
  4691. inst.onLayoutChange();
  4692. if (inst.behavior_insts)
  4693. {
  4694. for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
  4695. {
  4696. binst = inst.behavior_insts[k];
  4697. if (binst.onLayoutChange)
  4698. binst.onLayoutChange();
  4699. }
  4700. }
  4701. }
  4702. }
  4703. this.redraw = true;
  4704. this.layout_first_tick = true;
  4705. this.ClearDeathRow();
  4706. };
  4707. Runtime.prototype.pretickMe = function (inst)
  4708. {
  4709. this.objects_to_pretick.add(inst);
  4710. };
  4711. Runtime.prototype.unpretickMe = function (inst)
  4712. {
  4713. this.objects_to_pretick.remove(inst);
  4714. };
  4715. Runtime.prototype.tickMe = function (inst)
  4716. {
  4717. this.objects_to_tick.add(inst);
  4718. };
  4719. Runtime.prototype.untickMe = function (inst)
  4720. {
  4721. this.objects_to_tick.remove(inst);
  4722. };
  4723. Runtime.prototype.tick2Me = function (inst)
  4724. {
  4725. this.objects_to_tick2.add(inst);
  4726. };
  4727. Runtime.prototype.untick2Me = function (inst)
  4728. {
  4729. this.objects_to_tick2.remove(inst);
  4730. };
  4731. Runtime.prototype.getDt = function (inst)
  4732. {
  4733. if (!inst || inst.my_timescale === -1.0)
  4734. return this.dt;
  4735. return this.dt1 * inst.my_timescale;
  4736. };
  4737. Runtime.prototype.draw = function ()
  4738. {
  4739. this.running_layout.draw(this.ctx);
  4740. if (this.isDirectCanvas)
  4741. this.ctx["present"]();
  4742. };
  4743. Runtime.prototype.drawGL = function ()
  4744. {
  4745. this.running_layout.drawGL(this.glwrap);
  4746. this.glwrap.present();
  4747. };
  4748. Runtime.prototype.addDestroyCallback = function (f)
  4749. {
  4750. if (f)
  4751. this.destroycallbacks.push(f);
  4752. };
  4753. Runtime.prototype.removeDestroyCallback = function (f)
  4754. {
  4755. cr.arrayFindRemove(this.destroycallbacks, f);
  4756. };
  4757. Runtime.prototype.getObjectByUID = function (uid_)
  4758. {
  4759. ;
  4760. var uidstr = uid_.toString();
  4761. if (this.objectsByUid.hasOwnProperty(uidstr))
  4762. return this.objectsByUid[uidstr];
  4763. else
  4764. return null;
  4765. };
  4766. var objectset_cache = [];
  4767. function alloc_objectset()
  4768. {
  4769. if (objectset_cache.length)
  4770. return objectset_cache.pop();
  4771. else
  4772. return new cr.ObjectSet();
  4773. };
  4774. function free_objectset(s)
  4775. {
  4776. s.clear();
  4777. objectset_cache.push(s);
  4778. };
  4779. Runtime.prototype.DestroyInstance = function (inst)
  4780. {
  4781. var i, len;
  4782. var type = inst.type;
  4783. var typename = type.name;
  4784. var has_typename = this.deathRow.hasOwnProperty(typename);
  4785. var obj_set = null;
  4786. if (has_typename)
  4787. {
  4788. obj_set = this.deathRow[typename];
  4789. if (obj_set.contains(inst))
  4790. return; // already had DestroyInstance called
  4791. }
  4792. else
  4793. {
  4794. obj_set = alloc_objectset();
  4795. this.deathRow[typename] = obj_set;
  4796. }
  4797. obj_set.add(inst);
  4798. this.hasPendingInstances = true;
  4799. if (inst.is_contained)
  4800. {
  4801. for (i = 0, len = inst.siblings.length; i < len; i++)
  4802. {
  4803. this.DestroyInstance(inst.siblings[i]);
  4804. }
  4805. }
  4806. if (this.isInClearDeathRow)
  4807. obj_set.values_cache.push(inst);
  4808. this.isInOnDestroy++; // support recursion
  4809. this.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnDestroyed, inst);
  4810. this.isInOnDestroy--;
  4811. };
  4812. Runtime.prototype.ClearDeathRow = function ()
  4813. {
  4814. if (!this.hasPendingInstances)
  4815. return;
  4816. var inst, type, instances;
  4817. var i, j, leni, lenj, obj_set;
  4818. this.isInClearDeathRow = true;
  4819. for (i = 0, leni = this.createRow.length; i < leni; ++i)
  4820. {
  4821. inst = this.createRow[i];
  4822. type = inst.type;
  4823. type.instances.push(inst);
  4824. for (j = 0, lenj = type.families.length; j < lenj; ++j)
  4825. {
  4826. type.families[j].instances.push(inst);
  4827. type.families[j].stale_iids = true;
  4828. }
  4829. }
  4830. this.createRow.length = 0;
  4831. this.IterateDeathRow(); // moved to separate function so for-in performance doesn't hobble entire function
  4832. cr.wipe(this.deathRow); // all objectsets have already been recycled
  4833. this.isInClearDeathRow = false;
  4834. this.hasPendingInstances = false;
  4835. };
  4836. Runtime.prototype.IterateDeathRow = function ()
  4837. {
  4838. for (var p in this.deathRow)
  4839. {
  4840. if (this.deathRow.hasOwnProperty(p))
  4841. {
  4842. this.ClearDeathRowForType(this.deathRow[p]);
  4843. }
  4844. }
  4845. };
  4846. Runtime.prototype.ClearDeathRowForType = function (obj_set)
  4847. {
  4848. var arr = obj_set.valuesRef(); // get array of items from set
  4849. ;
  4850. var type = arr[0].type;
  4851. ;
  4852. ;
  4853. var i, len, j, lenj, w, f, layer_instances, inst;
  4854. cr.arrayRemoveAllFromObjectSet(type.instances, obj_set);
  4855. type.stale_iids = true;
  4856. if (type.instances.length === 0)
  4857. type.any_instance_parallaxed = false;
  4858. for (i = 0, len = type.families.length; i < len; ++i)
  4859. {
  4860. f = type.families[i];
  4861. cr.arrayRemoveAllFromObjectSet(f.instances, obj_set);
  4862. f.stale_iids = true;
  4863. }
  4864. for (i = 0, len = this.system.waits.length; i < len; ++i)
  4865. {
  4866. w = this.system.waits[i];
  4867. if (w.sols.hasOwnProperty(type.index))
  4868. cr.arrayRemoveAllFromObjectSet(w.sols[type.index].insts, obj_set);
  4869. if (!type.is_family)
  4870. {
  4871. for (j = 0, lenj = type.families.length; j < lenj; ++j)
  4872. {
  4873. f = type.families[j];
  4874. if (w.sols.hasOwnProperty(f.index))
  4875. cr.arrayRemoveAllFromObjectSet(w.sols[f.index].insts, obj_set);
  4876. }
  4877. }
  4878. }
  4879. var first_layer = arr[0].layer;
  4880. if (first_layer)
  4881. {
  4882. if (first_layer.useRenderCells)
  4883. {
  4884. layer_instances = first_layer.instances;
  4885. for (i = 0, len = layer_instances.length; i < len; ++i)
  4886. {
  4887. inst = layer_instances[i];
  4888. if (!obj_set.contains(inst))
  4889. continue; // not destroying this instance
  4890. inst.update_bbox();
  4891. first_layer.render_grid.update(inst, inst.rendercells, null);
  4892. inst.rendercells.set(0, 0, -1, -1);
  4893. }
  4894. }
  4895. cr.arrayRemoveAllFromObjectSet(first_layer.instances, obj_set);
  4896. first_layer.setZIndicesStaleFrom(0);
  4897. }
  4898. for (i = 0; i < arr.length; ++i) // check array length every time in case it changes
  4899. {
  4900. this.ClearDeathRowForSingleInstance(arr[i], type);
  4901. }
  4902. free_objectset(obj_set);
  4903. this.redraw = true;
  4904. };
  4905. Runtime.prototype.ClearDeathRowForSingleInstance = function (inst, type)
  4906. {
  4907. var i, len, binst;
  4908. for (i = 0, len = this.destroycallbacks.length; i < len; ++i)
  4909. this.destroycallbacks[i](inst);
  4910. if (inst.collcells)
  4911. {
  4912. type.collision_grid.update(inst, inst.collcells, null);
  4913. }
  4914. var layer = inst.layer;
  4915. if (layer)
  4916. {
  4917. layer.removeFromInstanceList(inst, true); // remove from both instance list and render grid
  4918. }
  4919. if (inst.behavior_insts)
  4920. {
  4921. for (i = 0, len = inst.behavior_insts.length; i < len; ++i)
  4922. {
  4923. binst = inst.behavior_insts[i];
  4924. if (binst.onDestroy)
  4925. binst.onDestroy();
  4926. binst.behavior.my_instances.remove(inst);
  4927. }
  4928. }
  4929. this.objects_to_pretick.remove(inst);
  4930. this.objects_to_tick.remove(inst);
  4931. this.objects_to_tick2.remove(inst);
  4932. if (inst.onDestroy)
  4933. inst.onDestroy();
  4934. if (this.objectsByUid.hasOwnProperty(inst.uid.toString()))
  4935. delete this.objectsByUid[inst.uid.toString()];
  4936. this.objectcount--;
  4937. if (type.deadCache.length < 100)
  4938. type.deadCache.push(inst);
  4939. };
  4940. Runtime.prototype.createInstance = function (type, layer, sx, sy)
  4941. {
  4942. if (type.is_family)
  4943. {
  4944. var i = cr.floor(Math.random() * type.members.length);
  4945. return this.createInstance(type.members[i], layer, sx, sy);
  4946. }
  4947. if (!type.default_instance)
  4948. {
  4949. return null;
  4950. }
  4951. return this.createInstanceFromInit(type.default_instance, layer, false, sx, sy, false);
  4952. };
  4953. var all_behaviors = [];
  4954. Runtime.prototype.createInstanceFromInit = function (initial_inst, layer, is_startup_instance, sx, sy, skip_siblings)
  4955. {
  4956. var i, len, j, lenj, p, effect_fallback, x, y;
  4957. if (!initial_inst)
  4958. return null;
  4959. var type = this.types_by_index[initial_inst[1]];
  4960. ;
  4961. ;
  4962. var is_world = type.plugin.is_world;
  4963. ;
  4964. if (this.isloading && is_world && !type.isOnLoaderLayout)
  4965. return null;
  4966. if (is_world && !this.glwrap && initial_inst[0][11] === 11)
  4967. return null;
  4968. var original_layer = layer;
  4969. if (!is_world)
  4970. layer = null;
  4971. var inst;
  4972. if (type.deadCache.length)
  4973. {
  4974. inst = type.deadCache.pop();
  4975. inst.recycled = true;
  4976. type.plugin.Instance.call(inst, type);
  4977. }
  4978. else
  4979. {
  4980. inst = new type.plugin.Instance(type);
  4981. inst.recycled = false;
  4982. }
  4983. if (is_startup_instance && !skip_siblings && !this.objectsByUid.hasOwnProperty(initial_inst[2].toString()))
  4984. inst.uid = initial_inst[2];
  4985. else
  4986. inst.uid = this.next_uid++;
  4987. this.objectsByUid[inst.uid.toString()] = inst;
  4988. inst.puid = this.next_puid++;
  4989. inst.iid = type.instances.length;
  4990. for (i = 0, len = this.createRow.length; i < len; ++i)
  4991. {
  4992. if (this.createRow[i].type === type)
  4993. inst.iid++;
  4994. }
  4995. inst.get_iid = cr.inst_get_iid;
  4996. inst.toString = cr.inst_toString;
  4997. var initial_vars = initial_inst[3];
  4998. if (inst.recycled)
  4999. {
  5000. cr.wipe(inst.extra);
  5001. }
  5002. else
  5003. {
  5004. inst.extra = {};
  5005. if (typeof cr_is_preview !== "undefined")
  5006. {
  5007. inst.instance_var_names = [];
  5008. inst.instance_var_names.length = initial_vars.length;
  5009. for (i = 0, len = initial_vars.length; i < len; i++)
  5010. inst.instance_var_names[i] = initial_vars[i][1];
  5011. }
  5012. inst.instance_vars = [];
  5013. inst.instance_vars.length = initial_vars.length;
  5014. }
  5015. for (i = 0, len = initial_vars.length; i < len; i++)
  5016. inst.instance_vars[i] = initial_vars[i][0];
  5017. if (is_world)
  5018. {
  5019. var wm = initial_inst[0];
  5020. ;
  5021. inst.x = cr.is_undefined(sx) ? wm[0] : sx;
  5022. inst.y = cr.is_undefined(sy) ? wm[1] : sy;
  5023. inst.z = wm[2];
  5024. inst.width = wm[3];
  5025. inst.height = wm[4];
  5026. inst.depth = wm[5];
  5027. inst.angle = wm[6];
  5028. inst.opacity = wm[7];
  5029. inst.hotspotX = wm[8];
  5030. inst.hotspotY = wm[9];
  5031. inst.blend_mode = wm[10];
  5032. effect_fallback = wm[11];
  5033. if (!this.glwrap && type.effect_types.length) // no WebGL renderer and shaders used
  5034. inst.blend_mode = effect_fallback; // use fallback blend mode - destroy mode was handled above
  5035. inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
  5036. if (this.gl)
  5037. cr.setGLBlend(inst, inst.blend_mode, this.gl);
  5038. if (inst.recycled)
  5039. {
  5040. for (i = 0, len = wm[12].length; i < len; i++)
  5041. {
  5042. for (j = 0, lenj = wm[12][i].length; j < lenj; j++)
  5043. inst.effect_params[i][j] = wm[12][i][j];
  5044. }
  5045. inst.bbox.set(0, 0, 0, 0);
  5046. inst.collcells.set(0, 0, -1, -1);
  5047. inst.rendercells.set(0, 0, -1, -1);
  5048. inst.bquad.set_from_rect(inst.bbox);
  5049. inst.bbox_changed_callbacks.length = 0;
  5050. }
  5051. else
  5052. {
  5053. inst.effect_params = wm[12].slice(0);
  5054. for (i = 0, len = inst.effect_params.length; i < len; i++)
  5055. inst.effect_params[i] = wm[12][i].slice(0);
  5056. inst.active_effect_types = [];
  5057. inst.active_effect_flags = [];
  5058. inst.active_effect_flags.length = type.effect_types.length;
  5059. inst.bbox = new cr.rect(0, 0, 0, 0);
  5060. inst.collcells = new cr.rect(0, 0, -1, -1);
  5061. inst.rendercells = new cr.rect(0, 0, -1, -1);
  5062. inst.bquad = new cr.quad();
  5063. inst.bbox_changed_callbacks = [];
  5064. inst.set_bbox_changed = cr.set_bbox_changed;
  5065. inst.add_bbox_changed_callback = cr.add_bbox_changed_callback;
  5066. inst.contains_pt = cr.inst_contains_pt;
  5067. inst.update_bbox = cr.update_bbox;
  5068. inst.update_render_cell = cr.update_render_cell;
  5069. inst.update_collision_cell = cr.update_collision_cell;
  5070. inst.get_zindex = cr.inst_get_zindex;
  5071. }
  5072. inst.tilemap_exists = false;
  5073. inst.tilemap_width = 0;
  5074. inst.tilemap_height = 0;
  5075. inst.tilemap_data = null;
  5076. if (wm.length === 14)
  5077. {
  5078. inst.tilemap_exists = true;
  5079. inst.tilemap_width = wm[13][0];
  5080. inst.tilemap_height = wm[13][1];
  5081. inst.tilemap_data = wm[13][2];
  5082. }
  5083. for (i = 0, len = type.effect_types.length; i < len; i++)
  5084. inst.active_effect_flags[i] = true;
  5085. inst.updateActiveEffects = cr.inst_updateActiveEffects;
  5086. inst.updateActiveEffects();
  5087. inst.uses_shaders = !!inst.active_effect_types.length;
  5088. inst.bbox_changed = true;
  5089. inst.cell_changed = true;
  5090. type.any_cell_changed = true;
  5091. inst.visible = true;
  5092. inst.my_timescale = -1.0;
  5093. inst.layer = layer;
  5094. inst.zindex = layer.instances.length; // will be placed at top of current layer
  5095. if (typeof inst.collision_poly === "undefined")
  5096. inst.collision_poly = null;
  5097. inst.collisionsEnabled = true;
  5098. this.redraw = true;
  5099. }
  5100. var initial_props, binst;
  5101. all_behaviors.length = 0;
  5102. for (i = 0, len = type.families.length; i < len; i++)
  5103. {
  5104. all_behaviors.push.apply(all_behaviors, type.families[i].behaviors);
  5105. }
  5106. all_behaviors.push.apply(all_behaviors, type.behaviors);
  5107. if (inst.recycled)
  5108. {
  5109. for (i = 0, len = all_behaviors.length; i < len; i++)
  5110. {
  5111. var btype = all_behaviors[i];
  5112. binst = inst.behavior_insts[i];
  5113. binst.recycled = true;
  5114. btype.behavior.Instance.call(binst, btype, inst);
  5115. initial_props = initial_inst[4][i];
  5116. for (j = 0, lenj = initial_props.length; j < lenj; j++)
  5117. binst.properties[j] = initial_props[j];
  5118. binst.onCreate();
  5119. btype.behavior.my_instances.add(inst);
  5120. }
  5121. }
  5122. else
  5123. {
  5124. inst.behavior_insts = [];
  5125. for (i = 0, len = all_behaviors.length; i < len; i++)
  5126. {
  5127. var btype = all_behaviors[i];
  5128. var binst = new btype.behavior.Instance(btype, inst);
  5129. binst.recycled = false;
  5130. binst.properties = initial_inst[4][i].slice(0);
  5131. binst.onCreate();
  5132. cr.seal(binst);
  5133. inst.behavior_insts.push(binst);
  5134. btype.behavior.my_instances.add(inst);
  5135. }
  5136. }
  5137. initial_props = initial_inst[5];
  5138. if (inst.recycled)
  5139. {
  5140. for (i = 0, len = initial_props.length; i < len; i++)
  5141. inst.properties[i] = initial_props[i];
  5142. }
  5143. else
  5144. inst.properties = initial_props.slice(0);
  5145. this.createRow.push(inst);
  5146. this.hasPendingInstances = true;
  5147. if (layer)
  5148. {
  5149. ;
  5150. layer.appendToInstanceList(inst, true);
  5151. if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
  5152. type.any_instance_parallaxed = true;
  5153. }
  5154. this.objectcount++;
  5155. if (type.is_contained)
  5156. {
  5157. inst.is_contained = true;
  5158. if (inst.recycled)
  5159. inst.siblings.length = 0;
  5160. else
  5161. inst.siblings = []; // note: should not include self in siblings
  5162. if (!is_startup_instance && !skip_siblings) // layout links initial instances
  5163. {
  5164. for (i = 0, len = type.container.length; i < len; i++)
  5165. {
  5166. if (type.container[i] === type)
  5167. continue;
  5168. if (!type.container[i].default_instance)
  5169. {
  5170. return null;
  5171. }
  5172. inst.siblings.push(this.createInstanceFromInit(type.container[i].default_instance, original_layer, false, is_world ? inst.x : sx, is_world ? inst.y : sy, true));
  5173. }
  5174. for (i = 0, len = inst.siblings.length; i < len; i++)
  5175. {
  5176. inst.siblings[i].siblings.push(inst);
  5177. for (j = 0; j < len; j++)
  5178. {
  5179. if (i !== j)
  5180. inst.siblings[i].siblings.push(inst.siblings[j]);
  5181. }
  5182. }
  5183. }
  5184. }
  5185. else
  5186. {
  5187. inst.is_contained = false;
  5188. inst.siblings = null;
  5189. }
  5190. inst.onCreate();
  5191. if (!inst.recycled)
  5192. cr.seal(inst);
  5193. for (i = 0, len = inst.behavior_insts.length; i < len; i++)
  5194. {
  5195. if (inst.behavior_insts[i].postCreate)
  5196. inst.behavior_insts[i].postCreate();
  5197. }
  5198. return inst;
  5199. };
  5200. Runtime.prototype.getLayerByName = function (layer_name)
  5201. {
  5202. var i, len;
  5203. for (i = 0, len = this.running_layout.layers.length; i < len; i++)
  5204. {
  5205. var layer = this.running_layout.layers[i];
  5206. if (cr.equals_nocase(layer.name, layer_name))
  5207. return layer;
  5208. }
  5209. return null;
  5210. };
  5211. Runtime.prototype.getLayerByNumber = function (index)
  5212. {
  5213. index = cr.floor(index);
  5214. if (index < 0)
  5215. index = 0;
  5216. if (index >= this.running_layout.layers.length)
  5217. index = this.running_layout.layers.length - 1;
  5218. return this.running_layout.layers[index];
  5219. };
  5220. Runtime.prototype.getLayer = function (l)
  5221. {
  5222. if (cr.is_number(l))
  5223. return this.getLayerByNumber(l);
  5224. else
  5225. return this.getLayerByName(l.toString());
  5226. };
  5227. Runtime.prototype.clearSol = function (solModifiers)
  5228. {
  5229. var i, len;
  5230. for (i = 0, len = solModifiers.length; i < len; i++)
  5231. {
  5232. solModifiers[i].getCurrentSol().select_all = true;
  5233. }
  5234. };
  5235. Runtime.prototype.pushCleanSol = function (solModifiers)
  5236. {
  5237. var i, len;
  5238. for (i = 0, len = solModifiers.length; i < len; i++)
  5239. {
  5240. solModifiers[i].pushCleanSol();
  5241. }
  5242. };
  5243. Runtime.prototype.pushCopySol = function (solModifiers)
  5244. {
  5245. var i, len;
  5246. for (i = 0, len = solModifiers.length; i < len; i++)
  5247. {
  5248. solModifiers[i].pushCopySol();
  5249. }
  5250. };
  5251. Runtime.prototype.popSol = function (solModifiers)
  5252. {
  5253. var i, len;
  5254. for (i = 0, len = solModifiers.length; i < len; i++)
  5255. {
  5256. solModifiers[i].popSol();
  5257. }
  5258. };
  5259. Runtime.prototype.updateAllCells = function (type)
  5260. {
  5261. if (!type.any_cell_changed)
  5262. return; // all instances must already be up-to-date
  5263. var i, len, instances = type.instances;
  5264. for (i = 0, len = instances.length; i < len; ++i)
  5265. {
  5266. instances[i].update_collision_cell();
  5267. }
  5268. var createRow = this.createRow;
  5269. for (i = 0, len = createRow.length; i < len; ++i)
  5270. {
  5271. if (createRow[i].type === type)
  5272. createRow[i].update_collision_cell();
  5273. }
  5274. type.any_cell_changed = false;
  5275. };
  5276. Runtime.prototype.getCollisionCandidates = function (layer, rtype, bbox, candidates)
  5277. {
  5278. var i, len, t;
  5279. var is_parallaxed = (layer ? (layer.parallaxX !== 1 || layer.parallaxY !== 1) : false);
  5280. if (rtype.is_family)
  5281. {
  5282. for (i = 0, len = rtype.members.length; i < len; ++i)
  5283. {
  5284. t = rtype.members[i];
  5285. if (is_parallaxed || t.any_instance_parallaxed)
  5286. {
  5287. cr.appendArray(candidates, t.instances);
  5288. }
  5289. else
  5290. {
  5291. this.updateAllCells(t);
  5292. t.collision_grid.queryRange(bbox, candidates);
  5293. }
  5294. }
  5295. }
  5296. else
  5297. {
  5298. if (is_parallaxed || rtype.any_instance_parallaxed)
  5299. {
  5300. cr.appendArray(candidates, rtype.instances);
  5301. }
  5302. else
  5303. {
  5304. this.updateAllCells(rtype);
  5305. rtype.collision_grid.queryRange(bbox, candidates);
  5306. }
  5307. }
  5308. };
  5309. Runtime.prototype.getTypesCollisionCandidates = function (layer, types, bbox, candidates)
  5310. {
  5311. var i, len;
  5312. for (i = 0, len = types.length; i < len; ++i)
  5313. {
  5314. this.getCollisionCandidates(layer, types[i], bbox, candidates);
  5315. }
  5316. };
  5317. Runtime.prototype.getSolidCollisionCandidates = function (layer, bbox, candidates)
  5318. {
  5319. var solid = this.getSolidBehavior();
  5320. if (!solid)
  5321. return null;
  5322. this.getTypesCollisionCandidates(layer, solid.my_types, bbox, candidates);
  5323. };
  5324. Runtime.prototype.getJumpthruCollisionCandidates = function (layer, bbox, candidates)
  5325. {
  5326. var jumpthru = this.getJumpthruBehavior();
  5327. if (!jumpthru)
  5328. return null;
  5329. this.getTypesCollisionCandidates(layer, jumpthru.my_types, bbox, candidates);
  5330. };
  5331. Runtime.prototype.testAndSelectCanvasPointOverlap = function (type, ptx, pty, inverted)
  5332. {
  5333. var sol = type.getCurrentSol();
  5334. var i, j, inst, len;
  5335. var lx, ly;
  5336. if (sol.select_all)
  5337. {
  5338. if (!inverted)
  5339. {
  5340. sol.select_all = false;
  5341. sol.instances.length = 0; // clear contents
  5342. }
  5343. for (i = 0, len = type.instances.length; i < len; i++)
  5344. {
  5345. inst = type.instances[i];
  5346. inst.update_bbox();
  5347. lx = inst.layer.canvasToLayer(ptx, pty, true);
  5348. ly = inst.layer.canvasToLayer(ptx, pty, false);
  5349. if (inst.contains_pt(lx, ly))
  5350. {
  5351. if (inverted)
  5352. return false;
  5353. else
  5354. sol.instances.push(inst);
  5355. }
  5356. }
  5357. }
  5358. else
  5359. {
  5360. j = 0;
  5361. for (i = 0, len = sol.instances.length; i < len; i++)
  5362. {
  5363. inst = sol.instances[i];
  5364. inst.update_bbox();
  5365. lx = inst.layer.canvasToLayer(ptx, pty, true);
  5366. ly = inst.layer.canvasToLayer(ptx, pty, false);
  5367. if (inst.contains_pt(lx, ly))
  5368. {
  5369. if (inverted)
  5370. return false;
  5371. else
  5372. {
  5373. sol.instances[j] = sol.instances[i];
  5374. j++;
  5375. }
  5376. }
  5377. }
  5378. if (!inverted)
  5379. sol.instances.length = j;
  5380. }
  5381. type.applySolToContainer();
  5382. if (inverted)
  5383. return true; // did not find anything overlapping
  5384. else
  5385. return sol.hasObjects();
  5386. };
  5387. Runtime.prototype.testOverlap = function (a, b)
  5388. {
  5389. if (!a || !b || a === b || !a.collisionsEnabled || !b.collisionsEnabled)
  5390. return false;
  5391. a.update_bbox();
  5392. b.update_bbox();
  5393. var layera = a.layer;
  5394. var layerb = b.layer;
  5395. var different_layers = (layera !== layerb && (layera.parallaxX !== layerb.parallaxX || layerb.parallaxY !== layerb.parallaxY || layera.scale !== layerb.scale || layera.angle !== layerb.angle || layera.zoomRate !== layerb.zoomRate));
  5396. var i, len, i2, i21, x, y, haspolya, haspolyb, polya, polyb;
  5397. if (!different_layers) // same layers: easy check
  5398. {
  5399. if (!a.bbox.intersects_rect(b.bbox))
  5400. return false;
  5401. if (!a.bquad.intersects_quad(b.bquad))
  5402. return false;
  5403. if (a.tilemap_exists && b.tilemap_exists)
  5404. return false;
  5405. if (a.tilemap_exists)
  5406. return this.testTilemapOverlap(a, b);
  5407. if (b.tilemap_exists)
  5408. return this.testTilemapOverlap(b, a);
  5409. haspolya = (a.collision_poly && !a.collision_poly.is_empty());
  5410. haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
  5411. if (!haspolya && !haspolyb)
  5412. return true;
  5413. if (haspolya)
  5414. {
  5415. a.collision_poly.cache_poly(a.width, a.height, a.angle);
  5416. polya = a.collision_poly;
  5417. }
  5418. else
  5419. {
  5420. this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
  5421. polya = this.temp_poly;
  5422. }
  5423. if (haspolyb)
  5424. {
  5425. b.collision_poly.cache_poly(b.width, b.height, b.angle);
  5426. polyb = b.collision_poly;
  5427. }
  5428. else
  5429. {
  5430. this.temp_poly.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
  5431. polyb = this.temp_poly;
  5432. }
  5433. return polya.intersects_poly(polyb, b.x - a.x, b.y - a.y);
  5434. }
  5435. else // different layers: need to do full translated check
  5436. {
  5437. haspolya = (a.collision_poly && !a.collision_poly.is_empty());
  5438. haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
  5439. if (haspolya)
  5440. {
  5441. a.collision_poly.cache_poly(a.width, a.height, a.angle);
  5442. this.temp_poly.set_from_poly(a.collision_poly);
  5443. }
  5444. else
  5445. {
  5446. this.temp_poly.set_from_quad(a.bquad, a.x, a.y, a.width, a.height);
  5447. }
  5448. polya = this.temp_poly;
  5449. if (haspolyb)
  5450. {
  5451. b.collision_poly.cache_poly(b.width, b.height, b.angle);
  5452. this.temp_poly2.set_from_poly(b.collision_poly);
  5453. }
  5454. else
  5455. {
  5456. this.temp_poly2.set_from_quad(b.bquad, b.x, b.y, b.width, b.height);
  5457. }
  5458. polyb = this.temp_poly2;
  5459. for (i = 0, len = polya.pts_count; i < len; i++)
  5460. {
  5461. i2 = i * 2;
  5462. i21 = i2 + 1;
  5463. x = polya.pts_cache[i2];
  5464. y = polya.pts_cache[i21];
  5465. polya.pts_cache[i2] = layera.layerToCanvas(x + a.x, y + a.y, true);
  5466. polya.pts_cache[i21] = layera.layerToCanvas(x + a.x, y + a.y, false);
  5467. }
  5468. polya.update_bbox();
  5469. for (i = 0, len = polyb.pts_count; i < len; i++)
  5470. {
  5471. i2 = i * 2;
  5472. i21 = i2 + 1;
  5473. x = polyb.pts_cache[i2];
  5474. y = polyb.pts_cache[i21];
  5475. polyb.pts_cache[i2] = layerb.layerToCanvas(x + b.x, y + b.y, true);
  5476. polyb.pts_cache[i21] = layerb.layerToCanvas(x + b.x, y + b.y, false);
  5477. }
  5478. polyb.update_bbox();
  5479. return polya.intersects_poly(polyb, 0, 0);
  5480. }
  5481. };
  5482. var tmpQuad = new cr.quad();
  5483. var tmpRect = new cr.rect(0, 0, 0, 0);
  5484. var collrect_candidates = [];
  5485. Runtime.prototype.testTilemapOverlap = function (tm, a)
  5486. {
  5487. var i, len, c, rc;
  5488. var bbox = a.bbox;
  5489. var tmx = tm.x;
  5490. var tmy = tm.y;
  5491. tm.getCollisionRectCandidates(bbox, collrect_candidates);
  5492. var collrects = collrect_candidates;
  5493. var haspolya = (a.collision_poly && !a.collision_poly.is_empty());
  5494. for (i = 0, len = collrects.length; i < len; ++i)
  5495. {
  5496. c = collrects[i];
  5497. rc = c.rc;
  5498. if (bbox.intersects_rect_off(rc, tmx, tmy))
  5499. {
  5500. tmpQuad.set_from_rect(rc);
  5501. tmpQuad.offset(tmx, tmy);
  5502. if (tmpQuad.intersects_quad(a.bquad))
  5503. {
  5504. if (haspolya)
  5505. {
  5506. a.collision_poly.cache_poly(a.width, a.height, a.angle);
  5507. if (c.poly)
  5508. {
  5509. if (c.poly.intersects_poly(a.collision_poly, a.x - (tmx + rc.left), a.y - (tmy + rc.top)))
  5510. {
  5511. collrect_candidates.length = 0;
  5512. return true;
  5513. }
  5514. }
  5515. else
  5516. {
  5517. this.temp_poly.set_from_quad(tmpQuad, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
  5518. if (this.temp_poly.intersects_poly(a.collision_poly, a.x, a.y))
  5519. {
  5520. collrect_candidates.length = 0;
  5521. return true;
  5522. }
  5523. }
  5524. }
  5525. else
  5526. {
  5527. if (c.poly)
  5528. {
  5529. this.temp_poly.set_from_quad(a.bquad, 0, 0, a.width, a.height);
  5530. if (c.poly.intersects_poly(this.temp_poly, -(tmx + rc.left), -(tmy + rc.top)))
  5531. {
  5532. collrect_candidates.length = 0;
  5533. return true;
  5534. }
  5535. }
  5536. else
  5537. {
  5538. collrect_candidates.length = 0;
  5539. return true;
  5540. }
  5541. }
  5542. }
  5543. }
  5544. }
  5545. collrect_candidates.length = 0;
  5546. return false;
  5547. };
  5548. Runtime.prototype.testRectOverlap = function (r, b)
  5549. {
  5550. if (!b || !b.collisionsEnabled)
  5551. return false;
  5552. b.update_bbox();
  5553. var layerb = b.layer;
  5554. var haspolyb, polyb;
  5555. if (!b.bbox.intersects_rect(r))
  5556. return false;
  5557. if (b.tilemap_exists)
  5558. {
  5559. b.getCollisionRectCandidates(r, collrect_candidates);
  5560. var collrects = collrect_candidates;
  5561. var i, len, c, tilerc;
  5562. var tmx = b.x;
  5563. var tmy = b.y;
  5564. for (i = 0, len = collrects.length; i < len; ++i)
  5565. {
  5566. c = collrects[i];
  5567. tilerc = c.rc;
  5568. if (r.intersects_rect_off(tilerc, tmx, tmy))
  5569. {
  5570. if (c.poly)
  5571. {
  5572. this.temp_poly.set_from_rect(r, 0, 0);
  5573. if (c.poly.intersects_poly(this.temp_poly, -(tmx + tilerc.left), -(tmy + tilerc.top)))
  5574. {
  5575. collrect_candidates.length = 0;
  5576. return true;
  5577. }
  5578. }
  5579. else
  5580. {
  5581. collrect_candidates.length = 0;
  5582. return true;
  5583. }
  5584. }
  5585. }
  5586. collrect_candidates.length = 0;
  5587. return false;
  5588. }
  5589. else
  5590. {
  5591. tmpQuad.set_from_rect(r);
  5592. if (!b.bquad.intersects_quad(tmpQuad))
  5593. return false;
  5594. haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
  5595. if (!haspolyb)
  5596. return true;
  5597. b.collision_poly.cache_poly(b.width, b.height, b.angle);
  5598. tmpQuad.offset(-r.left, -r.top);
  5599. this.temp_poly.set_from_quad(tmpQuad, 0, 0, 1, 1);
  5600. return b.collision_poly.intersects_poly(this.temp_poly, r.left - b.x, r.top - b.y);
  5601. }
  5602. };
  5603. Runtime.prototype.testSegmentOverlap = function (x1, y1, x2, y2, b)
  5604. {
  5605. if (!b || !b.collisionsEnabled)
  5606. return false;
  5607. b.update_bbox();
  5608. var layerb = b.layer;
  5609. var haspolyb, polyb;
  5610. tmpRect.set(cr.min(x1, x2), cr.min(y1, y2), cr.max(x1, x2), cr.max(y1, y2));
  5611. if (!b.bbox.intersects_rect(tmpRect))
  5612. return false;
  5613. if (b.tilemap_exists)
  5614. {
  5615. b.getCollisionRectCandidates(tmpRect, collrect_candidates);
  5616. var collrects = collrect_candidates;
  5617. var i, len, c, tilerc;
  5618. var tmx = b.x;
  5619. var tmy = b.y;
  5620. for (i = 0, len = collrects.length; i < len; ++i)
  5621. {
  5622. c = collrects[i];
  5623. tilerc = c.rc;
  5624. if (tmpRect.intersects_rect_off(tilerc, tmx, tmy))
  5625. {
  5626. tmpQuad.set_from_rect(tilerc);
  5627. tmpQuad.offset(tmx, tmy);
  5628. if (tmpQuad.intersects_segment(x1, y1, x2, y2))
  5629. {
  5630. if (c.poly)
  5631. {
  5632. if (c.poly.intersects_segment(tmx + tilerc.left, tmy + tilerc.top, x1, y1, x2, y2))
  5633. {
  5634. collrect_candidates.length = 0;
  5635. return true;
  5636. }
  5637. }
  5638. else
  5639. {
  5640. collrect_candidates.length = 0;
  5641. return true;
  5642. }
  5643. }
  5644. }
  5645. }
  5646. collrect_candidates.length = 0;
  5647. return false;
  5648. }
  5649. else
  5650. {
  5651. if (!b.bquad.intersects_segment(x1, y1, x2, y2))
  5652. return false;
  5653. haspolyb = (b.collision_poly && !b.collision_poly.is_empty());
  5654. if (!haspolyb)
  5655. return true;
  5656. b.collision_poly.cache_poly(b.width, b.height, b.angle);
  5657. return b.collision_poly.intersects_segment(b.x, b.y, x1, y1, x2, y2);
  5658. }
  5659. };
  5660. Runtime.prototype.typeHasBehavior = function (t, b)
  5661. {
  5662. if (!b)
  5663. return false;
  5664. var i, len, j, lenj, f;
  5665. for (i = 0, len = t.behaviors.length; i < len; i++)
  5666. {
  5667. if (t.behaviors[i].behavior instanceof b)
  5668. return true;
  5669. }
  5670. if (!t.is_family)
  5671. {
  5672. for (i = 0, len = t.families.length; i < len; i++)
  5673. {
  5674. f = t.families[i];
  5675. for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
  5676. {
  5677. if (f.behaviors[j].behavior instanceof b)
  5678. return true;
  5679. }
  5680. }
  5681. }
  5682. return false;
  5683. };
  5684. Runtime.prototype.typeHasNoSaveBehavior = function (t)
  5685. {
  5686. return this.typeHasBehavior(t, cr.behaviors.NoSave);
  5687. };
  5688. Runtime.prototype.typeHasPersistBehavior = function (t)
  5689. {
  5690. return this.typeHasBehavior(t, cr.behaviors.Persist);
  5691. };
  5692. Runtime.prototype.getSolidBehavior = function ()
  5693. {
  5694. return this.solidBehavior;
  5695. };
  5696. Runtime.prototype.getJumpthruBehavior = function ()
  5697. {
  5698. return this.jumpthruBehavior;
  5699. };
  5700. var candidates = [];
  5701. Runtime.prototype.testOverlapSolid = function (inst)
  5702. {
  5703. var i, len, s;
  5704. inst.update_bbox();
  5705. this.getSolidCollisionCandidates(inst.layer, inst.bbox, candidates);
  5706. for (i = 0, len = candidates.length; i < len; ++i)
  5707. {
  5708. s = candidates[i];
  5709. if (!s.extra["solidEnabled"])
  5710. continue;
  5711. if (this.testOverlap(inst, s))
  5712. {
  5713. candidates.length = 0;
  5714. return s;
  5715. }
  5716. }
  5717. candidates.length = 0;
  5718. return null;
  5719. };
  5720. Runtime.prototype.testRectOverlapSolid = function (r)
  5721. {
  5722. var i, len, s;
  5723. this.getSolidCollisionCandidates(null, r, candidates);
  5724. for (i = 0, len = candidates.length; i < len; ++i)
  5725. {
  5726. s = candidates[i];
  5727. if (!s.extra["solidEnabled"])
  5728. continue;
  5729. if (this.testRectOverlap(r, s))
  5730. {
  5731. candidates.length = 0;
  5732. return s;
  5733. }
  5734. }
  5735. candidates.length = 0;
  5736. return null;
  5737. };
  5738. var jumpthru_array_ret = [];
  5739. Runtime.prototype.testOverlapJumpThru = function (inst, all)
  5740. {
  5741. var ret = null;
  5742. if (all)
  5743. {
  5744. ret = jumpthru_array_ret;
  5745. ret.length = 0;
  5746. }
  5747. inst.update_bbox();
  5748. this.getJumpthruCollisionCandidates(inst.layer, inst.bbox, candidates);
  5749. var i, len, j;
  5750. for (i = 0, len = candidates.length; i < len; ++i)
  5751. {
  5752. j = candidates[i];
  5753. if (!j.extra["jumpthruEnabled"])
  5754. continue;
  5755. if (this.testOverlap(inst, j))
  5756. {
  5757. if (all)
  5758. ret.push(j);
  5759. else
  5760. {
  5761. candidates.length = 0;
  5762. return j;
  5763. }
  5764. }
  5765. }
  5766. candidates.length = 0;
  5767. return ret;
  5768. };
  5769. Runtime.prototype.pushOutSolid = function (inst, xdir, ydir, dist, include_jumpthrus, specific_jumpthru)
  5770. {
  5771. var push_dist = dist || 50;
  5772. var oldx = inst.x
  5773. var oldy = inst.y;
  5774. var i;
  5775. var last_overlapped = null, secondlast_overlapped = null;
  5776. for (i = 0; i < push_dist; i++)
  5777. {
  5778. inst.x = (oldx + (xdir * i));
  5779. inst.y = (oldy + (ydir * i));
  5780. inst.set_bbox_changed();
  5781. if (!this.testOverlap(inst, last_overlapped))
  5782. {
  5783. last_overlapped = this.testOverlapSolid(inst);
  5784. if (last_overlapped)
  5785. secondlast_overlapped = last_overlapped;
  5786. if (!last_overlapped)
  5787. {
  5788. if (include_jumpthrus)
  5789. {
  5790. if (specific_jumpthru)
  5791. last_overlapped = (this.testOverlap(inst, specific_jumpthru) ? specific_jumpthru : null);
  5792. else
  5793. last_overlapped = this.testOverlapJumpThru(inst);
  5794. if (last_overlapped)
  5795. secondlast_overlapped = last_overlapped;
  5796. }
  5797. if (!last_overlapped)
  5798. {
  5799. if (secondlast_overlapped)
  5800. this.pushInFractional(inst, xdir, ydir, secondlast_overlapped, 16);
  5801. return true;
  5802. }
  5803. }
  5804. }
  5805. }
  5806. inst.x = oldx;
  5807. inst.y = oldy;
  5808. inst.set_bbox_changed();
  5809. return false;
  5810. };
  5811. Runtime.prototype.pushOut = function (inst, xdir, ydir, dist, otherinst)
  5812. {
  5813. var push_dist = dist || 50;
  5814. var oldx = inst.x
  5815. var oldy = inst.y;
  5816. var i;
  5817. for (i = 0; i < push_dist; i++)
  5818. {
  5819. inst.x = (oldx + (xdir * i));
  5820. inst.y = (oldy + (ydir * i));
  5821. inst.set_bbox_changed();
  5822. if (!this.testOverlap(inst, otherinst))
  5823. return true;
  5824. }
  5825. inst.x = oldx;
  5826. inst.y = oldy;
  5827. inst.set_bbox_changed();
  5828. return false;
  5829. };
  5830. Runtime.prototype.pushInFractional = function (inst, xdir, ydir, obj, limit)
  5831. {
  5832. var divisor = 2;
  5833. var frac;
  5834. var forward = false;
  5835. var overlapping = false;
  5836. var bestx = inst.x;
  5837. var besty = inst.y;
  5838. while (divisor <= limit)
  5839. {
  5840. frac = 1 / divisor;
  5841. divisor *= 2;
  5842. inst.x += xdir * frac * (forward ? 1 : -1);
  5843. inst.y += ydir * frac * (forward ? 1 : -1);
  5844. inst.set_bbox_changed();
  5845. if (this.testOverlap(inst, obj))
  5846. {
  5847. forward = true;
  5848. overlapping = true;
  5849. }
  5850. else
  5851. {
  5852. forward = false;
  5853. overlapping = false;
  5854. bestx = inst.x;
  5855. besty = inst.y;
  5856. }
  5857. }
  5858. if (overlapping)
  5859. {
  5860. inst.x = bestx;
  5861. inst.y = besty;
  5862. inst.set_bbox_changed();
  5863. }
  5864. };
  5865. Runtime.prototype.pushOutSolidNearest = function (inst, max_dist_)
  5866. {
  5867. var max_dist = (cr.is_undefined(max_dist_) ? 100 : max_dist_);
  5868. var dist = 0;
  5869. var oldx = inst.x
  5870. var oldy = inst.y;
  5871. var dir = 0;
  5872. var dx = 0, dy = 0;
  5873. var last_overlapped = this.testOverlapSolid(inst);
  5874. if (!last_overlapped)
  5875. return true; // already clear of solids
  5876. while (dist <= max_dist)
  5877. {
  5878. switch (dir) {
  5879. case 0: dx = 0; dy = -1; dist++; break;
  5880. case 1: dx = 1; dy = -1; break;
  5881. case 2: dx = 1; dy = 0; break;
  5882. case 3: dx = 1; dy = 1; break;
  5883. case 4: dx = 0; dy = 1; break;
  5884. case 5: dx = -1; dy = 1; break;
  5885. case 6: dx = -1; dy = 0; break;
  5886. case 7: dx = -1; dy = -1; break;
  5887. }
  5888. dir = (dir + 1) % 8;
  5889. inst.x = cr.floor(oldx + (dx * dist));
  5890. inst.y = cr.floor(oldy + (dy * dist));
  5891. inst.set_bbox_changed();
  5892. if (!this.testOverlap(inst, last_overlapped))
  5893. {
  5894. last_overlapped = this.testOverlapSolid(inst);
  5895. if (!last_overlapped)
  5896. return true;
  5897. }
  5898. }
  5899. inst.x = oldx;
  5900. inst.y = oldy;
  5901. inst.set_bbox_changed();
  5902. return false;
  5903. };
  5904. Runtime.prototype.registerCollision = function (a, b)
  5905. {
  5906. if (!a.collisionsEnabled || !b.collisionsEnabled)
  5907. return;
  5908. this.registered_collisions.push([a, b]);
  5909. };
  5910. Runtime.prototype.checkRegisteredCollision = function (a, b)
  5911. {
  5912. var i, len, x;
  5913. for (i = 0, len = this.registered_collisions.length; i < len; i++)
  5914. {
  5915. x = this.registered_collisions[i];
  5916. if ((x[0] == a && x[1] == b) || (x[0] == b && x[1] == a))
  5917. return true;
  5918. }
  5919. return false;
  5920. };
  5921. Runtime.prototype.calculateSolidBounceAngle = function(inst, startx, starty, obj)
  5922. {
  5923. var objx = inst.x;
  5924. var objy = inst.y;
  5925. var radius = cr.max(10, cr.distanceTo(startx, starty, objx, objy));
  5926. var startangle = cr.angleTo(startx, starty, objx, objy);
  5927. var firstsolid = obj || this.testOverlapSolid(inst);
  5928. if (!firstsolid)
  5929. return cr.clamp_angle(startangle + cr.PI);
  5930. var cursolid = firstsolid;
  5931. var i, curangle, anticlockwise_free_angle, clockwise_free_angle;
  5932. var increment = cr.to_radians(5); // 5 degree increments
  5933. for (i = 1; i < 36; i++)
  5934. {
  5935. curangle = startangle - i * increment;
  5936. inst.x = startx + Math.cos(curangle) * radius;
  5937. inst.y = starty + Math.sin(curangle) * radius;
  5938. inst.set_bbox_changed();
  5939. if (!this.testOverlap(inst, cursolid))
  5940. {
  5941. cursolid = obj ? null : this.testOverlapSolid(inst);
  5942. if (!cursolid)
  5943. {
  5944. anticlockwise_free_angle = curangle;
  5945. break;
  5946. }
  5947. }
  5948. }
  5949. if (i === 36)
  5950. anticlockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
  5951. var cursolid = firstsolid;
  5952. for (i = 1; i < 36; i++)
  5953. {
  5954. curangle = startangle + i * increment;
  5955. inst.x = startx + Math.cos(curangle) * radius;
  5956. inst.y = starty + Math.sin(curangle) * radius;
  5957. inst.set_bbox_changed();
  5958. if (!this.testOverlap(inst, cursolid))
  5959. {
  5960. cursolid = obj ? null : this.testOverlapSolid(inst);
  5961. if (!cursolid)
  5962. {
  5963. clockwise_free_angle = curangle;
  5964. break;
  5965. }
  5966. }
  5967. }
  5968. if (i === 36)
  5969. clockwise_free_angle = cr.clamp_angle(startangle + cr.PI);
  5970. inst.x = objx;
  5971. inst.y = objy;
  5972. inst.set_bbox_changed();
  5973. if (clockwise_free_angle === anticlockwise_free_angle)
  5974. return clockwise_free_angle;
  5975. var half_diff = cr.angleDiff(clockwise_free_angle, anticlockwise_free_angle) / 2;
  5976. var normal;
  5977. if (cr.angleClockwise(clockwise_free_angle, anticlockwise_free_angle))
  5978. {
  5979. normal = cr.clamp_angle(anticlockwise_free_angle + half_diff + cr.PI);
  5980. }
  5981. else
  5982. {
  5983. normal = cr.clamp_angle(clockwise_free_angle + half_diff);
  5984. }
  5985. ;
  5986. var vx = Math.cos(startangle);
  5987. var vy = Math.sin(startangle);
  5988. var nx = Math.cos(normal);
  5989. var ny = Math.sin(normal);
  5990. var v_dot_n = vx * nx + vy * ny;
  5991. var rx = vx - 2 * v_dot_n * nx;
  5992. var ry = vy - 2 * v_dot_n * ny;
  5993. return cr.angleTo(0, 0, rx, ry);
  5994. };
  5995. var triggerSheetIndex = -1;
  5996. Runtime.prototype.trigger = function (method, inst, value /* for fast triggers */)
  5997. {
  5998. ;
  5999. if (!this.running_layout)
  6000. return false;
  6001. var sheet = this.running_layout.event_sheet;
  6002. if (!sheet)
  6003. return false; // no event sheet active; nothing to trigger
  6004. var ret = false;
  6005. var r, i, len;
  6006. triggerSheetIndex++;
  6007. var deep_includes = sheet.deep_includes;
  6008. for (i = 0, len = deep_includes.length; i < len; ++i)
  6009. {
  6010. r = this.triggerOnSheet(method, inst, deep_includes[i], value);
  6011. ret = ret || r;
  6012. }
  6013. r = this.triggerOnSheet(method, inst, sheet, value);
  6014. ret = ret || r;
  6015. triggerSheetIndex--;
  6016. return ret;
  6017. };
  6018. Runtime.prototype.triggerOnSheet = function (method, inst, sheet, value)
  6019. {
  6020. var ret = false;
  6021. var i, leni, r, families;
  6022. if (!inst)
  6023. {
  6024. r = this.triggerOnSheetForTypeName(method, inst, "system", sheet, value);
  6025. ret = ret || r;
  6026. }
  6027. else
  6028. {
  6029. r = this.triggerOnSheetForTypeName(method, inst, inst.type.name, sheet, value);
  6030. ret = ret || r;
  6031. families = inst.type.families;
  6032. for (i = 0, leni = families.length; i < leni; ++i)
  6033. {
  6034. r = this.triggerOnSheetForTypeName(method, inst, families[i].name, sheet, value);
  6035. ret = ret || r;
  6036. }
  6037. }
  6038. return ret; // true if anything got triggered
  6039. };
  6040. Runtime.prototype.triggerOnSheetForTypeName = function (method, inst, type_name, sheet, value)
  6041. {
  6042. var i, leni;
  6043. var ret = false, ret2 = false;
  6044. var trig, index;
  6045. var fasttrigger = (typeof value !== "undefined");
  6046. var triggers = (fasttrigger ? sheet.fasttriggers : sheet.triggers);
  6047. var obj_entry = triggers[type_name];
  6048. if (!obj_entry)
  6049. return ret;
  6050. var triggers_list = null;
  6051. for (i = 0, leni = obj_entry.length; i < leni; ++i)
  6052. {
  6053. if (obj_entry[i].method == method)
  6054. {
  6055. triggers_list = obj_entry[i].evs;
  6056. break;
  6057. }
  6058. }
  6059. if (!triggers_list)
  6060. return ret;
  6061. var triggers_to_fire;
  6062. if (fasttrigger)
  6063. {
  6064. triggers_to_fire = triggers_list[value];
  6065. }
  6066. else
  6067. {
  6068. triggers_to_fire = triggers_list;
  6069. }
  6070. if (!triggers_to_fire)
  6071. return null;
  6072. for (i = 0, leni = triggers_to_fire.length; i < leni; i++)
  6073. {
  6074. trig = triggers_to_fire[i][0];
  6075. index = triggers_to_fire[i][1];
  6076. ret2 = this.executeSingleTrigger(inst, type_name, trig, index);
  6077. ret = ret || ret2;
  6078. }
  6079. return ret;
  6080. };
  6081. Runtime.prototype.executeSingleTrigger = function (inst, type_name, trig, index)
  6082. {
  6083. var i, leni;
  6084. var ret = false;
  6085. this.trigger_depth++;
  6086. var current_event = this.getCurrentEventStack().current_event;
  6087. if (current_event)
  6088. this.pushCleanSol(current_event.solModifiersIncludingParents);
  6089. var isrecursive = (this.trigger_depth > 1); // calling trigger from inside another trigger
  6090. this.pushCleanSol(trig.solModifiersIncludingParents);
  6091. if (isrecursive)
  6092. this.pushLocalVarStack();
  6093. var event_stack = this.pushEventStack(trig);
  6094. event_stack.current_event = trig;
  6095. if (inst)
  6096. {
  6097. var sol = this.types[type_name].getCurrentSol();
  6098. sol.select_all = false;
  6099. sol.instances.length = 1;
  6100. sol.instances[0] = inst;
  6101. this.types[type_name].applySolToContainer();
  6102. }
  6103. var ok_to_run = true;
  6104. if (trig.parent)
  6105. {
  6106. var temp_parents_arr = event_stack.temp_parents_arr;
  6107. var cur_parent = trig.parent;
  6108. while (cur_parent)
  6109. {
  6110. temp_parents_arr.push(cur_parent);
  6111. cur_parent = cur_parent.parent;
  6112. }
  6113. temp_parents_arr.reverse();
  6114. for (i = 0, leni = temp_parents_arr.length; i < leni; i++)
  6115. {
  6116. if (!temp_parents_arr[i].run_pretrigger()) // parent event failed
  6117. {
  6118. ok_to_run = false;
  6119. break;
  6120. }
  6121. }
  6122. }
  6123. if (ok_to_run)
  6124. {
  6125. this.execcount++;
  6126. if (trig.orblock)
  6127. trig.run_orblocktrigger(index);
  6128. else
  6129. trig.run();
  6130. ret = ret || event_stack.last_event_true;
  6131. }
  6132. this.popEventStack();
  6133. if (isrecursive)
  6134. this.popLocalVarStack();
  6135. this.popSol(trig.solModifiersIncludingParents);
  6136. if (current_event)
  6137. this.popSol(current_event.solModifiersIncludingParents);
  6138. if (this.hasPendingInstances && this.isInOnDestroy === 0 && triggerSheetIndex === 0 && !this.isRunningEvents)
  6139. {
  6140. this.ClearDeathRow();
  6141. }
  6142. this.trigger_depth--;
  6143. return ret;
  6144. };
  6145. Runtime.prototype.getCurrentCondition = function ()
  6146. {
  6147. var evinfo = this.getCurrentEventStack();
  6148. return evinfo.current_event.conditions[evinfo.cndindex];
  6149. };
  6150. Runtime.prototype.getCurrentAction = function ()
  6151. {
  6152. var evinfo = this.getCurrentEventStack();
  6153. return evinfo.current_event.actions[evinfo.actindex];
  6154. };
  6155. Runtime.prototype.pushLocalVarStack = function ()
  6156. {
  6157. this.localvar_stack_index++;
  6158. if (this.localvar_stack_index >= this.localvar_stack.length)
  6159. this.localvar_stack.push([]);
  6160. };
  6161. Runtime.prototype.popLocalVarStack = function ()
  6162. {
  6163. ;
  6164. this.localvar_stack_index--;
  6165. };
  6166. Runtime.prototype.getCurrentLocalVarStack = function ()
  6167. {
  6168. return this.localvar_stack[this.localvar_stack_index];
  6169. };
  6170. Runtime.prototype.pushEventStack = function (cur_event)
  6171. {
  6172. this.event_stack_index++;
  6173. if (this.event_stack_index >= this.event_stack.length)
  6174. this.event_stack.push(new cr.eventStackFrame());
  6175. var ret = this.getCurrentEventStack();
  6176. ret.reset(cur_event);
  6177. return ret;
  6178. };
  6179. Runtime.prototype.popEventStack = function ()
  6180. {
  6181. ;
  6182. this.event_stack_index--;
  6183. };
  6184. Runtime.prototype.getCurrentEventStack = function ()
  6185. {
  6186. return this.event_stack[this.event_stack_index];
  6187. };
  6188. Runtime.prototype.pushLoopStack = function (name_)
  6189. {
  6190. this.loop_stack_index++;
  6191. if (this.loop_stack_index >= this.loop_stack.length)
  6192. {
  6193. this.loop_stack.push(cr.seal({ name: name_, index: 0, stopped: false }));
  6194. }
  6195. var ret = this.getCurrentLoop();
  6196. ret.name = name_;
  6197. ret.index = 0;
  6198. ret.stopped = false;
  6199. return ret;
  6200. };
  6201. Runtime.prototype.popLoopStack = function ()
  6202. {
  6203. ;
  6204. this.loop_stack_index--;
  6205. };
  6206. Runtime.prototype.getCurrentLoop = function ()
  6207. {
  6208. return this.loop_stack[this.loop_stack_index];
  6209. };
  6210. Runtime.prototype.getEventVariableByName = function (name, scope)
  6211. {
  6212. var i, leni, j, lenj, sheet, e;
  6213. while (scope)
  6214. {
  6215. for (i = 0, leni = scope.subevents.length; i < leni; i++)
  6216. {
  6217. e = scope.subevents[i];
  6218. if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
  6219. return e;
  6220. }
  6221. scope = scope.parent;
  6222. }
  6223. for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
  6224. {
  6225. sheet = this.eventsheets_by_index[i];
  6226. for (j = 0, lenj = sheet.events.length; j < lenj; j++)
  6227. {
  6228. e = sheet.events[j];
  6229. if (e instanceof cr.eventvariable && cr.equals_nocase(name, e.name))
  6230. return e;
  6231. }
  6232. }
  6233. return null;
  6234. };
  6235. Runtime.prototype.getLayoutBySid = function (sid_)
  6236. {
  6237. var i, len;
  6238. for (i = 0, len = this.layouts_by_index.length; i < len; i++)
  6239. {
  6240. if (this.layouts_by_index[i].sid === sid_)
  6241. return this.layouts_by_index[i];
  6242. }
  6243. return null;
  6244. };
  6245. Runtime.prototype.getObjectTypeBySid = function (sid_)
  6246. {
  6247. var i, len;
  6248. for (i = 0, len = this.types_by_index.length; i < len; i++)
  6249. {
  6250. if (this.types_by_index[i].sid === sid_)
  6251. return this.types_by_index[i];
  6252. }
  6253. return null;
  6254. };
  6255. Runtime.prototype.getGroupBySid = function (sid_)
  6256. {
  6257. var i, len;
  6258. for (i = 0, len = this.allGroups.length; i < len; i++)
  6259. {
  6260. if (this.allGroups[i].sid === sid_)
  6261. return this.allGroups[i];
  6262. }
  6263. return null;
  6264. };
  6265. Runtime.prototype.doCanvasSnapshot = function (format_, quality_)
  6266. {
  6267. this.snapshotCanvas = [format_, quality_];
  6268. this.redraw = true; // force redraw so snapshot is always taken
  6269. };
  6270. function makeSaveDb(e)
  6271. {
  6272. var db = e.target.result;
  6273. db.createObjectStore("saves", { keyPath: "slot" });
  6274. };
  6275. function IndexedDB_WriteSlot(slot_, data_, oncomplete_, onerror_)
  6276. {
  6277. var request = indexedDB.open("_C2SaveStates");
  6278. request.onupgradeneeded = makeSaveDb;
  6279. request.onerror = onerror_;
  6280. request.onsuccess = function (e)
  6281. {
  6282. var db = e.target.result;
  6283. db.onerror = onerror_;
  6284. var transaction = db.transaction(["saves"], "readwrite");
  6285. var objectStore = transaction.objectStore("saves");
  6286. var putReq = objectStore.put({"slot": slot_, "data": data_ });
  6287. putReq.onsuccess = oncomplete_;
  6288. };
  6289. };
  6290. function IndexedDB_ReadSlot(slot_, oncomplete_, onerror_)
  6291. {
  6292. var request = indexedDB.open("_C2SaveStates");
  6293. request.onupgradeneeded = makeSaveDb;
  6294. request.onerror = onerror_;
  6295. request.onsuccess = function (e)
  6296. {
  6297. var db = e.target.result;
  6298. db.onerror = onerror_;
  6299. var transaction = db.transaction(["saves"]);
  6300. var objectStore = transaction.objectStore("saves");
  6301. var readReq = objectStore.get(slot_);
  6302. readReq.onsuccess = function (e)
  6303. {
  6304. if (readReq.result)
  6305. oncomplete_(readReq.result["data"]);
  6306. else
  6307. oncomplete_(null);
  6308. };
  6309. };
  6310. };
  6311. Runtime.prototype.signalContinuousPreview = function ()
  6312. {
  6313. this.signalledContinuousPreview = true;
  6314. };
  6315. function doContinuousPreviewReload()
  6316. {
  6317. cr.logexport("Reloading for continuous preview");
  6318. if (!!window["c2cocoonjs"])
  6319. {
  6320. CocoonJS["App"]["reload"]();
  6321. }
  6322. else
  6323. {
  6324. if (window.location.search.indexOf("continuous") > -1)
  6325. window.location.reload(true);
  6326. else
  6327. window.location = window.location + "?continuous";
  6328. }
  6329. };
  6330. Runtime.prototype.handleSaveLoad = function ()
  6331. {
  6332. var self = this;
  6333. var savingToSlot = this.saveToSlot;
  6334. var savingJson = this.lastSaveJson;
  6335. var loadingFromSlot = this.loadFromSlot;
  6336. var continuous = false;
  6337. if (this.signalledContinuousPreview)
  6338. {
  6339. continuous = true;
  6340. savingToSlot = "__c2_continuouspreview";
  6341. this.signalledContinuousPreview = false;
  6342. }
  6343. if (savingToSlot.length)
  6344. {
  6345. this.ClearDeathRow();
  6346. savingJson = this.saveToJSONString();
  6347. if (window.indexedDB && !this.isCocoonJs)
  6348. {
  6349. IndexedDB_WriteSlot(savingToSlot, savingJson, function ()
  6350. {
  6351. cr.logexport("Saved state to IndexedDB storage (" + savingJson.length + " bytes)");
  6352. self.lastSaveJson = savingJson;
  6353. self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
  6354. self.lastSaveJson = "";
  6355. if (continuous)
  6356. doContinuousPreviewReload();
  6357. }, function (e)
  6358. {
  6359. try {
  6360. localStorage.setItem("__c2save_" + savingToSlot, savingJson);
  6361. cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
  6362. self.lastSaveJson = savingJson;
  6363. self.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
  6364. self.lastSaveJson = "";
  6365. if (continuous)
  6366. doContinuousPreviewReload();
  6367. }
  6368. catch (f)
  6369. {
  6370. cr.logexport("Failed to save game state: " + e + "; " + f);
  6371. }
  6372. });
  6373. }
  6374. else
  6375. {
  6376. try {
  6377. localStorage.setItem("__c2save_" + savingToSlot, savingJson);
  6378. cr.logexport("Saved state to WebStorage (" + savingJson.length + " bytes)");
  6379. self.lastSaveJson = savingJson;
  6380. this.trigger(cr.system_object.prototype.cnds.OnSaveComplete, null);
  6381. self.lastSaveJson = "";
  6382. if (continuous)
  6383. doContinuousPreviewReload();
  6384. }
  6385. catch (e)
  6386. {
  6387. cr.logexport("Error saving to WebStorage: " + e);
  6388. }
  6389. }
  6390. this.saveToSlot = "";
  6391. this.loadFromSlot = "";
  6392. this.loadFromJson = "";
  6393. }
  6394. if (loadingFromSlot.length)
  6395. {
  6396. if (window.indexedDB && !this.isCocoonJs)
  6397. {
  6398. IndexedDB_ReadSlot(loadingFromSlot, function (result_)
  6399. {
  6400. if (result_)
  6401. {
  6402. self.loadFromJson = result_;
  6403. cr.logexport("Loaded state from IndexedDB storage (" + self.loadFromJson.length + " bytes)");
  6404. }
  6405. else
  6406. {
  6407. self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
  6408. cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
  6409. }
  6410. self.suspendDrawing = false;
  6411. if (!self.loadFromJson.length)
  6412. self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
  6413. }, function (e)
  6414. {
  6415. self.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
  6416. cr.logexport("Loaded state from WebStorage (" + self.loadFromJson.length + " bytes)");
  6417. self.suspendDrawing = false;
  6418. if (!self.loadFromJson.length)
  6419. self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
  6420. });
  6421. }
  6422. else
  6423. {
  6424. try {
  6425. this.loadFromJson = localStorage.getItem("__c2save_" + loadingFromSlot) || "";
  6426. cr.logexport("Loaded state from WebStorage (" + this.loadFromJson.length + " bytes)");
  6427. }
  6428. catch (e)
  6429. {
  6430. this.loadFromJson = "";
  6431. }
  6432. this.suspendDrawing = false;
  6433. if (!self.loadFromJson.length)
  6434. self.trigger(cr.system_object.prototype.cnds.OnLoadFailed, null);
  6435. }
  6436. this.loadFromSlot = "";
  6437. this.saveToSlot = "";
  6438. }
  6439. if (this.loadFromJson.length)
  6440. {
  6441. this.ClearDeathRow();
  6442. this.loadFromJSONString(this.loadFromJson);
  6443. this.lastSaveJson = this.loadFromJson;
  6444. this.trigger(cr.system_object.prototype.cnds.OnLoadComplete, null);
  6445. this.lastSaveJson = "";
  6446. this.loadFromJson = "";
  6447. }
  6448. };
  6449. function CopyExtraObject(extra)
  6450. {
  6451. var p, ret = {};
  6452. for (p in extra)
  6453. {
  6454. if (extra.hasOwnProperty(p))
  6455. {
  6456. if (extra[p] instanceof cr.ObjectSet)
  6457. continue;
  6458. if (extra[p] && typeof extra[p].c2userdata !== "undefined")
  6459. continue;
  6460. ret[p] = extra[p];
  6461. }
  6462. }
  6463. return ret;
  6464. };
  6465. Runtime.prototype.saveToJSONString = function()
  6466. {
  6467. var i, len, j, lenj, type, layout, typeobj, g, c, a, v, p;
  6468. var o = {
  6469. "c2save": true,
  6470. "version": 1,
  6471. "rt": {
  6472. "time": this.kahanTime.sum,
  6473. "walltime": this.wallTime.sum,
  6474. "timescale": this.timescale,
  6475. "tickcount": this.tickcount,
  6476. "execcount": this.execcount,
  6477. "next_uid": this.next_uid,
  6478. "running_layout": this.running_layout.sid,
  6479. "start_time_offset": (Date.now() - this.start_time)
  6480. },
  6481. "types": {},
  6482. "layouts": {},
  6483. "events": {
  6484. "groups": {},
  6485. "cnds": {},
  6486. "acts": {},
  6487. "vars": {}
  6488. }
  6489. };
  6490. for (i = 0, len = this.types_by_index.length; i < len; i++)
  6491. {
  6492. type = this.types_by_index[i];
  6493. if (type.is_family || this.typeHasNoSaveBehavior(type))
  6494. continue;
  6495. typeobj = {
  6496. "instances": []
  6497. };
  6498. if (cr.hasAnyOwnProperty(type.extra))
  6499. typeobj["ex"] = CopyExtraObject(type.extra);
  6500. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  6501. {
  6502. typeobj["instances"].push(this.saveInstanceToJSON(type.instances[j]));
  6503. }
  6504. o["types"][type.sid.toString()] = typeobj;
  6505. }
  6506. for (i = 0, len = this.layouts_by_index.length; i < len; i++)
  6507. {
  6508. layout = this.layouts_by_index[i];
  6509. o["layouts"][layout.sid.toString()] = layout.saveToJSON();
  6510. }
  6511. var ogroups = o["events"]["groups"];
  6512. for (i = 0, len = this.allGroups.length; i < len; i++)
  6513. {
  6514. g = this.allGroups[i];
  6515. ogroups[g.sid.toString()] = this.groups_by_name[g.group_name].group_active;
  6516. }
  6517. var ocnds = o["events"]["cnds"];
  6518. for (p in this.cndsBySid)
  6519. {
  6520. if (this.cndsBySid.hasOwnProperty(p))
  6521. {
  6522. c = this.cndsBySid[p];
  6523. if (cr.hasAnyOwnProperty(c.extra))
  6524. ocnds[p] = { "ex": CopyExtraObject(c.extra) };
  6525. }
  6526. }
  6527. var oacts = o["events"]["acts"];
  6528. for (p in this.actsBySid)
  6529. {
  6530. if (this.actsBySid.hasOwnProperty(p))
  6531. {
  6532. a = this.actsBySid[p];
  6533. if (cr.hasAnyOwnProperty(a.extra))
  6534. oacts[p] = { "ex": a.extra };
  6535. }
  6536. }
  6537. var ovars = o["events"]["vars"];
  6538. for (p in this.varsBySid)
  6539. {
  6540. if (this.varsBySid.hasOwnProperty(p))
  6541. {
  6542. v = this.varsBySid[p];
  6543. if (!v.is_constant && (!v.parent || v.is_static))
  6544. ovars[p] = v.data;
  6545. }
  6546. }
  6547. o["system"] = this.system.saveToJSON();
  6548. return JSON.stringify(o);
  6549. };
  6550. Runtime.prototype.refreshUidMap = function ()
  6551. {
  6552. var i, len, type, j, lenj, inst;
  6553. this.objectsByUid = {};
  6554. for (i = 0, len = this.types_by_index.length; i < len; i++)
  6555. {
  6556. type = this.types_by_index[i];
  6557. if (type.is_family)
  6558. continue;
  6559. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  6560. {
  6561. inst = type.instances[j];
  6562. this.objectsByUid[inst.uid.toString()] = inst;
  6563. }
  6564. }
  6565. };
  6566. Runtime.prototype.loadFromJSONString = function (str)
  6567. {
  6568. var o = JSON.parse(str);
  6569. if (!o["c2save"])
  6570. return; // probably not a c2 save state
  6571. if (o["version"] > 1)
  6572. return; // from future version of c2; assume not compatible
  6573. var rt = o["rt"];
  6574. this.kahanTime.reset();
  6575. this.kahanTime.sum = rt["time"];
  6576. this.wallTime.reset();
  6577. this.wallTime.sum = rt["walltime"] || 0;
  6578. this.timescale = rt["timescale"];
  6579. this.tickcount = rt["tickcount"];
  6580. this.execcount = rt["execcount"];
  6581. this.start_time = Date.now() - rt["start_time_offset"];
  6582. var layout_sid = rt["running_layout"];
  6583. if (layout_sid !== this.running_layout.sid)
  6584. {
  6585. var changeToLayout = this.getLayoutBySid(layout_sid);
  6586. if (changeToLayout)
  6587. this.doChangeLayout(changeToLayout);
  6588. else
  6589. return; // layout that was saved on has gone missing (deleted?)
  6590. }
  6591. this.isLoadingState = true;
  6592. var i, len, j, lenj, k, lenk, p, type, existing_insts, load_insts, inst, binst, layout, layer, g, iid, t;
  6593. var otypes = o["types"];
  6594. for (p in otypes)
  6595. {
  6596. if (otypes.hasOwnProperty(p))
  6597. {
  6598. type = this.getObjectTypeBySid(parseInt(p, 10));
  6599. if (!type || type.is_family || this.typeHasNoSaveBehavior(type))
  6600. continue;
  6601. if (otypes[p]["ex"])
  6602. type.extra = otypes[p]["ex"];
  6603. else
  6604. cr.wipe(type.extra);
  6605. existing_insts = type.instances;
  6606. load_insts = otypes[p]["instances"];
  6607. for (i = 0, len = cr.min(existing_insts.length, load_insts.length); i < len; i++)
  6608. {
  6609. this.loadInstanceFromJSON(existing_insts[i], load_insts[i]);
  6610. }
  6611. for (i = load_insts.length, len = existing_insts.length; i < len; i++)
  6612. this.DestroyInstance(existing_insts[i]);
  6613. for (i = existing_insts.length, len = load_insts.length; i < len; i++)
  6614. {
  6615. layer = null;
  6616. if (type.plugin.is_world)
  6617. {
  6618. layer = this.running_layout.getLayerBySid(load_insts[i]["w"]["l"]);
  6619. if (!layer)
  6620. continue;
  6621. }
  6622. inst = this.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
  6623. this.loadInstanceFromJSON(inst, load_insts[i]);
  6624. }
  6625. type.stale_iids = true;
  6626. }
  6627. }
  6628. this.ClearDeathRow();
  6629. this.refreshUidMap();
  6630. var olayouts = o["layouts"];
  6631. for (p in olayouts)
  6632. {
  6633. if (olayouts.hasOwnProperty(p))
  6634. {
  6635. layout = this.getLayoutBySid(parseInt(p, 10));
  6636. if (!layout)
  6637. continue; // must've gone missing
  6638. layout.loadFromJSON(olayouts[p]);
  6639. }
  6640. }
  6641. var ogroups = o["events"]["groups"];
  6642. for (p in ogroups)
  6643. {
  6644. if (ogroups.hasOwnProperty(p))
  6645. {
  6646. g = this.getGroupBySid(parseInt(p, 10));
  6647. if (g && this.groups_by_name[g.group_name])
  6648. this.groups_by_name[g.group_name].setGroupActive(ogroups[p]);
  6649. }
  6650. }
  6651. var ocnds = o["events"]["cnds"];
  6652. for (p in ocnds)
  6653. {
  6654. if (ocnds.hasOwnProperty(p) && this.cndsBySid.hasOwnProperty(p))
  6655. {
  6656. this.cndsBySid[p].extra = ocnds[p]["ex"];
  6657. }
  6658. }
  6659. var oacts = o["events"]["acts"];
  6660. for (p in oacts)
  6661. {
  6662. if (oacts.hasOwnProperty(p) && this.actsBySid.hasOwnProperty(p))
  6663. {
  6664. this.actsBySid[p].extra = oacts[p]["ex"];
  6665. }
  6666. }
  6667. var ovars = o["events"]["vars"];
  6668. for (p in ovars)
  6669. {
  6670. if (ovars.hasOwnProperty(p) && this.varsBySid.hasOwnProperty(p))
  6671. {
  6672. this.varsBySid[p].data = ovars[p];
  6673. }
  6674. }
  6675. this.next_uid = rt["next_uid"];
  6676. this.isLoadingState = false;
  6677. this.system.loadFromJSON(o["system"]);
  6678. for (i = 0, len = this.types_by_index.length; i < len; i++)
  6679. {
  6680. type = this.types_by_index[i];
  6681. if (type.is_family)
  6682. continue;
  6683. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  6684. {
  6685. inst = type.instances[j];
  6686. if (type.is_contained)
  6687. {
  6688. iid = inst.get_iid();
  6689. inst.siblings.length = 0;
  6690. for (k = 0, lenk = type.container.length; k < lenk; k++)
  6691. {
  6692. t = type.container[k];
  6693. if (type === t)
  6694. continue;
  6695. ;
  6696. inst.siblings.push(t.instances[iid]);
  6697. }
  6698. }
  6699. if (inst.afterLoad)
  6700. inst.afterLoad();
  6701. if (inst.behavior_insts)
  6702. {
  6703. for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
  6704. {
  6705. binst = inst.behavior_insts[k];
  6706. if (binst.afterLoad)
  6707. binst.afterLoad();
  6708. }
  6709. }
  6710. }
  6711. }
  6712. this.redraw = true;
  6713. };
  6714. Runtime.prototype.saveInstanceToJSON = function(inst, state_only)
  6715. {
  6716. var i, len, world, behinst, et;
  6717. var type = inst.type;
  6718. var plugin = type.plugin;
  6719. var o = {};
  6720. if (state_only)
  6721. o["c2"] = true; // mark as known json data from Construct 2
  6722. else
  6723. o["uid"] = inst.uid;
  6724. if (cr.hasAnyOwnProperty(inst.extra))
  6725. o["ex"] = CopyExtraObject(inst.extra);
  6726. if (inst.instance_vars && inst.instance_vars.length)
  6727. {
  6728. o["ivs"] = {};
  6729. for (i = 0, len = inst.instance_vars.length; i < len; i++)
  6730. {
  6731. o["ivs"][inst.type.instvar_sids[i].toString()] = inst.instance_vars[i];
  6732. }
  6733. }
  6734. if (plugin.is_world)
  6735. {
  6736. world = {
  6737. "x": inst.x,
  6738. "y": inst.y,
  6739. "w": inst.width,
  6740. "h": inst.height,
  6741. "l": inst.layer.sid,
  6742. "zi": inst.get_zindex()
  6743. };
  6744. if (inst.angle !== 0)
  6745. world["a"] = inst.angle;
  6746. if (inst.opacity !== 1)
  6747. world["o"] = inst.opacity;
  6748. if (inst.hotspotX !== 0.5)
  6749. world["hX"] = inst.hotspotX;
  6750. if (inst.hotspotY !== 0.5)
  6751. world["hY"] = inst.hotspotY;
  6752. if (inst.blend_mode !== 0)
  6753. world["bm"] = inst.blend_mode;
  6754. if (!inst.visible)
  6755. world["v"] = inst.visible;
  6756. if (!inst.collisionsEnabled)
  6757. world["ce"] = inst.collisionsEnabled;
  6758. if (inst.my_timescale !== -1)
  6759. world["mts"] = inst.my_timescale;
  6760. if (type.effect_types.length)
  6761. {
  6762. world["fx"] = [];
  6763. for (i = 0, len = type.effect_types.length; i < len; i++)
  6764. {
  6765. et = type.effect_types[i];
  6766. world["fx"].push({"name": et.name,
  6767. "active": inst.active_effect_flags[et.index],
  6768. "params": inst.effect_params[et.index] });
  6769. }
  6770. }
  6771. o["w"] = world;
  6772. }
  6773. if (inst.behavior_insts && inst.behavior_insts.length)
  6774. {
  6775. o["behs"] = {};
  6776. for (i = 0, len = inst.behavior_insts.length; i < len; i++)
  6777. {
  6778. behinst = inst.behavior_insts[i];
  6779. if (behinst.saveToJSON)
  6780. o["behs"][behinst.type.sid.toString()] = behinst.saveToJSON();
  6781. }
  6782. }
  6783. if (inst.saveToJSON)
  6784. o["data"] = inst.saveToJSON();
  6785. return o;
  6786. };
  6787. Runtime.prototype.getInstanceVarIndexBySid = function (type, sid_)
  6788. {
  6789. var i, len;
  6790. for (i = 0, len = type.instvar_sids.length; i < len; i++)
  6791. {
  6792. if (type.instvar_sids[i] === sid_)
  6793. return i;
  6794. }
  6795. return -1;
  6796. };
  6797. Runtime.prototype.getBehaviorIndexBySid = function (inst, sid_)
  6798. {
  6799. var i, len;
  6800. for (i = 0, len = inst.behavior_insts.length; i < len; i++)
  6801. {
  6802. if (inst.behavior_insts[i].type.sid === sid_)
  6803. return i;
  6804. }
  6805. return -1;
  6806. };
  6807. Runtime.prototype.loadInstanceFromJSON = function(inst, o, state_only)
  6808. {
  6809. var p, i, len, iv, oivs, world, fxindex, obehs, behindex;
  6810. var oldlayer;
  6811. var type = inst.type;
  6812. var plugin = type.plugin;
  6813. if (state_only)
  6814. {
  6815. if (!o["c2"])
  6816. return;
  6817. }
  6818. else
  6819. inst.uid = o["uid"];
  6820. if (o["ex"])
  6821. inst.extra = o["ex"];
  6822. else
  6823. cr.wipe(inst.extra);
  6824. oivs = o["ivs"];
  6825. if (oivs)
  6826. {
  6827. for (p in oivs)
  6828. {
  6829. if (oivs.hasOwnProperty(p))
  6830. {
  6831. iv = this.getInstanceVarIndexBySid(type, parseInt(p, 10));
  6832. if (iv < 0 || iv >= inst.instance_vars.length)
  6833. continue; // must've gone missing
  6834. inst.instance_vars[iv] = oivs[p];
  6835. }
  6836. }
  6837. }
  6838. if (plugin.is_world)
  6839. {
  6840. world = o["w"];
  6841. if (inst.layer.sid !== world["l"])
  6842. {
  6843. oldlayer = inst.layer;
  6844. inst.layer = this.running_layout.getLayerBySid(world["l"]);
  6845. if (inst.layer)
  6846. {
  6847. oldlayer.removeFromInstanceList(inst, true);
  6848. inst.layer.appendToInstanceList(inst, true);
  6849. inst.set_bbox_changed();
  6850. inst.layer.setZIndicesStaleFrom(0);
  6851. }
  6852. else
  6853. {
  6854. inst.layer = oldlayer;
  6855. if (!state_only)
  6856. this.DestroyInstance(inst);
  6857. }
  6858. }
  6859. inst.x = world["x"];
  6860. inst.y = world["y"];
  6861. inst.width = world["w"];
  6862. inst.height = world["h"];
  6863. inst.zindex = world["zi"];
  6864. inst.angle = world.hasOwnProperty("a") ? world["a"] : 0;
  6865. inst.opacity = world.hasOwnProperty("o") ? world["o"] : 1;
  6866. inst.hotspotX = world.hasOwnProperty("hX") ? world["hX"] : 0.5;
  6867. inst.hotspotY = world.hasOwnProperty("hY") ? world["hY"] : 0.5;
  6868. inst.visible = world.hasOwnProperty("v") ? world["v"] : true;
  6869. inst.collisionsEnabled = world.hasOwnProperty("ce") ? world["ce"] : true;
  6870. inst.my_timescale = world.hasOwnProperty("mts") ? world["mts"] : -1;
  6871. inst.blend_mode = world.hasOwnProperty("bm") ? world["bm"] : 0;;
  6872. inst.compositeOp = cr.effectToCompositeOp(inst.blend_mode);
  6873. if (this.gl)
  6874. cr.setGLBlend(inst, inst.blend_mode, this.gl);
  6875. inst.set_bbox_changed();
  6876. if (world.hasOwnProperty("fx"))
  6877. {
  6878. for (i = 0, len = world["fx"].length; i < len; i++)
  6879. {
  6880. fxindex = type.getEffectIndexByName(world["fx"][i]["name"]);
  6881. if (fxindex < 0)
  6882. continue; // must've gone missing
  6883. inst.active_effect_flags[fxindex] = world["fx"][i]["active"];
  6884. inst.effect_params[fxindex] = world["fx"][i]["params"];
  6885. }
  6886. }
  6887. inst.updateActiveEffects();
  6888. }
  6889. obehs = o["behs"];
  6890. if (obehs)
  6891. {
  6892. for (p in obehs)
  6893. {
  6894. if (obehs.hasOwnProperty(p))
  6895. {
  6896. behindex = this.getBehaviorIndexBySid(inst, parseInt(p, 10));
  6897. if (behindex < 0)
  6898. continue; // must've gone missing
  6899. inst.behavior_insts[behindex].loadFromJSON(obehs[p]);
  6900. }
  6901. }
  6902. }
  6903. if (o["data"])
  6904. inst.loadFromJSON(o["data"]);
  6905. };
  6906. cr.runtime = Runtime;
  6907. cr.createRuntime = function (canvasid)
  6908. {
  6909. return new Runtime(document.getElementById(canvasid));
  6910. };
  6911. cr.createDCRuntime = function (w, h)
  6912. {
  6913. return new Runtime({ "dc": true, "width": w, "height": h });
  6914. };
  6915. window["cr_createRuntime"] = cr.createRuntime;
  6916. window["cr_createDCRuntime"] = cr.createDCRuntime;
  6917. window["createCocoonJSRuntime"] = function ()
  6918. {
  6919. window["c2cocoonjs"] = true;
  6920. var canvas = document.createElement("screencanvas") || document.createElement("canvas");
  6921. canvas.screencanvas = true;
  6922. document.body.appendChild(canvas);
  6923. var rt = new Runtime(canvas);
  6924. window["c2runtime"] = rt;
  6925. window.addEventListener("orientationchange", function () {
  6926. window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
  6927. });
  6928. window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
  6929. return rt;
  6930. };
  6931. window["createEjectaRuntime"] = function ()
  6932. {
  6933. var canvas = document.getElementById("canvas");
  6934. var rt = new Runtime(canvas);
  6935. window["c2runtime"] = rt;
  6936. window["c2runtime"]["setSize"](window.innerWidth, window.innerHeight);
  6937. return rt;
  6938. };
  6939. }());
  6940. window["cr_getC2Runtime"] = function()
  6941. {
  6942. var canvas = document.getElementById("c2canvas");
  6943. if (canvas)
  6944. return canvas["c2runtime"];
  6945. else if (window["c2runtime"])
  6946. return window["c2runtime"];
  6947. else
  6948. return null;
  6949. }
  6950. window["cr_getSnapshot"] = function (format_, quality_)
  6951. {
  6952. var runtime = window["cr_getC2Runtime"]();
  6953. if (runtime)
  6954. runtime.doCanvasSnapshot(format_, quality_);
  6955. }
  6956. window["cr_sizeCanvas"] = function(w, h)
  6957. {
  6958. if (w === 0 || h === 0)
  6959. return;
  6960. var runtime = window["cr_getC2Runtime"]();
  6961. if (runtime)
  6962. runtime["setSize"](w, h);
  6963. }
  6964. window["cr_setSuspended"] = function(s)
  6965. {
  6966. var runtime = window["cr_getC2Runtime"]();
  6967. if (runtime)
  6968. runtime["setSuspended"](s);
  6969. }
  6970. ;
  6971. (function()
  6972. {
  6973. function Layout(runtime, m)
  6974. {
  6975. this.runtime = runtime;
  6976. this.event_sheet = null;
  6977. this.scrollX = (this.runtime.original_width / 2);
  6978. this.scrollY = (this.runtime.original_height / 2);
  6979. this.scale = 1.0;
  6980. this.angle = 0;
  6981. this.first_visit = true;
  6982. this.name = m[0];
  6983. this.width = m[1];
  6984. this.height = m[2];
  6985. this.unbounded_scrolling = m[3];
  6986. this.sheetname = m[4];
  6987. this.sid = m[5];
  6988. var lm = m[6];
  6989. var i, len;
  6990. this.layers = [];
  6991. this.initial_types = [];
  6992. for (i = 0, len = lm.length; i < len; i++)
  6993. {
  6994. var layer = new cr.layer(this, lm[i]);
  6995. layer.number = i;
  6996. cr.seal(layer);
  6997. this.layers.push(layer);
  6998. }
  6999. var im = m[7];
  7000. this.initial_nonworld = [];
  7001. for (i = 0, len = im.length; i < len; i++)
  7002. {
  7003. var inst = im[i];
  7004. var type = this.runtime.types_by_index[inst[1]];
  7005. ;
  7006. if (!type.default_instance)
  7007. type.default_instance = inst;
  7008. this.initial_nonworld.push(inst);
  7009. if (this.initial_types.indexOf(type) === -1)
  7010. this.initial_types.push(type);
  7011. }
  7012. this.effect_types = [];
  7013. this.active_effect_types = [];
  7014. this.effect_params = [];
  7015. for (i = 0, len = m[8].length; i < len; i++)
  7016. {
  7017. this.effect_types.push({
  7018. id: m[8][i][0],
  7019. name: m[8][i][1],
  7020. shaderindex: -1,
  7021. active: true,
  7022. index: i
  7023. });
  7024. this.effect_params.push(m[8][i][2].slice(0));
  7025. }
  7026. this.updateActiveEffects();
  7027. this.rcTex = new cr.rect(0, 0, 1, 1);
  7028. this.rcTex2 = new cr.rect(0, 0, 1, 1);
  7029. this.persist_data = {};
  7030. };
  7031. Layout.prototype.saveObjectToPersist = function (inst)
  7032. {
  7033. var sidStr = inst.type.sid.toString();
  7034. if (!this.persist_data.hasOwnProperty(sidStr))
  7035. this.persist_data[sidStr] = [];
  7036. var type_persist = this.persist_data[sidStr];
  7037. type_persist.push(this.runtime.saveInstanceToJSON(inst));
  7038. };
  7039. Layout.prototype.hasOpaqueBottomLayer = function ()
  7040. {
  7041. var layer = this.layers[0];
  7042. return !layer.transparent && layer.opacity === 1.0 && !layer.forceOwnTexture && layer.visible;
  7043. };
  7044. Layout.prototype.updateActiveEffects = function ()
  7045. {
  7046. this.active_effect_types.length = 0;
  7047. var i, len, et;
  7048. for (i = 0, len = this.effect_types.length; i < len; i++)
  7049. {
  7050. et = this.effect_types[i];
  7051. if (et.active)
  7052. this.active_effect_types.push(et);
  7053. }
  7054. };
  7055. Layout.prototype.getEffectByName = function (name_)
  7056. {
  7057. var i, len, et;
  7058. for (i = 0, len = this.effect_types.length; i < len; i++)
  7059. {
  7060. et = this.effect_types[i];
  7061. if (et.name === name_)
  7062. return et;
  7063. }
  7064. return null;
  7065. };
  7066. var created_instances = [];
  7067. function sort_by_zindex(a, b)
  7068. {
  7069. return a.zindex - b.zindex;
  7070. };
  7071. var first_layout = true;
  7072. Layout.prototype.startRunning = function ()
  7073. {
  7074. if (this.sheetname)
  7075. {
  7076. this.event_sheet = this.runtime.eventsheets[this.sheetname];
  7077. ;
  7078. this.event_sheet.updateDeepIncludes();
  7079. }
  7080. this.runtime.running_layout = this;
  7081. this.scrollX = (this.runtime.original_width / 2);
  7082. this.scrollY = (this.runtime.original_height / 2);
  7083. var i, k, len, lenk, type, type_instances, inst, iid, t, s, p, q, type_data, layer;
  7084. for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
  7085. {
  7086. type = this.runtime.types_by_index[i];
  7087. if (type.is_family)
  7088. continue; // instances are only transferred for their real type
  7089. type_instances = type.instances;
  7090. for (k = 0, lenk = type_instances.length; k < lenk; k++)
  7091. {
  7092. inst = type_instances[k];
  7093. if (inst.layer)
  7094. {
  7095. var num = inst.layer.number;
  7096. if (num >= this.layers.length)
  7097. num = this.layers.length - 1;
  7098. inst.layer = this.layers[num];
  7099. if (inst.layer.instances.indexOf(inst) === -1)
  7100. inst.layer.instances.push(inst);
  7101. inst.layer.zindices_stale = true;
  7102. }
  7103. }
  7104. }
  7105. if (!first_layout)
  7106. {
  7107. for (i = 0, len = this.layers.length; i < len; ++i)
  7108. {
  7109. this.layers[i].instances.sort(sort_by_zindex);
  7110. }
  7111. }
  7112. var layer;
  7113. created_instances.length = 0;
  7114. this.boundScrolling();
  7115. for (i = 0, len = this.layers.length; i < len; i++)
  7116. {
  7117. layer = this.layers[i];
  7118. layer.createInitialInstances(); // fills created_instances
  7119. layer.updateViewport(null);
  7120. }
  7121. var uids_changed = false;
  7122. if (!this.first_visit)
  7123. {
  7124. for (p in this.persist_data)
  7125. {
  7126. if (this.persist_data.hasOwnProperty(p))
  7127. {
  7128. type = this.runtime.getObjectTypeBySid(parseInt(p, 10));
  7129. if (!type || type.is_family || !this.runtime.typeHasPersistBehavior(type))
  7130. continue;
  7131. type_data = this.persist_data[p];
  7132. for (i = 0, len = type_data.length; i < len; i++)
  7133. {
  7134. layer = null;
  7135. if (type.plugin.is_world)
  7136. {
  7137. layer = this.getLayerBySid(type_data[i]["w"]["l"]);
  7138. if (!layer)
  7139. continue;
  7140. }
  7141. inst = this.runtime.createInstanceFromInit(type.default_instance, layer, false, 0, 0, true);
  7142. this.runtime.loadInstanceFromJSON(inst, type_data[i]);
  7143. uids_changed = true;
  7144. created_instances.push(inst);
  7145. }
  7146. type_data.length = 0;
  7147. }
  7148. }
  7149. for (i = 0, len = this.layers.length; i < len; i++)
  7150. {
  7151. this.layers[i].instances.sort(sort_by_zindex);
  7152. this.layers[i].zindices_stale = true; // in case of duplicates/holes
  7153. }
  7154. }
  7155. if (uids_changed)
  7156. {
  7157. this.runtime.ClearDeathRow();
  7158. this.runtime.refreshUidMap();
  7159. }
  7160. for (i = 0; i < created_instances.length; i++)
  7161. {
  7162. inst = created_instances[i];
  7163. if (!inst.type.is_contained)
  7164. continue;
  7165. iid = inst.get_iid();
  7166. for (k = 0, lenk = inst.type.container.length; k < lenk; k++)
  7167. {
  7168. t = inst.type.container[k];
  7169. if (inst.type === t)
  7170. continue;
  7171. if (t.instances.length > iid)
  7172. inst.siblings.push(t.instances[iid]);
  7173. else
  7174. {
  7175. if (!t.default_instance)
  7176. {
  7177. }
  7178. else
  7179. {
  7180. s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true);
  7181. this.runtime.ClearDeathRow();
  7182. t.updateIIDs();
  7183. inst.siblings.push(s);
  7184. created_instances.push(s); // come back around and link up its own instances too
  7185. }
  7186. }
  7187. }
  7188. }
  7189. for (i = 0, len = this.initial_nonworld.length; i < len; i++)
  7190. {
  7191. inst = this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true);
  7192. ;
  7193. }
  7194. this.runtime.changelayout = null;
  7195. this.runtime.ClearDeathRow();
  7196. if (this.runtime.ctx && !this.runtime.isDomFree)
  7197. {
  7198. for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
  7199. {
  7200. t = this.runtime.types_by_index[i];
  7201. if (t.is_family || !t.instances.length || !t.preloadCanvas2D)
  7202. continue;
  7203. t.preloadCanvas2D(this.runtime.ctx);
  7204. }
  7205. }
  7206. /*
  7207. if (this.runtime.glwrap)
  7208. {
  7209. console.log("Estimated VRAM at layout start: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
  7210. }
  7211. */
  7212. for (i = 0, len = created_instances.length; i < len; i++)
  7213. {
  7214. inst = created_instances[i];
  7215. this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
  7216. }
  7217. created_instances.length = 0;
  7218. this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null);
  7219. this.first_visit = false;
  7220. };
  7221. Layout.prototype.createGlobalNonWorlds = function ()
  7222. {
  7223. var i, k, len, initial_inst, inst, type;
  7224. for (i = 0, k = 0, len = this.initial_nonworld.length; i < len; i++)
  7225. {
  7226. initial_inst = this.initial_nonworld[i];
  7227. type = this.runtime.types_by_index[initial_inst[1]];
  7228. if (type.global)
  7229. {
  7230. if (!type.is_contained)
  7231. {
  7232. inst = this.runtime.createInstanceFromInit(initial_inst, null, true);
  7233. }
  7234. }
  7235. else
  7236. {
  7237. this.initial_nonworld[k] = initial_inst;
  7238. k++;
  7239. }
  7240. }
  7241. this.initial_nonworld.length = k;
  7242. };
  7243. Layout.prototype.stopRunning = function ()
  7244. {
  7245. ;
  7246. /*
  7247. if (this.runtime.glwrap)
  7248. {
  7249. console.log("Estimated VRAM at layout end: " + this.runtime.glwrap.textureCount() + " textures, approx. " + Math.round(this.runtime.glwrap.estimateVRAM() / 1024) + " kb");
  7250. }
  7251. */
  7252. this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutEnd, null);
  7253. this.runtime.system.waits.length = 0;
  7254. var i, leni, j, lenj;
  7255. var layer_instances, inst, type;
  7256. if (!this.first_visit)
  7257. {
  7258. for (i = 0, leni = this.layers.length; i < leni; i++)
  7259. {
  7260. this.layers[i].updateZIndices();
  7261. layer_instances = this.layers[i].instances;
  7262. for (j = 0, lenj = layer_instances.length; j < lenj; j++)
  7263. {
  7264. inst = layer_instances[j];
  7265. if (!inst.type.global)
  7266. {
  7267. if (this.runtime.typeHasPersistBehavior(inst.type))
  7268. this.saveObjectToPersist(inst);
  7269. }
  7270. }
  7271. }
  7272. }
  7273. for (i = 0, leni = this.layers.length; i < leni; i++)
  7274. {
  7275. layer_instances = this.layers[i].instances;
  7276. for (j = 0, lenj = layer_instances.length; j < lenj; j++)
  7277. {
  7278. inst = layer_instances[j];
  7279. if (!inst.type.global)
  7280. {
  7281. this.runtime.DestroyInstance(inst);
  7282. }
  7283. }
  7284. this.runtime.ClearDeathRow();
  7285. layer_instances.length = 0;
  7286. this.layers[i].zindices_stale = true;
  7287. }
  7288. for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++)
  7289. {
  7290. type = this.runtime.types_by_index[i];
  7291. if (type.global || type.plugin.is_world || type.plugin.singleglobal || type.is_family)
  7292. continue;
  7293. for (j = 0, lenj = type.instances.length; j < lenj; j++)
  7294. this.runtime.DestroyInstance(type.instances[j]);
  7295. this.runtime.ClearDeathRow();
  7296. }
  7297. first_layout = false;
  7298. };
  7299. var temp_rect = new cr.rect(0, 0, 0, 0);
  7300. Layout.prototype.recreateInitialObjects = function (type, x1, y1, x2, y2)
  7301. {
  7302. temp_rect.set(x1, y1, x2, y2);
  7303. var i, len;
  7304. for (i = 0, len = this.layers.length; i < len; i++)
  7305. {
  7306. this.layers[i].recreateInitialObjects(type, temp_rect);
  7307. }
  7308. };
  7309. Layout.prototype.draw = function (ctx)
  7310. {
  7311. var layout_canvas;
  7312. var layout_ctx = ctx;
  7313. var ctx_changed = false;
  7314. var render_offscreen = !this.runtime.fullscreenScalingQuality;
  7315. if (render_offscreen)
  7316. {
  7317. if (!this.runtime.layout_canvas)
  7318. {
  7319. this.runtime.layout_canvas = document.createElement("canvas");
  7320. layout_canvas = this.runtime.layout_canvas;
  7321. layout_canvas.width = this.runtime.draw_width;
  7322. layout_canvas.height = this.runtime.draw_height;
  7323. this.runtime.layout_ctx = layout_canvas.getContext("2d");
  7324. ctx_changed = true;
  7325. }
  7326. layout_canvas = this.runtime.layout_canvas;
  7327. layout_ctx = this.runtime.layout_ctx;
  7328. if (layout_canvas.width !== this.runtime.draw_width)
  7329. {
  7330. layout_canvas.width = this.runtime.draw_width;
  7331. ctx_changed = true;
  7332. }
  7333. if (layout_canvas.height !== this.runtime.draw_height)
  7334. {
  7335. layout_canvas.height = this.runtime.draw_height;
  7336. ctx_changed = true;
  7337. }
  7338. if (ctx_changed)
  7339. {
  7340. layout_ctx["webkitImageSmoothingEnabled"] = this.runtime.linearSampling;
  7341. layout_ctx["mozImageSmoothingEnabled"] = this.runtime.linearSampling;
  7342. layout_ctx["msImageSmoothingEnabled"] = this.runtime.linearSampling;
  7343. layout_ctx["imageSmoothingEnabled"] = this.runtime.linearSampling;
  7344. }
  7345. }
  7346. layout_ctx.globalAlpha = 1;
  7347. layout_ctx.globalCompositeOperation = "source-over";
  7348. if (this.runtime.alphaBackground && !this.hasOpaqueBottomLayer())
  7349. layout_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
  7350. var i, len, l;
  7351. for (i = 0, len = this.layers.length; i < len; i++)
  7352. {
  7353. l = this.layers[i];
  7354. if (l.visible && l.opacity > 0 && l.blend_mode !== 11 && (l.instances.length || !l.transparent))
  7355. l.draw(layout_ctx);
  7356. else
  7357. l.updateViewport(null); // even if not drawing, keep viewport up to date
  7358. }
  7359. if (render_offscreen)
  7360. {
  7361. ctx.drawImage(layout_canvas, 0, 0, this.runtime.width, this.runtime.height);
  7362. }
  7363. };
  7364. Layout.prototype.drawGL = function (glw)
  7365. {
  7366. var render_to_texture = (this.active_effect_types.length > 0 ||
  7367. this.runtime.uses_background_blending ||
  7368. !this.runtime.fullscreenScalingQuality);
  7369. if (render_to_texture)
  7370. {
  7371. if (!this.runtime.layout_tex)
  7372. {
  7373. this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
  7374. }
  7375. if (this.runtime.layout_tex.c2width !== this.runtime.draw_width || this.runtime.layout_tex.c2height !== this.runtime.draw_height)
  7376. {
  7377. glw.deleteTexture(this.runtime.layout_tex);
  7378. this.runtime.layout_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
  7379. }
  7380. glw.setRenderingToTexture(this.runtime.layout_tex);
  7381. if (!this.runtime.fullscreenScalingQuality)
  7382. {
  7383. glw.setSize(this.runtime.draw_width, this.runtime.draw_height);
  7384. }
  7385. }
  7386. else
  7387. {
  7388. if (this.runtime.layout_tex)
  7389. {
  7390. glw.setRenderingToTexture(null);
  7391. glw.deleteTexture(this.runtime.layout_tex);
  7392. this.runtime.layout_tex = null;
  7393. }
  7394. }
  7395. if (this.runtime.alphaBackground && !this.hasOpaqueBottomLayer())
  7396. glw.clear(0, 0, 0, 0);
  7397. var i, len, l;
  7398. for (i = 0, len = this.layers.length; i < len; i++)
  7399. {
  7400. l = this.layers[i];
  7401. if (l.visible && l.opacity > 0 && (l.instances.length || !l.transparent))
  7402. l.drawGL(glw);
  7403. else
  7404. l.updateViewport(null); // even if not drawing, keep viewport up to date
  7405. }
  7406. if (render_to_texture)
  7407. {
  7408. if (this.active_effect_types.length === 0 ||
  7409. (this.active_effect_types.length === 1 && this.runtime.fullscreenScalingQuality))
  7410. {
  7411. if (this.active_effect_types.length === 1)
  7412. {
  7413. var etindex = this.active_effect_types[0].index;
  7414. glw.switchProgram(this.active_effect_types[0].shaderindex);
  7415. glw.setProgramParameters(null, // backTex
  7416. 1.0 / this.runtime.draw_width, // pixelWidth
  7417. 1.0 / this.runtime.draw_height, // pixelHeight
  7418. 0.0, 0.0, // destStart
  7419. 1.0, 1.0, // destEnd
  7420. this.scale, // layerScale
  7421. this.angle, // layerAngle
  7422. 0.0, 0.0, // viewOrigin
  7423. this.runtime.draw_width / 2, this.runtime.draw_height / 2, // scrollPos
  7424. this.effect_params[etindex]); // fx parameters
  7425. if (glw.programIsAnimated(this.active_effect_types[0].shaderindex))
  7426. this.runtime.redraw = true;
  7427. }
  7428. else
  7429. glw.switchProgram(0);
  7430. if (!this.runtime.fullscreenScalingQuality)
  7431. {
  7432. glw.setSize(this.runtime.width, this.runtime.height);
  7433. }
  7434. glw.setRenderingToTexture(null); // to backbuffer
  7435. glw.setOpacity(1);
  7436. glw.setTexture(this.runtime.layout_tex);
  7437. glw.setAlphaBlend();
  7438. glw.resetModelView();
  7439. glw.updateModelView();
  7440. var halfw = this.runtime.width / 2;
  7441. var halfh = this.runtime.height / 2;
  7442. glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
  7443. glw.setTexture(null);
  7444. }
  7445. else
  7446. {
  7447. this.renderEffectChain(glw, null, null, null);
  7448. }
  7449. }
  7450. };
  7451. Layout.prototype.getRenderTarget = function()
  7452. {
  7453. return (this.active_effect_types.length > 0 ||
  7454. this.runtime.uses_background_blending ||
  7455. !this.runtime.fullscreenScalingQuality) ? this.runtime.layout_tex : null;
  7456. };
  7457. Layout.prototype.getMinLayerScale = function ()
  7458. {
  7459. var m = this.layers[0].getScale();
  7460. var i, len, l;
  7461. for (i = 1, len = this.layers.length; i < len; i++)
  7462. {
  7463. l = this.layers[i];
  7464. if (l.parallaxX === 0 && l.parallaxY === 0)
  7465. continue;
  7466. if (l.getScale() < m)
  7467. m = l.getScale();
  7468. }
  7469. return m;
  7470. };
  7471. Layout.prototype.scrollToX = function (x)
  7472. {
  7473. if (!this.unbounded_scrolling)
  7474. {
  7475. var widthBoundary = (this.runtime.draw_width * (1 / this.getMinLayerScale()) / 2);
  7476. if (x > this.width - widthBoundary)
  7477. x = this.width - widthBoundary;
  7478. if (x < widthBoundary)
  7479. x = widthBoundary;
  7480. }
  7481. if (this.scrollX !== x)
  7482. {
  7483. this.scrollX = x;
  7484. this.runtime.redraw = true;
  7485. }
  7486. };
  7487. Layout.prototype.scrollToY = function (y)
  7488. {
  7489. if (!this.unbounded_scrolling)
  7490. {
  7491. var heightBoundary = (this.runtime.draw_height * (1 / this.getMinLayerScale()) / 2);
  7492. if (y > this.height - heightBoundary)
  7493. y = this.height - heightBoundary;
  7494. if (y < heightBoundary)
  7495. y = heightBoundary;
  7496. }
  7497. if (this.scrollY !== y)
  7498. {
  7499. this.scrollY = y;
  7500. this.runtime.redraw = true;
  7501. }
  7502. };
  7503. Layout.prototype.boundScrolling = function ()
  7504. {
  7505. this.scrollToX(this.scrollX);
  7506. this.scrollToY(this.scrollY);
  7507. };
  7508. Layout.prototype.renderEffectChain = function (glw, layer, inst, rendertarget)
  7509. {
  7510. var active_effect_types = inst ?
  7511. inst.active_effect_types :
  7512. layer ?
  7513. layer.active_effect_types :
  7514. this.active_effect_types;
  7515. var layerScale = 1, layerAngle = 0, viewOriginLeft = 0, viewOriginTop = 0, viewOriginRight = this.runtime.draw_width, viewOriginBottom = this.runtime.draw_height;
  7516. if (inst)
  7517. {
  7518. layerScale = inst.layer.getScale();
  7519. layerAngle = inst.layer.getAngle();
  7520. viewOriginLeft = inst.layer.viewLeft;
  7521. viewOriginTop = inst.layer.viewTop;
  7522. viewOriginRight = inst.layer.viewRight;
  7523. viewOriginBottom = inst.layer.viewBottom;
  7524. }
  7525. else if (layer)
  7526. {
  7527. layerScale = layer.getScale();
  7528. layerAngle = layer.getAngle();
  7529. viewOriginLeft = layer.viewLeft;
  7530. viewOriginTop = layer.viewTop;
  7531. viewOriginRight = layer.viewRight;
  7532. viewOriginBottom = layer.viewBottom;
  7533. }
  7534. var fx_tex = this.runtime.fx_tex;
  7535. var i, len, last, temp, fx_index = 0, other_fx_index = 1;
  7536. var y, h;
  7537. var windowWidth = this.runtime.draw_width;
  7538. var windowHeight = this.runtime.draw_height;
  7539. var halfw = windowWidth / 2;
  7540. var halfh = windowHeight / 2;
  7541. var rcTex = layer ? layer.rcTex : this.rcTex;
  7542. var rcTex2 = layer ? layer.rcTex2 : this.rcTex2;
  7543. var screenleft = 0, clearleft = 0;
  7544. var screentop = 0, cleartop = 0;
  7545. var screenright = windowWidth, clearright = windowWidth;
  7546. var screenbottom = windowHeight, clearbottom = windowHeight;
  7547. var boxExtendHorizontal = 0;
  7548. var boxExtendVertical = 0;
  7549. var inst_layer_angle = inst ? inst.layer.getAngle() : 0;
  7550. if (inst)
  7551. {
  7552. for (i = 0, len = active_effect_types.length; i < len; i++)
  7553. {
  7554. boxExtendHorizontal += glw.getProgramBoxExtendHorizontal(active_effect_types[i].shaderindex);
  7555. boxExtendVertical += glw.getProgramBoxExtendVertical(active_effect_types[i].shaderindex);
  7556. }
  7557. var bbox = inst.bbox;
  7558. screenleft = layer.layerToCanvas(bbox.left, bbox.top, true, true);
  7559. screentop = layer.layerToCanvas(bbox.left, bbox.top, false, true);
  7560. screenright = layer.layerToCanvas(bbox.right, bbox.bottom, true, true);
  7561. screenbottom = layer.layerToCanvas(bbox.right, bbox.bottom, false, true);
  7562. if (inst_layer_angle !== 0)
  7563. {
  7564. var screentrx = layer.layerToCanvas(bbox.right, bbox.top, true, true);
  7565. var screentry = layer.layerToCanvas(bbox.right, bbox.top, false, true);
  7566. var screenblx = layer.layerToCanvas(bbox.left, bbox.bottom, true, true);
  7567. var screenbly = layer.layerToCanvas(bbox.left, bbox.bottom, false, true);
  7568. temp = Math.min(screenleft, screenright, screentrx, screenblx);
  7569. screenright = Math.max(screenleft, screenright, screentrx, screenblx);
  7570. screenleft = temp;
  7571. temp = Math.min(screentop, screenbottom, screentry, screenbly);
  7572. screenbottom = Math.max(screentop, screenbottom, screentry, screenbly);
  7573. screentop = temp;
  7574. }
  7575. screenleft -= boxExtendHorizontal;
  7576. screentop -= boxExtendVertical;
  7577. screenright += boxExtendHorizontal;
  7578. screenbottom += boxExtendVertical;
  7579. rcTex2.left = screenleft / windowWidth;
  7580. rcTex2.top = 1 - screentop / windowHeight;
  7581. rcTex2.right = screenright / windowWidth;
  7582. rcTex2.bottom = 1 - screenbottom / windowHeight;
  7583. clearleft = screenleft = cr.floor(screenleft);
  7584. cleartop = screentop = cr.floor(screentop);
  7585. clearright = screenright = cr.ceil(screenright);
  7586. clearbottom = screenbottom = cr.ceil(screenbottom);
  7587. clearleft -= boxExtendHorizontal;
  7588. cleartop -= boxExtendVertical;
  7589. clearright += boxExtendHorizontal;
  7590. clearbottom += boxExtendVertical;
  7591. if (screenleft < 0) screenleft = 0;
  7592. if (screentop < 0) screentop = 0;
  7593. if (screenright > windowWidth) screenright = windowWidth;
  7594. if (screenbottom > windowHeight) screenbottom = windowHeight;
  7595. if (clearleft < 0) clearleft = 0;
  7596. if (cleartop < 0) cleartop = 0;
  7597. if (clearright > windowWidth) clearright = windowWidth;
  7598. if (clearbottom > windowHeight) clearbottom = windowHeight;
  7599. rcTex.left = screenleft / windowWidth;
  7600. rcTex.top = 1 - screentop / windowHeight;
  7601. rcTex.right = screenright / windowWidth;
  7602. rcTex.bottom = 1 - screenbottom / windowHeight;
  7603. }
  7604. else
  7605. {
  7606. rcTex.left = rcTex2.left = 0;
  7607. rcTex.top = rcTex2.top = 0;
  7608. rcTex.right = rcTex2.right = 1;
  7609. rcTex.bottom = rcTex2.bottom = 1;
  7610. }
  7611. var pre_draw = (inst && (((inst.angle || inst_layer_angle) && glw.programUsesDest(active_effect_types[0].shaderindex)) || boxExtendHorizontal !== 0 || boxExtendVertical !== 0 || inst.opacity !== 1 || inst.type.plugin.must_predraw)) || (layer && !inst && layer.opacity !== 1);
  7612. glw.setAlphaBlend();
  7613. if (pre_draw)
  7614. {
  7615. if (!fx_tex[fx_index])
  7616. {
  7617. fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
  7618. }
  7619. if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
  7620. {
  7621. glw.deleteTexture(fx_tex[fx_index]);
  7622. fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
  7623. }
  7624. glw.switchProgram(0);
  7625. glw.setRenderingToTexture(fx_tex[fx_index]);
  7626. h = clearbottom - cleartop;
  7627. y = (windowHeight - cleartop) - h;
  7628. glw.clearRect(clearleft, y, clearright - clearleft, h);
  7629. if (inst)
  7630. {
  7631. inst.drawGL(glw);
  7632. }
  7633. else
  7634. {
  7635. glw.setTexture(this.runtime.layer_tex);
  7636. glw.setOpacity(layer.opacity);
  7637. glw.resetModelView();
  7638. glw.translate(-halfw, -halfh);
  7639. glw.updateModelView();
  7640. glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
  7641. }
  7642. rcTex2.left = rcTex2.top = 0;
  7643. rcTex2.right = rcTex2.bottom = 1;
  7644. if (inst)
  7645. {
  7646. temp = rcTex.top;
  7647. rcTex.top = rcTex.bottom;
  7648. rcTex.bottom = temp;
  7649. }
  7650. fx_index = 1;
  7651. other_fx_index = 0;
  7652. }
  7653. glw.setOpacity(1);
  7654. var last = active_effect_types.length - 1;
  7655. var post_draw = glw.programUsesCrossSampling(active_effect_types[last].shaderindex) ||
  7656. (!layer && !inst && !this.runtime.fullscreenScalingQuality);
  7657. var etindex = 0;
  7658. for (i = 0, len = active_effect_types.length; i < len; i++)
  7659. {
  7660. if (!fx_tex[fx_index])
  7661. {
  7662. fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
  7663. }
  7664. if (fx_tex[fx_index].c2width !== windowWidth || fx_tex[fx_index].c2height !== windowHeight)
  7665. {
  7666. glw.deleteTexture(fx_tex[fx_index]);
  7667. fx_tex[fx_index] = glw.createEmptyTexture(windowWidth, windowHeight, this.runtime.linearSampling);
  7668. }
  7669. glw.switchProgram(active_effect_types[i].shaderindex);
  7670. etindex = active_effect_types[i].index;
  7671. if (glw.programIsAnimated(active_effect_types[i].shaderindex))
  7672. this.runtime.redraw = true;
  7673. if (i == 0 && !pre_draw)
  7674. {
  7675. glw.setRenderingToTexture(fx_tex[fx_index]);
  7676. h = clearbottom - cleartop;
  7677. y = (windowHeight - cleartop) - h;
  7678. glw.clearRect(clearleft, y, clearright - clearleft, h);
  7679. if (inst)
  7680. {
  7681. glw.setProgramParameters(rendertarget, // backTex
  7682. 1.0 / inst.width, // pixelWidth
  7683. 1.0 / inst.height, // pixelHeight
  7684. rcTex2.left, rcTex2.top, // destStart
  7685. rcTex2.right, rcTex2.bottom, // destEnd
  7686. layerScale,
  7687. layerAngle,
  7688. viewOriginLeft, viewOriginTop,
  7689. (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
  7690. inst.effect_params[etindex]); // fx params
  7691. inst.drawGL(glw);
  7692. }
  7693. else
  7694. {
  7695. glw.setProgramParameters(rendertarget, // backTex
  7696. 1.0 / windowWidth, // pixelWidth
  7697. 1.0 / windowHeight, // pixelHeight
  7698. 0.0, 0.0, // destStart
  7699. 1.0, 1.0, // destEnd
  7700. layerScale,
  7701. layerAngle,
  7702. viewOriginLeft, viewOriginTop,
  7703. (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
  7704. layer ? // fx params
  7705. layer.effect_params[etindex] :
  7706. this.effect_params[etindex]);
  7707. glw.setTexture(layer ? this.runtime.layer_tex : this.runtime.layout_tex);
  7708. glw.resetModelView();
  7709. glw.translate(-halfw, -halfh);
  7710. glw.updateModelView();
  7711. glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
  7712. }
  7713. rcTex2.left = rcTex2.top = 0;
  7714. rcTex2.right = rcTex2.bottom = 1;
  7715. if (inst && !post_draw)
  7716. {
  7717. temp = screenbottom;
  7718. screenbottom = screentop;
  7719. screentop = temp;
  7720. }
  7721. }
  7722. else
  7723. {
  7724. glw.setProgramParameters(rendertarget, // backTex
  7725. 1.0 / windowWidth, // pixelWidth
  7726. 1.0 / windowHeight, // pixelHeight
  7727. rcTex2.left, rcTex2.top, // destStart
  7728. rcTex2.right, rcTex2.bottom, // destEnd
  7729. layerScale,
  7730. layerAngle,
  7731. viewOriginLeft, viewOriginTop,
  7732. (viewOriginLeft + viewOriginRight) / 2, (viewOriginTop + viewOriginBottom) / 2,
  7733. inst ? // fx params
  7734. inst.effect_params[etindex] :
  7735. layer ?
  7736. layer.effect_params[etindex] :
  7737. this.effect_params[etindex]);
  7738. glw.setTexture(null);
  7739. if (i === last && !post_draw)
  7740. {
  7741. if (inst)
  7742. glw.setBlend(inst.srcBlend, inst.destBlend);
  7743. else if (layer)
  7744. glw.setBlend(layer.srcBlend, layer.destBlend);
  7745. glw.setRenderingToTexture(rendertarget);
  7746. }
  7747. else
  7748. {
  7749. glw.setRenderingToTexture(fx_tex[fx_index]);
  7750. h = clearbottom - cleartop;
  7751. y = (windowHeight - cleartop) - h;
  7752. glw.clearRect(clearleft, y, clearright - clearleft, h);
  7753. }
  7754. glw.setTexture(fx_tex[other_fx_index]);
  7755. glw.resetModelView();
  7756. glw.translate(-halfw, -halfh);
  7757. glw.updateModelView();
  7758. glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
  7759. if (i === last && !post_draw)
  7760. glw.setTexture(null);
  7761. }
  7762. fx_index = (fx_index === 0 ? 1 : 0);
  7763. other_fx_index = (fx_index === 0 ? 1 : 0); // will be opposite to fx_index since it was just assigned
  7764. }
  7765. if (post_draw)
  7766. {
  7767. glw.switchProgram(0);
  7768. if (inst)
  7769. glw.setBlend(inst.srcBlend, inst.destBlend);
  7770. else if (layer)
  7771. glw.setBlend(layer.srcBlend, layer.destBlend);
  7772. else
  7773. {
  7774. if (!this.runtime.fullscreenScalingQuality)
  7775. {
  7776. glw.setSize(this.runtime.width, this.runtime.height);
  7777. halfw = this.runtime.width / 2;
  7778. halfh = this.runtime.height / 2;
  7779. screenleft = 0;
  7780. screentop = 0;
  7781. screenright = this.runtime.width;
  7782. screenbottom = this.runtime.height;
  7783. }
  7784. }
  7785. glw.setRenderingToTexture(rendertarget);
  7786. glw.setTexture(fx_tex[other_fx_index]);
  7787. glw.resetModelView();
  7788. glw.translate(-halfw, -halfh);
  7789. glw.updateModelView();
  7790. if (inst && active_effect_types.length === 1 && !pre_draw)
  7791. glw.quadTex(screenleft, screentop, screenright, screentop, screenright, screenbottom, screenleft, screenbottom, rcTex);
  7792. else
  7793. glw.quadTex(screenleft, screenbottom, screenright, screenbottom, screenright, screentop, screenleft, screentop, rcTex);
  7794. glw.setTexture(null);
  7795. }
  7796. };
  7797. Layout.prototype.getLayerBySid = function (sid_)
  7798. {
  7799. var i, len;
  7800. for (i = 0, len = this.layers.length; i < len; i++)
  7801. {
  7802. if (this.layers[i].sid === sid_)
  7803. return this.layers[i];
  7804. }
  7805. return null;
  7806. };
  7807. Layout.prototype.saveToJSON = function ()
  7808. {
  7809. var i, len, layer, et;
  7810. var o = {
  7811. "sx": this.scrollX,
  7812. "sy": this.scrollY,
  7813. "s": this.scale,
  7814. "a": this.angle,
  7815. "w": this.width,
  7816. "h": this.height,
  7817. "fv": this.first_visit, // added r127
  7818. "persist": this.persist_data,
  7819. "fx": [],
  7820. "layers": {}
  7821. };
  7822. for (i = 0, len = this.effect_types.length; i < len; i++)
  7823. {
  7824. et = this.effect_types[i];
  7825. o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
  7826. }
  7827. for (i = 0, len = this.layers.length; i < len; i++)
  7828. {
  7829. layer = this.layers[i];
  7830. o["layers"][layer.sid.toString()] = layer.saveToJSON();
  7831. }
  7832. return o;
  7833. };
  7834. Layout.prototype.loadFromJSON = function (o)
  7835. {
  7836. var i, j, len, fx, p, layer;
  7837. this.scrollX = o["sx"];
  7838. this.scrollY = o["sy"];
  7839. this.scale = o["s"];
  7840. this.angle = o["a"];
  7841. this.width = o["w"];
  7842. this.height = o["h"];
  7843. this.persist_data = o["persist"];
  7844. if (typeof o["fv"] !== "undefined")
  7845. this.first_visit = o["fv"];
  7846. var ofx = o["fx"];
  7847. for (i = 0, len = ofx.length; i < len; i++)
  7848. {
  7849. fx = this.getEffectByName(ofx[i]["name"]);
  7850. if (!fx)
  7851. continue; // must've gone missing
  7852. fx.active = ofx[i]["active"];
  7853. this.effect_params[fx.index] = ofx[i]["params"];
  7854. }
  7855. this.updateActiveEffects();
  7856. var olayers = o["layers"];
  7857. for (p in olayers)
  7858. {
  7859. if (olayers.hasOwnProperty(p))
  7860. {
  7861. layer = this.getLayerBySid(parseInt(p, 10));
  7862. if (!layer)
  7863. continue; // must've gone missing
  7864. layer.loadFromJSON(olayers[p]);
  7865. }
  7866. }
  7867. };
  7868. cr.layout = Layout;
  7869. function Layer(layout, m)
  7870. {
  7871. this.layout = layout;
  7872. this.runtime = layout.runtime;
  7873. this.instances = []; // running instances
  7874. this.scale = 1.0;
  7875. this.angle = 0;
  7876. this.disableAngle = false;
  7877. this.tmprect = new cr.rect(0, 0, 0, 0);
  7878. this.tmpquad = new cr.quad();
  7879. this.viewLeft = 0;
  7880. this.viewRight = 0;
  7881. this.viewTop = 0;
  7882. this.viewBottom = 0;
  7883. this.zindices_stale = false;
  7884. this.zindices_stale_from = -1; // first index that has changed, or -1 if no bound
  7885. this.name = m[0];
  7886. this.index = m[1];
  7887. this.sid = m[2];
  7888. this.visible = m[3]; // initially visible
  7889. this.background_color = m[4];
  7890. this.transparent = m[5];
  7891. this.parallaxX = m[6];
  7892. this.parallaxY = m[7];
  7893. this.opacity = m[8];
  7894. this.forceOwnTexture = m[9];
  7895. this.useRenderCells = m[10];
  7896. this.zoomRate = m[11];
  7897. this.blend_mode = m[12];
  7898. this.effect_fallback = m[13];
  7899. this.compositeOp = "source-over";
  7900. this.srcBlend = 0;
  7901. this.destBlend = 0;
  7902. this.render_grid = null;
  7903. this.last_render_list = alloc_arr();
  7904. this.render_list_stale = true;
  7905. this.last_render_cells = new cr.rect(0, 0, -1, -1);
  7906. this.cur_render_cells = new cr.rect(0, 0, -1, -1);
  7907. if (this.useRenderCells)
  7908. {
  7909. this.render_grid = new cr.RenderGrid(this.runtime.original_width, this.runtime.original_height);
  7910. }
  7911. this.render_offscreen = false;
  7912. var im = m[14];
  7913. var i, len;
  7914. this.startup_initial_instances = []; // for restoring initial_instances after load
  7915. this.initial_instances = [];
  7916. this.created_globals = []; // global object UIDs already created - for save/load to avoid recreating
  7917. for (i = 0, len = im.length; i < len; i++)
  7918. {
  7919. var inst = im[i];
  7920. var type = this.runtime.types_by_index[inst[1]];
  7921. ;
  7922. if (!type.default_instance)
  7923. {
  7924. type.default_instance = inst;
  7925. type.default_layerindex = this.index;
  7926. }
  7927. this.initial_instances.push(inst);
  7928. if (this.layout.initial_types.indexOf(type) === -1)
  7929. this.layout.initial_types.push(type);
  7930. }
  7931. cr.shallowAssignArray(this.startup_initial_instances, this.initial_instances);
  7932. this.effect_types = [];
  7933. this.active_effect_types = [];
  7934. this.effect_params = [];
  7935. for (i = 0, len = m[15].length; i < len; i++)
  7936. {
  7937. this.effect_types.push({
  7938. id: m[15][i][0],
  7939. name: m[15][i][1],
  7940. shaderindex: -1,
  7941. active: true,
  7942. index: i
  7943. });
  7944. this.effect_params.push(m[15][i][2].slice(0));
  7945. }
  7946. this.updateActiveEffects();
  7947. this.rcTex = new cr.rect(0, 0, 1, 1);
  7948. this.rcTex2 = new cr.rect(0, 0, 1, 1);
  7949. };
  7950. Layer.prototype.updateActiveEffects = function ()
  7951. {
  7952. this.active_effect_types.length = 0;
  7953. var i, len, et;
  7954. for (i = 0, len = this.effect_types.length; i < len; i++)
  7955. {
  7956. et = this.effect_types[i];
  7957. if (et.active)
  7958. this.active_effect_types.push(et);
  7959. }
  7960. };
  7961. Layer.prototype.getEffectByName = function (name_)
  7962. {
  7963. var i, len, et;
  7964. for (i = 0, len = this.effect_types.length; i < len; i++)
  7965. {
  7966. et = this.effect_types[i];
  7967. if (et.name === name_)
  7968. return et;
  7969. }
  7970. return null;
  7971. };
  7972. Layer.prototype.createInitialInstances = function ()
  7973. {
  7974. var i, k, len, inst, initial_inst, type, keep, hasPersistBehavior;
  7975. for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++)
  7976. {
  7977. initial_inst = this.initial_instances[i];
  7978. type = this.runtime.types_by_index[initial_inst[1]];
  7979. ;
  7980. hasPersistBehavior = this.runtime.typeHasPersistBehavior(type);
  7981. keep = true;
  7982. if (!hasPersistBehavior || this.layout.first_visit)
  7983. {
  7984. inst = this.runtime.createInstanceFromInit(initial_inst, this, true);
  7985. ;
  7986. created_instances.push(inst);
  7987. if (inst.type.global)
  7988. {
  7989. keep = false;
  7990. this.created_globals.push(inst.uid);
  7991. }
  7992. }
  7993. if (keep)
  7994. {
  7995. this.initial_instances[k] = this.initial_instances[i];
  7996. k++;
  7997. }
  7998. }
  7999. this.initial_instances.length = k;
  8000. this.runtime.ClearDeathRow(); // flushes creation row so IIDs will be correct
  8001. if (!this.runtime.glwrap && this.effect_types.length) // no WebGL renderer and shaders used
  8002. this.blend_mode = this.effect_fallback; // use fallback blend mode
  8003. this.compositeOp = cr.effectToCompositeOp(this.blend_mode);
  8004. if (this.runtime.gl)
  8005. cr.setGLBlend(this, this.blend_mode, this.runtime.gl);
  8006. this.render_list_stale = true;
  8007. };
  8008. Layer.prototype.recreateInitialObjects = function (only_type, rc)
  8009. {
  8010. var i, len, initial_inst, type, wm, x, y, inst, j, lenj, s;
  8011. var types_by_index = this.runtime.types_by_index;
  8012. var only_type_is_family = only_type.is_family;
  8013. var only_type_members = only_type.members;
  8014. for (i = 0, len = this.initial_instances.length; i < len; ++i)
  8015. {
  8016. initial_inst = this.initial_instances[i];
  8017. wm = initial_inst[0];
  8018. x = wm[0];
  8019. y = wm[1];
  8020. if (!rc.contains_pt(x, y))
  8021. continue; // not in the given area
  8022. type = types_by_index[initial_inst[1]];
  8023. if (type !== only_type)
  8024. {
  8025. if (only_type_is_family)
  8026. {
  8027. if (only_type_members.indexOf(type) < 0)
  8028. continue;
  8029. }
  8030. else
  8031. continue; // only_type is not a family, and the initial inst type does not match
  8032. }
  8033. inst = this.runtime.createInstanceFromInit(initial_inst, this, false);
  8034. this.runtime.isInOnDestroy++;
  8035. this.runtime.trigger(Object.getPrototypeOf(type.plugin).cnds.OnCreated, inst);
  8036. if (inst.is_contained)
  8037. {
  8038. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  8039. {
  8040. s = inst.siblings[i];
  8041. this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
  8042. }
  8043. }
  8044. this.runtime.isInOnDestroy--;
  8045. }
  8046. };
  8047. Layer.prototype.removeFromInstanceList = function (inst, remove_from_grid)
  8048. {
  8049. var index = cr.fastIndexOf(this.instances, inst);
  8050. if (index < 0)
  8051. return; // not found
  8052. if (remove_from_grid && this.useRenderCells && inst.rendercells && inst.rendercells.right >= inst.rendercells.left)
  8053. {
  8054. inst.update_bbox(); // make sure actually in its current rendercells
  8055. this.render_grid.update(inst, inst.rendercells, null); // no new range provided - remove only
  8056. inst.rendercells.set(0, 0, -1, -1); // set to invalid state to indicate not inserted
  8057. }
  8058. if (index === this.instances.length - 1)
  8059. this.instances.pop();
  8060. else
  8061. {
  8062. cr.arrayRemove(this.instances, index);
  8063. this.setZIndicesStaleFrom(index);
  8064. }
  8065. this.render_list_stale = true;
  8066. };
  8067. Layer.prototype.appendToInstanceList = function (inst, add_to_grid)
  8068. {
  8069. ;
  8070. inst.zindex = this.instances.length;
  8071. this.instances.push(inst);
  8072. if (add_to_grid && this.useRenderCells && inst.rendercells)
  8073. {
  8074. inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
  8075. }
  8076. this.render_list_stale = true;
  8077. };
  8078. Layer.prototype.prependToInstanceList = function (inst, add_to_grid)
  8079. {
  8080. ;
  8081. this.instances.unshift(inst);
  8082. this.setZIndicesStaleFrom(0);
  8083. if (add_to_grid && this.useRenderCells && inst.rendercells)
  8084. {
  8085. inst.set_bbox_changed(); // will cause immediate update and new insertion to grid
  8086. }
  8087. };
  8088. Layer.prototype.moveInstanceAdjacent = function (inst, other, isafter)
  8089. {
  8090. ;
  8091. var myZ = inst.get_zindex();
  8092. var insertZ = other.get_zindex();
  8093. cr.arrayRemove(this.instances, myZ);
  8094. if (myZ < insertZ)
  8095. insertZ--;
  8096. if (isafter)
  8097. insertZ++;
  8098. if (insertZ === this.instances.length)
  8099. this.instances.push(inst);
  8100. else
  8101. this.instances.splice(insertZ, 0, inst);
  8102. this.setZIndicesStaleFrom(myZ < insertZ ? myZ : insertZ);
  8103. };
  8104. Layer.prototype.setZIndicesStaleFrom = function (index)
  8105. {
  8106. if (this.zindices_stale_from === -1) // not yet set
  8107. this.zindices_stale_from = index;
  8108. else if (index < this.zindices_stale_from) // determine minimum z index affected
  8109. this.zindices_stale_from = index;
  8110. this.zindices_stale = true;
  8111. this.render_list_stale = true;
  8112. };
  8113. Layer.prototype.updateZIndices = function ()
  8114. {
  8115. if (!this.zindices_stale)
  8116. return;
  8117. if (this.zindices_stale_from === -1)
  8118. this.zindices_stale_from = 0;
  8119. var i, len, inst;
  8120. if (this.useRenderCells)
  8121. {
  8122. for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
  8123. {
  8124. inst = this.instances[i];
  8125. inst.zindex = i;
  8126. this.render_grid.markRangeChanged(inst.rendercells);
  8127. }
  8128. }
  8129. else
  8130. {
  8131. for (i = this.zindices_stale_from, len = this.instances.length; i < len; ++i)
  8132. {
  8133. this.instances[i].zindex = i;
  8134. }
  8135. }
  8136. this.zindices_stale = false;
  8137. this.zindices_stale_from = -1;
  8138. };
  8139. Layer.prototype.getScale = function (include_aspect)
  8140. {
  8141. return this.getNormalScale() * (this.runtime.fullscreenScalingQuality || include_aspect ? this.runtime.aspect_scale : 1);
  8142. };
  8143. Layer.prototype.getNormalScale = function ()
  8144. {
  8145. return ((this.scale * this.layout.scale) - 1) * this.zoomRate + 1;
  8146. };
  8147. Layer.prototype.getAngle = function ()
  8148. {
  8149. if (this.disableAngle)
  8150. return 0;
  8151. return cr.clamp_angle(this.layout.angle + this.angle);
  8152. };
  8153. var arr_cache = [];
  8154. function alloc_arr()
  8155. {
  8156. if (arr_cache.length)
  8157. return arr_cache.pop();
  8158. else
  8159. return [];
  8160. }
  8161. function free_arr(a)
  8162. {
  8163. a.length = 0;
  8164. arr_cache.push(a);
  8165. };
  8166. function mergeSortedZArrays(a, b, out)
  8167. {
  8168. var i = 0, j = 0, k = 0, lena = a.length, lenb = b.length, ai, bj;
  8169. out.length = lena + lenb;
  8170. for ( ; i < lena && j < lenb; ++k)
  8171. {
  8172. ai = a[i];
  8173. bj = b[j];
  8174. if (ai.zindex < bj.zindex)
  8175. {
  8176. out[k] = ai;
  8177. ++i;
  8178. }
  8179. else
  8180. {
  8181. out[k] = bj;
  8182. ++j;
  8183. }
  8184. }
  8185. for ( ; i < lena; ++i, ++k)
  8186. out[k] = a[i];
  8187. for ( ; j < lenb; ++j, ++k)
  8188. out[k] = b[j];
  8189. };
  8190. var next_arr = [];
  8191. function mergeAllSortedZArrays_pass(arr, first_pass)
  8192. {
  8193. var i, len, arr1, arr2, out;
  8194. for (i = 0, len = arr.length; i < len - 1; i += 2)
  8195. {
  8196. arr1 = arr[i];
  8197. arr2 = arr[i+1];
  8198. out = alloc_arr();
  8199. mergeSortedZArrays(arr1, arr2, out);
  8200. if (!first_pass)
  8201. {
  8202. free_arr(arr1);
  8203. free_arr(arr2);
  8204. }
  8205. next_arr.push(out);
  8206. }
  8207. if (len % 2 === 1)
  8208. {
  8209. if (first_pass)
  8210. {
  8211. arr1 = alloc_arr();
  8212. cr.shallowAssignArray(arr1, arr[len - 1]);
  8213. next_arr.push(arr1);
  8214. }
  8215. else
  8216. {
  8217. next_arr.push(arr[len - 1]);
  8218. }
  8219. }
  8220. cr.shallowAssignArray(arr, next_arr);
  8221. next_arr.length = 0;
  8222. };
  8223. function mergeAllSortedZArrays(arr)
  8224. {
  8225. var first_pass = true;
  8226. while (arr.length > 1)
  8227. {
  8228. mergeAllSortedZArrays_pass(arr, first_pass);
  8229. first_pass = false;
  8230. }
  8231. return arr[0];
  8232. };
  8233. var render_arr = [];
  8234. Layer.prototype.getRenderCellInstancesToDraw = function ()
  8235. {
  8236. ;
  8237. this.updateZIndices();
  8238. this.render_grid.queryRange(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom, render_arr);
  8239. if (!render_arr.length)
  8240. return alloc_arr();
  8241. if (render_arr.length === 1)
  8242. {
  8243. var a = alloc_arr();
  8244. cr.shallowAssignArray(a, render_arr[0]);
  8245. render_arr.length = 0;
  8246. return a;
  8247. }
  8248. var draw_list = mergeAllSortedZArrays(render_arr);
  8249. render_arr.length = 0;
  8250. return draw_list;
  8251. };
  8252. Layer.prototype.draw = function (ctx)
  8253. {
  8254. this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.blend_mode !== 0);
  8255. var layer_canvas = this.runtime.canvas;
  8256. var layer_ctx = ctx;
  8257. var ctx_changed = false;
  8258. if (this.render_offscreen)
  8259. {
  8260. if (!this.runtime.layer_canvas)
  8261. {
  8262. this.runtime.layer_canvas = document.createElement("canvas");
  8263. ;
  8264. layer_canvas = this.runtime.layer_canvas;
  8265. layer_canvas.width = this.runtime.draw_width;
  8266. layer_canvas.height = this.runtime.draw_height;
  8267. this.runtime.layer_ctx = layer_canvas.getContext("2d");
  8268. ;
  8269. ctx_changed = true;
  8270. }
  8271. layer_canvas = this.runtime.layer_canvas;
  8272. layer_ctx = this.runtime.layer_ctx;
  8273. if (layer_canvas.width !== this.runtime.draw_width)
  8274. {
  8275. layer_canvas.width = this.runtime.draw_width;
  8276. ctx_changed = true;
  8277. }
  8278. if (layer_canvas.height !== this.runtime.draw_height)
  8279. {
  8280. layer_canvas.height = this.runtime.draw_height;
  8281. ctx_changed = true;
  8282. }
  8283. if (ctx_changed)
  8284. {
  8285. layer_ctx["webkitImageSmoothingEnabled"] = this.runtime.linearSampling;
  8286. layer_ctx["mozImageSmoothingEnabled"] = this.runtime.linearSampling;
  8287. layer_ctx["msImageSmoothingEnabled"] = this.runtime.linearSampling;
  8288. layer_ctx["imageSmoothingEnabled"] = this.runtime.linearSampling;
  8289. }
  8290. if (this.transparent)
  8291. layer_ctx.clearRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
  8292. }
  8293. layer_ctx.globalAlpha = 1;
  8294. layer_ctx.globalCompositeOperation = "source-over";
  8295. if (!this.transparent)
  8296. {
  8297. layer_ctx.fillStyle = "rgb(" + this.background_color[0] + "," + this.background_color[1] + "," + this.background_color[2] + ")";
  8298. layer_ctx.fillRect(0, 0, this.runtime.draw_width, this.runtime.draw_height);
  8299. }
  8300. layer_ctx.save();
  8301. this.disableAngle = true;
  8302. var px = this.canvasToLayer(0, 0, true, true);
  8303. var py = this.canvasToLayer(0, 0, false, true);
  8304. this.disableAngle = false;
  8305. if (this.runtime.pixel_rounding)
  8306. {
  8307. px = Math.round(px);
  8308. py = Math.round(py);
  8309. }
  8310. this.rotateViewport(px, py, layer_ctx);
  8311. var myscale = this.getScale();
  8312. layer_ctx.scale(myscale, myscale);
  8313. layer_ctx.translate(-px, -py);
  8314. var instances_to_draw;
  8315. if (this.useRenderCells)
  8316. {
  8317. this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
  8318. this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
  8319. this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
  8320. this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
  8321. if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
  8322. {
  8323. free_arr(this.last_render_list);
  8324. instances_to_draw = this.getRenderCellInstancesToDraw();
  8325. this.render_list_stale = false;
  8326. this.last_render_cells.copy(this.cur_render_cells);
  8327. }
  8328. else
  8329. instances_to_draw = this.last_render_list;
  8330. }
  8331. else
  8332. instances_to_draw = this.instances;
  8333. var i, len, inst, last_inst = null;
  8334. for (i = 0, len = instances_to_draw.length; i < len; ++i)
  8335. {
  8336. inst = instances_to_draw[i];
  8337. if (inst === last_inst)
  8338. continue;
  8339. this.drawInstance(inst, layer_ctx);
  8340. last_inst = inst;
  8341. }
  8342. if (this.useRenderCells)
  8343. this.last_render_list = instances_to_draw;
  8344. layer_ctx.restore();
  8345. if (this.render_offscreen)
  8346. {
  8347. ctx.globalCompositeOperation = this.compositeOp;
  8348. ctx.globalAlpha = this.opacity;
  8349. ctx.drawImage(layer_canvas, 0, 0);
  8350. }
  8351. };
  8352. Layer.prototype.drawInstance = function(inst, layer_ctx)
  8353. {
  8354. if (!inst.visible || inst.width === 0 || inst.height === 0)
  8355. return;
  8356. inst.update_bbox();
  8357. var bbox = inst.bbox;
  8358. if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
  8359. return;
  8360. layer_ctx.globalCompositeOperation = inst.compositeOp;
  8361. inst.draw(layer_ctx);
  8362. };
  8363. Layer.prototype.updateViewport = function (ctx)
  8364. {
  8365. this.disableAngle = true;
  8366. var px = this.canvasToLayer(0, 0, true, true);
  8367. var py = this.canvasToLayer(0, 0, false, true);
  8368. this.disableAngle = false;
  8369. if (this.runtime.pixel_rounding)
  8370. {
  8371. px = Math.round(px);
  8372. py = Math.round(py);
  8373. }
  8374. this.rotateViewport(px, py, ctx);
  8375. };
  8376. Layer.prototype.rotateViewport = function (px, py, ctx)
  8377. {
  8378. var myscale = this.getScale();
  8379. this.viewLeft = px;
  8380. this.viewTop = py;
  8381. this.viewRight = px + (this.runtime.draw_width * (1 / myscale));
  8382. this.viewBottom = py + (this.runtime.draw_height * (1 / myscale));
  8383. var myAngle = this.getAngle();
  8384. if (myAngle !== 0)
  8385. {
  8386. if (ctx)
  8387. {
  8388. ctx.translate(this.runtime.draw_width / 2, this.runtime.draw_height / 2);
  8389. ctx.rotate(-myAngle);
  8390. ctx.translate(this.runtime.draw_width / -2, this.runtime.draw_height / -2);
  8391. }
  8392. this.tmprect.set(this.viewLeft, this.viewTop, this.viewRight, this.viewBottom);
  8393. this.tmprect.offset((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
  8394. this.tmpquad.set_from_rotated_rect(this.tmprect, myAngle);
  8395. this.tmpquad.bounding_box(this.tmprect);
  8396. this.tmprect.offset((this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2);
  8397. this.viewLeft = this.tmprect.left;
  8398. this.viewTop = this.tmprect.top;
  8399. this.viewRight = this.tmprect.right;
  8400. this.viewBottom = this.tmprect.bottom;
  8401. }
  8402. }
  8403. Layer.prototype.drawGL = function (glw)
  8404. {
  8405. var windowWidth = this.runtime.draw_width;
  8406. var windowHeight = this.runtime.draw_height;
  8407. var shaderindex = 0;
  8408. var etindex = 0;
  8409. this.render_offscreen = (this.forceOwnTexture || this.opacity !== 1.0 || this.active_effect_types.length > 0 || this.blend_mode !== 0);
  8410. if (this.render_offscreen)
  8411. {
  8412. if (!this.runtime.layer_tex)
  8413. {
  8414. this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
  8415. }
  8416. if (this.runtime.layer_tex.c2width !== this.runtime.draw_width || this.runtime.layer_tex.c2height !== this.runtime.draw_height)
  8417. {
  8418. glw.deleteTexture(this.runtime.layer_tex);
  8419. this.runtime.layer_tex = glw.createEmptyTexture(this.runtime.draw_width, this.runtime.draw_height, this.runtime.linearSampling);
  8420. }
  8421. glw.setRenderingToTexture(this.runtime.layer_tex);
  8422. if (this.transparent)
  8423. glw.clear(0, 0, 0, 0);
  8424. }
  8425. if (!this.transparent)
  8426. {
  8427. glw.clear(this.background_color[0] / 255, this.background_color[1] / 255, this.background_color[2] / 255, 1);
  8428. }
  8429. this.disableAngle = true;
  8430. var px = this.canvasToLayer(0, 0, true, true);
  8431. var py = this.canvasToLayer(0, 0, false, true);
  8432. this.disableAngle = false;
  8433. if (this.runtime.pixel_rounding)
  8434. {
  8435. px = Math.round(px);
  8436. py = Math.round(py);
  8437. }
  8438. this.rotateViewport(px, py, null);
  8439. var myscale = this.getScale();
  8440. glw.resetModelView();
  8441. glw.scale(myscale, myscale);
  8442. glw.rotateZ(-this.getAngle());
  8443. glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
  8444. glw.updateModelView();
  8445. var instances_to_draw;
  8446. if (this.useRenderCells)
  8447. {
  8448. this.cur_render_cells.left = this.render_grid.XToCell(this.viewLeft);
  8449. this.cur_render_cells.top = this.render_grid.YToCell(this.viewTop);
  8450. this.cur_render_cells.right = this.render_grid.XToCell(this.viewRight);
  8451. this.cur_render_cells.bottom = this.render_grid.YToCell(this.viewBottom);
  8452. if (this.render_list_stale || !this.cur_render_cells.equals(this.last_render_cells))
  8453. {
  8454. free_arr(this.last_render_list);
  8455. instances_to_draw = this.getRenderCellInstancesToDraw();
  8456. this.render_list_stale = false;
  8457. this.last_render_cells.copy(this.cur_render_cells);
  8458. }
  8459. else
  8460. instances_to_draw = this.last_render_list;
  8461. }
  8462. else
  8463. instances_to_draw = this.instances;
  8464. var i, len, inst, last_inst = null;
  8465. for (i = 0, len = instances_to_draw.length; i < len; ++i)
  8466. {
  8467. inst = instances_to_draw[i];
  8468. if (inst === last_inst)
  8469. continue;
  8470. this.drawInstanceGL(instances_to_draw[i], glw);
  8471. last_inst = inst;
  8472. }
  8473. if (this.useRenderCells)
  8474. this.last_render_list = instances_to_draw;
  8475. if (this.render_offscreen)
  8476. {
  8477. shaderindex = this.active_effect_types.length ? this.active_effect_types[0].shaderindex : 0;
  8478. etindex = this.active_effect_types.length ? this.active_effect_types[0].index : 0;
  8479. if (this.active_effect_types.length === 0 || (this.active_effect_types.length === 1 &&
  8480. !glw.programUsesCrossSampling(shaderindex) && this.opacity === 1))
  8481. {
  8482. if (this.active_effect_types.length === 1)
  8483. {
  8484. glw.switchProgram(shaderindex);
  8485. glw.setProgramParameters(this.layout.getRenderTarget(), // backTex
  8486. 1.0 / this.runtime.draw_width, // pixelWidth
  8487. 1.0 / this.runtime.draw_height, // pixelHeight
  8488. 0.0, 0.0, // destStart
  8489. 1.0, 1.0, // destEnd
  8490. myscale, // layerScale
  8491. this.getAngle(),
  8492. this.viewLeft, this.viewTop,
  8493. (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
  8494. this.effect_params[etindex]); // fx parameters
  8495. if (glw.programIsAnimated(shaderindex))
  8496. this.runtime.redraw = true;
  8497. }
  8498. else
  8499. glw.switchProgram(0);
  8500. glw.setRenderingToTexture(this.layout.getRenderTarget());
  8501. glw.setOpacity(this.opacity);
  8502. glw.setTexture(this.runtime.layer_tex);
  8503. glw.setBlend(this.srcBlend, this.destBlend);
  8504. glw.resetModelView();
  8505. glw.updateModelView();
  8506. var halfw = this.runtime.draw_width / 2;
  8507. var halfh = this.runtime.draw_height / 2;
  8508. glw.quad(-halfw, halfh, halfw, halfh, halfw, -halfh, -halfw, -halfh);
  8509. glw.setTexture(null);
  8510. }
  8511. else
  8512. {
  8513. this.layout.renderEffectChain(glw, this, null, this.layout.getRenderTarget());
  8514. }
  8515. }
  8516. };
  8517. Layer.prototype.drawInstanceGL = function (inst, glw)
  8518. {
  8519. ;
  8520. if (!inst.visible || inst.width === 0 || inst.height === 0)
  8521. return;
  8522. inst.update_bbox();
  8523. var bbox = inst.bbox;
  8524. if (bbox.right < this.viewLeft || bbox.bottom < this.viewTop || bbox.left > this.viewRight || bbox.top > this.viewBottom)
  8525. return;
  8526. if (inst.uses_shaders)
  8527. {
  8528. this.drawInstanceWithShadersGL(inst, glw);
  8529. }
  8530. else
  8531. {
  8532. glw.switchProgram(0); // un-set any previously set shader
  8533. glw.setBlend(inst.srcBlend, inst.destBlend);
  8534. inst.drawGL(glw);
  8535. }
  8536. };
  8537. Layer.prototype.drawInstanceWithShadersGL = function (inst, glw)
  8538. {
  8539. var shaderindex = inst.active_effect_types[0].shaderindex;
  8540. var etindex = inst.active_effect_types[0].index;
  8541. var myscale = this.getScale();
  8542. if (inst.active_effect_types.length === 1 && !glw.programUsesCrossSampling(shaderindex) &&
  8543. !glw.programExtendsBox(shaderindex) && ((!inst.angle && !inst.layer.getAngle()) || !glw.programUsesDest(shaderindex)) &&
  8544. inst.opacity === 1 && !inst.type.plugin.must_predraw)
  8545. {
  8546. glw.switchProgram(shaderindex);
  8547. glw.setBlend(inst.srcBlend, inst.destBlend);
  8548. if (glw.programIsAnimated(shaderindex))
  8549. this.runtime.redraw = true;
  8550. var destStartX = 0, destStartY = 0, destEndX = 0, destEndY = 0;
  8551. if (glw.programUsesDest(shaderindex))
  8552. {
  8553. var bbox = inst.bbox;
  8554. var screenleft = this.layerToCanvas(bbox.left, bbox.top, true, true);
  8555. var screentop = this.layerToCanvas(bbox.left, bbox.top, false, true);
  8556. var screenright = this.layerToCanvas(bbox.right, bbox.bottom, true, true);
  8557. var screenbottom = this.layerToCanvas(bbox.right, bbox.bottom, false, true);
  8558. destStartX = screenleft / windowWidth;
  8559. destStartY = 1 - screentop / windowHeight;
  8560. destEndX = screenright / windowWidth;
  8561. destEndY = 1 - screenbottom / windowHeight;
  8562. }
  8563. glw.setProgramParameters(this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget(), // backTex
  8564. 1.0 / inst.width, // pixelWidth
  8565. 1.0 / inst.height, // pixelHeight
  8566. destStartX, destStartY,
  8567. destEndX, destEndY,
  8568. myscale,
  8569. this.getAngle(),
  8570. this.viewLeft, this.viewTop,
  8571. (this.viewLeft + this.viewRight) / 2, (this.viewTop + this.viewBottom) / 2,
  8572. inst.effect_params[etindex]);
  8573. inst.drawGL(glw);
  8574. }
  8575. else
  8576. {
  8577. this.layout.renderEffectChain(glw, this, inst, this.render_offscreen ? this.runtime.layer_tex : this.layout.getRenderTarget());
  8578. glw.resetModelView();
  8579. glw.scale(myscale, myscale);
  8580. glw.rotateZ(-this.getAngle());
  8581. glw.translate((this.viewLeft + this.viewRight) / -2, (this.viewTop + this.viewBottom) / -2);
  8582. glw.updateModelView();
  8583. }
  8584. };
  8585. Layer.prototype.canvasToLayer = function (ptx, pty, getx, using_draw_area)
  8586. {
  8587. var multiplier = this.runtime.devicePixelRatio;
  8588. if (this.runtime.isRetina)
  8589. {
  8590. ptx *= multiplier;
  8591. pty *= multiplier;
  8592. }
  8593. var ox = this.runtime.parallax_x_origin;
  8594. var oy = this.runtime.parallax_y_origin;
  8595. var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
  8596. var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
  8597. var x = par_x;
  8598. var y = par_y;
  8599. var invScale = 1 / this.getScale(!using_draw_area);
  8600. if (using_draw_area)
  8601. {
  8602. x -= (this.runtime.draw_width * invScale) / 2;
  8603. y -= (this.runtime.draw_height * invScale) / 2;
  8604. }
  8605. else
  8606. {
  8607. x -= (this.runtime.width * invScale) / 2;
  8608. y -= (this.runtime.height * invScale) / 2;
  8609. }
  8610. x += ptx * invScale;
  8611. y += pty * invScale;
  8612. var a = this.getAngle();
  8613. if (a !== 0)
  8614. {
  8615. x -= par_x;
  8616. y -= par_y;
  8617. var cosa = Math.cos(a);
  8618. var sina = Math.sin(a);
  8619. var x_temp = (x * cosa) - (y * sina);
  8620. y = (y * cosa) + (x * sina);
  8621. x = x_temp;
  8622. x += par_x;
  8623. y += par_y;
  8624. }
  8625. return getx ? x : y;
  8626. };
  8627. Layer.prototype.layerToCanvas = function (ptx, pty, getx, using_draw_area)
  8628. {
  8629. var ox = this.runtime.parallax_x_origin;
  8630. var oy = this.runtime.parallax_y_origin;
  8631. var par_x = ((this.layout.scrollX - ox) * this.parallaxX) + ox;
  8632. var par_y = ((this.layout.scrollY - oy) * this.parallaxY) + oy;
  8633. var x = par_x;
  8634. var y = par_y;
  8635. var a = this.getAngle();
  8636. if (a !== 0)
  8637. {
  8638. ptx -= par_x;
  8639. pty -= par_y;
  8640. var cosa = Math.cos(-a);
  8641. var sina = Math.sin(-a);
  8642. var x_temp = (ptx * cosa) - (pty * sina);
  8643. pty = (pty * cosa) + (ptx * sina);
  8644. ptx = x_temp;
  8645. ptx += par_x;
  8646. pty += par_y;
  8647. }
  8648. var invScale = 1 / this.getScale(!using_draw_area);
  8649. if (using_draw_area)
  8650. {
  8651. x -= (this.runtime.draw_width * invScale) / 2;
  8652. y -= (this.runtime.draw_height * invScale) / 2;
  8653. }
  8654. else
  8655. {
  8656. x -= (this.runtime.width * invScale) / 2;
  8657. y -= (this.runtime.height * invScale) / 2;
  8658. }
  8659. x = (ptx - x) / invScale;
  8660. y = (pty - y) / invScale;
  8661. var multiplier = this.runtime.devicePixelRatio;
  8662. if (this.runtime.isRetina && !using_draw_area)
  8663. {
  8664. x /= multiplier;
  8665. y /= multiplier;
  8666. }
  8667. return getx ? x : y;
  8668. };
  8669. Layer.prototype.rotatePt = function (x_, y_, getx)
  8670. {
  8671. if (this.getAngle() === 0)
  8672. return getx ? x_ : y_;
  8673. var nx = this.layerToCanvas(x_, y_, true);
  8674. var ny = this.layerToCanvas(x_, y_, false);
  8675. this.disableAngle = true;
  8676. var px = this.canvasToLayer(nx, ny, true);
  8677. var py = this.canvasToLayer(nx, ny, true);
  8678. this.disableAngle = false;
  8679. return getx ? px : py;
  8680. };
  8681. Layer.prototype.saveToJSON = function ()
  8682. {
  8683. var i, len, et;
  8684. var o = {
  8685. "s": this.scale,
  8686. "a": this.angle,
  8687. "vl": this.viewLeft,
  8688. "vt": this.viewTop,
  8689. "vr": this.viewRight,
  8690. "vb": this.viewBottom,
  8691. "v": this.visible,
  8692. "bc": this.background_color,
  8693. "t": this.transparent,
  8694. "px": this.parallaxX,
  8695. "py": this.parallaxY,
  8696. "o": this.opacity,
  8697. "zr": this.zoomRate,
  8698. "fx": [],
  8699. "cg": this.created_globals, // added r197; list of global UIDs already created
  8700. "instances": []
  8701. };
  8702. for (i = 0, len = this.effect_types.length; i < len; i++)
  8703. {
  8704. et = this.effect_types[i];
  8705. o["fx"].push({"name": et.name, "active": et.active, "params": this.effect_params[et.index] });
  8706. }
  8707. return o;
  8708. };
  8709. Layer.prototype.loadFromJSON = function (o)
  8710. {
  8711. var i, j, len, p, inst, fx;
  8712. this.scale = o["s"];
  8713. this.angle = o["a"];
  8714. this.viewLeft = o["vl"];
  8715. this.viewTop = o["vt"];
  8716. this.viewRight = o["vr"];
  8717. this.viewBottom = o["vb"];
  8718. this.visible = o["v"];
  8719. this.background_color = o["bc"];
  8720. this.transparent = o["t"];
  8721. this.parallaxX = o["px"];
  8722. this.parallaxY = o["py"];
  8723. this.opacity = o["o"];
  8724. this.zoomRate = o["zr"];
  8725. this.created_globals = o["cg"] || []; // added r197
  8726. cr.shallowAssignArray(this.initial_instances, this.startup_initial_instances);
  8727. var temp_set = new cr.ObjectSet();
  8728. for (i = 0, len = this.created_globals.length; i < len; ++i)
  8729. temp_set.add(this.created_globals[i]);
  8730. for (i = 0, j = 0, len = this.initial_instances.length; i < len; ++i)
  8731. {
  8732. if (!temp_set.contains(this.initial_instances[i][2])) // UID in element 2
  8733. {
  8734. this.initial_instances[j] = this.initial_instances[i];
  8735. ++j;
  8736. }
  8737. }
  8738. this.initial_instances.length = j;
  8739. var ofx = o["fx"];
  8740. for (i = 0, len = ofx.length; i < len; i++)
  8741. {
  8742. fx = this.getEffectByName(ofx[i]["name"]);
  8743. if (!fx)
  8744. continue; // must've gone missing
  8745. fx.active = ofx[i]["active"];
  8746. this.effect_params[fx.index] = ofx[i]["params"];
  8747. }
  8748. this.updateActiveEffects();
  8749. this.instances.sort(sort_by_zindex);
  8750. this.zindices_stale = true;
  8751. };
  8752. cr.layer = Layer;
  8753. }());
  8754. ;
  8755. (function()
  8756. {
  8757. var allUniqueSolModifiers = [];
  8758. function testSolsMatch(arr1, arr2)
  8759. {
  8760. var i, len = arr1.length;
  8761. switch (len) {
  8762. case 0:
  8763. return true;
  8764. case 1:
  8765. return arr1[0] === arr2[0];
  8766. case 2:
  8767. return arr1[0] === arr2[0] && arr1[1] === arr2[1];
  8768. default:
  8769. for (i = 0; i < len; i++)
  8770. {
  8771. if (arr1[i] !== arr2[i])
  8772. return false;
  8773. }
  8774. return true;
  8775. }
  8776. };
  8777. function solArraySorter(t1, t2)
  8778. {
  8779. return t1.index - t2.index;
  8780. };
  8781. function findMatchingSolModifier(arr)
  8782. {
  8783. var i, len, u, temp, subarr;
  8784. if (arr.length === 2)
  8785. {
  8786. if (arr[0].index > arr[1].index)
  8787. {
  8788. temp = arr[0];
  8789. arr[0] = arr[1];
  8790. arr[1] = temp;
  8791. }
  8792. }
  8793. else if (arr.length > 2)
  8794. arr.sort(solArraySorter); // so testSolsMatch compares in same order
  8795. if (arr.length >= allUniqueSolModifiers.length)
  8796. allUniqueSolModifiers.length = arr.length + 1;
  8797. if (!allUniqueSolModifiers[arr.length])
  8798. allUniqueSolModifiers[arr.length] = [];
  8799. subarr = allUniqueSolModifiers[arr.length];
  8800. for (i = 0, len = subarr.length; i < len; i++)
  8801. {
  8802. u = subarr[i];
  8803. if (testSolsMatch(arr, u))
  8804. return u;
  8805. }
  8806. subarr.push(arr);
  8807. return arr;
  8808. };
  8809. function EventSheet(runtime, m)
  8810. {
  8811. this.runtime = runtime;
  8812. this.triggers = {};
  8813. this.fasttriggers = {};
  8814. this.hasRun = false;
  8815. this.includes = new cr.ObjectSet(); // all event sheets included by this sheet, at first-level indirection only
  8816. this.deep_includes = []; // all includes from this sheet recursively, in trigger order
  8817. this.already_included_sheets = []; // used while building deep_includes
  8818. this.name = m[0];
  8819. var em = m[1]; // events model
  8820. this.events = []; // triggers won't make it to this array
  8821. var i, len;
  8822. for (i = 0, len = em.length; i < len; i++)
  8823. this.init_event(em[i], null, this.events);
  8824. };
  8825. EventSheet.prototype.toString = function ()
  8826. {
  8827. return this.name;
  8828. };
  8829. EventSheet.prototype.init_event = function (m, parent, nontriggers)
  8830. {
  8831. switch (m[0]) {
  8832. case 0: // event block
  8833. {
  8834. var block = new cr.eventblock(this, parent, m);
  8835. cr.seal(block);
  8836. if (block.orblock)
  8837. {
  8838. nontriggers.push(block);
  8839. var i, len;
  8840. for (i = 0, len = block.conditions.length; i < len; i++)
  8841. {
  8842. if (block.conditions[i].trigger)
  8843. this.init_trigger(block, i);
  8844. }
  8845. }
  8846. else
  8847. {
  8848. if (block.is_trigger())
  8849. this.init_trigger(block, 0);
  8850. else
  8851. nontriggers.push(block);
  8852. }
  8853. break;
  8854. }
  8855. case 1: // variable
  8856. {
  8857. var v = new cr.eventvariable(this, parent, m);
  8858. cr.seal(v);
  8859. nontriggers.push(v);
  8860. break;
  8861. }
  8862. case 2: // include
  8863. {
  8864. var inc = new cr.eventinclude(this, parent, m);
  8865. cr.seal(inc);
  8866. nontriggers.push(inc);
  8867. break;
  8868. }
  8869. default:
  8870. ;
  8871. }
  8872. };
  8873. EventSheet.prototype.postInit = function ()
  8874. {
  8875. var i, len;
  8876. for (i = 0, len = this.events.length; i < len; i++)
  8877. {
  8878. this.events[i].postInit(i < len - 1 && this.events[i + 1].is_else_block);
  8879. }
  8880. };
  8881. EventSheet.prototype.updateDeepIncludes = function ()
  8882. {
  8883. cr.clearArray(this.deep_includes);
  8884. cr.clearArray(this.already_included_sheets);
  8885. this.addDeepIncludes(this);
  8886. cr.clearArray(this.already_included_sheets);
  8887. };
  8888. EventSheet.prototype.addDeepIncludes = function (root_sheet)
  8889. {
  8890. var i, len, inc, sheet;
  8891. var deep_includes = root_sheet.deep_includes;
  8892. var already_included_sheets = root_sheet.already_included_sheets;
  8893. var arr = this.includes.valuesRef();
  8894. for (i = 0, len = arr.length; i < len; ++i)
  8895. {
  8896. inc = arr[i];
  8897. sheet = inc.include_sheet;
  8898. if (!inc.isActive() || root_sheet === sheet || already_included_sheets.indexOf(sheet) > -1)
  8899. continue;
  8900. already_included_sheets.push(sheet);
  8901. sheet.addDeepIncludes(root_sheet);
  8902. deep_includes.push(sheet);
  8903. }
  8904. };
  8905. EventSheet.prototype.run = function (from_include)
  8906. {
  8907. if (!this.runtime.resuming_breakpoint)
  8908. {
  8909. this.hasRun = true;
  8910. if (!from_include)
  8911. this.runtime.isRunningEvents = true;
  8912. }
  8913. var i, len;
  8914. for (i = 0, len = this.events.length; i < len; i++)
  8915. {
  8916. var ev = this.events[i];
  8917. ev.run();
  8918. this.runtime.clearSol(ev.solModifiers);
  8919. if (this.runtime.hasPendingInstances)
  8920. this.runtime.ClearDeathRow();
  8921. }
  8922. if (!from_include)
  8923. this.runtime.isRunningEvents = false;
  8924. };
  8925. function isPerformanceSensitiveTrigger(method)
  8926. {
  8927. if (cr.plugins_.Sprite && method === cr.plugins_.Sprite.prototype.cnds.OnFrameChanged)
  8928. {
  8929. return true;
  8930. }
  8931. return false;
  8932. };
  8933. EventSheet.prototype.init_trigger = function (trig, index)
  8934. {
  8935. if (!trig.orblock)
  8936. this.runtime.triggers_to_postinit.push(trig); // needs to be postInit'd later
  8937. var i, len;
  8938. var cnd = trig.conditions[index];
  8939. var type_name;
  8940. if (cnd.type)
  8941. type_name = cnd.type.name;
  8942. else
  8943. type_name = "system";
  8944. var fasttrigger = cnd.fasttrigger;
  8945. var triggers = (fasttrigger ? this.fasttriggers : this.triggers);
  8946. if (!triggers[type_name])
  8947. triggers[type_name] = [];
  8948. var obj_entry = triggers[type_name];
  8949. var method = cnd.func;
  8950. if (fasttrigger)
  8951. {
  8952. if (!cnd.parameters.length) // no parameters
  8953. return;
  8954. var firstparam = cnd.parameters[0];
  8955. if (firstparam.type !== 1 || // not a string param
  8956. firstparam.expression.type !== 2) // not a string literal node
  8957. {
  8958. return;
  8959. }
  8960. var fastevs;
  8961. var firstvalue = firstparam.expression.value.toLowerCase();
  8962. var i, len;
  8963. for (i = 0, len = obj_entry.length; i < len; i++)
  8964. {
  8965. if (obj_entry[i].method == method)
  8966. {
  8967. fastevs = obj_entry[i].evs;
  8968. if (!fastevs[firstvalue])
  8969. fastevs[firstvalue] = [[trig, index]];
  8970. else
  8971. fastevs[firstvalue].push([trig, index]);
  8972. return;
  8973. }
  8974. }
  8975. fastevs = {};
  8976. fastevs[firstvalue] = [[trig, index]];
  8977. obj_entry.push({ method: method, evs: fastevs });
  8978. }
  8979. else
  8980. {
  8981. for (i = 0, len = obj_entry.length; i < len; i++)
  8982. {
  8983. if (obj_entry[i].method == method)
  8984. {
  8985. obj_entry[i].evs.push([trig, index]);
  8986. return;
  8987. }
  8988. }
  8989. if (isPerformanceSensitiveTrigger(method))
  8990. obj_entry.unshift({ method: method, evs: [[trig, index]]});
  8991. else
  8992. obj_entry.push({ method: method, evs: [[trig, index]]});
  8993. }
  8994. };
  8995. cr.eventsheet = EventSheet;
  8996. function Selection(type)
  8997. {
  8998. this.type = type;
  8999. this.instances = []; // subset of picked instances
  9000. this.else_instances = []; // subset of unpicked instances
  9001. this.select_all = true;
  9002. };
  9003. Selection.prototype.hasObjects = function ()
  9004. {
  9005. if (this.select_all)
  9006. return this.type.instances.length;
  9007. else
  9008. return this.instances.length;
  9009. };
  9010. Selection.prototype.getObjects = function ()
  9011. {
  9012. if (this.select_all)
  9013. return this.type.instances;
  9014. else
  9015. return this.instances;
  9016. };
  9017. /*
  9018. Selection.prototype.ensure_picked = function (inst, skip_siblings)
  9019. {
  9020. var i, len;
  9021. var orblock = inst.runtime.getCurrentEventStack().current_event.orblock;
  9022. if (this.select_all)
  9023. {
  9024. this.select_all = false;
  9025. if (orblock)
  9026. {
  9027. cr.shallowAssignArray(this.else_instances, inst.type.instances);
  9028. cr.arrayFindRemove(this.else_instances, inst);
  9029. }
  9030. this.instances.length = 1;
  9031. this.instances[0] = inst;
  9032. }
  9033. else
  9034. {
  9035. if (orblock)
  9036. {
  9037. i = this.else_instances.indexOf(inst);
  9038. if (i !== -1)
  9039. {
  9040. this.instances.push(this.else_instances[i]);
  9041. this.else_instances.splice(i, 1);
  9042. }
  9043. }
  9044. else
  9045. {
  9046. if (this.instances.indexOf(inst) === -1)
  9047. this.instances.push(inst);
  9048. }
  9049. }
  9050. if (!skip_siblings)
  9051. {
  9052. }
  9053. };
  9054. */
  9055. Selection.prototype.pick_one = function (inst)
  9056. {
  9057. if (!inst)
  9058. return;
  9059. if (inst.runtime.getCurrentEventStack().current_event.orblock)
  9060. {
  9061. if (this.select_all)
  9062. {
  9063. cr.clearArray(this.instances);
  9064. cr.shallowAssignArray(this.else_instances, inst.type.instances);
  9065. this.select_all = false;
  9066. }
  9067. var i = this.else_instances.indexOf(inst);
  9068. if (i !== -1)
  9069. {
  9070. this.instances.push(this.else_instances[i]);
  9071. this.else_instances.splice(i, 1);
  9072. }
  9073. }
  9074. else
  9075. {
  9076. this.select_all = false;
  9077. cr.clearArray(this.instances);
  9078. this.instances[0] = inst;
  9079. }
  9080. };
  9081. cr.selection = Selection;
  9082. function EventBlock(sheet, parent, m)
  9083. {
  9084. this.sheet = sheet;
  9085. this.parent = parent;
  9086. this.runtime = sheet.runtime;
  9087. this.solModifiers = [];
  9088. this.solModifiersIncludingParents = [];
  9089. this.solWriterAfterCnds = false; // block does not change SOL after running its conditions
  9090. this.group = false; // is group of events
  9091. this.initially_activated = false; // if a group, is active on startup
  9092. this.toplevelevent = false; // is an event block parented only by a top-level group
  9093. this.toplevelgroup = false; // is parented only by other groups or is top-level (i.e. not in a subevent)
  9094. this.has_else_block = false; // is followed by else
  9095. ;
  9096. this.conditions = [];
  9097. this.actions = [];
  9098. this.subevents = [];
  9099. this.group_name = "";
  9100. this.group = false;
  9101. this.initially_activated = false;
  9102. this.group_active = false;
  9103. this.contained_includes = null;
  9104. if (m[1])
  9105. {
  9106. this.group_name = m[1][1].toLowerCase();
  9107. this.group = true;
  9108. this.initially_activated = !!m[1][0];
  9109. this.contained_includes = [];
  9110. this.group_active = this.initially_activated;
  9111. this.runtime.allGroups.push(this);
  9112. this.runtime.groups_by_name[this.group_name] = this;
  9113. }
  9114. this.orblock = m[2];
  9115. this.sid = m[4];
  9116. if (!this.group)
  9117. this.runtime.blocksBySid[this.sid.toString()] = this;
  9118. var i, len;
  9119. var cm = m[5];
  9120. for (i = 0, len = cm.length; i < len; i++)
  9121. {
  9122. var cnd = new cr.condition(this, cm[i]);
  9123. cnd.index = i;
  9124. cr.seal(cnd);
  9125. this.conditions.push(cnd);
  9126. /*
  9127. if (cnd.is_logical())
  9128. this.is_logical = true;
  9129. if (cnd.type && !cnd.type.plugin.singleglobal && this.cndReferences.indexOf(cnd.type) === -1)
  9130. this.cndReferences.push(cnd.type);
  9131. */
  9132. this.addSolModifier(cnd.type);
  9133. }
  9134. var am = m[6];
  9135. for (i = 0, len = am.length; i < len; i++)
  9136. {
  9137. var act = new cr.action(this, am[i]);
  9138. act.index = i;
  9139. cr.seal(act);
  9140. this.actions.push(act);
  9141. }
  9142. if (m.length === 8)
  9143. {
  9144. var em = m[7];
  9145. for (i = 0, len = em.length; i < len; i++)
  9146. this.sheet.init_event(em[i], this, this.subevents);
  9147. }
  9148. this.is_else_block = false;
  9149. if (this.conditions.length)
  9150. {
  9151. this.is_else_block = (this.conditions[0].type == null && this.conditions[0].func == cr.system_object.prototype.cnds.Else);
  9152. }
  9153. };
  9154. window["_c2hh_"] = "DE239334C48DAB94C32CB8CBD790EBFCDB31D26F";
  9155. EventBlock.prototype.postInit = function (hasElse/*, prevBlock_*/)
  9156. {
  9157. var i, len;
  9158. var p = this.parent;
  9159. if (this.group)
  9160. {
  9161. this.toplevelgroup = true;
  9162. while (p)
  9163. {
  9164. if (!p.group)
  9165. {
  9166. this.toplevelgroup = false;
  9167. break;
  9168. }
  9169. p = p.parent;
  9170. }
  9171. }
  9172. this.toplevelevent = !this.is_trigger() && (!this.parent || (this.parent.group && this.parent.toplevelgroup));
  9173. this.has_else_block = !!hasElse;
  9174. this.solModifiersIncludingParents = this.solModifiers.slice(0);
  9175. p = this.parent;
  9176. while (p)
  9177. {
  9178. for (i = 0, len = p.solModifiers.length; i < len; i++)
  9179. this.addParentSolModifier(p.solModifiers[i]);
  9180. p = p.parent;
  9181. }
  9182. this.solModifiers = findMatchingSolModifier(this.solModifiers);
  9183. this.solModifiersIncludingParents = findMatchingSolModifier(this.solModifiersIncludingParents);
  9184. var i, len/*, s*/;
  9185. for (i = 0, len = this.conditions.length; i < len; i++)
  9186. this.conditions[i].postInit();
  9187. for (i = 0, len = this.actions.length; i < len; i++)
  9188. this.actions[i].postInit();
  9189. for (i = 0, len = this.subevents.length; i < len; i++)
  9190. {
  9191. this.subevents[i].postInit(i < len - 1 && this.subevents[i + 1].is_else_block);
  9192. }
  9193. /*
  9194. if (this.is_else_block && this.prev_block)
  9195. {
  9196. for (i = 0, len = this.prev_block.solModifiers.length; i < len; i++)
  9197. {
  9198. s = this.prev_block.solModifiers[i];
  9199. if (this.solModifiers.indexOf(s) === -1)
  9200. this.solModifiers.push(s);
  9201. }
  9202. }
  9203. */
  9204. };
  9205. EventBlock.prototype.setGroupActive = function (a)
  9206. {
  9207. if (this.group_active === !!a)
  9208. return; // same state
  9209. this.group_active = !!a;
  9210. var i, len;
  9211. for (i = 0, len = this.contained_includes.length; i < len; ++i)
  9212. {
  9213. this.contained_includes[i].updateActive();
  9214. }
  9215. if (len > 0 && this.runtime.running_layout.event_sheet)
  9216. this.runtime.running_layout.event_sheet.updateDeepIncludes();
  9217. };
  9218. function addSolModifierToList(type, arr)
  9219. {
  9220. var i, len, t;
  9221. if (!type)
  9222. return;
  9223. if (arr.indexOf(type) === -1)
  9224. arr.push(type);
  9225. if (type.is_contained)
  9226. {
  9227. for (i = 0, len = type.container.length; i < len; i++)
  9228. {
  9229. t = type.container[i];
  9230. if (type === t)
  9231. continue; // already handled
  9232. if (arr.indexOf(t) === -1)
  9233. arr.push(t);
  9234. }
  9235. }
  9236. };
  9237. EventBlock.prototype.addSolModifier = function (type)
  9238. {
  9239. addSolModifierToList(type, this.solModifiers);
  9240. };
  9241. EventBlock.prototype.addParentSolModifier = function (type)
  9242. {
  9243. addSolModifierToList(type, this.solModifiersIncludingParents);
  9244. };
  9245. EventBlock.prototype.setSolWriterAfterCnds = function ()
  9246. {
  9247. this.solWriterAfterCnds = true;
  9248. if (this.parent)
  9249. this.parent.setSolWriterAfterCnds();
  9250. };
  9251. EventBlock.prototype.is_trigger = function ()
  9252. {
  9253. if (!this.conditions.length) // no conditions
  9254. return false;
  9255. else
  9256. return this.conditions[0].trigger;
  9257. };
  9258. EventBlock.prototype.run = function ()
  9259. {
  9260. var i, len, c, any_true = false, cnd_result;
  9261. var runtime = this.runtime;
  9262. var evinfo = this.runtime.getCurrentEventStack();
  9263. evinfo.current_event = this;
  9264. var conditions = this.conditions;
  9265. if (!this.is_else_block)
  9266. evinfo.else_branch_ran = false;
  9267. if (this.orblock)
  9268. {
  9269. if (conditions.length === 0)
  9270. any_true = true; // be sure to run if empty block
  9271. evinfo.cndindex = 0
  9272. for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
  9273. {
  9274. c = conditions[evinfo.cndindex];
  9275. if (c.trigger) // skip triggers when running OR block
  9276. continue;
  9277. cnd_result = c.run();
  9278. if (cnd_result) // make sure all conditions run and run if any were true
  9279. any_true = true;
  9280. }
  9281. evinfo.last_event_true = any_true;
  9282. if (any_true)
  9283. this.run_actions_and_subevents();
  9284. }
  9285. else
  9286. {
  9287. evinfo.cndindex = 0
  9288. for (len = conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
  9289. {
  9290. cnd_result = conditions[evinfo.cndindex].run();
  9291. if (!cnd_result) // condition failed
  9292. {
  9293. evinfo.last_event_true = false;
  9294. if (this.toplevelevent && runtime.hasPendingInstances)
  9295. runtime.ClearDeathRow();
  9296. return; // bail out now
  9297. }
  9298. }
  9299. evinfo.last_event_true = true;
  9300. this.run_actions_and_subevents();
  9301. }
  9302. this.end_run(evinfo);
  9303. };
  9304. EventBlock.prototype.end_run = function (evinfo)
  9305. {
  9306. if (evinfo.last_event_true && this.has_else_block)
  9307. evinfo.else_branch_ran = true;
  9308. if (this.toplevelevent && this.runtime.hasPendingInstances)
  9309. this.runtime.ClearDeathRow();
  9310. };
  9311. EventBlock.prototype.run_orblocktrigger = function (index)
  9312. {
  9313. var evinfo = this.runtime.getCurrentEventStack();
  9314. evinfo.current_event = this;
  9315. if (this.conditions[index].run())
  9316. {
  9317. this.run_actions_and_subevents();
  9318. this.runtime.getCurrentEventStack().last_event_true = true;
  9319. }
  9320. };
  9321. EventBlock.prototype.run_actions_and_subevents = function ()
  9322. {
  9323. var evinfo = this.runtime.getCurrentEventStack();
  9324. var len;
  9325. for (evinfo.actindex = 0, len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
  9326. {
  9327. if (this.actions[evinfo.actindex].run())
  9328. return;
  9329. }
  9330. this.run_subevents();
  9331. };
  9332. EventBlock.prototype.resume_actions_and_subevents = function ()
  9333. {
  9334. var evinfo = this.runtime.getCurrentEventStack();
  9335. var len;
  9336. for (len = this.actions.length; evinfo.actindex < len; evinfo.actindex++)
  9337. {
  9338. if (this.actions[evinfo.actindex].run())
  9339. return;
  9340. }
  9341. this.run_subevents();
  9342. };
  9343. EventBlock.prototype.run_subevents = function ()
  9344. {
  9345. if (!this.subevents.length)
  9346. return;
  9347. var i, len, subev, pushpop/*, skipped_pop = false, pop_modifiers = null*/;
  9348. var last = this.subevents.length - 1;
  9349. this.runtime.pushEventStack(this);
  9350. if (this.solWriterAfterCnds)
  9351. {
  9352. for (i = 0, len = this.subevents.length; i < len; i++)
  9353. {
  9354. subev = this.subevents[i];
  9355. pushpop = (!this.toplevelgroup || (!this.group && i < last));
  9356. if (pushpop)
  9357. this.runtime.pushCopySol(subev.solModifiers);
  9358. subev.run();
  9359. if (pushpop)
  9360. this.runtime.popSol(subev.solModifiers);
  9361. else
  9362. this.runtime.clearSol(subev.solModifiers);
  9363. }
  9364. }
  9365. else
  9366. {
  9367. for (i = 0, len = this.subevents.length; i < len; i++)
  9368. {
  9369. this.subevents[i].run();
  9370. }
  9371. }
  9372. this.runtime.popEventStack();
  9373. };
  9374. EventBlock.prototype.run_pretrigger = function ()
  9375. {
  9376. var evinfo = this.runtime.getCurrentEventStack();
  9377. evinfo.current_event = this;
  9378. var any_true = false;
  9379. var i, len;
  9380. for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
  9381. {
  9382. ;
  9383. if (this.conditions[evinfo.cndindex].run())
  9384. any_true = true;
  9385. else if (!this.orblock) // condition failed (let OR blocks run all conditions anyway)
  9386. return false; // bail out
  9387. }
  9388. return this.orblock ? any_true : true;
  9389. };
  9390. EventBlock.prototype.retrigger = function ()
  9391. {
  9392. this.runtime.execcount++;
  9393. var prevcndindex = this.runtime.getCurrentEventStack().cndindex;
  9394. var len;
  9395. var evinfo = this.runtime.pushEventStack(this);
  9396. if (!this.orblock)
  9397. {
  9398. for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
  9399. {
  9400. if (!this.conditions[evinfo.cndindex].run()) // condition failed
  9401. {
  9402. this.runtime.popEventStack(); // moving up level of recursion
  9403. return false; // bail out
  9404. }
  9405. }
  9406. }
  9407. this.run_actions_and_subevents();
  9408. this.runtime.popEventStack();
  9409. return true; // ran an iteration
  9410. };
  9411. EventBlock.prototype.isFirstConditionOfType = function (cnd)
  9412. {
  9413. var cndindex = cnd.index;
  9414. if (cndindex === 0)
  9415. return true;
  9416. --cndindex;
  9417. for ( ; cndindex >= 0; --cndindex)
  9418. {
  9419. if (this.conditions[cndindex].type === cnd.type)
  9420. return false;
  9421. }
  9422. return true;
  9423. };
  9424. cr.eventblock = EventBlock;
  9425. function Condition(block, m)
  9426. {
  9427. this.block = block;
  9428. this.sheet = block.sheet;
  9429. this.runtime = block.runtime;
  9430. this.parameters = [];
  9431. this.results = [];
  9432. this.extra = {}; // for plugins to stow away some custom info
  9433. this.index = -1;
  9434. this.anyParamVariesPerInstance = false;
  9435. this.func = this.runtime.GetObjectReference(m[1]);
  9436. ;
  9437. this.trigger = (m[3] > 0);
  9438. this.fasttrigger = (m[3] === 2);
  9439. this.looping = m[4];
  9440. this.inverted = m[5];
  9441. this.isstatic = m[6];
  9442. this.sid = m[7];
  9443. this.runtime.cndsBySid[this.sid.toString()] = this;
  9444. if (m[0] === -1) // system object
  9445. {
  9446. this.type = null;
  9447. this.run = this.run_system;
  9448. this.behaviortype = null;
  9449. this.beh_index = -1;
  9450. }
  9451. else
  9452. {
  9453. this.type = this.runtime.types_by_index[m[0]];
  9454. ;
  9455. if (this.isstatic)
  9456. this.run = this.run_static;
  9457. else
  9458. this.run = this.run_object;
  9459. if (m[2])
  9460. {
  9461. this.behaviortype = this.type.getBehaviorByName(m[2]);
  9462. ;
  9463. this.beh_index = this.type.getBehaviorIndexByName(m[2]);
  9464. ;
  9465. }
  9466. else
  9467. {
  9468. this.behaviortype = null;
  9469. this.beh_index = -1;
  9470. }
  9471. if (this.block.parent)
  9472. this.block.parent.setSolWriterAfterCnds();
  9473. }
  9474. if (this.fasttrigger)
  9475. this.run = this.run_true;
  9476. if (m.length === 10)
  9477. {
  9478. var i, len;
  9479. var em = m[9];
  9480. for (i = 0, len = em.length; i < len; i++)
  9481. {
  9482. var param = new cr.parameter(this, em[i]);
  9483. cr.seal(param);
  9484. this.parameters.push(param);
  9485. }
  9486. this.results.length = em.length;
  9487. }
  9488. };
  9489. Condition.prototype.postInit = function ()
  9490. {
  9491. var i, len, p;
  9492. for (i = 0, len = this.parameters.length; i < len; i++)
  9493. {
  9494. p = this.parameters[i];
  9495. p.postInit();
  9496. if (p.variesPerInstance)
  9497. this.anyParamVariesPerInstance = true;
  9498. }
  9499. };
  9500. /*
  9501. Condition.prototype.is_logical = function ()
  9502. {
  9503. return !this.type || this.type.plugin.singleglobal;
  9504. };
  9505. */
  9506. Condition.prototype.run_true = function ()
  9507. {
  9508. return true;
  9509. };
  9510. Condition.prototype.run_system = function ()
  9511. {
  9512. var i, len;
  9513. for (i = 0, len = this.parameters.length; i < len; i++)
  9514. this.results[i] = this.parameters[i].get();
  9515. return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted);
  9516. };
  9517. Condition.prototype.run_static = function ()
  9518. {
  9519. var i, len;
  9520. for (i = 0, len = this.parameters.length; i < len; i++)
  9521. this.results[i] = this.parameters[i].get();
  9522. var ret = this.func.apply(this.behaviortype ? this.behaviortype : this.type, this.results);
  9523. this.type.applySolToContainer();
  9524. return ret;
  9525. };
  9526. Condition.prototype.run_object = function ()
  9527. {
  9528. var i, j, k, leni, lenj, p, ret, met, inst, s, sol2;
  9529. var type = this.type;
  9530. var sol = type.getCurrentSol();
  9531. var is_orblock = this.block.orblock && !this.trigger; // triggers in OR blocks need to work normally
  9532. var offset = 0;
  9533. var is_contained = type.is_contained;
  9534. var is_family = type.is_family;
  9535. var family_index = type.family_index;
  9536. var beh_index = this.beh_index;
  9537. var is_beh = (beh_index > -1);
  9538. var params_vary = this.anyParamVariesPerInstance;
  9539. var parameters = this.parameters;
  9540. var results = this.results;
  9541. var inverted = this.inverted;
  9542. var func = this.func;
  9543. var arr, container;
  9544. if (params_vary)
  9545. {
  9546. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9547. {
  9548. p = parameters[j];
  9549. if (!p.variesPerInstance)
  9550. results[j] = p.get(0);
  9551. }
  9552. }
  9553. else
  9554. {
  9555. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9556. results[j] = parameters[j].get(0);
  9557. }
  9558. if (sol.select_all) {
  9559. cr.clearArray(sol.instances); // clear contents
  9560. cr.clearArray(sol.else_instances);
  9561. arr = type.instances;
  9562. for (i = 0, leni = arr.length; i < leni; ++i)
  9563. {
  9564. inst = arr[i];
  9565. ;
  9566. if (params_vary)
  9567. {
  9568. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9569. {
  9570. p = parameters[j];
  9571. if (p.variesPerInstance)
  9572. results[j] = p.get(i); // default SOL index is current object
  9573. }
  9574. }
  9575. if (is_beh)
  9576. {
  9577. offset = 0;
  9578. if (is_family)
  9579. {
  9580. offset = inst.type.family_beh_map[family_index];
  9581. }
  9582. ret = func.apply(inst.behavior_insts[beh_index + offset], results);
  9583. }
  9584. else
  9585. ret = func.apply(inst, results);
  9586. met = cr.xor(ret, inverted);
  9587. if (met)
  9588. sol.instances.push(inst);
  9589. else if (is_orblock) // in OR blocks, keep the instances not meeting the condition for subsequent testing
  9590. sol.else_instances.push(inst);
  9591. }
  9592. if (type.finish)
  9593. type.finish(true);
  9594. sol.select_all = false;
  9595. type.applySolToContainer();
  9596. return sol.hasObjects();
  9597. }
  9598. else {
  9599. k = 0;
  9600. var using_else_instances = (is_orblock && !this.block.isFirstConditionOfType(this));
  9601. arr = (using_else_instances ? sol.else_instances : sol.instances);
  9602. var any_true = false;
  9603. for (i = 0, leni = arr.length; i < leni; ++i)
  9604. {
  9605. inst = arr[i];
  9606. ;
  9607. if (params_vary)
  9608. {
  9609. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9610. {
  9611. p = parameters[j];
  9612. if (p.variesPerInstance)
  9613. results[j] = p.get(i); // default SOL index is current object
  9614. }
  9615. }
  9616. if (is_beh)
  9617. {
  9618. offset = 0;
  9619. if (is_family)
  9620. {
  9621. offset = inst.type.family_beh_map[family_index];
  9622. }
  9623. ret = func.apply(inst.behavior_insts[beh_index + offset], results);
  9624. }
  9625. else
  9626. ret = func.apply(inst, results);
  9627. if (cr.xor(ret, inverted))
  9628. {
  9629. any_true = true;
  9630. if (using_else_instances)
  9631. {
  9632. sol.instances.push(inst);
  9633. if (is_contained)
  9634. {
  9635. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  9636. {
  9637. s = inst.siblings[j];
  9638. s.type.getCurrentSol().instances.push(s);
  9639. }
  9640. }
  9641. }
  9642. else
  9643. {
  9644. arr[k] = inst;
  9645. if (is_contained)
  9646. {
  9647. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  9648. {
  9649. s = inst.siblings[j];
  9650. s.type.getCurrentSol().instances[k] = s;
  9651. }
  9652. }
  9653. k++;
  9654. }
  9655. }
  9656. else
  9657. {
  9658. if (using_else_instances)
  9659. {
  9660. arr[k] = inst;
  9661. if (is_contained)
  9662. {
  9663. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  9664. {
  9665. s = inst.siblings[j];
  9666. s.type.getCurrentSol().else_instances[k] = s;
  9667. }
  9668. }
  9669. k++;
  9670. }
  9671. else if (is_orblock)
  9672. {
  9673. sol.else_instances.push(inst);
  9674. if (is_contained)
  9675. {
  9676. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  9677. {
  9678. s = inst.siblings[j];
  9679. s.type.getCurrentSol().else_instances.push(s);
  9680. }
  9681. }
  9682. }
  9683. }
  9684. }
  9685. cr.truncateArray(arr, k);
  9686. if (is_contained)
  9687. {
  9688. container = type.container;
  9689. for (i = 0, leni = container.length; i < leni; i++)
  9690. {
  9691. sol2 = container[i].getCurrentSol();
  9692. if (using_else_instances)
  9693. cr.truncateArray(sol2.else_instances, k);
  9694. else
  9695. cr.truncateArray(sol2.instances, k);
  9696. }
  9697. }
  9698. var pick_in_finish = any_true; // don't pick in finish() if we're only doing the logic test below
  9699. if (using_else_instances && !any_true)
  9700. {
  9701. for (i = 0, leni = sol.instances.length; i < leni; i++)
  9702. {
  9703. inst = sol.instances[i];
  9704. if (params_vary)
  9705. {
  9706. for (j = 0, lenj = parameters.length; j < lenj; j++)
  9707. {
  9708. p = parameters[j];
  9709. if (p.variesPerInstance)
  9710. results[j] = p.get(i);
  9711. }
  9712. }
  9713. if (is_beh)
  9714. ret = func.apply(inst.behavior_insts[beh_index], results);
  9715. else
  9716. ret = func.apply(inst, results);
  9717. if (cr.xor(ret, inverted))
  9718. {
  9719. any_true = true;
  9720. break; // got our flag, don't need to test any more
  9721. }
  9722. }
  9723. }
  9724. if (type.finish)
  9725. type.finish(pick_in_finish || is_orblock);
  9726. return is_orblock ? any_true : sol.hasObjects();
  9727. }
  9728. };
  9729. cr.condition = Condition;
  9730. function Action(block, m)
  9731. {
  9732. this.block = block;
  9733. this.sheet = block.sheet;
  9734. this.runtime = block.runtime;
  9735. this.parameters = [];
  9736. this.results = [];
  9737. this.extra = {}; // for plugins to stow away some custom info
  9738. this.index = -1;
  9739. this.anyParamVariesPerInstance = false;
  9740. this.func = this.runtime.GetObjectReference(m[1]);
  9741. ;
  9742. if (m[0] === -1) // system
  9743. {
  9744. this.type = null;
  9745. this.run = this.run_system;
  9746. this.behaviortype = null;
  9747. this.beh_index = -1;
  9748. }
  9749. else
  9750. {
  9751. this.type = this.runtime.types_by_index[m[0]];
  9752. ;
  9753. this.run = this.run_object;
  9754. if (m[2])
  9755. {
  9756. this.behaviortype = this.type.getBehaviorByName(m[2]);
  9757. ;
  9758. this.beh_index = this.type.getBehaviorIndexByName(m[2]);
  9759. ;
  9760. }
  9761. else
  9762. {
  9763. this.behaviortype = null;
  9764. this.beh_index = -1;
  9765. }
  9766. }
  9767. this.sid = m[3];
  9768. this.runtime.actsBySid[this.sid.toString()] = this;
  9769. if (m.length === 6)
  9770. {
  9771. var i, len;
  9772. var em = m[5];
  9773. for (i = 0, len = em.length; i < len; i++)
  9774. {
  9775. var param = new cr.parameter(this, em[i]);
  9776. cr.seal(param);
  9777. this.parameters.push(param);
  9778. }
  9779. this.results.length = em.length;
  9780. }
  9781. };
  9782. Action.prototype.postInit = function ()
  9783. {
  9784. var i, len, p;
  9785. for (i = 0, len = this.parameters.length; i < len; i++)
  9786. {
  9787. p = this.parameters[i];
  9788. p.postInit();
  9789. if (p.variesPerInstance)
  9790. this.anyParamVariesPerInstance = true;
  9791. }
  9792. };
  9793. Action.prototype.run_system = function ()
  9794. {
  9795. var runtime = this.runtime;
  9796. var i, len;
  9797. var parameters = this.parameters;
  9798. var results = this.results;
  9799. for (i = 0, len = parameters.length; i < len; ++i)
  9800. results[i] = parameters[i].get();
  9801. return this.func.apply(runtime.system, results);
  9802. };
  9803. Action.prototype.run_object = function ()
  9804. {
  9805. var type = this.type;
  9806. var beh_index = this.beh_index;
  9807. var family_index = type.family_index;
  9808. var params_vary = this.anyParamVariesPerInstance;
  9809. var parameters = this.parameters;
  9810. var results = this.results;
  9811. var func = this.func;
  9812. var instances = type.getCurrentSol().getObjects();
  9813. var is_family = type.is_family;
  9814. var is_beh = (beh_index > -1);
  9815. var i, j, leni, lenj, p, inst, offset;
  9816. if (params_vary)
  9817. {
  9818. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9819. {
  9820. p = parameters[j];
  9821. if (!p.variesPerInstance)
  9822. results[j] = p.get(0);
  9823. }
  9824. }
  9825. else
  9826. {
  9827. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9828. results[j] = parameters[j].get(0);
  9829. }
  9830. for (i = 0, leni = instances.length; i < leni; ++i)
  9831. {
  9832. inst = instances[i];
  9833. if (params_vary)
  9834. {
  9835. for (j = 0, lenj = parameters.length; j < lenj; ++j)
  9836. {
  9837. p = parameters[j];
  9838. if (p.variesPerInstance)
  9839. results[j] = p.get(i); // pass i to use as default SOL index
  9840. }
  9841. }
  9842. if (is_beh)
  9843. {
  9844. offset = 0;
  9845. if (is_family)
  9846. {
  9847. offset = inst.type.family_beh_map[family_index];
  9848. }
  9849. func.apply(inst.behavior_insts[beh_index + offset], results);
  9850. }
  9851. else
  9852. func.apply(inst, results);
  9853. }
  9854. return false;
  9855. };
  9856. cr.action = Action;
  9857. var tempValues = [];
  9858. var tempValuesPtr = -1;
  9859. function pushTempValue()
  9860. {
  9861. tempValuesPtr++;
  9862. if (tempValues.length === tempValuesPtr)
  9863. tempValues.push(new cr.expvalue());
  9864. return tempValues[tempValuesPtr];
  9865. };
  9866. function popTempValue()
  9867. {
  9868. tempValuesPtr--;
  9869. };
  9870. function Parameter(owner, m)
  9871. {
  9872. this.owner = owner;
  9873. this.block = owner.block;
  9874. this.sheet = owner.sheet;
  9875. this.runtime = owner.runtime;
  9876. this.type = m[0];
  9877. this.expression = null;
  9878. this.solindex = 0;
  9879. this.get = null;
  9880. this.combosel = 0;
  9881. this.layout = null;
  9882. this.key = 0;
  9883. this.object = null;
  9884. this.index = 0;
  9885. this.varname = null;
  9886. this.eventvar = null;
  9887. this.fileinfo = null;
  9888. this.subparams = null;
  9889. this.variadicret = null;
  9890. this.subparams = null;
  9891. this.variadicret = null;
  9892. this.variesPerInstance = false;
  9893. var i, len, param;
  9894. switch (m[0])
  9895. {
  9896. case 0: // number
  9897. case 7: // any
  9898. this.expression = new cr.expNode(this, m[1]);
  9899. this.solindex = 0;
  9900. this.get = this.get_exp;
  9901. break;
  9902. case 1: // string
  9903. this.expression = new cr.expNode(this, m[1]);
  9904. this.solindex = 0;
  9905. this.get = this.get_exp_str;
  9906. break;
  9907. case 5: // layer
  9908. this.expression = new cr.expNode(this, m[1]);
  9909. this.solindex = 0;
  9910. this.get = this.get_layer;
  9911. break;
  9912. case 3: // combo
  9913. case 8: // cmp
  9914. this.combosel = m[1];
  9915. this.get = this.get_combosel;
  9916. break;
  9917. case 6: // layout
  9918. this.layout = this.runtime.layouts[m[1]];
  9919. ;
  9920. this.get = this.get_layout;
  9921. break;
  9922. case 9: // keyb
  9923. this.key = m[1];
  9924. this.get = this.get_key;
  9925. break;
  9926. case 4: // object
  9927. this.object = this.runtime.types_by_index[m[1]];
  9928. ;
  9929. this.get = this.get_object;
  9930. this.block.addSolModifier(this.object);
  9931. if (this.owner instanceof cr.action)
  9932. this.block.setSolWriterAfterCnds();
  9933. else if (this.block.parent)
  9934. this.block.parent.setSolWriterAfterCnds();
  9935. break;
  9936. case 10: // instvar
  9937. this.index = m[1];
  9938. if (owner.type.is_family)
  9939. {
  9940. this.get = this.get_familyvar;
  9941. this.variesPerInstance = true;
  9942. }
  9943. else
  9944. this.get = this.get_instvar;
  9945. break;
  9946. case 11: // eventvar
  9947. this.varname = m[1];
  9948. this.eventvar = null;
  9949. this.get = this.get_eventvar;
  9950. break;
  9951. case 2: // audiofile ["name", ismusic]
  9952. case 12: // fileinfo "name"
  9953. this.fileinfo = m[1];
  9954. this.get = this.get_audiofile;
  9955. break;
  9956. case 13: // variadic
  9957. this.get = this.get_variadic;
  9958. this.subparams = [];
  9959. this.variadicret = [];
  9960. for (i = 1, len = m.length; i < len; i++)
  9961. {
  9962. param = new cr.parameter(this.owner, m[i]);
  9963. cr.seal(param);
  9964. this.subparams.push(param);
  9965. this.variadicret.push(0);
  9966. }
  9967. break;
  9968. default:
  9969. ;
  9970. }
  9971. };
  9972. Parameter.prototype.postInit = function ()
  9973. {
  9974. var i, len;
  9975. if (this.type === 11) // eventvar
  9976. {
  9977. this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent);
  9978. ;
  9979. }
  9980. else if (this.type === 13) // variadic, postInit all sub-params
  9981. {
  9982. for (i = 0, len = this.subparams.length; i < len; i++)
  9983. this.subparams[i].postInit();
  9984. }
  9985. if (this.expression)
  9986. this.expression.postInit();
  9987. };
  9988. Parameter.prototype.maybeVaryForType = function (t)
  9989. {
  9990. if (this.variesPerInstance)
  9991. return; // already varies per instance, no need to check again
  9992. if (!t)
  9993. return; // never vary for system type
  9994. if (!t.plugin.singleglobal)
  9995. {
  9996. this.variesPerInstance = true;
  9997. return;
  9998. }
  9999. };
  10000. Parameter.prototype.setVaries = function ()
  10001. {
  10002. this.variesPerInstance = true;
  10003. };
  10004. Parameter.prototype.get_exp = function (solindex)
  10005. {
  10006. this.solindex = solindex || 0; // default SOL index to use
  10007. var temp = pushTempValue();
  10008. this.expression.get(temp);
  10009. popTempValue();
  10010. return temp.data; // return actual JS value, not expvalue
  10011. };
  10012. Parameter.prototype.get_exp_str = function (solindex)
  10013. {
  10014. this.solindex = solindex || 0; // default SOL index to use
  10015. var temp = pushTempValue();
  10016. this.expression.get(temp);
  10017. popTempValue();
  10018. if (cr.is_string(temp.data))
  10019. return temp.data;
  10020. else
  10021. return "";
  10022. };
  10023. Parameter.prototype.get_object = function ()
  10024. {
  10025. return this.object;
  10026. };
  10027. Parameter.prototype.get_combosel = function ()
  10028. {
  10029. return this.combosel;
  10030. };
  10031. Parameter.prototype.get_layer = function (solindex)
  10032. {
  10033. this.solindex = solindex || 0; // default SOL index to use
  10034. var temp = pushTempValue();
  10035. this.expression.get(temp);
  10036. popTempValue();
  10037. if (temp.is_number())
  10038. return this.runtime.getLayerByNumber(temp.data);
  10039. else
  10040. return this.runtime.getLayerByName(temp.data);
  10041. }
  10042. Parameter.prototype.get_layout = function ()
  10043. {
  10044. return this.layout;
  10045. };
  10046. Parameter.prototype.get_key = function ()
  10047. {
  10048. return this.key;
  10049. };
  10050. Parameter.prototype.get_instvar = function ()
  10051. {
  10052. return this.index;
  10053. };
  10054. Parameter.prototype.get_familyvar = function (solindex_)
  10055. {
  10056. var solindex = solindex_ || 0;
  10057. var familytype = this.owner.type;
  10058. var realtype = null;
  10059. var sol = familytype.getCurrentSol();
  10060. var objs = sol.getObjects();
  10061. if (objs.length)
  10062. realtype = objs[solindex % objs.length].type;
  10063. else if (sol.else_instances.length)
  10064. realtype = sol.else_instances[solindex % sol.else_instances.length].type;
  10065. else if (familytype.instances.length)
  10066. realtype = familytype.instances[solindex % familytype.instances.length].type;
  10067. else
  10068. return 0;
  10069. return this.index + realtype.family_var_map[familytype.family_index];
  10070. };
  10071. Parameter.prototype.get_eventvar = function ()
  10072. {
  10073. return this.eventvar;
  10074. };
  10075. Parameter.prototype.get_audiofile = function ()
  10076. {
  10077. return this.fileinfo;
  10078. };
  10079. Parameter.prototype.get_variadic = function ()
  10080. {
  10081. var i, len;
  10082. for (i = 0, len = this.subparams.length; i < len; i++)
  10083. {
  10084. this.variadicret[i] = this.subparams[i].get();
  10085. }
  10086. return this.variadicret;
  10087. };
  10088. cr.parameter = Parameter;
  10089. function EventVariable(sheet, parent, m)
  10090. {
  10091. this.sheet = sheet;
  10092. this.parent = parent;
  10093. this.runtime = sheet.runtime;
  10094. this.solModifiers = [];
  10095. this.name = m[1];
  10096. this.vartype = m[2];
  10097. this.initial = m[3];
  10098. this.is_static = !!m[4];
  10099. this.is_constant = !!m[5];
  10100. this.sid = m[6];
  10101. this.runtime.varsBySid[this.sid.toString()] = this;
  10102. this.data = this.initial; // note: also stored in event stack frame for local nonstatic nonconst vars
  10103. if (this.parent) // local var
  10104. {
  10105. if (this.is_static || this.is_constant)
  10106. this.localIndex = -1;
  10107. else
  10108. this.localIndex = this.runtime.stackLocalCount++;
  10109. this.runtime.all_local_vars.push(this);
  10110. }
  10111. else // global var
  10112. {
  10113. this.localIndex = -1;
  10114. this.runtime.all_global_vars.push(this);
  10115. }
  10116. };
  10117. EventVariable.prototype.postInit = function ()
  10118. {
  10119. this.solModifiers = findMatchingSolModifier(this.solModifiers);
  10120. };
  10121. EventVariable.prototype.setValue = function (x)
  10122. {
  10123. ;
  10124. var lvs = this.runtime.getCurrentLocalVarStack();
  10125. if (!this.parent || this.is_static || !lvs)
  10126. this.data = x;
  10127. else // local nonstatic variable: use event stack to keep value at this level of recursion
  10128. {
  10129. if (this.localIndex >= lvs.length)
  10130. lvs.length = this.localIndex + 1;
  10131. lvs[this.localIndex] = x;
  10132. }
  10133. };
  10134. EventVariable.prototype.getValue = function ()
  10135. {
  10136. var lvs = this.runtime.getCurrentLocalVarStack();
  10137. if (!this.parent || this.is_static || !lvs || this.is_constant)
  10138. return this.data;
  10139. else // local nonstatic variable
  10140. {
  10141. if (this.localIndex >= lvs.length)
  10142. {
  10143. ;
  10144. return this.initial;
  10145. }
  10146. if (typeof lvs[this.localIndex] === "undefined")
  10147. {
  10148. ;
  10149. return this.initial;
  10150. }
  10151. return lvs[this.localIndex];
  10152. }
  10153. };
  10154. EventVariable.prototype.run = function ()
  10155. {
  10156. if (this.parent && !this.is_static && !this.is_constant)
  10157. this.setValue(this.initial);
  10158. };
  10159. cr.eventvariable = EventVariable;
  10160. function EventInclude(sheet, parent, m)
  10161. {
  10162. this.sheet = sheet;
  10163. this.parent = parent;
  10164. this.runtime = sheet.runtime;
  10165. this.solModifiers = [];
  10166. this.include_sheet = null; // determined in postInit
  10167. this.include_sheet_name = m[1];
  10168. this.active = true;
  10169. };
  10170. EventInclude.prototype.toString = function ()
  10171. {
  10172. return "include:" + this.include_sheet.toString();
  10173. };
  10174. EventInclude.prototype.postInit = function ()
  10175. {
  10176. this.include_sheet = this.runtime.eventsheets[this.include_sheet_name];
  10177. ;
  10178. ;
  10179. this.sheet.includes.add(this);
  10180. this.solModifiers = findMatchingSolModifier(this.solModifiers);
  10181. var p = this.parent;
  10182. while (p)
  10183. {
  10184. if (p.group)
  10185. p.contained_includes.push(this);
  10186. p = p.parent;
  10187. }
  10188. this.updateActive();
  10189. };
  10190. EventInclude.prototype.run = function ()
  10191. {
  10192. if (this.parent)
  10193. this.runtime.pushCleanSol(this.runtime.types_by_index);
  10194. if (!this.include_sheet.hasRun)
  10195. this.include_sheet.run(true); // from include
  10196. if (this.parent)
  10197. this.runtime.popSol(this.runtime.types_by_index);
  10198. };
  10199. EventInclude.prototype.updateActive = function ()
  10200. {
  10201. var p = this.parent;
  10202. while (p)
  10203. {
  10204. if (p.group && !p.group_active)
  10205. {
  10206. this.active = false;
  10207. return;
  10208. }
  10209. p = p.parent;
  10210. }
  10211. this.active = true;
  10212. };
  10213. EventInclude.prototype.isActive = function ()
  10214. {
  10215. return this.active;
  10216. };
  10217. cr.eventinclude = EventInclude;
  10218. function EventStackFrame()
  10219. {
  10220. this.temp_parents_arr = [];
  10221. this.reset(null);
  10222. cr.seal(this);
  10223. };
  10224. EventStackFrame.prototype.reset = function (cur_event)
  10225. {
  10226. this.current_event = cur_event;
  10227. this.cndindex = 0;
  10228. this.actindex = 0;
  10229. cr.clearArray(this.temp_parents_arr);
  10230. this.last_event_true = false;
  10231. this.else_branch_ran = false;
  10232. this.any_true_state = false;
  10233. };
  10234. EventStackFrame.prototype.isModifierAfterCnds = function ()
  10235. {
  10236. if (this.current_event.solWriterAfterCnds)
  10237. return true;
  10238. if (this.cndindex < this.current_event.conditions.length - 1)
  10239. return !!this.current_event.solModifiers.length;
  10240. return false;
  10241. };
  10242. cr.eventStackFrame = EventStackFrame;
  10243. }());
  10244. (function()
  10245. {
  10246. function ExpNode(owner_, m)
  10247. {
  10248. this.owner = owner_;
  10249. this.runtime = owner_.runtime;
  10250. this.type = m[0];
  10251. ;
  10252. this.get = [this.eval_int,
  10253. this.eval_float,
  10254. this.eval_string,
  10255. this.eval_unaryminus,
  10256. this.eval_add,
  10257. this.eval_subtract,
  10258. this.eval_multiply,
  10259. this.eval_divide,
  10260. this.eval_mod,
  10261. this.eval_power,
  10262. this.eval_and,
  10263. this.eval_or,
  10264. this.eval_equal,
  10265. this.eval_notequal,
  10266. this.eval_less,
  10267. this.eval_lessequal,
  10268. this.eval_greater,
  10269. this.eval_greaterequal,
  10270. this.eval_conditional,
  10271. this.eval_system_exp,
  10272. this.eval_object_exp,
  10273. this.eval_instvar_exp,
  10274. this.eval_behavior_exp,
  10275. this.eval_eventvar_exp][this.type];
  10276. var paramsModel = null;
  10277. this.value = null;
  10278. this.first = null;
  10279. this.second = null;
  10280. this.third = null;
  10281. this.func = null;
  10282. this.results = null;
  10283. this.parameters = null;
  10284. this.object_type = null;
  10285. this.beh_index = -1;
  10286. this.instance_expr = null;
  10287. this.varindex = -1;
  10288. this.behavior_type = null;
  10289. this.varname = null;
  10290. this.eventvar = null;
  10291. this.return_string = false;
  10292. switch (this.type) {
  10293. case 0: // int
  10294. case 1: // float
  10295. case 2: // string
  10296. this.value = m[1];
  10297. break;
  10298. case 3: // unaryminus
  10299. this.first = new cr.expNode(owner_, m[1]);
  10300. break;
  10301. case 18: // conditional
  10302. this.first = new cr.expNode(owner_, m[1]);
  10303. this.second = new cr.expNode(owner_, m[2]);
  10304. this.third = new cr.expNode(owner_, m[3]);
  10305. break;
  10306. case 19: // system_exp
  10307. this.func = this.runtime.GetObjectReference(m[1]);
  10308. ;
  10309. if (this.func === cr.system_object.prototype.exps.random
  10310. || this.func === cr.system_object.prototype.exps.choose)
  10311. {
  10312. this.owner.setVaries();
  10313. }
  10314. this.results = [];
  10315. this.parameters = [];
  10316. if (m.length === 3)
  10317. {
  10318. paramsModel = m[2];
  10319. this.results.length = paramsModel.length + 1; // must also fit 'ret'
  10320. }
  10321. else
  10322. this.results.length = 1; // to fit 'ret'
  10323. break;
  10324. case 20: // object_exp
  10325. this.object_type = this.runtime.types_by_index[m[1]];
  10326. ;
  10327. this.beh_index = -1;
  10328. this.func = this.runtime.GetObjectReference(m[2]);
  10329. this.return_string = m[3];
  10330. if (cr.plugins_.Function && this.func === cr.plugins_.Function.prototype.exps.Call)
  10331. {
  10332. this.owner.setVaries();
  10333. }
  10334. if (m[4])
  10335. this.instance_expr = new cr.expNode(owner_, m[4]);
  10336. else
  10337. this.instance_expr = null;
  10338. this.results = [];
  10339. this.parameters = [];
  10340. if (m.length === 6)
  10341. {
  10342. paramsModel = m[5];
  10343. this.results.length = paramsModel.length + 1;
  10344. }
  10345. else
  10346. this.results.length = 1; // to fit 'ret'
  10347. break;
  10348. case 21: // instvar_exp
  10349. this.object_type = this.runtime.types_by_index[m[1]];
  10350. ;
  10351. this.return_string = m[2];
  10352. if (m[3])
  10353. this.instance_expr = new cr.expNode(owner_, m[3]);
  10354. else
  10355. this.instance_expr = null;
  10356. this.varindex = m[4];
  10357. break;
  10358. case 22: // behavior_exp
  10359. this.object_type = this.runtime.types_by_index[m[1]];
  10360. ;
  10361. this.behavior_type = this.object_type.getBehaviorByName(m[2]);
  10362. ;
  10363. this.beh_index = this.object_type.getBehaviorIndexByName(m[2]);
  10364. this.func = this.runtime.GetObjectReference(m[3]);
  10365. this.return_string = m[4];
  10366. if (m[5])
  10367. this.instance_expr = new cr.expNode(owner_, m[5]);
  10368. else
  10369. this.instance_expr = null;
  10370. this.results = [];
  10371. this.parameters = [];
  10372. if (m.length === 7)
  10373. {
  10374. paramsModel = m[6];
  10375. this.results.length = paramsModel.length + 1;
  10376. }
  10377. else
  10378. this.results.length = 1; // to fit 'ret'
  10379. break;
  10380. case 23: // eventvar_exp
  10381. this.varname = m[1];
  10382. this.eventvar = null; // assigned in postInit
  10383. break;
  10384. }
  10385. this.owner.maybeVaryForType(this.object_type);
  10386. if (this.type >= 4 && this.type <= 17)
  10387. {
  10388. this.first = new cr.expNode(owner_, m[1]);
  10389. this.second = new cr.expNode(owner_, m[2]);
  10390. }
  10391. if (paramsModel)
  10392. {
  10393. var i, len;
  10394. for (i = 0, len = paramsModel.length; i < len; i++)
  10395. this.parameters.push(new cr.expNode(owner_, paramsModel[i]));
  10396. }
  10397. cr.seal(this);
  10398. };
  10399. ExpNode.prototype.postInit = function ()
  10400. {
  10401. if (this.type === 23) // eventvar_exp
  10402. {
  10403. this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent);
  10404. ;
  10405. }
  10406. if (this.first)
  10407. this.first.postInit();
  10408. if (this.second)
  10409. this.second.postInit();
  10410. if (this.third)
  10411. this.third.postInit();
  10412. if (this.instance_expr)
  10413. this.instance_expr.postInit();
  10414. if (this.parameters)
  10415. {
  10416. var i, len;
  10417. for (i = 0, len = this.parameters.length; i < len; i++)
  10418. this.parameters[i].postInit();
  10419. }
  10420. };
  10421. var tempValues = [];
  10422. var tempValuesPtr = -1;
  10423. function pushTempValue()
  10424. {
  10425. ++tempValuesPtr;
  10426. if (tempValues.length === tempValuesPtr)
  10427. tempValues.push(new cr.expvalue());
  10428. return tempValues[tempValuesPtr];
  10429. };
  10430. function popTempValue()
  10431. {
  10432. --tempValuesPtr;
  10433. };
  10434. function eval_params(parameters, results, temp)
  10435. {
  10436. var i, len;
  10437. for (i = 0, len = parameters.length; i < len; ++i)
  10438. {
  10439. parameters[i].get(temp);
  10440. results[i + 1] = temp.data; // passing actual javascript value as argument instead of expvalue
  10441. }
  10442. }
  10443. ExpNode.prototype.eval_system_exp = function (ret)
  10444. {
  10445. var parameters = this.parameters;
  10446. var results = this.results;
  10447. results[0] = ret;
  10448. var temp = pushTempValue();
  10449. eval_params(parameters, results, temp);
  10450. popTempValue();
  10451. this.func.apply(this.runtime.system, results);
  10452. };
  10453. ExpNode.prototype.eval_object_exp = function (ret)
  10454. {
  10455. var object_type = this.object_type;
  10456. var results = this.results;
  10457. var parameters = this.parameters;
  10458. var instance_expr = this.instance_expr;
  10459. var func = this.func;
  10460. var index = this.owner.solindex; // default to parameter's intended SOL index
  10461. var sol = object_type.getCurrentSol();
  10462. var instances = sol.getObjects();
  10463. if (!instances.length)
  10464. {
  10465. if (sol.else_instances.length)
  10466. instances = sol.else_instances;
  10467. else
  10468. {
  10469. if (this.return_string)
  10470. ret.set_string("");
  10471. else
  10472. ret.set_int(0);
  10473. return;
  10474. }
  10475. }
  10476. results[0] = ret;
  10477. ret.object_class = object_type; // so expression can access family type if need be
  10478. var temp = pushTempValue();
  10479. eval_params(parameters, results, temp);
  10480. if (instance_expr) {
  10481. instance_expr.get(temp);
  10482. if (temp.is_number()) {
  10483. index = temp.data;
  10484. instances = object_type.instances; // pick from all instances, not SOL
  10485. }
  10486. }
  10487. popTempValue();
  10488. var len = instances.length;
  10489. if (index >= len || index <= -len)
  10490. index %= len; // wraparound
  10491. if (index < 0)
  10492. index += len;
  10493. var returned_val = func.apply(instances[index], results);
  10494. ;
  10495. };
  10496. ExpNode.prototype.eval_behavior_exp = function (ret)
  10497. {
  10498. var object_type = this.object_type;
  10499. var results = this.results;
  10500. var parameters = this.parameters;
  10501. var instance_expr = this.instance_expr;
  10502. var beh_index = this.beh_index;
  10503. var func = this.func;
  10504. var index = this.owner.solindex; // default to parameter's intended SOL index
  10505. var sol = object_type.getCurrentSol();
  10506. var instances = sol.getObjects();
  10507. if (!instances.length)
  10508. {
  10509. if (sol.else_instances.length)
  10510. instances = sol.else_instances;
  10511. else
  10512. {
  10513. if (this.return_string)
  10514. ret.set_string("");
  10515. else
  10516. ret.set_int(0);
  10517. return;
  10518. }
  10519. }
  10520. results[0] = ret;
  10521. ret.object_class = object_type; // so expression can access family type if need be
  10522. var temp = pushTempValue();
  10523. eval_params(parameters, results, temp);
  10524. if (instance_expr) {
  10525. instance_expr.get(temp);
  10526. if (temp.is_number()) {
  10527. index = temp.data;
  10528. instances = object_type.instances; // pick from all instances, not SOL
  10529. }
  10530. }
  10531. popTempValue();
  10532. var len = instances.length;
  10533. if (index >= len || index <= -len)
  10534. index %= len; // wraparound
  10535. if (index < 0)
  10536. index += len;
  10537. var inst = instances[index];
  10538. var offset = 0;
  10539. if (object_type.is_family)
  10540. {
  10541. offset = inst.type.family_beh_map[object_type.family_index];
  10542. }
  10543. var returned_val = func.apply(inst.behavior_insts[beh_index + offset], results);
  10544. ;
  10545. };
  10546. ExpNode.prototype.eval_instvar_exp = function (ret)
  10547. {
  10548. var instance_expr = this.instance_expr;
  10549. var object_type = this.object_type;
  10550. var varindex = this.varindex;
  10551. var index = this.owner.solindex; // default to parameter's intended SOL index
  10552. var sol = object_type.getCurrentSol();
  10553. var instances = sol.getObjects();
  10554. if (!instances.length)
  10555. {
  10556. if (sol.else_instances.length)
  10557. instances = sol.else_instances;
  10558. else
  10559. {
  10560. if (this.return_string)
  10561. ret.set_string("");
  10562. else
  10563. ret.set_int(0);
  10564. return;
  10565. }
  10566. }
  10567. if (instance_expr)
  10568. {
  10569. var temp = pushTempValue();
  10570. instance_expr.get(temp);
  10571. if (temp.is_number())
  10572. {
  10573. index = temp.data;
  10574. var type_instances = object_type.instances;
  10575. index %= type_instances.length; // wraparound
  10576. if (index < 0) // offset
  10577. index += type_instances.length;
  10578. var to_ret = type_instances[index].instance_vars[varindex];
  10579. if (cr.is_string(to_ret))
  10580. ret.set_string(to_ret);
  10581. else
  10582. ret.set_float(to_ret);
  10583. popTempValue();
  10584. return; // done
  10585. }
  10586. popTempValue();
  10587. }
  10588. var len = instances.length;
  10589. if (index >= len || index <= -len)
  10590. index %= len; // wraparound
  10591. if (index < 0)
  10592. index += len;
  10593. var inst = instances[index];
  10594. var offset = 0;
  10595. if (object_type.is_family)
  10596. {
  10597. offset = inst.type.family_var_map[object_type.family_index];
  10598. }
  10599. var to_ret = inst.instance_vars[varindex + offset];
  10600. if (cr.is_string(to_ret))
  10601. ret.set_string(to_ret);
  10602. else
  10603. ret.set_float(to_ret);
  10604. };
  10605. ExpNode.prototype.eval_int = function (ret)
  10606. {
  10607. ret.type = cr.exptype.Integer;
  10608. ret.data = this.value;
  10609. };
  10610. ExpNode.prototype.eval_float = function (ret)
  10611. {
  10612. ret.type = cr.exptype.Float;
  10613. ret.data = this.value;
  10614. };
  10615. ExpNode.prototype.eval_string = function (ret)
  10616. {
  10617. ret.type = cr.exptype.String;
  10618. ret.data = this.value;
  10619. };
  10620. ExpNode.prototype.eval_unaryminus = function (ret)
  10621. {
  10622. this.first.get(ret); // retrieve operand
  10623. if (ret.is_number())
  10624. ret.data = -ret.data;
  10625. };
  10626. ExpNode.prototype.eval_add = function (ret)
  10627. {
  10628. this.first.get(ret); // left operand
  10629. var temp = pushTempValue();
  10630. this.second.get(temp); // right operand
  10631. if (ret.is_number() && temp.is_number())
  10632. {
  10633. ret.data += temp.data; // both operands numbers: add
  10634. if (temp.is_float())
  10635. ret.make_float();
  10636. }
  10637. popTempValue();
  10638. };
  10639. ExpNode.prototype.eval_subtract = function (ret)
  10640. {
  10641. this.first.get(ret); // left operand
  10642. var temp = pushTempValue();
  10643. this.second.get(temp); // right operand
  10644. if (ret.is_number() && temp.is_number())
  10645. {
  10646. ret.data -= temp.data; // both operands numbers: subtract
  10647. if (temp.is_float())
  10648. ret.make_float();
  10649. }
  10650. popTempValue();
  10651. };
  10652. ExpNode.prototype.eval_multiply = function (ret)
  10653. {
  10654. this.first.get(ret); // left operand
  10655. var temp = pushTempValue();
  10656. this.second.get(temp); // right operand
  10657. if (ret.is_number() && temp.is_number())
  10658. {
  10659. ret.data *= temp.data; // both operands numbers: multiply
  10660. if (temp.is_float())
  10661. ret.make_float();
  10662. }
  10663. popTempValue();
  10664. };
  10665. ExpNode.prototype.eval_divide = function (ret)
  10666. {
  10667. this.first.get(ret); // left operand
  10668. var temp = pushTempValue();
  10669. this.second.get(temp); // right operand
  10670. if (ret.is_number() && temp.is_number())
  10671. {
  10672. ret.data /= temp.data; // both operands numbers: divide
  10673. ret.make_float();
  10674. }
  10675. popTempValue();
  10676. };
  10677. ExpNode.prototype.eval_mod = function (ret)
  10678. {
  10679. this.first.get(ret); // left operand
  10680. var temp = pushTempValue();
  10681. this.second.get(temp); // right operand
  10682. if (ret.is_number() && temp.is_number())
  10683. {
  10684. ret.data %= temp.data; // both operands numbers: modulo
  10685. if (temp.is_float())
  10686. ret.make_float();
  10687. }
  10688. popTempValue();
  10689. };
  10690. ExpNode.prototype.eval_power = function (ret)
  10691. {
  10692. this.first.get(ret); // left operand
  10693. var temp = pushTempValue();
  10694. this.second.get(temp); // right operand
  10695. if (ret.is_number() && temp.is_number())
  10696. {
  10697. ret.data = Math.pow(ret.data, temp.data); // both operands numbers: raise to power
  10698. if (temp.is_float())
  10699. ret.make_float();
  10700. }
  10701. popTempValue();
  10702. };
  10703. ExpNode.prototype.eval_and = function (ret)
  10704. {
  10705. this.first.get(ret); // left operand
  10706. var temp = pushTempValue();
  10707. this.second.get(temp); // right operand
  10708. if (temp.is_string() || ret.is_string())
  10709. this.eval_and_stringconcat(ret, temp);
  10710. else
  10711. this.eval_and_logical(ret, temp);
  10712. popTempValue();
  10713. };
  10714. ExpNode.prototype.eval_and_stringconcat = function (ret, temp)
  10715. {
  10716. if (ret.is_string() && temp.is_string())
  10717. this.eval_and_stringconcat_str_str(ret, temp);
  10718. else
  10719. this.eval_and_stringconcat_num(ret, temp);
  10720. };
  10721. ExpNode.prototype.eval_and_stringconcat_str_str = function (ret, temp)
  10722. {
  10723. ret.data += temp.data;
  10724. };
  10725. ExpNode.prototype.eval_and_stringconcat_num = function (ret, temp)
  10726. {
  10727. if (ret.is_string())
  10728. {
  10729. ret.data += (Math.round(temp.data * 1e10) / 1e10).toString();
  10730. }
  10731. else
  10732. {
  10733. ret.set_string(ret.data.toString() + temp.data);
  10734. }
  10735. };
  10736. ExpNode.prototype.eval_and_logical = function (ret, temp)
  10737. {
  10738. ret.set_int(ret.data && temp.data ? 1 : 0);
  10739. };
  10740. ExpNode.prototype.eval_or = function (ret)
  10741. {
  10742. this.first.get(ret); // left operand
  10743. var temp = pushTempValue();
  10744. this.second.get(temp); // right operand
  10745. if (ret.is_number() && temp.is_number())
  10746. {
  10747. if (ret.data || temp.data)
  10748. ret.set_int(1);
  10749. else
  10750. ret.set_int(0);
  10751. }
  10752. popTempValue();
  10753. };
  10754. ExpNode.prototype.eval_conditional = function (ret)
  10755. {
  10756. this.first.get(ret); // condition operand
  10757. if (ret.data) // is true
  10758. this.second.get(ret); // evaluate second operand to ret
  10759. else
  10760. this.third.get(ret); // evaluate third operand to ret
  10761. };
  10762. ExpNode.prototype.eval_equal = function (ret)
  10763. {
  10764. this.first.get(ret); // left operand
  10765. var temp = pushTempValue();
  10766. this.second.get(temp); // right operand
  10767. ret.set_int(ret.data === temp.data ? 1 : 0);
  10768. popTempValue();
  10769. };
  10770. ExpNode.prototype.eval_notequal = function (ret)
  10771. {
  10772. this.first.get(ret); // left operand
  10773. var temp = pushTempValue();
  10774. this.second.get(temp); // right operand
  10775. ret.set_int(ret.data !== temp.data ? 1 : 0);
  10776. popTempValue();
  10777. };
  10778. ExpNode.prototype.eval_less = function (ret)
  10779. {
  10780. this.first.get(ret); // left operand
  10781. var temp = pushTempValue();
  10782. this.second.get(temp); // right operand
  10783. ret.set_int(ret.data < temp.data ? 1 : 0);
  10784. popTempValue();
  10785. };
  10786. ExpNode.prototype.eval_lessequal = function (ret)
  10787. {
  10788. this.first.get(ret); // left operand
  10789. var temp = pushTempValue();
  10790. this.second.get(temp); // right operand
  10791. ret.set_int(ret.data <= temp.data ? 1 : 0);
  10792. popTempValue();
  10793. };
  10794. ExpNode.prototype.eval_greater = function (ret)
  10795. {
  10796. this.first.get(ret); // left operand
  10797. var temp = pushTempValue();
  10798. this.second.get(temp); // right operand
  10799. ret.set_int(ret.data > temp.data ? 1 : 0);
  10800. popTempValue();
  10801. };
  10802. ExpNode.prototype.eval_greaterequal = function (ret)
  10803. {
  10804. this.first.get(ret); // left operand
  10805. var temp = pushTempValue();
  10806. this.second.get(temp); // right operand
  10807. ret.set_int(ret.data >= temp.data ? 1 : 0);
  10808. popTempValue();
  10809. };
  10810. ExpNode.prototype.eval_eventvar_exp = function (ret)
  10811. {
  10812. var val = this.eventvar.getValue();
  10813. if (cr.is_number(val))
  10814. ret.set_float(val);
  10815. else
  10816. ret.set_string(val);
  10817. };
  10818. cr.expNode = ExpNode;
  10819. function ExpValue(type, data)
  10820. {
  10821. this.type = type || cr.exptype.Integer;
  10822. this.data = data || 0;
  10823. this.object_class = null;
  10824. ;
  10825. ;
  10826. ;
  10827. if (this.type == cr.exptype.Integer)
  10828. this.data = Math.floor(this.data);
  10829. cr.seal(this);
  10830. };
  10831. ExpValue.prototype.is_int = function ()
  10832. {
  10833. return this.type === cr.exptype.Integer;
  10834. };
  10835. ExpValue.prototype.is_float = function ()
  10836. {
  10837. return this.type === cr.exptype.Float;
  10838. };
  10839. ExpValue.prototype.is_number = function ()
  10840. {
  10841. return this.type === cr.exptype.Integer || this.type === cr.exptype.Float;
  10842. };
  10843. ExpValue.prototype.is_string = function ()
  10844. {
  10845. return this.type === cr.exptype.String;
  10846. };
  10847. ExpValue.prototype.make_int = function ()
  10848. {
  10849. if (!this.is_int())
  10850. {
  10851. if (this.is_float())
  10852. this.data = Math.floor(this.data); // truncate float
  10853. else if (this.is_string())
  10854. this.data = parseInt(this.data, 10);
  10855. this.type = cr.exptype.Integer;
  10856. }
  10857. };
  10858. ExpValue.prototype.make_float = function ()
  10859. {
  10860. if (!this.is_float())
  10861. {
  10862. if (this.is_string())
  10863. this.data = parseFloat(this.data);
  10864. this.type = cr.exptype.Float;
  10865. }
  10866. };
  10867. ExpValue.prototype.make_string = function ()
  10868. {
  10869. if (!this.is_string())
  10870. {
  10871. this.data = this.data.toString();
  10872. this.type = cr.exptype.String;
  10873. }
  10874. };
  10875. ExpValue.prototype.set_int = function (val)
  10876. {
  10877. ;
  10878. this.type = cr.exptype.Integer;
  10879. this.data = Math.floor(val);
  10880. };
  10881. ExpValue.prototype.set_float = function (val)
  10882. {
  10883. ;
  10884. this.type = cr.exptype.Float;
  10885. this.data = val;
  10886. };
  10887. ExpValue.prototype.set_string = function (val)
  10888. {
  10889. ;
  10890. this.type = cr.exptype.String;
  10891. this.data = val;
  10892. };
  10893. ExpValue.prototype.set_any = function (val)
  10894. {
  10895. if (cr.is_number(val))
  10896. {
  10897. this.type = cr.exptype.Float;
  10898. this.data = val;
  10899. }
  10900. else if (cr.is_string(val))
  10901. {
  10902. this.type = cr.exptype.String;
  10903. this.data = val.toString();
  10904. }
  10905. else
  10906. {
  10907. this.type = cr.exptype.Integer;
  10908. this.data = 0;
  10909. }
  10910. };
  10911. cr.expvalue = ExpValue;
  10912. cr.exptype = {
  10913. Integer: 0, // emulated; no native integer support in javascript
  10914. Float: 1,
  10915. String: 2
  10916. };
  10917. }());
  10918. ;
  10919. cr.system_object = function (runtime)
  10920. {
  10921. this.runtime = runtime;
  10922. this.waits = [];
  10923. };
  10924. cr.system_object.prototype.saveToJSON = function ()
  10925. {
  10926. var o = {};
  10927. var i, len, j, lenj, p, w, t, sobj;
  10928. o["waits"] = [];
  10929. var owaits = o["waits"];
  10930. var waitobj;
  10931. for (i = 0, len = this.waits.length; i < len; i++)
  10932. {
  10933. w = this.waits[i];
  10934. waitobj = {
  10935. "t": w.time,
  10936. "st": w.signaltag,
  10937. "s": w.signalled,
  10938. "ev": w.ev.sid,
  10939. "sm": [],
  10940. "sols": {}
  10941. };
  10942. if (w.ev.actions[w.actindex])
  10943. waitobj["act"] = w.ev.actions[w.actindex].sid;
  10944. for (j = 0, lenj = w.solModifiers.length; j < lenj; j++)
  10945. waitobj["sm"].push(w.solModifiers[j].sid);
  10946. for (p in w.sols)
  10947. {
  10948. if (w.sols.hasOwnProperty(p))
  10949. {
  10950. t = this.runtime.types_by_index[parseInt(p, 10)];
  10951. ;
  10952. sobj = {
  10953. "sa": w.sols[p].sa,
  10954. "insts": []
  10955. };
  10956. for (j = 0, lenj = w.sols[p].insts.length; j < lenj; j++)
  10957. sobj["insts"].push(w.sols[p].insts[j].uid);
  10958. waitobj["sols"][t.sid.toString()] = sobj;
  10959. }
  10960. }
  10961. owaits.push(waitobj);
  10962. }
  10963. return o;
  10964. };
  10965. cr.system_object.prototype.loadFromJSON = function (o)
  10966. {
  10967. var owaits = o["waits"];
  10968. var i, len, j, lenj, p, w, addWait, e, aindex, t, savedsol, nusol, inst;
  10969. cr.clearArray(this.waits);
  10970. for (i = 0, len = owaits.length; i < len; i++)
  10971. {
  10972. w = owaits[i];
  10973. e = this.runtime.blocksBySid[w["ev"].toString()];
  10974. if (!e)
  10975. continue; // event must've gone missing
  10976. aindex = -1;
  10977. for (j = 0, lenj = e.actions.length; j < lenj; j++)
  10978. {
  10979. if (e.actions[j].sid === w["act"])
  10980. {
  10981. aindex = j;
  10982. break;
  10983. }
  10984. }
  10985. if (aindex === -1)
  10986. continue; // action must've gone missing
  10987. addWait = {};
  10988. addWait.sols = {};
  10989. addWait.solModifiers = [];
  10990. addWait.deleteme = false;
  10991. addWait.time = w["t"];
  10992. addWait.signaltag = w["st"] || "";
  10993. addWait.signalled = !!w["s"];
  10994. addWait.ev = e;
  10995. addWait.actindex = aindex;
  10996. for (j = 0, lenj = w["sm"].length; j < lenj; j++)
  10997. {
  10998. t = this.runtime.getObjectTypeBySid(w["sm"][j]);
  10999. if (t)
  11000. addWait.solModifiers.push(t);
  11001. }
  11002. for (p in w["sols"])
  11003. {
  11004. if (w["sols"].hasOwnProperty(p))
  11005. {
  11006. t = this.runtime.getObjectTypeBySid(parseInt(p, 10));
  11007. if (!t)
  11008. continue; // type must've been deleted
  11009. savedsol = w["sols"][p];
  11010. nusol = {
  11011. sa: savedsol["sa"],
  11012. insts: []
  11013. };
  11014. for (j = 0, lenj = savedsol["insts"].length; j < lenj; j++)
  11015. {
  11016. inst = this.runtime.getObjectByUID(savedsol["insts"][j]);
  11017. if (inst)
  11018. nusol.insts.push(inst);
  11019. }
  11020. addWait.sols[t.index.toString()] = nusol;
  11021. }
  11022. }
  11023. this.waits.push(addWait);
  11024. }
  11025. };
  11026. (function ()
  11027. {
  11028. var sysProto = cr.system_object.prototype;
  11029. function SysCnds() {};
  11030. SysCnds.prototype.EveryTick = function()
  11031. {
  11032. return true;
  11033. };
  11034. SysCnds.prototype.OnLayoutStart = function()
  11035. {
  11036. return true;
  11037. };
  11038. SysCnds.prototype.OnLayoutEnd = function()
  11039. {
  11040. return true;
  11041. };
  11042. SysCnds.prototype.Compare = function(x, cmp, y)
  11043. {
  11044. return cr.do_cmp(x, cmp, y);
  11045. };
  11046. SysCnds.prototype.CompareTime = function (cmp, t)
  11047. {
  11048. var elapsed = this.runtime.kahanTime.sum;
  11049. if (cmp === 0)
  11050. {
  11051. var cnd = this.runtime.getCurrentCondition();
  11052. if (!cnd.extra["CompareTime_executed"])
  11053. {
  11054. if (elapsed >= t)
  11055. {
  11056. cnd.extra["CompareTime_executed"] = true;
  11057. return true;
  11058. }
  11059. }
  11060. return false;
  11061. }
  11062. return cr.do_cmp(elapsed, cmp, t);
  11063. };
  11064. SysCnds.prototype.LayerVisible = function (layer)
  11065. {
  11066. if (!layer)
  11067. return false;
  11068. else
  11069. return layer.visible;
  11070. };
  11071. SysCnds.prototype.LayerEmpty = function (layer)
  11072. {
  11073. if (!layer)
  11074. return false;
  11075. else
  11076. return !layer.instances.length;
  11077. };
  11078. SysCnds.prototype.LayerCmpOpacity = function (layer, cmp, opacity_)
  11079. {
  11080. if (!layer)
  11081. return false;
  11082. return cr.do_cmp(layer.opacity * 100, cmp, opacity_);
  11083. };
  11084. SysCnds.prototype.Repeat = function (count)
  11085. {
  11086. var current_frame = this.runtime.getCurrentEventStack();
  11087. var current_event = current_frame.current_event;
  11088. var solModifierAfterCnds = current_frame.isModifierAfterCnds();
  11089. var current_loop = this.runtime.pushLoopStack();
  11090. var i;
  11091. if (solModifierAfterCnds)
  11092. {
  11093. for (i = 0; i < count && !current_loop.stopped; i++)
  11094. {
  11095. this.runtime.pushCopySol(current_event.solModifiers);
  11096. current_loop.index = i;
  11097. current_event.retrigger();
  11098. this.runtime.popSol(current_event.solModifiers);
  11099. }
  11100. }
  11101. else
  11102. {
  11103. for (i = 0; i < count && !current_loop.stopped; i++)
  11104. {
  11105. current_loop.index = i;
  11106. current_event.retrigger();
  11107. }
  11108. }
  11109. this.runtime.popLoopStack();
  11110. return false;
  11111. };
  11112. SysCnds.prototype.While = function (count)
  11113. {
  11114. var current_frame = this.runtime.getCurrentEventStack();
  11115. var current_event = current_frame.current_event;
  11116. var solModifierAfterCnds = current_frame.isModifierAfterCnds();
  11117. var current_loop = this.runtime.pushLoopStack();
  11118. var i;
  11119. if (solModifierAfterCnds)
  11120. {
  11121. for (i = 0; !current_loop.stopped; i++)
  11122. {
  11123. this.runtime.pushCopySol(current_event.solModifiers);
  11124. current_loop.index = i;
  11125. if (!current_event.retrigger()) // one of the other conditions returned false
  11126. current_loop.stopped = true; // break
  11127. this.runtime.popSol(current_event.solModifiers);
  11128. }
  11129. }
  11130. else
  11131. {
  11132. for (i = 0; !current_loop.stopped; i++)
  11133. {
  11134. current_loop.index = i;
  11135. if (!current_event.retrigger())
  11136. current_loop.stopped = true;
  11137. }
  11138. }
  11139. this.runtime.popLoopStack();
  11140. return false;
  11141. };
  11142. SysCnds.prototype.For = function (name, start, end)
  11143. {
  11144. var current_frame = this.runtime.getCurrentEventStack();
  11145. var current_event = current_frame.current_event;
  11146. var solModifierAfterCnds = current_frame.isModifierAfterCnds();
  11147. var current_loop = this.runtime.pushLoopStack(name);
  11148. var i;
  11149. if (end < start)
  11150. {
  11151. if (solModifierAfterCnds)
  11152. {
  11153. for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
  11154. {
  11155. this.runtime.pushCopySol(current_event.solModifiers);
  11156. current_loop.index = i;
  11157. current_event.retrigger();
  11158. this.runtime.popSol(current_event.solModifiers);
  11159. }
  11160. }
  11161. else
  11162. {
  11163. for (i = start; i >= end && !current_loop.stopped; --i) // inclusive to end
  11164. {
  11165. current_loop.index = i;
  11166. current_event.retrigger();
  11167. }
  11168. }
  11169. }
  11170. else
  11171. {
  11172. if (solModifierAfterCnds)
  11173. {
  11174. for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
  11175. {
  11176. this.runtime.pushCopySol(current_event.solModifiers);
  11177. current_loop.index = i;
  11178. current_event.retrigger();
  11179. this.runtime.popSol(current_event.solModifiers);
  11180. }
  11181. }
  11182. else
  11183. {
  11184. for (i = start; i <= end && !current_loop.stopped; ++i) // inclusive to end
  11185. {
  11186. current_loop.index = i;
  11187. current_event.retrigger();
  11188. }
  11189. }
  11190. }
  11191. this.runtime.popLoopStack();
  11192. return false;
  11193. };
  11194. var foreach_instancestack = [];
  11195. var foreach_instanceptr = -1;
  11196. SysCnds.prototype.ForEach = function (obj)
  11197. {
  11198. var sol = obj.getCurrentSol();
  11199. foreach_instanceptr++;
  11200. if (foreach_instancestack.length === foreach_instanceptr)
  11201. foreach_instancestack.push([]);
  11202. var instances = foreach_instancestack[foreach_instanceptr];
  11203. cr.shallowAssignArray(instances, sol.getObjects());
  11204. var current_frame = this.runtime.getCurrentEventStack();
  11205. var current_event = current_frame.current_event;
  11206. var solModifierAfterCnds = current_frame.isModifierAfterCnds();
  11207. var current_loop = this.runtime.pushLoopStack();
  11208. var i, len, j, lenj, inst, s, sol2;
  11209. var is_contained = obj.is_contained;
  11210. if (solModifierAfterCnds)
  11211. {
  11212. for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
  11213. {
  11214. this.runtime.pushCopySol(current_event.solModifiers);
  11215. inst = instances[i];
  11216. sol = obj.getCurrentSol();
  11217. sol.select_all = false;
  11218. cr.clearArray(sol.instances);
  11219. sol.instances[0] = inst;
  11220. if (is_contained)
  11221. {
  11222. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  11223. {
  11224. s = inst.siblings[j];
  11225. sol2 = s.type.getCurrentSol();
  11226. sol2.select_all = false;
  11227. cr.clearArray(sol2.instances);
  11228. sol2.instances[0] = s;
  11229. }
  11230. }
  11231. current_loop.index = i;
  11232. current_event.retrigger();
  11233. this.runtime.popSol(current_event.solModifiers);
  11234. }
  11235. }
  11236. else
  11237. {
  11238. sol.select_all = false;
  11239. cr.clearArray(sol.instances);
  11240. for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
  11241. {
  11242. inst = instances[i];
  11243. sol.instances[0] = inst;
  11244. if (is_contained)
  11245. {
  11246. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  11247. {
  11248. s = inst.siblings[j];
  11249. sol2 = s.type.getCurrentSol();
  11250. sol2.select_all = false;
  11251. cr.clearArray(sol2.instances);
  11252. sol2.instances[0] = s;
  11253. }
  11254. }
  11255. current_loop.index = i;
  11256. current_event.retrigger();
  11257. }
  11258. }
  11259. cr.clearArray(instances);
  11260. this.runtime.popLoopStack();
  11261. foreach_instanceptr--;
  11262. return false;
  11263. };
  11264. function foreach_sortinstances(a, b)
  11265. {
  11266. var va = a.extra["c2_feo_val"];
  11267. var vb = b.extra["c2_feo_val"];
  11268. if (cr.is_number(va) && cr.is_number(vb))
  11269. return va - vb;
  11270. else
  11271. {
  11272. va = "" + va;
  11273. vb = "" + vb;
  11274. if (va < vb)
  11275. return -1;
  11276. else if (va > vb)
  11277. return 1;
  11278. else
  11279. return 0;
  11280. }
  11281. };
  11282. SysCnds.prototype.ForEachOrdered = function (obj, exp, order)
  11283. {
  11284. var sol = obj.getCurrentSol();
  11285. foreach_instanceptr++;
  11286. if (foreach_instancestack.length === foreach_instanceptr)
  11287. foreach_instancestack.push([]);
  11288. var instances = foreach_instancestack[foreach_instanceptr];
  11289. cr.shallowAssignArray(instances, sol.getObjects());
  11290. var current_frame = this.runtime.getCurrentEventStack();
  11291. var current_event = current_frame.current_event;
  11292. var current_condition = this.runtime.getCurrentCondition();
  11293. var solModifierAfterCnds = current_frame.isModifierAfterCnds();
  11294. var current_loop = this.runtime.pushLoopStack();
  11295. var i, len, j, lenj, inst, s, sol2;
  11296. for (i = 0, len = instances.length; i < len; i++)
  11297. {
  11298. instances[i].extra["c2_feo_val"] = current_condition.parameters[1].get(i);
  11299. }
  11300. instances.sort(foreach_sortinstances);
  11301. if (order === 1)
  11302. instances.reverse();
  11303. var is_contained = obj.is_contained;
  11304. if (solModifierAfterCnds)
  11305. {
  11306. for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
  11307. {
  11308. this.runtime.pushCopySol(current_event.solModifiers);
  11309. inst = instances[i];
  11310. sol = obj.getCurrentSol();
  11311. sol.select_all = false;
  11312. cr.clearArray(sol.instances);
  11313. sol.instances[0] = inst;
  11314. if (is_contained)
  11315. {
  11316. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  11317. {
  11318. s = inst.siblings[j];
  11319. sol2 = s.type.getCurrentSol();
  11320. sol2.select_all = false;
  11321. cr.clearArray(sol2.instances);
  11322. sol2.instances[0] = s;
  11323. }
  11324. }
  11325. current_loop.index = i;
  11326. current_event.retrigger();
  11327. this.runtime.popSol(current_event.solModifiers);
  11328. }
  11329. }
  11330. else
  11331. {
  11332. sol.select_all = false;
  11333. cr.clearArray(sol.instances);
  11334. for (i = 0, len = instances.length; i < len && !current_loop.stopped; i++)
  11335. {
  11336. inst = instances[i];
  11337. sol.instances[0] = inst;
  11338. if (is_contained)
  11339. {
  11340. for (j = 0, lenj = inst.siblings.length; j < lenj; j++)
  11341. {
  11342. s = inst.siblings[j];
  11343. sol2 = s.type.getCurrentSol();
  11344. sol2.select_all = false;
  11345. cr.clearArray(sol2.instances);
  11346. sol2.instances[0] = s;
  11347. }
  11348. }
  11349. current_loop.index = i;
  11350. current_event.retrigger();
  11351. }
  11352. }
  11353. cr.clearArray(instances);
  11354. this.runtime.popLoopStack();
  11355. foreach_instanceptr--;
  11356. return false;
  11357. };
  11358. SysCnds.prototype.PickByComparison = function (obj_, exp_, cmp_, val_)
  11359. {
  11360. var i, len, k, inst;
  11361. if (!obj_)
  11362. return;
  11363. foreach_instanceptr++;
  11364. if (foreach_instancestack.length === foreach_instanceptr)
  11365. foreach_instancestack.push([]);
  11366. var tmp_instances = foreach_instancestack[foreach_instanceptr];
  11367. var sol = obj_.getCurrentSol();
  11368. cr.shallowAssignArray(tmp_instances, sol.getObjects());
  11369. if (sol.select_all)
  11370. cr.clearArray(sol.else_instances);
  11371. var current_condition = this.runtime.getCurrentCondition();
  11372. for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
  11373. {
  11374. inst = tmp_instances[i];
  11375. tmp_instances[k] = inst;
  11376. exp_ = current_condition.parameters[1].get(i);
  11377. val_ = current_condition.parameters[3].get(i);
  11378. if (cr.do_cmp(exp_, cmp_, val_))
  11379. {
  11380. k++;
  11381. }
  11382. else
  11383. {
  11384. sol.else_instances.push(inst);
  11385. }
  11386. }
  11387. cr.truncateArray(tmp_instances, k);
  11388. sol.select_all = false;
  11389. cr.shallowAssignArray(sol.instances, tmp_instances);
  11390. cr.clearArray(tmp_instances);
  11391. foreach_instanceptr--;
  11392. obj_.applySolToContainer();
  11393. return !!sol.instances.length;
  11394. };
  11395. SysCnds.prototype.PickByEvaluate = function (obj_, exp_)
  11396. {
  11397. var i, len, k, inst;
  11398. if (!obj_)
  11399. return;
  11400. foreach_instanceptr++;
  11401. if (foreach_instancestack.length === foreach_instanceptr)
  11402. foreach_instancestack.push([]);
  11403. var tmp_instances = foreach_instancestack[foreach_instanceptr];
  11404. var sol = obj_.getCurrentSol();
  11405. cr.shallowAssignArray(tmp_instances, sol.getObjects());
  11406. if (sol.select_all)
  11407. cr.clearArray(sol.else_instances);
  11408. var current_condition = this.runtime.getCurrentCondition();
  11409. for (i = 0, k = 0, len = tmp_instances.length; i < len; i++)
  11410. {
  11411. inst = tmp_instances[i];
  11412. tmp_instances[k] = inst;
  11413. exp_ = current_condition.parameters[1].get(i);
  11414. if (exp_)
  11415. {
  11416. k++;
  11417. }
  11418. else
  11419. {
  11420. sol.else_instances.push(inst);
  11421. }
  11422. }
  11423. cr.truncateArray(tmp_instances, k);
  11424. sol.select_all = false;
  11425. cr.shallowAssignArray(sol.instances, tmp_instances);
  11426. cr.clearArray(tmp_instances);
  11427. foreach_instanceptr--;
  11428. obj_.applySolToContainer();
  11429. return !!sol.instances.length;
  11430. };
  11431. SysCnds.prototype.TriggerOnce = function ()
  11432. {
  11433. var cndextra = this.runtime.getCurrentCondition().extra;
  11434. if (typeof cndextra["TriggerOnce_lastTick"] === "undefined")
  11435. cndextra["TriggerOnce_lastTick"] = -1;
  11436. var last_tick = cndextra["TriggerOnce_lastTick"];
  11437. var cur_tick = this.runtime.tickcount;
  11438. cndextra["TriggerOnce_lastTick"] = cur_tick;
  11439. return this.runtime.layout_first_tick || last_tick !== cur_tick - 1;
  11440. };
  11441. SysCnds.prototype.Every = function (seconds)
  11442. {
  11443. var cnd = this.runtime.getCurrentCondition();
  11444. var last_time = cnd.extra["Every_lastTime"] || 0;
  11445. var cur_time = this.runtime.kahanTime.sum;
  11446. if (typeof cnd.extra["Every_seconds"] === "undefined")
  11447. cnd.extra["Every_seconds"] = seconds;
  11448. var this_seconds = cnd.extra["Every_seconds"];
  11449. if (cur_time >= last_time + this_seconds)
  11450. {
  11451. cnd.extra["Every_lastTime"] = last_time + this_seconds;
  11452. if (cur_time >= cnd.extra["Every_lastTime"] + 0.04)
  11453. {
  11454. cnd.extra["Every_lastTime"] = cur_time;
  11455. }
  11456. cnd.extra["Every_seconds"] = seconds;
  11457. return true;
  11458. }
  11459. else if (cur_time < last_time - 0.1)
  11460. {
  11461. cnd.extra["Every_lastTime"] = cur_time;
  11462. }
  11463. return false;
  11464. };
  11465. SysCnds.prototype.PickNth = function (obj, index)
  11466. {
  11467. if (!obj)
  11468. return false;
  11469. var sol = obj.getCurrentSol();
  11470. var instances = sol.getObjects();
  11471. index = cr.floor(index);
  11472. if (index < 0 || index >= instances.length)
  11473. return false;
  11474. var inst = instances[index];
  11475. sol.pick_one(inst);
  11476. obj.applySolToContainer();
  11477. return true;
  11478. };
  11479. SysCnds.prototype.PickRandom = function (obj)
  11480. {
  11481. if (!obj)
  11482. return false;
  11483. var sol = obj.getCurrentSol();
  11484. var instances = sol.getObjects();
  11485. var index = cr.floor(Math.random() * instances.length);
  11486. if (index >= instances.length)
  11487. return false;
  11488. var inst = instances[index];
  11489. sol.pick_one(inst);
  11490. obj.applySolToContainer();
  11491. return true;
  11492. };
  11493. SysCnds.prototype.CompareVar = function (v, cmp, val)
  11494. {
  11495. return cr.do_cmp(v.getValue(), cmp, val);
  11496. };
  11497. SysCnds.prototype.IsGroupActive = function (group)
  11498. {
  11499. var g = this.runtime.groups_by_name[group.toLowerCase()];
  11500. return g && g.group_active;
  11501. };
  11502. SysCnds.prototype.IsPreview = function ()
  11503. {
  11504. return typeof cr_is_preview !== "undefined";
  11505. };
  11506. SysCnds.prototype.PickAll = function (obj)
  11507. {
  11508. if (!obj)
  11509. return false;
  11510. if (!obj.instances.length)
  11511. return false;
  11512. var sol = obj.getCurrentSol();
  11513. sol.select_all = true;
  11514. obj.applySolToContainer();
  11515. return true;
  11516. };
  11517. SysCnds.prototype.IsMobile = function ()
  11518. {
  11519. return this.runtime.isMobile;
  11520. };
  11521. SysCnds.prototype.CompareBetween = function (x, a, b)
  11522. {
  11523. return x >= a && x <= b;
  11524. };
  11525. SysCnds.prototype.Else = function ()
  11526. {
  11527. var current_frame = this.runtime.getCurrentEventStack();
  11528. if (current_frame.else_branch_ran)
  11529. return false; // another event in this else-if chain has run
  11530. else
  11531. return !current_frame.last_event_true;
  11532. /*
  11533. var current_frame = this.runtime.getCurrentEventStack();
  11534. var current_event = current_frame.current_event;
  11535. var prev_event = current_event.prev_block;
  11536. if (!prev_event)
  11537. return false;
  11538. if (prev_event.is_logical)
  11539. return !this.runtime.last_event_true;
  11540. var i, len, j, lenj, s, sol, temp, inst, any_picked = false;
  11541. for (i = 0, len = prev_event.cndReferences.length; i < len; i++)
  11542. {
  11543. s = prev_event.cndReferences[i];
  11544. sol = s.getCurrentSol();
  11545. if (sol.select_all || sol.instances.length === s.instances.length)
  11546. {
  11547. sol.select_all = false;
  11548. sol.instances.length = 0;
  11549. }
  11550. else
  11551. {
  11552. if (sol.instances.length === 1 && sol.else_instances.length === 0 && s.instances.length >= 2)
  11553. {
  11554. inst = sol.instances[0];
  11555. sol.instances.length = 0;
  11556. for (j = 0, lenj = s.instances.length; j < lenj; j++)
  11557. {
  11558. if (s.instances[j] != inst)
  11559. sol.instances.push(s.instances[j]);
  11560. }
  11561. any_picked = true;
  11562. }
  11563. else
  11564. {
  11565. temp = sol.instances;
  11566. sol.instances = sol.else_instances;
  11567. sol.else_instances = temp;
  11568. any_picked = true;
  11569. }
  11570. }
  11571. }
  11572. return any_picked;
  11573. */
  11574. };
  11575. SysCnds.prototype.OnLoadFinished = function ()
  11576. {
  11577. return true;
  11578. };
  11579. SysCnds.prototype.OnCanvasSnapshot = function ()
  11580. {
  11581. return true;
  11582. };
  11583. SysCnds.prototype.EffectsSupported = function ()
  11584. {
  11585. return !!this.runtime.glwrap;
  11586. };
  11587. SysCnds.prototype.OnSaveComplete = function ()
  11588. {
  11589. return true;
  11590. };
  11591. SysCnds.prototype.OnLoadComplete = function ()
  11592. {
  11593. return true;
  11594. };
  11595. SysCnds.prototype.OnLoadFailed = function ()
  11596. {
  11597. return true;
  11598. };
  11599. SysCnds.prototype.ObjectUIDExists = function (u)
  11600. {
  11601. return !!this.runtime.getObjectByUID(u);
  11602. };
  11603. SysCnds.prototype.IsOnPlatform = function (p)
  11604. {
  11605. var rt = this.runtime;
  11606. switch (p) {
  11607. case 0: // HTML5 website
  11608. return !rt.isDomFree && !rt.isNodeWebkit && !rt.isCordova && !rt.isWinJS && !rt.isWindowsPhone8 && !rt.isBlackberry10 && !rt.isAmazonWebApp;
  11609. case 1: // iOS
  11610. return rt.isiOS;
  11611. case 2: // Android
  11612. return rt.isAndroid;
  11613. case 3: // Windows 8
  11614. return rt.isWindows8App;
  11615. case 4: // Windows Phone 8
  11616. return rt.isWindowsPhone8;
  11617. case 5: // Blackberry 10
  11618. return rt.isBlackberry10;
  11619. case 6: // Tizen
  11620. return rt.isTizen;
  11621. case 7: // CocoonJS
  11622. return rt.isCocoonJs;
  11623. case 8: // Cordova
  11624. return rt.isCordova;
  11625. case 9: // Scirra Arcade
  11626. return rt.isArcade;
  11627. case 10: // node-webkit
  11628. return rt.isNodeWebkit;
  11629. case 11: // crosswalk
  11630. return rt.isCrosswalk;
  11631. case 12: // amazon webapp
  11632. return rt.isAmazonWebApp;
  11633. default: // should not be possible
  11634. return false;
  11635. }
  11636. };
  11637. var cacheRegex = null;
  11638. var lastRegex = "";
  11639. var lastFlags = "";
  11640. function getRegex(regex_, flags_)
  11641. {
  11642. if (!cacheRegex || regex_ !== lastRegex || flags_ !== lastFlags)
  11643. {
  11644. cacheRegex = new RegExp(regex_, flags_);
  11645. lastRegex = regex_;
  11646. lastFlags = flags_;
  11647. }
  11648. cacheRegex.lastIndex = 0; // reset
  11649. return cacheRegex;
  11650. };
  11651. SysCnds.prototype.RegexTest = function (str_, regex_, flags_)
  11652. {
  11653. var regex = getRegex(regex_, flags_);
  11654. return regex.test(str_);
  11655. };
  11656. var tmp_arr = [];
  11657. SysCnds.prototype.PickOverlappingPoint = function (obj_, x_, y_)
  11658. {
  11659. if (!obj_)
  11660. return false;
  11661. var sol = obj_.getCurrentSol();
  11662. var instances = sol.getObjects();
  11663. var current_event = this.runtime.getCurrentEventStack().current_event;
  11664. var orblock = current_event.orblock;
  11665. var cnd = this.runtime.getCurrentCondition();
  11666. var i, len, inst, pick;
  11667. if (sol.select_all)
  11668. {
  11669. cr.shallowAssignArray(tmp_arr, instances);
  11670. cr.clearArray(sol.else_instances);
  11671. sol.select_all = false;
  11672. cr.clearArray(sol.instances);
  11673. }
  11674. else
  11675. {
  11676. if (orblock)
  11677. {
  11678. cr.shallowAssignArray(tmp_arr, sol.else_instances);
  11679. cr.clearArray(sol.else_instances);
  11680. }
  11681. else
  11682. {
  11683. cr.shallowAssignArray(tmp_arr, instances);
  11684. cr.clearArray(sol.instances);
  11685. }
  11686. }
  11687. for (i = 0, len = tmp_arr.length; i < len; ++i)
  11688. {
  11689. inst = tmp_arr[i];
  11690. inst.update_bbox();
  11691. pick = cr.xor(inst.contains_pt(x_, y_), cnd.inverted);
  11692. if (pick)
  11693. sol.instances.push(inst);
  11694. else
  11695. sol.else_instances.push(inst);
  11696. }
  11697. obj_.applySolToContainer();
  11698. return cr.xor(!!sol.instances.length, cnd.inverted);
  11699. };
  11700. SysCnds.prototype.IsNaN = function (n)
  11701. {
  11702. return !!isNaN(n);
  11703. };
  11704. SysCnds.prototype.AngleWithin = function (a1, within, a2)
  11705. {
  11706. return cr.angleDiff(cr.to_radians(a1), cr.to_radians(a2)) <= cr.to_radians(within);
  11707. };
  11708. SysCnds.prototype.IsClockwiseFrom = function (a1, a2)
  11709. {
  11710. return cr.angleClockwise(cr.to_radians(a1), cr.to_radians(a2));
  11711. };
  11712. SysCnds.prototype.IsBetweenAngles = function (a, la, ua)
  11713. {
  11714. var angle = cr.to_clamped_radians(a);
  11715. var lower = cr.to_clamped_radians(la);
  11716. var upper = cr.to_clamped_radians(ua);
  11717. var obtuse = (!cr.angleClockwise(upper, lower));
  11718. if (obtuse)
  11719. return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
  11720. else
  11721. return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
  11722. };
  11723. SysCnds.prototype.IsValueType = function (x, t)
  11724. {
  11725. if (typeof x === "number")
  11726. return t === 0;
  11727. else // string
  11728. return t === 1;
  11729. };
  11730. sysProto.cnds = new SysCnds();
  11731. function SysActs() {};
  11732. SysActs.prototype.GoToLayout = function (to)
  11733. {
  11734. if (this.runtime.isloading)
  11735. return; // cannot change layout while loading on loader layout
  11736. if (this.runtime.changelayout)
  11737. return; // already changing to a different layout
  11738. ;
  11739. this.runtime.changelayout = to;
  11740. };
  11741. SysActs.prototype.NextPrevLayout = function (prev)
  11742. {
  11743. if (this.runtime.isloading)
  11744. return; // cannot change layout while loading on loader layout
  11745. if (this.runtime.changelayout)
  11746. return; // already changing to a different layout
  11747. var index = this.runtime.layouts_by_index.indexOf(this.runtime.running_layout);
  11748. if (prev && index === 0)
  11749. return; // cannot go to previous layout from first layout
  11750. if (!prev && index === this.runtime.layouts_by_index.length - 1)
  11751. return; // cannot go to next layout from last layout
  11752. var to = this.runtime.layouts_by_index[index + (prev ? -1 : 1)];
  11753. ;
  11754. this.runtime.changelayout = to;
  11755. };
  11756. SysActs.prototype.CreateObject = function (obj, layer, x, y)
  11757. {
  11758. if (!layer || !obj)
  11759. return;
  11760. var inst = this.runtime.createInstance(obj, layer, x, y);
  11761. if (!inst)
  11762. return;
  11763. this.runtime.isInOnDestroy++;
  11764. var i, len, s;
  11765. this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
  11766. if (inst.is_contained)
  11767. {
  11768. for (i = 0, len = inst.siblings.length; i < len; i++)
  11769. {
  11770. s = inst.siblings[i];
  11771. this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
  11772. }
  11773. }
  11774. this.runtime.isInOnDestroy--;
  11775. var sol = obj.getCurrentSol();
  11776. sol.select_all = false;
  11777. cr.clearArray(sol.instances);
  11778. sol.instances[0] = inst;
  11779. if (inst.is_contained)
  11780. {
  11781. for (i = 0, len = inst.siblings.length; i < len; i++)
  11782. {
  11783. s = inst.siblings[i];
  11784. sol = s.type.getCurrentSol();
  11785. sol.select_all = false;
  11786. cr.clearArray(sol.instances);
  11787. sol.instances[0] = s;
  11788. }
  11789. }
  11790. };
  11791. SysActs.prototype.SetLayerVisible = function (layer, visible_)
  11792. {
  11793. if (!layer)
  11794. return;
  11795. if (layer.visible !== visible_)
  11796. {
  11797. layer.visible = visible_;
  11798. this.runtime.redraw = true;
  11799. }
  11800. };
  11801. SysActs.prototype.SetLayerOpacity = function (layer, opacity_)
  11802. {
  11803. if (!layer)
  11804. return;
  11805. opacity_ = cr.clamp(opacity_ / 100, 0, 1);
  11806. if (layer.opacity !== opacity_)
  11807. {
  11808. layer.opacity = opacity_;
  11809. this.runtime.redraw = true;
  11810. }
  11811. };
  11812. SysActs.prototype.SetLayerScaleRate = function (layer, sr)
  11813. {
  11814. if (!layer)
  11815. return;
  11816. if (layer.zoomRate !== sr)
  11817. {
  11818. layer.zoomRate = sr;
  11819. this.runtime.redraw = true;
  11820. }
  11821. };
  11822. SysActs.prototype.SetLayerForceOwnTexture = function (layer, f)
  11823. {
  11824. if (!layer)
  11825. return;
  11826. f = !!f;
  11827. if (layer.forceOwnTexture !== f)
  11828. {
  11829. layer.forceOwnTexture = f;
  11830. this.runtime.redraw = true;
  11831. }
  11832. };
  11833. SysActs.prototype.SetLayoutScale = function (s)
  11834. {
  11835. if (!this.runtime.running_layout)
  11836. return;
  11837. if (this.runtime.running_layout.scale !== s)
  11838. {
  11839. this.runtime.running_layout.scale = s;
  11840. this.runtime.running_layout.boundScrolling();
  11841. this.runtime.redraw = true;
  11842. }
  11843. };
  11844. SysActs.prototype.ScrollX = function(x)
  11845. {
  11846. this.runtime.running_layout.scrollToX(x);
  11847. };
  11848. SysActs.prototype.ScrollY = function(y)
  11849. {
  11850. this.runtime.running_layout.scrollToY(y);
  11851. };
  11852. SysActs.prototype.Scroll = function(x, y)
  11853. {
  11854. this.runtime.running_layout.scrollToX(x);
  11855. this.runtime.running_layout.scrollToY(y);
  11856. };
  11857. SysActs.prototype.ScrollToObject = function(obj)
  11858. {
  11859. var inst = obj.getFirstPicked();
  11860. if (inst)
  11861. {
  11862. this.runtime.running_layout.scrollToX(inst.x);
  11863. this.runtime.running_layout.scrollToY(inst.y);
  11864. }
  11865. };
  11866. SysActs.prototype.SetVar = function(v, x)
  11867. {
  11868. ;
  11869. if (v.vartype === 0)
  11870. {
  11871. if (cr.is_number(x))
  11872. v.setValue(x);
  11873. else
  11874. v.setValue(parseFloat(x));
  11875. }
  11876. else if (v.vartype === 1)
  11877. v.setValue(x.toString());
  11878. };
  11879. SysActs.prototype.AddVar = function(v, x)
  11880. {
  11881. ;
  11882. if (v.vartype === 0)
  11883. {
  11884. if (cr.is_number(x))
  11885. v.setValue(v.getValue() + x);
  11886. else
  11887. v.setValue(v.getValue() + parseFloat(x));
  11888. }
  11889. else if (v.vartype === 1)
  11890. v.setValue(v.getValue() + x.toString());
  11891. };
  11892. SysActs.prototype.SubVar = function(v, x)
  11893. {
  11894. ;
  11895. if (v.vartype === 0)
  11896. {
  11897. if (cr.is_number(x))
  11898. v.setValue(v.getValue() - x);
  11899. else
  11900. v.setValue(v.getValue() - parseFloat(x));
  11901. }
  11902. };
  11903. SysActs.prototype.SetGroupActive = function (group, active)
  11904. {
  11905. var g = this.runtime.groups_by_name[group.toLowerCase()];
  11906. if (!g)
  11907. return;
  11908. switch (active) {
  11909. case 0:
  11910. g.setGroupActive(false);
  11911. break;
  11912. case 1:
  11913. g.setGroupActive(true);
  11914. break;
  11915. case 2:
  11916. g.setGroupActive(!g.group_active);
  11917. break;
  11918. }
  11919. };
  11920. SysActs.prototype.SetTimescale = function (ts_)
  11921. {
  11922. var ts = ts_;
  11923. if (ts < 0)
  11924. ts = 0;
  11925. this.runtime.timescale = ts;
  11926. };
  11927. SysActs.prototype.SetObjectTimescale = function (obj, ts_)
  11928. {
  11929. var ts = ts_;
  11930. if (ts < 0)
  11931. ts = 0;
  11932. if (!obj)
  11933. return;
  11934. var sol = obj.getCurrentSol();
  11935. var instances = sol.getObjects();
  11936. var i, len;
  11937. for (i = 0, len = instances.length; i < len; i++)
  11938. {
  11939. instances[i].my_timescale = ts;
  11940. }
  11941. };
  11942. SysActs.prototype.RestoreObjectTimescale = function (obj)
  11943. {
  11944. if (!obj)
  11945. return false;
  11946. var sol = obj.getCurrentSol();
  11947. var instances = sol.getObjects();
  11948. var i, len;
  11949. for (i = 0, len = instances.length; i < len; i++)
  11950. {
  11951. instances[i].my_timescale = -1.0;
  11952. }
  11953. };
  11954. var waitobjrecycle = [];
  11955. function allocWaitObject()
  11956. {
  11957. var w;
  11958. if (waitobjrecycle.length)
  11959. w = waitobjrecycle.pop();
  11960. else
  11961. {
  11962. w = {};
  11963. w.sols = {};
  11964. w.solModifiers = [];
  11965. }
  11966. w.deleteme = false;
  11967. return w;
  11968. };
  11969. function freeWaitObject(w)
  11970. {
  11971. cr.wipe(w.sols);
  11972. cr.clearArray(w.solModifiers);
  11973. waitobjrecycle.push(w);
  11974. };
  11975. var solstateobjects = [];
  11976. function allocSolStateObject()
  11977. {
  11978. var s;
  11979. if (solstateobjects.length)
  11980. s = solstateobjects.pop();
  11981. else
  11982. {
  11983. s = {};
  11984. s.insts = [];
  11985. }
  11986. s.sa = false;
  11987. return s;
  11988. };
  11989. function freeSolStateObject(s)
  11990. {
  11991. cr.clearArray(s.insts);
  11992. solstateobjects.push(s);
  11993. };
  11994. SysActs.prototype.Wait = function (seconds)
  11995. {
  11996. if (seconds < 0)
  11997. return;
  11998. var i, len, s, t, ss;
  11999. var evinfo = this.runtime.getCurrentEventStack();
  12000. var waitobj = allocWaitObject();
  12001. waitobj.time = this.runtime.kahanTime.sum + seconds;
  12002. waitobj.signaltag = "";
  12003. waitobj.signalled = false;
  12004. waitobj.ev = evinfo.current_event;
  12005. waitobj.actindex = evinfo.actindex + 1; // pointing at next action
  12006. for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
  12007. {
  12008. t = this.runtime.types_by_index[i];
  12009. s = t.getCurrentSol();
  12010. if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
  12011. continue;
  12012. waitobj.solModifiers.push(t);
  12013. ss = allocSolStateObject();
  12014. ss.sa = s.select_all;
  12015. cr.shallowAssignArray(ss.insts, s.instances);
  12016. waitobj.sols[i.toString()] = ss;
  12017. }
  12018. this.waits.push(waitobj);
  12019. return true;
  12020. };
  12021. SysActs.prototype.WaitForSignal = function (tag)
  12022. {
  12023. var i, len, s, t, ss;
  12024. var evinfo = this.runtime.getCurrentEventStack();
  12025. var waitobj = allocWaitObject();
  12026. waitobj.time = -1;
  12027. waitobj.signaltag = tag.toLowerCase();
  12028. waitobj.signalled = false;
  12029. waitobj.ev = evinfo.current_event;
  12030. waitobj.actindex = evinfo.actindex + 1; // pointing at next action
  12031. for (i = 0, len = this.runtime.types_by_index.length; i < len; i++)
  12032. {
  12033. t = this.runtime.types_by_index[i];
  12034. s = t.getCurrentSol();
  12035. if (s.select_all && evinfo.current_event.solModifiers.indexOf(t) === -1)
  12036. continue;
  12037. waitobj.solModifiers.push(t);
  12038. ss = allocSolStateObject();
  12039. ss.sa = s.select_all;
  12040. cr.shallowAssignArray(ss.insts, s.instances);
  12041. waitobj.sols[i.toString()] = ss;
  12042. }
  12043. this.waits.push(waitobj);
  12044. return true;
  12045. };
  12046. SysActs.prototype.Signal = function (tag)
  12047. {
  12048. var lowertag = tag.toLowerCase();
  12049. var i, len, w;
  12050. for (i = 0, len = this.waits.length; i < len; ++i)
  12051. {
  12052. w = this.waits[i];
  12053. if (w.time !== -1)
  12054. continue; // timer wait, ignore
  12055. if (w.signaltag === lowertag) // waiting for this signal
  12056. w.signalled = true; // will run on next check
  12057. }
  12058. };
  12059. SysActs.prototype.SetLayerScale = function (layer, scale)
  12060. {
  12061. if (!layer)
  12062. return;
  12063. if (layer.scale === scale)
  12064. return;
  12065. layer.scale = scale;
  12066. this.runtime.redraw = true;
  12067. };
  12068. SysActs.prototype.ResetGlobals = function ()
  12069. {
  12070. var i, len, g;
  12071. for (i = 0, len = this.runtime.all_global_vars.length; i < len; i++)
  12072. {
  12073. g = this.runtime.all_global_vars[i];
  12074. g.data = g.initial;
  12075. }
  12076. };
  12077. SysActs.prototype.SetLayoutAngle = function (a)
  12078. {
  12079. a = cr.to_radians(a);
  12080. a = cr.clamp_angle(a);
  12081. if (this.runtime.running_layout)
  12082. {
  12083. if (this.runtime.running_layout.angle !== a)
  12084. {
  12085. this.runtime.running_layout.angle = a;
  12086. this.runtime.redraw = true;
  12087. }
  12088. }
  12089. };
  12090. SysActs.prototype.SetLayerAngle = function (layer, a)
  12091. {
  12092. if (!layer)
  12093. return;
  12094. a = cr.to_radians(a);
  12095. a = cr.clamp_angle(a);
  12096. if (layer.angle === a)
  12097. return;
  12098. layer.angle = a;
  12099. this.runtime.redraw = true;
  12100. };
  12101. SysActs.prototype.SetLayerParallax = function (layer, px, py)
  12102. {
  12103. if (!layer)
  12104. return;
  12105. if (layer.parallaxX === px / 100 && layer.parallaxY === py / 100)
  12106. return;
  12107. layer.parallaxX = px / 100;
  12108. layer.parallaxY = py / 100;
  12109. if (layer.parallaxX !== 1 || layer.parallaxY !== 1)
  12110. {
  12111. var i, len, instances = layer.instances;
  12112. for (i = 0, len = instances.length; i < len; ++i)
  12113. {
  12114. instances[i].type.any_instance_parallaxed = true;
  12115. }
  12116. }
  12117. this.runtime.redraw = true;
  12118. };
  12119. SysActs.prototype.SetLayerBackground = function (layer, c)
  12120. {
  12121. if (!layer)
  12122. return;
  12123. var r = cr.GetRValue(c);
  12124. var g = cr.GetGValue(c);
  12125. var b = cr.GetBValue(c);
  12126. if (layer.background_color[0] === r && layer.background_color[1] === g && layer.background_color[2] === b)
  12127. return;
  12128. layer.background_color[0] = r;
  12129. layer.background_color[1] = g;
  12130. layer.background_color[2] = b;
  12131. this.runtime.redraw = true;
  12132. };
  12133. SysActs.prototype.SetLayerTransparent = function (layer, t)
  12134. {
  12135. if (!layer)
  12136. return;
  12137. if (!!t === !!layer.transparent)
  12138. return;
  12139. layer.transparent = !!t;
  12140. this.runtime.redraw = true;
  12141. };
  12142. SysActs.prototype.SetLayerBlendMode = function (layer, bm)
  12143. {
  12144. if (!layer)
  12145. return;
  12146. if (layer.blend_mode === bm)
  12147. return;
  12148. layer.blend_mode = bm;
  12149. layer.compositeOp = cr.effectToCompositeOp(layer.blend_mode);
  12150. if (this.runtime.gl)
  12151. cr.setGLBlend(layer, layer.blend_mode, this.runtime.gl);
  12152. this.runtime.redraw = true;
  12153. };
  12154. SysActs.prototype.StopLoop = function ()
  12155. {
  12156. if (this.runtime.loop_stack_index < 0)
  12157. return; // no loop currently running
  12158. this.runtime.getCurrentLoop().stopped = true;
  12159. };
  12160. SysActs.prototype.GoToLayoutByName = function (layoutname)
  12161. {
  12162. if (this.runtime.isloading)
  12163. return; // cannot change layout while loading on loader layout
  12164. if (this.runtime.changelayout)
  12165. return; // already changing to different layout
  12166. ;
  12167. var l;
  12168. for (l in this.runtime.layouts)
  12169. {
  12170. if (this.runtime.layouts.hasOwnProperty(l) && cr.equals_nocase(l, layoutname))
  12171. {
  12172. this.runtime.changelayout = this.runtime.layouts[l];
  12173. return;
  12174. }
  12175. }
  12176. };
  12177. SysActs.prototype.RestartLayout = function (layoutname)
  12178. {
  12179. if (this.runtime.isloading)
  12180. return; // cannot restart loader layouts
  12181. if (this.runtime.changelayout)
  12182. return; // already changing to a different layout
  12183. ;
  12184. if (!this.runtime.running_layout)
  12185. return;
  12186. this.runtime.changelayout = this.runtime.running_layout;
  12187. var i, len, g;
  12188. for (i = 0, len = this.runtime.allGroups.length; i < len; i++)
  12189. {
  12190. g = this.runtime.allGroups[i];
  12191. g.setGroupActive(g.initially_activated);
  12192. }
  12193. };
  12194. SysActs.prototype.SnapshotCanvas = function (format_, quality_)
  12195. {
  12196. this.runtime.doCanvasSnapshot(format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100);
  12197. };
  12198. SysActs.prototype.SetCanvasSize = function (w, h)
  12199. {
  12200. if (w <= 0 || h <= 0)
  12201. return;
  12202. var mode = this.runtime.fullscreen_mode;
  12203. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
  12204. if (isfullscreen && this.runtime.fullscreen_scaling > 0)
  12205. mode = this.runtime.fullscreen_scaling;
  12206. if (mode === 0)
  12207. {
  12208. this.runtime["setSize"](w, h, true);
  12209. }
  12210. else
  12211. {
  12212. this.runtime.original_width = w;
  12213. this.runtime.original_height = h;
  12214. this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
  12215. }
  12216. };
  12217. SysActs.prototype.SetLayoutEffectEnabled = function (enable_, effectname_)
  12218. {
  12219. if (!this.runtime.running_layout || !this.runtime.glwrap)
  12220. return;
  12221. var et = this.runtime.running_layout.getEffectByName(effectname_);
  12222. if (!et)
  12223. return; // effect name not found
  12224. var enable = (enable_ === 1);
  12225. if (et.active == enable)
  12226. return; // no change
  12227. et.active = enable;
  12228. this.runtime.running_layout.updateActiveEffects();
  12229. this.runtime.redraw = true;
  12230. };
  12231. SysActs.prototype.SetLayerEffectEnabled = function (layer, enable_, effectname_)
  12232. {
  12233. if (!layer || !this.runtime.glwrap)
  12234. return;
  12235. var et = layer.getEffectByName(effectname_);
  12236. if (!et)
  12237. return; // effect name not found
  12238. var enable = (enable_ === 1);
  12239. if (et.active == enable)
  12240. return; // no change
  12241. et.active = enable;
  12242. layer.updateActiveEffects();
  12243. this.runtime.redraw = true;
  12244. };
  12245. SysActs.prototype.SetLayoutEffectParam = function (effectname_, index_, value_)
  12246. {
  12247. if (!this.runtime.running_layout || !this.runtime.glwrap)
  12248. return;
  12249. var et = this.runtime.running_layout.getEffectByName(effectname_);
  12250. if (!et)
  12251. return; // effect name not found
  12252. var params = this.runtime.running_layout.effect_params[et.index];
  12253. index_ = Math.floor(index_);
  12254. if (index_ < 0 || index_ >= params.length)
  12255. return; // effect index out of bounds
  12256. if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
  12257. value_ /= 100.0;
  12258. if (params[index_] === value_)
  12259. return; // no change
  12260. params[index_] = value_;
  12261. if (et.active)
  12262. this.runtime.redraw = true;
  12263. };
  12264. SysActs.prototype.SetLayerEffectParam = function (layer, effectname_, index_, value_)
  12265. {
  12266. if (!layer || !this.runtime.glwrap)
  12267. return;
  12268. var et = layer.getEffectByName(effectname_);
  12269. if (!et)
  12270. return; // effect name not found
  12271. var params = layer.effect_params[et.index];
  12272. index_ = Math.floor(index_);
  12273. if (index_ < 0 || index_ >= params.length)
  12274. return; // effect index out of bounds
  12275. if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
  12276. value_ /= 100.0;
  12277. if (params[index_] === value_)
  12278. return; // no change
  12279. params[index_] = value_;
  12280. if (et.active)
  12281. this.runtime.redraw = true;
  12282. };
  12283. SysActs.prototype.SaveState = function (slot_)
  12284. {
  12285. this.runtime.saveToSlot = slot_;
  12286. };
  12287. SysActs.prototype.LoadState = function (slot_)
  12288. {
  12289. this.runtime.loadFromSlot = slot_;
  12290. };
  12291. SysActs.prototype.LoadStateJSON = function (jsonstr_)
  12292. {
  12293. this.runtime.loadFromJson = jsonstr_;
  12294. };
  12295. SysActs.prototype.SetHalfFramerateMode = function (set_)
  12296. {
  12297. this.runtime.halfFramerateMode = (set_ !== 0);
  12298. };
  12299. SysActs.prototype.SetFullscreenQuality = function (q)
  12300. {
  12301. var isfullscreen = (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || this.isNodeFullscreen);
  12302. if (!isfullscreen && this.runtime.fullscreen_mode === 0)
  12303. return;
  12304. this.runtime.wantFullscreenScalingQuality = (q !== 0);
  12305. this.runtime["setSize"](this.runtime.lastWindowWidth, this.runtime.lastWindowHeight, true);
  12306. };
  12307. SysActs.prototype.ResetPersisted = function ()
  12308. {
  12309. var i, len;
  12310. for (i = 0, len = this.runtime.layouts_by_index.length; i < len; ++i)
  12311. {
  12312. this.runtime.layouts_by_index[i].persist_data = {};
  12313. this.runtime.layouts_by_index[i].first_visit = true;
  12314. }
  12315. };
  12316. SysActs.prototype.RecreateInitialObjects = function (obj, x1, y1, x2, y2)
  12317. {
  12318. if (!obj)
  12319. return;
  12320. this.runtime.running_layout.recreateInitialObjects(obj, x1, y1, x2, y2);
  12321. };
  12322. SysActs.prototype.SetPixelRounding = function (m)
  12323. {
  12324. this.runtime.pixel_rounding = (m !== 0);
  12325. this.runtime.redraw = true;
  12326. };
  12327. sysProto.acts = new SysActs();
  12328. function SysExps() {};
  12329. SysExps.prototype["int"] = function(ret, x)
  12330. {
  12331. if (cr.is_string(x))
  12332. {
  12333. ret.set_int(parseInt(x, 10));
  12334. if (isNaN(ret.data))
  12335. ret.data = 0;
  12336. }
  12337. else
  12338. ret.set_int(x);
  12339. };
  12340. SysExps.prototype["float"] = function(ret, x)
  12341. {
  12342. if (cr.is_string(x))
  12343. {
  12344. ret.set_float(parseFloat(x));
  12345. if (isNaN(ret.data))
  12346. ret.data = 0;
  12347. }
  12348. else
  12349. ret.set_float(x);
  12350. };
  12351. SysExps.prototype.str = function(ret, x)
  12352. {
  12353. if (cr.is_string(x))
  12354. ret.set_string(x);
  12355. else
  12356. ret.set_string(x.toString());
  12357. };
  12358. SysExps.prototype.len = function(ret, x)
  12359. {
  12360. ret.set_int(x.length || 0);
  12361. };
  12362. SysExps.prototype.random = function (ret, a, b)
  12363. {
  12364. if (b === undefined)
  12365. {
  12366. ret.set_float(Math.random() * a);
  12367. }
  12368. else
  12369. {
  12370. ret.set_float(Math.random() * (b - a) + a);
  12371. }
  12372. };
  12373. SysExps.prototype.sqrt = function(ret, x)
  12374. {
  12375. ret.set_float(Math.sqrt(x));
  12376. };
  12377. SysExps.prototype.abs = function(ret, x)
  12378. {
  12379. ret.set_float(Math.abs(x));
  12380. };
  12381. SysExps.prototype.round = function(ret, x)
  12382. {
  12383. ret.set_int(Math.round(x));
  12384. };
  12385. SysExps.prototype.floor = function(ret, x)
  12386. {
  12387. ret.set_int(Math.floor(x));
  12388. };
  12389. SysExps.prototype.ceil = function(ret, x)
  12390. {
  12391. ret.set_int(Math.ceil(x));
  12392. };
  12393. SysExps.prototype.sin = function(ret, x)
  12394. {
  12395. ret.set_float(Math.sin(cr.to_radians(x)));
  12396. };
  12397. SysExps.prototype.cos = function(ret, x)
  12398. {
  12399. ret.set_float(Math.cos(cr.to_radians(x)));
  12400. };
  12401. SysExps.prototype.tan = function(ret, x)
  12402. {
  12403. ret.set_float(Math.tan(cr.to_radians(x)));
  12404. };
  12405. SysExps.prototype.asin = function(ret, x)
  12406. {
  12407. ret.set_float(cr.to_degrees(Math.asin(x)));
  12408. };
  12409. SysExps.prototype.acos = function(ret, x)
  12410. {
  12411. ret.set_float(cr.to_degrees(Math.acos(x)));
  12412. };
  12413. SysExps.prototype.atan = function(ret, x)
  12414. {
  12415. ret.set_float(cr.to_degrees(Math.atan(x)));
  12416. };
  12417. SysExps.prototype.exp = function(ret, x)
  12418. {
  12419. ret.set_float(Math.exp(x));
  12420. };
  12421. SysExps.prototype.ln = function(ret, x)
  12422. {
  12423. ret.set_float(Math.log(x));
  12424. };
  12425. SysExps.prototype.log10 = function(ret, x)
  12426. {
  12427. ret.set_float(Math.log(x) / Math.LN10);
  12428. };
  12429. SysExps.prototype.max = function(ret)
  12430. {
  12431. var max_ = arguments[1];
  12432. if (typeof max_ !== "number")
  12433. max_ = 0;
  12434. var i, len, a;
  12435. for (i = 2, len = arguments.length; i < len; i++)
  12436. {
  12437. a = arguments[i];
  12438. if (typeof a !== "number")
  12439. continue; // ignore non-numeric types
  12440. if (max_ < a)
  12441. max_ = a;
  12442. }
  12443. ret.set_float(max_);
  12444. };
  12445. SysExps.prototype.min = function(ret)
  12446. {
  12447. var min_ = arguments[1];
  12448. if (typeof min_ !== "number")
  12449. min_ = 0;
  12450. var i, len, a;
  12451. for (i = 2, len = arguments.length; i < len; i++)
  12452. {
  12453. a = arguments[i];
  12454. if (typeof a !== "number")
  12455. continue; // ignore non-numeric types
  12456. if (min_ > a)
  12457. min_ = a;
  12458. }
  12459. ret.set_float(min_);
  12460. };
  12461. SysExps.prototype.dt = function(ret)
  12462. {
  12463. ret.set_float(this.runtime.dt);
  12464. };
  12465. SysExps.prototype.timescale = function(ret)
  12466. {
  12467. ret.set_float(this.runtime.timescale);
  12468. };
  12469. SysExps.prototype.wallclocktime = function(ret)
  12470. {
  12471. ret.set_float((Date.now() - this.runtime.start_time) / 1000.0);
  12472. };
  12473. SysExps.prototype.time = function(ret)
  12474. {
  12475. ret.set_float(this.runtime.kahanTime.sum);
  12476. };
  12477. SysExps.prototype.tickcount = function(ret)
  12478. {
  12479. ret.set_int(this.runtime.tickcount);
  12480. };
  12481. SysExps.prototype.objectcount = function(ret)
  12482. {
  12483. ret.set_int(this.runtime.objectcount);
  12484. };
  12485. SysExps.prototype.fps = function(ret)
  12486. {
  12487. ret.set_int(this.runtime.fps);
  12488. };
  12489. SysExps.prototype.loopindex = function(ret, name_)
  12490. {
  12491. var loop, i, len;
  12492. if (!this.runtime.loop_stack.length)
  12493. {
  12494. ret.set_int(0);
  12495. return;
  12496. }
  12497. if (name_)
  12498. {
  12499. for (i = 0, len = this.runtime.loop_stack.length; i < len; i++)
  12500. {
  12501. loop = this.runtime.loop_stack[i];
  12502. if (loop.name === name_)
  12503. {
  12504. ret.set_int(loop.index);
  12505. return;
  12506. }
  12507. }
  12508. ret.set_int(0);
  12509. }
  12510. else
  12511. {
  12512. loop = this.runtime.getCurrentLoop();
  12513. ret.set_int(loop ? loop.index : -1);
  12514. }
  12515. };
  12516. SysExps.prototype.distance = function(ret, x1, y1, x2, y2)
  12517. {
  12518. ret.set_float(cr.distanceTo(x1, y1, x2, y2));
  12519. };
  12520. SysExps.prototype.angle = function(ret, x1, y1, x2, y2)
  12521. {
  12522. ret.set_float(cr.to_degrees(cr.angleTo(x1, y1, x2, y2)));
  12523. };
  12524. SysExps.prototype.scrollx = function(ret)
  12525. {
  12526. ret.set_float(this.runtime.running_layout.scrollX);
  12527. };
  12528. SysExps.prototype.scrolly = function(ret)
  12529. {
  12530. ret.set_float(this.runtime.running_layout.scrollY);
  12531. };
  12532. SysExps.prototype.newline = function(ret)
  12533. {
  12534. ret.set_string("\n");
  12535. };
  12536. SysExps.prototype.lerp = function(ret, a, b, x)
  12537. {
  12538. ret.set_float(cr.lerp(a, b, x));
  12539. };
  12540. SysExps.prototype.qarp = function(ret, a, b, c, x)
  12541. {
  12542. ret.set_float(cr.qarp(a, b, c, x));
  12543. };
  12544. SysExps.prototype.cubic = function(ret, a, b, c, d, x)
  12545. {
  12546. ret.set_float(cr.cubic(a, b, c, d, x));
  12547. };
  12548. SysExps.prototype.cosp = function(ret, a, b, x)
  12549. {
  12550. ret.set_float(cr.cosp(a, b, x));
  12551. };
  12552. SysExps.prototype.windowwidth = function(ret)
  12553. {
  12554. ret.set_int(this.runtime.width);
  12555. };
  12556. SysExps.prototype.windowheight = function(ret)
  12557. {
  12558. ret.set_int(this.runtime.height);
  12559. };
  12560. SysExps.prototype.uppercase = function(ret, str)
  12561. {
  12562. ret.set_string(cr.is_string(str) ? str.toUpperCase() : "");
  12563. };
  12564. SysExps.prototype.lowercase = function(ret, str)
  12565. {
  12566. ret.set_string(cr.is_string(str) ? str.toLowerCase() : "");
  12567. };
  12568. SysExps.prototype.clamp = function(ret, x, l, u)
  12569. {
  12570. if (x < l)
  12571. ret.set_float(l);
  12572. else if (x > u)
  12573. ret.set_float(u);
  12574. else
  12575. ret.set_float(x);
  12576. };
  12577. SysExps.prototype.layerscale = function (ret, layerparam)
  12578. {
  12579. var layer = this.runtime.getLayer(layerparam);
  12580. if (!layer)
  12581. ret.set_float(0);
  12582. else
  12583. ret.set_float(layer.scale);
  12584. };
  12585. SysExps.prototype.layeropacity = function (ret, layerparam)
  12586. {
  12587. var layer = this.runtime.getLayer(layerparam);
  12588. if (!layer)
  12589. ret.set_float(0);
  12590. else
  12591. ret.set_float(layer.opacity * 100);
  12592. };
  12593. SysExps.prototype.layerscalerate = function (ret, layerparam)
  12594. {
  12595. var layer = this.runtime.getLayer(layerparam);
  12596. if (!layer)
  12597. ret.set_float(0);
  12598. else
  12599. ret.set_float(layer.zoomRate);
  12600. };
  12601. SysExps.prototype.layerparallaxx = function (ret, layerparam)
  12602. {
  12603. var layer = this.runtime.getLayer(layerparam);
  12604. if (!layer)
  12605. ret.set_float(0);
  12606. else
  12607. ret.set_float(layer.parallaxX * 100);
  12608. };
  12609. SysExps.prototype.layerparallaxy = function (ret, layerparam)
  12610. {
  12611. var layer = this.runtime.getLayer(layerparam);
  12612. if (!layer)
  12613. ret.set_float(0);
  12614. else
  12615. ret.set_float(layer.parallaxY * 100);
  12616. };
  12617. SysExps.prototype.layerindex = function (ret, layerparam)
  12618. {
  12619. var layer = this.runtime.getLayer(layerparam);
  12620. if (!layer)
  12621. ret.set_int(-1);
  12622. else
  12623. ret.set_int(layer.index);
  12624. };
  12625. SysExps.prototype.layoutscale = function (ret)
  12626. {
  12627. if (this.runtime.running_layout)
  12628. ret.set_float(this.runtime.running_layout.scale);
  12629. else
  12630. ret.set_float(0);
  12631. };
  12632. SysExps.prototype.layoutangle = function (ret)
  12633. {
  12634. ret.set_float(cr.to_degrees(this.runtime.running_layout.angle));
  12635. };
  12636. SysExps.prototype.layerangle = function (ret, layerparam)
  12637. {
  12638. var layer = this.runtime.getLayer(layerparam);
  12639. if (!layer)
  12640. ret.set_float(0);
  12641. else
  12642. ret.set_float(cr.to_degrees(layer.angle));
  12643. };
  12644. SysExps.prototype.layoutwidth = function (ret)
  12645. {
  12646. ret.set_int(this.runtime.running_layout.width);
  12647. };
  12648. SysExps.prototype.layoutheight = function (ret)
  12649. {
  12650. ret.set_int(this.runtime.running_layout.height);
  12651. };
  12652. SysExps.prototype.find = function (ret, text, searchstr)
  12653. {
  12654. if (cr.is_string(text) && cr.is_string(searchstr))
  12655. ret.set_int(text.search(new RegExp(cr.regexp_escape(searchstr), "i")));
  12656. else
  12657. ret.set_int(-1);
  12658. };
  12659. SysExps.prototype.left = function (ret, text, n)
  12660. {
  12661. ret.set_string(cr.is_string(text) ? text.substr(0, n) : "");
  12662. };
  12663. SysExps.prototype.right = function (ret, text, n)
  12664. {
  12665. ret.set_string(cr.is_string(text) ? text.substr(text.length - n) : "");
  12666. };
  12667. SysExps.prototype.mid = function (ret, text, index_, length_)
  12668. {
  12669. ret.set_string(cr.is_string(text) ? text.substr(index_, length_) : "");
  12670. };
  12671. SysExps.prototype.tokenat = function (ret, text, index_, sep)
  12672. {
  12673. if (cr.is_string(text) && cr.is_string(sep))
  12674. {
  12675. var arr = text.split(sep);
  12676. var i = cr.floor(index_);
  12677. if (i < 0 || i >= arr.length)
  12678. ret.set_string("");
  12679. else
  12680. ret.set_string(arr[i]);
  12681. }
  12682. else
  12683. ret.set_string("");
  12684. };
  12685. SysExps.prototype.tokencount = function (ret, text, sep)
  12686. {
  12687. if (cr.is_string(text) && text.length)
  12688. ret.set_int(text.split(sep).length);
  12689. else
  12690. ret.set_int(0);
  12691. };
  12692. SysExps.prototype.replace = function (ret, text, find_, replace_)
  12693. {
  12694. if (cr.is_string(text) && cr.is_string(find_) && cr.is_string(replace_))
  12695. ret.set_string(text.replace(new RegExp(cr.regexp_escape(find_), "gi"), replace_));
  12696. else
  12697. ret.set_string(cr.is_string(text) ? text : "");
  12698. };
  12699. SysExps.prototype.trim = function (ret, text)
  12700. {
  12701. ret.set_string(cr.is_string(text) ? text.trim() : "");
  12702. };
  12703. SysExps.prototype.pi = function (ret)
  12704. {
  12705. ret.set_float(cr.PI);
  12706. };
  12707. SysExps.prototype.layoutname = function (ret)
  12708. {
  12709. if (this.runtime.running_layout)
  12710. ret.set_string(this.runtime.running_layout.name);
  12711. else
  12712. ret.set_string("");
  12713. };
  12714. SysExps.prototype.renderer = function (ret)
  12715. {
  12716. ret.set_string(this.runtime.gl ? "webgl" : "canvas2d");
  12717. };
  12718. SysExps.prototype.rendererdetail = function (ret)
  12719. {
  12720. ret.set_string(this.runtime.glUnmaskedRenderer);
  12721. };
  12722. SysExps.prototype.anglediff = function (ret, a, b)
  12723. {
  12724. ret.set_float(cr.to_degrees(cr.angleDiff(cr.to_radians(a), cr.to_radians(b))));
  12725. };
  12726. SysExps.prototype.choose = function (ret)
  12727. {
  12728. var index = cr.floor(Math.random() * (arguments.length - 1));
  12729. ret.set_any(arguments[index + 1]);
  12730. };
  12731. SysExps.prototype.rgb = function (ret, r, g, b)
  12732. {
  12733. ret.set_int(cr.RGB(r, g, b));
  12734. };
  12735. SysExps.prototype.projectversion = function (ret)
  12736. {
  12737. ret.set_string(this.runtime.versionstr);
  12738. };
  12739. SysExps.prototype.projectname = function (ret)
  12740. {
  12741. ret.set_string(this.runtime.projectName);
  12742. };
  12743. SysExps.prototype.anglelerp = function (ret, a, b, x)
  12744. {
  12745. a = cr.to_radians(a);
  12746. b = cr.to_radians(b);
  12747. var diff = cr.angleDiff(a, b);
  12748. if (cr.angleClockwise(b, a))
  12749. {
  12750. ret.set_float(cr.to_clamped_degrees(a + diff * x));
  12751. }
  12752. else
  12753. {
  12754. ret.set_float(cr.to_clamped_degrees(a - diff * x));
  12755. }
  12756. };
  12757. SysExps.prototype.anglerotate = function (ret, a, b, c)
  12758. {
  12759. a = cr.to_radians(a);
  12760. b = cr.to_radians(b);
  12761. c = cr.to_radians(c);
  12762. ret.set_float(cr.to_clamped_degrees(cr.angleRotate(a, b, c)));
  12763. };
  12764. SysExps.prototype.zeropad = function (ret, n, d)
  12765. {
  12766. var s = (n < 0 ? "-" : "");
  12767. if (n < 0) n = -n;
  12768. var zeroes = d - n.toString().length;
  12769. for (var i = 0; i < zeroes; i++)
  12770. s += "0";
  12771. ret.set_string(s + n.toString());
  12772. };
  12773. SysExps.prototype.cpuutilisation = function (ret)
  12774. {
  12775. ret.set_float(this.runtime.cpuutilisation / 1000);
  12776. };
  12777. SysExps.prototype.viewportleft = function (ret, layerparam)
  12778. {
  12779. var layer = this.runtime.getLayer(layerparam);
  12780. ret.set_float(layer ? layer.viewLeft : 0);
  12781. };
  12782. SysExps.prototype.viewporttop = function (ret, layerparam)
  12783. {
  12784. var layer = this.runtime.getLayer(layerparam);
  12785. ret.set_float(layer ? layer.viewTop : 0);
  12786. };
  12787. SysExps.prototype.viewportright = function (ret, layerparam)
  12788. {
  12789. var layer = this.runtime.getLayer(layerparam);
  12790. ret.set_float(layer ? layer.viewRight : 0);
  12791. };
  12792. SysExps.prototype.viewportbottom = function (ret, layerparam)
  12793. {
  12794. var layer = this.runtime.getLayer(layerparam);
  12795. ret.set_float(layer ? layer.viewBottom : 0);
  12796. };
  12797. SysExps.prototype.loadingprogress = function (ret)
  12798. {
  12799. ret.set_float(this.runtime.loadingprogress);
  12800. };
  12801. SysExps.prototype.unlerp = function(ret, a, b, y)
  12802. {
  12803. ret.set_float(cr.unlerp(a, b, y));
  12804. };
  12805. SysExps.prototype.canvassnapshot = function (ret)
  12806. {
  12807. ret.set_string(this.runtime.snapshotData);
  12808. };
  12809. SysExps.prototype.urlencode = function (ret, s)
  12810. {
  12811. ret.set_string(encodeURIComponent(s));
  12812. };
  12813. SysExps.prototype.urldecode = function (ret, s)
  12814. {
  12815. ret.set_string(decodeURIComponent(s));
  12816. };
  12817. SysExps.prototype.canvastolayerx = function (ret, layerparam, x, y)
  12818. {
  12819. var layer = this.runtime.getLayer(layerparam);
  12820. ret.set_float(layer ? layer.canvasToLayer(x, y, true) : 0);
  12821. };
  12822. SysExps.prototype.canvastolayery = function (ret, layerparam, x, y)
  12823. {
  12824. var layer = this.runtime.getLayer(layerparam);
  12825. ret.set_float(layer ? layer.canvasToLayer(x, y, false) : 0);
  12826. };
  12827. SysExps.prototype.layertocanvasx = function (ret, layerparam, x, y)
  12828. {
  12829. var layer = this.runtime.getLayer(layerparam);
  12830. ret.set_float(layer ? layer.layerToCanvas(x, y, true) : 0);
  12831. };
  12832. SysExps.prototype.layertocanvasy = function (ret, layerparam, x, y)
  12833. {
  12834. var layer = this.runtime.getLayer(layerparam);
  12835. ret.set_float(layer ? layer.layerToCanvas(x, y, false) : 0);
  12836. };
  12837. SysExps.prototype.savestatejson = function (ret)
  12838. {
  12839. ret.set_string(this.runtime.lastSaveJson);
  12840. };
  12841. SysExps.prototype.imagememoryusage = function (ret)
  12842. {
  12843. if (this.runtime.glwrap)
  12844. ret.set_float(Math.round(100 * this.runtime.glwrap.estimateVRAM() / (1024 * 1024)) / 100);
  12845. else
  12846. ret.set_float(0);
  12847. };
  12848. SysExps.prototype.regexsearch = function (ret, str_, regex_, flags_)
  12849. {
  12850. var regex = getRegex(regex_, flags_);
  12851. ret.set_int(str_ ? str_.search(regex) : -1);
  12852. };
  12853. SysExps.prototype.regexreplace = function (ret, str_, regex_, flags_, replace_)
  12854. {
  12855. var regex = getRegex(regex_, flags_);
  12856. ret.set_string(str_ ? str_.replace(regex, replace_) : "");
  12857. };
  12858. var regexMatches = [];
  12859. var lastMatchesStr = "";
  12860. var lastMatchesRegex = "";
  12861. var lastMatchesFlags = "";
  12862. function updateRegexMatches(str_, regex_, flags_)
  12863. {
  12864. if (str_ === lastMatchesStr && regex_ === lastMatchesRegex && flags_ === lastMatchesFlags)
  12865. return;
  12866. var regex = getRegex(regex_, flags_);
  12867. regexMatches = str_.match(regex);
  12868. lastMatchesStr = str_;
  12869. lastMatchesRegex = regex_;
  12870. lastMatchesFlags = flags_;
  12871. };
  12872. SysExps.prototype.regexmatchcount = function (ret, str_, regex_, flags_)
  12873. {
  12874. var regex = getRegex(regex_, flags_);
  12875. updateRegexMatches(str_, regex_, flags_);
  12876. ret.set_int(regexMatches ? regexMatches.length : 0);
  12877. };
  12878. SysExps.prototype.regexmatchat = function (ret, str_, regex_, flags_, index_)
  12879. {
  12880. index_ = Math.floor(index_);
  12881. var regex = getRegex(regex_, flags_);
  12882. updateRegexMatches(str_, regex_, flags_);
  12883. if (!regexMatches || index_ < 0 || index_ >= regexMatches.length)
  12884. ret.set_string("");
  12885. else
  12886. ret.set_string(regexMatches[index_]);
  12887. };
  12888. SysExps.prototype.infinity = function (ret)
  12889. {
  12890. ret.set_float(Infinity);
  12891. };
  12892. SysExps.prototype.setbit = function (ret, n, b, v)
  12893. {
  12894. n = n | 0;
  12895. b = b | 0;
  12896. v = (v !== 0 ? 1 : 0);
  12897. ret.set_int((n & ~(1 << b)) | (v << b));
  12898. };
  12899. SysExps.prototype.togglebit = function (ret, n, b)
  12900. {
  12901. n = n | 0;
  12902. b = b | 0;
  12903. ret.set_int(n ^ (1 << b));
  12904. };
  12905. SysExps.prototype.getbit = function (ret, n, b)
  12906. {
  12907. n = n | 0;
  12908. b = b | 0;
  12909. ret.set_int((n & (1 << b)) ? 1 : 0);
  12910. };
  12911. SysExps.prototype.originalwindowwidth = function (ret)
  12912. {
  12913. ret.set_int(this.runtime.original_width);
  12914. };
  12915. SysExps.prototype.originalwindowheight = function (ret)
  12916. {
  12917. ret.set_int(this.runtime.original_height);
  12918. };
  12919. sysProto.exps = new SysExps();
  12920. sysProto.runWaits = function ()
  12921. {
  12922. var i, j, len, w, k, s, ss;
  12923. var evinfo = this.runtime.getCurrentEventStack();
  12924. for (i = 0, len = this.waits.length; i < len; i++)
  12925. {
  12926. w = this.waits[i];
  12927. if (w.time === -1) // signalled wait
  12928. {
  12929. if (!w.signalled)
  12930. continue; // not yet signalled
  12931. }
  12932. else // timer wait
  12933. {
  12934. if (w.time > this.runtime.kahanTime.sum)
  12935. continue; // timer not yet expired
  12936. }
  12937. evinfo.current_event = w.ev;
  12938. evinfo.actindex = w.actindex;
  12939. evinfo.cndindex = 0;
  12940. for (k in w.sols)
  12941. {
  12942. if (w.sols.hasOwnProperty(k))
  12943. {
  12944. s = this.runtime.types_by_index[parseInt(k, 10)].getCurrentSol();
  12945. ss = w.sols[k];
  12946. s.select_all = ss.sa;
  12947. cr.shallowAssignArray(s.instances, ss.insts);
  12948. freeSolStateObject(ss);
  12949. }
  12950. }
  12951. w.ev.resume_actions_and_subevents();
  12952. this.runtime.clearSol(w.solModifiers);
  12953. w.deleteme = true;
  12954. }
  12955. for (i = 0, j = 0, len = this.waits.length; i < len; i++)
  12956. {
  12957. w = this.waits[i];
  12958. this.waits[j] = w;
  12959. if (w.deleteme)
  12960. freeWaitObject(w);
  12961. else
  12962. j++;
  12963. }
  12964. cr.truncateArray(this.waits, j);
  12965. };
  12966. }());
  12967. ;
  12968. (function () {
  12969. cr.add_common_aces = function (m, pluginProto)
  12970. {
  12971. var singleglobal_ = m[1];
  12972. var position_aces = m[3];
  12973. var size_aces = m[4];
  12974. var angle_aces = m[5];
  12975. var appearance_aces = m[6];
  12976. var zorder_aces = m[7];
  12977. var effects_aces = m[8];
  12978. if (!pluginProto.cnds)
  12979. pluginProto.cnds = {};
  12980. if (!pluginProto.acts)
  12981. pluginProto.acts = {};
  12982. if (!pluginProto.exps)
  12983. pluginProto.exps = {};
  12984. var cnds = pluginProto.cnds;
  12985. var acts = pluginProto.acts;
  12986. var exps = pluginProto.exps;
  12987. if (position_aces)
  12988. {
  12989. cnds.CompareX = function (cmp, x)
  12990. {
  12991. return cr.do_cmp(this.x, cmp, x);
  12992. };
  12993. cnds.CompareY = function (cmp, y)
  12994. {
  12995. return cr.do_cmp(this.y, cmp, y);
  12996. };
  12997. cnds.IsOnScreen = function ()
  12998. {
  12999. var layer = this.layer;
  13000. this.update_bbox();
  13001. var bbox = this.bbox;
  13002. return !(bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom);
  13003. };
  13004. cnds.IsOutsideLayout = function ()
  13005. {
  13006. this.update_bbox();
  13007. var bbox = this.bbox;
  13008. var layout = this.runtime.running_layout;
  13009. return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height);
  13010. };
  13011. cnds.PickDistance = function (which, x, y)
  13012. {
  13013. var sol = this.getCurrentSol();
  13014. var instances = sol.getObjects();
  13015. if (!instances.length)
  13016. return false;
  13017. var inst = instances[0];
  13018. var pickme = inst;
  13019. var dist = cr.distanceTo(inst.x, inst.y, x, y);
  13020. var i, len, d;
  13021. for (i = 1, len = instances.length; i < len; i++)
  13022. {
  13023. inst = instances[i];
  13024. d = cr.distanceTo(inst.x, inst.y, x, y);
  13025. if ((which === 0 && d < dist) || (which === 1 && d > dist))
  13026. {
  13027. dist = d;
  13028. pickme = inst;
  13029. }
  13030. }
  13031. sol.pick_one(pickme);
  13032. return true;
  13033. };
  13034. acts.SetX = function (x)
  13035. {
  13036. if (this.x !== x)
  13037. {
  13038. this.x = x;
  13039. this.set_bbox_changed();
  13040. }
  13041. };
  13042. acts.SetY = function (y)
  13043. {
  13044. if (this.y !== y)
  13045. {
  13046. this.y = y;
  13047. this.set_bbox_changed();
  13048. }
  13049. };
  13050. acts.SetPos = function (x, y)
  13051. {
  13052. if (this.x !== x || this.y !== y)
  13053. {
  13054. this.x = x;
  13055. this.y = y;
  13056. this.set_bbox_changed();
  13057. }
  13058. };
  13059. acts.SetPosToObject = function (obj, imgpt)
  13060. {
  13061. var inst = obj.getPairedInstance(this);
  13062. if (!inst)
  13063. return;
  13064. var newx, newy;
  13065. if (inst.getImagePoint)
  13066. {
  13067. newx = inst.getImagePoint(imgpt, true);
  13068. newy = inst.getImagePoint(imgpt, false);
  13069. }
  13070. else
  13071. {
  13072. newx = inst.x;
  13073. newy = inst.y;
  13074. }
  13075. if (this.x !== newx || this.y !== newy)
  13076. {
  13077. this.x = newx;
  13078. this.y = newy;
  13079. this.set_bbox_changed();
  13080. }
  13081. };
  13082. acts.MoveForward = function (dist)
  13083. {
  13084. if (dist !== 0)
  13085. {
  13086. this.x += Math.cos(this.angle) * dist;
  13087. this.y += Math.sin(this.angle) * dist;
  13088. this.set_bbox_changed();
  13089. }
  13090. };
  13091. acts.MoveAtAngle = function (a, dist)
  13092. {
  13093. if (dist !== 0)
  13094. {
  13095. this.x += Math.cos(cr.to_radians(a)) * dist;
  13096. this.y += Math.sin(cr.to_radians(a)) * dist;
  13097. this.set_bbox_changed();
  13098. }
  13099. };
  13100. exps.X = function (ret)
  13101. {
  13102. ret.set_float(this.x);
  13103. };
  13104. exps.Y = function (ret)
  13105. {
  13106. ret.set_float(this.y);
  13107. };
  13108. exps.dt = function (ret)
  13109. {
  13110. ret.set_float(this.runtime.getDt(this));
  13111. };
  13112. }
  13113. if (size_aces)
  13114. {
  13115. cnds.CompareWidth = function (cmp, w)
  13116. {
  13117. return cr.do_cmp(this.width, cmp, w);
  13118. };
  13119. cnds.CompareHeight = function (cmp, h)
  13120. {
  13121. return cr.do_cmp(this.height, cmp, h);
  13122. };
  13123. acts.SetWidth = function (w)
  13124. {
  13125. if (this.width !== w)
  13126. {
  13127. this.width = w;
  13128. this.set_bbox_changed();
  13129. }
  13130. };
  13131. acts.SetHeight = function (h)
  13132. {
  13133. if (this.height !== h)
  13134. {
  13135. this.height = h;
  13136. this.set_bbox_changed();
  13137. }
  13138. };
  13139. acts.SetSize = function (w, h)
  13140. {
  13141. if (this.width !== w || this.height !== h)
  13142. {
  13143. this.width = w;
  13144. this.height = h;
  13145. this.set_bbox_changed();
  13146. }
  13147. };
  13148. exps.Width = function (ret)
  13149. {
  13150. ret.set_float(this.width);
  13151. };
  13152. exps.Height = function (ret)
  13153. {
  13154. ret.set_float(this.height);
  13155. };
  13156. exps.BBoxLeft = function (ret)
  13157. {
  13158. this.update_bbox();
  13159. ret.set_float(this.bbox.left);
  13160. };
  13161. exps.BBoxTop = function (ret)
  13162. {
  13163. this.update_bbox();
  13164. ret.set_float(this.bbox.top);
  13165. };
  13166. exps.BBoxRight = function (ret)
  13167. {
  13168. this.update_bbox();
  13169. ret.set_float(this.bbox.right);
  13170. };
  13171. exps.BBoxBottom = function (ret)
  13172. {
  13173. this.update_bbox();
  13174. ret.set_float(this.bbox.bottom);
  13175. };
  13176. }
  13177. if (angle_aces)
  13178. {
  13179. cnds.AngleWithin = function (within, a)
  13180. {
  13181. return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within);
  13182. };
  13183. cnds.IsClockwiseFrom = function (a)
  13184. {
  13185. return cr.angleClockwise(this.angle, cr.to_radians(a));
  13186. };
  13187. cnds.IsBetweenAngles = function (a, b)
  13188. {
  13189. var lower = cr.to_clamped_radians(a);
  13190. var upper = cr.to_clamped_radians(b);
  13191. var angle = cr.clamp_angle(this.angle);
  13192. var obtuse = (!cr.angleClockwise(upper, lower));
  13193. if (obtuse)
  13194. return !(!cr.angleClockwise(angle, lower) && cr.angleClockwise(angle, upper));
  13195. else
  13196. return cr.angleClockwise(angle, lower) && !cr.angleClockwise(angle, upper);
  13197. };
  13198. acts.SetAngle = function (a)
  13199. {
  13200. var newangle = cr.to_radians(cr.clamp_angle_degrees(a));
  13201. if (isNaN(newangle))
  13202. return;
  13203. if (this.angle !== newangle)
  13204. {
  13205. this.angle = newangle;
  13206. this.set_bbox_changed();
  13207. }
  13208. };
  13209. acts.RotateClockwise = function (a)
  13210. {
  13211. if (a !== 0 && !isNaN(a))
  13212. {
  13213. this.angle += cr.to_radians(a);
  13214. this.angle = cr.clamp_angle(this.angle);
  13215. this.set_bbox_changed();
  13216. }
  13217. };
  13218. acts.RotateCounterclockwise = function (a)
  13219. {
  13220. if (a !== 0 && !isNaN(a))
  13221. {
  13222. this.angle -= cr.to_radians(a);
  13223. this.angle = cr.clamp_angle(this.angle);
  13224. this.set_bbox_changed();
  13225. }
  13226. };
  13227. acts.RotateTowardAngle = function (amt, target)
  13228. {
  13229. var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt));
  13230. if (isNaN(newangle))
  13231. return;
  13232. if (this.angle !== newangle)
  13233. {
  13234. this.angle = newangle;
  13235. this.set_bbox_changed();
  13236. }
  13237. };
  13238. acts.RotateTowardPosition = function (amt, x, y)
  13239. {
  13240. var dx = x - this.x;
  13241. var dy = y - this.y;
  13242. var target = Math.atan2(dy, dx);
  13243. var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt));
  13244. if (isNaN(newangle))
  13245. return;
  13246. if (this.angle !== newangle)
  13247. {
  13248. this.angle = newangle;
  13249. this.set_bbox_changed();
  13250. }
  13251. };
  13252. acts.SetTowardPosition = function (x, y)
  13253. {
  13254. var dx = x - this.x;
  13255. var dy = y - this.y;
  13256. var newangle = Math.atan2(dy, dx);
  13257. if (isNaN(newangle))
  13258. return;
  13259. if (this.angle !== newangle)
  13260. {
  13261. this.angle = newangle;
  13262. this.set_bbox_changed();
  13263. }
  13264. };
  13265. exps.Angle = function (ret)
  13266. {
  13267. ret.set_float(cr.to_clamped_degrees(this.angle));
  13268. };
  13269. }
  13270. if (!singleglobal_)
  13271. {
  13272. cnds.CompareInstanceVar = function (iv, cmp, val)
  13273. {
  13274. return cr.do_cmp(this.instance_vars[iv], cmp, val);
  13275. };
  13276. cnds.IsBoolInstanceVarSet = function (iv)
  13277. {
  13278. return this.instance_vars[iv];
  13279. };
  13280. cnds.PickInstVarHiLow = function (which, iv)
  13281. {
  13282. var sol = this.getCurrentSol();
  13283. var instances = sol.getObjects();
  13284. if (!instances.length)
  13285. return false;
  13286. var inst = instances[0];
  13287. var pickme = inst;
  13288. var val = inst.instance_vars[iv];
  13289. var i, len, v;
  13290. for (i = 1, len = instances.length; i < len; i++)
  13291. {
  13292. inst = instances[i];
  13293. v = inst.instance_vars[iv];
  13294. if ((which === 0 && v < val) || (which === 1 && v > val))
  13295. {
  13296. val = v;
  13297. pickme = inst;
  13298. }
  13299. }
  13300. sol.pick_one(pickme);
  13301. return true;
  13302. };
  13303. cnds.PickByUID = function (u)
  13304. {
  13305. var i, len, j, inst, families, instances, sol;
  13306. var cnd = this.runtime.getCurrentCondition();
  13307. if (cnd.inverted)
  13308. {
  13309. sol = this.getCurrentSol();
  13310. if (sol.select_all)
  13311. {
  13312. sol.select_all = false;
  13313. cr.clearArray(sol.instances);
  13314. cr.clearArray(sol.else_instances);
  13315. instances = this.instances;
  13316. for (i = 0, len = instances.length; i < len; i++)
  13317. {
  13318. inst = instances[i];
  13319. if (inst.uid === u)
  13320. sol.else_instances.push(inst);
  13321. else
  13322. sol.instances.push(inst);
  13323. }
  13324. this.applySolToContainer();
  13325. return !!sol.instances.length;
  13326. }
  13327. else
  13328. {
  13329. for (i = 0, j = 0, len = sol.instances.length; i < len; i++)
  13330. {
  13331. inst = sol.instances[i];
  13332. sol.instances[j] = inst;
  13333. if (inst.uid === u)
  13334. {
  13335. sol.else_instances.push(inst);
  13336. }
  13337. else
  13338. j++;
  13339. }
  13340. cr.truncateArray(sol.instances, j);
  13341. this.applySolToContainer();
  13342. return !!sol.instances.length;
  13343. }
  13344. }
  13345. else
  13346. {
  13347. inst = this.runtime.getObjectByUID(u);
  13348. if (!inst)
  13349. return false;
  13350. sol = this.getCurrentSol();
  13351. if (!sol.select_all && sol.instances.indexOf(inst) === -1)
  13352. return false; // not picked
  13353. if (this.is_family)
  13354. {
  13355. families = inst.type.families;
  13356. for (i = 0, len = families.length; i < len; i++)
  13357. {
  13358. if (families[i] === this)
  13359. {
  13360. sol.pick_one(inst);
  13361. this.applySolToContainer();
  13362. return true;
  13363. }
  13364. }
  13365. }
  13366. else if (inst.type === this)
  13367. {
  13368. sol.pick_one(inst);
  13369. this.applySolToContainer();
  13370. return true;
  13371. }
  13372. return false;
  13373. }
  13374. };
  13375. cnds.OnCreated = function ()
  13376. {
  13377. return true;
  13378. };
  13379. cnds.OnDestroyed = function ()
  13380. {
  13381. return true;
  13382. };
  13383. acts.SetInstanceVar = function (iv, val)
  13384. {
  13385. var myinstvars = this.instance_vars;
  13386. if (cr.is_number(myinstvars[iv]))
  13387. {
  13388. if (cr.is_number(val))
  13389. myinstvars[iv] = val;
  13390. else
  13391. myinstvars[iv] = parseFloat(val);
  13392. }
  13393. else if (cr.is_string(myinstvars[iv]))
  13394. {
  13395. if (cr.is_string(val))
  13396. myinstvars[iv] = val;
  13397. else
  13398. myinstvars[iv] = val.toString();
  13399. }
  13400. else
  13401. ;
  13402. };
  13403. acts.AddInstanceVar = function (iv, val)
  13404. {
  13405. var myinstvars = this.instance_vars;
  13406. if (cr.is_number(myinstvars[iv]))
  13407. {
  13408. if (cr.is_number(val))
  13409. myinstvars[iv] += val;
  13410. else
  13411. myinstvars[iv] += parseFloat(val);
  13412. }
  13413. else if (cr.is_string(myinstvars[iv]))
  13414. {
  13415. if (cr.is_string(val))
  13416. myinstvars[iv] += val;
  13417. else
  13418. myinstvars[iv] += val.toString();
  13419. }
  13420. else
  13421. ;
  13422. };
  13423. acts.SubInstanceVar = function (iv, val)
  13424. {
  13425. var myinstvars = this.instance_vars;
  13426. if (cr.is_number(myinstvars[iv]))
  13427. {
  13428. if (cr.is_number(val))
  13429. myinstvars[iv] -= val;
  13430. else
  13431. myinstvars[iv] -= parseFloat(val);
  13432. }
  13433. else
  13434. ;
  13435. };
  13436. acts.SetBoolInstanceVar = function (iv, val)
  13437. {
  13438. this.instance_vars[iv] = val ? 1 : 0;
  13439. };
  13440. acts.ToggleBoolInstanceVar = function (iv)
  13441. {
  13442. this.instance_vars[iv] = 1 - this.instance_vars[iv];
  13443. };
  13444. acts.Destroy = function ()
  13445. {
  13446. this.runtime.DestroyInstance(this);
  13447. };
  13448. if (!acts.LoadFromJsonString)
  13449. {
  13450. acts.LoadFromJsonString = function (str_)
  13451. {
  13452. var o, i, len, binst;
  13453. try {
  13454. o = JSON.parse(str_);
  13455. }
  13456. catch (e) {
  13457. return;
  13458. }
  13459. this.runtime.loadInstanceFromJSON(this, o, true);
  13460. if (this.afterLoad)
  13461. this.afterLoad();
  13462. if (this.behavior_insts)
  13463. {
  13464. for (i = 0, len = this.behavior_insts.length; i < len; ++i)
  13465. {
  13466. binst = this.behavior_insts[i];
  13467. if (binst.afterLoad)
  13468. binst.afterLoad();
  13469. }
  13470. }
  13471. };
  13472. }
  13473. exps.Count = function (ret)
  13474. {
  13475. var count = ret.object_class.instances.length;
  13476. var i, len, inst;
  13477. for (i = 0, len = this.runtime.createRow.length; i < len; i++)
  13478. {
  13479. inst = this.runtime.createRow[i];
  13480. if (ret.object_class.is_family)
  13481. {
  13482. if (inst.type.families.indexOf(ret.object_class) >= 0)
  13483. count++;
  13484. }
  13485. else
  13486. {
  13487. if (inst.type === ret.object_class)
  13488. count++;
  13489. }
  13490. }
  13491. ret.set_int(count);
  13492. };
  13493. exps.PickedCount = function (ret)
  13494. {
  13495. ret.set_int(ret.object_class.getCurrentSol().getObjects().length);
  13496. };
  13497. exps.UID = function (ret)
  13498. {
  13499. ret.set_int(this.uid);
  13500. };
  13501. exps.IID = function (ret)
  13502. {
  13503. ret.set_int(this.get_iid());
  13504. };
  13505. if (!exps.AsJSON)
  13506. {
  13507. exps.AsJSON = function (ret)
  13508. {
  13509. ret.set_string(JSON.stringify(this.runtime.saveInstanceToJSON(this, true)));
  13510. };
  13511. }
  13512. }
  13513. if (appearance_aces)
  13514. {
  13515. cnds.IsVisible = function ()
  13516. {
  13517. return this.visible;
  13518. };
  13519. acts.SetVisible = function (v)
  13520. {
  13521. if (!v !== !this.visible)
  13522. {
  13523. this.visible = v;
  13524. this.runtime.redraw = true;
  13525. }
  13526. };
  13527. cnds.CompareOpacity = function (cmp, x)
  13528. {
  13529. return cr.do_cmp(cr.round6dp(this.opacity * 100), cmp, x);
  13530. };
  13531. acts.SetOpacity = function (x)
  13532. {
  13533. var new_opacity = x / 100.0;
  13534. if (new_opacity < 0)
  13535. new_opacity = 0;
  13536. else if (new_opacity > 1)
  13537. new_opacity = 1;
  13538. if (new_opacity !== this.opacity)
  13539. {
  13540. this.opacity = new_opacity;
  13541. this.runtime.redraw = true;
  13542. }
  13543. };
  13544. exps.Opacity = function (ret)
  13545. {
  13546. ret.set_float(cr.round6dp(this.opacity * 100.0));
  13547. };
  13548. }
  13549. if (zorder_aces)
  13550. {
  13551. cnds.IsOnLayer = function (layer_)
  13552. {
  13553. if (!layer_)
  13554. return false;
  13555. return this.layer === layer_;
  13556. };
  13557. cnds.PickTopBottom = function (which_)
  13558. {
  13559. var sol = this.getCurrentSol();
  13560. var instances = sol.getObjects();
  13561. if (!instances.length)
  13562. return false;
  13563. var inst = instances[0];
  13564. var pickme = inst;
  13565. var i, len;
  13566. for (i = 1, len = instances.length; i < len; i++)
  13567. {
  13568. inst = instances[i];
  13569. if (which_ === 0)
  13570. {
  13571. if (inst.layer.index > pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() > pickme.get_zindex()))
  13572. {
  13573. pickme = inst;
  13574. }
  13575. }
  13576. else
  13577. {
  13578. if (inst.layer.index < pickme.layer.index || (inst.layer.index === pickme.layer.index && inst.get_zindex() < pickme.get_zindex()))
  13579. {
  13580. pickme = inst;
  13581. }
  13582. }
  13583. }
  13584. sol.pick_one(pickme);
  13585. return true;
  13586. };
  13587. acts.MoveToTop = function ()
  13588. {
  13589. var layer = this.layer;
  13590. var layer_instances = layer.instances;
  13591. if (layer_instances.length && layer_instances[layer_instances.length - 1] === this)
  13592. return; // is already at top
  13593. layer.removeFromInstanceList(this, false);
  13594. layer.appendToInstanceList(this, false);
  13595. this.runtime.redraw = true;
  13596. };
  13597. acts.MoveToBottom = function ()
  13598. {
  13599. var layer = this.layer;
  13600. var layer_instances = layer.instances;
  13601. if (layer_instances.length && layer_instances[0] === this)
  13602. return; // is already at bottom
  13603. layer.removeFromInstanceList(this, false);
  13604. layer.prependToInstanceList(this, false);
  13605. this.runtime.redraw = true;
  13606. };
  13607. acts.MoveToLayer = function (layerMove)
  13608. {
  13609. if (!layerMove || layerMove == this.layer)
  13610. return;
  13611. this.layer.removeFromInstanceList(this, true);
  13612. this.layer = layerMove;
  13613. layerMove.appendToInstanceList(this, true);
  13614. this.runtime.redraw = true;
  13615. };
  13616. acts.ZMoveToObject = function (where_, obj_)
  13617. {
  13618. var isafter = (where_ === 0);
  13619. if (!obj_)
  13620. return;
  13621. var other = obj_.getFirstPicked(this);
  13622. if (!other || other.uid === this.uid)
  13623. return;
  13624. if (this.layer.index !== other.layer.index)
  13625. {
  13626. this.layer.removeFromInstanceList(this, true);
  13627. this.layer = other.layer;
  13628. other.layer.appendToInstanceList(this, true);
  13629. }
  13630. this.layer.moveInstanceAdjacent(this, other, isafter);
  13631. this.runtime.redraw = true;
  13632. };
  13633. exps.LayerNumber = function (ret)
  13634. {
  13635. ret.set_int(this.layer.number);
  13636. };
  13637. exps.LayerName = function (ret)
  13638. {
  13639. ret.set_string(this.layer.name);
  13640. };
  13641. exps.ZIndex = function (ret)
  13642. {
  13643. ret.set_int(this.get_zindex());
  13644. };
  13645. }
  13646. if (effects_aces)
  13647. {
  13648. acts.SetEffectEnabled = function (enable_, effectname_)
  13649. {
  13650. if (!this.runtime.glwrap)
  13651. return;
  13652. var i = this.type.getEffectIndexByName(effectname_);
  13653. if (i < 0)
  13654. return; // effect name not found
  13655. var enable = (enable_ === 1);
  13656. if (this.active_effect_flags[i] === enable)
  13657. return; // no change
  13658. this.active_effect_flags[i] = enable;
  13659. this.updateActiveEffects();
  13660. this.runtime.redraw = true;
  13661. };
  13662. acts.SetEffectParam = function (effectname_, index_, value_)
  13663. {
  13664. if (!this.runtime.glwrap)
  13665. return;
  13666. var i = this.type.getEffectIndexByName(effectname_);
  13667. if (i < 0)
  13668. return; // effect name not found
  13669. var et = this.type.effect_types[i];
  13670. var params = this.effect_params[i];
  13671. index_ = Math.floor(index_);
  13672. if (index_ < 0 || index_ >= params.length)
  13673. return; // effect index out of bounds
  13674. if (this.runtime.glwrap.getProgramParameterType(et.shaderindex, index_) === 1)
  13675. value_ /= 100.0;
  13676. if (params[index_] === value_)
  13677. return; // no change
  13678. params[index_] = value_;
  13679. if (et.active)
  13680. this.runtime.redraw = true;
  13681. };
  13682. }
  13683. };
  13684. cr.set_bbox_changed = function ()
  13685. {
  13686. this.bbox_changed = true; // will recreate next time box requested
  13687. this.cell_changed = true;
  13688. this.type.any_cell_changed = true; // avoid unnecessary updateAllBBox() calls
  13689. this.runtime.redraw = true; // assume runtime needs to redraw
  13690. var i, len, callbacks = this.bbox_changed_callbacks;
  13691. for (i = 0, len = callbacks.length; i < len; ++i)
  13692. {
  13693. callbacks[i](this);
  13694. }
  13695. if (this.layer.useRenderCells)
  13696. this.update_bbox();
  13697. };
  13698. cr.add_bbox_changed_callback = function (f)
  13699. {
  13700. if (f)
  13701. {
  13702. this.bbox_changed_callbacks.push(f);
  13703. }
  13704. };
  13705. cr.update_bbox = function ()
  13706. {
  13707. if (!this.bbox_changed)
  13708. return; // bounding box not changed
  13709. var bbox = this.bbox;
  13710. var bquad = this.bquad;
  13711. bbox.set(this.x, this.y, this.x + this.width, this.y + this.height);
  13712. bbox.offset(-this.hotspotX * this.width, -this.hotspotY * this.height);
  13713. if (!this.angle)
  13714. {
  13715. bquad.set_from_rect(bbox); // make bounding quad from box
  13716. }
  13717. else
  13718. {
  13719. bbox.offset(-this.x, -this.y); // translate to origin
  13720. bquad.set_from_rotated_rect(bbox, this.angle); // rotate around origin
  13721. bquad.offset(this.x, this.y); // translate back to original position
  13722. bquad.bounding_box(bbox);
  13723. }
  13724. bbox.normalize();
  13725. this.bbox_changed = false; // bounding box up to date
  13726. this.update_render_cell();
  13727. };
  13728. var tmprc = new cr.rect(0, 0, 0, 0);
  13729. cr.update_render_cell = function ()
  13730. {
  13731. if (!this.layer.useRenderCells)
  13732. return;
  13733. var mygrid = this.layer.render_grid;
  13734. var bbox = this.bbox;
  13735. tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
  13736. if (this.rendercells.equals(tmprc))
  13737. return;
  13738. if (this.rendercells.right < this.rendercells.left)
  13739. mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
  13740. else
  13741. mygrid.update(this, this.rendercells, tmprc);
  13742. this.rendercells.copy(tmprc);
  13743. this.layer.render_list_stale = true;
  13744. };
  13745. cr.update_collision_cell = function ()
  13746. {
  13747. if (!this.cell_changed || !this.collisionsEnabled)
  13748. return;
  13749. this.update_bbox();
  13750. var mygrid = this.type.collision_grid;
  13751. var bbox = this.bbox;
  13752. tmprc.set(mygrid.XToCell(bbox.left), mygrid.YToCell(bbox.top), mygrid.XToCell(bbox.right), mygrid.YToCell(bbox.bottom));
  13753. if (this.collcells.equals(tmprc))
  13754. return;
  13755. if (this.collcells.right < this.collcells.left)
  13756. mygrid.update(this, null, tmprc); // first insertion with invalid rect: don't provide old range
  13757. else
  13758. mygrid.update(this, this.collcells, tmprc);
  13759. this.collcells.copy(tmprc);
  13760. this.cell_changed = false;
  13761. };
  13762. cr.inst_contains_pt = function (x, y)
  13763. {
  13764. if (!this.bbox.contains_pt(x, y))
  13765. return false;
  13766. if (!this.bquad.contains_pt(x, y))
  13767. return false;
  13768. if (this.collision_poly && !this.collision_poly.is_empty())
  13769. {
  13770. this.collision_poly.cache_poly(this.width, this.height, this.angle);
  13771. return this.collision_poly.contains_pt(x - this.x, y - this.y);
  13772. }
  13773. else
  13774. return true;
  13775. };
  13776. cr.inst_get_iid = function ()
  13777. {
  13778. this.type.updateIIDs();
  13779. return this.iid;
  13780. };
  13781. cr.inst_get_zindex = function ()
  13782. {
  13783. this.layer.updateZIndices();
  13784. return this.zindex;
  13785. };
  13786. cr.inst_updateActiveEffects = function ()
  13787. {
  13788. cr.clearArray(this.active_effect_types);
  13789. var i, len, et, inst;
  13790. for (i = 0, len = this.active_effect_flags.length; i < len; i++)
  13791. {
  13792. if (this.active_effect_flags[i])
  13793. this.active_effect_types.push(this.type.effect_types[i]);
  13794. }
  13795. this.uses_shaders = !!this.active_effect_types.length;
  13796. };
  13797. cr.inst_toString = function ()
  13798. {
  13799. return "Inst" + this.puid;
  13800. };
  13801. cr.type_getFirstPicked = function (frominst)
  13802. {
  13803. if (frominst && frominst.is_contained && frominst.type != this)
  13804. {
  13805. var i, len, s;
  13806. for (i = 0, len = frominst.siblings.length; i < len; i++)
  13807. {
  13808. s = frominst.siblings[i];
  13809. if (s.type == this)
  13810. return s;
  13811. }
  13812. }
  13813. var instances = this.getCurrentSol().getObjects();
  13814. if (instances.length)
  13815. return instances[0];
  13816. else
  13817. return null;
  13818. };
  13819. cr.type_getPairedInstance = function (inst)
  13820. {
  13821. var instances = this.getCurrentSol().getObjects();
  13822. if (instances.length)
  13823. return instances[inst.get_iid() % instances.length];
  13824. else
  13825. return null;
  13826. };
  13827. cr.type_updateIIDs = function ()
  13828. {
  13829. if (!this.stale_iids || this.is_family)
  13830. return; // up to date or is family - don't want family to overwrite IIDs
  13831. var i, len;
  13832. for (i = 0, len = this.instances.length; i < len; i++)
  13833. this.instances[i].iid = i;
  13834. var next_iid = i;
  13835. var createRow = this.runtime.createRow;
  13836. for (i = 0, len = createRow.length; i < len; ++i)
  13837. {
  13838. if (createRow[i].type === this)
  13839. createRow[i].iid = next_iid++;
  13840. }
  13841. this.stale_iids = false;
  13842. };
  13843. cr.type_getInstanceByIID = function (i)
  13844. {
  13845. if (i < this.instances.length)
  13846. return this.instances[i];
  13847. i -= this.instances.length;
  13848. var createRow = this.runtime.createRow;
  13849. var j, lenj;
  13850. for (j = 0, lenj = createRow.length; j < lenj; ++j)
  13851. {
  13852. if (createRow[j].type === this)
  13853. {
  13854. if (i === 0)
  13855. return createRow[j];
  13856. --i;
  13857. }
  13858. }
  13859. ;
  13860. return null;
  13861. };
  13862. cr.type_getCurrentSol = function ()
  13863. {
  13864. return this.solstack[this.cur_sol];
  13865. };
  13866. cr.type_pushCleanSol = function ()
  13867. {
  13868. this.cur_sol++;
  13869. if (this.cur_sol === this.solstack.length)
  13870. this.solstack.push(new cr.selection(this));
  13871. else
  13872. this.solstack[this.cur_sol].select_all = true; // else clear next SOL
  13873. };
  13874. cr.type_pushCopySol = function ()
  13875. {
  13876. this.cur_sol++;
  13877. if (this.cur_sol === this.solstack.length)
  13878. this.solstack.push(new cr.selection(this));
  13879. var clonesol = this.solstack[this.cur_sol];
  13880. var prevsol = this.solstack[this.cur_sol - 1];
  13881. if (prevsol.select_all)
  13882. clonesol.select_all = true;
  13883. else
  13884. {
  13885. clonesol.select_all = false;
  13886. cr.shallowAssignArray(clonesol.instances, prevsol.instances);
  13887. cr.shallowAssignArray(clonesol.else_instances, prevsol.else_instances);
  13888. }
  13889. };
  13890. cr.type_popSol = function ()
  13891. {
  13892. ;
  13893. this.cur_sol--;
  13894. };
  13895. cr.type_getBehaviorByName = function (behname)
  13896. {
  13897. var i, len, j, lenj, f, index = 0;
  13898. if (!this.is_family)
  13899. {
  13900. for (i = 0, len = this.families.length; i < len; i++)
  13901. {
  13902. f = this.families[i];
  13903. for (j = 0, lenj = f.behaviors.length; j < lenj; j++)
  13904. {
  13905. if (behname === f.behaviors[j].name)
  13906. {
  13907. this.extra["lastBehIndex"] = index;
  13908. return f.behaviors[j];
  13909. }
  13910. index++;
  13911. }
  13912. }
  13913. }
  13914. for (i = 0, len = this.behaviors.length; i < len; i++) {
  13915. if (behname === this.behaviors[i].name)
  13916. {
  13917. this.extra["lastBehIndex"] = index;
  13918. return this.behaviors[i];
  13919. }
  13920. index++;
  13921. }
  13922. return null;
  13923. };
  13924. cr.type_getBehaviorIndexByName = function (behname)
  13925. {
  13926. var b = this.getBehaviorByName(behname);
  13927. if (b)
  13928. return this.extra["lastBehIndex"];
  13929. else
  13930. return -1;
  13931. };
  13932. cr.type_getEffectIndexByName = function (name_)
  13933. {
  13934. var i, len;
  13935. for (i = 0, len = this.effect_types.length; i < len; i++)
  13936. {
  13937. if (this.effect_types[i].name === name_)
  13938. return i;
  13939. }
  13940. return -1;
  13941. };
  13942. cr.type_applySolToContainer = function ()
  13943. {
  13944. if (!this.is_contained || this.is_family)
  13945. return;
  13946. var i, len, j, lenj, t, sol, sol2;
  13947. this.updateIIDs();
  13948. sol = this.getCurrentSol();
  13949. var select_all = sol.select_all;
  13950. var es = this.runtime.getCurrentEventStack();
  13951. var orblock = es && es.current_event && es.current_event.orblock;
  13952. for (i = 0, len = this.container.length; i < len; i++)
  13953. {
  13954. t = this.container[i];
  13955. if (t === this)
  13956. continue;
  13957. t.updateIIDs();
  13958. sol2 = t.getCurrentSol();
  13959. sol2.select_all = select_all;
  13960. if (!select_all)
  13961. {
  13962. cr.clearArray(sol2.instances);
  13963. for (j = 0, lenj = sol.instances.length; j < lenj; ++j)
  13964. sol2.instances[j] = t.getInstanceByIID(sol.instances[j].iid);
  13965. if (orblock)
  13966. {
  13967. cr.clearArray(sol2.else_instances);
  13968. for (j = 0, lenj = sol.else_instances.length; j < lenj; ++j)
  13969. sol2.else_instances[j] = t.getInstanceByIID(sol.else_instances[j].iid);
  13970. }
  13971. }
  13972. }
  13973. };
  13974. cr.type_toString = function ()
  13975. {
  13976. return "Type" + this.sid;
  13977. };
  13978. cr.do_cmp = function (x, cmp, y)
  13979. {
  13980. if (typeof x === "undefined" || typeof y === "undefined")
  13981. return false;
  13982. switch (cmp)
  13983. {
  13984. case 0: // equal
  13985. return x === y;
  13986. case 1: // not equal
  13987. return x !== y;
  13988. case 2: // less
  13989. return x < y;
  13990. case 3: // less/equal
  13991. return x <= y;
  13992. case 4: // greater
  13993. return x > y;
  13994. case 5: // greater/equal
  13995. return x >= y;
  13996. default:
  13997. ;
  13998. return false;
  13999. }
  14000. };
  14001. })();
  14002. cr.shaders = {};
  14003. ;
  14004. ;
  14005. cr.plugins_.Arr = function(runtime)
  14006. {
  14007. this.runtime = runtime;
  14008. };
  14009. (function ()
  14010. {
  14011. var pluginProto = cr.plugins_.Arr.prototype;
  14012. pluginProto.Type = function(plugin)
  14013. {
  14014. this.plugin = plugin;
  14015. this.runtime = plugin.runtime;
  14016. };
  14017. var typeProto = pluginProto.Type.prototype;
  14018. typeProto.onCreate = function()
  14019. {
  14020. };
  14021. pluginProto.Instance = function(type)
  14022. {
  14023. this.type = type;
  14024. this.runtime = type.runtime;
  14025. };
  14026. var instanceProto = pluginProto.Instance.prototype;
  14027. var arrCache = [];
  14028. function allocArray()
  14029. {
  14030. if (arrCache.length)
  14031. return arrCache.pop();
  14032. else
  14033. return [];
  14034. };
  14035. if (!Array.isArray)
  14036. {
  14037. Array.isArray = function (vArg) {
  14038. return Object.prototype.toString.call(vArg) === "[object Array]";
  14039. };
  14040. }
  14041. function freeArray(a)
  14042. {
  14043. var i, len;
  14044. for (i = 0, len = a.length; i < len; i++)
  14045. {
  14046. if (Array.isArray(a[i]))
  14047. freeArray(a[i]);
  14048. }
  14049. cr.clearArray(a);
  14050. arrCache.push(a);
  14051. };
  14052. instanceProto.onCreate = function()
  14053. {
  14054. this.cx = this.properties[0];
  14055. this.cy = this.properties[1];
  14056. this.cz = this.properties[2];
  14057. if (!this.recycled)
  14058. this.arr = allocArray();
  14059. var a = this.arr;
  14060. a.length = this.cx;
  14061. var x, y, z;
  14062. for (x = 0; x < this.cx; x++)
  14063. {
  14064. if (!a[x])
  14065. a[x] = allocArray();
  14066. a[x].length = this.cy;
  14067. for (y = 0; y < this.cy; y++)
  14068. {
  14069. if (!a[x][y])
  14070. a[x][y] = allocArray();
  14071. a[x][y].length = this.cz;
  14072. for (z = 0; z < this.cz; z++)
  14073. a[x][y][z] = 0;
  14074. }
  14075. }
  14076. this.forX = [];
  14077. this.forY = [];
  14078. this.forZ = [];
  14079. this.forDepth = -1;
  14080. };
  14081. instanceProto.onDestroy = function ()
  14082. {
  14083. var x;
  14084. for (x = 0; x < this.cx; x++)
  14085. freeArray(this.arr[x]); // will recurse down and recycle other arrays
  14086. cr.clearArray(this.arr);
  14087. };
  14088. instanceProto.at = function (x, y, z)
  14089. {
  14090. x = Math.floor(x);
  14091. y = Math.floor(y);
  14092. z = Math.floor(z);
  14093. if (isNaN(x) || x < 0 || x > this.cx - 1)
  14094. return 0;
  14095. if (isNaN(y) || y < 0 || y > this.cy - 1)
  14096. return 0;
  14097. if (isNaN(z) || z < 0 || z > this.cz - 1)
  14098. return 0;
  14099. return this.arr[x][y][z];
  14100. };
  14101. instanceProto.set = function (x, y, z, val)
  14102. {
  14103. x = Math.floor(x);
  14104. y = Math.floor(y);
  14105. z = Math.floor(z);
  14106. if (isNaN(x) || x < 0 || x > this.cx - 1)
  14107. return;
  14108. if (isNaN(y) || y < 0 || y > this.cy - 1)
  14109. return;
  14110. if (isNaN(z) || z < 0 || z > this.cz - 1)
  14111. return;
  14112. this.arr[x][y][z] = val;
  14113. };
  14114. instanceProto.getAsJSON = function ()
  14115. {
  14116. return JSON.stringify({
  14117. "c2array": true,
  14118. "size": [this.cx, this.cy, this.cz],
  14119. "data": this.arr
  14120. });
  14121. };
  14122. instanceProto.saveToJSON = function ()
  14123. {
  14124. return {
  14125. "size": [this.cx, this.cy, this.cz],
  14126. "data": this.arr
  14127. };
  14128. };
  14129. instanceProto.loadFromJSON = function (o)
  14130. {
  14131. var sz = o["size"];
  14132. this.cx = sz[0];
  14133. this.cy = sz[1];
  14134. this.cz = sz[2];
  14135. this.arr = o["data"];
  14136. };
  14137. instanceProto.setSize = function (w, h, d)
  14138. {
  14139. if (w < 0) w = 0;
  14140. if (h < 0) h = 0;
  14141. if (d < 0) d = 0;
  14142. if (this.cx === w && this.cy === h && this.cz === d)
  14143. return; // no change
  14144. this.cx = w;
  14145. this.cy = h;
  14146. this.cz = d;
  14147. var x, y, z;
  14148. var a = this.arr;
  14149. a.length = w;
  14150. for (x = 0; x < this.cx; x++)
  14151. {
  14152. if (cr.is_undefined(a[x]))
  14153. a[x] = allocArray();
  14154. a[x].length = h;
  14155. for (y = 0; y < this.cy; y++)
  14156. {
  14157. if (cr.is_undefined(a[x][y]))
  14158. a[x][y] = allocArray();
  14159. a[x][y].length = d;
  14160. for (z = 0; z < this.cz; z++)
  14161. {
  14162. if (cr.is_undefined(a[x][y][z]))
  14163. a[x][y][z] = 0;
  14164. }
  14165. }
  14166. }
  14167. };
  14168. instanceProto.getForX = function ()
  14169. {
  14170. if (this.forDepth >= 0 && this.forDepth < this.forX.length)
  14171. return this.forX[this.forDepth];
  14172. else
  14173. return 0;
  14174. };
  14175. instanceProto.getForY = function ()
  14176. {
  14177. if (this.forDepth >= 0 && this.forDepth < this.forY.length)
  14178. return this.forY[this.forDepth];
  14179. else
  14180. return 0;
  14181. };
  14182. instanceProto.getForZ = function ()
  14183. {
  14184. if (this.forDepth >= 0 && this.forDepth < this.forZ.length)
  14185. return this.forZ[this.forDepth];
  14186. else
  14187. return 0;
  14188. };
  14189. function Cnds() {};
  14190. Cnds.prototype.CompareX = function (x, cmp, val)
  14191. {
  14192. return cr.do_cmp(this.at(x, 0, 0), cmp, val);
  14193. };
  14194. Cnds.prototype.CompareXY = function (x, y, cmp, val)
  14195. {
  14196. return cr.do_cmp(this.at(x, y, 0), cmp, val);
  14197. };
  14198. Cnds.prototype.CompareXYZ = function (x, y, z, cmp, val)
  14199. {
  14200. return cr.do_cmp(this.at(x, y, z), cmp, val);
  14201. };
  14202. instanceProto.doForEachTrigger = function (current_event)
  14203. {
  14204. this.runtime.pushCopySol(current_event.solModifiers);
  14205. current_event.retrigger();
  14206. this.runtime.popSol(current_event.solModifiers);
  14207. };
  14208. Cnds.prototype.ArrForEach = function (dims)
  14209. {
  14210. var current_event = this.runtime.getCurrentEventStack().current_event;
  14211. this.forDepth++;
  14212. var forDepth = this.forDepth;
  14213. if (forDepth === this.forX.length)
  14214. {
  14215. this.forX.push(0);
  14216. this.forY.push(0);
  14217. this.forZ.push(0);
  14218. }
  14219. else
  14220. {
  14221. this.forX[forDepth] = 0;
  14222. this.forY[forDepth] = 0;
  14223. this.forZ[forDepth] = 0;
  14224. }
  14225. switch (dims) {
  14226. case 0:
  14227. for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
  14228. {
  14229. for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
  14230. {
  14231. for (this.forZ[forDepth] = 0; this.forZ[forDepth] < this.cz; this.forZ[forDepth]++)
  14232. {
  14233. this.doForEachTrigger(current_event);
  14234. }
  14235. }
  14236. }
  14237. break;
  14238. case 1:
  14239. for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
  14240. {
  14241. for (this.forY[forDepth] = 0; this.forY[forDepth] < this.cy; this.forY[forDepth]++)
  14242. {
  14243. this.doForEachTrigger(current_event);
  14244. }
  14245. }
  14246. break;
  14247. case 2:
  14248. for (this.forX[forDepth] = 0; this.forX[forDepth] < this.cx; this.forX[forDepth]++)
  14249. {
  14250. this.doForEachTrigger(current_event);
  14251. }
  14252. break;
  14253. }
  14254. this.forDepth--;
  14255. return false;
  14256. };
  14257. Cnds.prototype.CompareCurrent = function (cmp, val)
  14258. {
  14259. return cr.do_cmp(this.at(this.getForX(), this.getForY(), this.getForZ()), cmp, val);
  14260. };
  14261. Cnds.prototype.Contains = function(val)
  14262. {
  14263. var x, y, z;
  14264. for (x = 0; x < this.cx; x++)
  14265. {
  14266. for (y = 0; y < this.cy; y++)
  14267. {
  14268. for (z = 0; z < this.cz; z++)
  14269. {
  14270. if (this.arr[x][y][z] === val)
  14271. return true;
  14272. }
  14273. }
  14274. }
  14275. return false;
  14276. };
  14277. Cnds.prototype.IsEmpty = function ()
  14278. {
  14279. return this.cx === 0 || this.cy === 0 || this.cz === 0;
  14280. };
  14281. Cnds.prototype.CompareSize = function (axis, cmp, value)
  14282. {
  14283. var s = 0;
  14284. switch (axis) {
  14285. case 0:
  14286. s = this.cx;
  14287. break;
  14288. case 1:
  14289. s = this.cy;
  14290. break;
  14291. case 2:
  14292. s = this.cz;
  14293. break;
  14294. }
  14295. return cr.do_cmp(s, cmp, value);
  14296. };
  14297. pluginProto.cnds = new Cnds();
  14298. function Acts() {};
  14299. Acts.prototype.Clear = function ()
  14300. {
  14301. var x, y, z;
  14302. for (x = 0; x < this.cx; x++)
  14303. for (y = 0; y < this.cy; y++)
  14304. for (z = 0; z < this.cz; z++)
  14305. this.arr[x][y][z] = 0;
  14306. };
  14307. Acts.prototype.SetSize = function (w, h, d)
  14308. {
  14309. this.setSize(w, h, d);
  14310. };
  14311. Acts.prototype.SetX = function (x, val)
  14312. {
  14313. this.set(x, 0, 0, val);
  14314. };
  14315. Acts.prototype.SetXY = function (x, y, val)
  14316. {
  14317. this.set(x, y, 0, val);
  14318. };
  14319. Acts.prototype.SetXYZ = function (x, y, z, val)
  14320. {
  14321. this.set(x, y, z, val);
  14322. };
  14323. Acts.prototype.Push = function (where, value, axis)
  14324. {
  14325. var x = 0, y = 0, z = 0;
  14326. var a = this.arr;
  14327. switch (axis) {
  14328. case 0: // X axis
  14329. if (where === 0) // back
  14330. {
  14331. x = a.length;
  14332. a.push(allocArray());
  14333. }
  14334. else // front
  14335. {
  14336. x = 0;
  14337. a.unshift(allocArray());
  14338. }
  14339. a[x].length = this.cy;
  14340. for ( ; y < this.cy; y++)
  14341. {
  14342. a[x][y] = allocArray();
  14343. a[x][y].length = this.cz;
  14344. for (z = 0; z < this.cz; z++)
  14345. a[x][y][z] = value;
  14346. }
  14347. this.cx++;
  14348. break;
  14349. case 1: // Y axis
  14350. for ( ; x < this.cx; x++)
  14351. {
  14352. if (where === 0) // back
  14353. {
  14354. y = a[x].length;
  14355. a[x].push(allocArray());
  14356. }
  14357. else // front
  14358. {
  14359. y = 0;
  14360. a[x].unshift(allocArray());
  14361. }
  14362. a[x][y].length = this.cz;
  14363. for (z = 0; z < this.cz; z++)
  14364. a[x][y][z] = value;
  14365. }
  14366. this.cy++;
  14367. break;
  14368. case 2: // Z axis
  14369. for ( ; x < this.cx; x++)
  14370. {
  14371. for (y = 0; y < this.cy; y++)
  14372. {
  14373. if (where === 0) // back
  14374. {
  14375. a[x][y].push(value);
  14376. }
  14377. else // front
  14378. {
  14379. a[x][y].unshift(value);
  14380. }
  14381. }
  14382. }
  14383. this.cz++;
  14384. break;
  14385. }
  14386. };
  14387. Acts.prototype.Pop = function (where, axis)
  14388. {
  14389. var x = 0, y = 0, z = 0;
  14390. var a = this.arr;
  14391. switch (axis) {
  14392. case 0: // X axis
  14393. if (this.cx === 0)
  14394. break;
  14395. if (where === 0) // back
  14396. {
  14397. freeArray(a.pop());
  14398. }
  14399. else // front
  14400. {
  14401. freeArray(a.shift());
  14402. }
  14403. this.cx--;
  14404. break;
  14405. case 1: // Y axis
  14406. if (this.cy === 0)
  14407. break;
  14408. for ( ; x < this.cx; x++)
  14409. {
  14410. if (where === 0) // back
  14411. {
  14412. freeArray(a[x].pop());
  14413. }
  14414. else // front
  14415. {
  14416. freeArray(a[x].shift());
  14417. }
  14418. }
  14419. this.cy--;
  14420. break;
  14421. case 2: // Z axis
  14422. if (this.cz === 0)
  14423. break;
  14424. for ( ; x < this.cx; x++)
  14425. {
  14426. for (y = 0; y < this.cy; y++)
  14427. {
  14428. if (where === 0) // back
  14429. {
  14430. a[x][y].pop();
  14431. }
  14432. else // front
  14433. {
  14434. a[x][y].shift();
  14435. }
  14436. }
  14437. }
  14438. this.cz--;
  14439. break;
  14440. }
  14441. };
  14442. Acts.prototype.Reverse = function (axis)
  14443. {
  14444. var x = 0, y = 0, z = 0;
  14445. var a = this.arr;
  14446. if (this.cx === 0 || this.cy === 0 || this.cz === 0)
  14447. return; // no point reversing empty array
  14448. switch (axis) {
  14449. case 0: // X axis
  14450. a.reverse();
  14451. break;
  14452. case 1: // Y axis
  14453. for ( ; x < this.cx; x++)
  14454. a[x].reverse();
  14455. break;
  14456. case 2: // Z axis
  14457. for ( ; x < this.cx; x++)
  14458. for (y = 0; y < this.cy; y++)
  14459. a[x][y].reverse();
  14460. this.cz--;
  14461. break;
  14462. }
  14463. };
  14464. function compareValues(va, vb)
  14465. {
  14466. if (cr.is_number(va) && cr.is_number(vb))
  14467. return va - vb;
  14468. else
  14469. {
  14470. var sa = "" + va;
  14471. var sb = "" + vb;
  14472. if (sa < sb)
  14473. return -1;
  14474. else if (sa > sb)
  14475. return 1;
  14476. else
  14477. return 0;
  14478. }
  14479. }
  14480. Acts.prototype.Sort = function (axis)
  14481. {
  14482. var x = 0, y = 0, z = 0;
  14483. var a = this.arr;
  14484. if (this.cx === 0 || this.cy === 0 || this.cz === 0)
  14485. return; // no point sorting empty array
  14486. switch (axis) {
  14487. case 0: // X axis
  14488. a.sort(function (a, b) {
  14489. return compareValues(a[0][0], b[0][0]);
  14490. });
  14491. break;
  14492. case 1: // Y axis
  14493. for ( ; x < this.cx; x++)
  14494. {
  14495. a[x].sort(function (a, b) {
  14496. return compareValues(a[0], b[0]);
  14497. });
  14498. }
  14499. break;
  14500. case 2: // Z axis
  14501. for ( ; x < this.cx; x++)
  14502. {
  14503. for (y = 0; y < this.cy; y++)
  14504. {
  14505. a[x][y].sort(compareValues);
  14506. }
  14507. }
  14508. break;
  14509. }
  14510. };
  14511. Acts.prototype.Delete = function (index, axis)
  14512. {
  14513. var x = 0, y = 0, z = 0;
  14514. index = Math.floor(index);
  14515. var a = this.arr;
  14516. if (index < 0)
  14517. return;
  14518. switch (axis) {
  14519. case 0: // X axis
  14520. if (index >= this.cx)
  14521. break;
  14522. freeArray(a[index]);
  14523. a.splice(index, 1);
  14524. this.cx--;
  14525. break;
  14526. case 1: // Y axis
  14527. if (index >= this.cy)
  14528. break;
  14529. for ( ; x < this.cx; x++)
  14530. {
  14531. freeArray(a[x][index]);
  14532. a[x].splice(index, 1);
  14533. }
  14534. this.cy--;
  14535. break;
  14536. case 2: // Z axis
  14537. if (index >= this.cz)
  14538. break;
  14539. for ( ; x < this.cx; x++)
  14540. {
  14541. for (y = 0; y < this.cy; y++)
  14542. {
  14543. a[x][y].splice(index, 1);
  14544. }
  14545. }
  14546. this.cz--;
  14547. break;
  14548. }
  14549. };
  14550. Acts.prototype.Insert = function (value, index, axis)
  14551. {
  14552. var x = 0, y = 0, z = 0;
  14553. index = Math.floor(index);
  14554. var a = this.arr;
  14555. if (index < 0)
  14556. return;
  14557. switch (axis) {
  14558. case 0: // X axis
  14559. if (index > this.cx)
  14560. return;
  14561. x = index;
  14562. a.splice(x, 0, allocArray());
  14563. a[x].length = this.cy;
  14564. for ( ; y < this.cy; y++)
  14565. {
  14566. a[x][y] = allocArray();
  14567. a[x][y].length = this.cz;
  14568. for (z = 0; z < this.cz; z++)
  14569. a[x][y][z] = value;
  14570. }
  14571. this.cx++;
  14572. break;
  14573. case 1: // Y axis
  14574. if (index > this.cy)
  14575. return;
  14576. for ( ; x < this.cx; x++)
  14577. {
  14578. y = index;
  14579. a[x].splice(y, 0, allocArray());
  14580. a[x][y].length = this.cz;
  14581. for (z = 0; z < this.cz; z++)
  14582. a[x][y][z] = value;
  14583. }
  14584. this.cy++;
  14585. break;
  14586. case 2: // Z axis
  14587. if (index > this.cz)
  14588. return;
  14589. for ( ; x < this.cx; x++)
  14590. {
  14591. for (y = 0; y < this.cy; y++)
  14592. {
  14593. a[x][y].splice(index, 0, value);
  14594. }
  14595. }
  14596. this.cz++;
  14597. break;
  14598. }
  14599. };
  14600. Acts.prototype.JSONLoad = function (json_)
  14601. {
  14602. var o;
  14603. try {
  14604. o = JSON.parse(json_);
  14605. }
  14606. catch(e) { return; }
  14607. if (!o["c2array"]) // presumably not a c2array object
  14608. return;
  14609. var sz = o["size"];
  14610. this.cx = sz[0];
  14611. this.cy = sz[1];
  14612. this.cz = sz[2];
  14613. this.arr = o["data"];
  14614. };
  14615. Acts.prototype.JSONDownload = function (filename)
  14616. {
  14617. var a = document.createElement("a");
  14618. if (typeof a.download === "undefined")
  14619. {
  14620. var str = 'data:text/html,' + encodeURIComponent("<p><a download='" + filename + "' href=\"data:application/json,"
  14621. + encodeURIComponent(this.getAsJSON())
  14622. + "\">Download link</a></p>");
  14623. window.open(str);
  14624. }
  14625. else
  14626. {
  14627. var body = document.getElementsByTagName("body")[0];
  14628. a.textContent = filename;
  14629. a.href = "data:application/json," + encodeURIComponent(this.getAsJSON());
  14630. a.download = filename;
  14631. body.appendChild(a);
  14632. var clickEvent = document.createEvent("MouseEvent");
  14633. clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  14634. a.dispatchEvent(clickEvent);
  14635. body.removeChild(a);
  14636. }
  14637. };
  14638. pluginProto.acts = new Acts();
  14639. function Exps() {};
  14640. Exps.prototype.At = function (ret, x, y_, z_)
  14641. {
  14642. var y = y_ || 0;
  14643. var z = z_ || 0;
  14644. ret.set_any(this.at(x, y, z));
  14645. };
  14646. Exps.prototype.Width = function (ret)
  14647. {
  14648. ret.set_int(this.cx);
  14649. };
  14650. Exps.prototype.Height = function (ret)
  14651. {
  14652. ret.set_int(this.cy);
  14653. };
  14654. Exps.prototype.Depth = function (ret)
  14655. {
  14656. ret.set_int(this.cz);
  14657. };
  14658. Exps.prototype.CurX = function (ret)
  14659. {
  14660. ret.set_int(this.getForX());
  14661. };
  14662. Exps.prototype.CurY = function (ret)
  14663. {
  14664. ret.set_int(this.getForY());
  14665. };
  14666. Exps.prototype.CurZ = function (ret)
  14667. {
  14668. ret.set_int(this.getForZ());
  14669. };
  14670. Exps.prototype.CurValue = function (ret)
  14671. {
  14672. ret.set_any(this.at(this.getForX(), this.getForY(), this.getForZ()));
  14673. };
  14674. Exps.prototype.Front = function (ret)
  14675. {
  14676. ret.set_any(this.at(0, 0, 0));
  14677. };
  14678. Exps.prototype.Back = function (ret)
  14679. {
  14680. ret.set_any(this.at(this.cx - 1, 0, 0));
  14681. };
  14682. Exps.prototype.IndexOf = function (ret, v)
  14683. {
  14684. for (var i = 0; i < this.cx; i++)
  14685. {
  14686. if (this.arr[i][0][0] === v)
  14687. {
  14688. ret.set_int(i);
  14689. return;
  14690. }
  14691. }
  14692. ret.set_int(-1);
  14693. };
  14694. Exps.prototype.LastIndexOf = function (ret, v)
  14695. {
  14696. for (var i = this.cx - 1; i >= 0; i--)
  14697. {
  14698. if (this.arr[i][0][0] === v)
  14699. {
  14700. ret.set_int(i);
  14701. return;
  14702. }
  14703. }
  14704. ret.set_int(-1);
  14705. };
  14706. Exps.prototype.AsJSON = function (ret)
  14707. {
  14708. ret.set_string(this.getAsJSON());
  14709. };
  14710. pluginProto.exps = new Exps();
  14711. }());
  14712. ;
  14713. ;
  14714. cr.plugins_.Audio = function(runtime)
  14715. {
  14716. this.runtime = runtime;
  14717. };
  14718. (function ()
  14719. {
  14720. var pluginProto = cr.plugins_.Audio.prototype;
  14721. pluginProto.Type = function(plugin)
  14722. {
  14723. this.plugin = plugin;
  14724. this.runtime = plugin.runtime;
  14725. };
  14726. var typeProto = pluginProto.Type.prototype;
  14727. typeProto.onCreate = function()
  14728. {
  14729. };
  14730. var audRuntime = null;
  14731. var audInst = null;
  14732. var audTag = "";
  14733. var appPath = ""; // for Cordova only
  14734. var API_HTML5 = 0;
  14735. var API_WEBAUDIO = 1;
  14736. var API_CORDOVA = 2;
  14737. var API_APPMOBI = 3;
  14738. var api = API_HTML5;
  14739. var context = null;
  14740. var audioBuffers = []; // cache of buffers
  14741. var audioInstances = []; // cache of instances
  14742. var lastAudio = null;
  14743. var useOgg = false; // determined at create time
  14744. var timescale_mode = 0;
  14745. var silent = false;
  14746. var masterVolume = 1;
  14747. var listenerX = 0;
  14748. var listenerY = 0;
  14749. var panningModel = 1; // HRTF
  14750. var distanceModel = 1; // Inverse
  14751. var refDistance = 10;
  14752. var maxDistance = 10000;
  14753. var rolloffFactor = 1;
  14754. var micSource = null;
  14755. var micTag = "";
  14756. var isMusicWorkaround = false;
  14757. var musicPlayNextTouch = [];
  14758. function dbToLinear(x)
  14759. {
  14760. var v = dbToLinear_nocap(x);
  14761. if (v < 0)
  14762. v = 0;
  14763. if (v > 1)
  14764. v = 1;
  14765. return v;
  14766. };
  14767. function linearToDb(x)
  14768. {
  14769. if (x < 0)
  14770. x = 0;
  14771. if (x > 1)
  14772. x = 1;
  14773. return linearToDb_nocap(x);
  14774. };
  14775. function dbToLinear_nocap(x)
  14776. {
  14777. return Math.pow(10, x / 20);
  14778. };
  14779. function linearToDb_nocap(x)
  14780. {
  14781. return (Math.log(x) / Math.log(10)) * 20;
  14782. };
  14783. var effects = {};
  14784. function getDestinationForTag(tag)
  14785. {
  14786. tag = tag.toLowerCase();
  14787. if (effects.hasOwnProperty(tag))
  14788. {
  14789. if (effects[tag].length)
  14790. return effects[tag][0].getInputNode();
  14791. }
  14792. return context["destination"];
  14793. };
  14794. function createGain()
  14795. {
  14796. if (context["createGain"])
  14797. return context["createGain"]();
  14798. else
  14799. return context["createGainNode"]();
  14800. };
  14801. function createDelay(d)
  14802. {
  14803. if (context["createDelay"])
  14804. return context["createDelay"](d);
  14805. else
  14806. return context["createDelayNode"](d);
  14807. };
  14808. function startSource(s)
  14809. {
  14810. if (s["start"])
  14811. s["start"](0);
  14812. else
  14813. s["noteOn"](0);
  14814. };
  14815. function startSourceAt(s, x, d)
  14816. {
  14817. if (s["start"])
  14818. s["start"](0, x);
  14819. else
  14820. s["noteGrainOn"](0, x, d - x);
  14821. };
  14822. function stopSource(s)
  14823. {
  14824. try {
  14825. if (s["stop"])
  14826. s["stop"](0);
  14827. else
  14828. s["noteOff"](0);
  14829. }
  14830. catch (e) {}
  14831. };
  14832. function setAudioParam(ap, value, ramp, time)
  14833. {
  14834. if (!ap)
  14835. return; // iOS is missing some parameters
  14836. ap["cancelScheduledValues"](0);
  14837. if (time === 0)
  14838. {
  14839. ap["value"] = value;
  14840. return;
  14841. }
  14842. var curTime = context["currentTime"];
  14843. time += curTime;
  14844. switch (ramp) {
  14845. case 0: // step
  14846. ap["setValueAtTime"](value, time);
  14847. break;
  14848. case 1: // linear
  14849. ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
  14850. ap["linearRampToValueAtTime"](value, time);
  14851. break;
  14852. case 2: // exponential
  14853. ap["setValueAtTime"](ap["value"], curTime); // to set what to ramp from
  14854. ap["exponentialRampToValueAtTime"](value, time);
  14855. break;
  14856. }
  14857. };
  14858. var filterTypes = ["lowpass", "highpass", "bandpass", "lowshelf", "highshelf", "peaking", "notch", "allpass"];
  14859. function FilterEffect(type, freq, detune, q, gain, mix)
  14860. {
  14861. this.type = "filter";
  14862. this.params = [type, freq, detune, q, gain, mix];
  14863. this.inputNode = createGain();
  14864. this.wetNode = createGain();
  14865. this.wetNode["gain"]["value"] = mix;
  14866. this.dryNode = createGain();
  14867. this.dryNode["gain"]["value"] = 1 - mix;
  14868. this.filterNode = context["createBiquadFilter"]();
  14869. if (typeof this.filterNode["type"] === "number")
  14870. this.filterNode["type"] = type;
  14871. else
  14872. this.filterNode["type"] = filterTypes[type];
  14873. this.filterNode["frequency"]["value"] = freq;
  14874. if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
  14875. this.filterNode["detune"]["value"] = detune;
  14876. this.filterNode["Q"]["value"] = q;
  14877. this.filterNode["gain"]["value"] = gain;
  14878. this.inputNode["connect"](this.filterNode);
  14879. this.inputNode["connect"](this.dryNode);
  14880. this.filterNode["connect"](this.wetNode);
  14881. };
  14882. FilterEffect.prototype.connectTo = function (node)
  14883. {
  14884. this.wetNode["disconnect"]();
  14885. this.wetNode["connect"](node);
  14886. this.dryNode["disconnect"]();
  14887. this.dryNode["connect"](node);
  14888. };
  14889. FilterEffect.prototype.remove = function ()
  14890. {
  14891. this.inputNode["disconnect"]();
  14892. this.filterNode["disconnect"]();
  14893. this.wetNode["disconnect"]();
  14894. this.dryNode["disconnect"]();
  14895. };
  14896. FilterEffect.prototype.getInputNode = function ()
  14897. {
  14898. return this.inputNode;
  14899. };
  14900. FilterEffect.prototype.setParam = function(param, value, ramp, time)
  14901. {
  14902. switch (param) {
  14903. case 0: // mix
  14904. value = value / 100;
  14905. if (value < 0) value = 0;
  14906. if (value > 1) value = 1;
  14907. this.params[5] = value;
  14908. setAudioParam(this.wetNode["gain"], value, ramp, time);
  14909. setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
  14910. break;
  14911. case 1: // filter frequency
  14912. this.params[1] = value;
  14913. setAudioParam(this.filterNode["frequency"], value, ramp, time);
  14914. break;
  14915. case 2: // filter detune
  14916. this.params[2] = value;
  14917. setAudioParam(this.filterNode["detune"], value, ramp, time);
  14918. break;
  14919. case 3: // filter Q
  14920. this.params[3] = value;
  14921. setAudioParam(this.filterNode["Q"], value, ramp, time);
  14922. break;
  14923. case 4: // filter/delay gain (note value is in dB here)
  14924. this.params[4] = value;
  14925. setAudioParam(this.filterNode["gain"], value, ramp, time);
  14926. break;
  14927. }
  14928. };
  14929. function DelayEffect(delayTime, delayGain, mix)
  14930. {
  14931. this.type = "delay";
  14932. this.params = [delayTime, delayGain, mix];
  14933. this.inputNode = createGain();
  14934. this.wetNode = createGain();
  14935. this.wetNode["gain"]["value"] = mix;
  14936. this.dryNode = createGain();
  14937. this.dryNode["gain"]["value"] = 1 - mix;
  14938. this.mainNode = createGain();
  14939. this.delayNode = createDelay(delayTime);
  14940. this.delayNode["delayTime"]["value"] = delayTime;
  14941. this.delayGainNode = createGain();
  14942. this.delayGainNode["gain"]["value"] = delayGain;
  14943. this.inputNode["connect"](this.mainNode);
  14944. this.inputNode["connect"](this.dryNode);
  14945. this.mainNode["connect"](this.wetNode);
  14946. this.mainNode["connect"](this.delayNode);
  14947. this.delayNode["connect"](this.delayGainNode);
  14948. this.delayGainNode["connect"](this.mainNode);
  14949. };
  14950. DelayEffect.prototype.connectTo = function (node)
  14951. {
  14952. this.wetNode["disconnect"]();
  14953. this.wetNode["connect"](node);
  14954. this.dryNode["disconnect"]();
  14955. this.dryNode["connect"](node);
  14956. };
  14957. DelayEffect.prototype.remove = function ()
  14958. {
  14959. this.inputNode["disconnect"]();
  14960. this.mainNode["disconnect"]();
  14961. this.delayNode["disconnect"]();
  14962. this.delayGainNode["disconnect"]();
  14963. this.wetNode["disconnect"]();
  14964. this.dryNode["disconnect"]();
  14965. };
  14966. DelayEffect.prototype.getInputNode = function ()
  14967. {
  14968. return this.inputNode;
  14969. };
  14970. DelayEffect.prototype.setParam = function(param, value, ramp, time)
  14971. {
  14972. switch (param) {
  14973. case 0: // mix
  14974. value = value / 100;
  14975. if (value < 0) value = 0;
  14976. if (value > 1) value = 1;
  14977. this.params[2] = value;
  14978. setAudioParam(this.wetNode["gain"], value, ramp, time);
  14979. setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
  14980. break;
  14981. case 4: // filter/delay gain (note value is passed in dB but needs to be linear here)
  14982. this.params[1] = dbToLinear(value);
  14983. setAudioParam(this.delayGainNode["gain"], dbToLinear(value), ramp, time);
  14984. break;
  14985. case 5: // delay time
  14986. this.params[0] = value;
  14987. setAudioParam(this.delayNode["delayTime"], value, ramp, time);
  14988. break;
  14989. }
  14990. };
  14991. function ConvolveEffect(buffer, normalize, mix, src)
  14992. {
  14993. this.type = "convolve";
  14994. this.params = [normalize, mix, src];
  14995. this.inputNode = createGain();
  14996. this.wetNode = createGain();
  14997. this.wetNode["gain"]["value"] = mix;
  14998. this.dryNode = createGain();
  14999. this.dryNode["gain"]["value"] = 1 - mix;
  15000. this.convolveNode = context["createConvolver"]();
  15001. if (buffer)
  15002. {
  15003. this.convolveNode["normalize"] = normalize;
  15004. this.convolveNode["buffer"] = buffer;
  15005. }
  15006. this.inputNode["connect"](this.convolveNode);
  15007. this.inputNode["connect"](this.dryNode);
  15008. this.convolveNode["connect"](this.wetNode);
  15009. };
  15010. ConvolveEffect.prototype.connectTo = function (node)
  15011. {
  15012. this.wetNode["disconnect"]();
  15013. this.wetNode["connect"](node);
  15014. this.dryNode["disconnect"]();
  15015. this.dryNode["connect"](node);
  15016. };
  15017. ConvolveEffect.prototype.remove = function ()
  15018. {
  15019. this.inputNode["disconnect"]();
  15020. this.convolveNode["disconnect"]();
  15021. this.wetNode["disconnect"]();
  15022. this.dryNode["disconnect"]();
  15023. };
  15024. ConvolveEffect.prototype.getInputNode = function ()
  15025. {
  15026. return this.inputNode;
  15027. };
  15028. ConvolveEffect.prototype.setParam = function(param, value, ramp, time)
  15029. {
  15030. switch (param) {
  15031. case 0: // mix
  15032. value = value / 100;
  15033. if (value < 0) value = 0;
  15034. if (value > 1) value = 1;
  15035. this.params[1] = value;
  15036. setAudioParam(this.wetNode["gain"], value, ramp, time);
  15037. setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
  15038. break;
  15039. }
  15040. };
  15041. function FlangerEffect(delay, modulation, freq, feedback, mix)
  15042. {
  15043. this.type = "flanger";
  15044. this.params = [delay, modulation, freq, feedback, mix];
  15045. this.inputNode = createGain();
  15046. this.dryNode = createGain();
  15047. this.dryNode["gain"]["value"] = 1 - (mix / 2);
  15048. this.wetNode = createGain();
  15049. this.wetNode["gain"]["value"] = mix / 2;
  15050. this.feedbackNode = createGain();
  15051. this.feedbackNode["gain"]["value"] = feedback;
  15052. this.delayNode = createDelay(delay + modulation);
  15053. this.delayNode["delayTime"]["value"] = delay;
  15054. this.oscNode = context["createOscillator"]();
  15055. this.oscNode["frequency"]["value"] = freq;
  15056. this.oscGainNode = createGain();
  15057. this.oscGainNode["gain"]["value"] = modulation;
  15058. this.inputNode["connect"](this.delayNode);
  15059. this.inputNode["connect"](this.dryNode);
  15060. this.delayNode["connect"](this.wetNode);
  15061. this.delayNode["connect"](this.feedbackNode);
  15062. this.feedbackNode["connect"](this.delayNode);
  15063. this.oscNode["connect"](this.oscGainNode);
  15064. this.oscGainNode["connect"](this.delayNode["delayTime"]);
  15065. startSource(this.oscNode);
  15066. };
  15067. FlangerEffect.prototype.connectTo = function (node)
  15068. {
  15069. this.dryNode["disconnect"]();
  15070. this.dryNode["connect"](node);
  15071. this.wetNode["disconnect"]();
  15072. this.wetNode["connect"](node);
  15073. };
  15074. FlangerEffect.prototype.remove = function ()
  15075. {
  15076. this.inputNode["disconnect"]();
  15077. this.delayNode["disconnect"]();
  15078. this.oscNode["disconnect"]();
  15079. this.oscGainNode["disconnect"]();
  15080. this.dryNode["disconnect"]();
  15081. this.wetNode["disconnect"]();
  15082. this.feedbackNode["disconnect"]();
  15083. };
  15084. FlangerEffect.prototype.getInputNode = function ()
  15085. {
  15086. return this.inputNode;
  15087. };
  15088. FlangerEffect.prototype.setParam = function(param, value, ramp, time)
  15089. {
  15090. switch (param) {
  15091. case 0: // mix
  15092. value = value / 100;
  15093. if (value < 0) value = 0;
  15094. if (value > 1) value = 1;
  15095. this.params[4] = value;
  15096. setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
  15097. setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
  15098. break;
  15099. case 6: // modulation
  15100. this.params[1] = value / 1000;
  15101. setAudioParam(this.oscGainNode["gain"], value / 1000, ramp, time);
  15102. break;
  15103. case 7: // modulation frequency
  15104. this.params[2] = value;
  15105. setAudioParam(this.oscNode["frequency"], value, ramp, time);
  15106. break;
  15107. case 8: // feedback
  15108. this.params[3] = value / 100;
  15109. setAudioParam(this.feedbackNode["gain"], value / 100, ramp, time);
  15110. break;
  15111. }
  15112. };
  15113. function PhaserEffect(freq, detune, q, modulation, modfreq, mix)
  15114. {
  15115. this.type = "phaser";
  15116. this.params = [freq, detune, q, modulation, modfreq, mix];
  15117. this.inputNode = createGain();
  15118. this.dryNode = createGain();
  15119. this.dryNode["gain"]["value"] = 1 - (mix / 2);
  15120. this.wetNode = createGain();
  15121. this.wetNode["gain"]["value"] = mix / 2;
  15122. this.filterNode = context["createBiquadFilter"]();
  15123. if (typeof this.filterNode["type"] === "number")
  15124. this.filterNode["type"] = 7; // all-pass
  15125. else
  15126. this.filterNode["type"] = "allpass";
  15127. this.filterNode["frequency"]["value"] = freq;
  15128. if (this.filterNode["detune"]) // iOS 6 doesn't have detune yet
  15129. this.filterNode["detune"]["value"] = detune;
  15130. this.filterNode["Q"]["value"] = q;
  15131. this.oscNode = context["createOscillator"]();
  15132. this.oscNode["frequency"]["value"] = modfreq;
  15133. this.oscGainNode = createGain();
  15134. this.oscGainNode["gain"]["value"] = modulation;
  15135. this.inputNode["connect"](this.filterNode);
  15136. this.inputNode["connect"](this.dryNode);
  15137. this.filterNode["connect"](this.wetNode);
  15138. this.oscNode["connect"](this.oscGainNode);
  15139. this.oscGainNode["connect"](this.filterNode["frequency"]);
  15140. startSource(this.oscNode);
  15141. };
  15142. PhaserEffect.prototype.connectTo = function (node)
  15143. {
  15144. this.dryNode["disconnect"]();
  15145. this.dryNode["connect"](node);
  15146. this.wetNode["disconnect"]();
  15147. this.wetNode["connect"](node);
  15148. };
  15149. PhaserEffect.prototype.remove = function ()
  15150. {
  15151. this.inputNode["disconnect"]();
  15152. this.filterNode["disconnect"]();
  15153. this.oscNode["disconnect"]();
  15154. this.oscGainNode["disconnect"]();
  15155. this.dryNode["disconnect"]();
  15156. this.wetNode["disconnect"]();
  15157. };
  15158. PhaserEffect.prototype.getInputNode = function ()
  15159. {
  15160. return this.inputNode;
  15161. };
  15162. PhaserEffect.prototype.setParam = function(param, value, ramp, time)
  15163. {
  15164. switch (param) {
  15165. case 0: // mix
  15166. value = value / 100;
  15167. if (value < 0) value = 0;
  15168. if (value > 1) value = 1;
  15169. this.params[5] = value;
  15170. setAudioParam(this.wetNode["gain"], value / 2, ramp, time);
  15171. setAudioParam(this.dryNode["gain"], 1 - (value / 2), ramp, time);
  15172. break;
  15173. case 1: // filter frequency
  15174. this.params[0] = value;
  15175. setAudioParam(this.filterNode["frequency"], value, ramp, time);
  15176. break;
  15177. case 2: // filter detune
  15178. this.params[1] = value;
  15179. setAudioParam(this.filterNode["detune"], value, ramp, time);
  15180. break;
  15181. case 3: // filter Q
  15182. this.params[2] = value;
  15183. setAudioParam(this.filterNode["Q"], value, ramp, time);
  15184. break;
  15185. case 6: // modulation
  15186. this.params[3] = value;
  15187. setAudioParam(this.oscGainNode["gain"], value, ramp, time);
  15188. break;
  15189. case 7: // modulation frequency
  15190. this.params[4] = value;
  15191. setAudioParam(this.oscNode["frequency"], value, ramp, time);
  15192. break;
  15193. }
  15194. };
  15195. function GainEffect(g)
  15196. {
  15197. this.type = "gain";
  15198. this.params = [g];
  15199. this.node = createGain();
  15200. this.node["gain"]["value"] = g;
  15201. };
  15202. GainEffect.prototype.connectTo = function (node_)
  15203. {
  15204. this.node["disconnect"]();
  15205. this.node["connect"](node_);
  15206. };
  15207. GainEffect.prototype.remove = function ()
  15208. {
  15209. this.node["disconnect"]();
  15210. };
  15211. GainEffect.prototype.getInputNode = function ()
  15212. {
  15213. return this.node;
  15214. };
  15215. GainEffect.prototype.setParam = function(param, value, ramp, time)
  15216. {
  15217. switch (param) {
  15218. case 4: // gain
  15219. this.params[0] = dbToLinear(value);
  15220. setAudioParam(this.node["gain"], dbToLinear(value), ramp, time);
  15221. break;
  15222. }
  15223. };
  15224. function TremoloEffect(freq, mix)
  15225. {
  15226. this.type = "tremolo";
  15227. this.params = [freq, mix];
  15228. this.node = createGain();
  15229. this.node["gain"]["value"] = 1 - (mix / 2);
  15230. this.oscNode = context["createOscillator"]();
  15231. this.oscNode["frequency"]["value"] = freq;
  15232. this.oscGainNode = createGain();
  15233. this.oscGainNode["gain"]["value"] = mix / 2;
  15234. this.oscNode["connect"](this.oscGainNode);
  15235. this.oscGainNode["connect"](this.node["gain"]);
  15236. startSource(this.oscNode);
  15237. };
  15238. TremoloEffect.prototype.connectTo = function (node_)
  15239. {
  15240. this.node["disconnect"]();
  15241. this.node["connect"](node_);
  15242. };
  15243. TremoloEffect.prototype.remove = function ()
  15244. {
  15245. this.oscNode["disconnect"]();
  15246. this.oscGainNode["disconnect"]();
  15247. this.node["disconnect"]();
  15248. };
  15249. TremoloEffect.prototype.getInputNode = function ()
  15250. {
  15251. return this.node;
  15252. };
  15253. TremoloEffect.prototype.setParam = function(param, value, ramp, time)
  15254. {
  15255. switch (param) {
  15256. case 0: // mix
  15257. value = value / 100;
  15258. if (value < 0) value = 0;
  15259. if (value > 1) value = 1;
  15260. this.params[1] = value;
  15261. setAudioParam(this.node["gain"]["value"], 1 - (value / 2), ramp, time);
  15262. setAudioParam(this.oscGainNode["gain"]["value"], value / 2, ramp, time);
  15263. break;
  15264. case 7: // modulation frequency
  15265. this.params[0] = value;
  15266. setAudioParam(this.oscNode["frequency"], value, ramp, time);
  15267. break;
  15268. }
  15269. };
  15270. function RingModulatorEffect(freq, mix)
  15271. {
  15272. this.type = "ringmod";
  15273. this.params = [freq, mix];
  15274. this.inputNode = createGain();
  15275. this.wetNode = createGain();
  15276. this.wetNode["gain"]["value"] = mix;
  15277. this.dryNode = createGain();
  15278. this.dryNode["gain"]["value"] = 1 - mix;
  15279. this.ringNode = createGain();
  15280. this.ringNode["gain"]["value"] = 0;
  15281. this.oscNode = context["createOscillator"]();
  15282. this.oscNode["frequency"]["value"] = freq;
  15283. this.oscNode["connect"](this.ringNode["gain"]);
  15284. startSource(this.oscNode);
  15285. this.inputNode["connect"](this.ringNode);
  15286. this.inputNode["connect"](this.dryNode);
  15287. this.ringNode["connect"](this.wetNode);
  15288. };
  15289. RingModulatorEffect.prototype.connectTo = function (node_)
  15290. {
  15291. this.wetNode["disconnect"]();
  15292. this.wetNode["connect"](node_);
  15293. this.dryNode["disconnect"]();
  15294. this.dryNode["connect"](node_);
  15295. };
  15296. RingModulatorEffect.prototype.remove = function ()
  15297. {
  15298. this.oscNode["disconnect"]();
  15299. this.ringNode["disconnect"]();
  15300. this.inputNode["disconnect"]();
  15301. this.wetNode["disconnect"]();
  15302. this.dryNode["disconnect"]();
  15303. };
  15304. RingModulatorEffect.prototype.getInputNode = function ()
  15305. {
  15306. return this.inputNode;
  15307. };
  15308. RingModulatorEffect.prototype.setParam = function(param, value, ramp, time)
  15309. {
  15310. switch (param) {
  15311. case 0: // mix
  15312. value = value / 100;
  15313. if (value < 0) value = 0;
  15314. if (value > 1) value = 1;
  15315. this.params[1] = value;
  15316. setAudioParam(this.wetNode["gain"], value, ramp, time);
  15317. setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
  15318. break;
  15319. case 7: // modulation frequency
  15320. this.params[0] = value;
  15321. setAudioParam(this.oscNode["frequency"], value, ramp, time);
  15322. break;
  15323. }
  15324. };
  15325. function DistortionEffect(threshold, headroom, drive, makeupgain, mix)
  15326. {
  15327. this.type = "distortion";
  15328. this.params = [threshold, headroom, drive, makeupgain, mix];
  15329. this.inputNode = createGain();
  15330. this.preGain = createGain();
  15331. this.postGain = createGain();
  15332. this.setDrive(drive, dbToLinear_nocap(makeupgain));
  15333. this.wetNode = createGain();
  15334. this.wetNode["gain"]["value"] = mix;
  15335. this.dryNode = createGain();
  15336. this.dryNode["gain"]["value"] = 1 - mix;
  15337. this.waveShaper = context["createWaveShaper"]();
  15338. this.curve = new Float32Array(65536);
  15339. this.generateColortouchCurve(threshold, headroom);
  15340. this.waveShaper.curve = this.curve;
  15341. this.inputNode["connect"](this.preGain);
  15342. this.inputNode["connect"](this.dryNode);
  15343. this.preGain["connect"](this.waveShaper);
  15344. this.waveShaper["connect"](this.postGain);
  15345. this.postGain["connect"](this.wetNode);
  15346. };
  15347. DistortionEffect.prototype.setDrive = function (drive, makeupgain)
  15348. {
  15349. if (drive < 0.01)
  15350. drive = 0.01;
  15351. this.preGain["gain"]["value"] = drive;
  15352. this.postGain["gain"]["value"] = Math.pow(1 / drive, 0.6) * makeupgain;
  15353. };
  15354. function e4(x, k)
  15355. {
  15356. return 1.0 - Math.exp(-k * x);
  15357. }
  15358. DistortionEffect.prototype.shape = function (x, linearThreshold, linearHeadroom)
  15359. {
  15360. var maximum = 1.05 * linearHeadroom * linearThreshold;
  15361. var kk = (maximum - linearThreshold);
  15362. var sign = x < 0 ? -1 : +1;
  15363. var absx = x < 0 ? -x : x;
  15364. var shapedInput = absx < linearThreshold ? absx : linearThreshold + kk * e4(absx - linearThreshold, 1.0 / kk);
  15365. shapedInput *= sign;
  15366. return shapedInput;
  15367. };
  15368. DistortionEffect.prototype.generateColortouchCurve = function (threshold, headroom)
  15369. {
  15370. var linearThreshold = dbToLinear_nocap(threshold);
  15371. var linearHeadroom = dbToLinear_nocap(headroom);
  15372. var n = 65536;
  15373. var n2 = n / 2;
  15374. var x = 0;
  15375. for (var i = 0; i < n2; ++i) {
  15376. x = i / n2;
  15377. x = this.shape(x, linearThreshold, linearHeadroom);
  15378. this.curve[n2 + i] = x;
  15379. this.curve[n2 - i - 1] = -x;
  15380. }
  15381. };
  15382. DistortionEffect.prototype.connectTo = function (node)
  15383. {
  15384. this.wetNode["disconnect"]();
  15385. this.wetNode["connect"](node);
  15386. this.dryNode["disconnect"]();
  15387. this.dryNode["connect"](node);
  15388. };
  15389. DistortionEffect.prototype.remove = function ()
  15390. {
  15391. this.inputNode["disconnect"]();
  15392. this.preGain["disconnect"]();
  15393. this.waveShaper["disconnect"]();
  15394. this.postGain["disconnect"]();
  15395. this.wetNode["disconnect"]();
  15396. this.dryNode["disconnect"]();
  15397. };
  15398. DistortionEffect.prototype.getInputNode = function ()
  15399. {
  15400. return this.inputNode;
  15401. };
  15402. DistortionEffect.prototype.setParam = function(param, value, ramp, time)
  15403. {
  15404. switch (param) {
  15405. case 0: // mix
  15406. value = value / 100;
  15407. if (value < 0) value = 0;
  15408. if (value > 1) value = 1;
  15409. this.params[4] = value;
  15410. setAudioParam(this.wetNode["gain"], value, ramp, time);
  15411. setAudioParam(this.dryNode["gain"], 1 - value, ramp, time);
  15412. break;
  15413. }
  15414. };
  15415. function CompressorEffect(threshold, knee, ratio, attack, release)
  15416. {
  15417. this.type = "compressor";
  15418. this.params = [threshold, knee, ratio, attack, release];
  15419. this.node = context["createDynamicsCompressor"]();
  15420. try {
  15421. this.node["threshold"]["value"] = threshold;
  15422. this.node["knee"]["value"] = knee;
  15423. this.node["ratio"]["value"] = ratio;
  15424. this.node["attack"]["value"] = attack;
  15425. this.node["release"]["value"] = release;
  15426. }
  15427. catch (e) {}
  15428. };
  15429. CompressorEffect.prototype.connectTo = function (node_)
  15430. {
  15431. this.node["disconnect"]();
  15432. this.node["connect"](node_);
  15433. };
  15434. CompressorEffect.prototype.remove = function ()
  15435. {
  15436. this.node["disconnect"]();
  15437. };
  15438. CompressorEffect.prototype.getInputNode = function ()
  15439. {
  15440. return this.node;
  15441. };
  15442. CompressorEffect.prototype.setParam = function(param, value, ramp, time)
  15443. {
  15444. };
  15445. function AnalyserEffect(fftSize, smoothing)
  15446. {
  15447. this.type = "analyser";
  15448. this.params = [fftSize, smoothing];
  15449. this.node = context["createAnalyser"]();
  15450. this.node["fftSize"] = fftSize;
  15451. this.node["smoothingTimeConstant"] = smoothing;
  15452. this.freqBins = new Float32Array(this.node["frequencyBinCount"]);
  15453. this.signal = new Uint8Array(fftSize);
  15454. this.peak = 0;
  15455. this.rms = 0;
  15456. };
  15457. AnalyserEffect.prototype.tick = function ()
  15458. {
  15459. this.node["getFloatFrequencyData"](this.freqBins);
  15460. this.node["getByteTimeDomainData"](this.signal);
  15461. var fftSize = this.node["fftSize"];
  15462. var i = 0;
  15463. this.peak = 0;
  15464. var rmsSquaredSum = 0;
  15465. var s = 0;
  15466. for ( ; i < fftSize; i++)
  15467. {
  15468. s = (this.signal[i] - 128) / 128;
  15469. if (s < 0)
  15470. s = -s;
  15471. if (this.peak < s)
  15472. this.peak = s;
  15473. rmsSquaredSum += s * s;
  15474. }
  15475. this.peak = linearToDb(this.peak);
  15476. this.rms = linearToDb(Math.sqrt(rmsSquaredSum / fftSize));
  15477. };
  15478. AnalyserEffect.prototype.connectTo = function (node_)
  15479. {
  15480. this.node["disconnect"]();
  15481. this.node["connect"](node_);
  15482. };
  15483. AnalyserEffect.prototype.remove = function ()
  15484. {
  15485. this.node["disconnect"]();
  15486. };
  15487. AnalyserEffect.prototype.getInputNode = function ()
  15488. {
  15489. return this.node;
  15490. };
  15491. AnalyserEffect.prototype.setParam = function(param, value, ramp, time)
  15492. {
  15493. };
  15494. var OT_POS_SAMPLES = 4;
  15495. function ObjectTracker()
  15496. {
  15497. this.obj = null;
  15498. this.loadUid = 0;
  15499. this.speeds = [];
  15500. this.lastX = 0;
  15501. this.lastY = 0;
  15502. this.moveAngle = 0;
  15503. };
  15504. ObjectTracker.prototype.setObject = function (obj_)
  15505. {
  15506. this.obj = obj_;
  15507. if (this.obj)
  15508. {
  15509. this.lastX = this.obj.x;
  15510. this.lastY = this.obj.y;
  15511. }
  15512. cr.clearArray(this.speeds);
  15513. };
  15514. ObjectTracker.prototype.hasObject = function ()
  15515. {
  15516. return !!this.obj;
  15517. };
  15518. ObjectTracker.prototype.tick = function (dt)
  15519. {
  15520. if (!this.obj || dt === 0)
  15521. return;
  15522. this.moveAngle = cr.angleTo(this.lastX, this.lastY, this.obj.x, this.obj.y);
  15523. var s = cr.distanceTo(this.lastX, this.lastY, this.obj.x, this.obj.y) / dt;
  15524. if (this.speeds.length < OT_POS_SAMPLES)
  15525. this.speeds.push(s);
  15526. else
  15527. {
  15528. this.speeds.shift();
  15529. this.speeds.push(s);
  15530. }
  15531. this.lastX = this.obj.x;
  15532. this.lastY = this.obj.y;
  15533. };
  15534. ObjectTracker.prototype.getSpeed = function ()
  15535. {
  15536. if (!this.speeds.length)
  15537. return 0;
  15538. var i, len, sum = 0;
  15539. for (i = 0, len = this.speeds.length; i < len; i++)
  15540. {
  15541. sum += this.speeds[i];
  15542. }
  15543. return sum / this.speeds.length;
  15544. };
  15545. ObjectTracker.prototype.getVelocityX = function ()
  15546. {
  15547. return Math.cos(this.moveAngle) * this.getSpeed();
  15548. };
  15549. ObjectTracker.prototype.getVelocityY = function ()
  15550. {
  15551. return Math.sin(this.moveAngle) * this.getSpeed();
  15552. };
  15553. var iOShadtouch = false; // has had touch input on iOS to work around web audio API muting
  15554. function C2AudioBuffer(src_, is_music)
  15555. {
  15556. this.src = src_;
  15557. this.myapi = api;
  15558. this.is_music = is_music;
  15559. this.added_end_listener = false;
  15560. var self = this;
  15561. this.outNode = null;
  15562. this.mediaSourceNode = null;
  15563. this.panWhenReady = []; // for web audio API positioned sounds
  15564. this.seekWhenReady = 0;
  15565. this.pauseWhenReady = false;
  15566. this.supportWebAudioAPI = false;
  15567. this.failedToLoad = false;
  15568. this.wasEverReady = false; // if a buffer is ever marked as ready, it's permanently considered ready after then.
  15569. if (api === API_WEBAUDIO && is_music)
  15570. {
  15571. this.myapi = API_HTML5;
  15572. this.outNode = createGain();
  15573. }
  15574. this.bufferObject = null; // actual audio object
  15575. this.audioData = null; // web audio api: ajax request result (compressed audio that needs decoding)
  15576. var request;
  15577. switch (this.myapi) {
  15578. case API_HTML5:
  15579. this.bufferObject = new Audio();
  15580. this.bufferObject.crossOrigin = "anonymous";
  15581. this.bufferObject.addEventListener("canplaythrough", function () {
  15582. self.wasEverReady = true; // update loaded state so preload is considered complete
  15583. });
  15584. if (api === API_WEBAUDIO && context["createMediaElementSource"] && !/wiiu/i.test(navigator.userAgent))
  15585. {
  15586. this.supportWebAudioAPI = true; // can be routed through web audio api
  15587. this.bufferObject.addEventListener("canplay", function ()
  15588. {
  15589. if (!self.mediaSourceNode) // protect against this event firing twice
  15590. {
  15591. self.mediaSourceNode = context["createMediaElementSource"](self.bufferObject);
  15592. self.mediaSourceNode["connect"](self.outNode);
  15593. }
  15594. });
  15595. }
  15596. this.bufferObject.autoplay = false; // this is only a source buffer, not an instance
  15597. this.bufferObject.preload = "auto";
  15598. this.bufferObject.src = src_;
  15599. break;
  15600. case API_WEBAUDIO:
  15601. request = new XMLHttpRequest();
  15602. request.open("GET", src_, true);
  15603. request.responseType = "arraybuffer";
  15604. request.onload = function () {
  15605. self.audioData = request.response;
  15606. self.decodeAudioBuffer();
  15607. };
  15608. request.onerror = function () {
  15609. self.failedToLoad = true;
  15610. };
  15611. request.send();
  15612. break;
  15613. case API_CORDOVA:
  15614. this.bufferObject = true;
  15615. break;
  15616. case API_APPMOBI:
  15617. this.bufferObject = true;
  15618. break;
  15619. }
  15620. };
  15621. C2AudioBuffer.prototype.decodeAudioBuffer = function ()
  15622. {
  15623. if (this.bufferObject || !this.audioData)
  15624. return; // audio already decoded or AJAX request not yet complete
  15625. var self = this;
  15626. if (context["decodeAudioData"])
  15627. {
  15628. context["decodeAudioData"](this.audioData, function (buffer) {
  15629. self.bufferObject = buffer;
  15630. self.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
  15631. var p, i, len, a;
  15632. if (!cr.is_undefined(self.playTagWhenReady) && !silent)
  15633. {
  15634. if (self.panWhenReady.length)
  15635. {
  15636. for (i = 0, len = self.panWhenReady.length; i < len; i++)
  15637. {
  15638. p = self.panWhenReady[i];
  15639. a = new C2AudioInstance(self, p.thistag);
  15640. a.setPannerEnabled(true);
  15641. if (typeof p.objUid !== "undefined")
  15642. {
  15643. p.obj = audRuntime.getObjectByUID(p.objUid);
  15644. if (!p.obj)
  15645. continue;
  15646. }
  15647. if (p.obj)
  15648. {
  15649. var px = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, true);
  15650. var py = cr.rotatePtAround(p.obj.x, p.obj.y, -p.obj.layer.getAngle(), listenerX, listenerY, false);
  15651. a.setPan(px, py, cr.to_degrees(p.obj.angle - p.obj.layer.getAngle()), p.ia, p.oa, p.og);
  15652. a.setObject(p.obj);
  15653. }
  15654. else
  15655. {
  15656. a.setPan(p.x, p.y, p.a, p.ia, p.oa, p.og);
  15657. }
  15658. a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
  15659. if (self.pauseWhenReady)
  15660. a.pause();
  15661. audioInstances.push(a);
  15662. }
  15663. cr.clearArray(self.panWhenReady);
  15664. }
  15665. else
  15666. {
  15667. a = new C2AudioInstance(self, self.playTagWhenReady || ""); // sometimes playTagWhenReady is not set - TODO: why?
  15668. a.play(self.loopWhenReady, self.volumeWhenReady, self.seekWhenReady);
  15669. if (self.pauseWhenReady)
  15670. a.pause();
  15671. audioInstances.push(a);
  15672. }
  15673. }
  15674. else if (!cr.is_undefined(self.convolveWhenReady))
  15675. {
  15676. var convolveNode = self.convolveWhenReady.convolveNode;
  15677. convolveNode["normalize"] = self.normalizeWhenReady;
  15678. convolveNode["buffer"] = buffer;
  15679. }
  15680. }, function (e) {
  15681. self.failedToLoad = true;
  15682. });
  15683. }
  15684. else
  15685. {
  15686. this.bufferObject = context["createBuffer"](this.audioData, false);
  15687. this.audioData = null; // clear AJAX response to allow GC and save memory, only need the bufferObject now
  15688. if (!cr.is_undefined(this.playTagWhenReady) && !silent)
  15689. {
  15690. var a = new C2AudioInstance(this, this.playTagWhenReady);
  15691. a.play(this.loopWhenReady, this.volumeWhenReady, this.seekWhenReady);
  15692. if (this.pauseWhenReady)
  15693. a.pause();
  15694. audioInstances.push(a);
  15695. }
  15696. else if (!cr.is_undefined(this.convolveWhenReady))
  15697. {
  15698. var convolveNode = this.convolveWhenReady.convolveNode;
  15699. convolveNode["normalize"] = this.normalizeWhenReady;
  15700. convolveNode["buffer"] = this.bufferObject;
  15701. }
  15702. }
  15703. };
  15704. C2AudioBuffer.prototype.isLoaded = function ()
  15705. {
  15706. switch (this.myapi) {
  15707. case API_HTML5:
  15708. var ret = this.bufferObject["readyState"] >= 4; // HAVE_ENOUGH_DATA
  15709. if (ret)
  15710. this.wasEverReady = true;
  15711. return ret || this.wasEverReady;
  15712. case API_WEBAUDIO:
  15713. return !!this.audioData || !!this.bufferObject;
  15714. case API_CORDOVA:
  15715. return true;
  15716. case API_APPMOBI:
  15717. return true;
  15718. }
  15719. return false;
  15720. };
  15721. C2AudioBuffer.prototype.isLoadedAndDecoded = function ()
  15722. {
  15723. switch (this.myapi) {
  15724. case API_HTML5:
  15725. return this.isLoaded(); // no distinction between loaded and decoded in HTML5 audio, just rely on ready state
  15726. case API_WEBAUDIO:
  15727. return !!this.bufferObject;
  15728. case API_CORDOVA:
  15729. return true;
  15730. case API_APPMOBI:
  15731. return true;
  15732. }
  15733. return false;
  15734. };
  15735. C2AudioBuffer.prototype.hasFailedToLoad = function ()
  15736. {
  15737. switch (this.myapi) {
  15738. case API_HTML5:
  15739. return !!this.bufferObject["error"];
  15740. case API_WEBAUDIO:
  15741. return this.failedToLoad;
  15742. }
  15743. return false;
  15744. };
  15745. function C2AudioInstance(buffer_, tag_)
  15746. {
  15747. var self = this;
  15748. this.tag = tag_;
  15749. this.fresh = true;
  15750. this.stopped = true;
  15751. this.src = buffer_.src;
  15752. this.buffer = buffer_;
  15753. this.myapi = api;
  15754. this.is_music = buffer_.is_music;
  15755. this.playbackRate = 1;
  15756. this.hasPlaybackEnded = true; // ended flag
  15757. this.resume_me = false; // make sure resumes when leaving suspend
  15758. this.is_paused = false;
  15759. this.resume_position = 0; // for web audio api to resume from correct playback position
  15760. this.looping = false;
  15761. this.is_muted = false;
  15762. this.is_silent = false;
  15763. this.volume = 1;
  15764. this.onended_handler = function ()
  15765. {
  15766. if (self.is_paused)
  15767. return;
  15768. if (this !== self.active_buffer)
  15769. return;
  15770. self.hasPlaybackEnded = true;
  15771. self.stopped = true;
  15772. audTag = self.tag;
  15773. audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
  15774. };
  15775. this.active_buffer = null;
  15776. this.isTimescaled = ((timescale_mode === 1 && !this.is_music) || timescale_mode === 2);
  15777. this.mutevol = 1;
  15778. this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum);
  15779. this.gainNode = null;
  15780. this.pannerNode = null;
  15781. this.pannerEnabled = false;
  15782. this.objectTracker = null;
  15783. this.panX = 0;
  15784. this.panY = 0;
  15785. this.panAngle = 0;
  15786. this.panConeInner = 0;
  15787. this.panConeOuter = 0;
  15788. this.panConeOuterGain = 0;
  15789. this.instanceObject = null;
  15790. var add_end_listener = false;
  15791. if (this.myapi === API_WEBAUDIO && this.buffer.myapi === API_HTML5 && !this.buffer.supportWebAudioAPI)
  15792. this.myapi = API_HTML5;
  15793. switch (this.myapi) {
  15794. case API_HTML5:
  15795. if (this.is_music)
  15796. {
  15797. this.instanceObject = buffer_.bufferObject;
  15798. add_end_listener = !buffer_.added_end_listener;
  15799. buffer_.added_end_listener = true;
  15800. }
  15801. else
  15802. {
  15803. this.instanceObject = new Audio();
  15804. this.instanceObject.crossOrigin = "anonymous";
  15805. this.instanceObject.autoplay = false;
  15806. this.instanceObject.src = buffer_.bufferObject.src;
  15807. add_end_listener = true;
  15808. }
  15809. if (add_end_listener)
  15810. {
  15811. this.instanceObject.addEventListener('ended', function () {
  15812. audTag = self.tag;
  15813. self.stopped = true;
  15814. audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
  15815. });
  15816. }
  15817. break;
  15818. case API_WEBAUDIO:
  15819. this.gainNode = createGain();
  15820. this.gainNode["connect"](getDestinationForTag(tag_));
  15821. if (this.buffer.myapi === API_WEBAUDIO)
  15822. {
  15823. if (buffer_.bufferObject)
  15824. {
  15825. this.instanceObject = context["createBufferSource"]();
  15826. this.instanceObject["buffer"] = buffer_.bufferObject;
  15827. this.instanceObject["connect"](this.gainNode);
  15828. }
  15829. }
  15830. else
  15831. {
  15832. this.instanceObject = this.buffer.bufferObject; // reference the audio element
  15833. this.buffer.outNode["connect"](this.gainNode);
  15834. if (!this.buffer.added_end_listener)
  15835. {
  15836. this.buffer.added_end_listener = true;
  15837. this.buffer.bufferObject.addEventListener('ended', function () {
  15838. audTag = self.tag;
  15839. self.stopped = true;
  15840. audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
  15841. });
  15842. }
  15843. }
  15844. break;
  15845. case API_CORDOVA:
  15846. this.instanceObject = new window["Media"](appPath + this.src, null, null, function (status) {
  15847. if (status === window["Media"]["MEDIA_STOPPED"])
  15848. {
  15849. self.hasPlaybackEnded = true;
  15850. self.stopped = true;
  15851. audTag = self.tag;
  15852. audRuntime.trigger(cr.plugins_.Audio.prototype.cnds.OnEnded, audInst);
  15853. }
  15854. });
  15855. break;
  15856. case API_APPMOBI:
  15857. this.instanceObject = true;
  15858. break;
  15859. }
  15860. };
  15861. C2AudioInstance.prototype.hasEnded = function ()
  15862. {
  15863. var time;
  15864. switch (this.myapi) {
  15865. case API_HTML5:
  15866. return this.instanceObject.ended;
  15867. case API_WEBAUDIO:
  15868. if (this.buffer.myapi === API_WEBAUDIO)
  15869. {
  15870. if (!this.fresh && !this.stopped && this.instanceObject["loop"])
  15871. return false;
  15872. if (this.is_paused)
  15873. return false;
  15874. return this.hasPlaybackEnded;
  15875. }
  15876. else
  15877. return this.instanceObject.ended;
  15878. case API_CORDOVA:
  15879. return this.hasPlaybackEnded;
  15880. case API_APPMOBI:
  15881. true; // recycling an AppMobi sound does not matter because it will just do another throwaway playSound
  15882. }
  15883. return true;
  15884. };
  15885. C2AudioInstance.prototype.canBeRecycled = function ()
  15886. {
  15887. if (this.fresh || this.stopped)
  15888. return true; // not yet used or is not playing
  15889. return this.hasEnded();
  15890. };
  15891. C2AudioInstance.prototype.setPannerEnabled = function (enable_)
  15892. {
  15893. if (api !== API_WEBAUDIO)
  15894. return;
  15895. if (!this.pannerEnabled && enable_)
  15896. {
  15897. if (!this.gainNode)
  15898. return;
  15899. if (!this.pannerNode)
  15900. {
  15901. this.pannerNode = context["createPanner"]();
  15902. if (typeof this.pannerNode["panningModel"] === "number")
  15903. this.pannerNode["panningModel"] = panningModel;
  15904. else
  15905. this.pannerNode["panningModel"] = ["equalpower", "HRTF", "soundfield"][panningModel];
  15906. if (typeof this.pannerNode["distanceModel"] === "number")
  15907. this.pannerNode["distanceModel"] = distanceModel;
  15908. else
  15909. this.pannerNode["distanceModel"] = ["linear", "inverse", "exponential"][distanceModel];
  15910. this.pannerNode["refDistance"] = refDistance;
  15911. this.pannerNode["maxDistance"] = maxDistance;
  15912. this.pannerNode["rolloffFactor"] = rolloffFactor;
  15913. }
  15914. this.gainNode["disconnect"]();
  15915. this.gainNode["connect"](this.pannerNode);
  15916. this.pannerNode["connect"](getDestinationForTag(this.tag));
  15917. this.pannerEnabled = true;
  15918. }
  15919. else if (this.pannerEnabled && !enable_)
  15920. {
  15921. if (!this.gainNode)
  15922. return;
  15923. this.pannerNode["disconnect"]();
  15924. this.gainNode["disconnect"]();
  15925. this.gainNode["connect"](getDestinationForTag(this.tag));
  15926. this.pannerEnabled = false;
  15927. }
  15928. };
  15929. C2AudioInstance.prototype.setPan = function (x, y, angle, innerangle, outerangle, outergain)
  15930. {
  15931. if (!this.pannerEnabled || api !== API_WEBAUDIO)
  15932. return;
  15933. this.pannerNode["setPosition"](x, y, 0);
  15934. this.pannerNode["setOrientation"](Math.cos(cr.to_radians(angle)), Math.sin(cr.to_radians(angle)), 0);
  15935. this.pannerNode["coneInnerAngle"] = innerangle;
  15936. this.pannerNode["coneOuterAngle"] = outerangle;
  15937. this.pannerNode["coneOuterGain"] = outergain;
  15938. this.panX = x;
  15939. this.panY = y;
  15940. this.panAngle = angle;
  15941. this.panConeInner = innerangle;
  15942. this.panConeOuter = outerangle;
  15943. this.panConeOuterGain = outergain;
  15944. };
  15945. C2AudioInstance.prototype.setObject = function (o)
  15946. {
  15947. if (!this.pannerEnabled || api !== API_WEBAUDIO)
  15948. return;
  15949. if (!this.objectTracker)
  15950. this.objectTracker = new ObjectTracker();
  15951. this.objectTracker.setObject(o);
  15952. };
  15953. C2AudioInstance.prototype.tick = function (dt)
  15954. {
  15955. if (!this.pannerEnabled || api !== API_WEBAUDIO || !this.objectTracker || !this.objectTracker.hasObject() || !this.isPlaying())
  15956. {
  15957. return;
  15958. }
  15959. this.objectTracker.tick(dt);
  15960. var inst = this.objectTracker.obj;
  15961. var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
  15962. var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
  15963. this.pannerNode["setPosition"](px, py, 0);
  15964. var a = 0;
  15965. if (typeof this.objectTracker.obj.angle !== "undefined")
  15966. {
  15967. a = inst.angle - inst.layer.getAngle();
  15968. this.pannerNode["setOrientation"](Math.cos(a), Math.sin(a), 0);
  15969. }
  15970. px = cr.rotatePtAround(this.objectTracker.getVelocityX(), this.objectTracker.getVelocityY(), -inst.layer.getAngle(), 0, 0, true);
  15971. py = cr.rotatePtAround(this.objectTracker.getVelocityX(), this.objectTracker.getVelocityY(), -inst.layer.getAngle(), 0, 0, false);
  15972. this.pannerNode["setVelocity"](px, py, 0);
  15973. };
  15974. C2AudioInstance.prototype.play = function (looping, vol, fromPosition)
  15975. {
  15976. var instobj = this.instanceObject;
  15977. this.looping = looping;
  15978. this.volume = vol;
  15979. var seekPos = fromPosition || 0;
  15980. switch (this.myapi) {
  15981. case API_HTML5:
  15982. if (instobj.playbackRate !== 1.0)
  15983. instobj.playbackRate = 1.0;
  15984. if (instobj.volume !== vol * masterVolume)
  15985. instobj.volume = vol * masterVolume;
  15986. if (instobj.loop !== looping)
  15987. instobj.loop = looping;
  15988. if (instobj.muted)
  15989. instobj.muted = false;
  15990. if (instobj.currentTime !== seekPos)
  15991. {
  15992. try {
  15993. instobj.currentTime = seekPos;
  15994. }
  15995. catch (err)
  15996. {
  15997. ;
  15998. }
  15999. }
  16000. if (this.is_music && isMusicWorkaround && !audRuntime.isInUserInputEvent)
  16001. musicPlayNextTouch.push(this);
  16002. else
  16003. {
  16004. try {
  16005. this.instanceObject.play();
  16006. }
  16007. catch (e) { // sometimes throws on WP8.1... try not to kill the app
  16008. if (console && console.log)
  16009. console.log("[C2] WARNING: exception trying to play audio '" + this.buffer.src + "': ", e);
  16010. }
  16011. }
  16012. break;
  16013. case API_WEBAUDIO:
  16014. this.muted = false;
  16015. this.mutevol = 1;
  16016. if (this.buffer.myapi === API_WEBAUDIO)
  16017. {
  16018. this.gainNode["gain"]["value"] = vol * masterVolume;
  16019. if (!this.fresh)
  16020. {
  16021. this.instanceObject = context["createBufferSource"]();
  16022. this.instanceObject["buffer"] = this.buffer.bufferObject;
  16023. this.instanceObject["connect"](this.gainNode);
  16024. }
  16025. this.instanceObject["onended"] = this.onended_handler;
  16026. this.active_buffer = this.instanceObject;
  16027. this.instanceObject.loop = looping;
  16028. this.hasPlaybackEnded = false;
  16029. if (seekPos === 0)
  16030. startSource(this.instanceObject);
  16031. else
  16032. startSourceAt(this.instanceObject, seekPos, this.getDuration());
  16033. }
  16034. else
  16035. {
  16036. if (instobj.playbackRate !== 1.0)
  16037. instobj.playbackRate = 1.0;
  16038. if (instobj.loop !== looping)
  16039. instobj.loop = looping;
  16040. instobj.volume = vol * masterVolume;
  16041. if (instobj.currentTime !== seekPos)
  16042. {
  16043. try {
  16044. instobj.currentTime = seekPos;
  16045. }
  16046. catch (err)
  16047. {
  16048. ;
  16049. }
  16050. }
  16051. if (this.is_music && isMusicWorkaround && !audRuntime.isInUserInputEvent)
  16052. musicPlayNextTouch.push(this);
  16053. else
  16054. instobj.play();
  16055. }
  16056. break;
  16057. case API_CORDOVA:
  16058. if ((!this.fresh && this.stopped) || seekPos !== 0)
  16059. instobj["seekTo"](seekPos);
  16060. instobj["play"]();
  16061. this.hasPlaybackEnded = false;
  16062. break;
  16063. case API_APPMOBI:
  16064. if (audRuntime.isDirectCanvas)
  16065. AppMobi["context"]["playSound"](this.src, looping);
  16066. else
  16067. AppMobi["player"]["playSound"](this.src, looping);
  16068. break;
  16069. }
  16070. this.playbackRate = 1;
  16071. this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - seekPos;
  16072. this.fresh = false;
  16073. this.stopped = false;
  16074. this.is_paused = false;
  16075. };
  16076. C2AudioInstance.prototype.stop = function ()
  16077. {
  16078. switch (this.myapi) {
  16079. case API_HTML5:
  16080. if (!this.instanceObject.paused)
  16081. this.instanceObject.pause();
  16082. break;
  16083. case API_WEBAUDIO:
  16084. if (this.buffer.myapi === API_WEBAUDIO)
  16085. stopSource(this.instanceObject);
  16086. else
  16087. {
  16088. if (!this.instanceObject.paused)
  16089. this.instanceObject.pause();
  16090. }
  16091. break;
  16092. case API_CORDOVA:
  16093. this.instanceObject["stop"]();
  16094. break;
  16095. case API_APPMOBI:
  16096. if (audRuntime.isDirectCanvas)
  16097. AppMobi["context"]["stopSound"](this.src);
  16098. break;
  16099. }
  16100. this.stopped = true;
  16101. this.is_paused = false;
  16102. };
  16103. C2AudioInstance.prototype.pause = function ()
  16104. {
  16105. if (this.fresh || this.stopped || this.hasEnded() || this.is_paused)
  16106. return;
  16107. switch (this.myapi) {
  16108. case API_HTML5:
  16109. if (!this.instanceObject.paused)
  16110. this.instanceObject.pause();
  16111. break;
  16112. case API_WEBAUDIO:
  16113. if (this.buffer.myapi === API_WEBAUDIO)
  16114. {
  16115. this.resume_position = this.getPlaybackTime();
  16116. if (this.looping)
  16117. this.resume_position = this.resume_position % this.getDuration();
  16118. this.is_paused = true;
  16119. stopSource(this.instanceObject);
  16120. }
  16121. else
  16122. {
  16123. if (!this.instanceObject.paused)
  16124. this.instanceObject.pause();
  16125. }
  16126. break;
  16127. case API_CORDOVA:
  16128. this.instanceObject["pause"]();
  16129. break;
  16130. case API_APPMOBI:
  16131. if (audRuntime.isDirectCanvas)
  16132. AppMobi["context"]["stopSound"](this.src);
  16133. break;
  16134. }
  16135. this.is_paused = true;
  16136. };
  16137. C2AudioInstance.prototype.resume = function ()
  16138. {
  16139. if (this.fresh || this.stopped || this.hasEnded() || !this.is_paused)
  16140. return;
  16141. switch (this.myapi) {
  16142. case API_HTML5:
  16143. this.instanceObject.play();
  16144. break;
  16145. case API_WEBAUDIO:
  16146. if (this.buffer.myapi === API_WEBAUDIO)
  16147. {
  16148. this.instanceObject = context["createBufferSource"]();
  16149. this.instanceObject["buffer"] = this.buffer.bufferObject;
  16150. this.instanceObject["connect"](this.gainNode);
  16151. this.instanceObject["onended"] = this.onended_handler;
  16152. this.active_buffer = this.instanceObject;
  16153. this.instanceObject.loop = this.looping;
  16154. this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
  16155. this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.resume_position;
  16156. startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
  16157. }
  16158. else
  16159. {
  16160. this.instanceObject.play();
  16161. }
  16162. break;
  16163. case API_CORDOVA:
  16164. this.instanceObject["play"]();
  16165. break;
  16166. case API_APPMOBI:
  16167. if (audRuntime.isDirectCanvas)
  16168. AppMobi["context"]["resumeSound"](this.src);
  16169. break;
  16170. }
  16171. this.is_paused = false;
  16172. };
  16173. C2AudioInstance.prototype.seek = function (pos)
  16174. {
  16175. if (this.fresh || this.stopped || this.hasEnded())
  16176. return;
  16177. switch (this.myapi) {
  16178. case API_HTML5:
  16179. try {
  16180. this.instanceObject.currentTime = pos;
  16181. }
  16182. catch (e) {}
  16183. break;
  16184. case API_WEBAUDIO:
  16185. if (this.buffer.myapi === API_WEBAUDIO)
  16186. {
  16187. if (this.is_paused)
  16188. this.resume_position = pos;
  16189. else
  16190. {
  16191. this.pause();
  16192. this.resume_position = pos;
  16193. this.resume();
  16194. }
  16195. }
  16196. else
  16197. {
  16198. try {
  16199. this.instanceObject.currentTime = pos;
  16200. }
  16201. catch (e) {}
  16202. }
  16203. break;
  16204. case API_CORDOVA:
  16205. break;
  16206. case API_APPMOBI:
  16207. if (audRuntime.isDirectCanvas)
  16208. AppMobi["context"]["seekSound"](this.src, pos);
  16209. break;
  16210. }
  16211. };
  16212. C2AudioInstance.prototype.reconnect = function (toNode)
  16213. {
  16214. if (this.myapi !== API_WEBAUDIO)
  16215. return;
  16216. if (this.pannerEnabled)
  16217. {
  16218. this.pannerNode["disconnect"]();
  16219. this.pannerNode["connect"](toNode);
  16220. }
  16221. else
  16222. {
  16223. this.gainNode["disconnect"]();
  16224. this.gainNode["connect"](toNode);
  16225. }
  16226. };
  16227. C2AudioInstance.prototype.getDuration = function ()
  16228. {
  16229. switch (this.myapi) {
  16230. case API_HTML5:
  16231. if (typeof this.instanceObject.duration !== "undefined")
  16232. return this.instanceObject.duration;
  16233. else
  16234. return 0;
  16235. case API_WEBAUDIO:
  16236. return this.buffer.bufferObject["duration"];
  16237. case API_CORDOVA:
  16238. return this.instanceObject["getDuration"]();
  16239. case API_APPMOBI:
  16240. if (audRuntime.isDirectCanvas)
  16241. return AppMobi["context"]["getDurationSound"](this.src);
  16242. else
  16243. return 0;
  16244. }
  16245. return 0;
  16246. };
  16247. C2AudioInstance.prototype.getPlaybackTime = function ()
  16248. {
  16249. var duration = this.getDuration();
  16250. var ret = 0;
  16251. switch (this.myapi) {
  16252. case API_HTML5:
  16253. if (typeof this.instanceObject.currentTime !== "undefined")
  16254. ret = this.instanceObject.currentTime;
  16255. break;
  16256. case API_WEBAUDIO:
  16257. if (this.buffer.myapi === API_WEBAUDIO)
  16258. {
  16259. if (this.is_paused)
  16260. return this.resume_position;
  16261. else
  16262. ret = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.startTime;
  16263. }
  16264. else if (typeof this.instanceObject.currentTime !== "undefined")
  16265. ret = this.instanceObject.currentTime;
  16266. break;
  16267. case API_CORDOVA:
  16268. break;
  16269. case API_APPMOBI:
  16270. if (audRuntime.isDirectCanvas)
  16271. ret = AppMobi["context"]["getPlaybackTimeSound"](this.src);
  16272. break;
  16273. }
  16274. if (!this.looping && ret > duration)
  16275. ret = duration;
  16276. return ret;
  16277. };
  16278. C2AudioInstance.prototype.isPlaying = function ()
  16279. {
  16280. return !this.is_paused && !this.fresh && !this.stopped && !this.hasEnded();
  16281. };
  16282. C2AudioInstance.prototype.setVolume = function (v)
  16283. {
  16284. this.volume = v;
  16285. this.updateVolume();
  16286. };
  16287. C2AudioInstance.prototype.updateVolume = function ()
  16288. {
  16289. var volToSet = this.volume * masterVolume;
  16290. if (!isFinite(volToSet))
  16291. volToSet = 0; // HTMLMediaElement throws if setting non-finite volume
  16292. switch (this.myapi) {
  16293. case API_HTML5:
  16294. if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
  16295. this.instanceObject.volume = volToSet;
  16296. break;
  16297. case API_WEBAUDIO:
  16298. if (this.buffer.myapi === API_WEBAUDIO)
  16299. {
  16300. this.gainNode["gain"]["value"] = volToSet * this.mutevol;
  16301. }
  16302. else
  16303. {
  16304. if (typeof this.instanceObject.volume !== "undefined" && this.instanceObject.volume !== volToSet)
  16305. this.instanceObject.volume = volToSet;
  16306. }
  16307. break;
  16308. case API_CORDOVA:
  16309. break;
  16310. case API_APPMOBI:
  16311. break;
  16312. }
  16313. };
  16314. C2AudioInstance.prototype.getVolume = function ()
  16315. {
  16316. return this.volume;
  16317. };
  16318. C2AudioInstance.prototype.doSetMuted = function (m)
  16319. {
  16320. switch (this.myapi) {
  16321. case API_HTML5:
  16322. if (this.instanceObject.muted !== !!m)
  16323. this.instanceObject.muted = !!m;
  16324. break;
  16325. case API_WEBAUDIO:
  16326. if (this.buffer.myapi === API_WEBAUDIO)
  16327. {
  16328. this.mutevol = (m ? 0 : 1);
  16329. this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
  16330. }
  16331. else
  16332. {
  16333. if (this.instanceObject.muted !== !!m)
  16334. this.instanceObject.muted = !!m;
  16335. }
  16336. break;
  16337. case API_CORDOVA:
  16338. break;
  16339. case API_APPMOBI:
  16340. break;
  16341. }
  16342. };
  16343. C2AudioInstance.prototype.setMuted = function (m)
  16344. {
  16345. this.is_muted = !!m;
  16346. this.doSetMuted(this.is_muted || this.is_silent);
  16347. };
  16348. C2AudioInstance.prototype.setSilent = function (m)
  16349. {
  16350. this.is_silent = !!m;
  16351. this.doSetMuted(this.is_muted || this.is_silent);
  16352. };
  16353. C2AudioInstance.prototype.setLooping = function (l)
  16354. {
  16355. this.looping = l;
  16356. switch (this.myapi) {
  16357. case API_HTML5:
  16358. if (this.instanceObject.loop !== !!l)
  16359. this.instanceObject.loop = !!l;
  16360. break;
  16361. case API_WEBAUDIO:
  16362. if (this.instanceObject.loop !== !!l)
  16363. this.instanceObject.loop = !!l;
  16364. break;
  16365. case API_CORDOVA:
  16366. break;
  16367. case API_APPMOBI:
  16368. if (audRuntime.isDirectCanvas)
  16369. AppMobi["context"]["setLoopingSound"](this.src, l);
  16370. break;
  16371. }
  16372. };
  16373. C2AudioInstance.prototype.setPlaybackRate = function (r)
  16374. {
  16375. this.playbackRate = r;
  16376. this.updatePlaybackRate();
  16377. };
  16378. C2AudioInstance.prototype.updatePlaybackRate = function ()
  16379. {
  16380. var r = this.playbackRate;
  16381. if (this.isTimescaled)
  16382. r *= audRuntime.timescale;
  16383. switch (this.myapi) {
  16384. case API_HTML5:
  16385. if (this.instanceObject.playbackRate !== r)
  16386. this.instanceObject.playbackRate = r;
  16387. break;
  16388. case API_WEBAUDIO:
  16389. if (this.buffer.myapi === API_WEBAUDIO)
  16390. {
  16391. if (this.instanceObject["playbackRate"]["value"] !== r)
  16392. this.instanceObject["playbackRate"]["value"] = r;
  16393. }
  16394. else
  16395. {
  16396. if (this.instanceObject.playbackRate !== r)
  16397. this.instanceObject.playbackRate = r;
  16398. }
  16399. break;
  16400. case API_CORDOVA:
  16401. break;
  16402. case API_APPMOBI:
  16403. break;
  16404. }
  16405. };
  16406. C2AudioInstance.prototype.setSuspended = function (s)
  16407. {
  16408. switch (this.myapi) {
  16409. case API_HTML5:
  16410. if (s)
  16411. {
  16412. if (this.isPlaying())
  16413. {
  16414. this.instanceObject["pause"]();
  16415. this.resume_me = true;
  16416. }
  16417. else
  16418. this.resume_me = false;
  16419. }
  16420. else
  16421. {
  16422. if (this.resume_me)
  16423. this.instanceObject["play"]();
  16424. }
  16425. break;
  16426. case API_WEBAUDIO:
  16427. if (s)
  16428. {
  16429. if (this.isPlaying())
  16430. {
  16431. if (this.buffer.myapi === API_WEBAUDIO)
  16432. {
  16433. this.resume_position = this.getPlaybackTime();
  16434. if (this.looping)
  16435. this.resume_position = this.resume_position % this.getDuration();
  16436. stopSource(this.instanceObject);
  16437. }
  16438. else
  16439. this.instanceObject["pause"]();
  16440. this.resume_me = true;
  16441. }
  16442. else
  16443. this.resume_me = false;
  16444. }
  16445. else
  16446. {
  16447. if (this.resume_me)
  16448. {
  16449. if (this.buffer.myapi === API_WEBAUDIO)
  16450. {
  16451. this.instanceObject = context["createBufferSource"]();
  16452. this.instanceObject["buffer"] = this.buffer.bufferObject;
  16453. this.instanceObject["connect"](this.gainNode);
  16454. this.instanceObject["onended"] = this.onended_handler;
  16455. this.active_buffer = this.instanceObject;
  16456. this.instanceObject.loop = this.looping;
  16457. this.gainNode["gain"]["value"] = masterVolume * this.volume * this.mutevol;
  16458. this.startTime = (this.isTimescaled ? audRuntime.kahanTime.sum : audRuntime.wallTime.sum) - this.resume_position;
  16459. startSourceAt(this.instanceObject, this.resume_position, this.getDuration());
  16460. }
  16461. else
  16462. {
  16463. this.instanceObject["play"]();
  16464. }
  16465. }
  16466. }
  16467. break;
  16468. case API_CORDOVA:
  16469. if (s)
  16470. {
  16471. if (this.isPlaying())
  16472. {
  16473. this.instanceObject["pause"]();
  16474. this.resume_me = true;
  16475. }
  16476. else
  16477. this.resume_me = false;
  16478. }
  16479. else
  16480. {
  16481. if (this.resume_me)
  16482. this.instanceObject["play"]();
  16483. }
  16484. break;
  16485. case API_APPMOBI:
  16486. break;
  16487. }
  16488. };
  16489. pluginProto.Instance = function(type)
  16490. {
  16491. this.type = type;
  16492. this.runtime = type.runtime;
  16493. audRuntime = this.runtime;
  16494. audInst = this;
  16495. this.listenerTracker = null;
  16496. this.listenerZ = -600;
  16497. if ((this.runtime.isiOS || (this.runtime.isAndroid && (this.runtime.isChrome || this.runtime.isAndroidStockBrowser))) && !this.runtime.isCrosswalk && !this.runtime.isDomFree && !this.runtime.isAmazonWebApp)
  16498. {
  16499. isMusicWorkaround = true;
  16500. }
  16501. context = null;
  16502. if (typeof AudioContext !== "undefined")
  16503. {
  16504. api = API_WEBAUDIO;
  16505. context = new AudioContext();
  16506. }
  16507. else if (typeof webkitAudioContext !== "undefined")
  16508. {
  16509. api = API_WEBAUDIO;
  16510. context = new webkitAudioContext();
  16511. }
  16512. if ((this.runtime.isiOS && api === API_WEBAUDIO) || isMusicWorkaround)
  16513. {
  16514. document.addEventListener("touchstart", function ()
  16515. {
  16516. var i, len, m;
  16517. if (!iOShadtouch && context)
  16518. {
  16519. var buffer = context["createBuffer"](1, 1, 22050);
  16520. var source = context["createBufferSource"]();
  16521. source["buffer"] = buffer;
  16522. source["connect"](context["destination"]);
  16523. startSource(source);
  16524. iOShadtouch = true;
  16525. }
  16526. if (isMusicWorkaround)
  16527. {
  16528. if (!silent)
  16529. {
  16530. for (i = 0, len = musicPlayNextTouch.length; i < len; ++i)
  16531. {
  16532. m = musicPlayNextTouch[i];
  16533. if (!m.stopped && !m.is_paused)
  16534. m.instanceObject.play();
  16535. }
  16536. }
  16537. cr.clearArray(musicPlayNextTouch);
  16538. }
  16539. }, true);
  16540. }
  16541. if (api !== API_WEBAUDIO)
  16542. {
  16543. if (this.runtime.isCordova && typeof window["Media"] !== "undefined")
  16544. api = API_CORDOVA;
  16545. else if (this.runtime.isAppMobi)
  16546. api = API_APPMOBI;
  16547. }
  16548. if (api === API_CORDOVA)
  16549. {
  16550. appPath = location.href;
  16551. var i = appPath.lastIndexOf("/");
  16552. if (i > -1)
  16553. appPath = appPath.substr(0, i + 1);
  16554. appPath = appPath.replace("file://", "");
  16555. }
  16556. if (this.runtime.isSafari && this.runtime.isWindows && typeof Audio === "undefined")
  16557. {
  16558. alert("It looks like you're using Safari for Windows without Quicktime. Audio cannot be played until Quicktime is installed.");
  16559. this.runtime.DestroyInstance(this);
  16560. }
  16561. else
  16562. {
  16563. if (this.runtime.isDirectCanvas)
  16564. useOgg = this.runtime.isAndroid; // AAC on iOS, OGG on Android
  16565. else
  16566. {
  16567. try {
  16568. useOgg = !!(new Audio().canPlayType('audio/ogg; codecs="vorbis"'));
  16569. }
  16570. catch (e)
  16571. {
  16572. useOgg = false;
  16573. }
  16574. }
  16575. switch (api) {
  16576. case API_HTML5:
  16577. ;
  16578. break;
  16579. case API_WEBAUDIO:
  16580. ;
  16581. break;
  16582. case API_CORDOVA:
  16583. ;
  16584. break;
  16585. case API_APPMOBI:
  16586. ;
  16587. break;
  16588. default:
  16589. ;
  16590. }
  16591. this.runtime.tickMe(this);
  16592. }
  16593. };
  16594. var instanceProto = pluginProto.Instance.prototype;
  16595. instanceProto.onCreate = function ()
  16596. {
  16597. this.runtime.audioInstance = this;
  16598. timescale_mode = this.properties[0]; // 0 = off, 1 = sounds only, 2 = all
  16599. this.saveload = this.properties[1]; // 0 = all, 1 = sounds only, 2 = music only, 3 = none
  16600. this.playinbackground = (this.properties[2] !== 0);
  16601. panningModel = this.properties[3]; // 0 = equalpower, 1 = hrtf, 3 = soundfield
  16602. distanceModel = this.properties[4]; // 0 = linear, 1 = inverse, 2 = exponential
  16603. this.listenerZ = -this.properties[5];
  16604. refDistance = this.properties[6];
  16605. maxDistance = this.properties[7];
  16606. rolloffFactor = this.properties[8];
  16607. this.listenerTracker = new ObjectTracker();
  16608. var draw_width = (this.runtime.draw_width || this.runtime.width);
  16609. var draw_height = (this.runtime.draw_height || this.runtime.height);
  16610. if (api === API_WEBAUDIO)
  16611. {
  16612. if (typeof context["listener"]["dopplerFactor"] !== "undefined")
  16613. context["listener"]["dopplerFactor"] = 0;
  16614. context["listener"]["setPosition"](draw_width / 2, draw_height / 2, this.listenerZ);
  16615. context["listener"]["setOrientation"](0, 0, 1, 0, -1, 0);
  16616. window["c2OnAudioMicStream"] = function (localMediaStream, tag)
  16617. {
  16618. if (micSource)
  16619. micSource["disconnect"]();
  16620. micTag = tag.toLowerCase();
  16621. micSource = context["createMediaStreamSource"](localMediaStream);
  16622. micSource["connect"](getDestinationForTag(micTag));
  16623. };
  16624. }
  16625. this.runtime.addSuspendCallback(function(s)
  16626. {
  16627. audInst.onSuspend(s);
  16628. });
  16629. var self = this;
  16630. this.runtime.addDestroyCallback(function (inst)
  16631. {
  16632. self.onInstanceDestroyed(inst);
  16633. });
  16634. };
  16635. instanceProto.onInstanceDestroyed = function (inst)
  16636. {
  16637. var i, len, a;
  16638. for (i = 0, len = audioInstances.length; i < len; i++)
  16639. {
  16640. a = audioInstances[i];
  16641. if (a.objectTracker)
  16642. {
  16643. if (a.objectTracker.obj === inst)
  16644. {
  16645. a.objectTracker.obj = null;
  16646. if (a.pannerEnabled && a.isPlaying() && a.looping)
  16647. a.stop();
  16648. }
  16649. }
  16650. }
  16651. if (this.listenerTracker.obj === inst)
  16652. this.listenerTracker.obj = null;
  16653. };
  16654. instanceProto.saveToJSON = function ()
  16655. {
  16656. var o = {
  16657. "silent": silent,
  16658. "masterVolume": masterVolume,
  16659. "listenerZ": this.listenerZ,
  16660. "listenerUid": this.listenerTracker.hasObject() ? this.listenerTracker.obj.uid : -1,
  16661. "playing": [],
  16662. "effects": {}
  16663. };
  16664. var playingarr = o["playing"];
  16665. var i, len, a, d, p, panobj, playbackTime;
  16666. for (i = 0, len = audioInstances.length; i < len; i++)
  16667. {
  16668. a = audioInstances[i];
  16669. if (!a.isPlaying())
  16670. continue; // no need to save stopped sounds
  16671. if (this.saveload === 3) // not saving/loading any sounds/music
  16672. continue;
  16673. if (a.is_music && this.saveload === 1) // not saving/loading music
  16674. continue;
  16675. if (!a.is_music && this.saveload === 2) // not saving/loading sound
  16676. continue;
  16677. playbackTime = a.getPlaybackTime();
  16678. if (a.looping)
  16679. playbackTime = playbackTime % a.getDuration();
  16680. d = {
  16681. "tag": a.tag,
  16682. "buffersrc": a.buffer.src,
  16683. "is_music": a.is_music,
  16684. "playbackTime": playbackTime,
  16685. "volume": a.volume,
  16686. "looping": a.looping,
  16687. "muted": a.is_muted,
  16688. "playbackRate": a.playbackRate,
  16689. "paused": a.is_paused,
  16690. "resume_position": a.resume_position
  16691. };
  16692. if (a.pannerEnabled)
  16693. {
  16694. d["pan"] = {};
  16695. panobj = d["pan"];
  16696. if (a.objectTracker && a.objectTracker.hasObject())
  16697. {
  16698. panobj["objUid"] = a.objectTracker.obj.uid;
  16699. }
  16700. else
  16701. {
  16702. panobj["x"] = a.panX;
  16703. panobj["y"] = a.panY;
  16704. panobj["a"] = a.panAngle;
  16705. }
  16706. panobj["ia"] = a.panConeInner;
  16707. panobj["oa"] = a.panConeOuter;
  16708. panobj["og"] = a.panConeOuterGain;
  16709. }
  16710. playingarr.push(d);
  16711. }
  16712. var fxobj = o["effects"];
  16713. var fxarr;
  16714. for (p in effects)
  16715. {
  16716. if (effects.hasOwnProperty(p))
  16717. {
  16718. fxarr = [];
  16719. for (i = 0, len = effects[p].length; i < len; i++)
  16720. {
  16721. fxarr.push({ "type": effects[p][i].type, "params": effects[p][i].params });
  16722. }
  16723. fxobj[p] = fxarr;
  16724. }
  16725. }
  16726. return o;
  16727. };
  16728. var objectTrackerUidsToLoad = [];
  16729. instanceProto.loadFromJSON = function (o)
  16730. {
  16731. var setSilent = o["silent"];
  16732. masterVolume = o["masterVolume"];
  16733. this.listenerZ = o["listenerZ"];
  16734. this.listenerTracker.setObject(null);
  16735. var listenerUid = o["listenerUid"];
  16736. if (listenerUid !== -1)
  16737. {
  16738. this.listenerTracker.loadUid = listenerUid;
  16739. objectTrackerUidsToLoad.push(this.listenerTracker);
  16740. }
  16741. var playingarr = o["playing"];
  16742. var i, len, d, src, is_music, tag, playbackTime, looping, vol, b, a, p, pan, panObjUid;
  16743. if (this.saveload !== 3)
  16744. {
  16745. for (i = 0, len = audioInstances.length; i < len; i++)
  16746. {
  16747. a = audioInstances[i];
  16748. if (a.is_music && this.saveload === 1)
  16749. continue; // only saving/loading sound: leave music playing
  16750. if (!a.is_music && this.saveload === 2)
  16751. continue; // only saving/loading music: leave sound playing
  16752. a.stop();
  16753. }
  16754. }
  16755. var fxarr, fxtype, fxparams, fx;
  16756. for (p in effects)
  16757. {
  16758. if (effects.hasOwnProperty(p))
  16759. {
  16760. for (i = 0, len = effects[p].length; i < len; i++)
  16761. effects[p][i].remove();
  16762. }
  16763. }
  16764. cr.wipe(effects);
  16765. for (p in o["effects"])
  16766. {
  16767. if (o["effects"].hasOwnProperty(p))
  16768. {
  16769. fxarr = o["effects"][p];
  16770. for (i = 0, len = fxarr.length; i < len; i++)
  16771. {
  16772. fxtype = fxarr[i]["type"];
  16773. fxparams = fxarr[i]["params"];
  16774. switch (fxtype) {
  16775. case "filter":
  16776. addEffectForTag(p, new FilterEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
  16777. break;
  16778. case "delay":
  16779. addEffectForTag(p, new DelayEffect(fxparams[0], fxparams[1], fxparams[2]));
  16780. break;
  16781. case "convolve":
  16782. src = fxparams[2];
  16783. b = this.getAudioBuffer(src, false);
  16784. if (b.bufferObject)
  16785. {
  16786. fx = new ConvolveEffect(b.bufferObject, fxparams[0], fxparams[1], src);
  16787. }
  16788. else
  16789. {
  16790. fx = new ConvolveEffect(null, fxparams[0], fxparams[1], src);
  16791. b.normalizeWhenReady = fxparams[0];
  16792. b.convolveWhenReady = fx;
  16793. }
  16794. addEffectForTag(p, fx);
  16795. break;
  16796. case "flanger":
  16797. addEffectForTag(p, new FlangerEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
  16798. break;
  16799. case "phaser":
  16800. addEffectForTag(p, new PhaserEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4], fxparams[5]));
  16801. break;
  16802. case "gain":
  16803. addEffectForTag(p, new GainEffect(fxparams[0]));
  16804. break;
  16805. case "tremolo":
  16806. addEffectForTag(p, new TremoloEffect(fxparams[0], fxparams[1]));
  16807. break;
  16808. case "ringmod":
  16809. addEffectForTag(p, new RingModulatorEffect(fxparams[0], fxparams[1]));
  16810. break;
  16811. case "distortion":
  16812. addEffectForTag(p, new DistortionEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
  16813. break;
  16814. case "compressor":
  16815. addEffectForTag(p, new CompressorEffect(fxparams[0], fxparams[1], fxparams[2], fxparams[3], fxparams[4]));
  16816. break;
  16817. case "analyser":
  16818. addEffectForTag(p, new AnalyserEffect(fxparams[0], fxparams[1]));
  16819. break;
  16820. }
  16821. }
  16822. }
  16823. }
  16824. for (i = 0, len = playingarr.length; i < len; i++)
  16825. {
  16826. if (this.saveload === 3) // not saving/loading any sounds/music
  16827. continue;
  16828. d = playingarr[i];
  16829. src = d["buffersrc"];
  16830. is_music = d["is_music"];
  16831. tag = d["tag"];
  16832. playbackTime = d["playbackTime"];
  16833. looping = d["looping"];
  16834. vol = d["volume"];
  16835. pan = d["pan"];
  16836. panObjUid = (pan && pan.hasOwnProperty("objUid")) ? pan["objUid"] : -1;
  16837. if (is_music && this.saveload === 1) // not saving/loading music
  16838. continue;
  16839. if (!is_music && this.saveload === 2) // not saving/loading sound
  16840. continue;
  16841. a = this.getAudioInstance(src, tag, is_music, looping, vol);
  16842. if (!a)
  16843. {
  16844. b = this.getAudioBuffer(src, is_music);
  16845. b.seekWhenReady = playbackTime;
  16846. b.pauseWhenReady = d["paused"];
  16847. if (pan)
  16848. {
  16849. if (panObjUid !== -1)
  16850. {
  16851. b.panWhenReady.push({ objUid: panObjUid, ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
  16852. }
  16853. else
  16854. {
  16855. b.panWhenReady.push({ x: pan["x"], y: pan["y"], a: pan["a"], ia: pan["ia"], oa: pan["oa"], og: pan["og"], thistag: tag });
  16856. }
  16857. }
  16858. continue;
  16859. }
  16860. a.resume_position = d["resume_position"];
  16861. a.setPannerEnabled(!!pan);
  16862. a.play(looping, vol, playbackTime);
  16863. a.updatePlaybackRate();
  16864. a.updateVolume();
  16865. a.doSetMuted(a.is_muted || a.is_silent);
  16866. if (d["paused"])
  16867. a.pause();
  16868. if (d["muted"])
  16869. a.setMuted(true);
  16870. a.doSetMuted(a.is_muted || a.is_silent);
  16871. if (pan)
  16872. {
  16873. if (panObjUid !== -1)
  16874. {
  16875. a.objectTracker = a.objectTracker || new ObjectTracker();
  16876. a.objectTracker.loadUid = panObjUid;
  16877. objectTrackerUidsToLoad.push(a.objectTracker);
  16878. }
  16879. else
  16880. {
  16881. a.setPan(pan["x"], pan["y"], pan["a"], pan["ia"], pan["oa"], pan["og"]);
  16882. }
  16883. }
  16884. }
  16885. if (setSilent && !silent) // setting silent
  16886. {
  16887. for (i = 0, len = audioInstances.length; i < len; i++)
  16888. audioInstances[i].setSilent(true);
  16889. silent = true;
  16890. }
  16891. else if (!setSilent && silent) // setting not silent
  16892. {
  16893. for (i = 0, len = audioInstances.length; i < len; i++)
  16894. audioInstances[i].setSilent(false);
  16895. silent = false;
  16896. }
  16897. };
  16898. instanceProto.afterLoad = function ()
  16899. {
  16900. var i, len, ot, inst;
  16901. for (i = 0, len = objectTrackerUidsToLoad.length; i < len; i++)
  16902. {
  16903. ot = objectTrackerUidsToLoad[i];
  16904. inst = this.runtime.getObjectByUID(ot.loadUid);
  16905. ot.setObject(inst);
  16906. ot.loadUid = -1;
  16907. if (inst)
  16908. {
  16909. listenerX = inst.x;
  16910. listenerY = inst.y;
  16911. }
  16912. }
  16913. cr.clearArray(objectTrackerUidsToLoad);
  16914. };
  16915. instanceProto.onSuspend = function (s)
  16916. {
  16917. if (this.playinbackground)
  16918. return;
  16919. if (!s && context && context["resume"])
  16920. context["resume"]();
  16921. var i, len;
  16922. for (i = 0, len = audioInstances.length; i < len; i++)
  16923. audioInstances[i].setSuspended(s);
  16924. if (s && context && context["suspend"])
  16925. context["suspend"]();
  16926. };
  16927. instanceProto.tick = function ()
  16928. {
  16929. var dt = this.runtime.dt;
  16930. var i, len, a;
  16931. for (i = 0, len = audioInstances.length; i < len; i++)
  16932. {
  16933. a = audioInstances[i];
  16934. a.tick(dt);
  16935. if (timescale_mode !== 0)
  16936. a.updatePlaybackRate();
  16937. }
  16938. var p, arr, f;
  16939. for (p in effects)
  16940. {
  16941. if (effects.hasOwnProperty(p))
  16942. {
  16943. arr = effects[p];
  16944. for (i = 0, len = arr.length; i < len; i++)
  16945. {
  16946. f = arr[i];
  16947. if (f.tick)
  16948. f.tick();
  16949. }
  16950. }
  16951. }
  16952. if (api === API_WEBAUDIO && this.listenerTracker.hasObject())
  16953. {
  16954. this.listenerTracker.tick(dt);
  16955. listenerX = this.listenerTracker.obj.x;
  16956. listenerY = this.listenerTracker.obj.y;
  16957. context["listener"]["setPosition"](this.listenerTracker.obj.x, this.listenerTracker.obj.y, this.listenerZ);
  16958. context["listener"]["setVelocity"](this.listenerTracker.getVelocityX(), this.listenerTracker.getVelocityY(), 0);
  16959. }
  16960. };
  16961. var preload_list = [];
  16962. instanceProto.setPreloadList = function (arr)
  16963. {
  16964. var i, len, p, filename, size, isOgg;
  16965. var total_size = 0;
  16966. for (i = 0, len = arr.length; i < len; ++i)
  16967. {
  16968. p = arr[i];
  16969. filename = p[0];
  16970. size = p[1] * 2;
  16971. isOgg = (filename.length > 4 && filename.substr(filename.length - 4) === ".ogg");
  16972. if ((isOgg && useOgg) || (!isOgg && !useOgg))
  16973. {
  16974. preload_list.push({
  16975. filename: filename,
  16976. size: size,
  16977. obj: null
  16978. });
  16979. total_size += size;
  16980. }
  16981. }
  16982. return total_size;
  16983. };
  16984. instanceProto.startPreloads = function ()
  16985. {
  16986. var i, len, p, src;
  16987. for (i = 0, len = preload_list.length; i < len; ++i)
  16988. {
  16989. p = preload_list[i];
  16990. src = this.runtime.files_subfolder + p.filename;
  16991. p.obj = this.getAudioBuffer(src, false);
  16992. }
  16993. };
  16994. instanceProto.getPreloadedSize = function ()
  16995. {
  16996. var completed = 0;
  16997. var i, len, p;
  16998. for (i = 0, len = preload_list.length; i < len; ++i)
  16999. {
  17000. p = preload_list[i];
  17001. if (p.obj.isLoadedAndDecoded() || p.obj.hasFailedToLoad() || this.runtime.isDomFree || this.runtime.isAndroidStockBrowser)
  17002. {
  17003. completed += p.size;
  17004. }
  17005. else if (p.obj.isLoaded()) // downloaded but not decoded: only happens in Web Audio API, count as half-way progress
  17006. {
  17007. completed += Math.floor(p.size / 2);
  17008. }
  17009. };
  17010. return completed;
  17011. };
  17012. instanceProto.getAudioBuffer = function (src_, is_music)
  17013. {
  17014. var i, len, a, ret = null, j, k, lenj, ai;
  17015. for (i = 0, len = audioBuffers.length; i < len; i++)
  17016. {
  17017. a = audioBuffers[i];
  17018. if (a.src === src_)
  17019. {
  17020. ret = a;
  17021. break;
  17022. }
  17023. }
  17024. if (!ret)
  17025. {
  17026. ret = new C2AudioBuffer(src_, is_music);
  17027. audioBuffers.push(ret);
  17028. }
  17029. return ret;
  17030. };
  17031. instanceProto.getAudioInstance = function (src_, tag, is_music, looping, vol)
  17032. {
  17033. var i, len, a;
  17034. for (i = 0, len = audioInstances.length; i < len; i++)
  17035. {
  17036. a = audioInstances[i];
  17037. if (a.src === src_ && (a.canBeRecycled() || is_music))
  17038. {
  17039. a.tag = tag;
  17040. return a;
  17041. }
  17042. }
  17043. var b = this.getAudioBuffer(src_, is_music);
  17044. if (!b.bufferObject)
  17045. {
  17046. if (tag !== "<preload>")
  17047. {
  17048. b.playTagWhenReady = tag;
  17049. b.loopWhenReady = looping;
  17050. b.volumeWhenReady = vol;
  17051. }
  17052. return null;
  17053. }
  17054. a = new C2AudioInstance(b, tag);
  17055. audioInstances.push(a);
  17056. return a;
  17057. };
  17058. var taggedAudio = [];
  17059. function SortByIsPlaying(a, b)
  17060. {
  17061. var an = a.isPlaying() ? 1 : 0;
  17062. var bn = b.isPlaying() ? 1 : 0;
  17063. if (an === bn)
  17064. return 0;
  17065. else if (an < bn)
  17066. return 1;
  17067. else
  17068. return -1;
  17069. };
  17070. function getAudioByTag(tag, sort_by_playing)
  17071. {
  17072. cr.clearArray(taggedAudio);
  17073. if (!tag.length)
  17074. {
  17075. if (!lastAudio || lastAudio.hasEnded())
  17076. return;
  17077. else
  17078. {
  17079. cr.clearArray(taggedAudio);
  17080. taggedAudio[0] = lastAudio;
  17081. return;
  17082. }
  17083. }
  17084. var i, len, a;
  17085. for (i = 0, len = audioInstances.length; i < len; i++)
  17086. {
  17087. a = audioInstances[i];
  17088. if (cr.equals_nocase(tag, a.tag))
  17089. taggedAudio.push(a);
  17090. }
  17091. if (sort_by_playing)
  17092. taggedAudio.sort(SortByIsPlaying);
  17093. };
  17094. function reconnectEffects(tag)
  17095. {
  17096. var i, len, arr, n, toNode = context["destination"];
  17097. if (effects.hasOwnProperty(tag))
  17098. {
  17099. arr = effects[tag];
  17100. if (arr.length)
  17101. {
  17102. toNode = arr[0].getInputNode();
  17103. for (i = 0, len = arr.length; i < len; i++)
  17104. {
  17105. n = arr[i];
  17106. if (i + 1 === len)
  17107. n.connectTo(context["destination"]);
  17108. else
  17109. n.connectTo(arr[i + 1].getInputNode());
  17110. }
  17111. }
  17112. }
  17113. getAudioByTag(tag);
  17114. for (i = 0, len = taggedAudio.length; i < len; i++)
  17115. taggedAudio[i].reconnect(toNode);
  17116. if (micSource && micTag === tag)
  17117. {
  17118. micSource["disconnect"]();
  17119. micSource["connect"](toNode);
  17120. }
  17121. };
  17122. function addEffectForTag(tag, fx)
  17123. {
  17124. if (!effects.hasOwnProperty(tag))
  17125. effects[tag] = [fx];
  17126. else
  17127. effects[tag].push(fx);
  17128. reconnectEffects(tag);
  17129. };
  17130. function Cnds() {};
  17131. Cnds.prototype.OnEnded = function (t)
  17132. {
  17133. return cr.equals_nocase(audTag, t);
  17134. };
  17135. Cnds.prototype.PreloadsComplete = function ()
  17136. {
  17137. var i, len;
  17138. for (i = 0, len = audioBuffers.length; i < len; i++)
  17139. {
  17140. if (!audioBuffers[i].isLoadedAndDecoded() && !audioBuffers[i].hasFailedToLoad())
  17141. return false;
  17142. }
  17143. return true;
  17144. };
  17145. Cnds.prototype.AdvancedAudioSupported = function ()
  17146. {
  17147. return api === API_WEBAUDIO;
  17148. };
  17149. Cnds.prototype.IsSilent = function ()
  17150. {
  17151. return silent;
  17152. };
  17153. Cnds.prototype.IsAnyPlaying = function ()
  17154. {
  17155. var i, len;
  17156. for (i = 0, len = audioInstances.length; i < len; i++)
  17157. {
  17158. if (audioInstances[i].isPlaying())
  17159. return true;
  17160. }
  17161. return false;
  17162. };
  17163. Cnds.prototype.IsTagPlaying = function (tag)
  17164. {
  17165. getAudioByTag(tag);
  17166. var i, len;
  17167. for (i = 0, len = taggedAudio.length; i < len; i++)
  17168. {
  17169. if (taggedAudio[i].isPlaying())
  17170. return true;
  17171. }
  17172. return false;
  17173. };
  17174. pluginProto.cnds = new Cnds();
  17175. function Acts() {};
  17176. Acts.prototype.Play = function (file, looping, vol, tag)
  17177. {
  17178. if (silent)
  17179. return;
  17180. var v = dbToLinear(vol);
  17181. var is_music = file[1];
  17182. var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
  17183. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17184. if (!lastAudio)
  17185. return;
  17186. lastAudio.setPannerEnabled(false);
  17187. lastAudio.play(looping!==0, v);
  17188. };
  17189. Acts.prototype.PlayAtPosition = function (file, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
  17190. {
  17191. if (silent)
  17192. return;
  17193. var v = dbToLinear(vol);
  17194. var is_music = file[1];
  17195. var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
  17196. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17197. if (!lastAudio)
  17198. {
  17199. var b = this.getAudioBuffer(src, is_music);
  17200. b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
  17201. return;
  17202. }
  17203. lastAudio.setPannerEnabled(true);
  17204. lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
  17205. lastAudio.play(looping!==0, v);
  17206. };
  17207. Acts.prototype.PlayAtObject = function (file, looping, vol, obj, innerangle, outerangle, outergain, tag)
  17208. {
  17209. if (silent || !obj)
  17210. return;
  17211. var inst = obj.getFirstPicked();
  17212. if (!inst)
  17213. return;
  17214. var v = dbToLinear(vol);
  17215. var is_music = file[1];
  17216. var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
  17217. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17218. if (!lastAudio)
  17219. {
  17220. var b = this.getAudioBuffer(src, is_music);
  17221. b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
  17222. return;
  17223. }
  17224. lastAudio.setPannerEnabled(true);
  17225. var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
  17226. var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
  17227. lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
  17228. lastAudio.setObject(inst);
  17229. lastAudio.play(looping!==0, v);
  17230. };
  17231. Acts.prototype.PlayByName = function (folder, filename, looping, vol, tag)
  17232. {
  17233. if (silent)
  17234. return;
  17235. var v = dbToLinear(vol);
  17236. var is_music = (folder === 1);
  17237. var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
  17238. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17239. if (!lastAudio)
  17240. return;
  17241. lastAudio.setPannerEnabled(false);
  17242. lastAudio.play(looping!==0, v);
  17243. };
  17244. Acts.prototype.PlayAtPositionByName = function (folder, filename, looping, vol, x_, y_, angle_, innerangle_, outerangle_, outergain_, tag)
  17245. {
  17246. if (silent)
  17247. return;
  17248. var v = dbToLinear(vol);
  17249. var is_music = (folder === 1);
  17250. var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
  17251. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17252. if (!lastAudio)
  17253. {
  17254. var b = this.getAudioBuffer(src, is_music);
  17255. b.panWhenReady.push({ x: x_, y: y_, a: angle_, ia: innerangle_, oa: outerangle_, og: dbToLinear(outergain_), thistag: tag });
  17256. return;
  17257. }
  17258. lastAudio.setPannerEnabled(true);
  17259. lastAudio.setPan(x_, y_, angle_, innerangle_, outerangle_, dbToLinear(outergain_));
  17260. lastAudio.play(looping!==0, v);
  17261. };
  17262. Acts.prototype.PlayAtObjectByName = function (folder, filename, looping, vol, obj, innerangle, outerangle, outergain, tag)
  17263. {
  17264. if (silent || !obj)
  17265. return;
  17266. var inst = obj.getFirstPicked();
  17267. if (!inst)
  17268. return;
  17269. var v = dbToLinear(vol);
  17270. var is_music = (folder === 1);
  17271. var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
  17272. lastAudio = this.getAudioInstance(src, tag, is_music, looping!==0, v);
  17273. if (!lastAudio)
  17274. {
  17275. var b = this.getAudioBuffer(src, is_music);
  17276. b.panWhenReady.push({ obj: inst, ia: innerangle, oa: outerangle, og: dbToLinear(outergain), thistag: tag });
  17277. return;
  17278. }
  17279. lastAudio.setPannerEnabled(true);
  17280. var px = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, true);
  17281. var py = cr.rotatePtAround(inst.x, inst.y, -inst.layer.getAngle(), listenerX, listenerY, false);
  17282. lastAudio.setPan(px, py, cr.to_degrees(inst.angle - inst.layer.getAngle()), innerangle, outerangle, dbToLinear(outergain));
  17283. lastAudio.setObject(inst);
  17284. lastAudio.play(looping!==0, v);
  17285. };
  17286. Acts.prototype.SetLooping = function (tag, looping)
  17287. {
  17288. getAudioByTag(tag);
  17289. var i, len;
  17290. for (i = 0, len = taggedAudio.length; i < len; i++)
  17291. taggedAudio[i].setLooping(looping === 0);
  17292. };
  17293. Acts.prototype.SetMuted = function (tag, muted)
  17294. {
  17295. getAudioByTag(tag);
  17296. var i, len;
  17297. for (i = 0, len = taggedAudio.length; i < len; i++)
  17298. taggedAudio[i].setMuted(muted === 0);
  17299. };
  17300. Acts.prototype.SetVolume = function (tag, vol)
  17301. {
  17302. getAudioByTag(tag);
  17303. var v = dbToLinear(vol);
  17304. var i, len;
  17305. for (i = 0, len = taggedAudio.length; i < len; i++)
  17306. taggedAudio[i].setVolume(v);
  17307. };
  17308. Acts.prototype.Preload = function (file)
  17309. {
  17310. if (silent)
  17311. return;
  17312. var is_music = file[1];
  17313. var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
  17314. if (api === API_APPMOBI)
  17315. {
  17316. if (this.runtime.isDirectCanvas)
  17317. AppMobi["context"]["loadSound"](src);
  17318. else
  17319. AppMobi["player"]["loadSound"](src);
  17320. return;
  17321. }
  17322. else if (api === API_CORDOVA)
  17323. {
  17324. return;
  17325. }
  17326. this.getAudioInstance(src, "<preload>", is_music, false);
  17327. };
  17328. Acts.prototype.PreloadByName = function (folder, filename)
  17329. {
  17330. if (silent)
  17331. return;
  17332. var is_music = (folder === 1);
  17333. var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
  17334. if (api === API_APPMOBI)
  17335. {
  17336. if (this.runtime.isDirectCanvas)
  17337. AppMobi["context"]["loadSound"](src);
  17338. else
  17339. AppMobi["player"]["loadSound"](src);
  17340. return;
  17341. }
  17342. else if (api === API_CORDOVA)
  17343. {
  17344. return;
  17345. }
  17346. this.getAudioInstance(src, "<preload>", is_music, false);
  17347. };
  17348. Acts.prototype.SetPlaybackRate = function (tag, rate)
  17349. {
  17350. getAudioByTag(tag);
  17351. if (rate < 0.0)
  17352. rate = 0;
  17353. var i, len;
  17354. for (i = 0, len = taggedAudio.length; i < len; i++)
  17355. taggedAudio[i].setPlaybackRate(rate);
  17356. };
  17357. Acts.prototype.Stop = function (tag)
  17358. {
  17359. getAudioByTag(tag);
  17360. var i, len;
  17361. for (i = 0, len = taggedAudio.length; i < len; i++)
  17362. taggedAudio[i].stop();
  17363. };
  17364. Acts.prototype.StopAll = function ()
  17365. {
  17366. var i, len;
  17367. for (i = 0, len = audioInstances.length; i < len; i++)
  17368. audioInstances[i].stop();
  17369. };
  17370. Acts.prototype.SetPaused = function (tag, state)
  17371. {
  17372. getAudioByTag(tag);
  17373. var i, len;
  17374. for (i = 0, len = taggedAudio.length; i < len; i++)
  17375. {
  17376. if (state === 0)
  17377. taggedAudio[i].pause();
  17378. else
  17379. taggedAudio[i].resume();
  17380. }
  17381. };
  17382. Acts.prototype.Seek = function (tag, pos)
  17383. {
  17384. getAudioByTag(tag);
  17385. var i, len;
  17386. for (i = 0, len = taggedAudio.length; i < len; i++)
  17387. {
  17388. taggedAudio[i].seek(pos);
  17389. }
  17390. };
  17391. Acts.prototype.SetSilent = function (s)
  17392. {
  17393. var i, len;
  17394. if (s === 2) // toggling
  17395. s = (silent ? 1 : 0); // choose opposite state
  17396. if (s === 0 && !silent) // setting silent
  17397. {
  17398. for (i = 0, len = audioInstances.length; i < len; i++)
  17399. audioInstances[i].setSilent(true);
  17400. silent = true;
  17401. }
  17402. else if (s === 1 && silent) // setting not silent
  17403. {
  17404. for (i = 0, len = audioInstances.length; i < len; i++)
  17405. audioInstances[i].setSilent(false);
  17406. silent = false;
  17407. }
  17408. };
  17409. Acts.prototype.SetMasterVolume = function (vol)
  17410. {
  17411. masterVolume = dbToLinear(vol);
  17412. var i, len;
  17413. for (i = 0, len = audioInstances.length; i < len; i++)
  17414. audioInstances[i].updateVolume();
  17415. };
  17416. Acts.prototype.AddFilterEffect = function (tag, type, freq, detune, q, gain, mix)
  17417. {
  17418. if (api !== API_WEBAUDIO || type < 0 || type >= filterTypes.length || !context["createBiquadFilter"])
  17419. return;
  17420. tag = tag.toLowerCase();
  17421. mix = mix / 100;
  17422. if (mix < 0) mix = 0;
  17423. if (mix > 1) mix = 1;
  17424. addEffectForTag(tag, new FilterEffect(type, freq, detune, q, gain, mix));
  17425. };
  17426. Acts.prototype.AddDelayEffect = function (tag, delay, gain, mix)
  17427. {
  17428. if (api !== API_WEBAUDIO)
  17429. return;
  17430. tag = tag.toLowerCase();
  17431. mix = mix / 100;
  17432. if (mix < 0) mix = 0;
  17433. if (mix > 1) mix = 1;
  17434. addEffectForTag(tag, new DelayEffect(delay, dbToLinear(gain), mix));
  17435. };
  17436. Acts.prototype.AddFlangerEffect = function (tag, delay, modulation, freq, feedback, mix)
  17437. {
  17438. if (api !== API_WEBAUDIO || !context["createOscillator"])
  17439. return;
  17440. tag = tag.toLowerCase();
  17441. mix = mix / 100;
  17442. if (mix < 0) mix = 0;
  17443. if (mix > 1) mix = 1;
  17444. addEffectForTag(tag, new FlangerEffect(delay / 1000, modulation / 1000, freq, feedback / 100, mix));
  17445. };
  17446. Acts.prototype.AddPhaserEffect = function (tag, freq, detune, q, mod, modfreq, mix)
  17447. {
  17448. if (api !== API_WEBAUDIO || !context["createOscillator"])
  17449. return;
  17450. tag = tag.toLowerCase();
  17451. mix = mix / 100;
  17452. if (mix < 0) mix = 0;
  17453. if (mix > 1) mix = 1;
  17454. addEffectForTag(tag, new PhaserEffect(freq, detune, q, mod, modfreq, mix));
  17455. };
  17456. Acts.prototype.AddConvolutionEffect = function (tag, file, norm, mix)
  17457. {
  17458. if (api !== API_WEBAUDIO || !context["createConvolver"])
  17459. return;
  17460. var doNormalize = (norm === 0);
  17461. var src = this.runtime.files_subfolder + file[0] + (useOgg ? ".ogg" : ".m4a");
  17462. var b = this.getAudioBuffer(src, false);
  17463. tag = tag.toLowerCase();
  17464. mix = mix / 100;
  17465. if (mix < 0) mix = 0;
  17466. if (mix > 1) mix = 1;
  17467. var fx;
  17468. if (b.bufferObject)
  17469. {
  17470. fx = new ConvolveEffect(b.bufferObject, doNormalize, mix, src);
  17471. }
  17472. else
  17473. {
  17474. fx = new ConvolveEffect(null, doNormalize, mix, src);
  17475. b.normalizeWhenReady = doNormalize;
  17476. b.convolveWhenReady = fx;
  17477. }
  17478. addEffectForTag(tag, fx);
  17479. };
  17480. Acts.prototype.AddGainEffect = function (tag, g)
  17481. {
  17482. if (api !== API_WEBAUDIO)
  17483. return;
  17484. tag = tag.toLowerCase();
  17485. addEffectForTag(tag, new GainEffect(dbToLinear(g)));
  17486. };
  17487. Acts.prototype.AddMuteEffect = function (tag)
  17488. {
  17489. if (api !== API_WEBAUDIO)
  17490. return;
  17491. tag = tag.toLowerCase();
  17492. addEffectForTag(tag, new GainEffect(0)); // re-use gain effect with 0 gain
  17493. };
  17494. Acts.prototype.AddTremoloEffect = function (tag, freq, mix)
  17495. {
  17496. if (api !== API_WEBAUDIO || !context["createOscillator"])
  17497. return;
  17498. tag = tag.toLowerCase();
  17499. mix = mix / 100;
  17500. if (mix < 0) mix = 0;
  17501. if (mix > 1) mix = 1;
  17502. addEffectForTag(tag, new TremoloEffect(freq, mix));
  17503. };
  17504. Acts.prototype.AddRingModEffect = function (tag, freq, mix)
  17505. {
  17506. if (api !== API_WEBAUDIO || !context["createOscillator"])
  17507. return;
  17508. tag = tag.toLowerCase();
  17509. mix = mix / 100;
  17510. if (mix < 0) mix = 0;
  17511. if (mix > 1) mix = 1;
  17512. addEffectForTag(tag, new RingModulatorEffect(freq, mix));
  17513. };
  17514. Acts.prototype.AddDistortionEffect = function (tag, threshold, headroom, drive, makeupgain, mix)
  17515. {
  17516. if (api !== API_WEBAUDIO || !context["createWaveShaper"])
  17517. return;
  17518. tag = tag.toLowerCase();
  17519. mix = mix / 100;
  17520. if (mix < 0) mix = 0;
  17521. if (mix > 1) mix = 1;
  17522. addEffectForTag(tag, new DistortionEffect(threshold, headroom, drive, makeupgain, mix));
  17523. };
  17524. Acts.prototype.AddCompressorEffect = function (tag, threshold, knee, ratio, attack, release)
  17525. {
  17526. if (api !== API_WEBAUDIO || !context["createDynamicsCompressor"])
  17527. return;
  17528. tag = tag.toLowerCase();
  17529. addEffectForTag(tag, new CompressorEffect(threshold, knee, ratio, attack / 1000, release / 1000));
  17530. };
  17531. Acts.prototype.AddAnalyserEffect = function (tag, fftSize, smoothing)
  17532. {
  17533. if (api !== API_WEBAUDIO)
  17534. return;
  17535. tag = tag.toLowerCase();
  17536. addEffectForTag(tag, new AnalyserEffect(fftSize, smoothing));
  17537. };
  17538. Acts.prototype.RemoveEffects = function (tag)
  17539. {
  17540. if (api !== API_WEBAUDIO)
  17541. return;
  17542. tag = tag.toLowerCase();
  17543. var i, len, arr;
  17544. if (effects.hasOwnProperty(tag))
  17545. {
  17546. arr = effects[tag];
  17547. if (arr.length)
  17548. {
  17549. for (i = 0, len = arr.length; i < len; i++)
  17550. arr[i].remove();
  17551. cr.clearArray(arr);
  17552. reconnectEffects(tag);
  17553. }
  17554. }
  17555. };
  17556. Acts.prototype.SetEffectParameter = function (tag, index, param, value, ramp, time)
  17557. {
  17558. if (api !== API_WEBAUDIO)
  17559. return;
  17560. tag = tag.toLowerCase();
  17561. index = Math.floor(index);
  17562. var arr;
  17563. if (!effects.hasOwnProperty(tag))
  17564. return;
  17565. arr = effects[tag];
  17566. if (index < 0 || index >= arr.length)
  17567. return;
  17568. arr[index].setParam(param, value, ramp, time);
  17569. };
  17570. Acts.prototype.SetListenerObject = function (obj_)
  17571. {
  17572. if (!obj_ || api !== API_WEBAUDIO)
  17573. return;
  17574. var inst = obj_.getFirstPicked();
  17575. if (!inst)
  17576. return;
  17577. this.listenerTracker.setObject(inst);
  17578. listenerX = inst.x;
  17579. listenerY = inst.y;
  17580. };
  17581. Acts.prototype.SetListenerZ = function (z)
  17582. {
  17583. this.listenerZ = z;
  17584. };
  17585. pluginProto.acts = new Acts();
  17586. function Exps() {};
  17587. Exps.prototype.Duration = function (ret, tag)
  17588. {
  17589. getAudioByTag(tag, true);
  17590. if (taggedAudio.length)
  17591. ret.set_float(taggedAudio[0].getDuration());
  17592. else
  17593. ret.set_float(0);
  17594. };
  17595. Exps.prototype.PlaybackTime = function (ret, tag)
  17596. {
  17597. getAudioByTag(tag, true);
  17598. if (taggedAudio.length)
  17599. ret.set_float(taggedAudio[0].getPlaybackTime());
  17600. else
  17601. ret.set_float(0);
  17602. };
  17603. Exps.prototype.Volume = function (ret, tag)
  17604. {
  17605. getAudioByTag(tag, true);
  17606. if (taggedAudio.length)
  17607. {
  17608. var v = taggedAudio[0].getVolume();
  17609. ret.set_float(linearToDb(v));
  17610. }
  17611. else
  17612. ret.set_float(0);
  17613. };
  17614. Exps.prototype.MasterVolume = function (ret)
  17615. {
  17616. ret.set_float(linearToDb(masterVolume));
  17617. };
  17618. Exps.prototype.EffectCount = function (ret, tag)
  17619. {
  17620. tag = tag.toLowerCase();
  17621. var arr = null;
  17622. if (effects.hasOwnProperty(tag))
  17623. arr = effects[tag];
  17624. ret.set_int(arr ? arr.length : 0);
  17625. };
  17626. function getAnalyser(tag, index)
  17627. {
  17628. var arr = null;
  17629. if (effects.hasOwnProperty(tag))
  17630. arr = effects[tag];
  17631. if (arr && index >= 0 && index < arr.length && arr[index].freqBins)
  17632. return arr[index];
  17633. else
  17634. return null;
  17635. };
  17636. Exps.prototype.AnalyserFreqBinCount = function (ret, tag, index)
  17637. {
  17638. tag = tag.toLowerCase();
  17639. index = Math.floor(index);
  17640. var analyser = getAnalyser(tag, index);
  17641. ret.set_int(analyser ? analyser.node["frequencyBinCount"] : 0);
  17642. };
  17643. Exps.prototype.AnalyserFreqBinAt = function (ret, tag, index, bin)
  17644. {
  17645. tag = tag.toLowerCase();
  17646. index = Math.floor(index);
  17647. bin = Math.floor(bin);
  17648. var analyser = getAnalyser(tag, index);
  17649. if (!analyser)
  17650. ret.set_float(0);
  17651. else if (bin < 0 || bin >= analyser.node["frequencyBinCount"])
  17652. ret.set_float(0);
  17653. else
  17654. ret.set_float(analyser.freqBins[bin]);
  17655. };
  17656. Exps.prototype.AnalyserPeakLevel = function (ret, tag, index)
  17657. {
  17658. tag = tag.toLowerCase();
  17659. index = Math.floor(index);
  17660. var analyser = getAnalyser(tag, index);
  17661. if (analyser)
  17662. ret.set_float(analyser.peak);
  17663. else
  17664. ret.set_float(0);
  17665. };
  17666. Exps.prototype.AnalyserRMSLevel = function (ret, tag, index)
  17667. {
  17668. tag = tag.toLowerCase();
  17669. index = Math.floor(index);
  17670. var analyser = getAnalyser(tag, index);
  17671. if (analyser)
  17672. ret.set_float(analyser.rms);
  17673. else
  17674. ret.set_float(0);
  17675. };
  17676. pluginProto.exps = new Exps();
  17677. }());
  17678. ;
  17679. ;
  17680. cr.plugins_.Browser = function(runtime)
  17681. {
  17682. this.runtime = runtime;
  17683. };
  17684. (function ()
  17685. {
  17686. var pluginProto = cr.plugins_.Browser.prototype;
  17687. pluginProto.Type = function(plugin)
  17688. {
  17689. this.plugin = plugin;
  17690. this.runtime = plugin.runtime;
  17691. };
  17692. var typeProto = pluginProto.Type.prototype;
  17693. typeProto.onCreate = function()
  17694. {
  17695. };
  17696. pluginProto.Instance = function(type)
  17697. {
  17698. this.type = type;
  17699. this.runtime = type.runtime;
  17700. };
  17701. var instanceProto = pluginProto.Instance.prototype;
  17702. instanceProto.onCreate = function()
  17703. {
  17704. var self = this;
  17705. window.addEventListener("resize", function () {
  17706. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnResize, self);
  17707. });
  17708. if (typeof navigator.onLine !== "undefined")
  17709. {
  17710. window.addEventListener("online", function() {
  17711. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOnline, self);
  17712. });
  17713. window.addEventListener("offline", function() {
  17714. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnOffline, self);
  17715. });
  17716. }
  17717. if (typeof window.applicationCache !== "undefined")
  17718. {
  17719. window.applicationCache.addEventListener('updateready', function() {
  17720. self.runtime.loadingprogress = 1;
  17721. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, self);
  17722. });
  17723. window.applicationCache.addEventListener('progress', function(e) {
  17724. self.runtime.loadingprogress = e["loaded"] / e["total"];
  17725. });
  17726. }
  17727. if (!this.runtime.isDirectCanvas)
  17728. {
  17729. document.addEventListener("appMobi.device.update.available", function() {
  17730. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnUpdateReady, self);
  17731. });
  17732. document.addEventListener("backbutton", function() {
  17733. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
  17734. });
  17735. document.addEventListener("menubutton", function() {
  17736. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
  17737. });
  17738. document.addEventListener("searchbutton", function() {
  17739. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnSearchButton, self);
  17740. });
  17741. document.addEventListener("tizenhwkey", function (e) {
  17742. var ret;
  17743. switch (e["keyName"]) {
  17744. case "back":
  17745. ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
  17746. if (!ret)
  17747. {
  17748. if (window["tizen"])
  17749. window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
  17750. }
  17751. break;
  17752. case "menu":
  17753. ret = self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnMenuButton, self);
  17754. if (!ret)
  17755. e.preventDefault();
  17756. break;
  17757. }
  17758. });
  17759. }
  17760. if (this.runtime.isWindowsPhone81)
  17761. {
  17762. WinJS["Application"]["onbackclick"] = function (e)
  17763. {
  17764. return !!self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnBackButton, self);
  17765. };
  17766. }
  17767. this.runtime.addSuspendCallback(function(s) {
  17768. if (s)
  17769. {
  17770. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageHidden, self);
  17771. }
  17772. else
  17773. {
  17774. self.runtime.trigger(cr.plugins_.Browser.prototype.cnds.OnPageVisible, self);
  17775. }
  17776. });
  17777. this.is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
  17778. };
  17779. var batteryManager = null;
  17780. var loadedBatteryManager = false;
  17781. function maybeLoadBatteryManager()
  17782. {
  17783. if (loadedBatteryManager)
  17784. return;
  17785. if (!navigator["getBattery"])
  17786. return;
  17787. var promise = navigator["getBattery"]();
  17788. loadedBatteryManager = true;
  17789. if (promise)
  17790. {
  17791. promise.then(function (manager) {
  17792. batteryManager = manager;
  17793. });
  17794. }
  17795. };
  17796. function Cnds() {};
  17797. Cnds.prototype.CookiesEnabled = function()
  17798. {
  17799. return navigator ? navigator.cookieEnabled : false;
  17800. };
  17801. Cnds.prototype.IsOnline = function()
  17802. {
  17803. return navigator ? navigator.onLine : false;
  17804. };
  17805. Cnds.prototype.HasJava = function()
  17806. {
  17807. return navigator ? navigator.javaEnabled() : false;
  17808. };
  17809. Cnds.prototype.OnOnline = function()
  17810. {
  17811. return true;
  17812. };
  17813. Cnds.prototype.OnOffline = function()
  17814. {
  17815. return true;
  17816. };
  17817. Cnds.prototype.IsDownloadingUpdate = function ()
  17818. {
  17819. if (typeof window["applicationCache"] === "undefined")
  17820. return false;
  17821. else
  17822. return window["applicationCache"]["status"] === window["applicationCache"]["DOWNLOADING"];
  17823. };
  17824. Cnds.prototype.OnUpdateReady = function ()
  17825. {
  17826. return true;
  17827. };
  17828. Cnds.prototype.PageVisible = function ()
  17829. {
  17830. return !this.runtime.isSuspended;
  17831. };
  17832. Cnds.prototype.OnPageVisible = function ()
  17833. {
  17834. return true;
  17835. };
  17836. Cnds.prototype.OnPageHidden = function ()
  17837. {
  17838. return true;
  17839. };
  17840. Cnds.prototype.OnResize = function ()
  17841. {
  17842. return true;
  17843. };
  17844. Cnds.prototype.IsFullscreen = function ()
  17845. {
  17846. return !!(document["mozFullScreen"] || document["webkitIsFullScreen"] || document["fullScreen"] || this.runtime.isNodeFullscreen);
  17847. };
  17848. Cnds.prototype.OnBackButton = function ()
  17849. {
  17850. return true;
  17851. };
  17852. Cnds.prototype.OnMenuButton = function ()
  17853. {
  17854. return true;
  17855. };
  17856. Cnds.prototype.OnSearchButton = function ()
  17857. {
  17858. return true;
  17859. };
  17860. Cnds.prototype.IsMetered = function ()
  17861. {
  17862. var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
  17863. if (!connection)
  17864. return false;
  17865. return !!connection["metered"];
  17866. };
  17867. Cnds.prototype.IsCharging = function ()
  17868. {
  17869. var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
  17870. if (battery)
  17871. {
  17872. return !!battery["charging"]
  17873. }
  17874. else
  17875. {
  17876. maybeLoadBatteryManager();
  17877. if (batteryManager)
  17878. {
  17879. return !!batteryManager["charging"];
  17880. }
  17881. else
  17882. {
  17883. return true; // if unknown, default to charging (powered)
  17884. }
  17885. }
  17886. };
  17887. Cnds.prototype.IsPortraitLandscape = function (p)
  17888. {
  17889. var current = (window.innerWidth <= window.innerHeight ? 0 : 1);
  17890. return current === p;
  17891. };
  17892. Cnds.prototype.SupportsFullscreen = function ()
  17893. {
  17894. if (this.runtime.isNodeWebkit)
  17895. return true;
  17896. var elem = this.runtime.canvasdiv || this.runtime.canvas;
  17897. return !!(elem["requestFullscreen"] || elem["mozRequestFullScreen"] || elem["msRequestFullscreen"] || elem["webkitRequestFullScreen"]);
  17898. };
  17899. pluginProto.cnds = new Cnds();
  17900. function Acts() {};
  17901. Acts.prototype.Alert = function (msg)
  17902. {
  17903. if (!this.runtime.isDomFree)
  17904. alert(msg.toString());
  17905. };
  17906. Acts.prototype.Close = function ()
  17907. {
  17908. if (this.runtime.isCocoonJs)
  17909. CocoonJS["App"]["forceToFinish"]();
  17910. else if (window["tizen"])
  17911. window["tizen"]["application"]["getCurrentApplication"]()["exit"]();
  17912. else if (navigator["app"] && navigator["app"]["exitApp"])
  17913. navigator["app"]["exitApp"]();
  17914. else if (navigator["device"] && navigator["device"]["exitApp"])
  17915. navigator["device"]["exitApp"]();
  17916. else if (!this.is_arcade && !this.runtime.isDomFree)
  17917. window.close();
  17918. };
  17919. Acts.prototype.Focus = function ()
  17920. {
  17921. if (this.runtime.isNodeWebkit)
  17922. {
  17923. var win = window["nwgui"]["Window"]["get"]();
  17924. win["focus"]();
  17925. }
  17926. else if (!this.is_arcade && !this.runtime.isDomFree)
  17927. window.focus();
  17928. };
  17929. Acts.prototype.Blur = function ()
  17930. {
  17931. if (this.runtime.isNodeWebkit)
  17932. {
  17933. var win = window["nwgui"]["Window"]["get"]();
  17934. win["blur"]();
  17935. }
  17936. else if (!this.is_arcade && !this.runtime.isDomFree)
  17937. window.blur();
  17938. };
  17939. Acts.prototype.GoBack = function ()
  17940. {
  17941. if (navigator["app"] && navigator["app"]["backHistory"])
  17942. navigator["app"]["backHistory"]();
  17943. else if (!this.is_arcade && !this.runtime.isDomFree && window.back)
  17944. window.back();
  17945. };
  17946. Acts.prototype.GoForward = function ()
  17947. {
  17948. if (!this.is_arcade && !this.runtime.isDomFree && window.forward)
  17949. window.forward();
  17950. };
  17951. Acts.prototype.GoHome = function ()
  17952. {
  17953. if (!this.is_arcade && !this.runtime.isDomFree && window.home)
  17954. window.home();
  17955. };
  17956. Acts.prototype.GoToURL = function (url, target)
  17957. {
  17958. if (this.runtime.isCocoonJs)
  17959. CocoonJS["App"]["openURL"](url);
  17960. else if (this.runtime.isEjecta)
  17961. ejecta["openURL"](url);
  17962. else if (this.runtime.isWinJS)
  17963. Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
  17964. else if (navigator["app"] && navigator["app"]["loadUrl"])
  17965. navigator["app"]["loadUrl"](url, { "openExternal": true });
  17966. else if (this.runtime.isCordova)
  17967. window.open(url, "_system");
  17968. else if (!this.is_arcade && !this.runtime.isDomFree)
  17969. {
  17970. if (target === 2 && !this.is_arcade) // top
  17971. window.top.location = url;
  17972. else if (target === 1 && !this.is_arcade) // parent
  17973. window.parent.location = url;
  17974. else // self
  17975. window.location = url;
  17976. }
  17977. };
  17978. Acts.prototype.GoToURLWindow = function (url, tag)
  17979. {
  17980. if (this.runtime.isCocoonJs)
  17981. CocoonJS["App"]["openURL"](url);
  17982. else if (this.runtime.isEjecta)
  17983. ejecta["openURL"](url);
  17984. else if (this.runtime.isWinJS)
  17985. Windows["System"]["Launcher"]["launchUriAsync"](new Windows["Foundation"]["Uri"](url));
  17986. else if (navigator["app"] && navigator["app"]["loadUrl"])
  17987. navigator["app"]["loadUrl"](url, { "openExternal": true });
  17988. else if (this.runtime.isCordova)
  17989. window.open(url, "_system");
  17990. else if (!this.is_arcade && !this.runtime.isDomFree)
  17991. window.open(url, tag);
  17992. };
  17993. Acts.prototype.Reload = function ()
  17994. {
  17995. if (!this.is_arcade && !this.runtime.isDomFree)
  17996. window.location.reload();
  17997. };
  17998. var firstRequestFullscreen = true;
  17999. var crruntime = null;
  18000. function onFullscreenError(e)
  18001. {
  18002. if (console && console.warn)
  18003. console.warn("Fullscreen request failed: ", e);
  18004. crruntime["setSize"](window.innerWidth, window.innerHeight);
  18005. };
  18006. Acts.prototype.RequestFullScreen = function (stretchmode)
  18007. {
  18008. if (this.runtime.isDomFree)
  18009. {
  18010. cr.logexport("[Construct 2] Requesting fullscreen is not supported on this platform - the request has been ignored");
  18011. return;
  18012. }
  18013. if (stretchmode >= 2)
  18014. stretchmode += 1;
  18015. if (stretchmode === 6)
  18016. stretchmode = 2;
  18017. if (this.runtime.isNodeWebkit)
  18018. {
  18019. if (this.runtime.isDebug)
  18020. {
  18021. debuggerFullscreen(true);
  18022. }
  18023. else if (!this.runtime.isNodeFullscreen && window["nwgui"])
  18024. {
  18025. window["nwgui"]["Window"]["get"]()["enterFullscreen"]();
  18026. this.runtime.isNodeFullscreen = true;
  18027. this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
  18028. }
  18029. }
  18030. else
  18031. {
  18032. if (document["mozFullScreen"] || document["webkitIsFullScreen"] || !!document["msFullscreenElement"] || document["fullScreen"] || document["fullScreenElement"])
  18033. {
  18034. return;
  18035. }
  18036. this.runtime.fullscreen_scaling = (stretchmode >= 2 ? stretchmode : 0);
  18037. var elem = this.runtime.canvasdiv || this.runtime.canvas;
  18038. if (firstRequestFullscreen)
  18039. {
  18040. firstRequestFullscreen = false;
  18041. crruntime = this.runtime;
  18042. elem.addEventListener("mozfullscreenerror", onFullscreenError);
  18043. elem.addEventListener("webkitfullscreenerror", onFullscreenError);
  18044. elem.addEventListener("MSFullscreenError", onFullscreenError);
  18045. elem.addEventListener("fullscreenerror", onFullscreenError);
  18046. }
  18047. if (elem["requestFullscreen"])
  18048. elem["requestFullscreen"]();
  18049. else if (elem["mozRequestFullScreen"])
  18050. elem["mozRequestFullScreen"]();
  18051. else if (elem["msRequestFullscreen"])
  18052. elem["msRequestFullscreen"]();
  18053. else if (elem["webkitRequestFullScreen"])
  18054. {
  18055. if (typeof Element !== "undefined" && typeof Element["ALLOW_KEYBOARD_INPUT"] !== "undefined")
  18056. elem["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]);
  18057. else
  18058. elem["webkitRequestFullScreen"]();
  18059. }
  18060. }
  18061. };
  18062. Acts.prototype.CancelFullScreen = function ()
  18063. {
  18064. if (this.runtime.isDomFree)
  18065. {
  18066. cr.logexport("[Construct 2] Exiting fullscreen is not supported on this platform - the request has been ignored");
  18067. return;
  18068. }
  18069. if (this.runtime.isNodeWebkit)
  18070. {
  18071. if (this.runtime.isDebug)
  18072. {
  18073. debuggerFullscreen(false);
  18074. }
  18075. else if (this.runtime.isNodeFullscreen && window["nwgui"])
  18076. {
  18077. window["nwgui"]["Window"]["get"]()["leaveFullscreen"]();
  18078. this.runtime.isNodeFullscreen = false;
  18079. }
  18080. }
  18081. else
  18082. {
  18083. if (document["exitFullscreen"])
  18084. document["exitFullscreen"]();
  18085. else if (document["mozCancelFullScreen"])
  18086. document["mozCancelFullScreen"]();
  18087. else if (document["msExitFullscreen"])
  18088. document["msExitFullscreen"]();
  18089. else if (document["webkitCancelFullScreen"])
  18090. document["webkitCancelFullScreen"]();
  18091. }
  18092. };
  18093. Acts.prototype.Vibrate = function (pattern_)
  18094. {
  18095. try {
  18096. var arr = pattern_.split(",");
  18097. var i, len;
  18098. for (i = 0, len = arr.length; i < len; i++)
  18099. {
  18100. arr[i] = parseInt(arr[i], 10);
  18101. }
  18102. if (navigator["vibrate"])
  18103. navigator["vibrate"](arr);
  18104. else if (navigator["mozVibrate"])
  18105. navigator["mozVibrate"](arr);
  18106. else if (navigator["webkitVibrate"])
  18107. navigator["webkitVibrate"](arr);
  18108. else if (navigator["msVibrate"])
  18109. navigator["msVibrate"](arr);
  18110. }
  18111. catch (e) {}
  18112. };
  18113. Acts.prototype.InvokeDownload = function (url_, filename_)
  18114. {
  18115. var a = document.createElement("a");
  18116. if (typeof a["download"] === "undefined")
  18117. {
  18118. window.open(url_);
  18119. }
  18120. else
  18121. {
  18122. var body = document.getElementsByTagName("body")[0];
  18123. a.textContent = filename_;
  18124. a.href = url_;
  18125. a["download"] = filename_;
  18126. body.appendChild(a);
  18127. var clickEvent = document.createEvent("MouseEvent");
  18128. clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  18129. a.dispatchEvent(clickEvent);
  18130. body.removeChild(a);
  18131. }
  18132. };
  18133. Acts.prototype.InvokeDownloadString = function (str_, mimetype_, filename_)
  18134. {
  18135. var datauri = "data:" + mimetype_ + "," + encodeURIComponent(str_);
  18136. var a = document.createElement("a");
  18137. if (typeof a["download"] === "undefined")
  18138. {
  18139. window.open(datauri);
  18140. }
  18141. else
  18142. {
  18143. var body = document.getElementsByTagName("body")[0];
  18144. a.textContent = filename_;
  18145. a.href = datauri;
  18146. a["download"] = filename_;
  18147. body.appendChild(a);
  18148. var clickEvent = document.createEvent("MouseEvent");
  18149. clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  18150. a.dispatchEvent(clickEvent);
  18151. body.removeChild(a);
  18152. }
  18153. };
  18154. Acts.prototype.ConsoleLog = function (type_, msg_)
  18155. {
  18156. if (typeof console === "undefined")
  18157. return;
  18158. if (type_ === 0 && console.log)
  18159. console.log(msg_.toString());
  18160. if (type_ === 1 && console.warn)
  18161. console.warn(msg_.toString());
  18162. if (type_ === 2 && console.error)
  18163. console.error(msg_.toString());
  18164. };
  18165. Acts.prototype.ConsoleGroup = function (name_)
  18166. {
  18167. if (console && console.group)
  18168. console.group(name_);
  18169. };
  18170. Acts.prototype.ConsoleGroupEnd = function ()
  18171. {
  18172. if (console && console.groupEnd)
  18173. console.groupEnd();
  18174. };
  18175. Acts.prototype.ExecJs = function (js_)
  18176. {
  18177. try {
  18178. if (eval)
  18179. eval(js_);
  18180. }
  18181. catch (e)
  18182. {
  18183. if (console && console.error)
  18184. console.error("Error executing Javascript: ", e);
  18185. }
  18186. };
  18187. var orientations = [
  18188. "portrait",
  18189. "landscape",
  18190. "portrait-primary",
  18191. "portrait-secondary",
  18192. "landscape-primary",
  18193. "landscape-secondary"
  18194. ];
  18195. Acts.prototype.LockOrientation = function (o)
  18196. {
  18197. o = Math.floor(o);
  18198. if (o < 0 || o >= orientations.length)
  18199. return;
  18200. this.runtime.autoLockOrientation = false;
  18201. var orientation = orientations[o];
  18202. if (screen["orientation"] && screen["orientation"]["lock"])
  18203. screen["orientation"]["lock"](orientation);
  18204. else if (screen["lockOrientation"])
  18205. screen["lockOrientation"](orientation);
  18206. else if (screen["webkitLockOrientation"])
  18207. screen["webkitLockOrientation"](orientation);
  18208. else if (screen["mozLockOrientation"])
  18209. screen["mozLockOrientation"](orientation);
  18210. else if (screen["msLockOrientation"])
  18211. screen["msLockOrientation"](orientation);
  18212. };
  18213. Acts.prototype.UnlockOrientation = function ()
  18214. {
  18215. this.runtime.autoLockOrientation = false;
  18216. if (screen["orientation"] && screen["orientation"]["unlock"])
  18217. screen["orientation"]["unlock"]();
  18218. else if (screen["unlockOrientation"])
  18219. screen["unlockOrientation"]();
  18220. else if (screen["webkitUnlockOrientation"])
  18221. screen["webkitUnlockOrientation"]();
  18222. else if (screen["mozUnlockOrientation"])
  18223. screen["mozUnlockOrientation"]();
  18224. else if (screen["msUnlockOrientation"])
  18225. screen["msUnlockOrientation"]();
  18226. };
  18227. pluginProto.acts = new Acts();
  18228. function Exps() {};
  18229. Exps.prototype.URL = function (ret)
  18230. {
  18231. ret.set_string(this.runtime.isDomFree ? "" : window.location.toString());
  18232. };
  18233. Exps.prototype.Protocol = function (ret)
  18234. {
  18235. ret.set_string(this.runtime.isDomFree ? "" : window.location.protocol);
  18236. };
  18237. Exps.prototype.Domain = function (ret)
  18238. {
  18239. ret.set_string(this.runtime.isDomFree ? "" : window.location.hostname);
  18240. };
  18241. Exps.prototype.PathName = function (ret)
  18242. {
  18243. ret.set_string(this.runtime.isDomFree ? "" : window.location.pathname);
  18244. };
  18245. Exps.prototype.Hash = function (ret)
  18246. {
  18247. ret.set_string(this.runtime.isDomFree ? "" : window.location.hash);
  18248. };
  18249. Exps.prototype.Referrer = function (ret)
  18250. {
  18251. ret.set_string(this.runtime.isDomFree ? "" : document.referrer);
  18252. };
  18253. Exps.prototype.Title = function (ret)
  18254. {
  18255. ret.set_string(this.runtime.isDomFree ? "" : document.title);
  18256. };
  18257. Exps.prototype.Name = function (ret)
  18258. {
  18259. ret.set_string(this.runtime.isDomFree ? "" : navigator.appName);
  18260. };
  18261. Exps.prototype.Version = function (ret)
  18262. {
  18263. ret.set_string(this.runtime.isDomFree ? "" : navigator.appVersion);
  18264. };
  18265. Exps.prototype.Language = function (ret)
  18266. {
  18267. if (navigator && navigator.language)
  18268. ret.set_string(navigator.language);
  18269. else
  18270. ret.set_string("");
  18271. };
  18272. Exps.prototype.Platform = function (ret)
  18273. {
  18274. ret.set_string(this.runtime.isDomFree ? "" : navigator.platform);
  18275. };
  18276. Exps.prototype.Product = function (ret)
  18277. {
  18278. if (navigator && navigator.product)
  18279. ret.set_string(navigator.product);
  18280. else
  18281. ret.set_string("");
  18282. };
  18283. Exps.prototype.Vendor = function (ret)
  18284. {
  18285. if (navigator && navigator.vendor)
  18286. ret.set_string(navigator.vendor);
  18287. else
  18288. ret.set_string("");
  18289. };
  18290. Exps.prototype.UserAgent = function (ret)
  18291. {
  18292. ret.set_string(this.runtime.isDomFree ? "" : navigator.userAgent);
  18293. };
  18294. Exps.prototype.QueryString = function (ret)
  18295. {
  18296. ret.set_string(this.runtime.isDomFree ? "" : window.location.search);
  18297. };
  18298. Exps.prototype.QueryParam = function (ret, paramname)
  18299. {
  18300. if (this.runtime.isDomFree)
  18301. {
  18302. ret.set_string("");
  18303. return;
  18304. }
  18305. var match = RegExp('[?&]' + paramname + '=([^&]*)').exec(window.location.search);
  18306. if (match)
  18307. ret.set_string(decodeURIComponent(match[1].replace(/\+/g, ' ')));
  18308. else
  18309. ret.set_string("");
  18310. };
  18311. Exps.prototype.Bandwidth = function (ret)
  18312. {
  18313. var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
  18314. if (!connection)
  18315. ret.set_float(Number.POSITIVE_INFINITY);
  18316. else
  18317. {
  18318. if (typeof connection["bandwidth"] !== "undefined")
  18319. ret.set_float(connection["bandwidth"]);
  18320. else if (typeof connection["downlinkMax"] !== "undefined")
  18321. ret.set_float(connection["downlinkMax"]);
  18322. else
  18323. ret.set_float(Number.POSITIVE_INFINITY);
  18324. }
  18325. };
  18326. Exps.prototype.ConnectionType = function (ret)
  18327. {
  18328. var connection = navigator["connection"] || navigator["mozConnection"] || navigator["webkitConnection"];
  18329. if (!connection)
  18330. ret.set_string("unknown");
  18331. else
  18332. {
  18333. ret.set_string(connection["type"] || "unknown");
  18334. }
  18335. };
  18336. Exps.prototype.BatteryLevel = function (ret)
  18337. {
  18338. var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
  18339. if (battery)
  18340. {
  18341. ret.set_float(battery["level"]);
  18342. }
  18343. else
  18344. {
  18345. maybeLoadBatteryManager();
  18346. if (batteryManager)
  18347. {
  18348. ret.set_float(batteryManager["level"]);
  18349. }
  18350. else
  18351. {
  18352. ret.set_float(1); // not supported/unknown: assume charged
  18353. }
  18354. }
  18355. };
  18356. Exps.prototype.BatteryTimeLeft = function (ret)
  18357. {
  18358. var battery = navigator["battery"] || navigator["mozBattery"] || navigator["webkitBattery"];
  18359. if (battery)
  18360. {
  18361. ret.set_float(battery["dischargingTime"]);
  18362. }
  18363. else
  18364. {
  18365. maybeLoadBatteryManager();
  18366. if (batteryManager)
  18367. {
  18368. ret.set_float(batteryManager["dischargingTime"]);
  18369. }
  18370. else
  18371. {
  18372. ret.set_float(Number.POSITIVE_INFINITY); // not supported/unknown: assume infinite time left
  18373. }
  18374. }
  18375. };
  18376. Exps.prototype.ExecJS = function (ret, js_)
  18377. {
  18378. if (!eval)
  18379. {
  18380. ret.set_any(0);
  18381. return;
  18382. }
  18383. var result = 0;
  18384. try {
  18385. result = eval(js_);
  18386. }
  18387. catch (e)
  18388. {
  18389. if (console && console.error)
  18390. console.error("Error executing Javascript: ", e);
  18391. }
  18392. if (typeof result === "number")
  18393. ret.set_any(result);
  18394. else if (typeof result === "string")
  18395. ret.set_any(result);
  18396. else if (typeof result === "boolean")
  18397. ret.set_any(result ? 1 : 0);
  18398. else
  18399. ret.set_any(0);
  18400. };
  18401. Exps.prototype.ScreenWidth = function (ret)
  18402. {
  18403. ret.set_int(screen.width);
  18404. };
  18405. Exps.prototype.ScreenHeight = function (ret)
  18406. {
  18407. ret.set_int(screen.height);
  18408. };
  18409. Exps.prototype.DevicePixelRatio = function (ret)
  18410. {
  18411. ret.set_float(this.runtime.devicePixelRatio);
  18412. };
  18413. pluginProto.exps = new Exps();
  18414. }());
  18415. ;
  18416. ;
  18417. cr.plugins_.Function = function(runtime)
  18418. {
  18419. this.runtime = runtime;
  18420. };
  18421. (function ()
  18422. {
  18423. var pluginProto = cr.plugins_.Function.prototype;
  18424. pluginProto.Type = function(plugin)
  18425. {
  18426. this.plugin = plugin;
  18427. this.runtime = plugin.runtime;
  18428. };
  18429. var typeProto = pluginProto.Type.prototype;
  18430. typeProto.onCreate = function()
  18431. {
  18432. };
  18433. pluginProto.Instance = function(type)
  18434. {
  18435. this.type = type;
  18436. this.runtime = type.runtime;
  18437. };
  18438. var instanceProto = pluginProto.Instance.prototype;
  18439. var funcStack = [];
  18440. var funcStackPtr = -1;
  18441. var isInPreview = false; // set in onCreate
  18442. function FuncStackEntry()
  18443. {
  18444. this.name = "";
  18445. this.retVal = 0;
  18446. this.params = [];
  18447. };
  18448. function pushFuncStack()
  18449. {
  18450. funcStackPtr++;
  18451. if (funcStackPtr === funcStack.length)
  18452. funcStack.push(new FuncStackEntry());
  18453. return funcStack[funcStackPtr];
  18454. };
  18455. function getCurrentFuncStack()
  18456. {
  18457. if (funcStackPtr < 0)
  18458. return null;
  18459. return funcStack[funcStackPtr];
  18460. };
  18461. function getOneAboveFuncStack()
  18462. {
  18463. if (!funcStack.length)
  18464. return null;
  18465. var i = funcStackPtr + 1;
  18466. if (i >= funcStack.length)
  18467. i = funcStack.length - 1;
  18468. return funcStack[i];
  18469. };
  18470. function popFuncStack()
  18471. {
  18472. ;
  18473. funcStackPtr--;
  18474. };
  18475. instanceProto.onCreate = function()
  18476. {
  18477. isInPreview = (typeof cr_is_preview !== "undefined");
  18478. var self = this;
  18479. window["c2_callFunction"] = function (name_, params_)
  18480. {
  18481. var i, len, v;
  18482. var fs = pushFuncStack();
  18483. fs.name = name_.toLowerCase();
  18484. fs.retVal = 0;
  18485. if (params_)
  18486. {
  18487. fs.params.length = params_.length;
  18488. for (i = 0, len = params_.length; i < len; ++i)
  18489. {
  18490. v = params_[i];
  18491. if (typeof v === "number" || typeof v === "string")
  18492. fs.params[i] = v;
  18493. else if (typeof v === "boolean")
  18494. fs.params[i] = (v ? 1 : 0);
  18495. else
  18496. fs.params[i] = 0;
  18497. }
  18498. }
  18499. else
  18500. {
  18501. cr.clearArray(fs.params);
  18502. }
  18503. self.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, self, fs.name);
  18504. popFuncStack();
  18505. return fs.retVal;
  18506. };
  18507. };
  18508. function Cnds() {};
  18509. Cnds.prototype.OnFunction = function (name_)
  18510. {
  18511. var fs = getCurrentFuncStack();
  18512. if (!fs)
  18513. return false;
  18514. return cr.equals_nocase(name_, fs.name);
  18515. };
  18516. Cnds.prototype.CompareParam = function (index_, cmp_, value_)
  18517. {
  18518. var fs = getCurrentFuncStack();
  18519. if (!fs)
  18520. return false;
  18521. index_ = cr.floor(index_);
  18522. if (index_ < 0 || index_ >= fs.params.length)
  18523. return false;
  18524. return cr.do_cmp(fs.params[index_], cmp_, value_);
  18525. };
  18526. pluginProto.cnds = new Cnds();
  18527. function Acts() {};
  18528. Acts.prototype.CallFunction = function (name_, params_)
  18529. {
  18530. var fs = pushFuncStack();
  18531. fs.name = name_.toLowerCase();
  18532. fs.retVal = 0;
  18533. cr.shallowAssignArray(fs.params, params_);
  18534. var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
  18535. if (isInPreview && !ran)
  18536. {
  18537. ;
  18538. }
  18539. popFuncStack();
  18540. };
  18541. Acts.prototype.SetReturnValue = function (value_)
  18542. {
  18543. var fs = getCurrentFuncStack();
  18544. if (fs)
  18545. fs.retVal = value_;
  18546. else
  18547. ;
  18548. };
  18549. Acts.prototype.CallExpression = function (unused)
  18550. {
  18551. };
  18552. pluginProto.acts = new Acts();
  18553. function Exps() {};
  18554. Exps.prototype.ReturnValue = function (ret)
  18555. {
  18556. var fs = getOneAboveFuncStack();
  18557. if (fs)
  18558. ret.set_any(fs.retVal);
  18559. else
  18560. ret.set_int(0);
  18561. };
  18562. Exps.prototype.ParamCount = function (ret)
  18563. {
  18564. var fs = getCurrentFuncStack();
  18565. if (fs)
  18566. ret.set_int(fs.params.length);
  18567. else
  18568. {
  18569. ;
  18570. ret.set_int(0);
  18571. }
  18572. };
  18573. Exps.prototype.Param = function (ret, index_)
  18574. {
  18575. index_ = cr.floor(index_);
  18576. var fs = getCurrentFuncStack();
  18577. if (fs)
  18578. {
  18579. if (index_ >= 0 && index_ < fs.params.length)
  18580. {
  18581. ret.set_any(fs.params[index_]);
  18582. }
  18583. else
  18584. {
  18585. ;
  18586. ret.set_int(0);
  18587. }
  18588. }
  18589. else
  18590. {
  18591. ;
  18592. ret.set_int(0);
  18593. }
  18594. };
  18595. Exps.prototype.Call = function (ret, name_)
  18596. {
  18597. var fs = pushFuncStack();
  18598. fs.name = name_.toLowerCase();
  18599. fs.retVal = 0;
  18600. cr.clearArray(fs.params);
  18601. var i, len;
  18602. for (i = 2, len = arguments.length; i < len; i++)
  18603. fs.params.push(arguments[i]);
  18604. var ran = this.runtime.trigger(cr.plugins_.Function.prototype.cnds.OnFunction, this, fs.name);
  18605. if (isInPreview && !ran)
  18606. {
  18607. ;
  18608. }
  18609. popFuncStack();
  18610. ret.set_any(fs.retVal);
  18611. };
  18612. pluginProto.exps = new Exps();
  18613. }());
  18614. ;
  18615. ;
  18616. cr.plugins_.Keyboard = function(runtime)
  18617. {
  18618. this.runtime = runtime;
  18619. };
  18620. (function ()
  18621. {
  18622. var pluginProto = cr.plugins_.Keyboard.prototype;
  18623. pluginProto.Type = function(plugin)
  18624. {
  18625. this.plugin = plugin;
  18626. this.runtime = plugin.runtime;
  18627. };
  18628. var typeProto = pluginProto.Type.prototype;
  18629. typeProto.onCreate = function()
  18630. {
  18631. };
  18632. pluginProto.Instance = function(type)
  18633. {
  18634. this.type = type;
  18635. this.runtime = type.runtime;
  18636. this.keyMap = new Array(256); // stores key up/down state
  18637. this.usedKeys = new Array(256);
  18638. this.triggerKey = 0;
  18639. };
  18640. var instanceProto = pluginProto.Instance.prototype;
  18641. instanceProto.onCreate = function()
  18642. {
  18643. var self = this;
  18644. if (!this.runtime.isDomFree)
  18645. {
  18646. jQuery(document).keydown(
  18647. function(info) {
  18648. self.onKeyDown(info);
  18649. }
  18650. );
  18651. jQuery(document).keyup(
  18652. function(info) {
  18653. self.onKeyUp(info);
  18654. }
  18655. );
  18656. }
  18657. };
  18658. var keysToBlockWhenFramed = [32, 33, 34, 35, 36, 37, 38, 39, 40, 44];
  18659. instanceProto.onKeyDown = function (info)
  18660. {
  18661. var alreadyPreventedDefault = false;
  18662. if (window != window.top && keysToBlockWhenFramed.indexOf(info.which) > -1)
  18663. {
  18664. info.preventDefault();
  18665. alreadyPreventedDefault = true;
  18666. info.stopPropagation();
  18667. }
  18668. if (this.keyMap[info.which])
  18669. {
  18670. if (this.usedKeys[info.which] && !alreadyPreventedDefault)
  18671. info.preventDefault();
  18672. return;
  18673. }
  18674. this.keyMap[info.which] = true;
  18675. this.triggerKey = info.which;
  18676. this.runtime.isInUserInputEvent = true;
  18677. this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKey, this);
  18678. var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKey, this);
  18679. var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCode, this);
  18680. this.runtime.isInUserInputEvent = false;
  18681. if (eventRan || eventRan2)
  18682. {
  18683. this.usedKeys[info.which] = true;
  18684. if (!alreadyPreventedDefault)
  18685. info.preventDefault();
  18686. }
  18687. };
  18688. instanceProto.onKeyUp = function (info)
  18689. {
  18690. this.keyMap[info.which] = false;
  18691. this.triggerKey = info.which;
  18692. this.runtime.isInUserInputEvent = true;
  18693. this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnAnyKeyReleased, this);
  18694. var eventRan = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyReleased, this);
  18695. var eventRan2 = this.runtime.trigger(cr.plugins_.Keyboard.prototype.cnds.OnKeyCodeReleased, this);
  18696. this.runtime.isInUserInputEvent = false;
  18697. if (eventRan || eventRan2 || this.usedKeys[info.which])
  18698. {
  18699. this.usedKeys[info.which] = true;
  18700. info.preventDefault();
  18701. }
  18702. };
  18703. instanceProto.saveToJSON = function ()
  18704. {
  18705. return { "triggerKey": this.triggerKey };
  18706. };
  18707. instanceProto.loadFromJSON = function (o)
  18708. {
  18709. this.triggerKey = o["triggerKey"];
  18710. };
  18711. function Cnds() {};
  18712. Cnds.prototype.IsKeyDown = function(key)
  18713. {
  18714. return this.keyMap[key];
  18715. };
  18716. Cnds.prototype.OnKey = function(key)
  18717. {
  18718. return (key === this.triggerKey);
  18719. };
  18720. Cnds.prototype.OnAnyKey = function(key)
  18721. {
  18722. return true;
  18723. };
  18724. Cnds.prototype.OnAnyKeyReleased = function(key)
  18725. {
  18726. return true;
  18727. };
  18728. Cnds.prototype.OnKeyReleased = function(key)
  18729. {
  18730. return (key === this.triggerKey);
  18731. };
  18732. Cnds.prototype.IsKeyCodeDown = function(key)
  18733. {
  18734. key = Math.floor(key);
  18735. if (key < 0 || key >= this.keyMap.length)
  18736. return false;
  18737. return this.keyMap[key];
  18738. };
  18739. Cnds.prototype.OnKeyCode = function(key)
  18740. {
  18741. return (key === this.triggerKey);
  18742. };
  18743. Cnds.prototype.OnKeyCodeReleased = function(key)
  18744. {
  18745. return (key === this.triggerKey);
  18746. };
  18747. pluginProto.cnds = new Cnds();
  18748. function Acts() {};
  18749. pluginProto.acts = new Acts();
  18750. function Exps() {};
  18751. Exps.prototype.LastKeyCode = function (ret)
  18752. {
  18753. ret.set_int(this.triggerKey);
  18754. };
  18755. function fixedStringFromCharCode(kc)
  18756. {
  18757. kc = Math.floor(kc);
  18758. switch (kc) {
  18759. case 8: return "backspace";
  18760. case 9: return "tab";
  18761. case 13: return "enter";
  18762. case 16: return "shift";
  18763. case 17: return "control";
  18764. case 18: return "alt";
  18765. case 19: return "pause";
  18766. case 20: return "capslock";
  18767. case 27: return "esc";
  18768. case 33: return "pageup";
  18769. case 34: return "pagedown";
  18770. case 35: return "end";
  18771. case 36: return "home";
  18772. case 37: return "←";
  18773. case 38: return "↑";
  18774. case 39: return "→";
  18775. case 40: return "↓";
  18776. case 45: return "insert";
  18777. case 46: return "del";
  18778. case 91: return "left window key";
  18779. case 92: return "right window key";
  18780. case 93: return "select";
  18781. case 96: return "numpad 0";
  18782. case 97: return "numpad 1";
  18783. case 98: return "numpad 2";
  18784. case 99: return "numpad 3";
  18785. case 100: return "numpad 4";
  18786. case 101: return "numpad 5";
  18787. case 102: return "numpad 6";
  18788. case 103: return "numpad 7";
  18789. case 104: return "numpad 8";
  18790. case 105: return "numpad 9";
  18791. case 106: return "numpad *";
  18792. case 107: return "numpad +";
  18793. case 109: return "numpad -";
  18794. case 110: return "numpad .";
  18795. case 111: return "numpad /";
  18796. case 112: return "F1";
  18797. case 113: return "F2";
  18798. case 114: return "F3";
  18799. case 115: return "F4";
  18800. case 116: return "F5";
  18801. case 117: return "F6";
  18802. case 118: return "F7";
  18803. case 119: return "F8";
  18804. case 120: return "F9";
  18805. case 121: return "F10";
  18806. case 122: return "F11";
  18807. case 123: return "F12";
  18808. case 144: return "numlock";
  18809. case 145: return "scroll lock";
  18810. case 186: return ";";
  18811. case 187: return "=";
  18812. case 188: return ",";
  18813. case 189: return "-";
  18814. case 190: return ".";
  18815. case 191: return "/";
  18816. case 192: return "'";
  18817. case 219: return "[";
  18818. case 220: return "\\";
  18819. case 221: return "]";
  18820. case 222: return "#";
  18821. case 223: return "`";
  18822. default: return String.fromCharCode(kc);
  18823. }
  18824. };
  18825. Exps.prototype.StringFromKeyCode = function (ret, kc)
  18826. {
  18827. ret.set_string(fixedStringFromCharCode(kc));
  18828. };
  18829. pluginProto.exps = new Exps();
  18830. }());
  18831. ;
  18832. ;
  18833. cr.plugins_.Mouse = function(runtime)
  18834. {
  18835. this.runtime = runtime;
  18836. };
  18837. (function ()
  18838. {
  18839. var pluginProto = cr.plugins_.Mouse.prototype;
  18840. pluginProto.Type = function(plugin)
  18841. {
  18842. this.plugin = plugin;
  18843. this.runtime = plugin.runtime;
  18844. };
  18845. var typeProto = pluginProto.Type.prototype;
  18846. typeProto.onCreate = function()
  18847. {
  18848. };
  18849. pluginProto.Instance = function(type)
  18850. {
  18851. this.type = type;
  18852. this.runtime = type.runtime;
  18853. this.buttonMap = new Array(4); // mouse down states
  18854. this.mouseXcanvas = 0; // mouse position relative to canvas
  18855. this.mouseYcanvas = 0;
  18856. this.triggerButton = 0;
  18857. this.triggerType = 0;
  18858. this.triggerDir = 0;
  18859. this.handled = false;
  18860. };
  18861. var instanceProto = pluginProto.Instance.prototype;
  18862. instanceProto.onCreate = function()
  18863. {
  18864. var self = this;
  18865. if (!this.runtime.isDomFree)
  18866. {
  18867. jQuery(document).mousemove(
  18868. function(info) {
  18869. self.onMouseMove(info);
  18870. }
  18871. );
  18872. jQuery(document).mousedown(
  18873. function(info) {
  18874. self.onMouseDown(info);
  18875. }
  18876. );
  18877. jQuery(document).mouseup(
  18878. function(info) {
  18879. self.onMouseUp(info);
  18880. }
  18881. );
  18882. jQuery(document).dblclick(
  18883. function(info) {
  18884. self.onDoubleClick(info);
  18885. }
  18886. );
  18887. var wheelevent = function(info) {
  18888. self.onWheel(info);
  18889. };
  18890. document.addEventListener("mousewheel", wheelevent, false);
  18891. document.addEventListener("DOMMouseScroll", wheelevent, false);
  18892. }
  18893. };
  18894. var dummyoffset = {left: 0, top: 0};
  18895. instanceProto.onMouseMove = function(info)
  18896. {
  18897. var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
  18898. this.mouseXcanvas = info.pageX - offset.left;
  18899. this.mouseYcanvas = info.pageY - offset.top;
  18900. };
  18901. instanceProto.mouseInGame = function ()
  18902. {
  18903. if (this.runtime.fullscreen_mode > 0)
  18904. return true;
  18905. return this.mouseXcanvas >= 0 && this.mouseYcanvas >= 0
  18906. && this.mouseXcanvas < this.runtime.width && this.mouseYcanvas < this.runtime.height;
  18907. };
  18908. instanceProto.onMouseDown = function(info)
  18909. {
  18910. if (!this.mouseInGame())
  18911. return;
  18912. this.buttonMap[info.which] = true;
  18913. this.runtime.isInUserInputEvent = true;
  18914. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnAnyClick, this);
  18915. this.triggerButton = info.which - 1; // 1-based
  18916. this.triggerType = 0; // single click
  18917. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
  18918. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
  18919. this.runtime.isInUserInputEvent = false;
  18920. };
  18921. instanceProto.onMouseUp = function(info)
  18922. {
  18923. if (!this.buttonMap[info.which])
  18924. return;
  18925. if (this.runtime.had_a_click && !this.runtime.isMobile)
  18926. info.preventDefault();
  18927. this.runtime.had_a_click = true;
  18928. this.buttonMap[info.which] = false;
  18929. this.runtime.isInUserInputEvent = true;
  18930. this.triggerButton = info.which - 1; // 1-based
  18931. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnRelease, this);
  18932. this.runtime.isInUserInputEvent = false;
  18933. };
  18934. instanceProto.onDoubleClick = function(info)
  18935. {
  18936. if (!this.mouseInGame())
  18937. return;
  18938. info.preventDefault();
  18939. this.runtime.isInUserInputEvent = true;
  18940. this.triggerButton = info.which - 1; // 1-based
  18941. this.triggerType = 1; // double click
  18942. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnClick, this);
  18943. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnObjectClicked, this);
  18944. this.runtime.isInUserInputEvent = false;
  18945. };
  18946. instanceProto.onWheel = function (info)
  18947. {
  18948. var delta = info.wheelDelta ? info.wheelDelta : info.detail ? -info.detail : 0;
  18949. this.triggerDir = (delta < 0 ? 0 : 1);
  18950. this.handled = false;
  18951. this.runtime.isInUserInputEvent = true;
  18952. this.runtime.trigger(cr.plugins_.Mouse.prototype.cnds.OnWheel, this);
  18953. this.runtime.isInUserInputEvent = false;
  18954. if (this.handled && cr.isCanvasInputEvent(info))
  18955. info.preventDefault();
  18956. };
  18957. function Cnds() {};
  18958. Cnds.prototype.OnClick = function (button, type)
  18959. {
  18960. return button === this.triggerButton && type === this.triggerType;
  18961. };
  18962. Cnds.prototype.OnAnyClick = function ()
  18963. {
  18964. return true;
  18965. };
  18966. Cnds.prototype.IsButtonDown = function (button)
  18967. {
  18968. return this.buttonMap[button + 1]; // jQuery uses 1-based buttons for some reason
  18969. };
  18970. Cnds.prototype.OnRelease = function (button)
  18971. {
  18972. return button === this.triggerButton;
  18973. };
  18974. Cnds.prototype.IsOverObject = function (obj)
  18975. {
  18976. var cnd = this.runtime.getCurrentCondition();
  18977. var mx = this.mouseXcanvas;
  18978. var my = this.mouseYcanvas;
  18979. return cr.xor(this.runtime.testAndSelectCanvasPointOverlap(obj, mx, my, cnd.inverted), cnd.inverted);
  18980. };
  18981. Cnds.prototype.OnObjectClicked = function (button, type, obj)
  18982. {
  18983. if (button !== this.triggerButton || type !== this.triggerType)
  18984. return false; // wrong click type
  18985. return this.runtime.testAndSelectCanvasPointOverlap(obj, this.mouseXcanvas, this.mouseYcanvas, false);
  18986. };
  18987. Cnds.prototype.OnWheel = function (dir)
  18988. {
  18989. this.handled = true;
  18990. return dir === this.triggerDir;
  18991. };
  18992. pluginProto.cnds = new Cnds();
  18993. function Acts() {};
  18994. var lastSetCursor = null;
  18995. Acts.prototype.SetCursor = function (c)
  18996. {
  18997. var cursor_style = ["auto", "pointer", "text", "crosshair", "move", "help", "wait", "none"][c];
  18998. if (lastSetCursor === cursor_style)
  18999. return; // redundant
  19000. lastSetCursor = cursor_style;
  19001. if (this.runtime.canvas && this.runtime.canvas.style)
  19002. this.runtime.canvas.style.cursor = cursor_style;
  19003. };
  19004. Acts.prototype.SetCursorSprite = function (obj)
  19005. {
  19006. if (this.runtime.isDomFree || this.runtime.isMobile || !obj)
  19007. return;
  19008. var inst = obj.getFirstPicked();
  19009. if (!inst || !inst.curFrame)
  19010. return;
  19011. var frame = inst.curFrame;
  19012. if (lastSetCursor === frame)
  19013. return; // already set this frame
  19014. lastSetCursor = frame;
  19015. var datauri = frame.getDataUri();
  19016. var cursor_style = "url(" + datauri + ") " + Math.round(frame.hotspotX * frame.width) + " " + Math.round(frame.hotspotY * frame.height) + ", auto";
  19017. jQuery(this.runtime.canvas).css("cursor", cursor_style);
  19018. };
  19019. pluginProto.acts = new Acts();
  19020. function Exps() {};
  19021. Exps.prototype.X = function (ret, layerparam)
  19022. {
  19023. var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
  19024. if (cr.is_undefined(layerparam))
  19025. {
  19026. layer = this.runtime.getLayerByNumber(0);
  19027. oldScale = layer.scale;
  19028. oldZoomRate = layer.zoomRate;
  19029. oldParallaxX = layer.parallaxX;
  19030. oldAngle = layer.angle;
  19031. layer.scale = 1;
  19032. layer.zoomRate = 1.0;
  19033. layer.parallaxX = 1.0;
  19034. layer.angle = 0;
  19035. ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
  19036. layer.scale = oldScale;
  19037. layer.zoomRate = oldZoomRate;
  19038. layer.parallaxX = oldParallaxX;
  19039. layer.angle = oldAngle;
  19040. }
  19041. else
  19042. {
  19043. if (cr.is_number(layerparam))
  19044. layer = this.runtime.getLayerByNumber(layerparam);
  19045. else
  19046. layer = this.runtime.getLayerByName(layerparam);
  19047. if (layer)
  19048. ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, true));
  19049. else
  19050. ret.set_float(0);
  19051. }
  19052. };
  19053. Exps.prototype.Y = function (ret, layerparam)
  19054. {
  19055. var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
  19056. if (cr.is_undefined(layerparam))
  19057. {
  19058. layer = this.runtime.getLayerByNumber(0);
  19059. oldScale = layer.scale;
  19060. oldZoomRate = layer.zoomRate;
  19061. oldParallaxY = layer.parallaxY;
  19062. oldAngle = layer.angle;
  19063. layer.scale = 1;
  19064. layer.zoomRate = 1.0;
  19065. layer.parallaxY = 1.0;
  19066. layer.angle = 0;
  19067. ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
  19068. layer.scale = oldScale;
  19069. layer.zoomRate = oldZoomRate;
  19070. layer.parallaxY = oldParallaxY;
  19071. layer.angle = oldAngle;
  19072. }
  19073. else
  19074. {
  19075. if (cr.is_number(layerparam))
  19076. layer = this.runtime.getLayerByNumber(layerparam);
  19077. else
  19078. layer = this.runtime.getLayerByName(layerparam);
  19079. if (layer)
  19080. ret.set_float(layer.canvasToLayer(this.mouseXcanvas, this.mouseYcanvas, false));
  19081. else
  19082. ret.set_float(0);
  19083. }
  19084. };
  19085. Exps.prototype.AbsoluteX = function (ret)
  19086. {
  19087. ret.set_float(this.mouseXcanvas);
  19088. };
  19089. Exps.prototype.AbsoluteY = function (ret)
  19090. {
  19091. ret.set_float(this.mouseYcanvas);
  19092. };
  19093. pluginProto.exps = new Exps();
  19094. }());
  19095. ;
  19096. ;
  19097. cr.plugins_.Rex_ZSorter = function(runtime)
  19098. {
  19099. this.runtime = runtime;
  19100. };
  19101. (function ()
  19102. {
  19103. var pluginProto = cr.plugins_.Rex_ZSorter.prototype;
  19104. pluginProto.Type = function(plugin)
  19105. {
  19106. this.plugin = plugin;
  19107. this.runtime = plugin.runtime;
  19108. };
  19109. var typeProto = pluginProto.Type.prototype;
  19110. typeProto.onCreate = function()
  19111. {
  19112. };
  19113. pluginProto.Instance = function(type)
  19114. {
  19115. this.type = type;
  19116. this.runtime = type.runtime;
  19117. };
  19118. var instanceProto = pluginProto.Instance.prototype;
  19119. var x_increasing = true;
  19120. instanceProto.onCreate = function()
  19121. {
  19122. x_increasing = (this.properties[0] == 0);
  19123. this._cmp_uidA = 0;
  19124. this._cmp_uidB = 0;
  19125. this._compared_result = 0;
  19126. this._sort_fn_name = "";
  19127. };
  19128. instanceProto.draw = function(ctx)
  19129. {
  19130. };
  19131. instanceProto.get_layer = function(layerparam)
  19132. {
  19133. return (typeof layerparam == "number")?
  19134. this.runtime.getLayerByNumber(layerparam):
  19135. this.runtime.getLayerByName(layerparam);
  19136. };
  19137. var _thisArg = null;
  19138. var _sort_fn = function(instance_a, instance_b)
  19139. {
  19140. _thisArg._cmp_uidA = instance_a.uid;
  19141. _thisArg._cmp_uidB = instance_b.uid;
  19142. _thisArg.runtime.trigger(cr.plugins_.Rex_ZSorter.prototype.cnds.OnSortingFn, _thisArg);
  19143. return _thisArg._compared_result;
  19144. };
  19145. instanceProto.saveToJSON = function ()
  19146. {
  19147. return { "xi": x_increasing };
  19148. };
  19149. instanceProto.loadFromJSON = function (o)
  19150. {
  19151. x_increasing = o["xi"];
  19152. };
  19153. function Cnds() {};
  19154. pluginProto.cnds = new Cnds();
  19155. Cnds.prototype.OnSortingFn = function (name)
  19156. {
  19157. return (this._sort_fn_name == name);
  19158. };
  19159. function Acts() {};
  19160. pluginProto.acts = new Acts();
  19161. var ZSORT = function(instance_a, instance_b)
  19162. {
  19163. var ax = instance_a.x;
  19164. var ay = instance_a.y;
  19165. var bx = instance_b.x;
  19166. var by = instance_b.y;
  19167. if (ay > by)
  19168. return 1;
  19169. else if (ay == by)
  19170. {
  19171. if (ax == bx)
  19172. return 0;
  19173. if ((x_increasing && (ax > bx)) || (!x_increasing && (ax < bx)))
  19174. return 1;
  19175. else
  19176. return (-1);
  19177. }
  19178. else // ay < by
  19179. return (-1);
  19180. }
  19181. Acts.prototype.SortObjsLayerByY = function (layerparam)
  19182. {
  19183. var layer = this.get_layer(layerparam);
  19184. if (layer == null)
  19185. {
  19186. alart("Z Sort: Can not find layer " + layerparam);
  19187. return;
  19188. }
  19189. layer.instances.sort(ZSORT);
  19190. layer.zindices_stale = true;
  19191. this.runtime.redraw = true;
  19192. };
  19193. Acts.prototype.SetXorder = function (x_order)
  19194. {
  19195. x_increasing = (x_order == 0);
  19196. };
  19197. Acts.prototype.SortByFn = function (layerparam, fn_name)
  19198. {
  19199. var layer = this.get_layer(layerparam);
  19200. if (layer == null)
  19201. {
  19202. alert("Z Sort: Can not find layer " + layerparam);
  19203. return;
  19204. }
  19205. _thisArg = this;
  19206. this._sort_fn_name = fn_name;
  19207. layer.instances.sort(_sort_fn);
  19208. layer.zindices_stale = true;
  19209. this.runtime.redraw = true;
  19210. };
  19211. Acts.prototype.SetCmpResultDirectly = function (result)
  19212. {
  19213. this._compared_result = result;
  19214. };
  19215. Acts.prototype.SetCmpResultCombo = function (result)
  19216. {
  19217. this._compared_result = result -1;
  19218. };
  19219. function Exps() {};
  19220. pluginProto.exps = new Exps();
  19221. Exps.prototype.CmpUIDA = function (ret)
  19222. {
  19223. ret.set_int(this._cmp_uidA);
  19224. };
  19225. Exps.prototype.CmpUIDB = function (ret)
  19226. {
  19227. ret.set_int(this._cmp_uidB);
  19228. };
  19229. }());
  19230. ;
  19231. ;
  19232. cr.plugins_.Sprite = function(runtime)
  19233. {
  19234. this.runtime = runtime;
  19235. };
  19236. (function ()
  19237. {
  19238. var pluginProto = cr.plugins_.Sprite.prototype;
  19239. pluginProto.Type = function(plugin)
  19240. {
  19241. this.plugin = plugin;
  19242. this.runtime = plugin.runtime;
  19243. };
  19244. var typeProto = pluginProto.Type.prototype;
  19245. function frame_getDataUri()
  19246. {
  19247. if (this.datauri.length === 0)
  19248. {
  19249. var tmpcanvas = document.createElement("canvas");
  19250. tmpcanvas.width = this.width;
  19251. tmpcanvas.height = this.height;
  19252. var tmpctx = tmpcanvas.getContext("2d");
  19253. if (this.spritesheeted)
  19254. {
  19255. tmpctx.drawImage(this.texture_img, this.offx, this.offy, this.width, this.height,
  19256. 0, 0, this.width, this.height);
  19257. }
  19258. else
  19259. {
  19260. tmpctx.drawImage(this.texture_img, 0, 0, this.width, this.height);
  19261. }
  19262. this.datauri = tmpcanvas.toDataURL("image/png");
  19263. }
  19264. return this.datauri;
  19265. };
  19266. typeProto.onCreate = function()
  19267. {
  19268. if (this.is_family)
  19269. return;
  19270. var i, leni, j, lenj;
  19271. var anim, frame, animobj, frameobj, wt, uv;
  19272. this.all_frames = [];
  19273. this.has_loaded_textures = false;
  19274. for (i = 0, leni = this.animations.length; i < leni; i++)
  19275. {
  19276. anim = this.animations[i];
  19277. animobj = {};
  19278. animobj.name = anim[0];
  19279. animobj.speed = anim[1];
  19280. animobj.loop = anim[2];
  19281. animobj.repeatcount = anim[3];
  19282. animobj.repeatto = anim[4];
  19283. animobj.pingpong = anim[5];
  19284. animobj.sid = anim[6];
  19285. animobj.frames = [];
  19286. for (j = 0, lenj = anim[7].length; j < lenj; j++)
  19287. {
  19288. frame = anim[7][j];
  19289. frameobj = {};
  19290. frameobj.texture_file = frame[0];
  19291. frameobj.texture_filesize = frame[1];
  19292. frameobj.offx = frame[2];
  19293. frameobj.offy = frame[3];
  19294. frameobj.width = frame[4];
  19295. frameobj.height = frame[5];
  19296. frameobj.duration = frame[6];
  19297. frameobj.hotspotX = frame[7];
  19298. frameobj.hotspotY = frame[8];
  19299. frameobj.image_points = frame[9];
  19300. frameobj.poly_pts = frame[10];
  19301. frameobj.pixelformat = frame[11];
  19302. frameobj.spritesheeted = (frameobj.width !== 0);
  19303. frameobj.datauri = ""; // generated on demand and cached
  19304. frameobj.getDataUri = frame_getDataUri;
  19305. uv = {};
  19306. uv.left = 0;
  19307. uv.top = 0;
  19308. uv.right = 1;
  19309. uv.bottom = 1;
  19310. frameobj.sheetTex = uv;
  19311. frameobj.webGL_texture = null;
  19312. wt = this.runtime.findWaitingTexture(frame[0]);
  19313. if (wt)
  19314. {
  19315. frameobj.texture_img = wt;
  19316. }
  19317. else
  19318. {
  19319. frameobj.texture_img = new Image();
  19320. frameobj.texture_img.cr_src = frame[0];
  19321. frameobj.texture_img.cr_filesize = frame[1];
  19322. frameobj.texture_img.c2webGL_texture = null;
  19323. this.runtime.waitForImageLoad(frameobj.texture_img, frame[0]);
  19324. }
  19325. cr.seal(frameobj);
  19326. animobj.frames.push(frameobj);
  19327. this.all_frames.push(frameobj);
  19328. }
  19329. cr.seal(animobj);
  19330. this.animations[i] = animobj; // swap array data for object
  19331. }
  19332. };
  19333. typeProto.updateAllCurrentTexture = function ()
  19334. {
  19335. var i, len, inst;
  19336. for (i = 0, len = this.instances.length; i < len; i++)
  19337. {
  19338. inst = this.instances[i];
  19339. inst.curWebGLTexture = inst.curFrame.webGL_texture;
  19340. }
  19341. };
  19342. typeProto.onLostWebGLContext = function ()
  19343. {
  19344. if (this.is_family)
  19345. return;
  19346. var i, len, frame;
  19347. for (i = 0, len = this.all_frames.length; i < len; ++i)
  19348. {
  19349. frame = this.all_frames[i];
  19350. frame.texture_img.c2webGL_texture = null;
  19351. frame.webGL_texture = null;
  19352. }
  19353. this.has_loaded_textures = false;
  19354. this.updateAllCurrentTexture();
  19355. };
  19356. typeProto.onRestoreWebGLContext = function ()
  19357. {
  19358. if (this.is_family || !this.instances.length)
  19359. return;
  19360. var i, len, frame;
  19361. for (i = 0, len = this.all_frames.length; i < len; ++i)
  19362. {
  19363. frame = this.all_frames[i];
  19364. frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
  19365. }
  19366. this.updateAllCurrentTexture();
  19367. };
  19368. typeProto.loadTextures = function ()
  19369. {
  19370. if (this.is_family || this.has_loaded_textures || !this.runtime.glwrap)
  19371. return;
  19372. var i, len, frame;
  19373. for (i = 0, len = this.all_frames.length; i < len; ++i)
  19374. {
  19375. frame = this.all_frames[i];
  19376. frame.webGL_texture = this.runtime.glwrap.loadTexture(frame.texture_img, false, this.runtime.linearSampling, frame.pixelformat);
  19377. }
  19378. this.has_loaded_textures = true;
  19379. };
  19380. typeProto.unloadTextures = function ()
  19381. {
  19382. if (this.is_family || this.instances.length || !this.has_loaded_textures)
  19383. return;
  19384. var i, len, frame;
  19385. for (i = 0, len = this.all_frames.length; i < len; ++i)
  19386. {
  19387. frame = this.all_frames[i];
  19388. this.runtime.glwrap.deleteTexture(frame.webGL_texture);
  19389. frame.webGL_texture = null;
  19390. }
  19391. this.has_loaded_textures = false;
  19392. };
  19393. var already_drawn_images = [];
  19394. typeProto.preloadCanvas2D = function (ctx)
  19395. {
  19396. var i, len, frameimg;
  19397. cr.clearArray(already_drawn_images);
  19398. for (i = 0, len = this.all_frames.length; i < len; ++i)
  19399. {
  19400. frameimg = this.all_frames[i].texture_img;
  19401. if (already_drawn_images.indexOf(frameimg) !== -1)
  19402. continue;
  19403. ctx.drawImage(frameimg, 0, 0);
  19404. already_drawn_images.push(frameimg);
  19405. }
  19406. };
  19407. pluginProto.Instance = function(type)
  19408. {
  19409. this.type = type;
  19410. this.runtime = type.runtime;
  19411. var poly_pts = this.type.animations[0].frames[0].poly_pts;
  19412. if (this.recycled)
  19413. this.collision_poly.set_pts(poly_pts);
  19414. else
  19415. this.collision_poly = new cr.CollisionPoly(poly_pts);
  19416. };
  19417. var instanceProto = pluginProto.Instance.prototype;
  19418. instanceProto.onCreate = function()
  19419. {
  19420. this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
  19421. this.isTicking = false;
  19422. this.inAnimTrigger = false;
  19423. this.collisionsEnabled = (this.properties[3] !== 0);
  19424. if (!(this.type.animations.length === 1 && this.type.animations[0].frames.length === 1) && this.type.animations[0].speed !== 0)
  19425. {
  19426. this.runtime.tickMe(this);
  19427. this.isTicking = true;
  19428. }
  19429. this.cur_animation = this.getAnimationByName(this.properties[1]) || this.type.animations[0];
  19430. this.cur_frame = this.properties[2];
  19431. if (this.cur_frame < 0)
  19432. this.cur_frame = 0;
  19433. if (this.cur_frame >= this.cur_animation.frames.length)
  19434. this.cur_frame = this.cur_animation.frames.length - 1;
  19435. var curanimframe = this.cur_animation.frames[this.cur_frame];
  19436. this.collision_poly.set_pts(curanimframe.poly_pts);
  19437. this.hotspotX = curanimframe.hotspotX;
  19438. this.hotspotY = curanimframe.hotspotY;
  19439. this.cur_anim_speed = this.cur_animation.speed;
  19440. if (this.recycled)
  19441. this.animTimer.reset();
  19442. else
  19443. this.animTimer = new cr.KahanAdder();
  19444. this.frameStart = this.getNowTime();
  19445. this.animPlaying = true;
  19446. this.animRepeats = 0;
  19447. this.animForwards = true;
  19448. this.animTriggerName = "";
  19449. this.changeAnimName = "";
  19450. this.changeAnimFrom = 0;
  19451. this.changeAnimFrame = -1;
  19452. this.type.loadTextures();
  19453. var i, leni, j, lenj;
  19454. var anim, frame, uv, maintex;
  19455. for (i = 0, leni = this.type.animations.length; i < leni; i++)
  19456. {
  19457. anim = this.type.animations[i];
  19458. for (j = 0, lenj = anim.frames.length; j < lenj; j++)
  19459. {
  19460. frame = anim.frames[j];
  19461. if (frame.width === 0)
  19462. {
  19463. frame.width = frame.texture_img.width;
  19464. frame.height = frame.texture_img.height;
  19465. }
  19466. if (frame.spritesheeted)
  19467. {
  19468. maintex = frame.texture_img;
  19469. uv = frame.sheetTex;
  19470. uv.left = frame.offx / maintex.width;
  19471. uv.top = frame.offy / maintex.height;
  19472. uv.right = (frame.offx + frame.width) / maintex.width;
  19473. uv.bottom = (frame.offy + frame.height) / maintex.height;
  19474. if (frame.offx === 0 && frame.offy === 0 && frame.width === maintex.width && frame.height === maintex.height)
  19475. {
  19476. frame.spritesheeted = false;
  19477. }
  19478. }
  19479. }
  19480. }
  19481. this.curFrame = this.cur_animation.frames[this.cur_frame];
  19482. this.curWebGLTexture = this.curFrame.webGL_texture;
  19483. };
  19484. instanceProto.saveToJSON = function ()
  19485. {
  19486. var o = {
  19487. "a": this.cur_animation.sid,
  19488. "f": this.cur_frame,
  19489. "cas": this.cur_anim_speed,
  19490. "fs": this.frameStart,
  19491. "ar": this.animRepeats,
  19492. "at": this.animTimer.sum
  19493. };
  19494. if (!this.animPlaying)
  19495. o["ap"] = this.animPlaying;
  19496. if (!this.animForwards)
  19497. o["af"] = this.animForwards;
  19498. return o;
  19499. };
  19500. instanceProto.loadFromJSON = function (o)
  19501. {
  19502. var anim = this.getAnimationBySid(o["a"]);
  19503. if (anim)
  19504. this.cur_animation = anim;
  19505. this.cur_frame = o["f"];
  19506. if (this.cur_frame < 0)
  19507. this.cur_frame = 0;
  19508. if (this.cur_frame >= this.cur_animation.frames.length)
  19509. this.cur_frame = this.cur_animation.frames.length - 1;
  19510. this.cur_anim_speed = o["cas"];
  19511. this.frameStart = o["fs"];
  19512. this.animRepeats = o["ar"];
  19513. this.animTimer.reset();
  19514. this.animTimer.sum = o["at"];
  19515. this.animPlaying = o.hasOwnProperty("ap") ? o["ap"] : true;
  19516. this.animForwards = o.hasOwnProperty("af") ? o["af"] : true;
  19517. this.curFrame = this.cur_animation.frames[this.cur_frame];
  19518. this.curWebGLTexture = this.curFrame.webGL_texture;
  19519. this.collision_poly.set_pts(this.curFrame.poly_pts);
  19520. this.hotspotX = this.curFrame.hotspotX;
  19521. this.hotspotY = this.curFrame.hotspotY;
  19522. };
  19523. instanceProto.animationFinish = function (reverse)
  19524. {
  19525. this.cur_frame = reverse ? 0 : this.cur_animation.frames.length - 1;
  19526. this.animPlaying = false;
  19527. this.animTriggerName = this.cur_animation.name;
  19528. this.inAnimTrigger = true;
  19529. this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished, this);
  19530. this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnAnimFinished, this);
  19531. this.inAnimTrigger = false;
  19532. this.animRepeats = 0;
  19533. };
  19534. instanceProto.getNowTime = function()
  19535. {
  19536. return this.animTimer.sum;
  19537. };
  19538. instanceProto.tick = function()
  19539. {
  19540. this.animTimer.add(this.runtime.getDt(this));
  19541. if (this.changeAnimName.length)
  19542. this.doChangeAnim();
  19543. if (this.changeAnimFrame >= 0)
  19544. this.doChangeAnimFrame();
  19545. var now = this.getNowTime();
  19546. var cur_animation = this.cur_animation;
  19547. var prev_frame = cur_animation.frames[this.cur_frame];
  19548. var next_frame;
  19549. var cur_frame_time = prev_frame.duration / this.cur_anim_speed;
  19550. if (this.animPlaying && now >= this.frameStart + cur_frame_time)
  19551. {
  19552. if (this.animForwards)
  19553. {
  19554. this.cur_frame++;
  19555. }
  19556. else
  19557. {
  19558. this.cur_frame--;
  19559. }
  19560. this.frameStart += cur_frame_time;
  19561. if (this.cur_frame >= cur_animation.frames.length)
  19562. {
  19563. if (cur_animation.pingpong)
  19564. {
  19565. this.animForwards = false;
  19566. this.cur_frame = cur_animation.frames.length - 2;
  19567. }
  19568. else if (cur_animation.loop)
  19569. {
  19570. this.cur_frame = cur_animation.repeatto;
  19571. }
  19572. else
  19573. {
  19574. this.animRepeats++;
  19575. if (this.animRepeats >= cur_animation.repeatcount)
  19576. {
  19577. this.animationFinish(false);
  19578. }
  19579. else
  19580. {
  19581. this.cur_frame = cur_animation.repeatto;
  19582. }
  19583. }
  19584. }
  19585. if (this.cur_frame < 0)
  19586. {
  19587. if (cur_animation.pingpong)
  19588. {
  19589. this.cur_frame = 1;
  19590. this.animForwards = true;
  19591. if (!cur_animation.loop)
  19592. {
  19593. this.animRepeats++;
  19594. if (this.animRepeats >= cur_animation.repeatcount)
  19595. {
  19596. this.animationFinish(true);
  19597. }
  19598. }
  19599. }
  19600. else
  19601. {
  19602. if (cur_animation.loop)
  19603. {
  19604. this.cur_frame = cur_animation.repeatto;
  19605. }
  19606. else
  19607. {
  19608. this.animRepeats++;
  19609. if (this.animRepeats >= cur_animation.repeatcount)
  19610. {
  19611. this.animationFinish(true);
  19612. }
  19613. else
  19614. {
  19615. this.cur_frame = cur_animation.repeatto;
  19616. }
  19617. }
  19618. }
  19619. }
  19620. if (this.cur_frame < 0)
  19621. this.cur_frame = 0;
  19622. else if (this.cur_frame >= cur_animation.frames.length)
  19623. this.cur_frame = cur_animation.frames.length - 1;
  19624. if (now > this.frameStart + (cur_animation.frames[this.cur_frame].duration / this.cur_anim_speed))
  19625. {
  19626. this.frameStart = now;
  19627. }
  19628. next_frame = cur_animation.frames[this.cur_frame];
  19629. this.OnFrameChanged(prev_frame, next_frame);
  19630. this.runtime.redraw = true;
  19631. }
  19632. };
  19633. instanceProto.getAnimationByName = function (name_)
  19634. {
  19635. var i, len, a;
  19636. for (i = 0, len = this.type.animations.length; i < len; i++)
  19637. {
  19638. a = this.type.animations[i];
  19639. if (cr.equals_nocase(a.name, name_))
  19640. return a;
  19641. }
  19642. return null;
  19643. };
  19644. instanceProto.getAnimationBySid = function (sid_)
  19645. {
  19646. var i, len, a;
  19647. for (i = 0, len = this.type.animations.length; i < len; i++)
  19648. {
  19649. a = this.type.animations[i];
  19650. if (a.sid === sid_)
  19651. return a;
  19652. }
  19653. return null;
  19654. };
  19655. instanceProto.doChangeAnim = function ()
  19656. {
  19657. var prev_frame = this.cur_animation.frames[this.cur_frame];
  19658. var anim = this.getAnimationByName(this.changeAnimName);
  19659. this.changeAnimName = "";
  19660. if (!anim)
  19661. return;
  19662. if (cr.equals_nocase(anim.name, this.cur_animation.name) && this.animPlaying)
  19663. return;
  19664. this.cur_animation = anim;
  19665. this.cur_anim_speed = anim.speed;
  19666. if (this.cur_frame < 0)
  19667. this.cur_frame = 0;
  19668. if (this.cur_frame >= this.cur_animation.frames.length)
  19669. this.cur_frame = this.cur_animation.frames.length - 1;
  19670. if (this.changeAnimFrom === 1)
  19671. this.cur_frame = 0;
  19672. this.animPlaying = true;
  19673. this.frameStart = this.getNowTime();
  19674. this.animForwards = true;
  19675. this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
  19676. this.runtime.redraw = true;
  19677. };
  19678. instanceProto.doChangeAnimFrame = function ()
  19679. {
  19680. var prev_frame = this.cur_animation.frames[this.cur_frame];
  19681. var prev_frame_number = this.cur_frame;
  19682. this.cur_frame = cr.floor(this.changeAnimFrame);
  19683. if (this.cur_frame < 0)
  19684. this.cur_frame = 0;
  19685. if (this.cur_frame >= this.cur_animation.frames.length)
  19686. this.cur_frame = this.cur_animation.frames.length - 1;
  19687. if (prev_frame_number !== this.cur_frame)
  19688. {
  19689. this.OnFrameChanged(prev_frame, this.cur_animation.frames[this.cur_frame]);
  19690. this.frameStart = this.getNowTime();
  19691. this.runtime.redraw = true;
  19692. }
  19693. this.changeAnimFrame = -1;
  19694. };
  19695. instanceProto.OnFrameChanged = function (prev_frame, next_frame)
  19696. {
  19697. var oldw = prev_frame.width;
  19698. var oldh = prev_frame.height;
  19699. var neww = next_frame.width;
  19700. var newh = next_frame.height;
  19701. if (oldw != neww)
  19702. this.width *= (neww / oldw);
  19703. if (oldh != newh)
  19704. this.height *= (newh / oldh);
  19705. this.hotspotX = next_frame.hotspotX;
  19706. this.hotspotY = next_frame.hotspotY;
  19707. this.collision_poly.set_pts(next_frame.poly_pts);
  19708. this.set_bbox_changed();
  19709. this.curFrame = next_frame;
  19710. this.curWebGLTexture = next_frame.webGL_texture;
  19711. var i, len, b;
  19712. for (i = 0, len = this.behavior_insts.length; i < len; i++)
  19713. {
  19714. b = this.behavior_insts[i];
  19715. if (b.onSpriteFrameChanged)
  19716. b.onSpriteFrameChanged(prev_frame, next_frame);
  19717. }
  19718. this.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnFrameChanged, this);
  19719. };
  19720. instanceProto.draw = function(ctx)
  19721. {
  19722. ctx.globalAlpha = this.opacity;
  19723. var cur_frame = this.curFrame;
  19724. var spritesheeted = cur_frame.spritesheeted;
  19725. var cur_image = cur_frame.texture_img;
  19726. var myx = this.x;
  19727. var myy = this.y;
  19728. var w = this.width;
  19729. var h = this.height;
  19730. if (this.angle === 0 && w >= 0 && h >= 0)
  19731. {
  19732. myx -= this.hotspotX * w;
  19733. myy -= this.hotspotY * h;
  19734. if (this.runtime.pixel_rounding)
  19735. {
  19736. myx = Math.round(myx);
  19737. myy = Math.round(myy);
  19738. }
  19739. if (spritesheeted)
  19740. {
  19741. ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
  19742. myx, myy, w, h);
  19743. }
  19744. else
  19745. {
  19746. ctx.drawImage(cur_image, myx, myy, w, h);
  19747. }
  19748. }
  19749. else
  19750. {
  19751. if (this.runtime.pixel_rounding)
  19752. {
  19753. myx = Math.round(myx);
  19754. myy = Math.round(myy);
  19755. }
  19756. ctx.save();
  19757. var widthfactor = w > 0 ? 1 : -1;
  19758. var heightfactor = h > 0 ? 1 : -1;
  19759. ctx.translate(myx, myy);
  19760. if (widthfactor !== 1 || heightfactor !== 1)
  19761. ctx.scale(widthfactor, heightfactor);
  19762. ctx.rotate(this.angle * widthfactor * heightfactor);
  19763. var drawx = 0 - (this.hotspotX * cr.abs(w))
  19764. var drawy = 0 - (this.hotspotY * cr.abs(h));
  19765. if (spritesheeted)
  19766. {
  19767. ctx.drawImage(cur_image, cur_frame.offx, cur_frame.offy, cur_frame.width, cur_frame.height,
  19768. drawx, drawy, cr.abs(w), cr.abs(h));
  19769. }
  19770. else
  19771. {
  19772. ctx.drawImage(cur_image, drawx, drawy, cr.abs(w), cr.abs(h));
  19773. }
  19774. ctx.restore();
  19775. }
  19776. /*
  19777. ctx.strokeStyle = "#f00";
  19778. ctx.lineWidth = 3;
  19779. ctx.beginPath();
  19780. this.collision_poly.cache_poly(this.width, this.height, this.angle);
  19781. var i, len, ax, ay, bx, by;
  19782. for (i = 0, len = this.collision_poly.pts_count; i < len; i++)
  19783. {
  19784. ax = this.collision_poly.pts_cache[i*2] + this.x;
  19785. ay = this.collision_poly.pts_cache[i*2+1] + this.y;
  19786. bx = this.collision_poly.pts_cache[((i+1)%len)*2] + this.x;
  19787. by = this.collision_poly.pts_cache[((i+1)%len)*2+1] + this.y;
  19788. ctx.moveTo(ax, ay);
  19789. ctx.lineTo(bx, by);
  19790. }
  19791. ctx.stroke();
  19792. ctx.closePath();
  19793. */
  19794. /*
  19795. if (this.behavior_insts.length >= 1 && this.behavior_insts[0].draw)
  19796. {
  19797. this.behavior_insts[0].draw(ctx);
  19798. }
  19799. */
  19800. };
  19801. instanceProto.drawGL_earlyZPass = function(glw)
  19802. {
  19803. this.drawGL(glw);
  19804. };
  19805. instanceProto.drawGL = function(glw)
  19806. {
  19807. glw.setTexture(this.curWebGLTexture);
  19808. glw.setOpacity(this.opacity);
  19809. var cur_frame = this.curFrame;
  19810. var q = this.bquad;
  19811. if (this.runtime.pixel_rounding)
  19812. {
  19813. var ox = Math.round(this.x) - this.x;
  19814. var oy = Math.round(this.y) - this.y;
  19815. if (cur_frame.spritesheeted)
  19816. glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, cur_frame.sheetTex);
  19817. else
  19818. glw.quad(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy);
  19819. }
  19820. else
  19821. {
  19822. if (cur_frame.spritesheeted)
  19823. glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, cur_frame.sheetTex);
  19824. else
  19825. glw.quad(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly);
  19826. }
  19827. };
  19828. instanceProto.getImagePointIndexByName = function(name_)
  19829. {
  19830. var cur_frame = this.curFrame;
  19831. var i, len;
  19832. for (i = 0, len = cur_frame.image_points.length; i < len; i++)
  19833. {
  19834. if (cr.equals_nocase(name_, cur_frame.image_points[i][0]))
  19835. return i;
  19836. }
  19837. return -1;
  19838. };
  19839. instanceProto.getImagePoint = function(imgpt, getX)
  19840. {
  19841. var cur_frame = this.curFrame;
  19842. var image_points = cur_frame.image_points;
  19843. var index;
  19844. if (cr.is_string(imgpt))
  19845. index = this.getImagePointIndexByName(imgpt);
  19846. else
  19847. index = imgpt - 1; // 0 is origin
  19848. index = cr.floor(index);
  19849. if (index < 0 || index >= image_points.length)
  19850. return getX ? this.x : this.y; // return origin
  19851. var x = (image_points[index][1] - cur_frame.hotspotX) * this.width;
  19852. var y = image_points[index][2];
  19853. y = (y - cur_frame.hotspotY) * this.height;
  19854. var cosa = Math.cos(this.angle);
  19855. var sina = Math.sin(this.angle);
  19856. var x_temp = (x * cosa) - (y * sina);
  19857. y = (y * cosa) + (x * sina);
  19858. x = x_temp;
  19859. x += this.x;
  19860. y += this.y;
  19861. return getX ? x : y;
  19862. };
  19863. function Cnds() {};
  19864. var arrCache = [];
  19865. function allocArr()
  19866. {
  19867. if (arrCache.length)
  19868. return arrCache.pop();
  19869. else
  19870. return [0, 0, 0];
  19871. };
  19872. function freeArr(a)
  19873. {
  19874. a[0] = 0;
  19875. a[1] = 0;
  19876. a[2] = 0;
  19877. arrCache.push(a);
  19878. };
  19879. function makeCollKey(a, b)
  19880. {
  19881. if (a < b)
  19882. return "" + a + "," + b;
  19883. else
  19884. return "" + b + "," + a;
  19885. };
  19886. function collmemory_add(collmemory, a, b, tickcount)
  19887. {
  19888. var a_uid = a.uid;
  19889. var b_uid = b.uid;
  19890. var key = makeCollKey(a_uid, b_uid);
  19891. if (collmemory.hasOwnProperty(key))
  19892. {
  19893. collmemory[key][2] = tickcount;
  19894. return;
  19895. }
  19896. var arr = allocArr();
  19897. arr[0] = a_uid;
  19898. arr[1] = b_uid;
  19899. arr[2] = tickcount;
  19900. collmemory[key] = arr;
  19901. };
  19902. function collmemory_remove(collmemory, a, b)
  19903. {
  19904. var key = makeCollKey(a.uid, b.uid);
  19905. if (collmemory.hasOwnProperty(key))
  19906. {
  19907. freeArr(collmemory[key]);
  19908. delete collmemory[key];
  19909. }
  19910. };
  19911. function collmemory_removeInstance(collmemory, inst)
  19912. {
  19913. var uid = inst.uid;
  19914. var p, entry;
  19915. for (p in collmemory)
  19916. {
  19917. if (collmemory.hasOwnProperty(p))
  19918. {
  19919. entry = collmemory[p];
  19920. if (entry[0] === uid || entry[1] === uid)
  19921. {
  19922. freeArr(collmemory[p]);
  19923. delete collmemory[p];
  19924. }
  19925. }
  19926. }
  19927. };
  19928. var last_coll_tickcount = -2;
  19929. function collmemory_has(collmemory, a, b)
  19930. {
  19931. var key = makeCollKey(a.uid, b.uid);
  19932. if (collmemory.hasOwnProperty(key))
  19933. {
  19934. last_coll_tickcount = collmemory[key][2];
  19935. return true;
  19936. }
  19937. else
  19938. {
  19939. last_coll_tickcount = -2;
  19940. return false;
  19941. }
  19942. };
  19943. var candidates1 = [];
  19944. Cnds.prototype.OnCollision = function (rtype)
  19945. {
  19946. if (!rtype)
  19947. return false;
  19948. var runtime = this.runtime;
  19949. var cnd = runtime.getCurrentCondition();
  19950. var ltype = cnd.type;
  19951. var collmemory = null;
  19952. if (cnd.extra["collmemory"])
  19953. {
  19954. collmemory = cnd.extra["collmemory"];
  19955. }
  19956. else
  19957. {
  19958. collmemory = {};
  19959. cnd.extra["collmemory"] = collmemory;
  19960. runtime.addDestroyCallback(function(inst) {
  19961. collmemory_removeInstance(cnd.extra["collmemory"], inst);
  19962. });
  19963. }
  19964. var lsol = ltype.getCurrentSol();
  19965. var rsol = rtype.getCurrentSol();
  19966. var linstances = lsol.getObjects();
  19967. var rinstances;
  19968. var l, linst, r, rinst;
  19969. var curlsol, currsol;
  19970. var tickcount = this.runtime.tickcount;
  19971. var lasttickcount = tickcount - 1;
  19972. var exists, run;
  19973. var current_event = runtime.getCurrentEventStack().current_event;
  19974. var orblock = current_event.orblock;
  19975. for (l = 0; l < linstances.length; l++)
  19976. {
  19977. linst = linstances[l];
  19978. if (rsol.select_all)
  19979. {
  19980. linst.update_bbox();
  19981. this.runtime.getCollisionCandidates(linst.layer, rtype, linst.bbox, candidates1);
  19982. rinstances = candidates1;
  19983. }
  19984. else
  19985. rinstances = rsol.getObjects();
  19986. for (r = 0; r < rinstances.length; r++)
  19987. {
  19988. rinst = rinstances[r];
  19989. if (runtime.testOverlap(linst, rinst) || runtime.checkRegisteredCollision(linst, rinst))
  19990. {
  19991. exists = collmemory_has(collmemory, linst, rinst);
  19992. run = (!exists || (last_coll_tickcount < lasttickcount));
  19993. collmemory_add(collmemory, linst, rinst, tickcount);
  19994. if (run)
  19995. {
  19996. runtime.pushCopySol(current_event.solModifiers);
  19997. curlsol = ltype.getCurrentSol();
  19998. currsol = rtype.getCurrentSol();
  19999. curlsol.select_all = false;
  20000. currsol.select_all = false;
  20001. if (ltype === rtype)
  20002. {
  20003. curlsol.instances.length = 2; // just use lsol, is same reference as rsol
  20004. curlsol.instances[0] = linst;
  20005. curlsol.instances[1] = rinst;
  20006. ltype.applySolToContainer();
  20007. }
  20008. else
  20009. {
  20010. curlsol.instances.length = 1;
  20011. currsol.instances.length = 1;
  20012. curlsol.instances[0] = linst;
  20013. currsol.instances[0] = rinst;
  20014. ltype.applySolToContainer();
  20015. rtype.applySolToContainer();
  20016. }
  20017. current_event.retrigger();
  20018. runtime.popSol(current_event.solModifiers);
  20019. }
  20020. }
  20021. else
  20022. {
  20023. collmemory_remove(collmemory, linst, rinst);
  20024. }
  20025. }
  20026. cr.clearArray(candidates1);
  20027. }
  20028. return false;
  20029. };
  20030. var rpicktype = null;
  20031. var rtopick = new cr.ObjectSet();
  20032. var needscollisionfinish = false;
  20033. var candidates2 = [];
  20034. var temp_bbox = new cr.rect(0, 0, 0, 0);
  20035. function DoOverlapCondition(rtype, offx, offy)
  20036. {
  20037. if (!rtype)
  20038. return false;
  20039. var do_offset = (offx !== 0 || offy !== 0);
  20040. var oldx, oldy, ret = false, r, lenr, rinst;
  20041. var cnd = this.runtime.getCurrentCondition();
  20042. var ltype = cnd.type;
  20043. var inverted = cnd.inverted;
  20044. var rsol = rtype.getCurrentSol();
  20045. var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
  20046. var rinstances;
  20047. if (rsol.select_all)
  20048. {
  20049. this.update_bbox();
  20050. temp_bbox.copy(this.bbox);
  20051. temp_bbox.offset(offx, offy);
  20052. this.runtime.getCollisionCandidates(this.layer, rtype, temp_bbox, candidates2);
  20053. rinstances = candidates2;
  20054. }
  20055. else if (orblock)
  20056. rinstances = rsol.else_instances;
  20057. else
  20058. rinstances = rsol.instances;
  20059. rpicktype = rtype;
  20060. needscollisionfinish = (ltype !== rtype && !inverted);
  20061. if (do_offset)
  20062. {
  20063. oldx = this.x;
  20064. oldy = this.y;
  20065. this.x += offx;
  20066. this.y += offy;
  20067. this.set_bbox_changed();
  20068. }
  20069. for (r = 0, lenr = rinstances.length; r < lenr; r++)
  20070. {
  20071. rinst = rinstances[r];
  20072. if (this.runtime.testOverlap(this, rinst))
  20073. {
  20074. ret = true;
  20075. if (inverted)
  20076. break;
  20077. if (ltype !== rtype)
  20078. rtopick.add(rinst);
  20079. }
  20080. }
  20081. if (do_offset)
  20082. {
  20083. this.x = oldx;
  20084. this.y = oldy;
  20085. this.set_bbox_changed();
  20086. }
  20087. cr.clearArray(candidates2);
  20088. return ret;
  20089. };
  20090. typeProto.finish = function (do_pick)
  20091. {
  20092. if (!needscollisionfinish)
  20093. return;
  20094. if (do_pick)
  20095. {
  20096. var orblock = this.runtime.getCurrentEventStack().current_event.orblock;
  20097. var sol = rpicktype.getCurrentSol();
  20098. var topick = rtopick.valuesRef();
  20099. var i, len, inst;
  20100. if (sol.select_all)
  20101. {
  20102. sol.select_all = false;
  20103. cr.clearArray(sol.instances);
  20104. for (i = 0, len = topick.length; i < len; ++i)
  20105. {
  20106. sol.instances[i] = topick[i];
  20107. }
  20108. if (orblock)
  20109. {
  20110. cr.clearArray(sol.else_instances);
  20111. for (i = 0, len = rpicktype.instances.length; i < len; ++i)
  20112. {
  20113. inst = rpicktype.instances[i];
  20114. if (!rtopick.contains(inst))
  20115. sol.else_instances.push(inst);
  20116. }
  20117. }
  20118. }
  20119. else
  20120. {
  20121. if (orblock)
  20122. {
  20123. var initsize = sol.instances.length;
  20124. for (i = 0, len = topick.length; i < len; ++i)
  20125. {
  20126. sol.instances[initsize + i] = topick[i];
  20127. cr.arrayFindRemove(sol.else_instances, topick[i]);
  20128. }
  20129. }
  20130. else
  20131. {
  20132. cr.shallowAssignArray(sol.instances, topick);
  20133. }
  20134. }
  20135. rpicktype.applySolToContainer();
  20136. }
  20137. rtopick.clear();
  20138. needscollisionfinish = false;
  20139. };
  20140. Cnds.prototype.IsOverlapping = function (rtype)
  20141. {
  20142. return DoOverlapCondition.call(this, rtype, 0, 0);
  20143. };
  20144. Cnds.prototype.IsOverlappingOffset = function (rtype, offx, offy)
  20145. {
  20146. return DoOverlapCondition.call(this, rtype, offx, offy);
  20147. };
  20148. Cnds.prototype.IsAnimPlaying = function (animname)
  20149. {
  20150. if (this.changeAnimName.length)
  20151. return cr.equals_nocase(this.changeAnimName, animname);
  20152. else
  20153. return cr.equals_nocase(this.cur_animation.name, animname);
  20154. };
  20155. Cnds.prototype.CompareFrame = function (cmp, framenum)
  20156. {
  20157. return cr.do_cmp(this.cur_frame, cmp, framenum);
  20158. };
  20159. Cnds.prototype.CompareAnimSpeed = function (cmp, x)
  20160. {
  20161. var s = (this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
  20162. return cr.do_cmp(s, cmp, x);
  20163. };
  20164. Cnds.prototype.OnAnimFinished = function (animname)
  20165. {
  20166. return cr.equals_nocase(this.animTriggerName, animname);
  20167. };
  20168. Cnds.prototype.OnAnyAnimFinished = function ()
  20169. {
  20170. return true;
  20171. };
  20172. Cnds.prototype.OnFrameChanged = function ()
  20173. {
  20174. return true;
  20175. };
  20176. Cnds.prototype.IsMirrored = function ()
  20177. {
  20178. return this.width < 0;
  20179. };
  20180. Cnds.prototype.IsFlipped = function ()
  20181. {
  20182. return this.height < 0;
  20183. };
  20184. Cnds.prototype.OnURLLoaded = function ()
  20185. {
  20186. return true;
  20187. };
  20188. Cnds.prototype.IsCollisionEnabled = function ()
  20189. {
  20190. return this.collisionsEnabled;
  20191. };
  20192. pluginProto.cnds = new Cnds();
  20193. function Acts() {};
  20194. Acts.prototype.Spawn = function (obj, layer, imgpt)
  20195. {
  20196. if (!obj || !layer)
  20197. return;
  20198. var inst = this.runtime.createInstance(obj, layer, this.getImagePoint(imgpt, true), this.getImagePoint(imgpt, false));
  20199. if (!inst)
  20200. return;
  20201. if (typeof inst.angle !== "undefined")
  20202. {
  20203. inst.angle = this.angle;
  20204. inst.set_bbox_changed();
  20205. }
  20206. this.runtime.isInOnDestroy++;
  20207. var i, len, s;
  20208. this.runtime.trigger(Object.getPrototypeOf(obj.plugin).cnds.OnCreated, inst);
  20209. if (inst.is_contained)
  20210. {
  20211. for (i = 0, len = inst.siblings.length; i < len; i++)
  20212. {
  20213. s = inst.siblings[i];
  20214. this.runtime.trigger(Object.getPrototypeOf(s.type.plugin).cnds.OnCreated, s);
  20215. }
  20216. }
  20217. this.runtime.isInOnDestroy--;
  20218. var cur_act = this.runtime.getCurrentAction();
  20219. var reset_sol = false;
  20220. if (cr.is_undefined(cur_act.extra["Spawn_LastExec"]) || cur_act.extra["Spawn_LastExec"] < this.runtime.execcount)
  20221. {
  20222. reset_sol = true;
  20223. cur_act.extra["Spawn_LastExec"] = this.runtime.execcount;
  20224. }
  20225. var sol;
  20226. if (obj != this.type)
  20227. {
  20228. sol = obj.getCurrentSol();
  20229. sol.select_all = false;
  20230. if (reset_sol)
  20231. {
  20232. cr.clearArray(sol.instances);
  20233. sol.instances[0] = inst;
  20234. }
  20235. else
  20236. sol.instances.push(inst);
  20237. if (inst.is_contained)
  20238. {
  20239. for (i = 0, len = inst.siblings.length; i < len; i++)
  20240. {
  20241. s = inst.siblings[i];
  20242. sol = s.type.getCurrentSol();
  20243. sol.select_all = false;
  20244. if (reset_sol)
  20245. {
  20246. cr.clearArray(sol.instances);
  20247. sol.instances[0] = s;
  20248. }
  20249. else
  20250. sol.instances.push(s);
  20251. }
  20252. }
  20253. }
  20254. };
  20255. Acts.prototype.SetEffect = function (effect)
  20256. {
  20257. this.blend_mode = effect;
  20258. this.compositeOp = cr.effectToCompositeOp(effect);
  20259. cr.setGLBlend(this, effect, this.runtime.gl);
  20260. this.runtime.redraw = true;
  20261. };
  20262. Acts.prototype.StopAnim = function ()
  20263. {
  20264. this.animPlaying = false;
  20265. };
  20266. Acts.prototype.StartAnim = function (from)
  20267. {
  20268. this.animPlaying = true;
  20269. this.frameStart = this.getNowTime();
  20270. if (from === 1 && this.cur_frame !== 0)
  20271. {
  20272. this.changeAnimFrame = 0;
  20273. if (!this.inAnimTrigger)
  20274. this.doChangeAnimFrame();
  20275. }
  20276. if (!this.isTicking)
  20277. {
  20278. this.runtime.tickMe(this);
  20279. this.isTicking = true;
  20280. }
  20281. };
  20282. Acts.prototype.SetAnim = function (animname, from)
  20283. {
  20284. this.changeAnimName = animname;
  20285. this.changeAnimFrom = from;
  20286. if (!this.isTicking)
  20287. {
  20288. this.runtime.tickMe(this);
  20289. this.isTicking = true;
  20290. }
  20291. if (!this.inAnimTrigger)
  20292. this.doChangeAnim();
  20293. };
  20294. Acts.prototype.SetAnimFrame = function (framenumber)
  20295. {
  20296. this.changeAnimFrame = framenumber;
  20297. if (!this.isTicking)
  20298. {
  20299. this.runtime.tickMe(this);
  20300. this.isTicking = true;
  20301. }
  20302. if (!this.inAnimTrigger)
  20303. this.doChangeAnimFrame();
  20304. };
  20305. Acts.prototype.SetAnimSpeed = function (s)
  20306. {
  20307. this.cur_anim_speed = cr.abs(s);
  20308. this.animForwards = (s >= 0);
  20309. if (!this.isTicking)
  20310. {
  20311. this.runtime.tickMe(this);
  20312. this.isTicking = true;
  20313. }
  20314. };
  20315. Acts.prototype.SetMirrored = function (m)
  20316. {
  20317. var neww = cr.abs(this.width) * (m === 0 ? -1 : 1);
  20318. if (this.width === neww)
  20319. return;
  20320. this.width = neww;
  20321. this.set_bbox_changed();
  20322. };
  20323. Acts.prototype.SetFlipped = function (f)
  20324. {
  20325. var newh = cr.abs(this.height) * (f === 0 ? -1 : 1);
  20326. if (this.height === newh)
  20327. return;
  20328. this.height = newh;
  20329. this.set_bbox_changed();
  20330. };
  20331. Acts.prototype.SetScale = function (s)
  20332. {
  20333. var cur_frame = this.curFrame;
  20334. var mirror_factor = (this.width < 0 ? -1 : 1);
  20335. var flip_factor = (this.height < 0 ? -1 : 1);
  20336. var new_width = cur_frame.width * s * mirror_factor;
  20337. var new_height = cur_frame.height * s * flip_factor;
  20338. if (this.width !== new_width || this.height !== new_height)
  20339. {
  20340. this.width = new_width;
  20341. this.height = new_height;
  20342. this.set_bbox_changed();
  20343. }
  20344. };
  20345. Acts.prototype.LoadURL = function (url_, resize_)
  20346. {
  20347. var img = new Image();
  20348. var self = this;
  20349. var curFrame_ = this.curFrame;
  20350. img.onload = function ()
  20351. {
  20352. if (curFrame_.texture_img.src === img.src)
  20353. {
  20354. if (self.runtime.glwrap && self.curFrame === curFrame_)
  20355. self.curWebGLTexture = curFrame_.webGL_texture;
  20356. if (resize_ === 0) // resize to image size
  20357. {
  20358. self.width = img.width;
  20359. self.height = img.height;
  20360. self.set_bbox_changed();
  20361. }
  20362. self.runtime.redraw = true;
  20363. self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
  20364. return;
  20365. }
  20366. curFrame_.texture_img = img;
  20367. curFrame_.offx = 0;
  20368. curFrame_.offy = 0;
  20369. curFrame_.width = img.width;
  20370. curFrame_.height = img.height;
  20371. curFrame_.spritesheeted = false;
  20372. curFrame_.datauri = "";
  20373. curFrame_.pixelformat = 0; // reset to RGBA, since we don't know what type of image will have come in
  20374. if (self.runtime.glwrap)
  20375. {
  20376. if (curFrame_.webGL_texture)
  20377. self.runtime.glwrap.deleteTexture(curFrame_.webGL_texture);
  20378. curFrame_.webGL_texture = self.runtime.glwrap.loadTexture(img, false, self.runtime.linearSampling);
  20379. if (self.curFrame === curFrame_)
  20380. self.curWebGLTexture = curFrame_.webGL_texture;
  20381. self.type.updateAllCurrentTexture();
  20382. }
  20383. if (resize_ === 0) // resize to image size
  20384. {
  20385. self.width = img.width;
  20386. self.height = img.height;
  20387. self.set_bbox_changed();
  20388. }
  20389. self.runtime.redraw = true;
  20390. self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
  20391. };
  20392. if (url_.substr(0, 5) !== "data:")
  20393. img["crossOrigin"] = "anonymous";
  20394. img.src = url_;
  20395. };
  20396. Acts.prototype.SetCollisions = function (set_)
  20397. {
  20398. if (this.collisionsEnabled === (set_ !== 0))
  20399. return; // no change
  20400. this.collisionsEnabled = (set_ !== 0);
  20401. if (this.collisionsEnabled)
  20402. this.set_bbox_changed(); // needs to be added back to cells
  20403. else
  20404. {
  20405. if (this.collcells.right >= this.collcells.left)
  20406. this.type.collision_grid.update(this, this.collcells, null);
  20407. this.collcells.set(0, 0, -1, -1);
  20408. }
  20409. };
  20410. pluginProto.acts = new Acts();
  20411. function Exps() {};
  20412. Exps.prototype.AnimationFrame = function (ret)
  20413. {
  20414. ret.set_int(this.cur_frame);
  20415. };
  20416. Exps.prototype.AnimationFrameCount = function (ret)
  20417. {
  20418. ret.set_int(this.cur_animation.frames.length);
  20419. };
  20420. Exps.prototype.AnimationName = function (ret)
  20421. {
  20422. ret.set_string(this.cur_animation.name);
  20423. };
  20424. Exps.prototype.AnimationSpeed = function (ret)
  20425. {
  20426. ret.set_float(this.animForwards ? this.cur_anim_speed : -this.cur_anim_speed);
  20427. };
  20428. Exps.prototype.ImagePointX = function (ret, imgpt)
  20429. {
  20430. ret.set_float(this.getImagePoint(imgpt, true));
  20431. };
  20432. Exps.prototype.ImagePointY = function (ret, imgpt)
  20433. {
  20434. ret.set_float(this.getImagePoint(imgpt, false));
  20435. };
  20436. Exps.prototype.ImagePointCount = function (ret)
  20437. {
  20438. ret.set_int(this.curFrame.image_points.length);
  20439. };
  20440. Exps.prototype.ImageWidth = function (ret)
  20441. {
  20442. ret.set_float(this.curFrame.width);
  20443. };
  20444. Exps.prototype.ImageHeight = function (ret)
  20445. {
  20446. ret.set_float(this.curFrame.height);
  20447. };
  20448. pluginProto.exps = new Exps();
  20449. }());
  20450. /* global cr,log,assert2 */
  20451. /* jshint globalstrict: true */
  20452. /* jshint strict: true */
  20453. ;
  20454. ;
  20455. cr.plugins_.Spritefont2 = function(runtime)
  20456. {
  20457. this.runtime = runtime;
  20458. };
  20459. (function ()
  20460. {
  20461. var pluginProto = cr.plugins_.Spritefont2.prototype;
  20462. pluginProto.onCreate = function ()
  20463. {
  20464. };
  20465. pluginProto.Type = function(plugin)
  20466. {
  20467. this.plugin = plugin;
  20468. this.runtime = plugin.runtime;
  20469. };
  20470. var typeProto = pluginProto.Type.prototype;
  20471. typeProto.onCreate = function()
  20472. {
  20473. if (this.is_family)
  20474. return;
  20475. this.texture_img = new Image();
  20476. this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
  20477. this.webGL_texture = null;
  20478. };
  20479. typeProto.onLostWebGLContext = function ()
  20480. {
  20481. if (this.is_family)
  20482. return;
  20483. this.webGL_texture = null;
  20484. };
  20485. typeProto.onRestoreWebGLContext = function ()
  20486. {
  20487. if (this.is_family || !this.instances.length)
  20488. return;
  20489. if (!this.webGL_texture)
  20490. {
  20491. this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, false, this.runtime.linearSampling, this.texture_pixelformat);
  20492. }
  20493. var i, len;
  20494. for (i = 0, len = this.instances.length; i < len; i++)
  20495. this.instances[i].webGL_texture = this.webGL_texture;
  20496. };
  20497. typeProto.unloadTextures = function ()
  20498. {
  20499. if (this.is_family || this.instances.length || !this.webGL_texture)
  20500. return;
  20501. this.runtime.glwrap.deleteTexture(this.webGL_texture);
  20502. this.webGL_texture = null;
  20503. };
  20504. typeProto.preloadCanvas2D = function (ctx)
  20505. {
  20506. ctx.drawImage(this.texture_img, 0, 0);
  20507. };
  20508. pluginProto.Instance = function(type)
  20509. {
  20510. this.type = type;
  20511. this.runtime = type.runtime;
  20512. };
  20513. var instanceProto = pluginProto.Instance.prototype;
  20514. instanceProto.onDestroy = function()
  20515. {
  20516. freeAllLines (this.lines);
  20517. freeAllClip (this.clipList);
  20518. freeAllClipUV(this.clipUV);
  20519. cr.wipe(this.characterWidthList);
  20520. };
  20521. instanceProto.onCreate = function()
  20522. {
  20523. this.texture_img = this.type.texture_img;
  20524. this.characterWidth = this.properties[0];
  20525. this.characterHeight = this.properties[1];
  20526. this.characterSet = this.properties[2];
  20527. this.text = this.properties[3];
  20528. this.characterScale = this.properties[4];
  20529. this.visible = (this.properties[5] === 0); // 0=visible, 1=invisible
  20530. this.halign = this.properties[6]/2.0; // 0=left, 1=center, 2=right
  20531. this.valign = this.properties[7]/2.0; // 0=top, 1=center, 2=bottom
  20532. this.wrapbyword = (this.properties[9] === 0); // 0=word, 1=character
  20533. this.characterSpacing = this.properties[10];
  20534. this.lineHeight = this.properties[11];
  20535. this.textWidth = 0;
  20536. this.textHeight = 0;
  20537. if (this.recycled)
  20538. {
  20539. cr.clearArray(this.lines);
  20540. cr.wipe(this.clipList);
  20541. cr.wipe(this.clipUV);
  20542. cr.wipe(this.characterWidthList);
  20543. }
  20544. else
  20545. {
  20546. this.lines = [];
  20547. this.clipList = {};
  20548. this.clipUV = {};
  20549. this.characterWidthList = {};
  20550. }
  20551. this.text_changed = true;
  20552. this.lastwrapwidth = this.width;
  20553. if (this.runtime.glwrap)
  20554. {
  20555. if (!this.type.webGL_texture)
  20556. {
  20557. this.type.webGL_texture = this.runtime.glwrap.loadTexture(this.type.texture_img, false, this.runtime.linearSampling, this.type.texture_pixelformat);
  20558. }
  20559. this.webGL_texture = this.type.webGL_texture;
  20560. }
  20561. this.SplitSheet();
  20562. };
  20563. instanceProto.saveToJSON = function ()
  20564. {
  20565. var save = {
  20566. "t": this.text,
  20567. "csc": this.characterScale,
  20568. "csp": this.characterSpacing,
  20569. "lh": this.lineHeight,
  20570. "tw": this.textWidth,
  20571. "th": this.textHeight,
  20572. "lrt": this.last_render_tick,
  20573. "ha": this.halign,
  20574. "va": this.valign,
  20575. "cw": {}
  20576. };
  20577. for (var ch in this.characterWidthList)
  20578. save["cw"][ch] = this.characterWidthList[ch];
  20579. return save;
  20580. };
  20581. instanceProto.loadFromJSON = function (o)
  20582. {
  20583. this.text = o["t"];
  20584. this.characterScale = o["csc"];
  20585. this.characterSpacing = o["csp"];
  20586. this.lineHeight = o["lh"];
  20587. this.textWidth = o["tw"];
  20588. this.textHeight = o["th"];
  20589. this.last_render_tick = o["lrt"];
  20590. if (o.hasOwnProperty("ha"))
  20591. this.halign = o["ha"];
  20592. if (o.hasOwnProperty("va"))
  20593. this.valign = o["va"];
  20594. for(var ch in o["cw"])
  20595. this.characterWidthList[ch] = o["cw"][ch];
  20596. this.text_changed = true;
  20597. this.lastwrapwidth = this.width;
  20598. };
  20599. function trimRight(text)
  20600. {
  20601. return text.replace(/\s\s*$/, '');
  20602. }
  20603. var MAX_CACHE_SIZE = 1000;
  20604. function alloc(cache,Constructor)
  20605. {
  20606. if (cache.length)
  20607. return cache.pop();
  20608. else
  20609. return new Constructor();
  20610. }
  20611. function free(cache,data)
  20612. {
  20613. if (cache.length < MAX_CACHE_SIZE)
  20614. {
  20615. cache.push(data);
  20616. }
  20617. }
  20618. function freeAll(cache,dataList,isArray)
  20619. {
  20620. if (isArray) {
  20621. var i, len;
  20622. for (i = 0, len = dataList.length; i < len; i++)
  20623. {
  20624. free(cache,dataList[i]);
  20625. }
  20626. cr.clearArray(dataList);
  20627. } else {
  20628. var prop;
  20629. for(prop in dataList) {
  20630. if(Object.prototype.hasOwnProperty.call(dataList,prop)) {
  20631. free(cache,dataList[prop]);
  20632. delete dataList[prop];
  20633. }
  20634. }
  20635. }
  20636. }
  20637. function addLine(inst,lineIndex,cur_line) {
  20638. var lines = inst.lines;
  20639. var line;
  20640. cur_line = trimRight(cur_line);
  20641. if (lineIndex >= lines.length)
  20642. lines.push(allocLine());
  20643. line = lines[lineIndex];
  20644. line.text = cur_line;
  20645. line.width = inst.measureWidth(cur_line);
  20646. inst.textWidth = cr.max(inst.textWidth,line.width);
  20647. }
  20648. var linesCache = [];
  20649. function allocLine() { return alloc(linesCache,Object); }
  20650. function freeLine(l) { free(linesCache,l); }
  20651. function freeAllLines(arr) { freeAll(linesCache,arr,true); }
  20652. function addClip(obj,property,x,y,w,h) {
  20653. if (obj[property] === undefined) {
  20654. obj[property] = alloc(clipCache,Object);
  20655. }
  20656. obj[property].x = x;
  20657. obj[property].y = y;
  20658. obj[property].w = w;
  20659. obj[property].h = h;
  20660. }
  20661. var clipCache = [];
  20662. function allocClip() { return alloc(clipCache,Object); }
  20663. function freeAllClip(obj) { freeAll(clipCache,obj,false);}
  20664. function addClipUV(obj,property,left,top,right,bottom) {
  20665. if (obj[property] === undefined) {
  20666. obj[property] = alloc(clipUVCache,cr.rect);
  20667. }
  20668. obj[property].left = left;
  20669. obj[property].top = top;
  20670. obj[property].right = right;
  20671. obj[property].bottom = bottom;
  20672. }
  20673. var clipUVCache = [];
  20674. function allocClipUV() { return alloc(clipUVCache,cr.rect);}
  20675. function freeAllClipUV(obj) { freeAll(clipUVCache,obj,false);}
  20676. instanceProto.SplitSheet = function() {
  20677. var texture = this.texture_img;
  20678. var texWidth = texture.width;
  20679. var texHeight = texture.height;
  20680. var charWidth = this.characterWidth;
  20681. var charHeight = this.characterHeight;
  20682. var charU = charWidth /texWidth;
  20683. var charV = charHeight/texHeight;
  20684. var charSet = this.characterSet ;
  20685. var cols = Math.floor(texWidth/charWidth);
  20686. var rows = Math.floor(texHeight/charHeight);
  20687. for ( var c = 0; c < charSet.length; c++) {
  20688. if (c >= cols * rows) break;
  20689. var x = c%cols;
  20690. var y = Math.floor(c/cols);
  20691. var letter = charSet.charAt(c);
  20692. if (this.runtime.glwrap) {
  20693. addClipUV(
  20694. this.clipUV, letter,
  20695. x * charU ,
  20696. y * charV ,
  20697. (x+1) * charU ,
  20698. (y+1) * charV
  20699. );
  20700. } else {
  20701. addClip(
  20702. this.clipList, letter,
  20703. x * charWidth,
  20704. y * charHeight,
  20705. charWidth,
  20706. charHeight
  20707. );
  20708. }
  20709. }
  20710. };
  20711. /*
  20712. * Word-Wrapping
  20713. */
  20714. var wordsCache = [];
  20715. pluginProto.TokeniseWords = function (text)
  20716. {
  20717. cr.clearArray(wordsCache);
  20718. var cur_word = "";
  20719. var ch;
  20720. var i = 0;
  20721. while (i < text.length)
  20722. {
  20723. ch = text.charAt(i);
  20724. if (ch === "\n")
  20725. {
  20726. if (cur_word.length)
  20727. {
  20728. wordsCache.push(cur_word);
  20729. cur_word = "";
  20730. }
  20731. wordsCache.push("\n");
  20732. ++i;
  20733. }
  20734. else if (ch === " " || ch === "\t" || ch === "-")
  20735. {
  20736. do {
  20737. cur_word += text.charAt(i);
  20738. i++;
  20739. }
  20740. while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
  20741. wordsCache.push(cur_word);
  20742. cur_word = "";
  20743. }
  20744. else if (i < text.length)
  20745. {
  20746. cur_word += ch;
  20747. i++;
  20748. }
  20749. }
  20750. if (cur_word.length)
  20751. wordsCache.push(cur_word);
  20752. };
  20753. pluginProto.WordWrap = function (inst)
  20754. {
  20755. var text = inst.text;
  20756. var lines = inst.lines;
  20757. if (!text || !text.length)
  20758. {
  20759. freeAllLines(lines);
  20760. return;
  20761. }
  20762. var width = inst.width;
  20763. if (width <= 2.0)
  20764. {
  20765. freeAllLines(lines);
  20766. return;
  20767. }
  20768. var charWidth = inst.characterWidth;
  20769. var charScale = inst.characterScale;
  20770. var charSpacing = inst.characterSpacing;
  20771. if ( (text.length * (charWidth * charScale + charSpacing) - charSpacing) <= width && text.indexOf("\n") === -1)
  20772. {
  20773. var all_width = inst.measureWidth(text);
  20774. if (all_width <= width)
  20775. {
  20776. freeAllLines(lines);
  20777. lines.push(allocLine());
  20778. lines[0].text = text;
  20779. lines[0].width = all_width;
  20780. inst.textWidth = all_width;
  20781. inst.textHeight = inst.characterHeight * charScale + inst.lineHeight;
  20782. return;
  20783. }
  20784. }
  20785. var wrapbyword = inst.wrapbyword;
  20786. this.WrapText(inst);
  20787. inst.textHeight = lines.length * (inst.characterHeight * charScale + inst.lineHeight);
  20788. };
  20789. pluginProto.WrapText = function (inst)
  20790. {
  20791. var wrapbyword = inst.wrapbyword;
  20792. var text = inst.text;
  20793. var lines = inst.lines;
  20794. var width = inst.width;
  20795. var wordArray;
  20796. if (wrapbyword) {
  20797. this.TokeniseWords(text); // writes to wordsCache
  20798. wordArray = wordsCache;
  20799. } else {
  20800. wordArray = text;
  20801. }
  20802. var cur_line = "";
  20803. var prev_line;
  20804. var line_width;
  20805. var i;
  20806. var lineIndex = 0;
  20807. var line;
  20808. var ignore_newline = false;
  20809. for (i = 0; i < wordArray.length; i++)
  20810. {
  20811. if (wordArray[i] === "\n")
  20812. {
  20813. if (ignore_newline === true) {
  20814. ignore_newline = false;
  20815. } else {
  20816. addLine(inst,lineIndex,cur_line);
  20817. lineIndex++;
  20818. }
  20819. cur_line = "";
  20820. continue;
  20821. }
  20822. ignore_newline = false;
  20823. prev_line = cur_line;
  20824. cur_line += wordArray[i];
  20825. line_width = inst.measureWidth(trimRight(cur_line));
  20826. if (line_width > width)
  20827. {
  20828. if (prev_line === "") {
  20829. addLine(inst,lineIndex,cur_line);
  20830. cur_line = "";
  20831. ignore_newline = true;
  20832. } else {
  20833. addLine(inst,lineIndex,prev_line);
  20834. cur_line = wordArray[i];
  20835. }
  20836. lineIndex++;
  20837. if (!wrapbyword && cur_line === " ")
  20838. cur_line = "";
  20839. }
  20840. }
  20841. if (trimRight(cur_line).length)
  20842. {
  20843. addLine(inst,lineIndex,cur_line);
  20844. lineIndex++;
  20845. }
  20846. for (i = lineIndex; i < lines.length; i++)
  20847. freeLine(lines[i]);
  20848. lines.length = lineIndex;
  20849. };
  20850. instanceProto.measureWidth = function(text) {
  20851. var spacing = this.characterSpacing;
  20852. var len = text.length;
  20853. var width = 0;
  20854. for (var i = 0; i < len; i++) {
  20855. width += this.getCharacterWidth(text.charAt(i)) * this.characterScale + spacing;
  20856. }
  20857. width -= (width > 0) ? spacing : 0;
  20858. return width;
  20859. };
  20860. /***/
  20861. instanceProto.getCharacterWidth = function(character) {
  20862. var widthList = this.characterWidthList;
  20863. if (widthList[character] !== undefined) {
  20864. return widthList[character];
  20865. } else {
  20866. return this.characterWidth;
  20867. }
  20868. };
  20869. instanceProto.rebuildText = function() {
  20870. if (this.text_changed || this.width !== this.lastwrapwidth) {
  20871. this.textWidth = 0;
  20872. this.textHeight = 0;
  20873. this.type.plugin.WordWrap(this);
  20874. this.text_changed = false;
  20875. this.lastwrapwidth = this.width;
  20876. }
  20877. };
  20878. var EPSILON = 0.00001;
  20879. instanceProto.draw = function(ctx, glmode)
  20880. {
  20881. var texture = this.texture_img;
  20882. if (this.text !== "" && texture != null) {
  20883. this.rebuildText();
  20884. if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
  20885. return;
  20886. }
  20887. ctx.globalAlpha = this.opacity;
  20888. var myx = this.x;
  20889. var myy = this.y;
  20890. if (this.runtime.pixel_rounding)
  20891. {
  20892. myx = Math.round(myx);
  20893. myy = Math.round(myy);
  20894. }
  20895. var viewLeft = this.layer.viewLeft;
  20896. var viewTop = this.layer.viewTop;
  20897. var viewRight = this.layer.viewRight;
  20898. var viewBottom = this.layer.viewBottom;
  20899. ctx.save();
  20900. ctx.translate(myx, myy);
  20901. ctx.rotate(this.angle);
  20902. var ha = this.halign;
  20903. var va = this.valign;
  20904. var scale = this.characterScale;
  20905. var charHeight = this.characterHeight * scale;
  20906. var lineHeight = this.lineHeight;
  20907. var charSpace = this.characterSpacing;
  20908. var lines = this.lines;
  20909. var textHeight = this.textHeight;
  20910. var letterWidth;
  20911. var halign;
  20912. var valign = va * cr.max(0,(this.height - textHeight));
  20913. var offx = -(this.hotspotX * this.width);
  20914. var offy = -(this.hotspotY * this.height);
  20915. offy += valign;
  20916. var drawX ;
  20917. var drawY = offy;
  20918. var roundX, roundY;
  20919. for(var i = 0; i < lines.length; i++) {
  20920. var line = lines[i].text;
  20921. var len = lines[i].width;
  20922. halign = ha * cr.max(0,this.width - len);
  20923. drawX = offx + halign;
  20924. drawY += lineHeight;
  20925. if (myy + drawY + charHeight < viewTop)
  20926. {
  20927. drawY += charHeight;
  20928. continue;
  20929. }
  20930. for(var j = 0; j < line.length; j++) {
  20931. var letter = line.charAt(j);
  20932. letterWidth = this.getCharacterWidth(letter);
  20933. var clip = this.clipList[letter];
  20934. if (myx + drawX + letterWidth * scale + charSpace < viewLeft)
  20935. {
  20936. drawX += letterWidth * scale + charSpace;
  20937. continue;
  20938. }
  20939. if ( drawX + letterWidth * scale > this.width + EPSILON ) {
  20940. break;
  20941. }
  20942. if (clip !== undefined) {
  20943. roundX = drawX;
  20944. roundY = drawY;
  20945. if (this.angle === 0)
  20946. {
  20947. roundX = Math.round(roundX);
  20948. roundY = Math.round(roundY);
  20949. }
  20950. ctx.drawImage( this.texture_img,
  20951. clip.x, clip.y, clip.w, clip.h,
  20952. roundX,roundY,clip.w*scale,clip.h*scale);
  20953. }
  20954. drawX += letterWidth * scale + charSpace;
  20955. if (myx + drawX > viewRight)
  20956. break;
  20957. }
  20958. drawY += charHeight;
  20959. if (drawY + charHeight + lineHeight > this.height || myy + drawY > viewBottom)
  20960. {
  20961. break;
  20962. }
  20963. }
  20964. ctx.restore();
  20965. }
  20966. };
  20967. var dQuad = new cr.quad();
  20968. function rotateQuad(quad,cosa,sina) {
  20969. var x_temp;
  20970. x_temp = (quad.tlx * cosa) - (quad.tly * sina);
  20971. quad.tly = (quad.tly * cosa) + (quad.tlx * sina);
  20972. quad.tlx = x_temp;
  20973. x_temp = (quad.trx * cosa) - (quad.try_ * sina);
  20974. quad.try_ = (quad.try_ * cosa) + (quad.trx * sina);
  20975. quad.trx = x_temp;
  20976. x_temp = (quad.blx * cosa) - (quad.bly * sina);
  20977. quad.bly = (quad.bly * cosa) + (quad.blx * sina);
  20978. quad.blx = x_temp;
  20979. x_temp = (quad.brx * cosa) - (quad.bry * sina);
  20980. quad.bry = (quad.bry * cosa) + (quad.brx * sina);
  20981. quad.brx = x_temp;
  20982. }
  20983. instanceProto.drawGL = function(glw)
  20984. {
  20985. glw.setTexture(this.webGL_texture);
  20986. glw.setOpacity(this.opacity);
  20987. if (!this.text)
  20988. return;
  20989. this.rebuildText();
  20990. if (this.height < this.characterHeight*this.characterScale + this.lineHeight) {
  20991. return;
  20992. }
  20993. this.update_bbox();
  20994. var q = this.bquad;
  20995. var ox = 0;
  20996. var oy = 0;
  20997. if (this.runtime.pixel_rounding)
  20998. {
  20999. ox = Math.round(this.x) - this.x;
  21000. oy = Math.round(this.y) - this.y;
  21001. }
  21002. var viewLeft = this.layer.viewLeft;
  21003. var viewTop = this.layer.viewTop;
  21004. var viewRight = this.layer.viewRight;
  21005. var viewBottom = this.layer.viewBottom;
  21006. var angle = this.angle;
  21007. var ha = this.halign;
  21008. var va = this.valign;
  21009. var scale = this.characterScale;
  21010. var charHeight = this.characterHeight * scale; // to precalculate in onCreate or on change
  21011. var lineHeight = this.lineHeight;
  21012. var charSpace = this.characterSpacing;
  21013. var lines = this.lines;
  21014. var textHeight = this.textHeight;
  21015. var letterWidth;
  21016. var cosa,sina;
  21017. if (angle !== 0)
  21018. {
  21019. cosa = Math.cos(angle);
  21020. sina = Math.sin(angle);
  21021. }
  21022. var halign;
  21023. var valign = va * cr.max(0,(this.height - textHeight));
  21024. var offx = q.tlx + ox;
  21025. var offy = q.tly + oy;
  21026. var drawX ;
  21027. var drawY = valign;
  21028. var roundX, roundY;
  21029. for(var i = 0; i < lines.length; i++) {
  21030. var line = lines[i].text;
  21031. var lineWidth = lines[i].width;
  21032. halign = ha * cr.max(0,this.width - lineWidth);
  21033. drawX = halign;
  21034. drawY += lineHeight;
  21035. if (angle === 0 && offy + drawY + charHeight < viewTop)
  21036. {
  21037. drawY += charHeight;
  21038. continue;
  21039. }
  21040. for(var j = 0; j < line.length; j++) {
  21041. var letter = line.charAt(j);
  21042. letterWidth = this.getCharacterWidth(letter);
  21043. var clipUV = this.clipUV[letter];
  21044. if (offx + drawX + letterWidth * scale + charSpace < viewLeft)
  21045. {
  21046. drawX += letterWidth * scale + charSpace;
  21047. continue;
  21048. }
  21049. if (drawX + letterWidth * scale > this.width + EPSILON)
  21050. {
  21051. break;
  21052. }
  21053. if (clipUV !== undefined) {
  21054. var clipWidth = this.characterWidth*scale;
  21055. var clipHeight = this.characterHeight*scale;
  21056. roundX = drawX;
  21057. roundY = drawY;
  21058. if (angle === 0)
  21059. {
  21060. roundX = Math.round(roundX);
  21061. roundY = Math.round(roundY);
  21062. }
  21063. dQuad.tlx = roundX;
  21064. dQuad.tly = roundY;
  21065. dQuad.trx = roundX + clipWidth;
  21066. dQuad.try_ = roundY ;
  21067. dQuad.blx = roundX;
  21068. dQuad.bly = roundY + clipHeight;
  21069. dQuad.brx = roundX + clipWidth;
  21070. dQuad.bry = roundY + clipHeight;
  21071. if(angle !== 0)
  21072. {
  21073. rotateQuad(dQuad,cosa,sina);
  21074. }
  21075. dQuad.offset(offx,offy);
  21076. glw.quadTex(
  21077. dQuad.tlx, dQuad.tly,
  21078. dQuad.trx, dQuad.try_,
  21079. dQuad.brx, dQuad.bry,
  21080. dQuad.blx, dQuad.bly,
  21081. clipUV
  21082. );
  21083. }
  21084. drawX += letterWidth * scale + charSpace;
  21085. if (angle === 0 && offx + drawX > viewRight)
  21086. break;
  21087. }
  21088. drawY += charHeight;
  21089. if (drawY + charHeight + lineHeight > this.height || offy + drawY > viewBottom)
  21090. {
  21091. break;
  21092. }
  21093. }
  21094. };
  21095. function Cnds() {}
  21096. Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
  21097. {
  21098. if (case_sensitive)
  21099. return this.text == text_to_compare;
  21100. else
  21101. return cr.equals_nocase(this.text, text_to_compare);
  21102. };
  21103. pluginProto.cnds = new Cnds();
  21104. function Acts() {}
  21105. Acts.prototype.SetText = function(param)
  21106. {
  21107. if (cr.is_number(param) && param < 1e9)
  21108. param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
  21109. var text_to_set = param.toString();
  21110. if (this.text !== text_to_set)
  21111. {
  21112. this.text = text_to_set;
  21113. this.text_changed = true;
  21114. this.runtime.redraw = true;
  21115. }
  21116. };
  21117. Acts.prototype.AppendText = function(param)
  21118. {
  21119. if (cr.is_number(param))
  21120. param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
  21121. var text_to_append = param.toString();
  21122. if (text_to_append) // not empty
  21123. {
  21124. this.text += text_to_append;
  21125. this.text_changed = true;
  21126. this.runtime.redraw = true;
  21127. }
  21128. };
  21129. Acts.prototype.SetScale = function(param)
  21130. {
  21131. if (param !== this.characterScale) {
  21132. this.characterScale = param;
  21133. this.text_changed = true;
  21134. this.runtime.redraw = true;
  21135. }
  21136. };
  21137. Acts.prototype.SetCharacterSpacing = function(param)
  21138. {
  21139. if (param !== this.CharacterSpacing) {
  21140. this.characterSpacing = param;
  21141. this.text_changed = true;
  21142. this.runtime.redraw = true;
  21143. }
  21144. };
  21145. Acts.prototype.SetLineHeight = function(param)
  21146. {
  21147. if (param !== this.lineHeight) {
  21148. this.lineHeight = param;
  21149. this.text_changed = true;
  21150. this.runtime.redraw = true;
  21151. }
  21152. };
  21153. instanceProto.SetCharWidth = function(character,width) {
  21154. var w = parseInt(width,10);
  21155. if (this.characterWidthList[character] !== w) {
  21156. this.characterWidthList[character] = w;
  21157. this.text_changed = true;
  21158. this.runtime.redraw = true;
  21159. }
  21160. };
  21161. Acts.prototype.SetCharacterWidth = function(characterSet,width)
  21162. {
  21163. if (characterSet !== "") {
  21164. for(var c = 0; c < characterSet.length; c++) {
  21165. this.SetCharWidth(characterSet.charAt(c),width);
  21166. }
  21167. }
  21168. };
  21169. Acts.prototype.SetEffect = function (effect)
  21170. {
  21171. this.blend_mode = effect;
  21172. this.compositeOp = cr.effectToCompositeOp(effect);
  21173. cr.setGLBlend(this, effect, this.runtime.gl);
  21174. this.runtime.redraw = true;
  21175. };
  21176. Acts.prototype.SetHAlign = function (a)
  21177. {
  21178. this.halign = a / 2.0;
  21179. this.text_changed = true;
  21180. this.runtime.redraw = true;
  21181. };
  21182. Acts.prototype.SetVAlign = function (a)
  21183. {
  21184. this.valign = a / 2.0;
  21185. this.text_changed = true;
  21186. this.runtime.redraw = true;
  21187. };
  21188. pluginProto.acts = new Acts();
  21189. function Exps() {}
  21190. Exps.prototype.CharacterWidth = function(ret,character)
  21191. {
  21192. ret.set_int(this.getCharacterWidth(character));
  21193. };
  21194. Exps.prototype.CharacterHeight = function(ret)
  21195. {
  21196. ret.set_int(this.characterHeight);
  21197. };
  21198. Exps.prototype.CharacterScale = function(ret)
  21199. {
  21200. ret.set_float(this.characterScale);
  21201. };
  21202. Exps.prototype.CharacterSpacing = function(ret)
  21203. {
  21204. ret.set_int(this.characterSpacing);
  21205. };
  21206. Exps.prototype.LineHeight = function(ret)
  21207. {
  21208. ret.set_int(this.lineHeight);
  21209. };
  21210. Exps.prototype.Text = function(ret)
  21211. {
  21212. ret.set_string(this.text);
  21213. };
  21214. Exps.prototype.TextWidth = function (ret)
  21215. {
  21216. this.rebuildText();
  21217. ret.set_float(this.textWidth);
  21218. };
  21219. Exps.prototype.TextHeight = function (ret)
  21220. {
  21221. this.rebuildText();
  21222. ret.set_float(this.textHeight);
  21223. };
  21224. pluginProto.exps = new Exps();
  21225. }());
  21226. ;
  21227. ;
  21228. cr.plugins_.Text = function(runtime)
  21229. {
  21230. this.runtime = runtime;
  21231. };
  21232. (function ()
  21233. {
  21234. var pluginProto = cr.plugins_.Text.prototype;
  21235. pluginProto.onCreate = function ()
  21236. {
  21237. pluginProto.acts.SetWidth = function (w)
  21238. {
  21239. if (this.width !== w)
  21240. {
  21241. this.width = w;
  21242. this.text_changed = true; // also recalculate text wrapping
  21243. this.set_bbox_changed();
  21244. }
  21245. };
  21246. };
  21247. pluginProto.Type = function(plugin)
  21248. {
  21249. this.plugin = plugin;
  21250. this.runtime = plugin.runtime;
  21251. };
  21252. var typeProto = pluginProto.Type.prototype;
  21253. typeProto.onCreate = function()
  21254. {
  21255. };
  21256. typeProto.onLostWebGLContext = function ()
  21257. {
  21258. if (this.is_family)
  21259. return;
  21260. var i, len, inst;
  21261. for (i = 0, len = this.instances.length; i < len; i++)
  21262. {
  21263. inst = this.instances[i];
  21264. inst.mycanvas = null;
  21265. inst.myctx = null;
  21266. inst.mytex = null;
  21267. }
  21268. };
  21269. pluginProto.Instance = function(type)
  21270. {
  21271. this.type = type;
  21272. this.runtime = type.runtime;
  21273. if (this.recycled)
  21274. cr.clearArray(this.lines);
  21275. else
  21276. this.lines = []; // for word wrapping
  21277. this.text_changed = true;
  21278. };
  21279. var instanceProto = pluginProto.Instance.prototype;
  21280. var requestedWebFonts = {}; // already requested web fonts have an entry here
  21281. instanceProto.onCreate = function()
  21282. {
  21283. this.text = this.properties[0];
  21284. this.visible = (this.properties[1] === 0); // 0=visible, 1=invisible
  21285. this.font = this.properties[2];
  21286. this.color = this.properties[3];
  21287. this.halign = this.properties[4]; // 0=left, 1=center, 2=right
  21288. this.valign = this.properties[5]; // 0=top, 1=center, 2=bottom
  21289. this.wrapbyword = (this.properties[7] === 0); // 0=word, 1=character
  21290. this.lastwidth = this.width;
  21291. this.lastwrapwidth = this.width;
  21292. this.lastheight = this.height;
  21293. this.line_height_offset = this.properties[8];
  21294. this.facename = "";
  21295. this.fontstyle = "";
  21296. this.ptSize = 0;
  21297. this.textWidth = 0;
  21298. this.textHeight = 0;
  21299. this.parseFont();
  21300. this.mycanvas = null;
  21301. this.myctx = null;
  21302. this.mytex = null;
  21303. this.need_text_redraw = false;
  21304. this.last_render_tick = this.runtime.tickcount;
  21305. if (this.recycled)
  21306. this.rcTex.set(0, 0, 1, 1);
  21307. else
  21308. this.rcTex = new cr.rect(0, 0, 1, 1);
  21309. if (this.runtime.glwrap)
  21310. this.runtime.tickMe(this);
  21311. ;
  21312. };
  21313. instanceProto.parseFont = function ()
  21314. {
  21315. var arr = this.font.split(" ");
  21316. var i;
  21317. for (i = 0; i < arr.length; i++)
  21318. {
  21319. if (arr[i].substr(arr[i].length - 2, 2) === "pt")
  21320. {
  21321. this.ptSize = parseInt(arr[i].substr(0, arr[i].length - 2));
  21322. this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
  21323. if (i > 0)
  21324. this.fontstyle = arr[i - 1];
  21325. this.facename = arr[i + 1];
  21326. for (i = i + 2; i < arr.length; i++)
  21327. this.facename += " " + arr[i];
  21328. break;
  21329. }
  21330. }
  21331. };
  21332. instanceProto.saveToJSON = function ()
  21333. {
  21334. return {
  21335. "t": this.text,
  21336. "f": this.font,
  21337. "c": this.color,
  21338. "ha": this.halign,
  21339. "va": this.valign,
  21340. "wr": this.wrapbyword,
  21341. "lho": this.line_height_offset,
  21342. "fn": this.facename,
  21343. "fs": this.fontstyle,
  21344. "ps": this.ptSize,
  21345. "pxh": this.pxHeight,
  21346. "tw": this.textWidth,
  21347. "th": this.textHeight,
  21348. "lrt": this.last_render_tick
  21349. };
  21350. };
  21351. instanceProto.loadFromJSON = function (o)
  21352. {
  21353. this.text = o["t"];
  21354. this.font = o["f"];
  21355. this.color = o["c"];
  21356. this.halign = o["ha"];
  21357. this.valign = o["va"];
  21358. this.wrapbyword = o["wr"];
  21359. this.line_height_offset = o["lho"];
  21360. this.facename = o["fn"];
  21361. this.fontstyle = o["fs"];
  21362. this.ptSize = o["ps"];
  21363. this.pxHeight = o["pxh"];
  21364. this.textWidth = o["tw"];
  21365. this.textHeight = o["th"];
  21366. this.last_render_tick = o["lrt"];
  21367. this.text_changed = true;
  21368. this.lastwidth = this.width;
  21369. this.lastwrapwidth = this.width;
  21370. this.lastheight = this.height;
  21371. };
  21372. instanceProto.tick = function ()
  21373. {
  21374. if (this.runtime.glwrap && this.mytex && (this.runtime.tickcount - this.last_render_tick >= 300))
  21375. {
  21376. var layer = this.layer;
  21377. this.update_bbox();
  21378. var bbox = this.bbox;
  21379. if (bbox.right < layer.viewLeft || bbox.bottom < layer.viewTop || bbox.left > layer.viewRight || bbox.top > layer.viewBottom)
  21380. {
  21381. this.runtime.glwrap.deleteTexture(this.mytex);
  21382. this.mytex = null;
  21383. this.myctx = null;
  21384. this.mycanvas = null;
  21385. }
  21386. }
  21387. };
  21388. instanceProto.onDestroy = function ()
  21389. {
  21390. this.myctx = null;
  21391. this.mycanvas = null;
  21392. if (this.runtime.glwrap && this.mytex)
  21393. this.runtime.glwrap.deleteTexture(this.mytex);
  21394. this.mytex = null;
  21395. };
  21396. instanceProto.updateFont = function ()
  21397. {
  21398. this.font = this.fontstyle + " " + this.ptSize.toString() + "pt " + this.facename;
  21399. this.text_changed = true;
  21400. this.runtime.redraw = true;
  21401. };
  21402. instanceProto.draw = function(ctx, glmode)
  21403. {
  21404. ctx.font = this.font;
  21405. ctx.textBaseline = "top";
  21406. ctx.fillStyle = this.color;
  21407. ctx.globalAlpha = glmode ? 1 : this.opacity;
  21408. var myscale = 1;
  21409. if (glmode)
  21410. {
  21411. myscale = this.layer.getScale();
  21412. ctx.save();
  21413. ctx.scale(myscale, myscale);
  21414. }
  21415. if (this.text_changed || this.width !== this.lastwrapwidth)
  21416. {
  21417. this.type.plugin.WordWrap(this.text, this.lines, ctx, this.width, this.wrapbyword);
  21418. this.text_changed = false;
  21419. this.lastwrapwidth = this.width;
  21420. }
  21421. this.update_bbox();
  21422. var penX = glmode ? 0 : this.bquad.tlx;
  21423. var penY = glmode ? 0 : this.bquad.tly;
  21424. if (this.runtime.pixel_rounding)
  21425. {
  21426. penX = (penX + 0.5) | 0;
  21427. penY = (penY + 0.5) | 0;
  21428. }
  21429. if (this.angle !== 0 && !glmode)
  21430. {
  21431. ctx.save();
  21432. ctx.translate(penX, penY);
  21433. ctx.rotate(this.angle);
  21434. penX = 0;
  21435. penY = 0;
  21436. }
  21437. var endY = penY + this.height;
  21438. var line_height = this.pxHeight;
  21439. line_height += this.line_height_offset;
  21440. var drawX;
  21441. var i;
  21442. if (this.valign === 1) // center
  21443. penY += Math.max(this.height / 2 - (this.lines.length * line_height) / 2, 0);
  21444. else if (this.valign === 2) // bottom
  21445. penY += Math.max(this.height - (this.lines.length * line_height) - 2, 0);
  21446. for (i = 0; i < this.lines.length; i++)
  21447. {
  21448. drawX = penX;
  21449. if (this.halign === 1) // center
  21450. drawX = penX + (this.width - this.lines[i].width) / 2;
  21451. else if (this.halign === 2) // right
  21452. drawX = penX + (this.width - this.lines[i].width);
  21453. ctx.fillText(this.lines[i].text, drawX, penY);
  21454. penY += line_height;
  21455. if (penY >= endY - line_height)
  21456. break;
  21457. }
  21458. if (this.angle !== 0 || glmode)
  21459. ctx.restore();
  21460. this.last_render_tick = this.runtime.tickcount;
  21461. };
  21462. instanceProto.drawGL = function(glw)
  21463. {
  21464. if (this.width < 1 || this.height < 1)
  21465. return;
  21466. var need_redraw = this.text_changed || this.need_text_redraw;
  21467. this.need_text_redraw = false;
  21468. var layer_scale = this.layer.getScale();
  21469. var layer_angle = this.layer.getAngle();
  21470. var rcTex = this.rcTex;
  21471. var floatscaledwidth = layer_scale * this.width;
  21472. var floatscaledheight = layer_scale * this.height;
  21473. var scaledwidth = Math.ceil(floatscaledwidth);
  21474. var scaledheight = Math.ceil(floatscaledheight);
  21475. var halfw = this.runtime.draw_width / 2;
  21476. var halfh = this.runtime.draw_height / 2;
  21477. if (!this.myctx)
  21478. {
  21479. this.mycanvas = document.createElement("canvas");
  21480. this.mycanvas.width = scaledwidth;
  21481. this.mycanvas.height = scaledheight;
  21482. this.lastwidth = scaledwidth;
  21483. this.lastheight = scaledheight;
  21484. need_redraw = true;
  21485. this.myctx = this.mycanvas.getContext("2d");
  21486. }
  21487. if (scaledwidth !== this.lastwidth || scaledheight !== this.lastheight)
  21488. {
  21489. this.mycanvas.width = scaledwidth;
  21490. this.mycanvas.height = scaledheight;
  21491. if (this.mytex)
  21492. {
  21493. glw.deleteTexture(this.mytex);
  21494. this.mytex = null;
  21495. }
  21496. need_redraw = true;
  21497. }
  21498. if (need_redraw)
  21499. {
  21500. this.myctx.clearRect(0, 0, scaledwidth, scaledheight);
  21501. this.draw(this.myctx, true);
  21502. if (!this.mytex)
  21503. this.mytex = glw.createEmptyTexture(scaledwidth, scaledheight, this.runtime.linearSampling, this.runtime.isMobile);
  21504. glw.videoToTexture(this.mycanvas, this.mytex, this.runtime.isMobile);
  21505. }
  21506. this.lastwidth = scaledwidth;
  21507. this.lastheight = scaledheight;
  21508. glw.setTexture(this.mytex);
  21509. glw.setOpacity(this.opacity);
  21510. glw.resetModelView();
  21511. glw.translate(-halfw, -halfh);
  21512. glw.updateModelView();
  21513. var q = this.bquad;
  21514. var tlx = this.layer.layerToCanvas(q.tlx, q.tly, true, true);
  21515. var tly = this.layer.layerToCanvas(q.tlx, q.tly, false, true);
  21516. var trx = this.layer.layerToCanvas(q.trx, q.try_, true, true);
  21517. var try_ = this.layer.layerToCanvas(q.trx, q.try_, false, true);
  21518. var brx = this.layer.layerToCanvas(q.brx, q.bry, true, true);
  21519. var bry = this.layer.layerToCanvas(q.brx, q.bry, false, true);
  21520. var blx = this.layer.layerToCanvas(q.blx, q.bly, true, true);
  21521. var bly = this.layer.layerToCanvas(q.blx, q.bly, false, true);
  21522. if (this.runtime.pixel_rounding || (this.angle === 0 && layer_angle === 0))
  21523. {
  21524. var ox = ((tlx + 0.5) | 0) - tlx;
  21525. var oy = ((tly + 0.5) | 0) - tly
  21526. tlx += ox;
  21527. tly += oy;
  21528. trx += ox;
  21529. try_ += oy;
  21530. brx += ox;
  21531. bry += oy;
  21532. blx += ox;
  21533. bly += oy;
  21534. }
  21535. if (this.angle === 0 && layer_angle === 0)
  21536. {
  21537. trx = tlx + scaledwidth;
  21538. try_ = tly;
  21539. brx = trx;
  21540. bry = tly + scaledheight;
  21541. blx = tlx;
  21542. bly = bry;
  21543. rcTex.right = 1;
  21544. rcTex.bottom = 1;
  21545. }
  21546. else
  21547. {
  21548. rcTex.right = floatscaledwidth / scaledwidth;
  21549. rcTex.bottom = floatscaledheight / scaledheight;
  21550. }
  21551. glw.quadTex(tlx, tly, trx, try_, brx, bry, blx, bly, rcTex);
  21552. glw.resetModelView();
  21553. glw.scale(layer_scale, layer_scale);
  21554. glw.rotateZ(-this.layer.getAngle());
  21555. glw.translate((this.layer.viewLeft + this.layer.viewRight) / -2, (this.layer.viewTop + this.layer.viewBottom) / -2);
  21556. glw.updateModelView();
  21557. this.last_render_tick = this.runtime.tickcount;
  21558. };
  21559. var wordsCache = [];
  21560. pluginProto.TokeniseWords = function (text)
  21561. {
  21562. cr.clearArray(wordsCache);
  21563. var cur_word = "";
  21564. var ch;
  21565. var i = 0;
  21566. while (i < text.length)
  21567. {
  21568. ch = text.charAt(i);
  21569. if (ch === "\n")
  21570. {
  21571. if (cur_word.length)
  21572. {
  21573. wordsCache.push(cur_word);
  21574. cur_word = "";
  21575. }
  21576. wordsCache.push("\n");
  21577. ++i;
  21578. }
  21579. else if (ch === " " || ch === "\t" || ch === "-")
  21580. {
  21581. do {
  21582. cur_word += text.charAt(i);
  21583. i++;
  21584. }
  21585. while (i < text.length && (text.charAt(i) === " " || text.charAt(i) === "\t"));
  21586. wordsCache.push(cur_word);
  21587. cur_word = "";
  21588. }
  21589. else if (i < text.length)
  21590. {
  21591. cur_word += ch;
  21592. i++;
  21593. }
  21594. }
  21595. if (cur_word.length)
  21596. wordsCache.push(cur_word);
  21597. };
  21598. var linesCache = [];
  21599. function allocLine()
  21600. {
  21601. if (linesCache.length)
  21602. return linesCache.pop();
  21603. else
  21604. return {};
  21605. };
  21606. function freeLine(l)
  21607. {
  21608. linesCache.push(l);
  21609. };
  21610. function freeAllLines(arr)
  21611. {
  21612. var i, len;
  21613. for (i = 0, len = arr.length; i < len; i++)
  21614. {
  21615. freeLine(arr[i]);
  21616. }
  21617. cr.clearArray(arr);
  21618. };
  21619. pluginProto.WordWrap = function (text, lines, ctx, width, wrapbyword)
  21620. {
  21621. if (!text || !text.length)
  21622. {
  21623. freeAllLines(lines);
  21624. return;
  21625. }
  21626. if (width <= 2.0)
  21627. {
  21628. freeAllLines(lines);
  21629. return;
  21630. }
  21631. if (text.length <= 100 && text.indexOf("\n") === -1)
  21632. {
  21633. var all_width = ctx.measureText(text).width;
  21634. if (all_width <= width)
  21635. {
  21636. freeAllLines(lines);
  21637. lines.push(allocLine());
  21638. lines[0].text = text;
  21639. lines[0].width = all_width;
  21640. return;
  21641. }
  21642. }
  21643. this.WrapText(text, lines, ctx, width, wrapbyword);
  21644. };
  21645. pluginProto.WrapText = function (text, lines, ctx, width, wrapbyword)
  21646. {
  21647. var wordArray;
  21648. if (wrapbyword)
  21649. {
  21650. this.TokeniseWords(text); // writes to wordsCache
  21651. wordArray = wordsCache;
  21652. }
  21653. else
  21654. wordArray = text;
  21655. var cur_line = "";
  21656. var prev_line;
  21657. var line_width;
  21658. var i;
  21659. var lineIndex = 0;
  21660. var line;
  21661. for (i = 0; i < wordArray.length; i++)
  21662. {
  21663. if (wordArray[i] === "\n")
  21664. {
  21665. if (lineIndex >= lines.length)
  21666. lines.push(allocLine());
  21667. line = lines[lineIndex];
  21668. line.text = cur_line;
  21669. line.width = ctx.measureText(cur_line).width;
  21670. lineIndex++;
  21671. cur_line = "";
  21672. continue;
  21673. }
  21674. prev_line = cur_line;
  21675. cur_line += wordArray[i];
  21676. line_width = ctx.measureText(cur_line).width;
  21677. if (line_width >= width)
  21678. {
  21679. if (lineIndex >= lines.length)
  21680. lines.push(allocLine());
  21681. line = lines[lineIndex];
  21682. line.text = prev_line;
  21683. line.width = ctx.measureText(prev_line).width;
  21684. lineIndex++;
  21685. cur_line = wordArray[i];
  21686. if (!wrapbyword && cur_line === " ")
  21687. cur_line = "";
  21688. }
  21689. }
  21690. if (cur_line.length)
  21691. {
  21692. if (lineIndex >= lines.length)
  21693. lines.push(allocLine());
  21694. line = lines[lineIndex];
  21695. line.text = cur_line;
  21696. line.width = ctx.measureText(cur_line).width;
  21697. lineIndex++;
  21698. }
  21699. for (i = lineIndex; i < lines.length; i++)
  21700. freeLine(lines[i]);
  21701. lines.length = lineIndex;
  21702. };
  21703. function Cnds() {};
  21704. Cnds.prototype.CompareText = function(text_to_compare, case_sensitive)
  21705. {
  21706. if (case_sensitive)
  21707. return this.text == text_to_compare;
  21708. else
  21709. return cr.equals_nocase(this.text, text_to_compare);
  21710. };
  21711. pluginProto.cnds = new Cnds();
  21712. function Acts() {};
  21713. Acts.prototype.SetText = function(param)
  21714. {
  21715. if (cr.is_number(param) && param < 1e9)
  21716. param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
  21717. var text_to_set = param.toString();
  21718. if (this.text !== text_to_set)
  21719. {
  21720. this.text = text_to_set;
  21721. this.text_changed = true;
  21722. this.runtime.redraw = true;
  21723. }
  21724. };
  21725. Acts.prototype.AppendText = function(param)
  21726. {
  21727. if (cr.is_number(param))
  21728. param = Math.round(param * 1e10) / 1e10; // round to nearest ten billionth - hides floating point errors
  21729. var text_to_append = param.toString();
  21730. if (text_to_append) // not empty
  21731. {
  21732. this.text += text_to_append;
  21733. this.text_changed = true;
  21734. this.runtime.redraw = true;
  21735. }
  21736. };
  21737. Acts.prototype.SetFontFace = function (face_, style_)
  21738. {
  21739. var newstyle = "";
  21740. switch (style_) {
  21741. case 1: newstyle = "bold"; break;
  21742. case 2: newstyle = "italic"; break;
  21743. case 3: newstyle = "bold italic"; break;
  21744. }
  21745. if (face_ === this.facename && newstyle === this.fontstyle)
  21746. return; // no change
  21747. this.facename = face_;
  21748. this.fontstyle = newstyle;
  21749. this.updateFont();
  21750. };
  21751. Acts.prototype.SetFontSize = function (size_)
  21752. {
  21753. if (this.ptSize === size_)
  21754. return;
  21755. this.ptSize = size_;
  21756. this.pxHeight = Math.ceil((this.ptSize / 72.0) * 96.0) + 4; // assume 96dpi...
  21757. this.updateFont();
  21758. };
  21759. Acts.prototype.SetFontColor = function (rgb)
  21760. {
  21761. var newcolor = "rgb(" + cr.GetRValue(rgb).toString() + "," + cr.GetGValue(rgb).toString() + "," + cr.GetBValue(rgb).toString() + ")";
  21762. if (newcolor === this.color)
  21763. return;
  21764. this.color = newcolor;
  21765. this.need_text_redraw = true;
  21766. this.runtime.redraw = true;
  21767. };
  21768. Acts.prototype.SetWebFont = function (familyname_, cssurl_)
  21769. {
  21770. if (this.runtime.isDomFree)
  21771. {
  21772. cr.logexport("[Construct 2] Text plugin: 'Set web font' not supported on this platform - the action has been ignored");
  21773. return; // DC todo
  21774. }
  21775. var self = this;
  21776. var refreshFunc = (function () {
  21777. self.runtime.redraw = true;
  21778. self.text_changed = true;
  21779. });
  21780. if (requestedWebFonts.hasOwnProperty(cssurl_))
  21781. {
  21782. var newfacename = "'" + familyname_ + "'";
  21783. if (this.facename === newfacename)
  21784. return; // no change
  21785. this.facename = newfacename;
  21786. this.updateFont();
  21787. for (var i = 1; i < 10; i++)
  21788. {
  21789. setTimeout(refreshFunc, i * 100);
  21790. setTimeout(refreshFunc, i * 1000);
  21791. }
  21792. return;
  21793. }
  21794. var wf = document.createElement("link");
  21795. wf.href = cssurl_;
  21796. wf.rel = "stylesheet";
  21797. wf.type = "text/css";
  21798. wf.onload = refreshFunc;
  21799. document.getElementsByTagName('head')[0].appendChild(wf);
  21800. requestedWebFonts[cssurl_] = true;
  21801. this.facename = "'" + familyname_ + "'";
  21802. this.updateFont();
  21803. for (var i = 1; i < 10; i++)
  21804. {
  21805. setTimeout(refreshFunc, i * 100);
  21806. setTimeout(refreshFunc, i * 1000);
  21807. }
  21808. ;
  21809. };
  21810. Acts.prototype.SetEffect = function (effect)
  21811. {
  21812. this.blend_mode = effect;
  21813. this.compositeOp = cr.effectToCompositeOp(effect);
  21814. cr.setGLBlend(this, effect, this.runtime.gl);
  21815. this.runtime.redraw = true;
  21816. };
  21817. pluginProto.acts = new Acts();
  21818. function Exps() {};
  21819. Exps.prototype.Text = function(ret)
  21820. {
  21821. ret.set_string(this.text);
  21822. };
  21823. Exps.prototype.FaceName = function (ret)
  21824. {
  21825. ret.set_string(this.facename);
  21826. };
  21827. Exps.prototype.FaceSize = function (ret)
  21828. {
  21829. ret.set_int(this.ptSize);
  21830. };
  21831. Exps.prototype.TextWidth = function (ret)
  21832. {
  21833. var w = 0;
  21834. var i, len, x;
  21835. for (i = 0, len = this.lines.length; i < len; i++)
  21836. {
  21837. x = this.lines[i].width;
  21838. if (w < x)
  21839. w = x;
  21840. }
  21841. ret.set_int(w);
  21842. };
  21843. Exps.prototype.TextHeight = function (ret)
  21844. {
  21845. ret.set_int(this.lines.length * (this.pxHeight + this.line_height_offset) - this.line_height_offset);
  21846. };
  21847. pluginProto.exps = new Exps();
  21848. }());
  21849. ;
  21850. ;
  21851. cr.plugins_.TiledBg = function(runtime)
  21852. {
  21853. this.runtime = runtime;
  21854. };
  21855. (function ()
  21856. {
  21857. var pluginProto = cr.plugins_.TiledBg.prototype;
  21858. pluginProto.Type = function(plugin)
  21859. {
  21860. this.plugin = plugin;
  21861. this.runtime = plugin.runtime;
  21862. };
  21863. var typeProto = pluginProto.Type.prototype;
  21864. typeProto.onCreate = function()
  21865. {
  21866. if (this.is_family)
  21867. return;
  21868. this.texture_img = new Image();
  21869. this.texture_img.cr_filesize = this.texture_filesize;
  21870. this.runtime.waitForImageLoad(this.texture_img, this.texture_file);
  21871. this.pattern = null;
  21872. this.webGL_texture = null;
  21873. };
  21874. typeProto.onLostWebGLContext = function ()
  21875. {
  21876. if (this.is_family)
  21877. return;
  21878. this.webGL_texture = null;
  21879. };
  21880. typeProto.onRestoreWebGLContext = function ()
  21881. {
  21882. if (this.is_family || !this.instances.length)
  21883. return;
  21884. if (!this.webGL_texture)
  21885. {
  21886. this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
  21887. }
  21888. var i, len;
  21889. for (i = 0, len = this.instances.length; i < len; i++)
  21890. this.instances[i].webGL_texture = this.webGL_texture;
  21891. };
  21892. typeProto.loadTextures = function ()
  21893. {
  21894. if (this.is_family || this.webGL_texture || !this.runtime.glwrap)
  21895. return;
  21896. this.webGL_texture = this.runtime.glwrap.loadTexture(this.texture_img, true, this.runtime.linearSampling, this.texture_pixelformat);
  21897. };
  21898. typeProto.unloadTextures = function ()
  21899. {
  21900. if (this.is_family || this.instances.length || !this.webGL_texture)
  21901. return;
  21902. this.runtime.glwrap.deleteTexture(this.webGL_texture);
  21903. this.webGL_texture = null;
  21904. };
  21905. typeProto.preloadCanvas2D = function (ctx)
  21906. {
  21907. ctx.drawImage(this.texture_img, 0, 0);
  21908. };
  21909. pluginProto.Instance = function(type)
  21910. {
  21911. this.type = type;
  21912. this.runtime = type.runtime;
  21913. };
  21914. var instanceProto = pluginProto.Instance.prototype;
  21915. instanceProto.onCreate = function()
  21916. {
  21917. this.visible = (this.properties[0] === 0); // 0=visible, 1=invisible
  21918. this.rcTex = new cr.rect(0, 0, 0, 0);
  21919. this.has_own_texture = false; // true if a texture loaded in from URL
  21920. this.texture_img = this.type.texture_img;
  21921. if (this.runtime.glwrap)
  21922. {
  21923. this.type.loadTextures();
  21924. this.webGL_texture = this.type.webGL_texture;
  21925. }
  21926. else
  21927. {
  21928. if (!this.type.pattern)
  21929. this.type.pattern = this.runtime.ctx.createPattern(this.type.texture_img, "repeat");
  21930. this.pattern = this.type.pattern;
  21931. }
  21932. };
  21933. instanceProto.afterLoad = function ()
  21934. {
  21935. this.has_own_texture = false;
  21936. this.texture_img = this.type.texture_img;
  21937. };
  21938. instanceProto.onDestroy = function ()
  21939. {
  21940. if (this.runtime.glwrap && this.has_own_texture && this.webGL_texture)
  21941. {
  21942. this.runtime.glwrap.deleteTexture(this.webGL_texture);
  21943. this.webGL_texture = null;
  21944. }
  21945. };
  21946. instanceProto.draw = function(ctx)
  21947. {
  21948. ctx.globalAlpha = this.opacity;
  21949. ctx.save();
  21950. ctx.fillStyle = this.pattern;
  21951. var myx = this.x;
  21952. var myy = this.y;
  21953. if (this.runtime.pixel_rounding)
  21954. {
  21955. myx = Math.round(myx);
  21956. myy = Math.round(myy);
  21957. }
  21958. var drawX = -(this.hotspotX * this.width);
  21959. var drawY = -(this.hotspotY * this.height);
  21960. var offX = drawX % this.texture_img.width;
  21961. var offY = drawY % this.texture_img.height;
  21962. if (offX < 0)
  21963. offX += this.texture_img.width;
  21964. if (offY < 0)
  21965. offY += this.texture_img.height;
  21966. ctx.translate(myx, myy);
  21967. ctx.rotate(this.angle);
  21968. ctx.translate(offX, offY);
  21969. ctx.fillRect(drawX - offX,
  21970. drawY - offY,
  21971. this.width,
  21972. this.height);
  21973. ctx.restore();
  21974. };
  21975. instanceProto.drawGL_earlyZPass = function(glw)
  21976. {
  21977. this.drawGL(glw);
  21978. };
  21979. instanceProto.drawGL = function(glw)
  21980. {
  21981. glw.setTexture(this.webGL_texture);
  21982. glw.setOpacity(this.opacity);
  21983. var rcTex = this.rcTex;
  21984. rcTex.right = this.width / this.texture_img.width;
  21985. rcTex.bottom = this.height / this.texture_img.height;
  21986. var q = this.bquad;
  21987. if (this.runtime.pixel_rounding)
  21988. {
  21989. var ox = Math.round(this.x) - this.x;
  21990. var oy = Math.round(this.y) - this.y;
  21991. glw.quadTex(q.tlx + ox, q.tly + oy, q.trx + ox, q.try_ + oy, q.brx + ox, q.bry + oy, q.blx + ox, q.bly + oy, rcTex);
  21992. }
  21993. else
  21994. glw.quadTex(q.tlx, q.tly, q.trx, q.try_, q.brx, q.bry, q.blx, q.bly, rcTex);
  21995. };
  21996. function Cnds() {};
  21997. Cnds.prototype.OnURLLoaded = function ()
  21998. {
  21999. return true;
  22000. };
  22001. pluginProto.cnds = new Cnds();
  22002. function Acts() {};
  22003. Acts.prototype.SetEffect = function (effect)
  22004. {
  22005. this.blend_mode = effect;
  22006. this.compositeOp = cr.effectToCompositeOp(effect);
  22007. cr.setGLBlend(this, effect, this.runtime.gl);
  22008. this.runtime.redraw = true;
  22009. };
  22010. Acts.prototype.LoadURL = function (url_)
  22011. {
  22012. var img = new Image();
  22013. var self = this;
  22014. img.onload = function ()
  22015. {
  22016. self.texture_img = img;
  22017. if (self.runtime.glwrap)
  22018. {
  22019. if (self.has_own_texture && self.webGL_texture)
  22020. self.runtime.glwrap.deleteTexture(self.webGL_texture);
  22021. self.webGL_texture = self.runtime.glwrap.loadTexture(img, true, self.runtime.linearSampling);
  22022. }
  22023. else
  22024. {
  22025. self.pattern = self.runtime.ctx.createPattern(img, "repeat");
  22026. }
  22027. self.has_own_texture = true;
  22028. self.runtime.redraw = true;
  22029. self.runtime.trigger(cr.plugins_.TiledBg.prototype.cnds.OnURLLoaded, self);
  22030. };
  22031. if (url_.substr(0, 5) !== "data:")
  22032. img.crossOrigin = "anonymous";
  22033. img.src = url_;
  22034. };
  22035. pluginProto.acts = new Acts();
  22036. function Exps() {};
  22037. Exps.prototype.ImageWidth = function (ret)
  22038. {
  22039. ret.set_float(this.texture_img.width);
  22040. };
  22041. Exps.prototype.ImageHeight = function (ret)
  22042. {
  22043. ret.set_float(this.texture_img.height);
  22044. };
  22045. pluginProto.exps = new Exps();
  22046. }());
  22047. ;
  22048. ;
  22049. cr.plugins_.Touch = function(runtime)
  22050. {
  22051. this.runtime = runtime;
  22052. };
  22053. (function ()
  22054. {
  22055. var pluginProto = cr.plugins_.Touch.prototype;
  22056. pluginProto.Type = function(plugin)
  22057. {
  22058. this.plugin = plugin;
  22059. this.runtime = plugin.runtime;
  22060. };
  22061. var typeProto = pluginProto.Type.prototype;
  22062. typeProto.onCreate = function()
  22063. {
  22064. };
  22065. pluginProto.Instance = function(type)
  22066. {
  22067. this.type = type;
  22068. this.runtime = type.runtime;
  22069. this.touches = [];
  22070. this.mouseDown = false;
  22071. };
  22072. var instanceProto = pluginProto.Instance.prototype;
  22073. var dummyoffset = {left: 0, top: 0};
  22074. instanceProto.findTouch = function (id)
  22075. {
  22076. var i, len;
  22077. for (i = 0, len = this.touches.length; i < len; i++)
  22078. {
  22079. if (this.touches[i]["id"] === id)
  22080. return i;
  22081. }
  22082. return -1;
  22083. };
  22084. var appmobi_accx = 0;
  22085. var appmobi_accy = 0;
  22086. var appmobi_accz = 0;
  22087. function AppMobiGetAcceleration(evt)
  22088. {
  22089. appmobi_accx = evt.x;
  22090. appmobi_accy = evt.y;
  22091. appmobi_accz = evt.z;
  22092. };
  22093. var pg_accx = 0;
  22094. var pg_accy = 0;
  22095. var pg_accz = 0;
  22096. function PhoneGapGetAcceleration(evt)
  22097. {
  22098. pg_accx = evt.x;
  22099. pg_accy = evt.y;
  22100. pg_accz = evt.z;
  22101. };
  22102. var theInstance = null;
  22103. var touchinfo_cache = [];
  22104. function AllocTouchInfo(x, y, id, index)
  22105. {
  22106. var ret;
  22107. if (touchinfo_cache.length)
  22108. ret = touchinfo_cache.pop();
  22109. else
  22110. ret = new TouchInfo();
  22111. ret.init(x, y, id, index);
  22112. return ret;
  22113. };
  22114. function ReleaseTouchInfo(ti)
  22115. {
  22116. if (touchinfo_cache.length < 100)
  22117. touchinfo_cache.push(ti);
  22118. };
  22119. var GESTURE_HOLD_THRESHOLD = 15; // max px motion for hold gesture to register
  22120. var GESTURE_HOLD_TIMEOUT = 500; // time for hold gesture to register
  22121. var GESTURE_TAP_TIMEOUT = 333; // time for tap gesture to register
  22122. var GESTURE_DOUBLETAP_THRESHOLD = 25; // max distance apart for taps to be
  22123. function TouchInfo()
  22124. {
  22125. this.starttime = 0;
  22126. this.time = 0;
  22127. this.lasttime = 0;
  22128. this.startx = 0;
  22129. this.starty = 0;
  22130. this.x = 0;
  22131. this.y = 0;
  22132. this.lastx = 0;
  22133. this.lasty = 0;
  22134. this["id"] = 0;
  22135. this.startindex = 0;
  22136. this.triggeredHold = false;
  22137. this.tooFarForHold = false;
  22138. };
  22139. TouchInfo.prototype.init = function (x, y, id, index)
  22140. {
  22141. var nowtime = cr.performance_now();
  22142. this.time = nowtime;
  22143. this.lasttime = nowtime;
  22144. this.starttime = nowtime;
  22145. this.startx = x;
  22146. this.starty = y;
  22147. this.x = x;
  22148. this.y = y;
  22149. this.lastx = x;
  22150. this.lasty = y;
  22151. this["id"] = id;
  22152. this.startindex = index;
  22153. this.triggeredHold = false;
  22154. this.tooFarForHold = false;
  22155. };
  22156. TouchInfo.prototype.update = function (nowtime, x, y)
  22157. {
  22158. this.lasttime = this.time;
  22159. this.time = nowtime;
  22160. this.lastx = this.x;
  22161. this.lasty = this.y;
  22162. this.x = x;
  22163. this.y = y;
  22164. if (!this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) >= GESTURE_HOLD_THRESHOLD)
  22165. {
  22166. this.tooFarForHold = true;
  22167. }
  22168. };
  22169. TouchInfo.prototype.maybeTriggerHold = function (inst, index)
  22170. {
  22171. if (this.triggeredHold)
  22172. return; // already triggered this gesture
  22173. var nowtime = cr.performance_now();
  22174. if (nowtime - this.starttime >= GESTURE_HOLD_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
  22175. {
  22176. this.triggeredHold = true;
  22177. inst.trigger_index = this.startindex;
  22178. inst.trigger_id = this["id"];
  22179. inst.getTouchIndex = index;
  22180. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGesture, inst);
  22181. inst.curTouchX = this.x;
  22182. inst.curTouchY = this.y;
  22183. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnHoldGestureObject, inst);
  22184. inst.getTouchIndex = 0;
  22185. }
  22186. };
  22187. var lastTapX = -1000;
  22188. var lastTapY = -1000;
  22189. var lastTapTime = -10000;
  22190. TouchInfo.prototype.maybeTriggerTap = function (inst, index)
  22191. {
  22192. if (this.triggeredHold)
  22193. return;
  22194. var nowtime = cr.performance_now();
  22195. if (nowtime - this.starttime <= GESTURE_TAP_TIMEOUT && !this.tooFarForHold && cr.distanceTo(this.startx, this.starty, this.x, this.y) < GESTURE_HOLD_THRESHOLD)
  22196. {
  22197. inst.trigger_index = this.startindex;
  22198. inst.trigger_id = this["id"];
  22199. inst.getTouchIndex = index;
  22200. if ((nowtime - lastTapTime <= GESTURE_TAP_TIMEOUT * 2) && cr.distanceTo(lastTapX, lastTapY, this.x, this.y) < GESTURE_DOUBLETAP_THRESHOLD)
  22201. {
  22202. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGesture, inst);
  22203. inst.curTouchX = this.x;
  22204. inst.curTouchY = this.y;
  22205. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnDoubleTapGestureObject, inst);
  22206. lastTapX = -1000;
  22207. lastTapY = -1000;
  22208. lastTapTime = -10000;
  22209. }
  22210. else
  22211. {
  22212. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGesture, inst);
  22213. inst.curTouchX = this.x;
  22214. inst.curTouchY = this.y;
  22215. inst.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTapGestureObject, inst);
  22216. lastTapX = this.x;
  22217. lastTapY = this.y;
  22218. lastTapTime = nowtime;
  22219. }
  22220. inst.getTouchIndex = 0;
  22221. }
  22222. };
  22223. instanceProto.onCreate = function()
  22224. {
  22225. theInstance = this;
  22226. this.isWindows8 = !!(typeof window["c2isWindows8"] !== "undefined" && window["c2isWindows8"]);
  22227. this.orient_alpha = 0;
  22228. this.orient_beta = 0;
  22229. this.orient_gamma = 0;
  22230. this.acc_g_x = 0;
  22231. this.acc_g_y = 0;
  22232. this.acc_g_z = 0;
  22233. this.acc_x = 0;
  22234. this.acc_y = 0;
  22235. this.acc_z = 0;
  22236. this.curTouchX = 0;
  22237. this.curTouchY = 0;
  22238. this.trigger_index = 0;
  22239. this.trigger_id = 0;
  22240. this.getTouchIndex = 0;
  22241. this.useMouseInput = (this.properties[0] !== 0);
  22242. var elem = (this.runtime.fullscreen_mode > 0) ? document : this.runtime.canvas;
  22243. var elem2 = document;
  22244. if (this.runtime.isDirectCanvas)
  22245. elem2 = elem = window["Canvas"];
  22246. else if (this.runtime.isCocoonJs)
  22247. elem2 = elem = window;
  22248. var self = this;
  22249. if (window.navigator["pointerEnabled"])
  22250. {
  22251. elem.addEventListener("pointerdown",
  22252. function(info) {
  22253. self.onPointerStart(info);
  22254. },
  22255. false
  22256. );
  22257. elem.addEventListener("pointermove",
  22258. function(info) {
  22259. self.onPointerMove(info);
  22260. },
  22261. false
  22262. );
  22263. elem2.addEventListener("pointerup",
  22264. function(info) {
  22265. self.onPointerEnd(info, false);
  22266. },
  22267. false
  22268. );
  22269. elem2.addEventListener("pointercancel",
  22270. function(info) {
  22271. self.onPointerEnd(info, true);
  22272. },
  22273. false
  22274. );
  22275. if (this.runtime.canvas)
  22276. {
  22277. this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
  22278. e.preventDefault();
  22279. }, false);
  22280. document.addEventListener("MSGestureHold", function(e) {
  22281. e.preventDefault();
  22282. }, false);
  22283. this.runtime.canvas.addEventListener("gesturehold", function(e) {
  22284. e.preventDefault();
  22285. }, false);
  22286. document.addEventListener("gesturehold", function(e) {
  22287. e.preventDefault();
  22288. }, false);
  22289. }
  22290. }
  22291. else if (window.navigator["msPointerEnabled"])
  22292. {
  22293. elem.addEventListener("MSPointerDown",
  22294. function(info) {
  22295. self.onPointerStart(info);
  22296. },
  22297. false
  22298. );
  22299. elem.addEventListener("MSPointerMove",
  22300. function(info) {
  22301. self.onPointerMove(info);
  22302. },
  22303. false
  22304. );
  22305. elem2.addEventListener("MSPointerUp",
  22306. function(info) {
  22307. self.onPointerEnd(info, false);
  22308. },
  22309. false
  22310. );
  22311. elem2.addEventListener("MSPointerCancel",
  22312. function(info) {
  22313. self.onPointerEnd(info, true);
  22314. },
  22315. false
  22316. );
  22317. if (this.runtime.canvas)
  22318. {
  22319. this.runtime.canvas.addEventListener("MSGestureHold", function(e) {
  22320. e.preventDefault();
  22321. }, false);
  22322. document.addEventListener("MSGestureHold", function(e) {
  22323. e.preventDefault();
  22324. }, false);
  22325. }
  22326. }
  22327. else
  22328. {
  22329. elem.addEventListener("touchstart",
  22330. function(info) {
  22331. self.onTouchStart(info);
  22332. },
  22333. false
  22334. );
  22335. elem.addEventListener("touchmove",
  22336. function(info) {
  22337. self.onTouchMove(info);
  22338. },
  22339. false
  22340. );
  22341. elem2.addEventListener("touchend",
  22342. function(info) {
  22343. self.onTouchEnd(info, false);
  22344. },
  22345. false
  22346. );
  22347. elem2.addEventListener("touchcancel",
  22348. function(info) {
  22349. self.onTouchEnd(info, true);
  22350. },
  22351. false
  22352. );
  22353. }
  22354. if (this.isWindows8)
  22355. {
  22356. var win8accelerometerFn = function(e) {
  22357. var reading = e["reading"];
  22358. self.acc_x = reading["accelerationX"];
  22359. self.acc_y = reading["accelerationY"];
  22360. self.acc_z = reading["accelerationZ"];
  22361. };
  22362. var win8inclinometerFn = function(e) {
  22363. var reading = e["reading"];
  22364. self.orient_alpha = reading["yawDegrees"];
  22365. self.orient_beta = reading["pitchDegrees"];
  22366. self.orient_gamma = reading["rollDegrees"];
  22367. };
  22368. var accelerometer = Windows["Devices"]["Sensors"]["Accelerometer"]["getDefault"]();
  22369. if (accelerometer)
  22370. {
  22371. accelerometer["reportInterval"] = Math.max(accelerometer["minimumReportInterval"], 16);
  22372. accelerometer.addEventListener("readingchanged", win8accelerometerFn);
  22373. }
  22374. var inclinometer = Windows["Devices"]["Sensors"]["Inclinometer"]["getDefault"]();
  22375. if (inclinometer)
  22376. {
  22377. inclinometer["reportInterval"] = Math.max(inclinometer["minimumReportInterval"], 16);
  22378. inclinometer.addEventListener("readingchanged", win8inclinometerFn);
  22379. }
  22380. document.addEventListener("visibilitychange", function(e) {
  22381. if (document["hidden"] || document["msHidden"])
  22382. {
  22383. if (accelerometer)
  22384. accelerometer.removeEventListener("readingchanged", win8accelerometerFn);
  22385. if (inclinometer)
  22386. inclinometer.removeEventListener("readingchanged", win8inclinometerFn);
  22387. }
  22388. else
  22389. {
  22390. if (accelerometer)
  22391. accelerometer.addEventListener("readingchanged", win8accelerometerFn);
  22392. if (inclinometer)
  22393. inclinometer.addEventListener("readingchanged", win8inclinometerFn);
  22394. }
  22395. }, false);
  22396. }
  22397. else
  22398. {
  22399. window.addEventListener("deviceorientation", function (eventData) {
  22400. self.orient_alpha = eventData["alpha"] || 0;
  22401. self.orient_beta = eventData["beta"] || 0;
  22402. self.orient_gamma = eventData["gamma"] || 0;
  22403. }, false);
  22404. window.addEventListener("devicemotion", function (eventData) {
  22405. if (eventData["accelerationIncludingGravity"])
  22406. {
  22407. self.acc_g_x = eventData["accelerationIncludingGravity"]["x"] || 0;
  22408. self.acc_g_y = eventData["accelerationIncludingGravity"]["y"] || 0;
  22409. self.acc_g_z = eventData["accelerationIncludingGravity"]["z"] || 0;
  22410. }
  22411. if (eventData["acceleration"])
  22412. {
  22413. self.acc_x = eventData["acceleration"]["x"] || 0;
  22414. self.acc_y = eventData["acceleration"]["y"] || 0;
  22415. self.acc_z = eventData["acceleration"]["z"] || 0;
  22416. }
  22417. }, false);
  22418. }
  22419. if (this.useMouseInput && !this.runtime.isDomFree)
  22420. {
  22421. jQuery(document).mousemove(
  22422. function(info) {
  22423. self.onMouseMove(info);
  22424. }
  22425. );
  22426. jQuery(document).mousedown(
  22427. function(info) {
  22428. self.onMouseDown(info);
  22429. }
  22430. );
  22431. jQuery(document).mouseup(
  22432. function(info) {
  22433. self.onMouseUp(info);
  22434. }
  22435. );
  22436. }
  22437. if (this.runtime.isAppMobi && !this.runtime.isDirectCanvas)
  22438. {
  22439. AppMobi["accelerometer"]["watchAcceleration"](AppMobiGetAcceleration, { "frequency": 40, "adjustForRotation": true });
  22440. }
  22441. if (this.runtime.isCordova && navigator["accelerometer"] && navigator["accelerometer"]["watchAcceleration"])
  22442. {
  22443. navigator["accelerometer"]["watchAcceleration"](PhoneGapGetAcceleration, null, { "frequency": 40 });
  22444. }
  22445. this.runtime.tick2Me(this);
  22446. };
  22447. instanceProto.onPointerMove = function (info)
  22448. {
  22449. if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
  22450. return;
  22451. if (info.preventDefault)
  22452. info.preventDefault();
  22453. var i = this.findTouch(info["pointerId"]);
  22454. var nowtime = cr.performance_now();
  22455. if (i >= 0)
  22456. {
  22457. var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
  22458. var t = this.touches[i];
  22459. if (nowtime - t.time < 2)
  22460. return;
  22461. t.update(nowtime, info.pageX - offset.left, info.pageY - offset.top);
  22462. }
  22463. };
  22464. instanceProto.onPointerStart = function (info)
  22465. {
  22466. if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
  22467. return;
  22468. if (info.preventDefault && cr.isCanvasInputEvent(info))
  22469. info.preventDefault();
  22470. var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
  22471. var touchx = info.pageX - offset.left;
  22472. var touchy = info.pageY - offset.top;
  22473. var nowtime = cr.performance_now();
  22474. this.trigger_index = this.touches.length;
  22475. this.trigger_id = info["pointerId"];
  22476. this.touches.push(AllocTouchInfo(touchx, touchy, info["pointerId"], this.trigger_index));
  22477. this.runtime.isInUserInputEvent = true;
  22478. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
  22479. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
  22480. this.curTouchX = touchx;
  22481. this.curTouchY = touchy;
  22482. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
  22483. this.runtime.isInUserInputEvent = false;
  22484. };
  22485. instanceProto.onPointerEnd = function (info, isCancel)
  22486. {
  22487. if (info["pointerType"] === info["MSPOINTER_TYPE_MOUSE"] || info["pointerType"] === "mouse")
  22488. return;
  22489. if (info.preventDefault && cr.isCanvasInputEvent(info))
  22490. info.preventDefault();
  22491. var i = this.findTouch(info["pointerId"]);
  22492. this.trigger_index = (i >= 0 ? this.touches[i].startindex : -1);
  22493. this.trigger_id = (i >= 0 ? this.touches[i]["id"] : -1);
  22494. this.runtime.isInUserInputEvent = true;
  22495. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
  22496. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
  22497. if (i >= 0)
  22498. {
  22499. if (!isCancel)
  22500. this.touches[i].maybeTriggerTap(this, i);
  22501. ReleaseTouchInfo(this.touches[i]);
  22502. this.touches.splice(i, 1);
  22503. }
  22504. this.runtime.isInUserInputEvent = false;
  22505. };
  22506. instanceProto.onTouchMove = function (info)
  22507. {
  22508. if (info.preventDefault)
  22509. info.preventDefault();
  22510. var nowtime = cr.performance_now();
  22511. var i, len, t, u;
  22512. for (i = 0, len = info.changedTouches.length; i < len; i++)
  22513. {
  22514. t = info.changedTouches[i];
  22515. var j = this.findTouch(t["identifier"]);
  22516. if (j >= 0)
  22517. {
  22518. var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
  22519. u = this.touches[j];
  22520. if (nowtime - u.time < 2)
  22521. continue;
  22522. u.update(nowtime, t.pageX - offset.left, t.pageY - offset.top);
  22523. }
  22524. }
  22525. };
  22526. instanceProto.onTouchStart = function (info)
  22527. {
  22528. if (info.preventDefault && cr.isCanvasInputEvent(info))
  22529. info.preventDefault();
  22530. var offset = this.runtime.isDomFree ? dummyoffset : jQuery(this.runtime.canvas).offset();
  22531. var nowtime = cr.performance_now();
  22532. this.runtime.isInUserInputEvent = true;
  22533. var i, len, t, j;
  22534. for (i = 0, len = info.changedTouches.length; i < len; i++)
  22535. {
  22536. t = info.changedTouches[i];
  22537. j = this.findTouch(t["identifier"]);
  22538. if (j !== -1)
  22539. continue;
  22540. var touchx = t.pageX - offset.left;
  22541. var touchy = t.pageY - offset.top;
  22542. this.trigger_index = this.touches.length;
  22543. this.trigger_id = t["identifier"];
  22544. this.touches.push(AllocTouchInfo(touchx, touchy, t["identifier"], this.trigger_index));
  22545. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchStart, this);
  22546. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchStart, this);
  22547. this.curTouchX = touchx;
  22548. this.curTouchY = touchy;
  22549. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchObject, this);
  22550. }
  22551. this.runtime.isInUserInputEvent = false;
  22552. };
  22553. instanceProto.onTouchEnd = function (info, isCancel)
  22554. {
  22555. if (info.preventDefault && cr.isCanvasInputEvent(info))
  22556. info.preventDefault();
  22557. this.runtime.isInUserInputEvent = true;
  22558. var i, len, t, j;
  22559. for (i = 0, len = info.changedTouches.length; i < len; i++)
  22560. {
  22561. t = info.changedTouches[i];
  22562. j = this.findTouch(t["identifier"]);
  22563. if (j >= 0)
  22564. {
  22565. this.trigger_index = this.touches[j].startindex;
  22566. this.trigger_id = this.touches[j]["id"];
  22567. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnNthTouchEnd, this);
  22568. this.runtime.trigger(cr.plugins_.Touch.prototype.cnds.OnTouchEnd, this);
  22569. if (!isCancel)
  22570. this.touches[j].maybeTriggerTap(this, j);
  22571. ReleaseTouchInfo(this.touches[j]);
  22572. this.touches.splice(j, 1);
  22573. }
  22574. }
  22575. this.runtime.isInUserInputEvent = false;
  22576. };
  22577. instanceProto.getAlpha = function ()
  22578. {
  22579. if (this.runtime.isAppMobi && this.orient_alpha === 0 && appmobi_accz !== 0)
  22580. return appmobi_accz * 90;
  22581. else if (this.runtime.isCordova && this.orient_alpha === 0 && pg_accz !== 0)
  22582. return pg_accz * 90;
  22583. else
  22584. return this.orient_alpha;
  22585. };
  22586. instanceProto.getBeta = function ()
  22587. {
  22588. if (this.runtime.isAppMobi && this.orient_beta === 0 && appmobi_accy !== 0)
  22589. return appmobi_accy * -90;
  22590. else if (this.runtime.isCordova && this.orient_beta === 0 && pg_accy !== 0)
  22591. return pg_accy * 90;
  22592. else
  22593. return this.orient_beta;
  22594. };
  22595. instanceProto.getGamma = function ()
  22596. {
  22597. if (this.runtime.isAppMobi && this.orient_gamma === 0 && appmobi_accx !== 0)
  22598. return appmobi_accx * 90;
  22599. else if (this.runtime.isCordova && this.orient_gamma === 0 && pg_accx !== 0)
  22600. return pg_accx * 90;
  22601. else
  22602. return this.orient_gamma;
  22603. };
  22604. var noop_func = function(){};
  22605. instanceProto.onMouseDown = function(info)
  22606. {
  22607. var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
  22608. var fakeinfo = { changedTouches: [t] };
  22609. this.onTouchStart(fakeinfo);
  22610. this.mouseDown = true;
  22611. };
  22612. instanceProto.onMouseMove = function(info)
  22613. {
  22614. if (!this.mouseDown)
  22615. return;
  22616. var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
  22617. var fakeinfo = { changedTouches: [t] };
  22618. this.onTouchMove(fakeinfo);
  22619. };
  22620. instanceProto.onMouseUp = function(info)
  22621. {
  22622. if (info.preventDefault && this.runtime.had_a_click && !this.runtime.isMobile)
  22623. info.preventDefault();
  22624. this.runtime.had_a_click = true;
  22625. var t = { pageX: info.pageX, pageY: info.pageY, "identifier": 0 };
  22626. var fakeinfo = { changedTouches: [t] };
  22627. this.onTouchEnd(fakeinfo);
  22628. this.mouseDown = false;
  22629. };
  22630. instanceProto.tick2 = function()
  22631. {
  22632. var i, len, t;
  22633. var nowtime = cr.performance_now();
  22634. for (i = 0, len = this.touches.length; i < len; ++i)
  22635. {
  22636. t = this.touches[i];
  22637. if (t.time <= nowtime - 50)
  22638. t.lasttime = nowtime;
  22639. t.maybeTriggerHold(this, i);
  22640. }
  22641. };
  22642. function Cnds() {};
  22643. Cnds.prototype.OnTouchStart = function ()
  22644. {
  22645. return true;
  22646. };
  22647. Cnds.prototype.OnTouchEnd = function ()
  22648. {
  22649. return true;
  22650. };
  22651. Cnds.prototype.IsInTouch = function ()
  22652. {
  22653. return this.touches.length;
  22654. };
  22655. Cnds.prototype.OnTouchObject = function (type)
  22656. {
  22657. if (!type)
  22658. return false;
  22659. return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
  22660. };
  22661. var touching = [];
  22662. Cnds.prototype.IsTouchingObject = function (type)
  22663. {
  22664. if (!type)
  22665. return false;
  22666. var sol = type.getCurrentSol();
  22667. var instances = sol.getObjects();
  22668. var px, py;
  22669. var i, leni, j, lenj;
  22670. for (i = 0, leni = instances.length; i < leni; i++)
  22671. {
  22672. var inst = instances[i];
  22673. inst.update_bbox();
  22674. for (j = 0, lenj = this.touches.length; j < lenj; j++)
  22675. {
  22676. var touch = this.touches[j];
  22677. px = inst.layer.canvasToLayer(touch.x, touch.y, true);
  22678. py = inst.layer.canvasToLayer(touch.x, touch.y, false);
  22679. if (inst.contains_pt(px, py))
  22680. {
  22681. touching.push(inst);
  22682. break;
  22683. }
  22684. }
  22685. }
  22686. if (touching.length)
  22687. {
  22688. sol.select_all = false;
  22689. cr.shallowAssignArray(sol.instances, touching);
  22690. type.applySolToContainer();
  22691. cr.clearArray(touching);
  22692. return true;
  22693. }
  22694. else
  22695. return false;
  22696. };
  22697. Cnds.prototype.CompareTouchSpeed = function (index, cmp, s)
  22698. {
  22699. index = Math.floor(index);
  22700. if (index < 0 || index >= this.touches.length)
  22701. return false;
  22702. var t = this.touches[index];
  22703. var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
  22704. var timediff = (t.time - t.lasttime) / 1000;
  22705. var speed = 0;
  22706. if (timediff > 0)
  22707. speed = dist / timediff;
  22708. return cr.do_cmp(speed, cmp, s);
  22709. };
  22710. Cnds.prototype.OrientationSupported = function ()
  22711. {
  22712. return typeof window["DeviceOrientationEvent"] !== "undefined";
  22713. };
  22714. Cnds.prototype.MotionSupported = function ()
  22715. {
  22716. return typeof window["DeviceMotionEvent"] !== "undefined";
  22717. };
  22718. Cnds.prototype.CompareOrientation = function (orientation_, cmp_, angle_)
  22719. {
  22720. var v = 0;
  22721. if (orientation_ === 0)
  22722. v = this.getAlpha();
  22723. else if (orientation_ === 1)
  22724. v = this.getBeta();
  22725. else
  22726. v = this.getGamma();
  22727. return cr.do_cmp(v, cmp_, angle_);
  22728. };
  22729. Cnds.prototype.CompareAcceleration = function (acceleration_, cmp_, angle_)
  22730. {
  22731. var v = 0;
  22732. if (acceleration_ === 0)
  22733. v = this.acc_g_x;
  22734. else if (acceleration_ === 1)
  22735. v = this.acc_g_y;
  22736. else if (acceleration_ === 2)
  22737. v = this.acc_g_z;
  22738. else if (acceleration_ === 3)
  22739. v = this.acc_x;
  22740. else if (acceleration_ === 4)
  22741. v = this.acc_y;
  22742. else if (acceleration_ === 5)
  22743. v = this.acc_z;
  22744. return cr.do_cmp(v, cmp_, angle_);
  22745. };
  22746. Cnds.prototype.OnNthTouchStart = function (touch_)
  22747. {
  22748. touch_ = Math.floor(touch_);
  22749. return touch_ === this.trigger_index;
  22750. };
  22751. Cnds.prototype.OnNthTouchEnd = function (touch_)
  22752. {
  22753. touch_ = Math.floor(touch_);
  22754. return touch_ === this.trigger_index;
  22755. };
  22756. Cnds.prototype.HasNthTouch = function (touch_)
  22757. {
  22758. touch_ = Math.floor(touch_);
  22759. return this.touches.length >= touch_ + 1;
  22760. };
  22761. Cnds.prototype.OnHoldGesture = function ()
  22762. {
  22763. return true;
  22764. };
  22765. Cnds.prototype.OnTapGesture = function ()
  22766. {
  22767. return true;
  22768. };
  22769. Cnds.prototype.OnDoubleTapGesture = function ()
  22770. {
  22771. return true;
  22772. };
  22773. Cnds.prototype.OnHoldGestureObject = function (type)
  22774. {
  22775. if (!type)
  22776. return false;
  22777. return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
  22778. };
  22779. Cnds.prototype.OnTapGestureObject = function (type)
  22780. {
  22781. if (!type)
  22782. return false;
  22783. return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
  22784. };
  22785. Cnds.prototype.OnDoubleTapGestureObject = function (type)
  22786. {
  22787. if (!type)
  22788. return false;
  22789. return this.runtime.testAndSelectCanvasPointOverlap(type, this.curTouchX, this.curTouchY, false);
  22790. };
  22791. pluginProto.cnds = new Cnds();
  22792. function Exps() {};
  22793. Exps.prototype.TouchCount = function (ret)
  22794. {
  22795. ret.set_int(this.touches.length);
  22796. };
  22797. Exps.prototype.X = function (ret, layerparam)
  22798. {
  22799. var index = this.getTouchIndex;
  22800. if (index < 0 || index >= this.touches.length)
  22801. {
  22802. ret.set_float(0);
  22803. return;
  22804. }
  22805. var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
  22806. if (cr.is_undefined(layerparam))
  22807. {
  22808. layer = this.runtime.getLayerByNumber(0);
  22809. oldScale = layer.scale;
  22810. oldZoomRate = layer.zoomRate;
  22811. oldParallaxX = layer.parallaxX;
  22812. oldAngle = layer.angle;
  22813. layer.scale = 1;
  22814. layer.zoomRate = 1.0;
  22815. layer.parallaxX = 1.0;
  22816. layer.angle = 0;
  22817. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
  22818. layer.scale = oldScale;
  22819. layer.zoomRate = oldZoomRate;
  22820. layer.parallaxX = oldParallaxX;
  22821. layer.angle = oldAngle;
  22822. }
  22823. else
  22824. {
  22825. if (cr.is_number(layerparam))
  22826. layer = this.runtime.getLayerByNumber(layerparam);
  22827. else
  22828. layer = this.runtime.getLayerByName(layerparam);
  22829. if (layer)
  22830. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
  22831. else
  22832. ret.set_float(0);
  22833. }
  22834. };
  22835. Exps.prototype.XAt = function (ret, index, layerparam)
  22836. {
  22837. index = Math.floor(index);
  22838. if (index < 0 || index >= this.touches.length)
  22839. {
  22840. ret.set_float(0);
  22841. return;
  22842. }
  22843. var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
  22844. if (cr.is_undefined(layerparam))
  22845. {
  22846. layer = this.runtime.getLayerByNumber(0);
  22847. oldScale = layer.scale;
  22848. oldZoomRate = layer.zoomRate;
  22849. oldParallaxX = layer.parallaxX;
  22850. oldAngle = layer.angle;
  22851. layer.scale = 1;
  22852. layer.zoomRate = 1.0;
  22853. layer.parallaxX = 1.0;
  22854. layer.angle = 0;
  22855. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
  22856. layer.scale = oldScale;
  22857. layer.zoomRate = oldZoomRate;
  22858. layer.parallaxX = oldParallaxX;
  22859. layer.angle = oldAngle;
  22860. }
  22861. else
  22862. {
  22863. if (cr.is_number(layerparam))
  22864. layer = this.runtime.getLayerByNumber(layerparam);
  22865. else
  22866. layer = this.runtime.getLayerByName(layerparam);
  22867. if (layer)
  22868. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, true));
  22869. else
  22870. ret.set_float(0);
  22871. }
  22872. };
  22873. Exps.prototype.XForID = function (ret, id, layerparam)
  22874. {
  22875. var index = this.findTouch(id);
  22876. if (index < 0)
  22877. {
  22878. ret.set_float(0);
  22879. return;
  22880. }
  22881. var touch = this.touches[index];
  22882. var layer, oldScale, oldZoomRate, oldParallaxX, oldAngle;
  22883. if (cr.is_undefined(layerparam))
  22884. {
  22885. layer = this.runtime.getLayerByNumber(0);
  22886. oldScale = layer.scale;
  22887. oldZoomRate = layer.zoomRate;
  22888. oldParallaxX = layer.parallaxX;
  22889. oldAngle = layer.angle;
  22890. layer.scale = 1;
  22891. layer.zoomRate = 1.0;
  22892. layer.parallaxX = 1.0;
  22893. layer.angle = 0;
  22894. ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
  22895. layer.scale = oldScale;
  22896. layer.zoomRate = oldZoomRate;
  22897. layer.parallaxX = oldParallaxX;
  22898. layer.angle = oldAngle;
  22899. }
  22900. else
  22901. {
  22902. if (cr.is_number(layerparam))
  22903. layer = this.runtime.getLayerByNumber(layerparam);
  22904. else
  22905. layer = this.runtime.getLayerByName(layerparam);
  22906. if (layer)
  22907. ret.set_float(layer.canvasToLayer(touch.x, touch.y, true));
  22908. else
  22909. ret.set_float(0);
  22910. }
  22911. };
  22912. Exps.prototype.Y = function (ret, layerparam)
  22913. {
  22914. var index = this.getTouchIndex;
  22915. if (index < 0 || index >= this.touches.length)
  22916. {
  22917. ret.set_float(0);
  22918. return;
  22919. }
  22920. var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
  22921. if (cr.is_undefined(layerparam))
  22922. {
  22923. layer = this.runtime.getLayerByNumber(0);
  22924. oldScale = layer.scale;
  22925. oldZoomRate = layer.zoomRate;
  22926. oldParallaxY = layer.parallaxY;
  22927. oldAngle = layer.angle;
  22928. layer.scale = 1;
  22929. layer.zoomRate = 1.0;
  22930. layer.parallaxY = 1.0;
  22931. layer.angle = 0;
  22932. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
  22933. layer.scale = oldScale;
  22934. layer.zoomRate = oldZoomRate;
  22935. layer.parallaxY = oldParallaxY;
  22936. layer.angle = oldAngle;
  22937. }
  22938. else
  22939. {
  22940. if (cr.is_number(layerparam))
  22941. layer = this.runtime.getLayerByNumber(layerparam);
  22942. else
  22943. layer = this.runtime.getLayerByName(layerparam);
  22944. if (layer)
  22945. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
  22946. else
  22947. ret.set_float(0);
  22948. }
  22949. };
  22950. Exps.prototype.YAt = function (ret, index, layerparam)
  22951. {
  22952. index = Math.floor(index);
  22953. if (index < 0 || index >= this.touches.length)
  22954. {
  22955. ret.set_float(0);
  22956. return;
  22957. }
  22958. var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
  22959. if (cr.is_undefined(layerparam))
  22960. {
  22961. layer = this.runtime.getLayerByNumber(0);
  22962. oldScale = layer.scale;
  22963. oldZoomRate = layer.zoomRate;
  22964. oldParallaxY = layer.parallaxY;
  22965. oldAngle = layer.angle;
  22966. layer.scale = 1;
  22967. layer.zoomRate = 1.0;
  22968. layer.parallaxY = 1.0;
  22969. layer.angle = 0;
  22970. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
  22971. layer.scale = oldScale;
  22972. layer.zoomRate = oldZoomRate;
  22973. layer.parallaxY = oldParallaxY;
  22974. layer.angle = oldAngle;
  22975. }
  22976. else
  22977. {
  22978. if (cr.is_number(layerparam))
  22979. layer = this.runtime.getLayerByNumber(layerparam);
  22980. else
  22981. layer = this.runtime.getLayerByName(layerparam);
  22982. if (layer)
  22983. ret.set_float(layer.canvasToLayer(this.touches[index].x, this.touches[index].y, false));
  22984. else
  22985. ret.set_float(0);
  22986. }
  22987. };
  22988. Exps.prototype.YForID = function (ret, id, layerparam)
  22989. {
  22990. var index = this.findTouch(id);
  22991. if (index < 0)
  22992. {
  22993. ret.set_float(0);
  22994. return;
  22995. }
  22996. var touch = this.touches[index];
  22997. var layer, oldScale, oldZoomRate, oldParallaxY, oldAngle;
  22998. if (cr.is_undefined(layerparam))
  22999. {
  23000. layer = this.runtime.getLayerByNumber(0);
  23001. oldScale = layer.scale;
  23002. oldZoomRate = layer.zoomRate;
  23003. oldParallaxY = layer.parallaxY;
  23004. oldAngle = layer.angle;
  23005. layer.scale = 1;
  23006. layer.zoomRate = 1.0;
  23007. layer.parallaxY = 1.0;
  23008. layer.angle = 0;
  23009. ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
  23010. layer.scale = oldScale;
  23011. layer.zoomRate = oldZoomRate;
  23012. layer.parallaxY = oldParallaxY;
  23013. layer.angle = oldAngle;
  23014. }
  23015. else
  23016. {
  23017. if (cr.is_number(layerparam))
  23018. layer = this.runtime.getLayerByNumber(layerparam);
  23019. else
  23020. layer = this.runtime.getLayerByName(layerparam);
  23021. if (layer)
  23022. ret.set_float(layer.canvasToLayer(touch.x, touch.y, false));
  23023. else
  23024. ret.set_float(0);
  23025. }
  23026. };
  23027. Exps.prototype.AbsoluteX = function (ret)
  23028. {
  23029. if (this.touches.length)
  23030. ret.set_float(this.touches[0].x);
  23031. else
  23032. ret.set_float(0);
  23033. };
  23034. Exps.prototype.AbsoluteXAt = function (ret, index)
  23035. {
  23036. index = Math.floor(index);
  23037. if (index < 0 || index >= this.touches.length)
  23038. {
  23039. ret.set_float(0);
  23040. return;
  23041. }
  23042. ret.set_float(this.touches[index].x);
  23043. };
  23044. Exps.prototype.AbsoluteXForID = function (ret, id)
  23045. {
  23046. var index = this.findTouch(id);
  23047. if (index < 0)
  23048. {
  23049. ret.set_float(0);
  23050. return;
  23051. }
  23052. var touch = this.touches[index];
  23053. ret.set_float(touch.x);
  23054. };
  23055. Exps.prototype.AbsoluteY = function (ret)
  23056. {
  23057. if (this.touches.length)
  23058. ret.set_float(this.touches[0].y);
  23059. else
  23060. ret.set_float(0);
  23061. };
  23062. Exps.prototype.AbsoluteYAt = function (ret, index)
  23063. {
  23064. index = Math.floor(index);
  23065. if (index < 0 || index >= this.touches.length)
  23066. {
  23067. ret.set_float(0);
  23068. return;
  23069. }
  23070. ret.set_float(this.touches[index].y);
  23071. };
  23072. Exps.prototype.AbsoluteYForID = function (ret, id)
  23073. {
  23074. var index = this.findTouch(id);
  23075. if (index < 0)
  23076. {
  23077. ret.set_float(0);
  23078. return;
  23079. }
  23080. var touch = this.touches[index];
  23081. ret.set_float(touch.y);
  23082. };
  23083. Exps.prototype.SpeedAt = function (ret, index)
  23084. {
  23085. index = Math.floor(index);
  23086. if (index < 0 || index >= this.touches.length)
  23087. {
  23088. ret.set_float(0);
  23089. return;
  23090. }
  23091. var t = this.touches[index];
  23092. var dist = cr.distanceTo(t.x, t.y, t.lastx, t.lasty);
  23093. var timediff = (t.time - t.lasttime) / 1000;
  23094. if (timediff === 0)
  23095. ret.set_float(0);
  23096. else
  23097. ret.set_float(dist / timediff);
  23098. };
  23099. Exps.prototype.SpeedForID = function (ret, id)
  23100. {
  23101. var index = this.findTouch(id);
  23102. if (index < 0)
  23103. {
  23104. ret.set_float(0);
  23105. return;
  23106. }
  23107. var touch = this.touches[index];
  23108. var dist = cr.distanceTo(touch.x, touch.y, touch.lastx, touch.lasty);
  23109. var timediff = (touch.time - touch.lasttime) / 1000;
  23110. if (timediff === 0)
  23111. ret.set_float(0);
  23112. else
  23113. ret.set_float(dist / timediff);
  23114. };
  23115. Exps.prototype.AngleAt = function (ret, index)
  23116. {
  23117. index = Math.floor(index);
  23118. if (index < 0 || index >= this.touches.length)
  23119. {
  23120. ret.set_float(0);
  23121. return;
  23122. }
  23123. var t = this.touches[index];
  23124. ret.set_float(cr.to_degrees(cr.angleTo(t.lastx, t.lasty, t.x, t.y)));
  23125. };
  23126. Exps.prototype.AngleForID = function (ret, id)
  23127. {
  23128. var index = this.findTouch(id);
  23129. if (index < 0)
  23130. {
  23131. ret.set_float(0);
  23132. return;
  23133. }
  23134. var touch = this.touches[index];
  23135. ret.set_float(cr.to_degrees(cr.angleTo(touch.lastx, touch.lasty, touch.x, touch.y)));
  23136. };
  23137. Exps.prototype.Alpha = function (ret)
  23138. {
  23139. ret.set_float(this.getAlpha());
  23140. };
  23141. Exps.prototype.Beta = function (ret)
  23142. {
  23143. ret.set_float(this.getBeta());
  23144. };
  23145. Exps.prototype.Gamma = function (ret)
  23146. {
  23147. ret.set_float(this.getGamma());
  23148. };
  23149. Exps.prototype.AccelerationXWithG = function (ret)
  23150. {
  23151. ret.set_float(this.acc_g_x);
  23152. };
  23153. Exps.prototype.AccelerationYWithG = function (ret)
  23154. {
  23155. ret.set_float(this.acc_g_y);
  23156. };
  23157. Exps.prototype.AccelerationZWithG = function (ret)
  23158. {
  23159. ret.set_float(this.acc_g_z);
  23160. };
  23161. Exps.prototype.AccelerationX = function (ret)
  23162. {
  23163. ret.set_float(this.acc_x);
  23164. };
  23165. Exps.prototype.AccelerationY = function (ret)
  23166. {
  23167. ret.set_float(this.acc_y);
  23168. };
  23169. Exps.prototype.AccelerationZ = function (ret)
  23170. {
  23171. ret.set_float(this.acc_z);
  23172. };
  23173. Exps.prototype.TouchIndex = function (ret)
  23174. {
  23175. ret.set_int(this.trigger_index);
  23176. };
  23177. Exps.prototype.TouchID = function (ret)
  23178. {
  23179. ret.set_float(this.trigger_id);
  23180. };
  23181. pluginProto.exps = new Exps();
  23182. }());
  23183. ;
  23184. ;
  23185. cr.plugins_.WebStorage = function(runtime)
  23186. {
  23187. this.runtime = runtime;
  23188. };
  23189. (function()
  23190. {
  23191. var pluginProto = cr.plugins_.WebStorage.prototype;
  23192. pluginProto.Type = function(plugin)
  23193. {
  23194. this.plugin = plugin;
  23195. this.runtime = plugin.runtime;
  23196. };
  23197. var typeProto = pluginProto.Type.prototype;
  23198. typeProto.onCreate = function()
  23199. {
  23200. };
  23201. pluginProto.Instance = function(type)
  23202. {
  23203. this.type = type;
  23204. this.runtime = type.runtime;
  23205. };
  23206. var instanceProto = pluginProto.Instance.prototype;
  23207. var prefix = "";
  23208. var is_arcade = (typeof window["is_scirra_arcade"] !== "undefined");
  23209. if (is_arcade)
  23210. prefix = "arcade" + window["scirra_arcade_id"];
  23211. var isSupported = false;
  23212. try {
  23213. localStorage.getItem("test");
  23214. isSupported = true;
  23215. }
  23216. catch (e)
  23217. {
  23218. isSupported = false;
  23219. }
  23220. instanceProto.onCreate = function()
  23221. {
  23222. if (!isSupported)
  23223. {
  23224. cr.logexport("[Construct 2] Webstorage plugin: local storage is not supported on this platform.");
  23225. }
  23226. };
  23227. function Cnds() {};
  23228. Cnds.prototype.LocalStorageEnabled = function()
  23229. {
  23230. return isSupported;
  23231. };
  23232. Cnds.prototype.SessionStorageEnabled = function()
  23233. {
  23234. return isSupported;
  23235. };
  23236. Cnds.prototype.LocalStorageExists = function(key)
  23237. {
  23238. if (!isSupported)
  23239. return false;
  23240. return localStorage.getItem(prefix + key) != null;
  23241. };
  23242. Cnds.prototype.SessionStorageExists = function(key)
  23243. {
  23244. if (!isSupported)
  23245. return false;
  23246. return sessionStorage.getItem(prefix + key) != null;
  23247. };
  23248. Cnds.prototype.OnQuotaExceeded = function ()
  23249. {
  23250. return true;
  23251. };
  23252. Cnds.prototype.CompareKeyText = function (key, text_to_compare, case_sensitive)
  23253. {
  23254. if (!isSupported)
  23255. return false;
  23256. var value = localStorage.getItem(prefix + key) || "";
  23257. if (case_sensitive)
  23258. return value == text_to_compare;
  23259. else
  23260. return cr.equals_nocase(value, text_to_compare);
  23261. };
  23262. Cnds.prototype.CompareKeyNumber = function (key, cmp, x)
  23263. {
  23264. if (!isSupported)
  23265. return false;
  23266. var value = localStorage.getItem(prefix + key) || "";
  23267. return cr.do_cmp(parseFloat(value), cmp, x);
  23268. };
  23269. pluginProto.cnds = new Cnds();
  23270. function Acts() {};
  23271. Acts.prototype.StoreLocal = function(key, data)
  23272. {
  23273. if (!isSupported)
  23274. return;
  23275. try {
  23276. localStorage.setItem(prefix + key, data);
  23277. }
  23278. catch (e)
  23279. {
  23280. this.runtime.trigger(cr.plugins_.WebStorage.prototype.cnds.OnQuotaExceeded, this);
  23281. }
  23282. };
  23283. Acts.prototype.StoreSession = function(key,data)
  23284. {
  23285. if (!isSupported)
  23286. return;
  23287. try {
  23288. sessionStorage.setItem(prefix + key, data);
  23289. }
  23290. catch (e)
  23291. {
  23292. this.runtime.trigger(cr.plugins_.WebStorage.prototype.cnds.OnQuotaExceeded, this);
  23293. }
  23294. };
  23295. Acts.prototype.RemoveLocal = function(key)
  23296. {
  23297. if (!isSupported)
  23298. return;
  23299. localStorage.removeItem(prefix + key);
  23300. };
  23301. Acts.prototype.RemoveSession = function(key)
  23302. {
  23303. if (!isSupported)
  23304. return;
  23305. sessionStorage.removeItem(prefix + key);
  23306. };
  23307. Acts.prototype.ClearLocal = function()
  23308. {
  23309. if (!isSupported)
  23310. return;
  23311. if (!is_arcade)
  23312. localStorage.clear();
  23313. };
  23314. Acts.prototype.ClearSession = function()
  23315. {
  23316. if (!isSupported)
  23317. return;
  23318. if (!is_arcade)
  23319. sessionStorage.clear();
  23320. };
  23321. Acts.prototype.JSONLoad = function (json_, mode_)
  23322. {
  23323. if (!isSupported)
  23324. return;
  23325. var d;
  23326. try {
  23327. d = JSON.parse(json_);
  23328. }
  23329. catch(e) { return; }
  23330. if (!d["c2dictionary"]) // presumably not a c2dictionary object
  23331. return;
  23332. var o = d["data"];
  23333. if (mode_ === 0 && !is_arcade) // 'set' mode: must clear webstorage first
  23334. localStorage.clear();
  23335. var p;
  23336. for (p in o)
  23337. {
  23338. if (o.hasOwnProperty(p))
  23339. {
  23340. try {
  23341. localStorage.setItem(prefix + p, o[p]);
  23342. }
  23343. catch (e)
  23344. {
  23345. this.runtime.trigger(cr.plugins_.WebStorage.prototype.cnds.OnQuotaExceeded, this);
  23346. return;
  23347. }
  23348. }
  23349. }
  23350. };
  23351. pluginProto.acts = new Acts();
  23352. function Exps() {};
  23353. Exps.prototype.LocalValue = function(ret,key)
  23354. {
  23355. if (!isSupported)
  23356. {
  23357. ret.set_string("");
  23358. return;
  23359. }
  23360. ret.set_string(localStorage.getItem(prefix + key) || "");
  23361. };
  23362. Exps.prototype.SessionValue = function(ret,key)
  23363. {
  23364. if (!isSupported)
  23365. {
  23366. ret.set_string("");
  23367. return;
  23368. }
  23369. ret.set_string(sessionStorage.getItem(prefix + key) || "");
  23370. };
  23371. Exps.prototype.LocalCount = function(ret)
  23372. {
  23373. if (!isSupported)
  23374. {
  23375. ret.set_int(0);
  23376. return;
  23377. }
  23378. ret.set_int(is_arcade ? 0 : localStorage.length);
  23379. };
  23380. Exps.prototype.SessionCount = function(ret)
  23381. {
  23382. if (!isSupported)
  23383. {
  23384. ret.set_int(0);
  23385. return;
  23386. }
  23387. ret.set_int(is_arcade ? 0 : sessionStorage.length);
  23388. };
  23389. Exps.prototype.LocalAt = function(ret,n)
  23390. {
  23391. if (is_arcade || !isSupported)
  23392. ret.set_string("");
  23393. else
  23394. ret.set_string(localStorage.getItem(localStorage.key(n)) || "");
  23395. };
  23396. Exps.prototype.SessionAt = function(ret,n)
  23397. {
  23398. if (is_arcade || !isSupported)
  23399. ret.set_string("");
  23400. else
  23401. ret.set_string(sessionStorage.getItem(sessionStorage.key(n)) || "");
  23402. };
  23403. Exps.prototype.LocalKeyAt = function(ret,n)
  23404. {
  23405. if (is_arcade || !isSupported)
  23406. ret.set_string("");
  23407. else
  23408. ret.set_string(localStorage.key(n) || "");
  23409. };
  23410. Exps.prototype.SessionKeyAt = function(ret,n)
  23411. {
  23412. if (is_arcade || !isSupported)
  23413. ret.set_string("");
  23414. else
  23415. ret.set_string(sessionStorage.key(n) || "");
  23416. };
  23417. Exps.prototype.AsJSON = function (ret)
  23418. {
  23419. if (!isSupported)
  23420. {
  23421. ret.set_string("");
  23422. return;
  23423. }
  23424. var o = {}, i, len, k;
  23425. for (i = 0, len = localStorage.length; i < len; i++)
  23426. {
  23427. k = localStorage.key(i);
  23428. if (is_arcade)
  23429. {
  23430. if (k.substr(0, prefix.length) === prefix)
  23431. {
  23432. o[k.substr(prefix.length)] = localStorage.getItem(k);
  23433. }
  23434. }
  23435. else
  23436. o[k] = localStorage.getItem(k);
  23437. }
  23438. ret.set_string(JSON.stringify({
  23439. "c2dictionary": true,
  23440. "data": o
  23441. }));
  23442. };
  23443. pluginProto.exps = new Exps();
  23444. }());
  23445. ;
  23446. ;
  23447. cr.behaviors.Anchor = function(runtime)
  23448. {
  23449. this.runtime = runtime;
  23450. };
  23451. (function ()
  23452. {
  23453. var behaviorProto = cr.behaviors.Anchor.prototype;
  23454. behaviorProto.Type = function(behavior, objtype)
  23455. {
  23456. this.behavior = behavior;
  23457. this.objtype = objtype;
  23458. this.runtime = behavior.runtime;
  23459. };
  23460. var behtypeProto = behaviorProto.Type.prototype;
  23461. behtypeProto.onCreate = function()
  23462. {
  23463. };
  23464. behaviorProto.Instance = function(type, inst)
  23465. {
  23466. this.type = type;
  23467. this.behavior = type.behavior;
  23468. this.inst = inst; // associated object instance to modify
  23469. this.runtime = type.runtime;
  23470. };
  23471. var behinstProto = behaviorProto.Instance.prototype;
  23472. behinstProto.onCreate = function()
  23473. {
  23474. this.anch_left = this.properties[0]; // 0 = left, 1 = right, 2 = none
  23475. this.anch_top = this.properties[1]; // 0 = top, 1 = bottom, 2 = none
  23476. this.anch_right = this.properties[2]; // 0 = none, 1 = right
  23477. this.anch_bottom = this.properties[3]; // 0 = none, 1 = bottom
  23478. this.inst.update_bbox();
  23479. this.xleft = this.inst.bbox.left;
  23480. this.ytop = this.inst.bbox.top;
  23481. this.xright = this.runtime.original_width - this.inst.bbox.left;
  23482. this.ybottom = this.runtime.original_height - this.inst.bbox.top;
  23483. this.rdiff = this.runtime.original_width - this.inst.bbox.right;
  23484. this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
  23485. this.enabled = (this.properties[4] !== 0);
  23486. };
  23487. behinstProto.saveToJSON = function ()
  23488. {
  23489. return {
  23490. "xleft": this.xleft,
  23491. "ytop": this.ytop,
  23492. "xright": this.xright,
  23493. "ybottom": this.ybottom,
  23494. "rdiff": this.rdiff,
  23495. "bdiff": this.bdiff,
  23496. "enabled": this.enabled
  23497. };
  23498. };
  23499. behinstProto.loadFromJSON = function (o)
  23500. {
  23501. this.xleft = o["xleft"];
  23502. this.ytop = o["ytop"];
  23503. this.xright = o["xright"];
  23504. this.ybottom = o["ybottom"];
  23505. this.rdiff = o["rdiff"];
  23506. this.bdiff = o["bdiff"];
  23507. this.enabled = o["enabled"];
  23508. };
  23509. behinstProto.tick = function ()
  23510. {
  23511. if (!this.enabled)
  23512. return;
  23513. var n;
  23514. var layer = this.inst.layer;
  23515. var inst = this.inst;
  23516. var bbox = this.inst.bbox;
  23517. if (this.anch_left === 0)
  23518. {
  23519. inst.update_bbox();
  23520. n = (layer.viewLeft + this.xleft) - bbox.left;
  23521. if (n !== 0)
  23522. {
  23523. inst.x += n;
  23524. inst.set_bbox_changed();
  23525. }
  23526. }
  23527. else if (this.anch_left === 1)
  23528. {
  23529. inst.update_bbox();
  23530. n = (layer.viewRight - this.xright) - bbox.left;
  23531. if (n !== 0)
  23532. {
  23533. inst.x += n;
  23534. inst.set_bbox_changed();
  23535. }
  23536. }
  23537. if (this.anch_top === 0)
  23538. {
  23539. inst.update_bbox();
  23540. n = (layer.viewTop + this.ytop) - bbox.top;
  23541. if (n !== 0)
  23542. {
  23543. inst.y += n;
  23544. inst.set_bbox_changed();
  23545. }
  23546. }
  23547. else if (this.anch_top === 1)
  23548. {
  23549. inst.update_bbox();
  23550. n = (layer.viewBottom - this.ybottom) - bbox.top;
  23551. if (n !== 0)
  23552. {
  23553. inst.y += n;
  23554. inst.set_bbox_changed();
  23555. }
  23556. }
  23557. if (this.anch_right === 1)
  23558. {
  23559. inst.update_bbox();
  23560. n = (layer.viewRight - this.rdiff) - bbox.right;
  23561. if (n !== 0)
  23562. {
  23563. inst.width += n;
  23564. if (inst.width < 0)
  23565. inst.width = 0;
  23566. inst.set_bbox_changed();
  23567. }
  23568. }
  23569. if (this.anch_bottom === 1)
  23570. {
  23571. inst.update_bbox();
  23572. n = (layer.viewBottom - this.bdiff) - bbox.bottom;
  23573. if (n !== 0)
  23574. {
  23575. inst.height += n;
  23576. if (inst.height < 0)
  23577. inst.height = 0;
  23578. inst.set_bbox_changed();
  23579. }
  23580. }
  23581. };
  23582. function Cnds() {};
  23583. behaviorProto.cnds = new Cnds();
  23584. function Acts() {};
  23585. Acts.prototype.SetEnabled = function (e)
  23586. {
  23587. if (this.enabled && e === 0)
  23588. this.enabled = false;
  23589. else if (!this.enabled && e !== 0)
  23590. {
  23591. this.inst.update_bbox();
  23592. this.xleft = this.inst.bbox.left;
  23593. this.ytop = this.inst.bbox.top;
  23594. this.xright = this.runtime.original_width - this.inst.bbox.left;
  23595. this.ybottom = this.runtime.original_height - this.inst.bbox.top;
  23596. this.rdiff = this.runtime.original_width - this.inst.bbox.right;
  23597. this.bdiff = this.runtime.original_height - this.inst.bbox.bottom;
  23598. this.enabled = true;
  23599. }
  23600. };
  23601. behaviorProto.acts = new Acts();
  23602. function Exps() {};
  23603. behaviorProto.exps = new Exps();
  23604. }());
  23605. ;
  23606. ;
  23607. cr.behaviors.Pin = function(runtime)
  23608. {
  23609. this.runtime = runtime;
  23610. };
  23611. (function ()
  23612. {
  23613. var behaviorProto = cr.behaviors.Pin.prototype;
  23614. behaviorProto.Type = function(behavior, objtype)
  23615. {
  23616. this.behavior = behavior;
  23617. this.objtype = objtype;
  23618. this.runtime = behavior.runtime;
  23619. };
  23620. var behtypeProto = behaviorProto.Type.prototype;
  23621. behtypeProto.onCreate = function()
  23622. {
  23623. };
  23624. behaviorProto.Instance = function(type, inst)
  23625. {
  23626. this.type = type;
  23627. this.behavior = type.behavior;
  23628. this.inst = inst; // associated object instance to modify
  23629. this.runtime = type.runtime;
  23630. };
  23631. var behinstProto = behaviorProto.Instance.prototype;
  23632. behinstProto.onCreate = function()
  23633. {
  23634. this.pinObject = null;
  23635. this.pinObjectUid = -1; // for loading
  23636. this.pinAngle = 0;
  23637. this.pinDist = 0;
  23638. this.myStartAngle = 0;
  23639. this.theirStartAngle = 0;
  23640. this.lastKnownAngle = 0;
  23641. this.mode = 0; // 0 = position & angle; 1 = position; 2 = angle; 3 = rope; 4 = bar
  23642. var self = this;
  23643. if (!this.recycled)
  23644. {
  23645. this.myDestroyCallback = (function(inst) {
  23646. self.onInstanceDestroyed(inst);
  23647. });
  23648. }
  23649. this.runtime.addDestroyCallback(this.myDestroyCallback);
  23650. };
  23651. behinstProto.saveToJSON = function ()
  23652. {
  23653. return {
  23654. "uid": this.pinObject ? this.pinObject.uid : -1,
  23655. "pa": this.pinAngle,
  23656. "pd": this.pinDist,
  23657. "msa": this.myStartAngle,
  23658. "tsa": this.theirStartAngle,
  23659. "lka": this.lastKnownAngle,
  23660. "m": this.mode
  23661. };
  23662. };
  23663. behinstProto.loadFromJSON = function (o)
  23664. {
  23665. this.pinObjectUid = o["uid"]; // wait until afterLoad to look up
  23666. this.pinAngle = o["pa"];
  23667. this.pinDist = o["pd"];
  23668. this.myStartAngle = o["msa"];
  23669. this.theirStartAngle = o["tsa"];
  23670. this.lastKnownAngle = o["lka"];
  23671. this.mode = o["m"];
  23672. };
  23673. behinstProto.afterLoad = function ()
  23674. {
  23675. if (this.pinObjectUid === -1)
  23676. this.pinObject = null;
  23677. else
  23678. {
  23679. this.pinObject = this.runtime.getObjectByUID(this.pinObjectUid);
  23680. ;
  23681. }
  23682. this.pinObjectUid = -1;
  23683. };
  23684. behinstProto.onInstanceDestroyed = function (inst)
  23685. {
  23686. if (this.pinObject == inst)
  23687. this.pinObject = null;
  23688. };
  23689. behinstProto.onDestroy = function()
  23690. {
  23691. this.pinObject = null;
  23692. this.runtime.removeDestroyCallback(this.myDestroyCallback);
  23693. };
  23694. behinstProto.tick = function ()
  23695. {
  23696. };
  23697. behinstProto.tick2 = function ()
  23698. {
  23699. if (!this.pinObject)
  23700. return;
  23701. if (this.lastKnownAngle !== this.inst.angle)
  23702. this.myStartAngle = cr.clamp_angle(this.myStartAngle + (this.inst.angle - this.lastKnownAngle));
  23703. var newx = this.inst.x;
  23704. var newy = this.inst.y;
  23705. if (this.mode === 3 || this.mode === 4) // rope mode or bar mode
  23706. {
  23707. var dist = cr.distanceTo(this.inst.x, this.inst.y, this.pinObject.x, this.pinObject.y);
  23708. if ((dist > this.pinDist) || (this.mode === 4 && dist < this.pinDist))
  23709. {
  23710. var a = cr.angleTo(this.pinObject.x, this.pinObject.y, this.inst.x, this.inst.y);
  23711. newx = this.pinObject.x + Math.cos(a) * this.pinDist;
  23712. newy = this.pinObject.y + Math.sin(a) * this.pinDist;
  23713. }
  23714. }
  23715. else
  23716. {
  23717. newx = this.pinObject.x + Math.cos(this.pinObject.angle + this.pinAngle) * this.pinDist;
  23718. newy = this.pinObject.y + Math.sin(this.pinObject.angle + this.pinAngle) * this.pinDist;
  23719. }
  23720. var newangle = cr.clamp_angle(this.myStartAngle + (this.pinObject.angle - this.theirStartAngle));
  23721. this.lastKnownAngle = newangle;
  23722. if ((this.mode === 0 || this.mode === 1 || this.mode === 3 || this.mode === 4)
  23723. && (this.inst.x !== newx || this.inst.y !== newy))
  23724. {
  23725. this.inst.x = newx;
  23726. this.inst.y = newy;
  23727. this.inst.set_bbox_changed();
  23728. }
  23729. if ((this.mode === 0 || this.mode === 2) && (this.inst.angle !== newangle))
  23730. {
  23731. this.inst.angle = newangle;
  23732. this.inst.set_bbox_changed();
  23733. }
  23734. };
  23735. function Cnds() {};
  23736. Cnds.prototype.IsPinned = function ()
  23737. {
  23738. return !!this.pinObject;
  23739. };
  23740. behaviorProto.cnds = new Cnds();
  23741. function Acts() {};
  23742. Acts.prototype.Pin = function (obj, mode_)
  23743. {
  23744. if (!obj)
  23745. return;
  23746. var otherinst = obj.getFirstPicked(this.inst);
  23747. if (!otherinst)
  23748. return;
  23749. this.pinObject = otherinst;
  23750. this.pinAngle = cr.angleTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y) - otherinst.angle;
  23751. this.pinDist = cr.distanceTo(otherinst.x, otherinst.y, this.inst.x, this.inst.y);
  23752. this.myStartAngle = this.inst.angle;
  23753. this.lastKnownAngle = this.inst.angle;
  23754. this.theirStartAngle = otherinst.angle;
  23755. this.mode = mode_;
  23756. };
  23757. Acts.prototype.Unpin = function ()
  23758. {
  23759. this.pinObject = null;
  23760. };
  23761. behaviorProto.acts = new Acts();
  23762. function Exps() {};
  23763. Exps.prototype.PinnedUID = function (ret)
  23764. {
  23765. ret.set_int(this.pinObject ? this.pinObject.uid : -1);
  23766. };
  23767. behaviorProto.exps = new Exps();
  23768. }());
  23769. var easeOutBounceArray = [];
  23770. var easeInElasticArray = [];
  23771. var easeOutElasticArray = [];
  23772. var easeInOutElasticArray = [];
  23773. var easeInCircle = [];
  23774. var easeOutCircle = [];
  23775. var easeInOutCircle = [];
  23776. var easeOutBack = [];
  23777. var easeInOutBack = [];
  23778. var litetween_precision = 10000;
  23779. var updateLimit = 0; //0.0165;
  23780. function easeOutBounce(t,b,c,d) {
  23781. if ((t/=d) < (1/2.75)) {
  23782. return c*(7.5625*t*t) + b;
  23783. } else if (t < (2/2.75)) {
  23784. return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
  23785. } else if (t < (2.5/2.75)) {
  23786. return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
  23787. } else {
  23788. return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
  23789. }
  23790. }
  23791. function integerize(t, d)
  23792. {
  23793. return Math.round(t/d*litetween_precision);
  23794. }
  23795. function easeFunc(easing, t, b, c, d, flip)
  23796. {
  23797. var ret_ease = 0;
  23798. switch (easing) {
  23799. case 0: // linear
  23800. ret_ease = c*t/d + b;
  23801. break;
  23802. case 1: // easeInQuad
  23803. ret_ease = c*(t/=d)*t + b;
  23804. break;
  23805. case 2: // easeOutQuad
  23806. ret_ease = -c *(t/=d)*(t-2) + b;
  23807. break;
  23808. case 3: // easeInOutQuad
  23809. if ((t/=d/2) < 1)
  23810. ret_ease = c/2*t*t + b
  23811. else
  23812. ret_ease = -c/2 * ((--t)*(t-2) - 1) + b;
  23813. break;
  23814. case 4: // easeInCubic
  23815. ret_ease = c*(t/=d)*t*t + b;
  23816. break;
  23817. case 5: // easeOutCubic
  23818. ret_ease = c*((t=t/d-1)*t*t + 1) + b;
  23819. break;
  23820. case 6: // easeInOutCubic
  23821. if ((t/=d/2) < 1)
  23822. ret_ease = c/2*t*t*t + b
  23823. else
  23824. ret_ease = c/2*((t-=2)*t*t + 2) + b;
  23825. break;
  23826. case 7: // easeInQuart
  23827. ret_ease = c*(t/=d)*t*t*t + b;
  23828. break;
  23829. case 8: // easeOutQuart
  23830. ret_ease = -c * ((t=t/d-1)*t*t*t - 1) + b;
  23831. break;
  23832. case 9: // easeInOutQuart
  23833. if ((t/=d/2) < 1)
  23834. ret_ease = c/2*t*t*t*t + b
  23835. else
  23836. ret_ease = -c/2 * ((t-=2)*t*t*t - 2) + b;
  23837. break;
  23838. case 10: // easeInQuint
  23839. ret_ease = c*(t/=d)*t*t*t*t + b;
  23840. break;
  23841. case 11: // easeOutQuint
  23842. ret_ease = c*((t=t/d-1)*t*t*t*t + 1) + b;
  23843. break;
  23844. case 12: // easeInOutQuint
  23845. if ((t/=d/2) < 1)
  23846. ret_ease = c/2*t*t*t*t*t + b
  23847. else
  23848. ret_ease = c/2*((t-=2)*t*t*t*t + 2) + b;
  23849. break;
  23850. case 13: // easeInCircle
  23851. ret_ease = easeInCircle[integerize(t,d)];
  23852. break;
  23853. case 14: // easeOutCircle
  23854. ret_ease = easeOutCircle[integerize(t,d)];
  23855. break;
  23856. case 15: // easeInOutCircle
  23857. ret_ease = easeInOutCircle[integerize(t,d)];
  23858. break;
  23859. case 16: // easeInBack
  23860. var s = 0;
  23861. if (s==0) s = 1.70158;
  23862. ret_ease = c*(t/=d)*t*((s+1)*t - s) + b;
  23863. break;
  23864. case 17: // easeOutBack
  23865. ret_ease = easeOutBack[integerize(t,d)];
  23866. break;
  23867. case 18: // easeInOutBack
  23868. ret_ease = easeInOutBack[integerize(t,d)];
  23869. break;
  23870. case 19: //easeInElastic
  23871. ret_ease = easeInElasticArray[integerize(t, d)];
  23872. break;
  23873. case 20: //easeOutElastic
  23874. ret_ease = easeOutElasticArray[integerize(t,d)];
  23875. break;
  23876. case 21: //easeInOutElastic
  23877. ret_ease = easeInOutElasticArray[integerize(t,d)];
  23878. break;
  23879. case 22: //easeInBounce
  23880. ret_ease = c - easeOutBounceArray[integerize(d-t, d)] + b;
  23881. break;
  23882. case 23: //easeOutBounce
  23883. ret_ease = easeOutBounceArray[integerize(t, d)];
  23884. break;
  23885. case 24: //easeInOutBounce
  23886. if (t < d/2)
  23887. ret_ease = (c - easeOutBounceArray[integerize(d-(t*2), d)] + b) * 0.5 +b;
  23888. else
  23889. ret_ease = easeOutBounceArray[integerize(t*2-d, d)] * .5 + c*.5 + b;
  23890. break;
  23891. case 25: //easeInSmoothstep
  23892. var mt = (t/d) / 2;
  23893. ret_ease = (2*(mt * mt * (3 - 2*mt)));
  23894. break;
  23895. case 26: //easeOutSmoothstep
  23896. var mt = ((t/d) + 1) / 2;
  23897. ret_ease = ((2*(mt * mt * (3 - 2*mt))) - 1);
  23898. break;
  23899. case 27: //easeInOutSmoothstep
  23900. var mt = (t / d);
  23901. ret_ease = (mt * mt * (3 - 2*mt));
  23902. break;
  23903. };
  23904. if (flip)
  23905. return (c - b) - ret_ease
  23906. else
  23907. return ret_ease;
  23908. };
  23909. (function preCalculateArray() {
  23910. var d = 1.0;
  23911. var b = 0.0;
  23912. var c = 1.0;
  23913. var result = 0.0;
  23914. var a = 0;
  23915. var p = 0;
  23916. var t = 0;
  23917. var s = 0;
  23918. for (var ti = 0; ti <= litetween_precision; ti++) {
  23919. t = ti/litetween_precision;
  23920. if ((t/=d) < (1/2.75)) {
  23921. result = c*(7.5625*t*t) + b;
  23922. } else if (t < (2/2.75)) {
  23923. result = c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
  23924. } else if (t < (2.5/2.75)) {
  23925. result = c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
  23926. } else {
  23927. result = c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
  23928. }
  23929. easeOutBounceArray[ti] = easeOutBounce(ti/litetween_precision, b, c, d);
  23930. t = ti/litetween_precision; a = 0; p = 0;
  23931. if (t==0) result = b; if ((t/=d)==1) result = b+c;
  23932. if (p==0) p=d*.3; if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
  23933. else var s = p/(2*Math.PI) * Math.asin (c/a);
  23934. result = -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  23935. easeInElasticArray[ti] = result;
  23936. t = ti/litetween_precision; a = 0; p = 0;
  23937. if (t==0) result= b; if ((t/=d)==1) result= b+c; if (p == 0) p=d*.3;
  23938. if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
  23939. else var s = p/(2*Math.PI) * Math.asin (c/a);
  23940. result= (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
  23941. easeOutElasticArray[ti] = result;
  23942. t = ti/litetween_precision; a = 0; p = 0;
  23943. if (t==0) result = b;
  23944. if ((t/=d/2)==2) result = b+c;
  23945. if (p==0) p=d*(.3*1.5);
  23946. if (a==0 || a < Math.abs(c)) { a=c; var s=p/4; }
  23947. else var s = p/(2*Math.PI) * Math.asin (c/a);
  23948. if (t < 1)
  23949. result = -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b
  23950. else
  23951. result = a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  23952. easeInOutElasticArray[ti] = result;
  23953. t = ti/litetween_precision; easeInCircle[ti] = -(Math.sqrt(1-t*t) - 1);
  23954. t = ti/litetween_precision; easeOutCircle[ti] = Math.sqrt(1 - ((t-1)*(t-1)));
  23955. t = ti/litetween_precision;
  23956. if ((t/=d/2) < 1) result = -c/2 * (Math.sqrt(1 - t*t) - 1) + b
  23957. else result = c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
  23958. easeInOutCircle[ti] = result;
  23959. t = ti/litetween_precision; s = 0;
  23960. if (s==0) s = 1.70158;
  23961. result = c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  23962. easeOutBack[ti] = result;
  23963. t = ti/litetween_precision; s = 0; if (s==0) s = 1.70158;
  23964. if ((t/=d/2) < 1)
  23965. result = c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b
  23966. else
  23967. result = c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  23968. easeInOutBack[ti] = result;
  23969. }
  23970. }())
  23971. var TweenObject = function()
  23972. {
  23973. var constructor = function (tname, tweened, easefunc, initial, target, duration, enforce)
  23974. {
  23975. this.name = tname;
  23976. this.value = 0;
  23977. this.setInitial(initial);
  23978. this.setTarget(target);
  23979. this.easefunc = easefunc;
  23980. this.tweened = tweened;
  23981. this.duration = duration;
  23982. this.progress = 0;
  23983. this.state = 0;
  23984. this.onStart = false;
  23985. this.onEnd = false;
  23986. this.onReverseStart = false;
  23987. this.onReverseEnd = false;
  23988. this.lastKnownValue = 0;
  23989. this.lastKnownValue2 = 0;
  23990. this.enforce = enforce;
  23991. this.pingpong = 1.0;
  23992. this.flipEase = false;
  23993. }
  23994. return constructor;
  23995. }();
  23996. (function () {
  23997. TweenObject.prototype = {
  23998. };
  23999. TweenObject.prototype.flipTarget = function ()
  24000. {
  24001. var x1 = this.initialparam1;
  24002. var x2 = this.initialparam2;
  24003. this.initialparam1 = this.targetparam1;
  24004. this.initialparam2 = this.targetparam2;
  24005. this.targetparam1 = x1;
  24006. this.targetparam2 = x2;
  24007. this.lastKnownValue = 0;
  24008. this.lastKnownValue2 = 0;
  24009. }
  24010. TweenObject.prototype.setInitial = function (initial)
  24011. {
  24012. this.initialparam1 = parseFloat(initial.split(",")[0]);
  24013. this.initialparam2 = parseFloat(initial.split(",")[1]);
  24014. this.lastKnownValue = 0;
  24015. this.lastKnownValue2 = 0;
  24016. }
  24017. TweenObject.prototype.setTarget = function (target)
  24018. {
  24019. this.targetparam1 = parseFloat(target.split(",")[0]);
  24020. this.targetparam2 = parseFloat(target.split(",")[1]);
  24021. if (isNaN(this.targetparam2)) this.targetparam2 = this.targetparam1;
  24022. }
  24023. TweenObject.prototype.OnTick = function(dt)
  24024. {
  24025. if (this.state === 0) return -1.0;
  24026. if (this.state === 1)
  24027. this.progress += dt;
  24028. if (this.state === 2)
  24029. this.progress -= dt;
  24030. if (this.state === 3) {
  24031. this.state = 0;
  24032. }
  24033. if ((this.state === 4) || (this.state === 6)) {
  24034. this.progress += dt * this.pingpong;
  24035. }
  24036. if (this.state === 5) {
  24037. this.progress += dt * this.pingpong;
  24038. }
  24039. if (this.progress < 0) {
  24040. this.progress = 0;
  24041. if (this.state === 4) {
  24042. this.pingpong = 1;
  24043. } else if (this.state === 6) {
  24044. this.pingpong = 1;
  24045. this.flipEase = false;
  24046. } else {
  24047. this.state = 0;
  24048. }
  24049. this.onReverseEnd = true;
  24050. return 0.0;
  24051. } else if (this.progress > this.duration) {
  24052. this.progress = this.duration;
  24053. if (this.state === 4) {
  24054. this.pingpong = -1;
  24055. } else if (this.state === 6) {
  24056. this.pingpong = -1;
  24057. this.flipEase = true;
  24058. } else if (this.state === 5) {
  24059. this.progress = 0.0;
  24060. } else {
  24061. this.state = 0;
  24062. }
  24063. this.onEnd = true;
  24064. return 1.0;
  24065. } else {
  24066. if (this.flipEase) {
  24067. var factor = easeFunc(this.easefunc, this.duration - this.progress, 0, 1, this.duration, this.flipEase);
  24068. } else {
  24069. var factor = easeFunc(this.easefunc, this.progress, 0, 1, this.duration, this.flipEase);
  24070. }
  24071. return factor;
  24072. }
  24073. };
  24074. }());
  24075. ;
  24076. ;
  24077. function trim (str) {
  24078. return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  24079. }
  24080. cr.behaviors.lunarray_LiteTween = function(runtime)
  24081. {
  24082. this.runtime = runtime;
  24083. };
  24084. (function ()
  24085. {
  24086. var behaviorProto = cr.behaviors.lunarray_LiteTween.prototype;
  24087. behaviorProto.Type = function(behavior, objtype)
  24088. {
  24089. this.behavior = behavior;
  24090. this.objtype = objtype;
  24091. this.runtime = behavior.runtime;
  24092. };
  24093. var behtypeProto = behaviorProto.Type.prototype;
  24094. behtypeProto.onCreate = function()
  24095. {
  24096. };
  24097. behaviorProto.Instance = function(type, inst)
  24098. {
  24099. this.type = type;
  24100. this.behavior = type.behavior;
  24101. this.inst = inst; // associated object instance to modify
  24102. this.runtime = type.runtime;
  24103. this.i = 0; // progress
  24104. };
  24105. var behinstProto = behaviorProto.Instance.prototype;
  24106. behinstProto.onCreate = function()
  24107. {
  24108. this.playmode = this.properties[0];
  24109. this.active = (this.playmode == 1) || (this.playmode == 2) || (this.playmode == 3) || (this.playmode == 4);
  24110. this.tweened = this.properties[1]; // 0=Position|1=Size|2=Width|3=Height|4=Angle|5=Opacity|6=Value only|7=Horizontal|8=Vertical|9=Scale
  24111. this.easing = this.properties[2];
  24112. this.target = this.properties[3];
  24113. this.targetmode = this.properties[4];
  24114. this.useCurrent = false;
  24115. if (this.targetmode === 1) this.target = "relative("+this.target+")";
  24116. this.duration = this.properties[5];
  24117. this.enforce = (this.properties[6] === 1);
  24118. this.value = 0;
  24119. this.tween_list = {};
  24120. this.addToTweenList("default", this.tweened, this.easing, "current", this.target, this.duration, this.enforce);
  24121. if (this.properties[0] === 1) this.startTween(0)
  24122. if (this.properties[0] === 2) this.startTween(2)
  24123. if (this.properties[0] === 3) this.startTween(3)
  24124. if (this.properties[0] === 4) this.startTween(4)
  24125. };
  24126. behinstProto.parseCurrent = function(tweened, parseText)
  24127. {
  24128. if (parseText === undefined) parseText = "current";
  24129. var parsed = trim(parseText);
  24130. parseText = trim(parseText);
  24131. var value = this.value;
  24132. if (parseText === "current") {
  24133. switch (tweened) {
  24134. case 0: parsed = this.inst.x + "," + this.inst.y; break;
  24135. case 1: parsed = this.inst.width + "," + this.inst.height; break;
  24136. case 2: parsed = this.inst.width + "," + this.inst.height; break;
  24137. case 3: parsed = this.inst.width + "," + this.inst.height; break;
  24138. case 4: parsed = cr.to_degrees(this.inst.angle) + "," + cr.to_degrees(this.inst.angle); break;
  24139. case 5: parsed = (this.inst.opacity*100) + "," + (this.inst.opacity*100); break;
  24140. case 6: parsed = value + "," + value; break;
  24141. case 7: parsed = this.inst.x + "," + this.inst.y; break;
  24142. case 8: parsed = this.inst.x + "," + this.inst.y; break;
  24143. case 9:
  24144. if (this.inst.curFrame !== undefined)
  24145. parsed = (this.inst.width/this.inst.curFrame.width) + "," +(this.inst.height/this.inst.curFrame.height)
  24146. else
  24147. parsed = "1,1";
  24148. break;
  24149. default: break;
  24150. }
  24151. }
  24152. if (parseText.substring(0,8) === "relative") {
  24153. var param1 = parseText.match(/\((.*?)\)/);
  24154. if (param1) {
  24155. var relativex = parseFloat(param1[1].split(",")[0]);
  24156. var relativey = parseFloat(param1[1].split(",")[1]);
  24157. }
  24158. if (isNaN(relativex)) relativex = 0;
  24159. if (isNaN(relativey)) relativey = 0;
  24160. switch (tweened) {
  24161. case 0: parsed = (this.inst.x+relativex) + "," + (this.inst.y+relativey); break;
  24162. case 1: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
  24163. case 2: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
  24164. case 3: parsed = (this.inst.width+relativex) + "," + (this.inst.height+relativey); break;
  24165. case 4: parsed = (cr.to_degrees(this.inst.angle)+relativex) + "," + (cr.to_degrees(this.inst.angle)+relativey); break;
  24166. case 5: parsed = (this.inst.opacity*100+relativex) + "," + (this.inst.opacity*100+relativey); break;
  24167. case 6: parsed = value+relativex + "," + value+relativex; break;
  24168. case 7: parsed = (this.inst.x+relativex) + "," + (this.inst.y); break;
  24169. case 8: parsed = (this.inst.x) + "," + (this.inst.y+relativex); break;
  24170. case 9: parsed = (relativex) + "," + (relativey); break;
  24171. default: break;
  24172. }
  24173. }
  24174. return parsed;
  24175. };
  24176. behinstProto.addToTweenList = function(tname, tweened, easing, init, targ, duration, enforce)
  24177. {
  24178. init = this.parseCurrent(tweened, init);
  24179. targ = this.parseCurrent(tweened, targ);
  24180. if (this.tween_list[tname] !== undefined) {
  24181. delete this.tween_list[tname]
  24182. }
  24183. this.tween_list[tname] = new TweenObject(tname, tweened, easing, init, targ, duration, enforce);
  24184. this.tween_list[tname].dt = 0;
  24185. };
  24186. behinstProto.saveToJSON = function ()
  24187. {
  24188. };
  24189. behinstProto.loadFromJSON = function (o)
  24190. {
  24191. };
  24192. behinstProto.setProgressTo = function (mark)
  24193. {
  24194. if (mark > 1.0) mark = 1.0;
  24195. if (mark < 0.0) mark = 0.0;
  24196. for (var i in this.tween_list) {
  24197. var inst = this.tween_list[i];
  24198. inst.lastKnownValue = 0;
  24199. inst.lastKnownValue2 = 0;
  24200. inst.state = 3;
  24201. inst.progress = mark * inst.duration;
  24202. var factor = inst.OnTick(0);
  24203. this.updateTween(inst, factor);
  24204. }
  24205. }
  24206. behinstProto.startTween = function (startMode)
  24207. {
  24208. for (var i in this.tween_list) {
  24209. var inst = this.tween_list[i];
  24210. if (this.useCurrent) {
  24211. var init = this.parseCurrent(inst.tweened, "current");
  24212. var target = this.parseCurrent(inst.tweened, this.target);
  24213. inst.setInitial(init);
  24214. inst.setTarget(target);
  24215. }
  24216. if (startMode === 0) {
  24217. inst.progress = 0.000001;
  24218. inst.lastKnownValue = 0;
  24219. inst.lastKnownValue2 = 0;
  24220. inst.onStart = true;
  24221. inst.state = 1;
  24222. }
  24223. if (startMode === 1) {
  24224. inst.state = 1;
  24225. }
  24226. if ((startMode === 2) || (startMode === 4)) {
  24227. inst.progress = 0.000001;
  24228. inst.lastKnownValue = 0;
  24229. inst.lastKnownValue2 = 0;
  24230. inst.onStart = true;
  24231. if (startMode == 2) inst.state = 4; //state ping pong
  24232. if (startMode == 4) inst.state = 6; //state flip flop
  24233. }
  24234. if (startMode === 3) {
  24235. inst.progress = 0.000001;
  24236. inst.lastKnownValue = 0;
  24237. inst.lastKnownValue2 = 0;
  24238. inst.onStart = true;
  24239. inst.state = 5;
  24240. }
  24241. }
  24242. }
  24243. behinstProto.stopTween = function (stopMode)
  24244. {
  24245. for (var i in this.tween_list) {
  24246. var inst = this.tween_list[i];
  24247. if (stopMode === 1) inst.progress = 0.0;
  24248. if (stopMode === 2) inst.progress = inst.duration;
  24249. inst.state = 3;
  24250. var factor = inst.OnTick(0);
  24251. this.updateTween(inst, factor);
  24252. }
  24253. }
  24254. behinstProto.reverseTween = function(reverseMode)
  24255. {
  24256. for (var i in this.tween_list) {
  24257. var inst = this.tween_list[i];
  24258. if (reverseMode === 1) {
  24259. inst.progress = inst.duration;
  24260. inst.lastKnownValue = 0;
  24261. inst.lastKnownValue2 = 0;
  24262. inst.onReverseStart = true;
  24263. }
  24264. inst.state = 2;
  24265. }
  24266. }
  24267. behinstProto.updateTween = function (inst, factor)
  24268. {
  24269. if (inst.tweened === 0) {
  24270. if (inst.enforce) {
  24271. this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
  24272. this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
  24273. } else {
  24274. this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
  24275. this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
  24276. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24277. inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
  24278. }
  24279. } else if (inst.tweened === 1) {
  24280. if (inst.enforce) {
  24281. this.inst.width = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
  24282. this.inst.height = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
  24283. } else {
  24284. this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
  24285. this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
  24286. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24287. inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
  24288. }
  24289. } else if (inst.tweened === 2) {
  24290. if (inst.enforce) {
  24291. this.inst.width = inst.initialparam1 + ((inst.targetparam1 - inst.initialparam1) * factor);
  24292. } else {
  24293. this.inst.width += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
  24294. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24295. }
  24296. } else if (inst.tweened === 3) {
  24297. if (inst.enforce) {
  24298. this.inst.height = inst.initialparam2 + ((inst.targetparam2 - inst.initialparam2) * factor);
  24299. } else {
  24300. this.inst.height += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
  24301. inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
  24302. }
  24303. } else if (inst.tweened === 4) {
  24304. if (inst.enforce) {
  24305. var tangle = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
  24306. this.inst.angle = cr.clamp_angle(cr.to_radians(tangle));
  24307. } else {
  24308. var tangle = ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
  24309. this.inst.angle = cr.clamp_angle(this.inst.angle + cr.to_radians(tangle));
  24310. inst.lastKnownValue = (inst.targetparam1 - inst.initialparam1) * factor;
  24311. }
  24312. } else if (inst.tweened === 5) {
  24313. if (inst.enforce) {
  24314. this.inst.opacity = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor) / 100;
  24315. } else {
  24316. this.inst.opacity += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue) / 100;
  24317. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24318. }
  24319. } else if (inst.tweened === 6) {
  24320. if (inst.enforce) {
  24321. this.value = (inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor);
  24322. } else {
  24323. this.value += (((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue);
  24324. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24325. }
  24326. } else if (inst.tweened === 7) {
  24327. if (inst.enforce) {
  24328. this.inst.x = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
  24329. } else {
  24330. this.inst.x += ((inst.targetparam1 - inst.initialparam1) * factor) - inst.lastKnownValue;
  24331. inst.lastKnownValue = ((inst.targetparam1 - inst.initialparam1) * factor);
  24332. }
  24333. } else if (inst.tweened === 8) {
  24334. if (inst.enforce) {
  24335. this.inst.y = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
  24336. } else {
  24337. this.inst.y += ((inst.targetparam2 - inst.initialparam2) * factor) - inst.lastKnownValue2;
  24338. inst.lastKnownValue2 = ((inst.targetparam2 - inst.initialparam2) * factor);
  24339. }
  24340. } else if (inst.tweened === 9) {
  24341. var scalex = inst.initialparam1 + (inst.targetparam1 - inst.initialparam1) * factor;
  24342. var scaley = inst.initialparam2 + (inst.targetparam2 - inst.initialparam2) * factor;
  24343. if (this.inst.width < 0) scalex = inst.initialparam1 + (inst.targetparam1 + inst.initialparam1) * -factor;
  24344. if (this.inst.height < 0) scaley = inst.initialparam2 + (inst.targetparam2 + inst.initialparam2) * -factor;
  24345. if (inst.enforce) {
  24346. this.inst.width = this.inst.curFrame.width * scalex;
  24347. this.inst.height = this.inst.curFrame.height * scaley;
  24348. } else {
  24349. if (this.inst.width < 0) {
  24350. this.inst.width = scalex * (this.inst.width / (-1+inst.lastKnownValue));
  24351. inst.lastKnownValue = scalex + 1
  24352. } else {
  24353. this.inst.width = scalex * (this.inst.width / (1+inst.lastKnownValue));
  24354. inst.lastKnownValue = scalex - 1;
  24355. }
  24356. if (this.inst.height < 0) {
  24357. this.inst.height = scaley * (this.inst.height / (-1+inst.lastKnownValue2));
  24358. inst.lastKnownValue2 = scaley + 1
  24359. } else {
  24360. this.inst.height = scaley * (this.inst.height / (1+inst.lastKnownValue2));
  24361. inst.lastKnownValue2 = scaley - 1;
  24362. }
  24363. }
  24364. }
  24365. this.inst.set_bbox_changed();
  24366. }
  24367. behinstProto.tick = function ()
  24368. {
  24369. var dt = this.runtime.getDt(this.inst);
  24370. var inst = this.tween_list["default"];
  24371. if (inst.state !== 0) {
  24372. if (inst.onStart) {
  24373. this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnStart, this.inst);
  24374. inst.onStart = false;
  24375. }
  24376. if (inst.onReverseStart) {
  24377. this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseStart, this.inst);
  24378. inst.onReverseStart = false;
  24379. }
  24380. this.active = (inst.state == 1) || (inst.state == 2) || (inst.state == 4) || (inst.state == 5) || (inst.state == 6);
  24381. var factor = inst.OnTick(dt);
  24382. this.updateTween(inst, factor);
  24383. if (inst.onEnd) {
  24384. this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd, this.inst);
  24385. inst.onEnd = false;
  24386. }
  24387. if (inst.onReverseEnd) {
  24388. this.runtime.trigger(cr.behaviors.lunarray_LiteTween.prototype.cnds.OnReverseEnd, this.inst);
  24389. inst.onReverseEnd = false;
  24390. }
  24391. }
  24392. };
  24393. behaviorProto.cnds = {};
  24394. var cnds = behaviorProto.cnds;
  24395. cnds.IsActive = function ()
  24396. {
  24397. return (this.tween_list["default"].state !== 0);
  24398. };
  24399. cnds.CompareProgress = function (cmp, v)
  24400. {
  24401. var inst = this.tween_list["default"];
  24402. return cr.do_cmp((inst.progress / inst.duration), cmp, v);
  24403. };
  24404. cnds.OnStart = function ()
  24405. {
  24406. if (this.tween_list["default"] === undefined)
  24407. return false;
  24408. return this.tween_list["default"].onStart;
  24409. };
  24410. cnds.OnReverseStart = function ()
  24411. {
  24412. if (this.tween_list["default"] === undefined)
  24413. return false;
  24414. return this.tween_list["default"].onReverseStart;
  24415. };
  24416. cnds.OnEnd = function ()
  24417. {
  24418. if (this.tween_list["default"] === undefined)
  24419. return false;
  24420. return this.tween_list["default"].onEnd;
  24421. };
  24422. cnds.OnReverseEnd = function ()
  24423. {
  24424. if (this.tween_list["default"] === undefined)
  24425. return false;
  24426. return this.tween_list["default"].onReverseEnd;
  24427. };
  24428. behaviorProto.acts = {};
  24429. var acts = behaviorProto.acts;
  24430. acts.Start = function (startmode, current)
  24431. {
  24432. this.useCurrent = (current == 1);
  24433. this.startTween(startmode);
  24434. };
  24435. acts.Stop = function (stopmode)
  24436. {
  24437. this.stopTween(stopmode);
  24438. };
  24439. acts.Reverse = function (revMode)
  24440. {
  24441. this.reverseTween(revMode);
  24442. };
  24443. acts.ProgressTo = function (progress)
  24444. {
  24445. this.setProgressTo(progress);
  24446. };
  24447. acts.SetDuration = function (x)
  24448. {
  24449. if (isNaN(x)) return;
  24450. if (x < 0) return;
  24451. if (this.tween_list["default"] === undefined) return;
  24452. this.tween_list["default"].duration = x;
  24453. };
  24454. acts.SetEnforce = function (x)
  24455. {
  24456. if (this.tween_list["default"] === undefined) return;
  24457. this.tween_list["default"].enforce = (x===1);
  24458. };
  24459. acts.SetInitial = function (x)
  24460. {
  24461. if (this.tween_list["default"] === undefined) return;
  24462. var init = this.parseCurrent(this.tween_list["default"].tweened, x);
  24463. this.tween_list["default"].setInitial(init);
  24464. };
  24465. acts.SetTarget = function (targettype, absrel, x)
  24466. {
  24467. if (this.tween_list["default"] === undefined) return;
  24468. if (isNaN(x)) return;
  24469. var inst = this.tween_list["default"];
  24470. var parsed = x + "";
  24471. this.targetmode = absrel;
  24472. var x1 = "";
  24473. var x2 = "";
  24474. if (absrel === 1) {
  24475. this.target = "relative(" + parsed + ")";
  24476. switch (targettype) {
  24477. case 0: x1 = (this.inst.x + x); x2 = inst.targetparam2; break;
  24478. case 1: x1 = inst.targetparam1; x2 = (this.inst.y + x); break;
  24479. case 2: x1 = "" + cr.to_degrees(this.inst.angle + cr.to_radians(x)); x2 = x1; break; //angle
  24480. case 3: x1 = "" + (this.inst.opacity*100) + x; x2 = x1; break; //opacity
  24481. case 4: x1 = (this.inst.width + x); x2 = inst.targetparam2; break; //width
  24482. case 5: x1 = inst.targetparam1; x2 = (this.inst.height + x); break; //height
  24483. case 6: x1 = x; x2 = x; break; //value
  24484. default: break;
  24485. }
  24486. parsed = x1 + "," + x2;
  24487. } else {
  24488. switch (targettype) {
  24489. case 0: x1 = x; x2 = inst.targetparam2; break;
  24490. case 1: x1 = inst.targetparam1; x2 = x; break;
  24491. case 2: x1 = x; x2 = x; break; //angle
  24492. case 3: x1 = x; x2 = x; break; //opacity
  24493. case 4: x1 = x; x2 = inst.targetparam2; break; //width
  24494. case 5: x1 = inst.targetparam1; x2 = x; break; //height
  24495. case 6: x1 = x; x2 = x; break; //value
  24496. default: break;
  24497. }
  24498. parsed = x1 + "," + x2;
  24499. this.target = parsed;
  24500. }
  24501. var init = this.parseCurrent(this.tween_list["default"].tweened, "current");
  24502. var targ = this.parseCurrent(this.tween_list["default"].tweened, parsed);
  24503. inst.setInitial(init);
  24504. inst.setTarget(targ);
  24505. };
  24506. acts.SetTweenedProperty = function (x)
  24507. {
  24508. if (this.tween_list["default"] === undefined) return;
  24509. this.tween_list["default"].tweened = x;
  24510. };
  24511. acts.SetEasing = function (x)
  24512. {
  24513. if (this.tween_list["default"] === undefined) return;
  24514. this.tween_list["default"].easefunc = x;
  24515. };
  24516. acts.SetValue = function (x)
  24517. {
  24518. var inst = this.tween_list["default"];
  24519. this.value = x;
  24520. if (inst.tweened === 6)
  24521. inst.setInitial( this.parseCurrent(inst.tweened, "current") );
  24522. };
  24523. acts.SetParameter = function (tweened, easefunction, target, duration, enforce)
  24524. {
  24525. if (this.tween_list["default"] === undefined) {
  24526. this.addToTweenList("default", tweened, easefunction, initial, target, duration, enforce, 0);
  24527. } else {
  24528. var inst = this.tween_list["default"];
  24529. inst.tweened = tweened;
  24530. inst.easefunc = easefunction;
  24531. inst.setInitial( this.parseCurrent(tweened, "current") );
  24532. inst.setTarget( this.parseCurrent(tweened, target) );
  24533. inst.duration = duration;
  24534. inst.enforce = (enforce === 1);
  24535. }
  24536. };
  24537. behaviorProto.exps = {};
  24538. var exps = behaviorProto.exps;
  24539. exps.Progress = function (ret)
  24540. {
  24541. var progress = this.tween_list["default"].progress/this.tween_list["default"].duration;
  24542. ret.set_float(progress);
  24543. };
  24544. exps.Duration = function (ret)
  24545. {
  24546. ret.set_float(this.tween_list["default"].duration);
  24547. };
  24548. exps.Target = function (ret)
  24549. {
  24550. var inst = this.tween_list["default"];
  24551. var parsed = "N/A";
  24552. switch (inst.tweened) {
  24553. case 0: parsed = inst.targetparam1; break;
  24554. case 1: parsed = inst.targetparam2; break;
  24555. case 2: parsed = inst.targetparam1; break;
  24556. case 3: parsed = inst.targetparam1; break;
  24557. case 4: parsed = inst.targetparam1; break;
  24558. case 5: parsed = inst.targetparam2; break;
  24559. case 6: parsed = inst.targetparam1; break;
  24560. default: break;
  24561. }
  24562. ret.set_float(parsed);
  24563. };
  24564. exps.Value = function (ret)
  24565. {
  24566. var tval = this.value;
  24567. ret.set_float(tval);
  24568. };
  24569. }());
  24570. cr.getObjectRefTable = function () { return [
  24571. cr.plugins_.Arr,
  24572. cr.plugins_.Browser,
  24573. cr.plugins_.Audio,
  24574. cr.plugins_.Function,
  24575. cr.plugins_.Keyboard,
  24576. cr.plugins_.Mouse,
  24577. cr.plugins_.Rex_ZSorter,
  24578. cr.plugins_.Sprite,
  24579. cr.plugins_.Spritefont2,
  24580. cr.plugins_.Text,
  24581. cr.plugins_.TiledBg,
  24582. cr.plugins_.Touch,
  24583. cr.plugins_.WebStorage,
  24584. cr.behaviors.Anchor,
  24585. cr.behaviors.lunarray_LiteTween,
  24586. cr.behaviors.Pin,
  24587. cr.system_object.prototype.cnds.IsGroupActive,
  24588. cr.plugins_.Touch.prototype.cnds.OnTouchEnd,
  24589. cr.plugins_.Sprite.prototype.acts.SetAnimFrame,
  24590. cr.system_object.prototype.cnds.ForEach,
  24591. cr.plugins_.Touch.prototype.cnds.IsTouchingObject,
  24592. cr.plugins_.Sprite.prototype.cnds.CompareInstanceVar,
  24593. cr.plugins_.Sprite.prototype.acts.SetInstanceVar,
  24594. cr.system_object.prototype.cnds.Else,
  24595. cr.plugins_.Function.prototype.acts.CallFunction,
  24596. cr.plugins_.Audio.prototype.acts.Play,
  24597. cr.plugins_.Touch.prototype.cnds.OnTouchObject,
  24598. cr.plugins_.Sprite.prototype.cnds.IsVisible,
  24599. cr.system_object.prototype.cnds.OnLayoutStart,
  24600. cr.plugins_.Sprite.prototype.acts.StopAnim,
  24601. cr.plugins_.Function.prototype.cnds.OnFunction,
  24602. cr.system_object.prototype.cnds.EveryTick,
  24603. cr.system_object.prototype.acts.SetVar,
  24604. cr.plugins_.Function.prototype.exps.Param,
  24605. cr.system_object.prototype.cnds.Compare,
  24606. cr.plugins_.Function.prototype.acts.SetReturnValue,
  24607. cr.plugins_.Sprite.prototype.acts.SetVisible,
  24608. cr.system_object.prototype.exps.time,
  24609. cr.system_object.prototype.exps.timescale,
  24610. cr.plugins_.Audio.prototype.acts.SetSilent,
  24611. cr.plugins_.Audio.prototype.acts.StopAll,
  24612. cr.plugins_.Browser.prototype.exps.ExecJS,
  24613. cr.system_object.prototype.cnds.TriggerOnce,
  24614. cr.system_object.prototype.acts.SetTimescale,
  24615. cr.plugins_.WebStorage.prototype.cnds.LocalStorageExists,
  24616. cr.system_object.prototype.exps["int"],
  24617. cr.plugins_.WebStorage.prototype.exps.LocalValue,
  24618. cr.plugins_.WebStorage.prototype.acts.StoreLocal,
  24619. cr.system_object.prototype.cnds.For,
  24620. cr.system_object.prototype.exps.len,
  24621. cr.plugins_.Arr.prototype.acts.SetX,
  24622. cr.system_object.prototype.exps.loopindex,
  24623. cr.system_object.prototype.exps.right,
  24624. cr.system_object.prototype.exps.left,
  24625. cr.plugins_.Arr.prototype.exps.Width,
  24626. cr.plugins_.Arr.prototype.exps.At,
  24627. cr.plugins_.Sprite.prototype.acts.Destroy,
  24628. cr.plugins_.TiledBg.prototype.acts.Destroy,
  24629. cr.system_object.prototype.acts.CreateObject,
  24630. cr.plugins_.TiledBg.prototype.acts.SetWidth,
  24631. cr.plugins_.TiledBg.prototype.acts.SetHeight,
  24632. cr.system_object.prototype.exps.viewportleft,
  24633. cr.system_object.prototype.exps.viewportright,
  24634. cr.system_object.prototype.exps.viewportbottom,
  24635. cr.system_object.prototype.exps.viewporttop,
  24636. cr.system_object.prototype.exps.scrollx,
  24637. cr.system_object.prototype.cnds.PickAll,
  24638. cr.behaviors.lunarray_LiteTween.prototype.cnds.IsActive,
  24639. cr.behaviors.lunarray_LiteTween.prototype.acts.Stop,
  24640. cr.plugins_.Sprite.prototype.exps.X,
  24641. cr.plugins_.Sprite.prototype.exps.Y,
  24642. cr.plugins_.Sprite.prototype.acts.SetX,
  24643. cr.plugins_.Sprite.prototype.exps.LayerName,
  24644. cr.plugins_.Sprite.prototype.acts.SetY,
  24645. cr.plugins_.Sprite.prototype.acts.SetPos,
  24646. cr.behaviors.lunarray_LiteTween.prototype.acts.SetParameter,
  24647. cr.system_object.prototype.exps.str,
  24648. cr.plugins_.Sprite.prototype.exps.UID,
  24649. cr.system_object.prototype.cnds.PickByComparison,
  24650. cr.plugins_.Sprite.prototype.exps.LayerNumber,
  24651. cr.system_object.prototype.cnds.LayerVisible,
  24652. cr.plugins_.Sprite.prototype.cnds.PickByUID,
  24653. cr.behaviors.lunarray_LiteTween.prototype.acts.Start,
  24654. cr.behaviors.lunarray_LiteTween.prototype.cnds.OnEnd,
  24655. cr.plugins_.Sprite.prototype.acts.SetOpacity,
  24656. cr.system_object.prototype.cnds.OnLayoutEnd,
  24657. cr.system_object.prototype.acts.SetGroupActive,
  24658. cr.behaviors.Pin.prototype.acts.Pin,
  24659. cr.plugins_.Spritefont2.prototype.acts.SetText,
  24660. cr.system_object.prototype.exps.floor,
  24661. cr.system_object.prototype.exps.random,
  24662. cr.plugins_.Sprite.prototype.exps.ImagePointX,
  24663. cr.plugins_.Sprite.prototype.exps.ImagePointY,
  24664. cr.system_object.prototype.exps.distance,
  24665. cr.plugins_.Spritefont2.prototype.acts.Destroy,
  24666. cr.system_object.prototype.acts.GoToLayoutByName,
  24667. cr.system_object.prototype.acts.GoToLayout,
  24668. cr.system_object.prototype.exps.loadingprogress,
  24669. cr.system_object.prototype.exps.round,
  24670. cr.plugins_.Sprite.prototype.acts.SetScale,
  24671. cr.system_object.prototype.exps.min,
  24672. cr.plugins_.Spritefont2.prototype.exps.Y,
  24673. cr.plugins_.Spritefont2.prototype.acts.SetX,
  24674. cr.plugins_.Spritefont2.prototype.exps.Width,
  24675. cr.plugins_.Spritefont2.prototype.acts.SetY,
  24676. cr.system_object.prototype.cnds.IsMobile,
  24677. cr.plugins_.Sprite.prototype.acts.SetAnim,
  24678. cr.plugins_.Touch.prototype.cnds.OnTouchStart,
  24679. cr.system_object.prototype.exps.dt,
  24680. cr.plugins_.Sprite.prototype.cnds.PickTopBottom,
  24681. cr.plugins_.Sprite.prototype.cnds.IsMirrored,
  24682. cr.plugins_.Sprite.prototype.exps.AnimationFrame,
  24683. cr.plugins_.Sprite.prototype.acts.SetMirrored,
  24684. cr.plugins_.Rex_ZSorter.prototype.acts.SortObjsLayerByY,
  24685. cr.system_object.prototype.exps.abs,
  24686. cr.system_object.prototype.exps.clamp,
  24687. cr.plugins_.Sprite.prototype.acts.SetCollisions,
  24688. cr.plugins_.Sprite.prototype.cnds.OnCreated,
  24689. cr.plugins_.Sprite.prototype.exps.AnimationName,
  24690. cr.plugins_.Sprite.prototype.acts.SetSize,
  24691. cr.behaviors.Anchor.prototype.acts.SetEnabled,
  24692. cr.plugins_.Keyboard.prototype.cnds.IsKeyDown,
  24693. cr.plugins_.Sprite.prototype.exps.Count,
  24694. cr.system_object.prototype.exps.max,
  24695. cr.plugins_.Sprite.prototype.exps.AnimationFrameCount,
  24696. cr.plugins_.Sprite.prototype.cnds.OnCollision,
  24697. cr.plugins_.Sprite.prototype.cnds.OnAnyAnimFinished,
  24698. cr.plugins_.Sprite.prototype.exps.Width,
  24699. cr.plugins_.Sprite.prototype.acts.StartAnim,
  24700. cr.plugins_.Keyboard.prototype.cnds.OnKey,
  24701. cr.plugins_.Sprite.prototype.cnds.OnAnimFinished,
  24702. cr.plugins_.Sprite.prototype.acts.SetAnimSpeed,
  24703. cr.plugins_.Sprite.prototype.acts.SetAngle,
  24704. cr.plugins_.Sprite.prototype.exps.Angle,
  24705. cr.plugins_.Sprite.prototype.cnds.OnDestroyed,
  24706. cr.system_object.prototype.cnds.PickByEvaluate,
  24707. cr.behaviors.Pin.prototype.exps.PinnedUID,
  24708. cr.plugins_.Sprite.prototype.cnds.PickDistance,
  24709. cr.system_object.prototype.cnds.While
  24710. ];};