sokol_spine.h 307 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469
  1. #if defined(SOKOL_IMPL) && !defined(SOKOL_SPINE_IMPL)
  2. #define SOKOL_SPINE_IMPL
  3. #endif
  4. #ifndef SOKOL_SPINE_INCLUDED
  5. /*
  6. sokol_spine.h -- a sokol-gfx renderer for the spine-c runtime
  7. (see https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c)
  8. Project URL: https://github.com/floooh/sokol
  9. Do this:
  10. #define SOKOL_IMPL or
  11. #define SOKOL_SPINE_IMPL
  12. before you include this file in *one* C or C++ file to create the
  13. implementation.
  14. The following defines are used by the implementation to select the
  15. platform-specific embedded shader code (these are the same defines as
  16. used by sokol_gfx.h and sokol_app.h):
  17. SOKOL_GLCORE
  18. SOKOL_GLES3
  19. SOKOL_D3D11
  20. SOKOL_METAL
  21. ...optionally provide the following macros to override defaults:
  22. SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
  23. SOKOL_SPINE_API_DECL - public function declaration prefix (default: extern)
  24. SOKOL_API_DECL - same as SOKOL_SPINE_API_DECL
  25. SOKOL_API_IMPL - public function implementation prefix (default: -)
  26. SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
  27. If sokol_spine.h is compiled as a DLL, define the following before
  28. including the declaration or implementation:
  29. SOKOL_DLL
  30. On Windows, SOKOL_DLL will define SOKOL_SPINE_API_DECL as __declspec(dllexport)
  31. or __declspec(dllimport) as needed.
  32. Include the following headers before including sokol_spine.h:
  33. sokol_gfx.h
  34. Include the following headers before include the sokol_spine.h *IMPLEMENTATION*:
  35. spine/spine.h
  36. You'll also need to compile and link with the spine-c runtime:
  37. https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c/spine-c
  38. FEATURE OVERVIEW
  39. ================
  40. sokol_spine.h is a sokol-gfx renderer and 'handle wrapper' for Spine
  41. (http://en.esotericsoftware.com/spine-in-depth) on top of the
  42. spine-c runtime: http://en.esotericsoftware.com/spine-c (source code:
  43. https://github.com/EsotericSoftware/spine-runtimes/tree/4.1/spine-c/spine-c).
  44. The sokol-gfx renderer allows to manage multiple contexts for rendering
  45. Spine scenes into different sokol-gfx render passes (similar to sokol-gl and
  46. sokol-debugtext), allows to split rendering into layers to mix Spine
  47. rendering with other rendering operations, and it automatically batches
  48. adjacent draw calls for Spine objects that use the same texture and in the
  49. same layer.
  50. Sokol-spine wraps 'raw' spine-c objects with tagged index handles. This
  51. eliminates the risk of memory corruption via dangling pointers. Any
  52. API calls involving invalid objects either result in a no-op, or
  53. in a proper error.
  54. The sokol-spine API exposes four 'base object types', and a number of
  55. 'subobject types' which are owned by base objects.
  56. Base object types are:
  57. - sspine_atlas: A wrapper around a spine-c spAtlas object, each spAtlas
  58. object owns at least one spAtlasPage object, and each spAtlasPage object
  59. owns exactly one sokol-gfx image object.
  60. - sspine_skeleton: A skeleton object requires an atlas object for creation,
  61. and is a wrapper around one spine-c spSkeletonData and one
  62. spAnimationStateData object. both contain the shared static data for
  63. individual spine instances
  64. - sspine_instance: Instance objects are created from skeleton objects.
  65. Instances are the objects that are actually getting rendered. Each instance
  66. tracks its own transformation and animation state, but otherwise just
  67. references shared data of the skeleton object it was created from. An
  68. sspine_instance object is a wrapper around one spine-c spSkeleton,
  69. spAnimationState and spSkeletonClipping object each.
  70. - sspine_skinset: Skin-set objects are collections of skins which define
  71. the look of an instance. Some Spine scenes consist of combinable skins
  72. (for instance a human character could offer different skins for different
  73. types of clothing, hats, scarfs, shirts, pants, and so on..., and a skin
  74. set would represent a specific outfit).
  75. Subobject types allow to inspect and manipulate Spine objects in more detail:
  76. - sspine_anim: Each skeleton object usually offers animations which can
  77. then be scheduled and mixed on an instance.
  78. - sspine_bone: Bone objects are the hierarchical transform nodes of
  79. a skeleton. The sokol-spine API allows both to inspect the shared
  80. static bone attributes of an sspine_skeleton object, as well as
  81. inspecting and manipulating the per-instance bone attributes
  82. on an sspine_instance object.
  83. - sspine_event: A running Spine animation may fire 'events' at certain
  84. positions in time (for instance a 'footstep' event whenever a foot
  85. hits the ground). Events can be used to play sound effects (or visual
  86. effects) at the right time.
  87. - sspine_iktarget: Allows to set the target position for a group of
  88. bones controlled by inverse kinematics.
  89. There's a couple of other subobject types which are mostly useful to
  90. inspect the interior structure of skeletons. Those will be explained
  91. in detail further down.
  92. MINIMAL API USAGE OVERVIEW
  93. ==========================
  94. During initialization:
  95. - call sspine_setup() after initializing sokol-gfx
  96. - create an atlas object from a Spine atlas file with sspine_make_atlas()
  97. - load and initialize the sokol-gfx image objects referenced by the atlas
  98. - create a skeleton object from a Spine skeleton file with sspine_make_skeleton()
  99. - create at least one instance object with sspine_make_instance()
  100. In the frame loop, outside of sokol-gfx render passes:
  101. - if needed, move instances around with sspine_set_position()
  102. - if needed, schedule new animations with sspine_set_animation() and sspine_add_animation()
  103. - each frame, advance the current instance animation state with sspine_update_instance()
  104. - each frame, render instances with sspine_draw_instance_in_layer(), this just records
  105. vertices, indices and draw commands into internal buffers, but does no actual
  106. sokol-gfx rendering
  107. In the frame loop, inside a sokol-gfx render pass:
  108. - call sspine_draw_layer() to draw all previously recorded instances in a specific layer
  109. On shutdown:
  110. - call sspine_shutdown(), ideally before shutting down sokol-gfx
  111. QUICKSTART STEP BY STEP
  112. =======================
  113. For a simple demo program using sokol_app.h, sokol_gfx.h and sokol_fetch.h,
  114. see here: [TODO: add link to spine-simple-sapp wasm demo].
  115. - sokol_spine.h must be included after sokol_gfx.h (this is true both
  116. for the declaration and implementation):
  117. #include "sokol_gfx.h"
  118. #include "sokol_spine.h"
  119. - ...and sokol_gfx.h must be initialized before sokol_spine.h:
  120. sg_setup(&(sg_desc){ ... });
  121. sspine_setup(&(sspine_desc){ ... });
  122. - You should always provide a logging callback to sokol-spine, otherwise
  123. no warning or errors will be logged. The easiest way is to use sokol_log.h
  124. for this:
  125. #include "sokol_log.h"
  126. sspine_setup(&(sspine_desc){
  127. .logger = {
  128. .func = slog_func
  129. }
  130. });
  131. - You can tweak the memory usage of sokol-spine by limiting or expanding the
  132. maximum number of vertices, draw commands and pool sizes:
  133. sspine_setup(&(sspine_desc){
  134. .max_vertices = 1024, // default: (1<<16) = 65536
  135. .max_commands = 128, // default: (1<<14) = 16384
  136. .context_pool_size = 1, // default: 4
  137. .atlas_pool_size = 1, // default: 64
  138. .skeleton_pool_size = 1, // default: 64
  139. .skinset_pool_size = 1, // default: 64
  140. .instance_pool_size = 16, // default: 1024
  141. .logger = {
  142. .func = slog_func,
  143. }
  144. });
  145. Sokol-spine uses 32-bit vertex-indices for rendering
  146. (SG_INDEXTYPE_UINT32), so that the maximum number of Spine vertices
  147. in a frame isn't limited to (1<<16).
  148. - You can override memory allocation and logging with your own
  149. functions, this is explained in detail further down:
  150. sspine_setup(&(sspine_desc){
  151. .allocator = {
  152. .alloc_fn = my_alloc,
  153. .free_fn = my_free,
  154. .user_data = ...,
  155. },
  156. .logger = {
  157. .log_func = my_log_func,
  158. .user_data = ...,
  159. }
  160. });
  161. - After initialization, the first thing you need is an sspine_atlas object.
  162. Sokol-spine doesn't concern itself with file IO, it expects all external
  163. data to be provided as pointer/size pairs:
  164. sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
  165. .data = {
  166. .ptr = ..., // pointer to Spine atlas file data in memory
  167. .size = ..., // atlas file data size in bytes
  168. }
  169. });
  170. assert(sspine_atlas_valid(atlas));
  171. If you load the atlas data asynchronously, you can still run your
  172. per-frame rendering code without waiting for the atlas data to be loaded
  173. and the atlas to be created. This works because calling sokol-spine
  174. functions with 'invalid' object handles is a valid no-op.
  175. - Optionally you can override some or all of the atlas texture creation parameters:
  176. sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
  177. .data = { ... },
  178. .overrides = {
  179. .min_filter = SG_FILTER_NEAREST,
  180. .mag_filter = SG_FILTER_NEAREST,
  181. .mipmap_filter = SG_FILTER_NEAREST,
  182. .wrap_u = SG_WRAP_MIRROR,
  183. .wrap_v = SG_WRAP_MIRROR,
  184. .premul_alpha_enabled = ...,
  185. .premul_alpha_disabled = ...,
  186. }
  187. });
  188. - The atlas file itself doesn't contain any texture data, it only contains
  189. filenames of the required textures. Sokol-spine has already allocated
  190. a sokol-gfx sg_image and sg_sample handle for each required texture, but the
  191. actual loading and initialization must be performed by user code:
  192. // iterate over atlas textures and initialize sokol-gfx image objects
  193. // with existing handles
  194. const int num = sspine_num_images(atlas);
  195. for (int i = 0; i < num; i++) {
  196. const sspine_image img = sspine_image_by_index(atlas, i);
  197. const sspine_image_info img_info = sspine_get_image_info(img);
  198. assert(img_info.valid);
  199. assert(!img_info.filename.truncated);
  200. // the filename is now in img_info.filename.cstr, 'somehow'
  201. // load and decode the image data into memory, and then
  202. // initialize the sokol-gfx image from the existing sg_image handle
  203. // in img_info.sgimage:
  204. sg_init_image(img_info.sgimage, &(sg_image_desc){
  205. .width = ...,
  206. .height = ...,
  207. .pixel_format = ...,
  208. .data.subimage[0][0] = {
  209. .ptr = ..., // pointer to decoded image pixel data
  210. .size = ..., // size of decoded image pixel data in bytes
  211. }
  212. });
  213. // ...and same procedure for the sampler object
  214. sg_init_sampler(img_info.sgsampler, &(sg_image_desc){
  215. .min_filter = img_info.min_filter,
  216. .mag_filter = img_info.mag_filter,
  217. .mipmap_filter = img_info.mipmap_filter,
  218. .wrap_u = img_info.wrap_u,
  219. .wrap_v = img_info.wrap_v,
  220. });
  221. }
  222. If you load the image data asynchronously, you can still simply start rendering
  223. before the image data is loaded. This works because sokol-gfx will silently drop
  224. any rendering operations that involve 'incomplete' objects.
  225. - Once an atlas object has been created (independently from loading any image data),
  226. an sspine_skeleton object is needed next. This requires a valid atlas object
  227. handle as input, and a pointer to the Spine skeleton file data loaded into memory.
  228. Spine skeleton files come in two flavours: binary or json, for binary data,
  229. a ptr/size pair must be provided:
  230. sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
  231. .atlas = atlas, // atlas must be a valid sspine_atlas handle
  232. .binary_data = {
  233. .ptr = ..., // pointer to binary skeleton data in memory
  234. .size = ..., // size of binary skeleton data in bytes
  235. }
  236. });
  237. assert(sspine_skeleton_valid(skeleton));
  238. For JSON skeleton file data, the data must be provided as a zero-terminated C string:
  239. sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
  240. .atlas = atlas,
  241. .json_data = ..., // JSON skeleton data as zero-terminated(!) C-string
  242. });
  243. Like with all sokol-spine objects, if you load the skeleton data asynchronously
  244. and only then create a skeleton object, you can already start rendering before
  245. the data is loaded and the Spine objects have been created. Any operations
  246. involving 'incomplete' handles will be dropped.
  247. - You can pre-scale the Spine scene size, and you can provide a default cross-fade
  248. duration for animation mixing:
  249. sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
  250. .atlas = atlas,
  251. .binary_data = { ... },
  252. .prescale = 0.5f, // scale to half-size
  253. .anim_default_mix = 0.2f, // default anim mixing cross-fade duration 0.2 seconds
  254. });
  255. - Once the skeleton object has been created, it's finally time to create one or many instance objects.
  256. If you want to independently render and animate the 'same' Spine object many times in a frame,
  257. you should only create one sspine_skeleton object, and then as many sspine_instance object
  258. as needed from the shared skeleton object:
  259. sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
  260. .skeleton = skeleton, // must be a valid skeleton handle
  261. });
  262. assert(sspine_instance_valid(instance));
  263. After creation, the sspine_instance will have a 'default skin' set as its appearance.
  264. - To set the position of an instance:
  265. sspine_set_position(inst, (sspine_vec2){ .x=..., .y=... });
  266. Sokol-spine doesn't define a specific unit (like pixels or meters), instead the
  267. rendering coordinate system is defined later at 'render time'.
  268. - To schedule an initial looping animation by its name:
  269. // first lookup up the animation by name on the skeleton:
  270. sspine_anim anim = sspine_anim_by_name(skeleton, "walk");
  271. assert(sspine_anim_valid(anim));
  272. // then schedule the animation on the instance, on mixer track 0, as looping:
  273. sspine_set_animation(instance, anim, 0, true);
  274. Scheduling and mixing animations will be explained in more detail further down.
  275. - To advance and mix instance animations:
  276. sspine_update_instance(instance, delta_time_in_seconds);
  277. Usually you'd call this each frame for each active instance with the
  278. frame duration in seconds.
  279. - Now it's finally time to 'render' the instance at its current position and
  280. animation state:
  281. sspine_draw_instance_in_layer(instance, 0);
  282. Instances are generally rendered into numbered virtual 'render layers' (in this
  283. case, layer 0). Layers are useful for interleaving sokol-spine rendering
  284. with other rendering commands (like background and foreground tile maps,
  285. sprites or text).
  286. - It's important to note that no actual sokol-gfx rendering happens in
  287. sspine_draw_instance_in_layer(), instead only vertices, indices and
  288. draw commands are recorded into internal memory buffes.
  289. - The only sokol-spine function which *must* (and should) be called inside
  290. a sokol-gfx rendering pass is sspine_draw_layer().
  291. This renders all draw commands that have been recorded previously in a
  292. specific layer via sspine_draw_instance_in_layer().
  293. const sspine_layer_transform tform = { ... };
  294. sg_begin_default_pass(...);
  295. sspine_draw_layer(0, tform);
  296. sg_end_pass();
  297. sg_commit();
  298. IMPORTANT: DO *NOT* MIX any calls to sspine_draw_instance_in_layer()
  299. with sspine_draw_layer(), as this will confuse the internal draw command
  300. recording. Ideally, move all sokol-gfx pass rendering (including all
  301. sspine_draw_layer() calls) towards the end of the frame, separate from
  302. any other sokol-spine calls.
  303. The sspine_layer_transform struct defines the layer's screen space coordinate
  304. system. For instance to map Spine coordinates to framebuffer pixels, with the
  305. origin in the screen center, you'd setup the layer transform like this:
  306. const float width = sapp_widthf();
  307. const float height = sapp_heightf();
  308. const sspine_layer_transform tform = {
  309. .size = { .x = width, .y = height },
  310. .origin = { .x = width * 0.5f, .y = height * 0.5f },
  311. };
  312. With this pixel mapping, the Spine scene would *not* scale with window size,
  313. which often is not very useful. Instead it might make more sense to render
  314. to a fixed 'virtual' resolution, for instance 1024 * 768:
  315. const sspine_layer_transform tform = {
  316. .size = { .x = 1024.0f, .y = 768.0f },
  317. .origin = { .x = 512.0f, .y = 384.0f },
  318. };
  319. How to configure a virtual resolution with a fixed aspect ratio is
  320. left as an exercise to the reader ;)
  321. - That's it for basic sokol-spine setup and rendering. Any existing objects
  322. will automatically be cleaned up when calling sspine_shutdown(), this
  323. should be called before shutting down sokol-gfx, but this is not required:
  324. sspine_shutdown();
  325. sg_shutdown();
  326. - You can explicitly destroy the base object types if you don't need them
  327. any longer. This will cause the underlying spine-c objects to be
  328. freed and the memory to be returned to the operating system:
  329. sspine_destroy_instance(instance);
  330. sspine_destroy_skinset(skinset);
  331. sspine_destroy_skeleton(skeleton);
  332. sspine_destroy_atlas(atlas);
  333. You can destroy these objects in any order without causing memory corruption
  334. issues. Instead any dependent object handles will simply become invalid (e.g.
  335. if you destroy an atlas object, all skeletons and instances created from
  336. this atlas will 'technically' still exist, but their handles will resolve to
  337. 'invalid' and all sokol-spine calls involving these handles will silently fail).
  338. For instance:
  339. // create an atlas, skeleton and instance
  340. sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){ ... });
  341. assert(sspine_atlas_valid(atlas));
  342. sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
  343. .atlas = atlas,
  344. ...
  345. });
  346. assert(sspine_skeleton_valid(skeleton));
  347. sspine_instance instance = sspine_make_instance(&(sspine_instance_desc){
  348. .skeleton = skeleton,
  349. });
  350. assert(sspine_instance_valid(instance));
  351. // destroy the atlas object:
  352. sspine_destroy_atlas(atlas);
  353. // the skeleton and instance handle should now be invalid, but
  354. // otherwise, nothing bad will happen:
  355. if (!sspine_skeleton_valid(skeleton)) {
  356. ...
  357. }
  358. if (!sspine_instance_valid(instance)) {
  359. ...
  360. }
  361. RENDERER DETAILS
  362. ================
  363. Any rendering related work happens in the functions sspine_draw_instance_in_layer() and
  364. sspine_draw_layer().
  365. sspine_draw_instance_in_layer() will result in vertices, indices and internal
  366. draw commands which will be recorded into internal memory buffers (e.g.
  367. no sokol-gfx functions will be called here).
  368. If possible, batching will be performed by merging a new draw command with
  369. the previously recorded draw command. For two draw commands to be merged,
  370. the following conditions must be tru:
  371. - rendering needs to go into the same layer
  372. - the same atlas texture must be used
  373. - the blend mode must be compatible (the Spine blending modes
  374. 'normal' and 'additive' can be merged, but not 'multiply')
  375. - the same premultiplied alpha mode must be used
  376. To make the most out of batching:
  377. - use Spine objects which only have a single atlas texture
  378. and blend mode across all slots
  379. - group sspine_draw_instance_in_layer() calls by layer
  380. After all instances have been 'rendered' (or rather: recorded) into layers,
  381. the actually rendering happens inside a sokol-gfx pass by calling the
  382. function sspine_draw_layer() for each layer in 'z order' (e.g. the layer
  383. index doesn't matter for z-ordering, only the order how sspine_draw_layer() is
  384. called).
  385. Only the first call to sspine_draw_layer() in a frame will copy the recorded
  386. vertices and indices into sokol-gfx buffers.
  387. Each call to sspine_draw_layer() will iterate over all recorded (and
  388. hopefully well-batched) draw commands, skip any draw commands with a
  389. non-matching layer index, and draw only those with a matching layer by
  390. calling:
  391. - if the pipeline object has changed:
  392. - sg_apply_pipeline()
  393. - sg_apply_uniforms() for the vertex stage
  394. - if the atlas texture has changed:
  395. - sg_apply_bindings()
  396. - if the premultiplied-alpha mode has changed:
  397. - sg_apply_uniforms() for the fragment stage
  398. - and finally sg_draw()
  399. The main purpose of render layers is to mix Spine rendering with other
  400. render operations. In the not too distant future, the same render layer idea
  401. will also be implemented at least for sokol-gl and sokol-debugtext.
  402. FIXME: does this section need more details about layer transforms?
  403. RENDERING WITH CONTEXTS
  404. =======================
  405. At first glance, render contexts may look like more heavy-weight
  406. render layers, but they serve a different purpose: they are useful
  407. if Spine rendering needs to happen in different sokol-gfx render passes
  408. with different pixel formats and MSAA sample counts.
  409. All Spine rendering happens within a context, even you don't call any
  410. of the context API functions, in this case, an internal 'default context'
  411. will be used.
  412. Each context has its own internal vertex-, index- and command buffer and
  413. all context state is completely independent from any other contexts.
  414. To create a new context object, call:
  415. sspine_context ctx = sspine_make_context(&(sspine_context_desc){
  416. .max_vertices = ...,
  417. .max_commands = ...,
  418. .color_format = SG_PIXELFORMAT_...,
  419. .depth_format = SG_PIXELFORMAT_...,
  420. .sample_count = ...,
  421. .color_write_mask = SG_COLORMASK_...,
  422. });
  423. The color_format, depth_format and sample_count items must be compatible
  424. with the sokol-gfx render pass you're going to render into.
  425. If you omit the color_format, depth_format and sample_count designators,
  426. the new context will be compatible with the sokol-gfx default pass
  427. (which is most likely not what you want, unless your offscreen render passes
  428. exactly match the default pass attributes).
  429. Once a context has been created, it can be made active with:
  430. sspine_set_context(ctx);
  431. To set the default context again:
  432. sspine_set_contxt(sspine_default_context());
  433. ...and to get the currently active context:
  434. sspine_context cur_ctx = sspine_get_context();
  435. The currently active context only matter for two functions:
  436. - sspine_draw_instance_in_layer()
  437. - sspine_draw_layer()
  438. Alternatively you can bypass the currently set context with these
  439. alternative functions:
  440. - sspine_context_draw_layer_in_instance(ctx, ...)
  441. - sspine_context_draw_layer(ctx, ...)
  442. These explicitly take a context argument, completely ignore
  443. and don't change the active context.
  444. You can query some information about a context with the function:
  445. sspine_context_info info = ssgpine_get_context_info(ctx);
  446. This returns the current number of recorded vertices, indices
  447. and draw commands.
  448. RESOURCE STATES:
  449. ================
  450. Similar to sokol-gfx, you can query the current 'resource state' of Spine
  451. objects:
  452. sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas);
  453. sspine_resource_state sspine_get_skeleton_resource_state(sspine_atlas atlas);
  454. sspine_resource_state sspine_get_instance_resource_state(sspine_atlas atlas);
  455. sspine_resource_state sspine_get_skinset_resource_state(sspine_atlas atlas);
  456. sspine_resource_state sspine_get_context_resource_state(sspine_atlas atlas);
  457. This returns one of
  458. - SSPINE_RESOURCE_VALID: the object is valid and ready to use
  459. - SSPINE_RESOURCE_FAILED: the object creation has failed
  460. - SSPINE_RESOURCE_INVALID: the object or one of its dependencies is
  461. invalid, it either no longer exists, or the handle hasn't been
  462. initialized with a call to one of the object creation functions
  463. MISC HELPER FUNCTIONS:
  464. ======================
  465. There's a couple of helper functions which don't fit into a big enough category
  466. of their own:
  467. You can ask a skeleton for the atlas it has been created from:
  468. sspine_atlas atlas = sspine_get_skeleton_atlas(skeleton);
  469. ...and likewise, ask an instance for the skeleton it has been created from:
  470. sspine_skeleton skeleton = sspine_get_instance_skeleton(instance);
  471. ...and finally you can convert a layer transform struct into a 4x4 projection
  472. matrix that's memory-layout compatible with sokol-gl:
  473. const sspine_layer_transform tform = { ... };
  474. const sspine_mat4 proj = sspine_layer_transform_to_mat4(&tform);
  475. sgl_matrix_mode_projection();
  476. sgl_load_matrix(proj.m);
  477. ANIMATIONS
  478. ==========
  479. Animations have their own handle type sspine_anim. A valid sspine_anim
  480. handle is either obtained by looking up an animation by name from a skeleton:
  481. sspine_anim anim = sspine_anim_by_name(skeleton, "walk");
  482. ...or by index:
  483. sspine_anim anim = sspine_anim_by_index(skeleton, 0);
  484. The returned anim handle will be invalid if an animation of that name doesn't
  485. exist, or the provided index is out-of-range:
  486. if (!sspine_anim_is_valid(anim)) {
  487. // animation handle is not valid
  488. }
  489. An animation handle will also become invalid when the skeleton object it was
  490. created is destroyed, or otherwise becomes invalid.
  491. You can iterate over all animations in a skeleton:
  492. const int num_anims = sspine_num_anims(skeleton);
  493. for (int anim_index = 0; anim_index < num_anims; anim_index++) {
  494. sspine_anim anim = sspine_anim_by_index(skeleton, anim_index);
  495. ...
  496. }
  497. Since sspine_anim is a 'fat handle' (it houses a skeleton handle and an index),
  498. there's a helper function which checks if two anim handles are equal:
  499. if (sspine_anim_equal(anim0, anim1)) {
  500. ...
  501. }
  502. To query information about an animation:
  503. const sspine_anim_info info = sspine_get_anim_info(anim);
  504. if (info.valid) {
  505. printf("index: %d, duration: %f, name: %s", info.index, info.duration, info.name.cstr);
  506. }
  507. Scheduling and mixing animations is controlled through the following functions:
  508. void sspine_clear_animation_tracks(sspine_instance instance);
  509. void sspine_clear_animation_track(sspine_instance instance, int track_index);
  510. void sspine_set_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop);
  511. void sspine_add_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop, float delay);
  512. void sspine_set_empty_animation(sspine_instance instance, int track_index, float mix_duration);
  513. void sspine_add_empty_animation(sspine_instance instance, int track_index, float mix_duration, float delay);
  514. Please refer to the spine-c documentation to get an idea what these functions do:
  515. http://en.esotericsoftware.com/spine-c#Applying-animations
  516. EVENTS
  517. ======
  518. For a general idea of Spine events, see here: http://esotericsoftware.com/spine-events
  519. After calling sspine_update_instance() to advance the currently configured animations,
  520. you can poll for triggered events like this:
  521. const int num_triggered_events = sspine_num_triggered_events(instance);
  522. for (int i = 0; i < num_triggered_events; i++) {
  523. const sspine_triggered_event_info info = sspine_get_triggered_event_info(instance, i);
  524. if (info.valid) {
  525. ...
  526. }
  527. }
  528. The returned sspine_triggered_event_info struct gives you the current runtime properties
  529. of the event (in case the event has keyed properties). For the actual list of event
  530. properties please see the actual sspine_triggered_event_info struct declaration.
  531. It's also possible to inspect the static event definition on a skeleton, this works
  532. the same as iterating through animations. You can lookup an event by name,
  533. get the number of events, lookup an event by its index, and get detailed
  534. information about an event:
  535. int sspine_num_events(sspine_skeleton skeleton);
  536. sspine_event sspine_event_by_name(sspine_skeleton skeleton, const char* name);
  537. sspine_event sspine_event_by_index(sspine_skeleton skeleton, int index);
  538. bool sspine_event_valid(sspine_event event);
  539. bool sspine_event_equal(sspine_event first, sspine_event second);
  540. sspine_event_info sspine_get_event_info(sspine_event event);
  541. (FIXME: shouldn't the event info struct contains an sspine_anim handle?)
  542. IK TARGETS
  543. ==========
  544. The IK target function group allows to iterate over the IK targets that have been
  545. defined on a skeleton, find an IK target by name, get detailed information about
  546. an IK target, and most importantly, set the world space position of an IK target
  547. which updates the position of all bones influenced by the IK target:
  548. int sspine_num_iktargets(sspine_skeleton skeleton);
  549. sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton, const char* name);
  550. sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton, int index);
  551. bool sspine_iktarget_valid(sspine_iktarget iktarget);
  552. bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second);
  553. sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget);
  554. void sspine_set_iktarget_world_pos(sspine_instance instance, sspine_iktarget iktarget, sspine_vec2 world_pos);
  555. BONES
  556. =====
  557. Skeleton bones are wrapped with an sspine_bone handle which can be created from
  558. a skeleton handle, and either a bone name:
  559. sspine_bone bone = sspine_bone_by_name(skeleton, "root");
  560. assert(sspine_bone_valid(bone));
  561. ...or a bone index:
  562. sspine_bone bone = sspine_bone_by_index(skeleton, 0);
  563. assert(sspine_bone_valid(bone));
  564. ...to iterate over all bones of a skeleton and query information about each
  565. bone:
  566. const int num_bones = sspine_num_bones(skeleton);
  567. for (int bone_index = 0; bone_index < num_bones; bone_index++) {
  568. sspine_bone bone = sspine_bone_by_index(skeleton, bone_index);
  569. const sspine_bone_info info = sspine_get_bone_info(skeleton, bone);
  570. if (info.valid) {
  571. ...
  572. }
  573. }
  574. The sspine_bone_info struct provides the shared, static bone state in the skeleton (like
  575. the name, a parent bone handle, bone length, pose transform and a color attribute),
  576. but doesn't contain any dynamic information of per-instance bones.
  577. To manipulate the per-instance bone attributes use the following setter functions:
  578. void sspine_set_bone_transform(sspine_instance instance, sspine_bone bone, const sspine_bone_transform* transform);
  579. void sspine_set_bone_position(sspine_instance instance, sspine_bone bone, sspine_vec2 position);
  580. void sspine_set_bone_rotation(sspine_instance instance, sspine_bone bone, float rotation);
  581. void sspine_set_bone_scale(sspine_instance instance, sspine_bone bone, sspine_vec2 scale);
  582. void sspine_set_bone_shear(sspine_instance instance, sspine_bone bone, sspine_vec2 shear);
  583. ...and to query the per-instance bone attributes, the following getters:
  584. sspine_bone_transform sspine_get_bone_transform(sspine_instance instance, sspine_bone bone);
  585. sspine_vec2 sspine_get_bone_position(sspine_instance instance, sspine_bone bone);
  586. float sspine_get_bone_rotation(sspine_instance instance, sspine_bone bone);
  587. sspine_vec2 sspine_get_bone_scale(sspine_instance instance, sspine_bone bone);
  588. sspine_vec2 sspine_get_bone_shear(sspine_instance instance, sspine_bone bone);
  589. These functions all work in the local bone coordinate system (relative to a bone's parent bone).
  590. To transform positions between bone-local and global space use the following helper functions:
  591. sspine_vec2 sspine_bone_local_to_world(sspine_instance instance, sspine_bone bone, sspine_vec2 local_pos);
  592. sspine_vec2 sspine_bone_world_to_local(sspine_instance instance, sspine_bone bone, sspine_vec2 world_pos);
  593. ...and as a convenience, there's a helper function which obtains the bone position in global space
  594. directly:
  595. sspine_vec2 sspine_get_bone_world_position(sspine_instance instance, sspine_bone bone);
  596. SKINS AND SKINSETS
  597. ==================
  598. Skins are named pieces of geometry which can be turned on and off, what makes Spine skins a bit
  599. confusing is that they are hierarchical. A skin can itself be a collection of other skins. Setting
  600. the 'root skin' will also make all 'child skins' visible. In sokol-spine collections of skins are
  601. managed through dedicated 'skin set' objects. Under the hood they create a 'root skin' where the
  602. skins of the skin set are attached to, but from the outside it just looks like a 'flat' collection
  603. of skins without the tricky hierarchical management.
  604. Like other 'subobjects', skin handles can be obtained by the skin name from a skeleton handle:
  605. sspine_skin skin = sspine_skin_by_name(skeleton, "jacket");
  606. assert(sspine_skin_valid(skin));
  607. ...or by a skin index:
  608. sspine_skin skin = sspine_skin_by_index(skeleton, 0);
  609. assert(sspine_skin_valid(skin));
  610. ...you can iterate over all skins of a skeleton and query some information about the skin:
  611. const int num_skins = sspine_num_skins(skeleton);
  612. for (int skin_index = 0; skin_index < num_skins; skin_index++) {
  613. sspine_skin skin = sspine_skin_by_index(skin_index);
  614. sspine_skin_info info = sspine_get_skin_info(skin);
  615. if (info.valid) {
  616. ...
  617. }
  618. }
  619. Currently, the only useful query item is the skin name though.
  620. To make a skin visible on an instance, just call:
  621. sspine_set_skin(instance, skin);
  622. ...this will first deactivate the previous skin before setting a new skin.
  623. A more powerful way to configure the skin visibility is through 'skin sets'. Skin
  624. sets are simply flat collections of skins which should be made visible at once.
  625. A new skin set is created like this:
  626. sspine_skinset skinset = sspine_make_skinset(&(sspine_skinset_desc){
  627. .skeleton = skeleton,
  628. .skins = {
  629. sspine_skin_by_name(skeleton, "blue-jacket"),
  630. sspine_skin_by_name(skeleton, "green-pants"),
  631. sspine_skin_by_name(skeleton, "blonde-hair"),
  632. ...
  633. }
  634. });
  635. assert(sspine_skinset_valid(skinset))
  636. ...then simply set the skinset on an instance to reconfigure the appearance
  637. of the instance:
  638. sspine_set_skinset(instance, skinset);
  639. The functions sspine_set_skinset() and sspine_set_skin() will cancel each other.
  640. Calling sspine_set_skinset() deactivates the effect of sspine_set_skin() and
  641. vice versa.
  642. ERROR REPORTING AND LOGGING
  643. ===========================
  644. To get any logging information at all you need to provide a logging callback in the setup call,
  645. the easiest way is to use sokol_log.h:
  646. #include "sokol_log.h"
  647. sspine_setup(&(sspine_desc){ .logger.func = slog_func });
  648. To override logging with your own callback, first write a logging function like this:
  649. void my_log(const char* tag, // e.g. 'sspine'
  650. uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
  651. uint32_t log_item_id, // SSPINE_LOGITEM_*
  652. const char* message_or_null, // a message string, may be nullptr in release mode
  653. uint32_t line_nr, // line number in sokol_spine.h
  654. const char* filename_or_null, // source filename, may be nullptr in release mode
  655. void* user_data)
  656. {
  657. ...
  658. }
  659. ...and then setup sokol-spine like this:
  660. sspine_setup(&(sspine_desc){
  661. .logger = {
  662. .func = my_log,
  663. .user_data = my_user_data,
  664. }
  665. });
  666. The provided logging function must be reentrant (e.g. be callable from
  667. different threads).
  668. If you don't want to provide your own custom logger it is highly recommended to use
  669. the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
  670. errors.
  671. MEMORY ALLOCATION OVERRIDE
  672. ==========================
  673. You can override the memory allocation functions at initialization time
  674. like this:
  675. void* my_alloc(size_t size, void* user_data) {
  676. return malloc(size);
  677. }
  678. void my_free(void* ptr, void* user_data) {
  679. free(ptr);
  680. }
  681. ...
  682. sspine_setup(&(sspine_desc){
  683. // ...
  684. .allocator = {
  685. .alloc_fn = my_alloc,
  686. .free_fn = my_free,
  687. .user_data = ...;
  688. }
  689. });
  690. ...
  691. If no overrides are provided, malloc and free will be used.
  692. This only affects memory allocation calls done by sokol_gfx.h
  693. itself though, not any allocations in OS libraries.
  694. LICENSE
  695. =======
  696. zlib/libpng license
  697. Copyright (c) 2022 Andre Weissflog
  698. This software is provided 'as-is', without any express or implied warranty.
  699. In no event will the authors be held liable for any damages arising from the
  700. use of this software.
  701. Permission is granted to anyone to use this software for any purpose,
  702. including commercial applications, and to alter it and redistribute it
  703. freely, subject to the following restrictions:
  704. 1. The origin of this software must not be misrepresented; you must not
  705. claim that you wrote the original software. If you use this software in a
  706. product, an acknowledgment in the product documentation would be
  707. appreciated but is not required.
  708. 2. Altered source versions must be plainly marked as such, and must not
  709. be misrepresented as being the original software.
  710. 3. This notice may not be removed or altered from any source
  711. distribution.
  712. */
  713. #define SOKOL_SPINE_INCLUDED (1)
  714. #include <stdint.h>
  715. #include <stdbool.h>
  716. #include <stddef.h> // size_t
  717. #if !defined(SOKOL_GFX_INCLUDED)
  718. #error "Please include sokol_gfx.h before sokol_spine.h"
  719. #endif
  720. #if defined(SOKOL_API_DECL) && !defined(SOKOL_SPINE_API_DECL)
  721. #define SOKOL_SPINE_API_DECL SOKOL_API_DECL
  722. #endif
  723. #ifndef SOKOL_SPINE_API_DECL
  724. #if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_SPINE_IMPL)
  725. #define SOKOL_SPINE_API_DECL __declspec(dllexport)
  726. #elif defined(_WIN32) && defined(SOKOL_DLL)
  727. #define SOKOL_SPINE_API_DECL __declspec(dllimport)
  728. #else
  729. #define SOKOL_SPINE_API_DECL extern
  730. #endif
  731. #endif
  732. #ifdef __cplusplus
  733. extern "C" {
  734. #endif
  735. enum {
  736. SSPINE_INVALID_ID = 0,
  737. SSPINE_MAX_SKINSET_SKINS = 32,
  738. SSPINE_MAX_STRING_SIZE = 61, // see sspine_string struct
  739. };
  740. typedef struct sspine_context { uint32_t id; } sspine_context;
  741. typedef struct sspine_atlas { uint32_t id; } sspine_atlas;
  742. typedef struct sspine_skeleton { uint32_t id; } sspine_skeleton;
  743. typedef struct sspine_instance { uint32_t id; } sspine_instance;
  744. typedef struct sspine_skinset { uint32_t id; } sspine_skinset;
  745. typedef struct sspine_image { uint32_t atlas_id; int index; } sspine_image;
  746. typedef struct sspine_atlas_page { uint32_t atlas_id; int index; } sspine_atlas_page;
  747. typedef struct sspine_anim { uint32_t skeleton_id; int index; } sspine_anim;
  748. typedef struct sspine_bone { uint32_t skeleton_id; int index; } sspine_bone;
  749. typedef struct sspine_slot { uint32_t skeleton_id; int index; } sspine_slot;
  750. typedef struct sspine_event { uint32_t skeleton_id; int index; } sspine_event;
  751. typedef struct sspine_iktarget { uint32_t skeleton_id; int index; } sspine_iktarget;
  752. typedef struct sspine_skin { uint32_t skeleton_id; int index; } sspine_skin;
  753. typedef struct sspine_range { const void* ptr; size_t size; } sspine_range;
  754. typedef struct sspine_vec2 { float x, y; } sspine_vec2;
  755. typedef struct sspine_mat4 { float m[16]; } sspine_mat4;
  756. typedef sg_color sspine_color;
  757. typedef struct sspine_string {
  758. bool valid;
  759. bool truncated;
  760. uint8_t len;
  761. char cstr[SSPINE_MAX_STRING_SIZE];
  762. } sspine_string;
  763. typedef enum sspine_resource_state {
  764. SSPINE_RESOURCESTATE_INITIAL,
  765. SSPINE_RESOURCESTATE_ALLOC,
  766. SSPINE_RESOURCESTATE_VALID,
  767. SSPINE_RESOURCESTATE_FAILED,
  768. SSPINE_RESOURCESTATE_INVALID,
  769. _SSPINE_RESOURCESTATE_FORCE_U32 = 0x7FFFFFFF
  770. } sspine_resource_state;
  771. // log item codes via x-macro magic
  772. #define _SSPINE_LOG_ITEMS \
  773. _SSPINE_LOGITEM_XMACRO(OK, "Ok")\
  774. _SSPINE_LOGITEM_XMACRO(MALLOC_FAILED, "memory allocation failed")\
  775. _SSPINE_LOGITEM_XMACRO(CONTEXT_POOL_EXHAUSTED, "context pool exhausted (adjust via sspine_desc.context_pool_size)")\
  776. _SSPINE_LOGITEM_XMACRO(ATLAS_POOL_EXHAUSTED, "atlas pool exhausted (adjust via sspine_desc.atlas_pool_size)")\
  777. _SSPINE_LOGITEM_XMACRO(SKELETON_POOL_EXHAUSTED, "skeleton pool exhausted (adjust via sspine_desc.skeleton_pool_size)")\
  778. _SSPINE_LOGITEM_XMACRO(SKINSET_POOL_EXHAUSTED, "skinset pool exhausted (adjust via sspine_desc.skinset_pool_size)")\
  779. _SSPINE_LOGITEM_XMACRO(INSTANCE_POOL_EXHAUSTED, "instance pool exhausted (adjust via sspine_desc.instance_pool_size)")\
  780. _SSPINE_LOGITEM_XMACRO(CANNOT_DESTROY_DEFAULT_CONTEXT, "cannot destroy default context")\
  781. _SSPINE_LOGITEM_XMACRO(ATLAS_DESC_NO_DATA, "no data provided in sspine_atlas_desc.data")\
  782. _SSPINE_LOGITEM_XMACRO(SPINE_ATLAS_CREATION_FAILED, "spAtlas_create() failed")\
  783. _SSPINE_LOGITEM_XMACRO(SG_ALLOC_IMAGE_FAILED, "sg_alloc_image() failed")\
  784. _SSPINE_LOGITEM_XMACRO(SG_ALLOC_SAMPLER_FAILED, "sg_alloc_sampler() failed")\
  785. _SSPINE_LOGITEM_XMACRO(SKELETON_DESC_NO_DATA, "no data provided in sspine_skeleton_desc.json_data or .binary_data")\
  786. _SSPINE_LOGITEM_XMACRO(SKELETON_DESC_NO_ATLAS, "no atlas object provided in sspine_skeleton_desc.atlas")\
  787. _SSPINE_LOGITEM_XMACRO(SKELETON_ATLAS_NOT_VALID, "sspine_skeleton_desc.atlas is not in valid state")\
  788. _SSPINE_LOGITEM_XMACRO(CREATE_SKELETON_DATA_FROM_JSON_FAILED, "spSkeletonJson_readSkeletonData() failed")\
  789. _SSPINE_LOGITEM_XMACRO(CREATE_SKELETON_DATA_FROM_BINARY_FAILED, "spSkeletonBinary_readSkeletonData() failed")\
  790. _SSPINE_LOGITEM_XMACRO(SKINSET_DESC_NO_SKELETON, "no skeleton object provided in sspine_skinset_desc.skeleton")\
  791. _SSPINE_LOGITEM_XMACRO(SKINSET_SKELETON_NOT_VALID, "sspine_skinset_desc.skeleton is not in valid state")\
  792. _SSPINE_LOGITEM_XMACRO(SKINSET_INVALID_SKIN_HANDLE, "invalid skin handle in sspine_skinset_desc.skins[]")\
  793. _SSPINE_LOGITEM_XMACRO(INSTANCE_DESC_NO_SKELETON, "no skeleton object provided in sspine_instance_desc.skeleton")\
  794. _SSPINE_LOGITEM_XMACRO(INSTANCE_SKELETON_NOT_VALID, "sspine_instance_desc.skeleton is not in valid state")\
  795. _SSPINE_LOGITEM_XMACRO(INSTANCE_ATLAS_NOT_VALID, "skeleton's atlas object no longer valid via sspine_instance_desc.skeleton")\
  796. _SSPINE_LOGITEM_XMACRO(SPINE_SKELETON_CREATION_FAILED, "spSkeleton_create() failed")\
  797. _SSPINE_LOGITEM_XMACRO(SPINE_ANIMATIONSTATE_CREATION_FAILED, "spAnimationState_create() failed")\
  798. _SSPINE_LOGITEM_XMACRO(SPINE_SKELETONCLIPPING_CREATION_FAILED, "spSkeletonClipping_create() failed")\
  799. _SSPINE_LOGITEM_XMACRO(COMMAND_BUFFER_FULL, "command buffer full (adjust via sspine_desc.max_commands)")\
  800. _SSPINE_LOGITEM_XMACRO(VERTEX_BUFFER_FULL, "vertex buffer (adjust via sspine_desc.max_vertices)")\
  801. _SSPINE_LOGITEM_XMACRO(INDEX_BUFFER_FULL, "index buffer full (adjust via sspine_desc.max_vertices)")\
  802. _SSPINE_LOGITEM_XMACRO(STRING_TRUNCATED, "a string has been truncated")\
  803. _SSPINE_LOGITEM_XMACRO(ADD_COMMIT_LISTENER_FAILED, "sg_add_commit_listener() failed")\
  804. #define _SSPINE_LOGITEM_XMACRO(item,msg) SSPINE_LOGITEM_##item,
  805. typedef enum sspine_log_item {
  806. _SSPINE_LOG_ITEMS
  807. } sspine_log_item;
  808. #undef _SSPINE_LOGITEM_XMACRO
  809. typedef struct sspine_layer_transform {
  810. sspine_vec2 size;
  811. sspine_vec2 origin;
  812. } sspine_layer_transform;
  813. typedef struct sspine_bone_transform {
  814. sspine_vec2 position;
  815. float rotation; // in degrees
  816. sspine_vec2 scale;
  817. sspine_vec2 shear; // in degrees
  818. } sspine_bone_transform;
  819. typedef struct sspine_context_desc {
  820. int max_vertices;
  821. int max_commands;
  822. sg_pixel_format color_format;
  823. sg_pixel_format depth_format;
  824. int sample_count;
  825. sg_color_mask color_write_mask;
  826. } sspine_context_desc;
  827. typedef struct sspine_context_info {
  828. int num_vertices; // current number of vertices
  829. int num_indices; // current number of indices
  830. int num_commands; // current number of commands
  831. } sspine_context_info;
  832. typedef struct sspine_image_info {
  833. bool valid;
  834. sg_image sgimage;
  835. sg_sampler sgsampler;
  836. sg_filter min_filter;
  837. sg_filter mag_filter;
  838. sg_filter mipmap_filter;
  839. sg_wrap wrap_u;
  840. sg_wrap wrap_v;
  841. int width;
  842. int height;
  843. bool premul_alpha;
  844. sspine_string filename;
  845. } sspine_image_info;
  846. typedef struct sspine_atlas_overrides {
  847. sg_filter min_filter;
  848. sg_filter mag_filter;
  849. sg_filter mipmap_filter;
  850. sg_wrap wrap_u;
  851. sg_wrap wrap_v;
  852. bool premul_alpha_enabled;
  853. bool premul_alpha_disabled;
  854. } sspine_atlas_overrides;
  855. typedef struct sspine_atlas_desc {
  856. sspine_range data;
  857. sspine_atlas_overrides override;
  858. } sspine_atlas_desc;
  859. typedef struct sspine_atlas_page_info {
  860. bool valid;
  861. sspine_atlas atlas;
  862. sspine_image_info image;
  863. sspine_atlas_overrides overrides;
  864. } sspine_atlas_page_info;
  865. typedef struct sspine_skeleton_desc {
  866. sspine_atlas atlas;
  867. float prescale;
  868. float anim_default_mix;
  869. const char* json_data;
  870. sspine_range binary_data;
  871. } sspine_skeleton_desc;
  872. typedef struct sspine_skinset_desc {
  873. sspine_skeleton skeleton;
  874. sspine_skin skins[SSPINE_MAX_SKINSET_SKINS];
  875. } sspine_skinset_desc;
  876. typedef struct sspine_anim_info {
  877. bool valid;
  878. int index;
  879. float duration;
  880. sspine_string name;
  881. } sspine_anim_info;
  882. typedef struct sspine_bone_info {
  883. bool valid;
  884. int index;
  885. sspine_bone parent_bone;
  886. float length;
  887. sspine_bone_transform pose;
  888. sspine_color color;
  889. sspine_string name;
  890. } sspine_bone_info;
  891. typedef struct sspine_slot_info {
  892. bool valid;
  893. int index;
  894. sspine_bone bone;
  895. sspine_color color;
  896. sspine_string attachment_name;
  897. sspine_string name;
  898. } sspine_slot_info;
  899. typedef struct sspine_iktarget_info {
  900. bool valid;
  901. int index;
  902. sspine_bone target_bone;
  903. sspine_string name;
  904. } sspine_iktarget_info;
  905. typedef struct sspine_skin_info {
  906. bool valid;
  907. int index;
  908. sspine_string name;
  909. } sspine_skin_info;
  910. typedef struct sspine_event_info {
  911. bool valid;
  912. int index;
  913. int int_value;
  914. float float_value;
  915. float volume;
  916. float balance;
  917. sspine_string name;
  918. sspine_string string_value;
  919. sspine_string audio_path;
  920. } sspine_event_info;
  921. typedef struct sspine_triggered_event_info {
  922. bool valid;
  923. sspine_event event;
  924. float time;
  925. int int_value;
  926. float float_value;
  927. float volume;
  928. float balance;
  929. sspine_string string_value;
  930. } sspine_triggered_event_info;
  931. typedef struct sspine_instance_desc {
  932. sspine_skeleton skeleton;
  933. } sspine_instance_desc;
  934. typedef struct sspine_allocator {
  935. void* (*alloc_fn)(size_t size, void* user_data);
  936. void (*free_fn)(void* ptr, void* user_data);
  937. void* user_data;
  938. } sspine_allocator;
  939. typedef struct sspine_logger {
  940. void (*func)(
  941. const char* tag, // always "sspine"
  942. uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
  943. uint32_t log_item_id, // SSPINE_LOGITEM_*
  944. const char* message_or_null, // a message string, may be nullptr in release mode
  945. uint32_t line_nr, // line number in sokol_spine.h
  946. const char* filename_or_null, // the source filename, may be nullptr in release mode
  947. void* user_data);
  948. void* user_data;
  949. } sspine_logger;
  950. typedef struct sspine_desc {
  951. int max_vertices;
  952. int max_commands;
  953. int context_pool_size;
  954. int atlas_pool_size;
  955. int skeleton_pool_size;
  956. int skinset_pool_size;
  957. int instance_pool_size;
  958. sg_pixel_format color_format;
  959. sg_pixel_format depth_format;
  960. int sample_count;
  961. sg_color_mask color_write_mask;
  962. sspine_allocator allocator; // optional allocation override functions (default: malloc/free)
  963. sspine_logger logger; // optional logging function (default: NO LOGGING!)
  964. } sspine_desc;
  965. // setup/shutdown
  966. SOKOL_SPINE_API_DECL void sspine_setup(const sspine_desc* desc);
  967. SOKOL_SPINE_API_DECL void sspine_shutdown(void);
  968. // context functions
  969. SOKOL_SPINE_API_DECL sspine_context sspine_make_context(const sspine_context_desc* desc);
  970. SOKOL_SPINE_API_DECL void sspine_destroy_context(sspine_context ctx);
  971. SOKOL_SPINE_API_DECL void sspine_set_context(sspine_context ctx);
  972. SOKOL_SPINE_API_DECL sspine_context sspine_get_context(void);
  973. SOKOL_SPINE_API_DECL sspine_context sspine_default_context(void);
  974. SOKOL_SPINE_API_DECL sspine_context_info sspine_get_context_info(sspine_context ctx);
  975. // create and destroy spine objects
  976. SOKOL_SPINE_API_DECL sspine_atlas sspine_make_atlas(const sspine_atlas_desc* desc);
  977. SOKOL_SPINE_API_DECL sspine_skeleton sspine_make_skeleton(const sspine_skeleton_desc* desc);
  978. SOKOL_SPINE_API_DECL sspine_skinset sspine_make_skinset(const sspine_skinset_desc* desc);
  979. SOKOL_SPINE_API_DECL sspine_instance sspine_make_instance(const sspine_instance_desc* desc);
  980. SOKOL_SPINE_API_DECL void sspine_destroy_atlas(sspine_atlas atlas);
  981. SOKOL_SPINE_API_DECL void sspine_destroy_skeleton(sspine_skeleton skeleton);
  982. SOKOL_SPINE_API_DECL void sspine_destroy_skinset(sspine_skinset skinset);
  983. SOKOL_SPINE_API_DECL void sspine_destroy_instance(sspine_instance instance);
  984. // configure instance appearance via skinsets
  985. SOKOL_SPINE_API_DECL void sspine_set_skinset(sspine_instance instance, sspine_skinset skinset);
  986. // update instance animations before drawing
  987. SOKOL_SPINE_API_DECL void sspine_update_instance(sspine_instance instance, float delta_time);
  988. // iterate over triggered events after updating an instance
  989. SOKOL_SPINE_API_DECL int sspine_num_triggered_events(sspine_instance instance);
  990. SOKOL_SPINE_API_DECL sspine_triggered_event_info sspine_get_triggered_event_info(sspine_instance instance, int triggered_event_index);
  991. // draw instance into current or explicit context
  992. SOKOL_SPINE_API_DECL void sspine_draw_instance_in_layer(sspine_instance instance, int layer);
  993. SOKOL_SPINE_API_DECL void sspine_context_draw_instance_in_layer(sspine_context ctx, sspine_instance instance, int layer);
  994. // helper function to convert sspine_layer_transform into projection matrix
  995. SOKOL_SPINE_API_DECL sspine_mat4 sspine_layer_transform_to_mat4(const sspine_layer_transform* tform);
  996. // draw a layer in current context or explicit context (call once per context and frame in sokol-gfx pass)
  997. SOKOL_SPINE_API_DECL void sspine_draw_layer(int layer, const sspine_layer_transform* tform);
  998. SOKOL_SPINE_API_DECL void sspine_context_draw_layer(sspine_context ctx, int layer, const sspine_layer_transform* tform);
  999. // get current resource state (INITIAL, ALLOC, VALID, FAILED, INVALID)
  1000. SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_context_resource_state(sspine_context context);
  1001. SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas);
  1002. SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton);
  1003. SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skinset_resource_state(sspine_skinset skinset);
  1004. SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance);
  1005. // shortcut for sspine_get_*_state() == SSPINE_RESOURCESTATE_VALID
  1006. SOKOL_SPINE_API_DECL bool sspine_context_valid(sspine_context context);
  1007. SOKOL_SPINE_API_DECL bool sspine_atlas_valid(sspine_atlas atlas);
  1008. SOKOL_SPINE_API_DECL bool sspine_skeleton_valid(sspine_skeleton skeleton);
  1009. SOKOL_SPINE_API_DECL bool sspine_instance_valid(sspine_instance instance);
  1010. SOKOL_SPINE_API_DECL bool sspine_skinset_valid(sspine_skinset skinset);
  1011. // get dependency objects
  1012. SOKOL_SPINE_API_DECL sspine_atlas sspine_get_skeleton_atlas(sspine_skeleton skeleton);
  1013. SOKOL_SPINE_API_DECL sspine_skeleton sspine_get_instance_skeleton(sspine_instance instance);
  1014. // atlas images
  1015. SOKOL_SPINE_API_DECL int sspine_num_images(sspine_atlas atlas);
  1016. SOKOL_SPINE_API_DECL sspine_image sspine_image_by_index(sspine_atlas atlas, int index);
  1017. SOKOL_SPINE_API_DECL bool sspine_image_valid(sspine_image image);
  1018. SOKOL_SPINE_API_DECL bool sspine_image_equal(sspine_image first, sspine_image second);
  1019. SOKOL_SPINE_API_DECL sspine_image_info sspine_get_image_info(sspine_image image);
  1020. // atlas page functions
  1021. SOKOL_SPINE_API_DECL int sspine_num_atlas_pages(sspine_atlas atlas);
  1022. SOKOL_SPINE_API_DECL sspine_atlas_page sspine_atlas_page_by_index(sspine_atlas atlas, int index);
  1023. SOKOL_SPINE_API_DECL bool sspine_atlas_page_valid(sspine_atlas_page page);
  1024. SOKOL_SPINE_API_DECL bool sspine_atlas_page_equal(sspine_atlas_page first, sspine_atlas_page second);
  1025. SOKOL_SPINE_API_DECL sspine_atlas_page_info sspine_get_atlas_page_info(sspine_atlas_page page);
  1026. // instance transform functions
  1027. SOKOL_SPINE_API_DECL void sspine_set_position(sspine_instance instance, sspine_vec2 position);
  1028. SOKOL_SPINE_API_DECL void sspine_set_scale(sspine_instance instance, sspine_vec2 scale);
  1029. SOKOL_SPINE_API_DECL void sspine_set_color(sspine_instance instance, sspine_color color);
  1030. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_position(sspine_instance instance);
  1031. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_scale(sspine_instance instance);
  1032. SOKOL_SPINE_API_DECL sspine_color sspine_get_color(sspine_instance instance);
  1033. // instance animation functions
  1034. SOKOL_SPINE_API_DECL int sspine_num_anims(sspine_skeleton skeleton);
  1035. SOKOL_SPINE_API_DECL sspine_anim sspine_anim_by_name(sspine_skeleton skeleton, const char* name);
  1036. SOKOL_SPINE_API_DECL sspine_anim sspine_anim_by_index(sspine_skeleton skeleton, int index);
  1037. SOKOL_SPINE_API_DECL bool sspine_anim_valid(sspine_anim anim);
  1038. SOKOL_SPINE_API_DECL bool sspine_anim_equal(sspine_anim first, sspine_anim second);
  1039. SOKOL_SPINE_API_DECL sspine_anim_info sspine_get_anim_info(sspine_anim anim);
  1040. SOKOL_SPINE_API_DECL void sspine_clear_animation_tracks(sspine_instance instance);
  1041. SOKOL_SPINE_API_DECL void sspine_clear_animation_track(sspine_instance instance, int track_index);
  1042. SOKOL_SPINE_API_DECL void sspine_set_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop);
  1043. SOKOL_SPINE_API_DECL void sspine_add_animation(sspine_instance instance, sspine_anim anim, int track_index, bool loop, float delay);
  1044. SOKOL_SPINE_API_DECL void sspine_set_empty_animation(sspine_instance instance, int track_index, float mix_duration);
  1045. SOKOL_SPINE_API_DECL void sspine_add_empty_animation(sspine_instance instance, int track_index, float mix_duration, float delay);
  1046. // bone functions
  1047. SOKOL_SPINE_API_DECL int sspine_num_bones(sspine_skeleton skeleton);
  1048. SOKOL_SPINE_API_DECL sspine_bone sspine_bone_by_name(sspine_skeleton skeleton, const char* name);
  1049. SOKOL_SPINE_API_DECL sspine_bone sspine_bone_by_index(sspine_skeleton skeleton, int index);
  1050. SOKOL_SPINE_API_DECL bool sspine_bone_valid(sspine_bone bone);
  1051. SOKOL_SPINE_API_DECL bool sspine_bone_equal(sspine_bone first, sspine_bone second);
  1052. SOKOL_SPINE_API_DECL sspine_bone_info sspine_get_bone_info(sspine_bone bone);
  1053. SOKOL_SPINE_API_DECL void sspine_set_bone_transform(sspine_instance instance, sspine_bone bone, const sspine_bone_transform* transform);
  1054. SOKOL_SPINE_API_DECL void sspine_set_bone_position(sspine_instance instance, sspine_bone bone, sspine_vec2 position);
  1055. SOKOL_SPINE_API_DECL void sspine_set_bone_rotation(sspine_instance instance, sspine_bone bone, float rotation);
  1056. SOKOL_SPINE_API_DECL void sspine_set_bone_scale(sspine_instance instance, sspine_bone bone, sspine_vec2 scale);
  1057. SOKOL_SPINE_API_DECL void sspine_set_bone_shear(sspine_instance instance, sspine_bone bone, sspine_vec2 shear);
  1058. SOKOL_SPINE_API_DECL sspine_bone_transform sspine_get_bone_transform(sspine_instance instance, sspine_bone bone);
  1059. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_position(sspine_instance instance, sspine_bone bone);
  1060. SOKOL_SPINE_API_DECL float sspine_get_bone_rotation(sspine_instance instance, sspine_bone bone);
  1061. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_scale(sspine_instance instance, sspine_bone bone);
  1062. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_shear(sspine_instance instance, sspine_bone bone);
  1063. SOKOL_SPINE_API_DECL sspine_vec2 sspine_get_bone_world_position(sspine_instance instance, sspine_bone bone);
  1064. SOKOL_SPINE_API_DECL sspine_vec2 sspine_bone_local_to_world(sspine_instance instance, sspine_bone bone, sspine_vec2 local_pos);
  1065. SOKOL_SPINE_API_DECL sspine_vec2 sspine_bone_world_to_local(sspine_instance instance, sspine_bone bone, sspine_vec2 world_pos);
  1066. // slot functions
  1067. SOKOL_SPINE_API_DECL int sspine_num_slots(sspine_skeleton skeleton);
  1068. SOKOL_SPINE_API_DECL sspine_slot sspine_slot_by_name(sspine_skeleton skeleton, const char* name);
  1069. SOKOL_SPINE_API_DECL sspine_slot sspine_slot_by_index(sspine_skeleton skeleton, int index);
  1070. SOKOL_SPINE_API_DECL bool sspine_slot_valid(sspine_slot slot);
  1071. SOKOL_SPINE_API_DECL bool sspine_slot_equal(sspine_slot first, sspine_slot second);
  1072. SOKOL_SPINE_API_DECL sspine_slot_info sspine_get_slot_info(sspine_slot slot);
  1073. SOKOL_SPINE_API_DECL void sspine_set_slot_color(sspine_instance instance, sspine_slot slot, sspine_color color);
  1074. SOKOL_SPINE_API_DECL sspine_color sspine_get_slot_color(sspine_instance instance, sspine_slot slot);
  1075. // event functions
  1076. SOKOL_SPINE_API_DECL int sspine_num_events(sspine_skeleton skeleton);
  1077. SOKOL_SPINE_API_DECL sspine_event sspine_event_by_name(sspine_skeleton skeleton, const char* name);
  1078. SOKOL_SPINE_API_DECL sspine_event sspine_event_by_index(sspine_skeleton skeleton, int index);
  1079. SOKOL_SPINE_API_DECL bool sspine_event_valid(sspine_event event);
  1080. SOKOL_SPINE_API_DECL bool sspine_event_equal(sspine_event first, sspine_event second);
  1081. SOKOL_SPINE_API_DECL sspine_event_info sspine_get_event_info(sspine_event event);
  1082. // ik target functions
  1083. SOKOL_SPINE_API_DECL int sspine_num_iktargets(sspine_skeleton skeleton);
  1084. SOKOL_SPINE_API_DECL sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton, const char* name);
  1085. SOKOL_SPINE_API_DECL sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton, int index);
  1086. SOKOL_SPINE_API_DECL bool sspine_iktarget_valid(sspine_iktarget iktarget);
  1087. SOKOL_SPINE_API_DECL bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second);
  1088. SOKOL_SPINE_API_DECL sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget);
  1089. SOKOL_SPINE_API_DECL void sspine_set_iktarget_world_pos(sspine_instance instance, sspine_iktarget iktarget, sspine_vec2 world_pos);
  1090. // skin functions
  1091. SOKOL_SPINE_API_DECL int sspine_num_skins(sspine_skeleton skeleton);
  1092. SOKOL_SPINE_API_DECL sspine_skin sspine_skin_by_name(sspine_skeleton skeleton, const char* name);
  1093. SOKOL_SPINE_API_DECL sspine_skin sspine_skin_by_index(sspine_skeleton skeleton, int index);
  1094. SOKOL_SPINE_API_DECL bool sspine_skin_valid(sspine_skin skin);
  1095. SOKOL_SPINE_API_DECL bool sspine_skin_equal(sspine_skin first, sspine_skin second);
  1096. SOKOL_SPINE_API_DECL sspine_skin_info sspine_get_skin_info(sspine_skin skin);
  1097. SOKOL_SPINE_API_DECL void sspine_set_skin(sspine_instance instance, sspine_skin skin);
  1098. #ifdef __cplusplus
  1099. } // extern "C"
  1100. #endif
  1101. // ██ ███ ███ ██████ ██ ███████ ███ ███ ███████ ███ ██ ████████ █████ ████████ ██ ██████ ███ ██
  1102. // ██ ████ ████ ██ ██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
  1103. // ██ ██ ████ ██ ██████ ██ █████ ██ ████ ██ █████ ██ ██ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ██
  1104. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  1105. // ██ ██ ██ ██ ███████ ███████ ██ ██ ███████ ██ ████ ██ ██ ██ ██ ██ ██████ ██ ████
  1106. //
  1107. // >>implementation
  1108. #ifdef SOKOL_SPINE_IMPL
  1109. #define SOKOL_SPINE_IMPL_INCLUDED (1)
  1110. #if !defined(SPINE_SPINE_H_)
  1111. #error "Please include spine/spine.h before the sokol_spine.h implementation"
  1112. #endif
  1113. #ifndef SOKOL_API_IMPL
  1114. #define SOKOL_API_IMPL
  1115. #endif
  1116. #ifndef SOKOL_DEBUG
  1117. #ifndef NDEBUG
  1118. #define SOKOL_DEBUG (1)
  1119. #endif
  1120. #endif
  1121. #ifndef SOKOL_ASSERT
  1122. #include <assert.h>
  1123. #define SOKOL_ASSERT(c) assert(c)
  1124. #endif
  1125. #ifndef SOKOL_UNREACHABLE
  1126. #define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
  1127. #endif
  1128. #ifndef SOKOL_UNUSED
  1129. #define SOKOL_UNUSED(x) (void)(x)
  1130. #endif
  1131. #include <stdlib.h> // malloc/free
  1132. #include <string.h> // memset, strcmp
  1133. // ███████╗██╗ ██╗ █████╗ ██████╗ ███████╗██████╗ ███████╗
  1134. // ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝██╔══██╗██╔════╝
  1135. // ███████╗███████║███████║██║ ██║█████╗ ██████╔╝███████╗
  1136. // ╚════██║██╔══██║██╔══██║██║ ██║██╔══╝ ██╔══██╗╚════██║
  1137. // ███████║██║ ██║██║ ██║██████╔╝███████╗██║ ██║███████║
  1138. // ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝╚══════╝
  1139. //
  1140. // >>shaders
  1141. /*
  1142. Embedded source compiled with:
  1143. sokol-shdc -i sspine.glsl -o sspine.h -l glsl410:glsl300es:hlsl4:metal_macos:metal_ios:metal_sim:wgsl -b
  1144. @vs vs
  1145. layout(binding=0) uniform vs_params {
  1146. mat4 mvp;
  1147. };
  1148. in vec2 position;
  1149. in vec2 texcoord0;
  1150. in vec4 color0;
  1151. out vec2 uv;
  1152. out vec4 color;
  1153. void main() {
  1154. gl_Position = mvp * vec4(position, 0.0, 1.0);
  1155. uv = texcoord0;
  1156. color = color0;
  1157. }
  1158. @end
  1159. @fs fs
  1160. layout(binding=0) uniform texture2D tex;
  1161. layout(binding=0) uniform sampler smp;
  1162. layout(binding=1) uniform fs_params {
  1163. float pma;
  1164. };
  1165. in vec2 uv;
  1166. in vec4 color;
  1167. out vec4 frag_color;
  1168. void main() {
  1169. vec4 c0 = texture(sampler2D(tex, smp), uv) * color;
  1170. vec4 c1 = vec4(c0.rgb * c0.a, c0.a) * color;
  1171. frag_color = mix(c0, c1, pma);
  1172. }
  1173. @end
  1174. @program sspine vs fs
  1175. */
  1176. #if defined(SOKOL_GLCORE)
  1177. /*
  1178. #version 410
  1179. uniform vec4 vs_params[4];
  1180. layout(location = 0) in vec2 position;
  1181. layout(location = 0) out vec2 uv;
  1182. layout(location = 1) in vec2 texcoord0;
  1183. layout(location = 1) out vec4 color;
  1184. layout(location = 2) in vec4 color0;
  1185. void main()
  1186. {
  1187. gl_Position = mat4(vs_params[0], vs_params[1], vs_params[2], vs_params[3]) * vec4(position, 0.0, 1.0);
  1188. uv = texcoord0;
  1189. color = color0;
  1190. }
  1191. */
  1192. static const uint8_t _sspine_vs_source_glsl410[394] = {
  1193. 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x31,0x30,0x0a,0x0a,0x75,0x6e,
  1194. 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61,
  1195. 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,
  1196. 0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,
  1197. 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3b,0x0a,
  1198. 0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,
  1199. 0x3d,0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,
  1200. 0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,
  1201. 0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x74,
  1202. 0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,
  1203. 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x6f,
  1204. 0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,
  1205. 0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,
  1206. 0x20,0x32,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,
  1207. 0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,
  1208. 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,
  1209. 0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x76,0x73,0x5f,0x70,0x61,0x72,
  1210. 0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
  1211. 0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,
  1212. 0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33,0x5d,
  1213. 0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x34,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,
  1214. 0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,
  1215. 0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,
  1216. 0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,
  1217. 0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  1218. };
  1219. /*
  1220. #version 410
  1221. uniform vec4 fs_params[1];
  1222. uniform sampler2D tex_smp;
  1223. layout(location = 0) in vec2 uv;
  1224. layout(location = 1) in vec4 color;
  1225. layout(location = 0) out vec4 frag_color;
  1226. void main()
  1227. {
  1228. vec4 _28 = texture(tex_smp, uv) * color;
  1229. float _37 = _28.w;
  1230. frag_color = mix(_28, vec4(_28.xyz * _37, _37) * color, vec4(fs_params[0].x));
  1231. }
  1232. */
  1233. static const uint8_t _sspine_fs_source_glsl410[350] = {
  1234. 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x31,0x30,0x0a,0x0a,0x75,0x6e,
  1235. 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x73,0x5f,0x70,0x61,
  1236. 0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,
  1237. 0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x5f,0x73,
  1238. 0x6d,0x70,0x3b,0x0a,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,
  1239. 0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,
  1240. 0x32,0x20,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,
  1241. 0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,
  1242. 0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,
  1243. 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f,
  1244. 0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,
  1245. 0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,
  1246. 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x32,0x38,0x20,
  1247. 0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x5f,0x73,0x6d,
  1248. 0x70,0x2c,0x20,0x75,0x76,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,
  1249. 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33,0x37,0x20,0x3d,0x20,
  1250. 0x5f,0x32,0x38,0x2e,0x77,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,
  1251. 0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f,0x32,0x38,0x2c,
  1252. 0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,0x38,0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,
  1253. 0x5f,0x33,0x37,0x2c,0x20,0x5f,0x33,0x37,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,
  1254. 0x72,0x2c,0x20,0x76,0x65,0x63,0x34,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
  1255. 0x73,0x5b,0x30,0x5d,0x2e,0x78,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  1256. };
  1257. #elif defined(SOKOL_GLES3)
  1258. /*
  1259. #version 300 es
  1260. uniform vec4 vs_params[4];
  1261. layout(location = 0) in vec2 position;
  1262. out vec2 uv;
  1263. layout(location = 1) in vec2 texcoord0;
  1264. out vec4 color;
  1265. layout(location = 2) in vec4 color0;
  1266. void main()
  1267. {
  1268. gl_Position = mat4(vs_params[0], vs_params[1], vs_params[2], vs_params[3]) * vec4(position, 0.0, 1.0);
  1269. uv = texcoord0;
  1270. color = color0;
  1271. }
  1272. */
  1273. static const uint8_t _sspine_vs_source_glsl300es[355] = {
  1274. 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a,
  1275. 0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,
  1276. 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,
  1277. 0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,
  1278. 0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,
  1279. 0x6e,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,
  1280. 0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,
  1281. 0x3d,0x20,0x31,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78,
  1282. 0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,
  1283. 0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,
  1284. 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x32,0x29,0x20,0x69,0x6e,0x20,
  1285. 0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,
  1286. 0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,
  1287. 0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,
  1288. 0x74,0x34,0x28,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,
  1289. 0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,
  1290. 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,
  1291. 0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33,0x5d,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,
  1292. 0x34,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,
  1293. 0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x20,0x3d,0x20,
  1294. 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,
  1295. 0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,
  1296. 0x0a,0x0a,0x00,
  1297. };
  1298. /*
  1299. #version 300 es
  1300. precision mediump float;
  1301. precision highp int;
  1302. uniform highp vec4 fs_params[1];
  1303. uniform highp sampler2D tex_smp;
  1304. in highp vec2 uv;
  1305. in highp vec4 color;
  1306. layout(location = 0) out highp vec4 frag_color;
  1307. void main()
  1308. {
  1309. highp vec4 _28 = texture(tex_smp, uv) * color;
  1310. highp float _37 = _28.w;
  1311. frag_color = mix(_28, vec4(_28.xyz * _37, _37) * color, vec4(fs_params[0].x));
  1312. }
  1313. */
  1314. static const uint8_t _sspine_fs_source_glsl300es[399] = {
  1315. 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a,
  1316. 0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,0x6d,0x65,0x64,0x69,0x75,0x6d,
  1317. 0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x3b,0x0a,0x70,0x72,0x65,0x63,0x69,0x73,0x69,
  1318. 0x6f,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x69,0x6e,0x74,0x3b,0x0a,0x0a,0x75,
  1319. 0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,
  1320. 0x34,0x20,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,
  1321. 0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x73,0x61,
  1322. 0x6d,0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x5f,0x73,0x6d,0x70,0x3b,
  1323. 0x0a,0x0a,0x69,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,
  1324. 0x75,0x76,0x3b,0x0a,0x69,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,
  1325. 0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,
  1326. 0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f,0x75,
  1327. 0x74,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,
  1328. 0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,
  1329. 0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x68,0x69,0x67,0x68,
  1330. 0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x5f,0x32,0x38,0x20,0x3d,0x20,0x74,0x65,0x78,
  1331. 0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x5f,0x73,0x6d,0x70,0x2c,0x20,0x75,0x76,
  1332. 0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x20,0x20,0x68,
  1333. 0x69,0x67,0x68,0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33,0x37,0x20,0x3d,
  1334. 0x20,0x5f,0x32,0x38,0x2e,0x77,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x72,0x61,0x67,
  1335. 0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f,0x32,0x38,
  1336. 0x2c,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,0x38,0x2e,0x78,0x79,0x7a,0x20,0x2a,
  1337. 0x20,0x5f,0x33,0x37,0x2c,0x20,0x5f,0x33,0x37,0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,
  1338. 0x6f,0x72,0x2c,0x20,0x76,0x65,0x63,0x34,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,
  1339. 0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  1340. };
  1341. #elif defined(SOKOL_D3D11)
  1342. /*
  1343. cbuffer vs_params : register(b0)
  1344. {
  1345. row_major float4x4 _19_mvp : packoffset(c0);
  1346. };
  1347. static float4 gl_Position;
  1348. static float2 position;
  1349. static float2 uv;
  1350. static float2 texcoord0;
  1351. static float4 color;
  1352. static float4 color0;
  1353. struct SPIRV_Cross_Input
  1354. {
  1355. float2 position : TEXCOORD0;
  1356. float2 texcoord0 : TEXCOORD1;
  1357. float4 color0 : TEXCOORD2;
  1358. };
  1359. struct SPIRV_Cross_Output
  1360. {
  1361. float2 uv : TEXCOORD0;
  1362. float4 color : TEXCOORD1;
  1363. float4 gl_Position : SV_Position;
  1364. };
  1365. void vert_main()
  1366. {
  1367. gl_Position = mul(float4(position, 0.0f, 1.0f), _19_mvp);
  1368. uv = texcoord0;
  1369. color = color0;
  1370. }
  1371. SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
  1372. {
  1373. position = stage_input.position;
  1374. texcoord0 = stage_input.texcoord0;
  1375. color0 = stage_input.color0;
  1376. vert_main();
  1377. SPIRV_Cross_Output stage_output;
  1378. stage_output.gl_Position = gl_Position;
  1379. stage_output.uv = uv;
  1380. stage_output.color = color;
  1381. return stage_output;
  1382. }
  1383. */
  1384. static const uint8_t _sspine_vs_bytecode_hlsl4[844] = {
  1385. 0x44,0x58,0x42,0x43,0x2a,0xc9,0x57,0x52,0x4b,0x3d,0x3e,0x89,0x00,0xf4,0xfa,0x41,
  1386. 0xfd,0xd7,0x63,0xc3,0x01,0x00,0x00,0x00,0x4c,0x03,0x00,0x00,0x05,0x00,0x00,0x00,
  1387. 0x34,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x58,0x01,0x00,0x00,0xc8,0x01,0x00,0x00,
  1388. 0xd0,0x02,0x00,0x00,0x52,0x44,0x45,0x46,0xb8,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
  1389. 0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xfe,0xff,
  1390. 0x10,0x81,0x00,0x00,0x90,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1391. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1392. 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
  1393. 0x73,0x00,0xab,0xab,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
  1394. 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
  1395. 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
  1396. 0x00,0x00,0x00,0x00,0x5f,0x31,0x39,0x5f,0x6d,0x76,0x70,0x00,0x02,0x00,0x03,0x00,
  1397. 0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x69,0x63,0x72,
  1398. 0x6f,0x73,0x6f,0x66,0x74,0x20,0x28,0x52,0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53,
  1399. 0x68,0x61,0x64,0x65,0x72,0x20,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31,
  1400. 0x30,0x2e,0x31,0x00,0x49,0x53,0x47,0x4e,0x5c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
  1401. 0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1402. 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x50,0x00,0x00,0x00,
  1403. 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
  1404. 0x03,0x03,0x00,0x00,0x50,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1405. 0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43,
  1406. 0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab,0x4f,0x53,0x47,0x4e,0x68,0x00,0x00,0x00,
  1407. 0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1408. 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0c,0x00,0x00,
  1409. 0x50,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
  1410. 0x01,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1411. 0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,
  1412. 0x54,0x45,0x58,0x43,0x4f,0x4f,0x52,0x44,0x00,0x53,0x56,0x5f,0x50,0x6f,0x73,0x69,
  1413. 0x74,0x69,0x6f,0x6e,0x00,0xab,0xab,0xab,0x53,0x48,0x44,0x52,0x00,0x01,0x00,0x00,
  1414. 0x40,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x59,0x00,0x00,0x04,0x46,0x8e,0x20,0x00,
  1415. 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x32,0x10,0x10,0x00,
  1416. 0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x32,0x10,0x10,0x00,0x01,0x00,0x00,0x00,
  1417. 0x5f,0x00,0x00,0x03,0xf2,0x10,0x10,0x00,0x02,0x00,0x00,0x00,0x65,0x00,0x00,0x03,
  1418. 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00,
  1419. 0x01,0x00,0x00,0x00,0x67,0x00,0x00,0x04,0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00,
  1420. 0x01,0x00,0x00,0x00,0x68,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x36,0x00,0x00,0x05,
  1421. 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x10,0x00,0x01,0x00,0x00,0x00,
  1422. 0x36,0x00,0x00,0x05,0xf2,0x20,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,
  1423. 0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x08,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
  1424. 0x56,0x15,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,
  1425. 0x01,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
  1426. 0x06,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,
  1427. 0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
  1428. 0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,
  1429. 0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x3e,0x00,0x00,0x01,
  1430. 0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
  1431. 0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1432. 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1433. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1434. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1435. 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1436. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1437. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1438. };
  1439. /*
  1440. cbuffer fs_params : register(b0)
  1441. {
  1442. float _53_pma : packoffset(c0);
  1443. };
  1444. Texture2D<float4> tex : register(t0);
  1445. SamplerState smp : register(s0);
  1446. static float2 uv;
  1447. static float4 color;
  1448. static float4 frag_color;
  1449. struct SPIRV_Cross_Input
  1450. {
  1451. float2 uv : TEXCOORD0;
  1452. float4 color : TEXCOORD1;
  1453. };
  1454. struct SPIRV_Cross_Output
  1455. {
  1456. float4 frag_color : SV_Target0;
  1457. };
  1458. void frag_main()
  1459. {
  1460. float4 _28 = tex.Sample(smp, uv) * color;
  1461. float _37 = _28.w;
  1462. frag_color = lerp(_28, float4(_28.xyz * _37, _37) * color, _53_pma.xxxx);
  1463. }
  1464. SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
  1465. {
  1466. uv = stage_input.uv;
  1467. color = stage_input.color;
  1468. frag_main();
  1469. SPIRV_Cross_Output stage_output;
  1470. stage_output.frag_color = frag_color;
  1471. return stage_output;
  1472. }
  1473. */
  1474. static const uint8_t _sspine_fs_bytecode_hlsl4[868] = {
  1475. 0x44,0x58,0x42,0x43,0xfb,0x9d,0xdb,0x19,0x85,0xbc,0x50,0x5d,0x6b,0x03,0xd4,0xc8,
  1476. 0x1b,0xea,0x59,0xf5,0x01,0x00,0x00,0x00,0x64,0x03,0x00,0x00,0x05,0x00,0x00,0x00,
  1477. 0x34,0x00,0x00,0x00,0x3c,0x01,0x00,0x00,0x88,0x01,0x00,0x00,0xbc,0x01,0x00,0x00,
  1478. 0xe8,0x02,0x00,0x00,0x52,0x44,0x45,0x46,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,
  1479. 0x90,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xff,0xff,
  1480. 0x10,0x81,0x00,0x00,0xd8,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
  1481. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1482. 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
  1483. 0x05,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
  1484. 0x01,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1485. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1486. 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x73,0x6d,0x70,0x00,0x74,0x65,0x78,0x00,
  1487. 0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x00,0xab,0xab,0x84,0x00,0x00,0x00,
  1488. 0x01,0x00,0x00,0x00,0xa8,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1489. 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
  1490. 0x02,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x35,0x33,0x5f,
  1491. 0x70,0x6d,0x61,0x00,0x00,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
  1492. 0x00,0x00,0x00,0x00,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,0x20,0x28,0x52,
  1493. 0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53,0x68,0x61,0x64,0x65,0x72,0x20,0x43,0x6f,
  1494. 0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31,0x30,0x2e,0x31,0x00,0x49,0x53,0x47,0x4e,
  1495. 0x44,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
  1496. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1497. 0x03,0x03,0x00,0x00,0x38,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1498. 0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43,
  1499. 0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab,0x4f,0x53,0x47,0x4e,0x2c,0x00,0x00,0x00,
  1500. 0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1501. 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,
  1502. 0x53,0x56,0x5f,0x54,0x61,0x72,0x67,0x65,0x74,0x00,0xab,0xab,0x53,0x48,0x44,0x52,
  1503. 0x24,0x01,0x00,0x00,0x40,0x00,0x00,0x00,0x49,0x00,0x00,0x00,0x59,0x00,0x00,0x04,
  1504. 0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x5a,0x00,0x00,0x03,
  1505. 0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x58,0x18,0x00,0x04,0x00,0x70,0x10,0x00,
  1506. 0x00,0x00,0x00,0x00,0x55,0x55,0x00,0x00,0x62,0x10,0x00,0x03,0x32,0x10,0x10,0x00,
  1507. 0x00,0x00,0x00,0x00,0x62,0x10,0x00,0x03,0xf2,0x10,0x10,0x00,0x01,0x00,0x00,0x00,
  1508. 0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x02,
  1509. 0x02,0x00,0x00,0x00,0x45,0x00,0x00,0x09,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
  1510. 0x46,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x7e,0x10,0x00,0x00,0x00,0x00,0x00,
  1511. 0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x07,0xf2,0x00,0x10,0x00,
  1512. 0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,
  1513. 0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x07,0x72,0x00,0x10,0x00,0x01,0x00,0x00,0x00,
  1514. 0xf6,0x0f,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x02,0x10,0x00,0x00,0x00,0x00,0x00,
  1515. 0x36,0x00,0x00,0x05,0x82,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x3a,0x00,0x10,0x00,
  1516. 0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,0xf2,0x00,0x10,0x00,0x01,0x00,0x00,0x00,
  1517. 0x46,0x0e,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,0x01,0x00,0x00,0x00,
  1518. 0x46,0x0e,0x10,0x80,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,
  1519. 0xf2,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x06,0x80,0x20,0x00,0x00,0x00,0x00,0x00,
  1520. 0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,
  1521. 0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x01,0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00,
  1522. 0x07,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
  1523. 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
  1524. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1525. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1526. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
  1527. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1528. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1529. 0x00,0x00,0x00,0x00,
  1530. };
  1531. #elif defined(SOKOL_METAL)
  1532. /*
  1533. #include <metal_stdlib>
  1534. #include <simd/simd.h>
  1535. using namespace metal;
  1536. struct vs_params
  1537. {
  1538. float4x4 mvp;
  1539. };
  1540. struct main0_out
  1541. {
  1542. float2 uv [[user(locn0)]];
  1543. float4 color [[user(locn1)]];
  1544. float4 gl_Position [[position]];
  1545. };
  1546. struct main0_in
  1547. {
  1548. float2 position [[attribute(0)]];
  1549. float2 texcoord0 [[attribute(1)]];
  1550. float4 color0 [[attribute(2)]];
  1551. };
  1552. vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _19 [[buffer(0)]])
  1553. {
  1554. main0_out out = {};
  1555. out.gl_Position = _19.mvp * float4(in.position, 0.0, 1.0);
  1556. out.uv = in.texcoord0;
  1557. out.color = in.color0;
  1558. return out;
  1559. }
  1560. */
  1561. static const uint8_t _sspine_vs_bytecode_metal_macos[3148] = {
  1562. 0x4d,0x54,0x4c,0x42,0x01,0x80,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1563. 0x4c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1564. 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1565. 0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  1566. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  1567. 0x40,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
  1568. 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
  1569. 0x01,0x00,0x00,0x48,0x41,0x53,0x48,0x20,0x00,0x04,0xdb,0x24,0x3a,0x7c,0x95,0x82,
  1570. 0x6f,0x4a,0xd6,0x7f,0x57,0x6d,0x3f,0xb7,0x34,0x4c,0x93,0x7d,0x68,0xcc,0x7f,0xc0,
  1571. 0x16,0xd5,0x32,0xe9,0xf6,0xe7,0xed,0xdd,0x00,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
  1572. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1573. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
  1574. 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x37,0x00,0x00,0x00,0x56,0x41,0x54,
  1575. 0x54,0x22,0x00,0x03,0x00,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x00,0x80,
  1576. 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x00,0x01,0x80,0x63,0x6f,0x6c,0x6f,
  1577. 0x72,0x30,0x00,0x02,0x80,0x56,0x41,0x54,0x59,0x05,0x00,0x03,0x00,0x04,0x04,0x06,
  1578. 0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,
  1579. 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x20,0x0b,0x00,0x00,0xff,0xff,0xff,0xff,
  1580. 0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0xc5,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,
  1581. 0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,
  1582. 0x06,0x10,0x32,0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,
  1583. 0x80,0x14,0x45,0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,
  1584. 0x0a,0x32,0x44,0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,
  1585. 0x24,0x07,0xc8,0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,
  1586. 0x51,0x18,0x00,0x00,0x68,0x00,0x00,0x00,0x1b,0x7e,0x24,0xf8,0xff,0xff,0xff,0xff,
  1587. 0x01,0x90,0x00,0x8a,0x08,0x07,0x78,0x80,0x07,0x79,0x78,0x07,0x7c,0x68,0x03,0x73,
  1588. 0xa8,0x07,0x77,0x18,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,
  1589. 0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xda,0x21,0x1d,0xdc,0xa1,0x0d,0xd8,
  1590. 0xa1,0x1c,0xce,0x21,0x1c,0xd8,0xa1,0x0d,0xec,0xa1,0x1c,0xc6,0x81,0x1e,0xde,0x41,
  1591. 0x1e,0xda,0xe0,0x1e,0xd2,0x81,0x1c,0xe8,0x01,0x1d,0x80,0x38,0x90,0x03,0x3c,0x00,
  1592. 0x06,0x77,0x78,0x87,0x36,0x10,0x87,0x7a,0x48,0x07,0x76,0xa0,0x87,0x74,0x70,0x87,
  1593. 0x79,0x00,0x08,0x77,0x78,0x87,0x36,0x30,0x07,0x79,0x08,0x87,0x76,0x28,0x87,0x36,
  1594. 0x80,0x87,0x77,0x48,0x07,0x77,0xa0,0x87,0x72,0x90,0x87,0x36,0x28,0x07,0x76,0x48,
  1595. 0x87,0x76,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xcc,
  1596. 0x41,0x1e,0xc2,0xa1,0x1d,0xca,0xa1,0x0d,0xe0,0xe1,0x1d,0xd2,0xc1,0x1d,0xe8,0xa1,
  1597. 0x1c,0xe4,0xa1,0x0d,0xca,0x81,0x1d,0xd2,0xa1,0x1d,0xda,0xc0,0x1d,0xde,0xc1,0x1d,
  1598. 0xda,0x80,0x1d,0xca,0x21,0x1c,0xcc,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,
  1599. 0x77,0x78,0x87,0x36,0x48,0x07,0x77,0x30,0x87,0x79,0x68,0x03,0x73,0x80,0x87,0x36,
  1600. 0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,
  1601. 0xde,0xa1,0x0d,0xdc,0x21,0x1c,0xdc,0x61,0x1e,0xda,0xc0,0x1c,0xe0,0xa1,0x0d,0xda,
  1602. 0x21,0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,0x77,
  1603. 0x68,0x83,0x79,0x48,0x87,0x73,0x70,0x87,0x72,0x20,0x87,0x36,0xd0,0x87,0x72,0x90,
  1604. 0x87,0x77,0x98,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,
  1605. 0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0x80,0x1e,0xe4,0x21,
  1606. 0x1c,0xe0,0x01,0x1e,0xd2,0xc1,0x1d,0xce,0xa1,0x0d,0xda,0x21,0x1c,0xe8,0x01,0x1d,
  1607. 0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x98,0x07,0x7a,0x08,0x87,0x71,0x58,0x87,
  1608. 0x36,0x80,0x07,0x79,0x78,0x07,0x7a,0x28,0x87,0x71,0xa0,0x87,0x77,0x90,0x87,0x36,
  1609. 0x10,0x87,0x7a,0x30,0x07,0x73,0x28,0x07,0x79,0x68,0x83,0x79,0x48,0x07,0x7d,0x28,
  1610. 0x07,0x00,0x0f,0x00,0xa2,0x1e,0xdc,0x61,0x1e,0xc2,0xc1,0x1c,0xca,0xa1,0x0d,0xcc,
  1611. 0x01,0x1e,0xda,0xa0,0x1d,0xc2,0x81,0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,
  1612. 0x00,0x36,0x18,0x02,0x01,0x2c,0x40,0x05,0x49,0x18,0x00,0x00,0x01,0x00,0x00,0x00,
  1613. 0x13,0x84,0x40,0x00,0x89,0x20,0x00,0x00,0x1f,0x00,0x00,0x00,0x32,0x22,0x48,0x09,
  1614. 0x20,0x64,0x85,0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,
  1615. 0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x44,0x33,0x00,0xc3,0x08,0x02,0x30,
  1616. 0x8c,0x40,0x00,0x76,0x08,0x42,0x24,0x81,0x98,0x89,0x9a,0x07,0x7a,0x90,0x87,0x7a,
  1617. 0x18,0x07,0x7a,0x70,0x83,0x76,0x28,0x07,0x7a,0x08,0x07,0x76,0xd0,0x03,0x3d,0x68,
  1618. 0x87,0x70,0xa0,0x07,0x79,0x48,0x07,0x7c,0x40,0x01,0x39,0x48,0x9a,0x22,0x4a,0x98,
  1619. 0xfc,0x4a,0xfa,0x1f,0x20,0x02,0x18,0x09,0x05,0x65,0x10,0xc1,0x10,0x4a,0x31,0x42,
  1620. 0x10,0x87,0xd0,0x40,0xc0,0x1c,0x01,0x18,0xa4,0xc0,0x9a,0x23,0x00,0x85,0x41,0x04,
  1621. 0x41,0x18,0x46,0x20,0x96,0x11,0x00,0x00,0x13,0xb2,0x70,0x48,0x07,0x79,0xb0,0x03,
  1622. 0x3a,0x68,0x83,0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,0x83,0x76,0x08,0x87,0x71,
  1623. 0x78,0x87,0x79,0xc0,0x87,0x38,0x80,0x03,0x37,0x88,0x83,0x38,0x70,0x03,0x38,0xd8,
  1624. 0x70,0x1b,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,
  1625. 0x07,0x76,0x40,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,
  1626. 0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x71,0x60,0x07,0x7a,
  1627. 0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73,0x20,0x07,0x7a,0x30,
  1628. 0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,
  1629. 0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,
  1630. 0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,
  1631. 0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,
  1632. 0x71,0x60,0x07,0x6d,0x60,0x0f,0x72,0x40,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,
  1633. 0x20,0x07,0x6d,0x60,0x0f,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,
  1634. 0x07,0x6d,0x60,0x0f,0x74,0x80,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,
  1635. 0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,
  1636. 0x60,0x0f,0x79,0x60,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,
  1637. 0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07,
  1638. 0x71,0x20,0x07,0x78,0xd0,0x06,0xf6,0x10,0x07,0x79,0x20,0x07,0x7a,0x20,0x07,0x75,
  1639. 0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x72,0x50,0x07,0x76,0xa0,
  1640. 0x07,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,0x50,0x07,
  1641. 0x71,0x20,0x07,0x7a,0x50,0x07,0x71,0x20,0x07,0x7a,0x50,0x07,0x71,0x20,0x07,0x6d,
  1642. 0x60,0x0f,0x71,0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xa0,
  1643. 0x07,0x71,0x00,0x07,0x72,0x40,0x07,0x6d,0xe0,0x0e,0x78,0xa0,0x07,0x71,0x60,0x07,
  1644. 0x7a,0x30,0x07,0x72,0x30,0x84,0x49,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0xc8,
  1645. 0x02,0x01,0x00,0x00,0x0a,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,
  1646. 0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x5a,0x25,0x30,0x02,0x50,0x04,0x05,0x18,0x50,
  1647. 0x08,0x05,0x51,0x06,0x05,0x42,0x6d,0x04,0x80,0xd8,0x58,0xc2,0x03,0x00,0x00,0x00,
  1648. 0x79,0x18,0x00,0x00,0xea,0x00,0x00,0x00,0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,
  1649. 0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x32,0x28,0x00,0xa3,0x50,0xb9,
  1650. 0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,0x2c,0x81,0x22,0x2c,0x05,
  1651. 0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,
  1652. 0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x06,0x04,
  1653. 0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,0xac,0x65,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,
  1654. 0xa6,0x26,0x65,0x88,0xa0,0x10,0x43,0x8c,0x25,0x58,0x8c,0x45,0x60,0xd1,0x54,0x46,
  1655. 0x17,0xc6,0x36,0x04,0x51,0x8e,0x25,0x58,0x82,0x45,0xe0,0x16,0x96,0x26,0xe7,0x32,
  1656. 0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,
  1657. 0x96,0x36,0x17,0x26,0xc6,0x56,0x36,0x44,0x50,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,
  1658. 0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,
  1659. 0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,0x43,0x04,0x65,0x61,0x19,0x84,0xa5,0xc9,0xb9,
  1660. 0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,
  1661. 0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x91,0xa5,0xcd,0x85,0x89,0xb1,
  1662. 0x95,0x0d,0x11,0x94,0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5d,0x99,0x1c,0x5d,0x19,0xde,
  1663. 0xd7,0x5b,0x1d,0x1d,0x5c,0x1d,0x1d,0x97,0xba,0xb9,0x32,0x39,0x14,0xb6,0xb7,0x31,
  1664. 0x37,0x98,0x14,0x46,0x61,0x69,0x72,0x2e,0x61,0x72,0x67,0x5f,0x74,0x79,0x70,0x65,
  1665. 0x5f,0x6e,0x61,0x6d,0x65,0x34,0xcc,0xd8,0xde,0xc2,0xe8,0x64,0xc8,0x84,0xa5,0xc9,
  1666. 0xb9,0x84,0xc9,0x9d,0x7d,0xb9,0x85,0xb5,0x95,0x51,0xa8,0xb3,0x1b,0xc2,0x28,0x8f,
  1667. 0x02,0x29,0x91,0x22,0x29,0x93,0x42,0x71,0xa9,0x9b,0x2b,0x93,0x43,0x61,0x7b,0x1b,
  1668. 0x73,0x8b,0x49,0xa1,0x61,0xc6,0xf6,0x16,0x46,0x47,0xc3,0x62,0xec,0x8d,0xed,0x4d,
  1669. 0x6e,0x08,0xa3,0x3c,0x8a,0xa5,0x44,0xca,0xa5,0x4c,0x0a,0x46,0x26,0x2c,0x4d,0xce,
  1670. 0x05,0xee,0x6d,0x2e,0x8d,0x2e,0xed,0xcd,0x8d,0xcb,0x19,0xdb,0x17,0xd4,0xdb,0x5c,
  1671. 0x1a,0x5d,0xda,0x9b,0xdb,0x10,0x45,0xd1,0x94,0x48,0xb9,0x94,0x49,0xd9,0x86,0x18,
  1672. 0x4a,0xa5,0x64,0x0a,0x47,0x28,0x2c,0x4d,0xce,0xc5,0xae,0x4c,0x8e,0xae,0x0c,0xef,
  1673. 0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x52,0x58,0x9a,0x9c,0x0b,0xdb,0xdb,0x58,0x18,0x5d,
  1674. 0xda,0x9b,0xdb,0x57,0x9a,0x1b,0x59,0x19,0x1e,0xbd,0xb3,0x32,0xb7,0x32,0xb9,0x30,
  1675. 0xba,0x32,0x32,0x94,0xaf,0xaf,0xb0,0x34,0xb9,0x2f,0x38,0xb6,0xb0,0xb1,0x32,0xb4,
  1676. 0x37,0x36,0xb2,0x32,0xb9,0xaf,0xaf,0x14,0x22,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,
  1677. 0x6e,0x43,0xa8,0x45,0x50,0x3c,0xe5,0x5b,0x84,0x25,0x50,0xc0,0x40,0x89,0x14,0x49,
  1678. 0x99,0x94,0x30,0x60,0x42,0x57,0x86,0x37,0xf6,0xf6,0x26,0x47,0x06,0x33,0x84,0x5a,
  1679. 0x02,0xc5,0x53,0xbe,0x25,0x58,0x02,0x05,0x0c,0x94,0x48,0x91,0x94,0x49,0x19,0x03,
  1680. 0x1a,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x43,0xa8,0x65,0x50,0x3c,0xe5,0x5b,0x86,0x25,
  1681. 0x50,0xc0,0x40,0x89,0x94,0x4b,0x99,0x94,0x32,0xa0,0x12,0x96,0x26,0xe7,0x22,0x56,
  1682. 0x67,0x66,0x56,0x26,0xc7,0x27,0x2c,0x4d,0xce,0x45,0xac,0xce,0xcc,0xac,0x4c,0xee,
  1683. 0x6b,0x2e,0x4d,0xaf,0x8c,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,0x19,0xa9,0xb0,
  1684. 0x34,0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,0xb2,0xaf,0x34,
  1685. 0x37,0xb3,0x37,0x22,0x66,0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x1c,0xda,0xec,0xe0,
  1686. 0x86,0x28,0x8b,0xb0,0x10,0x8b,0xa0,0xac,0x81,0xc2,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,
  1687. 0xc2,0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,
  1688. 0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,
  1689. 0x7d,0xcd,0xa5,0xe9,0x95,0x31,0xb1,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,
  1690. 0xf0,0x15,0x93,0x33,0x84,0x0c,0x96,0x43,0x39,0x03,0x05,0x0d,0x16,0x42,0xf9,0x16,
  1691. 0x61,0x09,0x94,0x34,0x50,0xd4,0x40,0x69,0x03,0xc5,0x0d,0x16,0x42,0x79,0x83,0x05,
  1692. 0x51,0x22,0x05,0x0e,0x94,0x49,0x89,0x83,0x21,0x88,0x22,0x06,0x0a,0x19,0x28,0x66,
  1693. 0xa0,0xc8,0xc1,0x10,0x23,0x01,0x94,0x4e,0x99,0x03,0x3e,0x6f,0x6d,0x6e,0x69,0x70,
  1694. 0x6f,0x74,0x65,0x6e,0x74,0x20,0x63,0x68,0x61,0x72,0x7c,0xa6,0xd2,0xda,0xe0,0xd8,
  1695. 0xca,0x40,0x86,0x56,0x56,0x40,0xa8,0x84,0x82,0x82,0x86,0x08,0x8a,0x1d,0x0c,0x31,
  1696. 0x94,0x3a,0x50,0xee,0xa0,0x49,0x86,0x18,0x0a,0x1e,0x28,0x78,0xd0,0x24,0x23,0x22,
  1697. 0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x77,0x20,0x87,0x7a,0x60,0x87,0x72,
  1698. 0x70,0x03,0x73,0x60,0x87,0x70,0x38,0x87,0x79,0x98,0x22,0x04,0xc3,0x08,0x85,0x1d,
  1699. 0xd8,0xc1,0x1e,0xda,0xc1,0x0d,0xd2,0x81,0x1c,0xca,0xc1,0x1d,0xe8,0x61,0x4a,0x50,
  1700. 0x8c,0x58,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xec,0xa1,0x1c,0xe4,0x61,0x1e,0xd2,0xe1,
  1701. 0x1d,0xdc,0x61,0x4a,0x60,0x8c,0xa0,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xd8,0x21,0x1c,
  1702. 0xdc,0xe1,0x1c,0xea,0x21,0x1c,0xce,0xa1,0x1c,0x7e,0xc1,0x1e,0xca,0x41,0x1e,0xe6,
  1703. 0x21,0x1d,0xde,0xc1,0x1d,0xa6,0x04,0xc8,0x88,0x29,0x1c,0xd2,0x41,0x1e,0xdc,0x60,
  1704. 0x1c,0xde,0xa1,0x1d,0xe0,0x21,0x1d,0xd8,0xa1,0x1c,0x7e,0xe1,0x1d,0xe0,0x81,0x1e,
  1705. 0xd2,0xe1,0x1d,0xdc,0x61,0x1e,0xa6,0x0c,0x0a,0xe3,0x8c,0x50,0xc2,0x21,0x1d,0xe4,
  1706. 0xc1,0x0d,0xec,0xa1,0x1c,0xe4,0x81,0x1e,0xca,0x01,0x1f,0xa6,0x04,0x74,0x00,0x00,
  1707. 0x79,0x18,0x00,0x00,0xa5,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,
  1708. 0x14,0x01,0x3d,0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,
  1709. 0x98,0x71,0x0c,0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,0x33,0x0c,0x42,0x1e,
  1710. 0xc2,0xc1,0x1d,0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,0x38,0x84,0x83,0x1b,
  1711. 0xcc,0x03,0x3d,0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,0x74,0x70,0x07,0x7b,
  1712. 0x08,0x07,0x79,0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,0x78,0x87,0x70,0x20,
  1713. 0x87,0x19,0xcc,0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,0x30,0x0f,0xe3,0xf0,
  1714. 0x0e,0xf0,0x50,0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,0x21,0x1d,0xc2,0x61,
  1715. 0x1e,0x66,0x30,0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,0x03,0x3c,0xbc,0x83,
  1716. 0x3c,0x84,0x03,0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,
  1717. 0x72,0x68,0x07,0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,0x76,0x28,0x07,0x76,
  1718. 0xf8,0x05,0x76,0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,0x18,0x87,0x72,0x98,
  1719. 0x87,0x79,0x98,0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,0xc0,0x0e,0xec,0x30,
  1720. 0x03,0x62,0xc8,0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x1c,0xdc,0x61,
  1721. 0x1c,0xca,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,0x43,0x39,0xc8,0x43,
  1722. 0x39,0x98,0x43,0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,0x38,0x88,0x03,0x3b,
  1723. 0x94,0xc3,0x2f,0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,0xb0,0xc3,0x0c,0xc7,
  1724. 0x69,0x87,0x70,0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,0x60,0x87,0x74,0x18,
  1725. 0x87,0x74,0xa0,0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,0x50,0x0e,0xe4,0x90,
  1726. 0x0e,0xe3,0x40,0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,0x28,0x1d,0xdc,0xc1,
  1727. 0x1e,0xc2,0x41,0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,0x1c,0xe4,0xe1,0x1d,
  1728. 0xea,0x01,0x1e,0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,0x3b,0xcc,0x50,0x24,
  1729. 0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,0x78,0x98,0x51,0x4c,
  1730. 0xf4,0x90,0x0f,0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,0x1c,0xe8,0x21,0x1d,
  1731. 0xde,0xc1,0x1d,0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,0xf0,0x61,0x06,0x54,
  1732. 0x85,0x83,0x38,0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,0xfc,0xc2,0x3c,0xe4,
  1733. 0x43,0x3b,0x88,0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,0x98,0x87,0x77,0x18,
  1734. 0x87,0x74,0x08,0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,0x10,0x0e,0xec,0xc0,
  1735. 0x0e,0xe5,0x50,0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,0xe1,0x17,0xd8,0xe1,
  1736. 0x1d,0xde,0x01,0x1e,0x66,0x48,0x19,0x3b,0xb0,0x83,0x3d,0xb4,0x83,0x1b,0x84,0xc3,
  1737. 0x38,0x8c,0x43,0x39,0xcc,0xc3,0x3c,0xb8,0xc1,0x39,0xc8,0xc3,0x3b,0xd4,0x03,0x3c,
  1738. 0xcc,0x48,0xb4,0x71,0x08,0x07,0x76,0x60,0x07,0x71,0x08,0x87,0x71,0x58,0x87,0x19,
  1739. 0xdb,0xc6,0x0e,0xec,0x60,0x0f,0xed,0xe0,0x06,0xf0,0x20,0x0f,0xe5,0x30,0x0f,0xe5,
  1740. 0x20,0x0f,0xf6,0x50,0x0e,0x6e,0x10,0x0e,0xe3,0x30,0x0e,0xe5,0x30,0x0f,0xf3,0xe0,
  1741. 0x06,0xe9,0xe0,0x0e,0xe4,0x50,0x0e,0xf8,0x30,0x23,0xe2,0xec,0x61,0x1c,0xc2,0x81,
  1742. 0x1d,0xd8,0xe1,0x17,0xec,0x21,0x1d,0xe6,0x21,0x1d,0xc4,0x21,0x1d,0xd8,0x21,0x1d,
  1743. 0xe8,0x21,0x1f,0x66,0x20,0x9d,0x3b,0xbc,0x43,0x3d,0xb8,0x03,0x39,0x94,0x83,0x39,
  1744. 0xcc,0x58,0xbc,0x70,0x70,0x07,0x77,0x78,0x07,0x7a,0x08,0x07,0x7a,0x48,0x87,0x77,
  1745. 0x70,0x87,0x19,0xce,0x87,0x0e,0xe5,0x10,0x0e,0xf0,0x10,0x0e,0xec,0xc0,0x0e,0xef,
  1746. 0x30,0x0e,0xf3,0x90,0x0e,0xf4,0x50,0x0e,0x33,0x28,0x30,0x08,0x87,0x74,0x90,0x07,
  1747. 0x37,0x30,0x87,0x7a,0x70,0x87,0x71,0xa0,0x87,0x74,0x78,0x07,0x77,0xf8,0x85,0x73,
  1748. 0x90,0x87,0x77,0xa8,0x07,0x78,0x98,0x07,0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,
  1749. 0x02,0x00,0x00,0x00,0x06,0x50,0x30,0x00,0xd2,0xd0,0x00,0x00,0x61,0x20,0x00,0x00,
  1750. 0x1e,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
  1751. 0xf4,0xc6,0x22,0x82,0x20,0x08,0x46,0x00,0xa8,0x95,0x40,0x19,0xd0,0x98,0x01,0xa0,
  1752. 0x30,0x03,0x00,0x00,0xe3,0x15,0x07,0x33,0x4d,0x0c,0x05,0x65,0x90,0x81,0x19,0x0e,
  1753. 0x13,0x02,0xf9,0x8c,0x57,0x2c,0xd0,0x75,0x21,0x14,0x94,0x41,0x06,0xe8,0x60,0x4c,
  1754. 0x08,0xe4,0x63,0x41,0x01,0x9f,0xf1,0x0a,0xa8,0xe2,0x38,0x86,0x82,0x62,0x43,0x00,
  1755. 0x9f,0xd9,0x06,0xa7,0x02,0x66,0x1b,0x82,0x2a,0x98,0x6d,0x08,0x06,0x21,0x83,0x80,
  1756. 0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x5b,0x86,0x20,0xc8,0x83,0x2d,0x43,0x11,
  1757. 0xe4,0xc1,0x96,0x41,0x09,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1758. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1759. };
  1760. /*
  1761. #include <metal_stdlib>
  1762. #include <simd/simd.h>
  1763. using namespace metal;
  1764. struct fs_params
  1765. {
  1766. float pma;
  1767. };
  1768. struct main0_out
  1769. {
  1770. float4 frag_color [[color(0)]];
  1771. };
  1772. struct main0_in
  1773. {
  1774. float2 uv [[user(locn0)]];
  1775. float4 color [[user(locn1)]];
  1776. };
  1777. fragment main0_out main0(main0_in in [[stage_in]], constant fs_params& _53 [[buffer(0)]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]])
  1778. {
  1779. main0_out out = {};
  1780. float4 _28 = tex.sample(smp, in.uv) * in.color;
  1781. float _37 = _28.w;
  1782. out.frag_color = mix(_28, float4(_28.xyz * _37, _37) * in.color, float4(_53.pma));
  1783. return out;
  1784. }
  1785. */
  1786. static const uint8_t _sspine_fs_bytecode_metal_macos[3465] = {
  1787. 0x4d,0x54,0x4c,0x42,0x01,0x80,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1788. 0x89,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1789. 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1790. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1791. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1792. 0xb0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
  1793. 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
  1794. 0x01,0x00,0x01,0x48,0x41,0x53,0x48,0x20,0x00,0x08,0x46,0x82,0xf4,0xfd,0xc1,0x65,
  1795. 0x5a,0x94,0x87,0x41,0x06,0x5e,0x69,0x32,0x47,0x25,0xad,0x8c,0xb9,0xca,0x2a,0xea,
  1796. 0xfa,0xea,0xb8,0x8d,0x01,0x55,0xee,0xb2,0x00,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
  1797. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1798. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
  1799. 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,
  1800. 0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,0x00,0x00,0x00,
  1801. 0x00,0x14,0x00,0x00,0x00,0x98,0x0c,0x00,0x00,0xff,0xff,0xff,0xff,0x42,0x43,0xc0,
  1802. 0xde,0x21,0x0c,0x00,0x00,0x23,0x03,0x00,0x00,0x0b,0x82,0x20,0x00,0x02,0x00,0x00,
  1803. 0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,
  1804. 0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,
  1805. 0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,
  1806. 0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,0x24,0x07,0xc8,
  1807. 0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,0x51,0x18,0x00,
  1808. 0x00,0x7b,0x00,0x00,0x00,0x1b,0xc2,0x24,0xf8,0xff,0xff,0xff,0xff,0x01,0x60,0x00,
  1809. 0x09,0xa8,0x88,0x70,0x80,0x07,0x78,0x90,0x87,0x77,0xc0,0x87,0x36,0x30,0x87,0x7a,
  1810. 0x70,0x87,0x71,0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,
  1811. 0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xa2,0x1d,0xd2,0xc1,0x1d,0xda,0x80,0x1d,0xca,
  1812. 0xe1,0x1c,0xc2,0x81,0x1d,0xda,0xc0,0x1e,0xca,0x61,0x1c,0xe8,0xe1,0x1d,0xe4,0xa1,
  1813. 0x0d,0xee,0x21,0x1d,0xc8,0x81,0x1e,0xd0,0x01,0x88,0x03,0x39,0xc0,0x03,0x60,0x70,
  1814. 0x87,0x77,0x68,0x03,0x71,0xa8,0x87,0x74,0x60,0x07,0x7a,0x48,0x07,0x77,0x98,0x07,
  1815. 0x80,0x70,0x87,0x77,0x68,0x03,0x73,0x90,0x87,0x70,0x68,0x87,0x72,0x68,0x03,0x78,
  1816. 0x78,0x87,0x74,0x70,0x07,0x7a,0x28,0x07,0x79,0x68,0x83,0x72,0x60,0x87,0x74,0x68,
  1817. 0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0xc0,0x1c,0xe4,
  1818. 0x21,0x1c,0xda,0xa1,0x1c,0xda,0x00,0x1e,0xde,0x21,0x1d,0xdc,0x81,0x1e,0xca,0x41,
  1819. 0x1e,0xda,0xa0,0x1c,0xd8,0x21,0x1d,0xda,0xa1,0x0d,0xdc,0xe1,0x1d,0xdc,0xa1,0x0d,
  1820. 0xd8,0xa1,0x1c,0xc2,0xc1,0x1c,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,
  1821. 0x77,0x68,0x83,0x74,0x70,0x07,0x73,0x98,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,
  1822. 0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,
  1823. 0xda,0xc0,0x1d,0xc2,0xc1,0x1d,0xe6,0xa1,0x0d,0xcc,0x01,0x1e,0xda,0xa0,0x1d,0xc2,
  1824. 0x81,0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,0x77,0x78,0x87,0x36,
  1825. 0x98,0x87,0x74,0x38,0x07,0x77,0x28,0x07,0x72,0x68,0x03,0x7d,0x28,0x07,0x79,0x78,
  1826. 0x87,0x79,0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,
  1827. 0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xe8,0x41,0x1e,0xc2,0x01,
  1828. 0x1e,0xe0,0x21,0x1d,0xdc,0xe1,0x1c,0xda,0xa0,0x1d,0xc2,0x81,0x1e,0xd0,0x01,0xa0,
  1829. 0x07,0x79,0xa8,0x87,0x72,0x00,0x88,0x79,0xa0,0x87,0x70,0x18,0x87,0x75,0x68,0x03,
  1830. 0x78,0x90,0x87,0x77,0xa0,0x87,0x72,0x18,0x07,0x7a,0x78,0x07,0x79,0x68,0x03,0x71,
  1831. 0xa8,0x07,0x73,0x30,0x87,0x72,0x90,0x87,0x36,0x98,0x87,0x74,0xd0,0x87,0x72,0x00,
  1832. 0xf0,0x00,0x20,0xea,0xc1,0x1d,0xe6,0x21,0x1c,0xcc,0xa1,0x1c,0xda,0xc0,0x1c,0xe0,
  1833. 0xa1,0x0d,0xda,0x21,0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x60,
  1834. 0x83,0x21,0x0c,0xc0,0x02,0x54,0x1b,0x8c,0x81,0x00,0x16,0xa0,0xda,0x60,0x10,0x05,
  1835. 0xb0,0x00,0xd5,0x06,0xa3,0xf8,0xff,0xff,0xff,0xff,0x01,0x90,0x00,0x6a,0x03,0x62,
  1836. 0xfc,0xff,0xff,0xff,0xff,0x00,0x30,0x80,0x04,0x54,0x1b,0x8c,0x23,0x00,0x16,0xa0,
  1837. 0xda,0x60,0x20,0x02,0xb0,0x00,0xd5,0x06,0x24,0xf9,0xff,0xff,0xff,0xff,0x01,0x60,
  1838. 0x00,0x09,0xa8,0x36,0x18,0xca,0xff,0xff,0xff,0xff,0x0f,0x80,0x04,0x50,0x00,0x00,
  1839. 0x00,0x49,0x18,0x00,0x00,0x05,0x00,0x00,0x00,0x13,0x88,0x40,0x18,0x88,0x09,0x41,
  1840. 0x31,0x61,0x30,0x0e,0x64,0xc2,0x90,0x1c,0xc8,0x84,0x40,0x01,0x00,0x89,0x20,0x00,
  1841. 0x00,0x27,0x00,0x00,0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,0x04,0x93,0x22,0xa4,
  1842. 0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,
  1843. 0x4c,0x10,0x6c,0x33,0x00,0xc3,0x08,0x04,0x60,0x83,0x30,0x8c,0x20,0x00,0x07,0x49,
  1844. 0x53,0x44,0x09,0x93,0x5f,0x48,0xff,0x03,0x44,0x00,0x23,0xa1,0x00,0x0c,0x22,0x10,
  1845. 0xc2,0x51,0xd2,0x14,0x51,0xc2,0xe4,0xff,0x13,0x71,0x4d,0x54,0x44,0xfc,0xf6,0xf0,
  1846. 0x4f,0x63,0x04,0xc0,0x20,0x82,0x11,0x5c,0x24,0x4d,0x11,0x25,0x4c,0xfe,0x2f,0x01,
  1847. 0xcc,0xb3,0x10,0xd1,0x3f,0x8d,0x11,0x00,0x83,0x08,0x88,0x50,0x0c,0x31,0x42,0x39,
  1848. 0x89,0x54,0x21,0x42,0x08,0x81,0xd8,0x1c,0x41,0x30,0x47,0x00,0x06,0xc3,0x08,0xc2,
  1849. 0x53,0x90,0x70,0xd2,0x70,0xd0,0x01,0x8a,0x03,0x01,0x29,0xf0,0x86,0x11,0x86,0x67,
  1850. 0x18,0x61,0x00,0x86,0x11,0x88,0x67,0x8e,0x00,0x14,0x06,0x11,0x00,0x61,0x04,0x00,
  1851. 0x00,0x13,0xb2,0x70,0x48,0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,0x70,0x80,0x07,0x78,
  1852. 0x60,0x87,0x72,0x68,0x83,0x76,0x08,0x87,0x71,0x78,0x87,0x79,0xc0,0x87,0x38,0x80,
  1853. 0x03,0x37,0x88,0x83,0x38,0x70,0x03,0x38,0xd8,0x70,0x1b,0xe5,0xd0,0x06,0xf0,0xa0,
  1854. 0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x90,0x0e,
  1855. 0x71,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,
  1856. 0x80,0x07,0x6d,0x90,0x0e,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,
  1857. 0x07,0x6d,0x90,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,
  1858. 0x6d,0x90,0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,
  1859. 0x60,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,
  1860. 0x0e,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,
  1861. 0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x60,0x0f,0x72,
  1862. 0x40,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0f,0x73,0x20,
  1863. 0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0f,0x74,0x80,0x07,
  1864. 0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,
  1865. 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x79,0x60,0x07,0x7a,0x10,
  1866. 0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,
  1867. 0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xf6,
  1868. 0x10,0x07,0x79,0x20,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,
  1869. 0x07,0x6d,0x60,0x0f,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,0xa0,0x07,
  1870. 0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,0x50,0x07,0x71,0x20,0x07,0x7a,0x50,0x07,0x71,
  1871. 0x20,0x07,0x7a,0x50,0x07,0x71,0x20,0x07,0x6d,0x60,0x0f,0x71,0x00,0x07,0x72,0x40,
  1872. 0x07,0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xa0,0x07,0x71,0x00,0x07,0x72,0x40,0x07,
  1873. 0x6d,0xe0,0x0e,0x78,0xa0,0x07,0x71,0x60,0x07,0x7a,0x30,0x07,0x72,0x30,0x84,0x59,
  1874. 0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x18,0xc2,0x34,0x40,0x00,0x08,0x00,0x00,
  1875. 0x00,0x00,0x00,0x0c,0x61,0x24,0x20,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xb2,0x40,
  1876. 0x00,0x09,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,
  1877. 0x47,0xc6,0x04,0x43,0x7a,0x23,0x00,0x25,0x50,0x08,0x45,0x50,0x10,0x65,0x40,0x78,
  1878. 0x04,0x80,0xe8,0x58,0xc2,0x03,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0x13,0x01,0x00,
  1879. 0x00,0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,
  1880. 0xb7,0x21,0xc6,0x63,0x4c,0x00,0xa5,0x50,0xb9,0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,
  1881. 0xd3,0x2b,0x1b,0x62,0x3c,0xc4,0x24,0x3c,0x05,0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,
  1882. 0xa4,0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x46,
  1883. 0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x06,0x04,0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,
  1884. 0xac,0x65,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x26,0x65,0x88,0x30,0x11,0x43,
  1885. 0x8c,0x87,0x78,0x8e,0x67,0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,0x04,0x99,0x8e,0x87,
  1886. 0x78,0x88,0x67,0xe0,0x16,0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,
  1887. 0x42,0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,0x26,0xc6,0x56,0x36,
  1888. 0x44,0x98,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,
  1889. 0x66,0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,
  1890. 0x43,0x84,0x69,0x61,0x19,0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,
  1891. 0xb9,0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,
  1892. 0x8d,0xa1,0x7d,0x91,0xa5,0xcd,0x85,0x89,0xb1,0x95,0x0d,0x11,0xa6,0x86,0x51,0x58,
  1893. 0x9a,0x9c,0x8b,0x5c,0x99,0x1b,0x59,0x99,0xdc,0x17,0x5d,0x98,0xdc,0x59,0x19,0x1d,
  1894. 0xa3,0xb0,0x34,0x39,0x97,0x30,0xb9,0xb3,0x2f,0xba,0x3c,0xb8,0xb2,0x2f,0xb7,0xb0,
  1895. 0xb6,0x32,0x1a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x64,0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,
  1896. 0xce,0xbe,0xdc,0xc2,0xda,0xca,0xa8,0x98,0xc9,0x85,0x9d,0x7d,0x8d,0xbd,0xb1,0xbd,
  1897. 0xc9,0x0d,0x61,0xa6,0xe7,0x19,0x26,0x68,0x8a,0x26,0x69,0x9a,0x86,0x08,0x13,0x45,
  1898. 0x29,0x2c,0x4d,0xce,0xc5,0x4c,0x2e,0xec,0xac,0xad,0xcc,0x8d,0xee,0x2b,0xcd,0x0d,
  1899. 0xae,0x8e,0x8e,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,0x1b,0x4c,0x0a,0x95,
  1900. 0xb0,0x34,0x39,0x97,0xb1,0x32,0x37,0xba,0x32,0x39,0x3e,0x61,0x69,0x72,0x2e,0x70,
  1901. 0x65,0x72,0x73,0x70,0x65,0x63,0x74,0x69,0x76,0x65,0x34,0xcc,0xd8,0xde,0xc2,0xe8,
  1902. 0x64,0x28,0xd4,0xd9,0x0d,0x91,0x9e,0x61,0xb2,0xa6,0x6b,0xc2,0xa6,0x6c,0x82,0x26,
  1903. 0x6d,0x92,0xa6,0x8d,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,0x5b,0x4c,0x0a,
  1904. 0x8b,0xb1,0x37,0xb6,0x37,0xb9,0x21,0xd2,0x43,0x4c,0xd6,0xd4,0x4d,0xd8,0x94,0x4d,
  1905. 0xd0,0x14,0x4d,0xd2,0xe4,0x51,0x09,0x4b,0x93,0x73,0x11,0xab,0x33,0x33,0x2b,0x93,
  1906. 0xe3,0x13,0x96,0x26,0xe7,0x22,0x56,0x67,0x66,0x56,0x26,0xf7,0x35,0x97,0xa6,0x57,
  1907. 0x46,0x29,0x2c,0x4d,0xce,0x85,0xed,0x6d,0x2c,0x8c,0x2e,0xed,0xcd,0xed,0x2b,0xcd,
  1908. 0x8d,0xac,0x0c,0x8f,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,0x19,0xa9,0xb0,0x34,
  1909. 0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,0xb2,0xaf,0x34,0x37,
  1910. 0xb3,0x37,0x16,0x66,0x6c,0x6f,0x61,0x74,0x1c,0xe0,0xda,0xc2,0x86,0x28,0xcf,0xf0,
  1911. 0x14,0xcf,0x30,0x95,0xc1,0x64,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,0xce,0xbe,
  1912. 0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,0xc9,0xb9,0x84,0xc9,
  1913. 0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,0x7d,0xcd,0xa5,0xe9,
  1914. 0x95,0x31,0x31,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf0,0x55,0x33,0x33,
  1915. 0x84,0x0c,0x1e,0x63,0x02,0x83,0x29,0x0c,0x9e,0x62,0x12,0x83,0x67,0x78,0x88,0x69,
  1916. 0x0c,0x26,0x32,0x98,0xce,0x60,0x42,0x83,0xa7,0x98,0xd2,0xe0,0x29,0x26,0x68,0x52,
  1917. 0x83,0x49,0x9a,0xd6,0x80,0x4b,0x58,0x9a,0x9c,0x0b,0x5d,0x19,0x1e,0x5d,0x9d,0x5c,
  1918. 0x19,0x95,0xb0,0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x62,0x74,0x65,0x78,
  1919. 0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,0x2c,0x20,0x73,0x61,
  1920. 0x6d,0x70,0x6c,0x65,0x3e,0x1c,0xe8,0xca,0xf0,0x86,0x50,0x0f,0x32,0xb5,0xc1,0x24,
  1921. 0x06,0xcf,0xf0,0x10,0x93,0x1b,0x4c,0xd0,0xf4,0x06,0x93,0x34,0xc1,0x01,0x97,0xb0,
  1922. 0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x39,0x1e,0x73,0x61,0x6d,0x70,0x6c,
  1923. 0x65,0x72,0x1c,0xe6,0xda,0xe0,0x86,0x48,0x4f,0x31,0xc9,0xc1,0x24,0x06,0xcf,0xf0,
  1924. 0x10,0x13,0x34,0xcd,0xc1,0x24,0x4d,0x74,0x30,0x44,0x99,0xb8,0xe9,0x9b,0xd8,0x60,
  1925. 0x8a,0x83,0xa9,0x0e,0x86,0x18,0x0b,0x30,0x55,0x93,0x1d,0xf0,0x0a,0x4b,0x93,0x6b,
  1926. 0x09,0x63,0x4b,0x0b,0x9b,0x6b,0x99,0x1b,0x7b,0x83,0x2b,0x9b,0x43,0x69,0x0b,0x4b,
  1927. 0x73,0x83,0x49,0x19,0x42,0x4c,0x79,0x30,0xe1,0x01,0xb1,0xb0,0x34,0xb9,0x96,0x30,
  1928. 0xb6,0xb4,0xb0,0xb9,0x96,0xb9,0xb1,0x37,0xb8,0xb2,0x16,0xba,0x32,0x3c,0xba,0x3a,
  1929. 0xb9,0xb2,0xb9,0x21,0xc6,0xb4,0x07,0x53,0x1e,0x4c,0x7a,0x40,0x2c,0x2c,0x4d,0xae,
  1930. 0x25,0x8c,0x2d,0x2d,0x6c,0xae,0x65,0x6e,0xec,0x0d,0xae,0xac,0x65,0x2e,0xac,0x0d,
  1931. 0x8e,0xad,0x4c,0x6e,0x6e,0x88,0x31,0xf5,0xc1,0x94,0x07,0x13,0x1f,0x0c,0x21,0xa6,
  1932. 0x3d,0x98,0xfa,0x80,0xce,0x97,0x16,0xd5,0x54,0x8e,0xd9,0xdc,0x17,0x5c,0x98,0x5c,
  1933. 0x58,0xdb,0x1c,0x9f,0xb7,0x36,0xb7,0x34,0xb8,0x37,0xba,0x32,0x37,0x3a,0x90,0x31,
  1934. 0xb4,0x30,0x39,0x3e,0x53,0x69,0x6d,0x70,0x6c,0x65,0x20,0x43,0x2b,0x2b,0x20,0x54,
  1935. 0x42,0x41,0x41,0x43,0x84,0x29,0x14,0x86,0x18,0x13,0x28,0x4c,0xa2,0x80,0x25,0x43,
  1936. 0x8c,0xa9,0x0c,0xa6,0x51,0xc0,0x92,0x21,0xc6,0xf4,0x07,0x13,0x29,0x60,0xc9,0x10,
  1937. 0x63,0x2a,0x85,0x89,0x14,0xb0,0x64,0x44,0xc4,0x0e,0xec,0x60,0x0f,0xed,0xe0,0x06,
  1938. 0xed,0xf0,0x0e,0xe4,0x50,0x0f,0xec,0x50,0x0e,0x6e,0x60,0x0e,0xec,0x10,0x0e,0xe7,
  1939. 0x30,0x0f,0x53,0x84,0x60,0x18,0xa1,0xb0,0x03,0x3b,0xd8,0x43,0x3b,0xb8,0x41,0x3a,
  1940. 0x90,0x43,0x39,0xb8,0x03,0x3d,0x4c,0x09,0x8a,0x11,0x4b,0x38,0xa4,0x83,0x3c,0xb8,
  1941. 0x81,0x3d,0x94,0x83,0x3c,0xcc,0x43,0x3a,0xbc,0x83,0x3b,0x4c,0x09,0x8c,0x11,0x54,
  1942. 0x38,0xa4,0x83,0x3c,0xb8,0x01,0x3b,0x84,0x83,0x3b,0x9c,0x43,0x3d,0x84,0xc3,0x39,
  1943. 0x94,0xc3,0x2f,0xd8,0x43,0x39,0xc8,0xc3,0x3c,0xa4,0xc3,0x3b,0xb8,0xc3,0x94,0x00,
  1944. 0x19,0x31,0x85,0x43,0x3a,0xc8,0x83,0x1b,0x8c,0xc3,0x3b,0xb4,0x03,0x3c,0xa4,0x03,
  1945. 0x3b,0x94,0xc3,0x2f,0xbc,0x03,0x3c,0xd0,0x43,0x3a,0xbc,0x83,0x3b,0xcc,0xc3,0x94,
  1946. 0x41,0x61,0x9c,0x11,0x4c,0x38,0xa4,0x83,0x3c,0xb8,0x81,0x39,0xc8,0x43,0x38,0x9c,
  1947. 0x43,0x3b,0x94,0x83,0x3b,0xd0,0xc3,0x94,0xe0,0x0e,0x00,0x00,0x00,0x79,0x18,0x00,
  1948. 0x00,0xa5,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,
  1949. 0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,0x98,0x71,0x0c,
  1950. 0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,
  1951. 0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,
  1952. 0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,0x74,0x70,0x07,0x7b,0x08,0x07,0x79,
  1953. 0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,0x78,0x87,0x70,0x20,0x87,0x19,0xcc,
  1954. 0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,
  1955. 0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,
  1956. 0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,
  1957. 0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x72,0x68,0x07,
  1958. 0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,0x76,0x28,0x07,0x76,0xf8,0x05,0x76,
  1959. 0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,0x18,0x87,0x72,0x98,0x87,0x79,0x98,
  1960. 0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,
  1961. 0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,
  1962. 0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,0x43,0x39,0xc8,0x43,0x39,0x98,0x43,
  1963. 0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,
  1964. 0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,
  1965. 0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,0x60,0x87,0x74,0x18,0x87,0x74,0xa0,
  1966. 0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,
  1967. 0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,
  1968. 0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,
  1969. 0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,
  1970. 0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,
  1971. 0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,
  1972. 0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,0xf0,0x61,0x06,0x54,0x85,0x83,0x38,
  1973. 0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,
  1974. 0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,0x98,0x87,0x77,0x18,0x87,0x74,0x08,
  1975. 0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,
  1976. 0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,
  1977. 0x1e,0x66,0x48,0x19,0x3b,0xb0,0x83,0x3d,0xb4,0x83,0x1b,0x84,0xc3,0x38,0x8c,0x43,
  1978. 0x39,0xcc,0xc3,0x3c,0xb8,0xc1,0x39,0xc8,0xc3,0x3b,0xd4,0x03,0x3c,0xcc,0x48,0xb4,
  1979. 0x71,0x08,0x07,0x76,0x60,0x07,0x71,0x08,0x87,0x71,0x58,0x87,0x19,0xdb,0xc6,0x0e,
  1980. 0xec,0x60,0x0f,0xed,0xe0,0x06,0xf0,0x20,0x0f,0xe5,0x30,0x0f,0xe5,0x20,0x0f,0xf6,
  1981. 0x50,0x0e,0x6e,0x10,0x0e,0xe3,0x30,0x0e,0xe5,0x30,0x0f,0xf3,0xe0,0x06,0xe9,0xe0,
  1982. 0x0e,0xe4,0x50,0x0e,0xf8,0x30,0x23,0xe2,0xec,0x61,0x1c,0xc2,0x81,0x1d,0xd8,0xe1,
  1983. 0x17,0xec,0x21,0x1d,0xe6,0x21,0x1d,0xc4,0x21,0x1d,0xd8,0x21,0x1d,0xe8,0x21,0x1f,
  1984. 0x66,0x20,0x9d,0x3b,0xbc,0x43,0x3d,0xb8,0x03,0x39,0x94,0x83,0x39,0xcc,0x58,0xbc,
  1985. 0x70,0x70,0x07,0x77,0x78,0x07,0x7a,0x08,0x07,0x7a,0x48,0x87,0x77,0x70,0x87,0x19,
  1986. 0xce,0x87,0x0e,0xe5,0x10,0x0e,0xf0,0x10,0x0e,0xec,0xc0,0x0e,0xef,0x30,0x0e,0xf3,
  1987. 0x90,0x0e,0xf4,0x50,0x0e,0x33,0x28,0x30,0x08,0x87,0x74,0x90,0x07,0x37,0x30,0x87,
  1988. 0x7a,0x70,0x87,0x71,0xa0,0x87,0x74,0x78,0x07,0x77,0xf8,0x85,0x73,0x90,0x87,0x77,
  1989. 0xa8,0x07,0x78,0x98,0x07,0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x0b,0x00,0x00,
  1990. 0x00,0x26,0xb0,0x01,0x48,0xe4,0x4b,0x00,0xf3,0x2c,0xc4,0x3f,0x11,0xd7,0x44,0x45,
  1991. 0xc4,0x6f,0x0f,0x7e,0x85,0x17,0xb7,0x6d,0x00,0x05,0x03,0x20,0x0d,0x6d,0x01,0x0d,
  1992. 0x80,0x44,0x3e,0x83,0x5c,0x7e,0x85,0x17,0xb7,0x0d,0x00,0x00,0x00,0x61,0x20,0x00,
  1993. 0x00,0x27,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x0d,0x00,0x00,
  1994. 0x00,0x74,0x47,0x00,0xc6,0x22,0x80,0x40,0x38,0xe6,0x20,0x06,0xc2,0xb0,0xa8,0x8e,
  1995. 0x35,0x0c,0xc3,0x40,0xae,0x06,0x46,0x00,0xe8,0xcd,0x00,0x10,0x1c,0x01,0xa0,0x3a,
  1996. 0xd6,0x00,0x04,0x02,0x89,0x19,0x00,0xb2,0x33,0x00,0x14,0x66,0x00,0x66,0x00,0x08,
  1997. 0x8c,0x00,0x00,0x00,0x00,0x23,0x06,0x0a,0x11,0x70,0xd0,0x33,0x29,0x47,0x12,0x58,
  1998. 0x30,0xc9,0x67,0x90,0x21,0x20,0x90,0x41,0x06,0xc1,0x70,0x4c,0x08,0xe4,0x33,0xc8,
  1999. 0x10,0x24,0xd1,0x20,0x43,0x50,0x4c,0x16,0x64,0xf2,0x19,0x6f,0xc8,0xba,0x31,0xa0,
  2000. 0x60,0xcc,0x31,0x30,0x41,0x19,0x0c,0x32,0x04,0x4d,0x36,0x62,0x60,0x14,0x41,0x1a,
  2001. 0x2c,0x45,0x30,0xdb,0x20,0x05,0x40,0x06,0x01,0x31,0x00,0x00,0x00,0x03,0x00,0x00,
  2002. 0x00,0x5b,0x06,0xe0,0xf0,0x83,0x2d,0x43,0x12,0x98,0x02,0x00,0x00,0x00,0x00,0x00,
  2003. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2004. };
  2005. /*
  2006. #include <metal_stdlib>
  2007. #include <simd/simd.h>
  2008. using namespace metal;
  2009. struct vs_params
  2010. {
  2011. float4x4 mvp;
  2012. };
  2013. struct main0_out
  2014. {
  2015. float2 uv [[user(locn0)]];
  2016. float4 color [[user(locn1)]];
  2017. float4 gl_Position [[position]];
  2018. };
  2019. struct main0_in
  2020. {
  2021. float2 position [[attribute(0)]];
  2022. float2 texcoord0 [[attribute(1)]];
  2023. float4 color0 [[attribute(2)]];
  2024. };
  2025. vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _19 [[buffer(0)]])
  2026. {
  2027. main0_out out = {};
  2028. out.gl_Position = _19.mvp * float4(in.position, 0.0, 1.0);
  2029. out.uv = in.texcoord0;
  2030. out.color = in.color0;
  2031. return out;
  2032. }
  2033. */
  2034. static const uint8_t _sspine_vs_bytecode_metal_ios[3244] = {
  2035. 0x4d,0x54,0x4c,0x42,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2036. 0xac,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2037. 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2038. 0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  2039. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  2040. 0xa0,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
  2041. 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
  2042. 0x01,0x00,0x00,0x48,0x41,0x53,0x48,0x20,0x00,0xc3,0xfa,0xed,0x98,0x72,0x47,0x43,
  2043. 0xff,0x08,0xf0,0xb1,0xc3,0x34,0x0d,0xef,0xaf,0xc8,0x0e,0xfa,0x68,0x10,0xed,0xb2,
  2044. 0x31,0x82,0x07,0xf2,0x24,0xf9,0x1c,0xaa,0x58,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
  2045. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2046. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
  2047. 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x37,0x00,0x00,0x00,0x56,0x41,0x54,
  2048. 0x54,0x22,0x00,0x03,0x00,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x00,0x80,
  2049. 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x00,0x01,0x80,0x63,0x6f,0x6c,0x6f,
  2050. 0x72,0x30,0x00,0x02,0x80,0x56,0x41,0x54,0x59,0x05,0x00,0x03,0x00,0x04,0x04,0x06,
  2051. 0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,
  2052. 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x84,0x0b,0x00,0x00,0xff,0xff,0xff,0xff,
  2053. 0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0xde,0x02,0x00,0x00,0x0b,0x82,0x20,0x00,
  2054. 0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,
  2055. 0x06,0x10,0x32,0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,
  2056. 0x80,0x14,0x45,0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,
  2057. 0x0a,0x32,0x44,0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,
  2058. 0x24,0x07,0xc8,0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,
  2059. 0x51,0x18,0x00,0x00,0x70,0x00,0x00,0x00,0x1b,0x7e,0x24,0xf8,0xff,0xff,0xff,0xff,
  2060. 0x01,0x90,0x00,0x8a,0x08,0x07,0x78,0x80,0x07,0x79,0x78,0x07,0x7c,0x68,0x03,0x73,
  2061. 0xa8,0x07,0x77,0x18,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,
  2062. 0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xda,0x21,0x1d,0xdc,0xa1,0x0d,0xd8,
  2063. 0xa1,0x1c,0xce,0x21,0x1c,0xd8,0xa1,0x0d,0xec,0xa1,0x1c,0xc6,0x81,0x1e,0xde,0x41,
  2064. 0x1e,0xda,0xe0,0x1e,0xd2,0x81,0x1c,0xe8,0x01,0x1d,0x80,0x38,0x90,0x03,0x3c,0x00,
  2065. 0x06,0x77,0x78,0x87,0x36,0x10,0x87,0x7a,0x48,0x07,0x76,0xa0,0x87,0x74,0x70,0x87,
  2066. 0x79,0x00,0x08,0x77,0x78,0x87,0x36,0x30,0x07,0x79,0x08,0x87,0x76,0x28,0x87,0x36,
  2067. 0x80,0x87,0x77,0x48,0x07,0x77,0xa0,0x87,0x72,0x90,0x87,0x36,0x28,0x07,0x76,0x48,
  2068. 0x87,0x76,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xcc,
  2069. 0x41,0x1e,0xc2,0xa1,0x1d,0xca,0xa1,0x0d,0xe0,0xe1,0x1d,0xd2,0xc1,0x1d,0xe8,0xa1,
  2070. 0x1c,0xe4,0xa1,0x0d,0xca,0x81,0x1d,0xd2,0xa1,0x1d,0xda,0xc0,0x1d,0xde,0xc1,0x1d,
  2071. 0xda,0x80,0x1d,0xca,0x21,0x1c,0xcc,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,
  2072. 0x77,0x78,0x87,0x36,0x48,0x07,0x77,0x30,0x87,0x79,0x68,0x03,0x73,0x80,0x87,0x36,
  2073. 0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,
  2074. 0xde,0xa1,0x0d,0xdc,0x21,0x1c,0xdc,0x61,0x1e,0xda,0xc0,0x1c,0xe0,0xa1,0x0d,0xda,
  2075. 0x21,0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,0x77,
  2076. 0x68,0x83,0x79,0x48,0x87,0x73,0x70,0x87,0x72,0x20,0x87,0x36,0xd0,0x87,0x72,0x90,
  2077. 0x87,0x77,0x98,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,0x08,0x07,0x7a,0x40,0x07,
  2078. 0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0x80,0x1e,0xe4,0x21,
  2079. 0x1c,0xe0,0x01,0x1e,0xd2,0xc1,0x1d,0xce,0xa1,0x0d,0xda,0x21,0x1c,0xe8,0x01,0x1d,
  2080. 0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x98,0x07,0x7a,0x08,0x87,0x71,0x58,0x87,
  2081. 0x36,0x80,0x07,0x79,0x78,0x07,0x7a,0x28,0x87,0x71,0xa0,0x87,0x77,0x90,0x87,0x36,
  2082. 0x10,0x87,0x7a,0x30,0x07,0x73,0x28,0x07,0x79,0x68,0x83,0x79,0x48,0x07,0x7d,0x28,
  2083. 0x07,0x00,0x0f,0x00,0xa2,0x1e,0xdc,0x61,0x1e,0xc2,0xc1,0x1c,0xca,0xa1,0x0d,0xcc,
  2084. 0x01,0x1e,0xda,0xa0,0x1d,0xc2,0x81,0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,
  2085. 0x00,0x36,0x6c,0x02,0x01,0x2c,0x40,0x35,0x84,0x43,0x3a,0xc8,0x43,0x1b,0x88,0x43,
  2086. 0x3d,0x98,0x83,0x39,0x94,0x83,0x3c,0xb4,0x81,0x3b,0xbc,0x43,0x1b,0x84,0x03,0x3b,
  2087. 0xa4,0x43,0x38,0xcc,0x03,0x00,0x00,0x00,0x49,0x18,0x00,0x00,0x01,0x00,0x00,0x00,
  2088. 0x13,0x84,0x40,0x00,0x89,0x20,0x00,0x00,0x1f,0x00,0x00,0x00,0x32,0x22,0x48,0x09,
  2089. 0x20,0x64,0x85,0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,0xe3,0x84,0xa1,0x90,0x14,
  2090. 0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x44,0x33,0x00,0xc3,0x08,0x02,0x30,
  2091. 0x8c,0x40,0x00,0x76,0x08,0x42,0x24,0x81,0x98,0x89,0x9a,0x07,0x7a,0x90,0x87,0x7a,
  2092. 0x18,0x07,0x7a,0x70,0x83,0x76,0x28,0x07,0x7a,0x08,0x07,0x76,0xd0,0x03,0x3d,0x68,
  2093. 0x87,0x70,0xa0,0x07,0x79,0x48,0x07,0x7c,0x40,0x01,0x39,0x48,0x9a,0x22,0x4a,0x98,
  2094. 0xfc,0x4a,0xfa,0x1f,0x20,0x02,0x18,0x09,0x05,0x65,0x10,0xc1,0x10,0x4a,0x31,0x42,
  2095. 0x10,0x87,0xd0,0x40,0xc0,0x1c,0x01,0x18,0xa4,0xc0,0x9a,0x23,0x00,0x85,0x41,0x04,
  2096. 0x41,0x18,0x46,0x20,0x96,0x11,0x00,0x00,0x13,0xa8,0x70,0x48,0x07,0x79,0xb0,0x03,
  2097. 0x3a,0x68,0x83,0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,0x83,0x74,0x78,0x87,0x79,
  2098. 0xc8,0x03,0x37,0x80,0x03,0x37,0x80,0x83,0x0d,0xb7,0x51,0x0e,0x6d,0x00,0x0f,0x7a,
  2099. 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe9,0x10,
  2100. 0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x78,0xa0,0x07,0x78,0xa0,0x07,
  2101. 0x78,0xd0,0x06,0xe9,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,
  2102. 0xd0,0x06,0xe9,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,
  2103. 0x06,0xe9,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,
  2104. 0xe6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe6,
  2105. 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x10,
  2106. 0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xf6,0x20,0x07,
  2107. 0x74,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xf6,0x30,0x07,0x72,
  2108. 0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xf6,0x40,0x07,0x78,0xa0,
  2109. 0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x60,0x07,0x74,0xa0,0x07,
  2110. 0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x90,0x07,0x76,0xa0,0x07,0x71,
  2111. 0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xf6,0x10,0x07,0x72,0x80,
  2112. 0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x6d,0x60,0x0f,
  2113. 0x71,0x90,0x07,0x72,0xa0,0x07,0x72,0x50,0x07,0x76,0xa0,0x07,0x72,0x50,0x07,0x76,
  2114. 0xd0,0x06,0xf6,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,
  2115. 0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x75,0x10,0x07,0x72,0xa0,0x07,0x75,0x10,0x07,
  2116. 0x72,0xa0,0x07,0x75,0x10,0x07,0x72,0xd0,0x06,0xf6,0x10,0x07,0x70,0x20,0x07,0x74,
  2117. 0xa0,0x07,0x71,0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,0x70,0x20,0x07,0x74,0xd0,
  2118. 0x06,0xee,0x80,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x73,0x20,0x07,0x43,0x98,0x04,
  2119. 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x2c,0x10,0x00,0x00,0x0a,0x00,0x00,0x00,
  2120. 0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x5a,
  2121. 0x25,0x30,0x02,0x50,0x04,0x05,0x18,0x50,0x08,0x05,0x51,0x06,0x05,0x42,0x6d,0x04,
  2122. 0x80,0xd8,0x58,0x82,0x04,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0xfb,0x00,0x00,0x00,
  2123. 0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,0x10,0xab,0x32,0xb9,0xb9,0xb4,0x37,0xb7,
  2124. 0x21,0xc6,0x32,0x28,0x00,0xa3,0x50,0xb9,0x1b,0x43,0x0b,0x93,0xfb,0x9a,0x4b,0xd3,
  2125. 0x2b,0x1b,0x62,0x2c,0x81,0x22,0x2c,0x05,0xe3,0x20,0x08,0x0e,0x8e,0xad,0x0c,0xa4,
  2126. 0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,0xcd,0x0d,0x64,0x46,0x06,
  2127. 0x46,0x66,0xc6,0x65,0x66,0xa6,0x06,0x04,0xa5,0xad,0x8c,0x2e,0x8c,0xcd,0xac,0xac,
  2128. 0x65,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x26,0x65,0x88,0xa0,0x10,0x43,0x8c,
  2129. 0x25,0x58,0x8c,0x45,0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,0x04,0x51,0x8e,0x25,0x58,
  2130. 0x82,0x45,0xe0,0x16,0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,0x97,0xc6,0x56,0xe6,0x42,
  2131. 0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,0x26,0xc6,0x56,0x36,0x44,
  2132. 0x50,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2e,0x66,
  2133. 0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,0x61,0x62,0x6c,0x65,0x43,
  2134. 0x04,0x65,0x21,0x19,0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,0xc1,0xa5,0xb1,0x95,0xb9,
  2135. 0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,0x7d,0x99,0x95,0xd1,0x8d,
  2136. 0xa1,0x7d,0x95,0xb9,0x85,0x89,0xb1,0x95,0x0d,0x11,0x94,0x86,0x51,0x58,0x9a,0x9c,
  2137. 0x8b,0x5d,0x99,0x1c,0x5d,0x19,0xde,0xd7,0x5b,0x1d,0x1d,0x5c,0x1d,0x1d,0x97,0xba,
  2138. 0xb9,0x32,0x39,0x14,0xb6,0xb7,0x31,0x37,0x98,0x14,0x46,0x61,0x69,0x72,0x2e,0x61,
  2139. 0x72,0x67,0x5f,0x74,0x79,0x70,0x65,0x5f,0x6e,0x61,0x6d,0x65,0x34,0xcc,0xd8,0xde,
  2140. 0xc2,0xe8,0x64,0xc8,0x84,0xa5,0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xb9,0x85,0xb5,0x95,
  2141. 0x51,0xa8,0xb3,0x1b,0xc2,0x28,0x8f,0x02,0x29,0x91,0x22,0x29,0x93,0x42,0x71,0xa9,
  2142. 0x9b,0x2b,0x93,0x43,0x61,0x7b,0x1b,0x73,0x8b,0x49,0xa1,0x61,0xc6,0xf6,0x16,0x46,
  2143. 0x47,0xc3,0x62,0xec,0x8d,0xed,0x4d,0x6e,0x08,0xa3,0x3c,0x8a,0xa5,0x44,0xca,0xa5,
  2144. 0x4c,0x0a,0x46,0x26,0x2c,0x4d,0xce,0x05,0xee,0x6d,0x2e,0x8d,0x2e,0xed,0xcd,0x8d,
  2145. 0xcb,0x19,0xdb,0x17,0xd4,0xdb,0x5c,0x1a,0x5d,0xda,0x9b,0xdb,0x10,0x45,0xd1,0x94,
  2146. 0x48,0xb9,0x94,0x49,0xd9,0x86,0x18,0x4a,0xa5,0x64,0x0a,0x47,0x28,0x2c,0x4d,0xce,
  2147. 0xc5,0xae,0x4c,0x8e,0xae,0x0c,0xef,0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x52,0x58,0x9a,
  2148. 0x9c,0x0b,0xdb,0xdb,0x58,0x18,0x5d,0xda,0x9b,0xdb,0x57,0x9a,0x1b,0x59,0x19,0x1e,
  2149. 0xbd,0xb3,0x32,0xb7,0x32,0xb9,0x30,0xba,0x32,0x32,0x94,0xaf,0xaf,0xb0,0x34,0xb9,
  2150. 0x2f,0x38,0xb6,0xb0,0xb1,0x32,0xb4,0x37,0x36,0xb2,0x32,0xb9,0xaf,0xaf,0x14,0x22,
  2151. 0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x43,0xa8,0x45,0x50,0x3c,0xe5,0x5b,0x84,
  2152. 0x25,0x50,0xc0,0x40,0x89,0x14,0x49,0x99,0x94,0x30,0x60,0x42,0x57,0x86,0x37,0xf6,
  2153. 0xf6,0x26,0x47,0x06,0x33,0x84,0x5a,0x02,0xc5,0x53,0xbe,0x25,0x58,0x02,0x05,0x0c,
  2154. 0x94,0x48,0x91,0x94,0x49,0x19,0x03,0x1a,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x43,0xa8,
  2155. 0x65,0x50,0x3c,0xe5,0x5b,0x86,0x25,0x50,0xc0,0x40,0x89,0x94,0x4b,0x99,0x94,0x32,
  2156. 0xa0,0x12,0x96,0x26,0xe7,0x22,0x56,0x67,0x66,0x56,0x26,0xc7,0x27,0x2c,0x4d,0xce,
  2157. 0x45,0xac,0xce,0xcc,0xac,0x4c,0xee,0x6b,0x2e,0x4d,0xaf,0x8c,0x48,0x58,0x9a,0x9c,
  2158. 0x8b,0x5c,0x59,0x18,0x19,0xa9,0xb0,0x34,0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,
  2159. 0x2f,0xba,0x3c,0xb8,0xb2,0xaf,0x34,0x37,0xb3,0x37,0x22,0x66,0x6c,0x6f,0x61,0x74,
  2160. 0x34,0x78,0x34,0x1c,0xda,0xec,0xe0,0x86,0x28,0x8b,0xb0,0x10,0x8b,0xa0,0xac,0x81,
  2161. 0xc2,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,0xc2,0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,
  2162. 0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,0xc9,0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,
  2163. 0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,0x7d,0xcd,0xa5,0xe9,0x95,0x31,0xb1,0x9b,0xfb,
  2164. 0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf0,0x15,0x93,0x33,0x84,0x0c,0x96,0x43,0x39,
  2165. 0x03,0x05,0x0d,0x16,0x42,0xf9,0x16,0x61,0x09,0x94,0x34,0x50,0xd4,0x40,0x69,0x03,
  2166. 0xc5,0x0d,0x16,0x42,0x79,0x83,0x05,0x51,0x22,0x05,0x0e,0x94,0x49,0x89,0x83,0x21,
  2167. 0x88,0x22,0x06,0x0a,0x19,0x28,0x66,0xa0,0xc8,0xc1,0x10,0x23,0x01,0x94,0x4e,0x99,
  2168. 0x03,0x3e,0x6f,0x6d,0x6e,0x69,0x70,0x6f,0x74,0x65,0x6e,0x74,0x20,0x63,0x68,0x61,
  2169. 0x72,0x7c,0xa6,0xd2,0xda,0xe0,0xd8,0xca,0x40,0x86,0x56,0x56,0x40,0xa8,0x84,0x82,
  2170. 0x82,0x86,0x08,0x8a,0x1d,0x0c,0x31,0x94,0x3a,0x50,0xee,0xa0,0x49,0x86,0x18,0x0a,
  2171. 0x1e,0x28,0x78,0xd0,0x24,0xbc,0xc2,0xd2,0xe4,0x5a,0xc2,0xd8,0xd2,0xc2,0xe6,0x5a,
  2172. 0xe6,0xc6,0xde,0xe0,0xca,0xe6,0x50,0xda,0xc2,0xd2,0xdc,0x60,0x52,0x86,0x10,0xca,
  2173. 0x1e,0x28,0x7a,0x40,0x2b,0x2c,0x4d,0xae,0x25,0x8c,0x2d,0x2d,0x6c,0xae,0x65,0x6e,
  2174. 0xec,0x0d,0xae,0xac,0x25,0x4c,0xee,0x0c,0x65,0x26,0x65,0x88,0xa1,0xf4,0x81,0xb2,
  2175. 0x07,0x0a,0x1f,0x0c,0x11,0x94,0x3e,0x18,0x11,0xb1,0x03,0x3b,0xd8,0x43,0x3b,0xb8,
  2176. 0x41,0x3b,0xbc,0x03,0x39,0xd4,0x03,0x3b,0x94,0x83,0x1b,0x98,0x03,0x3b,0x84,0xc3,
  2177. 0x39,0xcc,0xc3,0x14,0x21,0x18,0x46,0x28,0xec,0xc0,0x0e,0xf6,0xd0,0x0e,0x6e,0x90,
  2178. 0x0e,0xe4,0x50,0x0e,0xee,0x40,0x0f,0x53,0x82,0x62,0xc4,0x12,0x0e,0xe9,0x20,0x0f,
  2179. 0x6e,0x60,0x0f,0xe5,0x20,0x0f,0xf3,0x90,0x0e,0xef,0xe0,0x0e,0x53,0x02,0x63,0x04,
  2180. 0x15,0x0e,0xe9,0x20,0x0f,0x6e,0xc0,0x0e,0xe1,0xe0,0x0e,0xe7,0x50,0x0f,0xe1,0x70,
  2181. 0x0e,0xe5,0xf0,0x0b,0xf6,0x50,0x0e,0xf2,0x30,0x0f,0xe9,0xf0,0x0e,0xee,0x30,0x25,
  2182. 0x40,0x46,0x4c,0xe1,0x90,0x0e,0xf2,0xe0,0x06,0xe3,0xf0,0x0e,0xed,0x00,0x0f,0xe9,
  2183. 0xc0,0x0e,0xe5,0xf0,0x0b,0xef,0x00,0x0f,0xf4,0x90,0x0e,0xef,0xe0,0x0e,0xf3,0x30,
  2184. 0x65,0x50,0x18,0x67,0x84,0x12,0x0e,0xe9,0x20,0x0f,0x6e,0x60,0x0f,0xe5,0x20,0x0f,
  2185. 0xf4,0x50,0x0e,0xf8,0x30,0x25,0xa0,0x03,0x00,0x00,0x00,0x00,0x79,0x18,0x00,0x00,
  2186. 0xa5,0x00,0x00,0x00,0x33,0x08,0x80,0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,0x88,
  2187. 0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,0x07,0x79,0x78,0x07,0x73,0x98,0x71,0x0c,0xe6,
  2188. 0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,0x0e,0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,0xce,
  2189. 0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,0x43,0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,0xc8,
  2190. 0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,0x8c,0x74,0x70,0x07,0x7b,0x08,0x07,0x79,0x48,
  2191. 0x87,0x70,0x70,0x07,0x7a,0x70,0x03,0x76,0x78,0x87,0x70,0x20,0x87,0x19,0xcc,0x11,
  2192. 0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,0x6e,0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,0x0e,
  2193. 0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,0xd8,0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,0x89,
  2194. 0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,0xb4,0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,0x3b,
  2195. 0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x68,0x87,0x72,0x68,0x07,0x37,
  2196. 0x80,0x87,0x70,0x90,0x87,0x70,0x60,0x07,0x76,0x28,0x07,0x76,0xf8,0x05,0x76,0x78,
  2197. 0x87,0x77,0x80,0x87,0x5f,0x08,0x87,0x71,0x18,0x87,0x72,0x98,0x87,0x79,0x98,0x81,
  2198. 0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,0xf5,0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,0xa1,
  2199. 0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,0xe4,0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,0x1c,
  2200. 0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,0x90,0x43,0x39,0xc8,0x43,0x39,0x98,0x43,0x39,
  2201. 0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,0x43,0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,0xbc,
  2202. 0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,0x3b,0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,0x58,
  2203. 0x87,0x72,0x70,0x83,0x74,0x68,0x07,0x78,0x60,0x87,0x74,0x18,0x87,0x74,0xa0,0x87,
  2204. 0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,0xf2,0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,0x0f,
  2205. 0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,0x20,0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,0x1e,
  2206. 0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,0xe0,0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,0x66,
  2207. 0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,0x83,0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,0x7b,
  2208. 0x68,0x07,0x37,0x60,0x87,0x77,0x78,0x07,0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,0xf0,
  2209. 0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,0x61,0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,0x7e,
  2210. 0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,0x1d,0xf0,0x61,0x06,0x54,0x85,0x83,0x38,0xcc,
  2211. 0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,0x39,0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,0xc3,
  2212. 0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,0x79,0x98,0x87,0x77,0x18,0x87,0x74,0x08,0x07,
  2213. 0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,0xe3,0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,0x0e,
  2214. 0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,0xe4,0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,0x1e,
  2215. 0x66,0x48,0x19,0x3b,0xb0,0x83,0x3d,0xb4,0x83,0x1b,0x84,0xc3,0x38,0x8c,0x43,0x39,
  2216. 0xcc,0xc3,0x3c,0xb8,0xc1,0x39,0xc8,0xc3,0x3b,0xd4,0x03,0x3c,0xcc,0x48,0xb4,0x71,
  2217. 0x08,0x07,0x76,0x60,0x07,0x71,0x08,0x87,0x71,0x58,0x87,0x19,0xdb,0xc6,0x0e,0xec,
  2218. 0x60,0x0f,0xed,0xe0,0x06,0xf0,0x20,0x0f,0xe5,0x30,0x0f,0xe5,0x20,0x0f,0xf6,0x50,
  2219. 0x0e,0x6e,0x10,0x0e,0xe3,0x30,0x0e,0xe5,0x30,0x0f,0xf3,0xe0,0x06,0xe9,0xe0,0x0e,
  2220. 0xe4,0x50,0x0e,0xf8,0x30,0x23,0xe2,0xec,0x61,0x1c,0xc2,0x81,0x1d,0xd8,0xe1,0x17,
  2221. 0xec,0x21,0x1d,0xe6,0x21,0x1d,0xc4,0x21,0x1d,0xd8,0x21,0x1d,0xe8,0x21,0x1f,0x66,
  2222. 0x20,0x9d,0x3b,0xbc,0x43,0x3d,0xb8,0x03,0x39,0x94,0x83,0x39,0xcc,0x58,0xbc,0x70,
  2223. 0x70,0x07,0x77,0x78,0x07,0x7a,0x08,0x07,0x7a,0x48,0x87,0x77,0x70,0x87,0x19,0xce,
  2224. 0x87,0x0e,0xe5,0x10,0x0e,0xf0,0x10,0x0e,0xec,0xc0,0x0e,0xef,0x30,0x0e,0xf3,0x90,
  2225. 0x0e,0xf4,0x50,0x0e,0x33,0x28,0x30,0x08,0x87,0x74,0x90,0x07,0x37,0x30,0x87,0x7a,
  2226. 0x70,0x87,0x71,0xa0,0x87,0x74,0x78,0x07,0x77,0xf8,0x85,0x73,0x90,0x87,0x77,0xa8,
  2227. 0x07,0x78,0x98,0x07,0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x02,0x00,0x00,0x00,
  2228. 0x06,0x50,0x30,0x00,0xd2,0xd0,0x00,0x00,0x61,0x20,0x00,0x00,0x20,0x00,0x00,0x00,
  2229. 0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0xf4,0xc6,0x22,0x82,
  2230. 0x20,0x08,0x46,0x00,0xa8,0x95,0x40,0x19,0xd0,0x98,0x01,0xa0,0x30,0x03,0x00,0x00,
  2231. 0xe3,0x15,0x07,0x33,0x4d,0x0c,0x05,0x65,0x90,0x81,0x19,0x0e,0x13,0x02,0xf9,0x8c,
  2232. 0x57,0x2c,0xd0,0x75,0x21,0x14,0x94,0x41,0x06,0xe8,0x60,0x4c,0x08,0xe4,0x63,0x41,
  2233. 0x01,0x9f,0xf1,0x0a,0xa8,0xe2,0x38,0x86,0x82,0x62,0x43,0x00,0x9f,0xd9,0x06,0xa7,
  2234. 0x02,0x66,0x1b,0x82,0x2a,0x98,0x6d,0x08,0x06,0x21,0x83,0x80,0x18,0x00,0x00,0x00,
  2235. 0x06,0x00,0x00,0x00,0x5b,0x8a,0x20,0xc8,0x83,0xc3,0x0f,0xb6,0x14,0x45,0x90,0x07,
  2236. 0x87,0x1f,0x6c,0x29,0x94,0x20,0x0f,0x0e,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2237. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2238. };
  2239. /*
  2240. #include <metal_stdlib>
  2241. #include <simd/simd.h>
  2242. using namespace metal;
  2243. struct fs_params
  2244. {
  2245. float pma;
  2246. };
  2247. struct main0_out
  2248. {
  2249. float4 frag_color [[color(0)]];
  2250. };
  2251. struct main0_in
  2252. {
  2253. float2 uv [[user(locn0)]];
  2254. float4 color [[user(locn1)]];
  2255. };
  2256. fragment main0_out main0(main0_in in [[stage_in]], constant fs_params& _53 [[buffer(0)]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]])
  2257. {
  2258. main0_out out = {};
  2259. float4 _28 = tex.sample(smp, in.uv) * in.color;
  2260. float _37 = _28.w;
  2261. out.frag_color = mix(_28, float4(_28.xyz * _37, _37) * in.color, float4(_53.pma));
  2262. return out;
  2263. }
  2264. */
  2265. static const uint8_t _sspine_fs_bytecode_metal_ios[3529] = {
  2266. 0x4d,0x54,0x4c,0x42,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2267. 0xc9,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2268. 0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2269. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2270. 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2271. 0xf0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x6d,0x00,0x00,0x00,
  2272. 0x4e,0x41,0x4d,0x45,0x06,0x00,0x6d,0x61,0x69,0x6e,0x30,0x00,0x54,0x59,0x50,0x45,
  2273. 0x01,0x00,0x01,0x48,0x41,0x53,0x48,0x20,0x00,0xfb,0xc3,0x38,0x07,0x5d,0xf9,0xd9,
  2274. 0x68,0x99,0xff,0xba,0x47,0x1d,0x29,0xd8,0x13,0x4a,0xba,0xb3,0x71,0x0a,0x9c,0x4f,
  2275. 0x75,0x70,0x45,0x49,0x48,0xd7,0x6b,0xc4,0xf9,0x4f,0x46,0x46,0x54,0x18,0x00,0x00,
  2276. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2277. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x45,0x52,0x53,0x08,0x00,0x01,0x00,0x08,
  2278. 0x00,0x01,0x00,0x01,0x00,0x45,0x4e,0x44,0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,
  2279. 0x54,0x04,0x00,0x00,0x00,0x45,0x4e,0x44,0x54,0xde,0xc0,0x17,0x0b,0x00,0x00,0x00,
  2280. 0x00,0x14,0x00,0x00,0x00,0xd8,0x0c,0x00,0x00,0xff,0xff,0xff,0xff,0x42,0x43,0xc0,
  2281. 0xde,0x21,0x0c,0x00,0x00,0x33,0x03,0x00,0x00,0x0b,0x82,0x20,0x00,0x02,0x00,0x00,
  2282. 0x00,0x12,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,
  2283. 0x39,0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,
  2284. 0x02,0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,
  2285. 0x24,0x48,0x0a,0x90,0x21,0x23,0xc4,0x52,0x80,0x0c,0x19,0x21,0x72,0x24,0x07,0xc8,
  2286. 0x48,0x11,0x62,0xa8,0xa0,0xa8,0x40,0xc6,0xf0,0x01,0x00,0x00,0x00,0x51,0x18,0x00,
  2287. 0x00,0x82,0x00,0x00,0x00,0x1b,0xc2,0x24,0xf8,0xff,0xff,0xff,0xff,0x01,0x60,0x00,
  2288. 0x09,0xa8,0x88,0x70,0x80,0x07,0x78,0x90,0x87,0x77,0xc0,0x87,0x36,0x30,0x87,0x7a,
  2289. 0x70,0x87,0x71,0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,
  2290. 0xe8,0x41,0x1e,0xea,0xa1,0x1c,0x00,0xa2,0x1d,0xd2,0xc1,0x1d,0xda,0x80,0x1d,0xca,
  2291. 0xe1,0x1c,0xc2,0x81,0x1d,0xda,0xc0,0x1e,0xca,0x61,0x1c,0xe8,0xe1,0x1d,0xe4,0xa1,
  2292. 0x0d,0xee,0x21,0x1d,0xc8,0x81,0x1e,0xd0,0x01,0x88,0x03,0x39,0xc0,0x03,0x60,0x70,
  2293. 0x87,0x77,0x68,0x03,0x71,0xa8,0x87,0x74,0x60,0x07,0x7a,0x48,0x07,0x77,0x98,0x07,
  2294. 0x80,0x70,0x87,0x77,0x68,0x03,0x73,0x90,0x87,0x70,0x68,0x87,0x72,0x68,0x03,0x78,
  2295. 0x78,0x87,0x74,0x70,0x07,0x7a,0x28,0x07,0x79,0x68,0x83,0x72,0x60,0x87,0x74,0x68,
  2296. 0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,0xda,0xc0,0x1c,0xe4,
  2297. 0x21,0x1c,0xda,0xa1,0x1c,0xda,0x00,0x1e,0xde,0x21,0x1d,0xdc,0x81,0x1e,0xca,0x41,
  2298. 0x1e,0xda,0xa0,0x1c,0xd8,0x21,0x1d,0xda,0xa1,0x0d,0xdc,0xe1,0x1d,0xdc,0xa1,0x0d,
  2299. 0xd8,0xa1,0x1c,0xc2,0xc1,0x1c,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x80,0x70,0x87,
  2300. 0x77,0x68,0x83,0x74,0x70,0x07,0x73,0x98,0x87,0x36,0x30,0x07,0x78,0x68,0x83,0x76,
  2301. 0x08,0x07,0x7a,0x40,0x07,0x80,0x1e,0xe4,0xa1,0x1e,0xca,0x01,0x20,0xdc,0xe1,0x1d,
  2302. 0xda,0xc0,0x1d,0xc2,0xc1,0x1d,0xe6,0xa1,0x0d,0xcc,0x01,0x1e,0xda,0xa0,0x1d,0xc2,
  2303. 0x81,0x1e,0xd0,0x01,0xa0,0x07,0x79,0xa8,0x87,0x72,0x00,0x08,0x77,0x78,0x87,0x36,
  2304. 0x98,0x87,0x74,0x38,0x07,0x77,0x28,0x07,0x72,0x68,0x03,0x7d,0x28,0x07,0x79,0x78,
  2305. 0x87,0x79,0x68,0x03,0x73,0x80,0x87,0x36,0x68,0x87,0x70,0xa0,0x07,0x74,0x00,0xe8,
  2306. 0x41,0x1e,0xea,0xa1,0x1c,0x00,0xc2,0x1d,0xde,0xa1,0x0d,0xe8,0x41,0x1e,0xc2,0x01,
  2307. 0x1e,0xe0,0x21,0x1d,0xdc,0xe1,0x1c,0xda,0xa0,0x1d,0xc2,0x81,0x1e,0xd0,0x01,0xa0,
  2308. 0x07,0x79,0xa8,0x87,0x72,0x00,0x88,0x79,0xa0,0x87,0x70,0x18,0x87,0x75,0x68,0x03,
  2309. 0x78,0x90,0x87,0x77,0xa0,0x87,0x72,0x18,0x07,0x7a,0x78,0x07,0x79,0x68,0x03,0x71,
  2310. 0xa8,0x07,0x73,0x30,0x87,0x72,0x90,0x87,0x36,0x98,0x87,0x74,0xd0,0x87,0x72,0x00,
  2311. 0xf0,0x00,0x20,0xea,0xc1,0x1d,0xe6,0x21,0x1c,0xcc,0xa1,0x1c,0xda,0xc0,0x1c,0xe0,
  2312. 0xa1,0x0d,0xda,0x21,0x1c,0xe8,0x01,0x1d,0x00,0x7a,0x90,0x87,0x7a,0x28,0x07,0x60,
  2313. 0xc3,0x26,0x0c,0xc0,0x02,0x54,0x43,0x38,0xa4,0x83,0x3c,0xb4,0x81,0x38,0xd4,0x83,
  2314. 0x39,0x98,0x43,0x39,0xc8,0x43,0x1b,0xb8,0xc3,0x3b,0xb4,0x41,0x38,0xb0,0x43,0x3a,
  2315. 0x84,0xc3,0x3c,0x00,0x1b,0x8c,0x81,0x00,0x16,0xa0,0xda,0x60,0x10,0x05,0xb0,0x00,
  2316. 0xd5,0x06,0xa3,0xf8,0xff,0xff,0xff,0xff,0x01,0x90,0x00,0x6a,0x03,0x62,0xfc,0xff,
  2317. 0xff,0xff,0xff,0x00,0x30,0x80,0x04,0x54,0x1b,0x8c,0x23,0x00,0x16,0xa0,0xda,0x60,
  2318. 0x20,0x02,0xb0,0x00,0xd5,0x06,0x24,0xf9,0xff,0xff,0xff,0xff,0x01,0x60,0x00,0x09,
  2319. 0xa8,0x36,0x18,0xca,0xff,0xff,0xff,0xff,0x0f,0x80,0x04,0x50,0x00,0x49,0x18,0x00,
  2320. 0x00,0x05,0x00,0x00,0x00,0x13,0x88,0x40,0x18,0x88,0x09,0x41,0x31,0x61,0x30,0x0e,
  2321. 0x64,0xc2,0x90,0x1c,0xc8,0x84,0x40,0x01,0x00,0x89,0x20,0x00,0x00,0x27,0x00,0x00,
  2322. 0x00,0x32,0x22,0x48,0x09,0x20,0x64,0x85,0x04,0x93,0x22,0xa4,0x84,0x04,0x93,0x22,
  2323. 0xe3,0x84,0xa1,0x90,0x14,0x12,0x4c,0x8a,0x8c,0x0b,0x84,0xa4,0x4c,0x10,0x6c,0x33,
  2324. 0x00,0xc3,0x08,0x04,0x60,0x83,0x30,0x8c,0x20,0x00,0x07,0x49,0x53,0x44,0x09,0x93,
  2325. 0x5f,0x48,0xff,0x03,0x44,0x00,0x23,0xa1,0x00,0x0c,0x22,0x10,0xc2,0x51,0xd2,0x14,
  2326. 0x51,0xc2,0xe4,0xff,0x13,0x71,0x4d,0x54,0x44,0xfc,0xf6,0xf0,0x4f,0x63,0x04,0xc0,
  2327. 0x20,0x82,0x11,0x5c,0x24,0x4d,0x11,0x25,0x4c,0xfe,0x2f,0x01,0xcc,0xb3,0x10,0xd1,
  2328. 0x3f,0x8d,0x11,0x00,0x83,0x08,0x88,0x50,0x0c,0x31,0x42,0x39,0x89,0x54,0x21,0x42,
  2329. 0x08,0x81,0xd8,0x1c,0x41,0x30,0x47,0x00,0x06,0xc3,0x08,0xc2,0x53,0x90,0x70,0xd2,
  2330. 0x70,0xd0,0x01,0x8a,0x03,0x01,0x29,0xf0,0x86,0x11,0x86,0x67,0x18,0x61,0x00,0x86,
  2331. 0x11,0x88,0x67,0x8e,0x00,0x14,0x06,0x11,0x00,0x61,0x04,0x00,0x00,0x13,0xa8,0x70,
  2332. 0x48,0x07,0x79,0xb0,0x03,0x3a,0x68,0x83,0x70,0x80,0x07,0x78,0x60,0x87,0x72,0x68,
  2333. 0x83,0x74,0x78,0x87,0x79,0xc8,0x03,0x37,0x80,0x03,0x37,0x80,0x83,0x0d,0xb7,0x51,
  2334. 0x0e,0x6d,0x00,0x0f,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,
  2335. 0x74,0xd0,0x06,0xe9,0x10,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x78,
  2336. 0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,
  2337. 0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xe9,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,
  2338. 0x7a,0x30,0x07,0x72,0xd0,0x06,0xe9,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,
  2339. 0x60,0x07,0x74,0xd0,0x06,0xe6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,
  2340. 0x07,0x72,0xd0,0x06,0xe6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,
  2341. 0x74,0xd0,0x06,0xf6,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x7a,0x10,0x07,0x76,
  2342. 0xd0,0x06,0xf6,0x20,0x07,0x74,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,
  2343. 0x06,0xf6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,
  2344. 0xf6,0x40,0x07,0x78,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,
  2345. 0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xf6,0x90,
  2346. 0x07,0x76,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,
  2347. 0xf6,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,
  2348. 0x80,0x07,0x6d,0x60,0x0f,0x71,0x90,0x07,0x72,0xa0,0x07,0x72,0x50,0x07,0x76,0xa0,
  2349. 0x07,0x72,0x50,0x07,0x76,0xd0,0x06,0xf6,0x20,0x07,0x75,0x60,0x07,0x7a,0x20,0x07,
  2350. 0x75,0x60,0x07,0x7a,0x20,0x07,0x75,0x60,0x07,0x6d,0x60,0x0f,0x75,0x10,0x07,0x72,
  2351. 0xa0,0x07,0x75,0x10,0x07,0x72,0xa0,0x07,0x75,0x10,0x07,0x72,0xd0,0x06,0xf6,0x10,
  2352. 0x07,0x70,0x20,0x07,0x74,0xa0,0x07,0x71,0x00,0x07,0x72,0x40,0x07,0x7a,0x10,0x07,
  2353. 0x70,0x20,0x07,0x74,0xd0,0x06,0xee,0x80,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x73,
  2354. 0x20,0x07,0x43,0x98,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x21,0x4c,0x03,
  2355. 0x04,0x80,0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0x46,0x02,0x02,0x60,0x00,0x00,0x00,
  2356. 0x00,0x00,0x20,0x0b,0x04,0x09,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,
  2357. 0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x7a,0x23,0x00,0x25,0x50,0x08,0x45,0x50,
  2358. 0x10,0x65,0x40,0x78,0x04,0x80,0xe8,0x58,0x82,0x04,0x00,0x00,0x00,0x79,0x18,0x00,
  2359. 0x00,0x1c,0x01,0x00,0x00,0x1a,0x03,0x4c,0x10,0x97,0x29,0xa2,0x25,0x10,0xab,0x32,
  2360. 0xb9,0xb9,0xb4,0x37,0xb7,0x21,0xc6,0x63,0x4c,0x00,0xa5,0x50,0xb9,0x1b,0x43,0x0b,
  2361. 0x93,0xfb,0x9a,0x4b,0xd3,0x2b,0x1b,0x62,0x3c,0xc4,0x24,0x3c,0x05,0xe3,0x20,0x08,
  2362. 0x0e,0x8e,0xad,0x0c,0xa4,0xad,0x8c,0x2e,0x8c,0x0d,0xc4,0xae,0x4c,0x6e,0x2e,0xed,
  2363. 0xcd,0x0d,0x64,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x06,0x04,0xa5,0xad,0x8c,
  2364. 0x2e,0x8c,0xcd,0xac,0xac,0x65,0x46,0x06,0x46,0x66,0xc6,0x65,0x66,0xa6,0x26,0x65,
  2365. 0x88,0x30,0x11,0x43,0x8c,0x87,0x78,0x8e,0x67,0x60,0xd1,0x54,0x46,0x17,0xc6,0x36,
  2366. 0x04,0x99,0x8e,0x87,0x78,0x88,0x67,0xe0,0x16,0x96,0x26,0xe7,0x32,0xf6,0xd6,0x06,
  2367. 0x97,0xc6,0x56,0xe6,0x42,0x56,0xe6,0xf6,0x26,0xd7,0x36,0xf7,0x45,0x96,0x36,0x17,
  2368. 0x26,0xc6,0x56,0x36,0x44,0x98,0x12,0x72,0x61,0x69,0x72,0x2e,0x63,0x6f,0x6d,0x70,
  2369. 0x69,0x6c,0x65,0x2e,0x66,0x61,0x73,0x74,0x5f,0x6d,0x61,0x74,0x68,0x5f,0x65,0x6e,
  2370. 0x61,0x62,0x6c,0x65,0x43,0x84,0x69,0x21,0x19,0x84,0xa5,0xc9,0xb9,0x8c,0xbd,0xb5,
  2371. 0xc1,0xa5,0xb1,0x95,0xb9,0x98,0xc9,0x85,0xb5,0x95,0x89,0xd5,0x99,0x99,0x95,0xc9,
  2372. 0x7d,0x99,0x95,0xd1,0x8d,0xa1,0x7d,0x95,0xb9,0x85,0x89,0xb1,0x95,0x0d,0x11,0xa6,
  2373. 0x86,0x51,0x58,0x9a,0x9c,0x8b,0x5c,0x99,0x1b,0x59,0x99,0xdc,0x17,0x5d,0x98,0xdc,
  2374. 0x59,0x19,0x1d,0xa3,0xb0,0x34,0x39,0x97,0x30,0xb9,0xb3,0x2f,0xba,0x3c,0xb8,0xb2,
  2375. 0x2f,0xb7,0xb0,0xb6,0x32,0x1a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x64,0xc2,0xd2,0xe4,
  2376. 0x5c,0xc2,0xe4,0xce,0xbe,0xdc,0xc2,0xda,0xca,0xa8,0x98,0xc9,0x85,0x9d,0x7d,0x8d,
  2377. 0xbd,0xb1,0xbd,0xc9,0x0d,0x61,0xa6,0xe7,0x19,0x26,0x68,0x8a,0x26,0x69,0x9a,0x86,
  2378. 0x08,0x13,0x45,0x29,0x2c,0x4d,0xce,0xc5,0x4c,0x2e,0xec,0xac,0xad,0xcc,0x8d,0xee,
  2379. 0x2b,0xcd,0x0d,0xae,0x8e,0x8e,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,0x1b,
  2380. 0x4c,0x0a,0x95,0xb0,0x34,0x39,0x97,0xb1,0x32,0x37,0xba,0x32,0x39,0x3e,0x61,0x69,
  2381. 0x72,0x2e,0x70,0x65,0x72,0x73,0x70,0x65,0x63,0x74,0x69,0x76,0x65,0x34,0xcc,0xd8,
  2382. 0xde,0xc2,0xe8,0x64,0x28,0xd4,0xd9,0x0d,0x91,0x9e,0x61,0xb2,0xa6,0x6b,0xc2,0xa6,
  2383. 0x6c,0x82,0x26,0x6d,0x92,0xa6,0x8d,0x4b,0xdd,0x5c,0x99,0x1c,0x0a,0xdb,0xdb,0x98,
  2384. 0x5b,0x4c,0x0a,0x8b,0xb1,0x37,0xb6,0x37,0xb9,0x21,0xd2,0x43,0x4c,0xd6,0xd4,0x4d,
  2385. 0xd8,0x94,0x4d,0xd0,0x14,0x4d,0xd2,0xe4,0x51,0x09,0x4b,0x93,0x73,0x11,0xab,0x33,
  2386. 0x33,0x2b,0x93,0xe3,0x13,0x96,0x26,0xe7,0x22,0x56,0x67,0x66,0x56,0x26,0xf7,0x35,
  2387. 0x97,0xa6,0x57,0x46,0x29,0x2c,0x4d,0xce,0x85,0xed,0x6d,0x2c,0x8c,0x2e,0xed,0xcd,
  2388. 0xed,0x2b,0xcd,0x8d,0xac,0x0c,0x8f,0x48,0x58,0x9a,0x9c,0x8b,0x5c,0x59,0x18,0x19,
  2389. 0xa9,0xb0,0x34,0x39,0x97,0x39,0x3a,0xb9,0xba,0x31,0xba,0x2f,0xba,0x3c,0xb8,0xb2,
  2390. 0xaf,0x34,0x37,0xb3,0x37,0x16,0x66,0x6c,0x6f,0x61,0x74,0x1c,0xe0,0xda,0xc2,0x86,
  2391. 0x28,0xcf,0xf0,0x14,0xcf,0x30,0x95,0xc1,0x64,0x06,0x8c,0xc2,0xd2,0xe4,0x5c,0xc2,
  2392. 0xe4,0xce,0xbe,0xe8,0xf2,0xe0,0xca,0xbe,0xe6,0xd2,0xf4,0xca,0x78,0x85,0xa5,0xc9,
  2393. 0xb9,0x84,0xc9,0x9d,0x7d,0xd1,0xe5,0xc1,0x95,0x7d,0x85,0xb1,0xa5,0x9d,0xb9,0x7d,
  2394. 0xcd,0xa5,0xe9,0x95,0x31,0x31,0x9b,0xfb,0x82,0x0b,0x93,0x0b,0x6b,0x9b,0xe3,0xf0,
  2395. 0x55,0x33,0x33,0x84,0x0c,0x1e,0x63,0x02,0x83,0x29,0x0c,0x9e,0x62,0x12,0x83,0x67,
  2396. 0x78,0x88,0x69,0x0c,0x26,0x32,0x98,0xce,0x60,0x42,0x83,0xa7,0x98,0xd2,0xe0,0x29,
  2397. 0x26,0x68,0x52,0x83,0x49,0x9a,0xd6,0x80,0x4b,0x58,0x9a,0x9c,0x0b,0x5d,0x19,0x1e,
  2398. 0x5d,0x9d,0x5c,0x19,0x95,0xb0,0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x62,
  2399. 0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,0x2c,
  2400. 0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x3e,0x1c,0xe8,0xca,0xf0,0x86,0x50,0x0f,0x32,
  2401. 0xb5,0xc1,0x24,0x06,0xcf,0xf0,0x10,0x93,0x1b,0x4c,0xd0,0xf4,0x06,0x93,0x34,0xc1,
  2402. 0x01,0x97,0xb0,0x34,0x39,0x97,0xb9,0xb0,0x36,0x38,0xb6,0x32,0x39,0x1e,0x73,0x61,
  2403. 0x6d,0x70,0x6c,0x65,0x72,0x1c,0xe6,0xda,0xe0,0x86,0x48,0x4f,0x31,0xc9,0xc1,0x24,
  2404. 0x06,0xcf,0xf0,0x10,0x13,0x34,0xcd,0xc1,0x24,0x4d,0x74,0x30,0x44,0x99,0xb8,0xe9,
  2405. 0x9b,0xd8,0x60,0x8a,0x83,0xa9,0x0e,0x86,0x18,0x0b,0x30,0x55,0x93,0x1d,0xf0,0x0a,
  2406. 0x4b,0x93,0x6b,0x09,0x63,0x4b,0x0b,0x9b,0x6b,0x99,0x1b,0x7b,0x83,0x2b,0x9b,0x43,
  2407. 0x69,0x0b,0x4b,0x73,0x83,0x49,0x19,0x42,0x4c,0x79,0x30,0xe1,0x01,0xb1,0xb0,0x34,
  2408. 0xb9,0x96,0x30,0xb6,0xb4,0xb0,0xb9,0x96,0xb9,0xb1,0x37,0xb8,0xb2,0x16,0xba,0x32,
  2409. 0x3c,0xba,0x3a,0xb9,0xb2,0xb9,0x21,0xc6,0xb4,0x07,0x53,0x1e,0x4c,0x7a,0x40,0x2c,
  2410. 0x2c,0x4d,0xae,0x25,0x8c,0x2d,0x2d,0x6c,0xae,0x65,0x6e,0xec,0x0d,0xae,0xac,0x65,
  2411. 0x2e,0xac,0x0d,0x8e,0xad,0x4c,0x6e,0x6e,0x88,0x31,0xf5,0xc1,0x94,0x07,0x13,0x1f,
  2412. 0x0c,0x21,0xa6,0x3d,0x98,0xfa,0x80,0x56,0x58,0x9a,0x5c,0x4b,0x18,0x5b,0x5a,0xd8,
  2413. 0x5c,0xcb,0xdc,0xd8,0x1b,0x5c,0x59,0x4b,0x98,0xdc,0x19,0x8a,0x4c,0xca,0x10,0x63,
  2414. 0x02,0x85,0x29,0x0f,0xa6,0x3f,0x18,0x22,0x4c,0xa0,0x40,0xe7,0x4b,0x8b,0x6a,0x2a,
  2415. 0xc7,0x6c,0xee,0x0b,0x2e,0x4c,0x2e,0xac,0x6d,0x8e,0xcf,0x5b,0x9b,0x5b,0x1a,0xdc,
  2416. 0x1b,0x5d,0x99,0x1b,0x1d,0xc8,0x18,0x5a,0x98,0x1c,0x9f,0xa9,0xb4,0x36,0x38,0xb6,
  2417. 0x32,0x90,0xa1,0x95,0x15,0x10,0x2a,0xa1,0xa0,0xa0,0x21,0xc2,0x44,0x0a,0x43,0x8c,
  2418. 0x69,0x14,0xa6,0x52,0xc0,0x92,0x21,0xc6,0x54,0x06,0x93,0x29,0x60,0xc9,0x10,0x63,
  2419. 0x12,0x85,0xe9,0x14,0xb0,0x64,0x88,0x31,0xa1,0xc2,0x74,0x0a,0x58,0x32,0x22,0x62,
  2420. 0x07,0x76,0xb0,0x87,0x76,0x70,0x83,0x76,0x78,0x07,0x72,0xa8,0x07,0x76,0x28,0x07,
  2421. 0x37,0x30,0x07,0x76,0x08,0x87,0x73,0x98,0x87,0x29,0x42,0x30,0x8c,0x50,0xd8,0x81,
  2422. 0x1d,0xec,0xa1,0x1d,0xdc,0x20,0x1d,0xc8,0xa1,0x1c,0xdc,0x81,0x1e,0xa6,0x04,0xc5,
  2423. 0x88,0x25,0x1c,0xd2,0x41,0x1e,0xdc,0xc0,0x1e,0xca,0x41,0x1e,0xe6,0x21,0x1d,0xde,
  2424. 0xc1,0x1d,0xa6,0x04,0xc6,0x08,0x2a,0x1c,0xd2,0x41,0x1e,0xdc,0x80,0x1d,0xc2,0xc1,
  2425. 0x1d,0xce,0xa1,0x1e,0xc2,0xe1,0x1c,0xca,0xe1,0x17,0xec,0xa1,0x1c,0xe4,0x61,0x1e,
  2426. 0xd2,0xe1,0x1d,0xdc,0x61,0x4a,0x80,0x8c,0x98,0xc2,0x21,0x1d,0xe4,0xc1,0x0d,0xc6,
  2427. 0xe1,0x1d,0xda,0x01,0x1e,0xd2,0x81,0x1d,0xca,0xe1,0x17,0xde,0x01,0x1e,0xe8,0x21,
  2428. 0x1d,0xde,0xc1,0x1d,0xe6,0x61,0xca,0xa0,0x30,0xce,0x08,0x26,0x1c,0xd2,0x41,0x1e,
  2429. 0xdc,0xc0,0x1c,0xe4,0x21,0x1c,0xce,0xa1,0x1d,0xca,0xc1,0x1d,0xe8,0x61,0x4a,0x70,
  2430. 0x07,0x00,0x00,0x00,0x00,0x79,0x18,0x00,0x00,0xa5,0x00,0x00,0x00,0x33,0x08,0x80,
  2431. 0x1c,0xc4,0xe1,0x1c,0x66,0x14,0x01,0x3d,0x88,0x43,0x38,0x84,0xc3,0x8c,0x42,0x80,
  2432. 0x07,0x79,0x78,0x07,0x73,0x98,0x71,0x0c,0xe6,0x00,0x0f,0xed,0x10,0x0e,0xf4,0x80,
  2433. 0x0e,0x33,0x0c,0x42,0x1e,0xc2,0xc1,0x1d,0xce,0xa1,0x1c,0x66,0x30,0x05,0x3d,0x88,
  2434. 0x43,0x38,0x84,0x83,0x1b,0xcc,0x03,0x3d,0xc8,0x43,0x3d,0x8c,0x03,0x3d,0xcc,0x78,
  2435. 0x8c,0x74,0x70,0x07,0x7b,0x08,0x07,0x79,0x48,0x87,0x70,0x70,0x07,0x7a,0x70,0x03,
  2436. 0x76,0x78,0x87,0x70,0x20,0x87,0x19,0xcc,0x11,0x0e,0xec,0x90,0x0e,0xe1,0x30,0x0f,
  2437. 0x6e,0x30,0x0f,0xe3,0xf0,0x0e,0xf0,0x50,0x0e,0x33,0x10,0xc4,0x1d,0xde,0x21,0x1c,
  2438. 0xd8,0x21,0x1d,0xc2,0x61,0x1e,0x66,0x30,0x89,0x3b,0xbc,0x83,0x3b,0xd0,0x43,0x39,
  2439. 0xb4,0x03,0x3c,0xbc,0x83,0x3c,0x84,0x03,0x3b,0xcc,0xf0,0x14,0x76,0x60,0x07,0x7b,
  2440. 0x68,0x07,0x37,0x68,0x87,0x72,0x68,0x07,0x37,0x80,0x87,0x70,0x90,0x87,0x70,0x60,
  2441. 0x07,0x76,0x28,0x07,0x76,0xf8,0x05,0x76,0x78,0x87,0x77,0x80,0x87,0x5f,0x08,0x87,
  2442. 0x71,0x18,0x87,0x72,0x98,0x87,0x79,0x98,0x81,0x2c,0xee,0xf0,0x0e,0xee,0xe0,0x0e,
  2443. 0xf5,0xc0,0x0e,0xec,0x30,0x03,0x62,0xc8,0xa1,0x1c,0xe4,0xa1,0x1c,0xcc,0xa1,0x1c,
  2444. 0xe4,0xa1,0x1c,0xdc,0x61,0x1c,0xca,0x21,0x1c,0xc4,0x81,0x1d,0xca,0x61,0x06,0xd6,
  2445. 0x90,0x43,0x39,0xc8,0x43,0x39,0x98,0x43,0x39,0xc8,0x43,0x39,0xb8,0xc3,0x38,0x94,
  2446. 0x43,0x38,0x88,0x03,0x3b,0x94,0xc3,0x2f,0xbc,0x83,0x3c,0xfc,0x82,0x3b,0xd4,0x03,
  2447. 0x3b,0xb0,0xc3,0x0c,0xc7,0x69,0x87,0x70,0x58,0x87,0x72,0x70,0x83,0x74,0x68,0x07,
  2448. 0x78,0x60,0x87,0x74,0x18,0x87,0x74,0xa0,0x87,0x19,0xce,0x53,0x0f,0xee,0x00,0x0f,
  2449. 0xf2,0x50,0x0e,0xe4,0x90,0x0e,0xe3,0x40,0x0f,0xe1,0x20,0x0e,0xec,0x50,0x0e,0x33,
  2450. 0x20,0x28,0x1d,0xdc,0xc1,0x1e,0xc2,0x41,0x1e,0xd2,0x21,0x1c,0xdc,0x81,0x1e,0xdc,
  2451. 0xe0,0x1c,0xe4,0xe1,0x1d,0xea,0x01,0x1e,0x66,0x18,0x51,0x38,0xb0,0x43,0x3a,0x9c,
  2452. 0x83,0x3b,0xcc,0x50,0x24,0x76,0x60,0x07,0x7b,0x68,0x07,0x37,0x60,0x87,0x77,0x78,
  2453. 0x07,0x78,0x98,0x51,0x4c,0xf4,0x90,0x0f,0xf0,0x50,0x0e,0x33,0x1e,0x6a,0x1e,0xca,
  2454. 0x61,0x1c,0xe8,0x21,0x1d,0xde,0xc1,0x1d,0x7e,0x01,0x1e,0xe4,0xa1,0x1c,0xcc,0x21,
  2455. 0x1d,0xf0,0x61,0x06,0x54,0x85,0x83,0x38,0xcc,0xc3,0x3b,0xb0,0x43,0x3d,0xd0,0x43,
  2456. 0x39,0xfc,0xc2,0x3c,0xe4,0x43,0x3b,0x88,0xc3,0x3b,0xb0,0xc3,0x8c,0xc5,0x0a,0x87,
  2457. 0x79,0x98,0x87,0x77,0x18,0x87,0x74,0x08,0x07,0x7a,0x28,0x07,0x72,0x98,0x81,0x5c,
  2458. 0xe3,0x10,0x0e,0xec,0xc0,0x0e,0xe5,0x50,0x0e,0xf3,0x30,0x23,0xc1,0xd2,0x41,0x1e,
  2459. 0xe4,0xe1,0x17,0xd8,0xe1,0x1d,0xde,0x01,0x1e,0x66,0x48,0x19,0x3b,0xb0,0x83,0x3d,
  2460. 0xb4,0x83,0x1b,0x84,0xc3,0x38,0x8c,0x43,0x39,0xcc,0xc3,0x3c,0xb8,0xc1,0x39,0xc8,
  2461. 0xc3,0x3b,0xd4,0x03,0x3c,0xcc,0x48,0xb4,0x71,0x08,0x07,0x76,0x60,0x07,0x71,0x08,
  2462. 0x87,0x71,0x58,0x87,0x19,0xdb,0xc6,0x0e,0xec,0x60,0x0f,0xed,0xe0,0x06,0xf0,0x20,
  2463. 0x0f,0xe5,0x30,0x0f,0xe5,0x20,0x0f,0xf6,0x50,0x0e,0x6e,0x10,0x0e,0xe3,0x30,0x0e,
  2464. 0xe5,0x30,0x0f,0xf3,0xe0,0x06,0xe9,0xe0,0x0e,0xe4,0x50,0x0e,0xf8,0x30,0x23,0xe2,
  2465. 0xec,0x61,0x1c,0xc2,0x81,0x1d,0xd8,0xe1,0x17,0xec,0x21,0x1d,0xe6,0x21,0x1d,0xc4,
  2466. 0x21,0x1d,0xd8,0x21,0x1d,0xe8,0x21,0x1f,0x66,0x20,0x9d,0x3b,0xbc,0x43,0x3d,0xb8,
  2467. 0x03,0x39,0x94,0x83,0x39,0xcc,0x58,0xbc,0x70,0x70,0x07,0x77,0x78,0x07,0x7a,0x08,
  2468. 0x07,0x7a,0x48,0x87,0x77,0x70,0x87,0x19,0xce,0x87,0x0e,0xe5,0x10,0x0e,0xf0,0x10,
  2469. 0x0e,0xec,0xc0,0x0e,0xef,0x30,0x0e,0xf3,0x90,0x0e,0xf4,0x50,0x0e,0x33,0x28,0x30,
  2470. 0x08,0x87,0x74,0x90,0x07,0x37,0x30,0x87,0x7a,0x70,0x87,0x71,0xa0,0x87,0x74,0x78,
  2471. 0x07,0x77,0xf8,0x85,0x73,0x90,0x87,0x77,0xa8,0x07,0x78,0x98,0x07,0x00,0x00,0x00,
  2472. 0x00,0x71,0x20,0x00,0x00,0x0b,0x00,0x00,0x00,0x26,0xb0,0x01,0x48,0xe4,0x4b,0x00,
  2473. 0xf3,0x2c,0xc4,0x3f,0x11,0xd7,0x44,0x45,0xc4,0x6f,0x0f,0x7e,0x85,0x17,0xb7,0x6d,
  2474. 0x00,0x05,0x03,0x20,0x0d,0x6d,0x01,0x0d,0x80,0x44,0x3e,0x83,0x5c,0x7e,0x85,0x17,
  2475. 0xb7,0x0d,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x29,0x00,0x00,0x00,0x13,0x04,0x41,
  2476. 0x2c,0x10,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x74,0x47,0x00,0xc6,0x22,0x80,0x40,
  2477. 0x38,0xe6,0x20,0x06,0xc2,0xb0,0xa8,0x8e,0x35,0x0c,0xc3,0x40,0xae,0x06,0x46,0x00,
  2478. 0xe8,0xcd,0x00,0x10,0x1c,0x01,0xa0,0x3a,0xd6,0x00,0x04,0x02,0x89,0x19,0x00,0xb2,
  2479. 0x33,0x00,0x14,0x66,0x00,0x66,0x00,0x08,0x8c,0x00,0x00,0x00,0x00,0x23,0x06,0x0a,
  2480. 0x11,0x70,0xd0,0x33,0x29,0x47,0x12,0x58,0x30,0xc9,0x67,0x90,0x21,0x20,0x90,0x41,
  2481. 0x06,0xc1,0x70,0x4c,0x08,0xe4,0x33,0xc8,0x10,0x24,0xd1,0x20,0x43,0x50,0x4c,0x16,
  2482. 0x64,0xf2,0x19,0x6f,0xc8,0xba,0x31,0xa0,0x60,0xcc,0x31,0x30,0x41,0x19,0x0c,0x32,
  2483. 0x04,0x4d,0x36,0x62,0x60,0x14,0x41,0x1a,0x2c,0x45,0x30,0xdb,0x20,0x05,0x40,0x06,
  2484. 0x01,0x31,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x5b,0x0a,0xe0,0xf0,0x03,0x24,0x14,
  2485. 0xb6,0x1c,0x49,0x90,0x0a,0x47,0x28,0x20,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2486. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  2487. };
  2488. /*
  2489. #include <metal_stdlib>
  2490. #include <simd/simd.h>
  2491. using namespace metal;
  2492. struct vs_params
  2493. {
  2494. float4x4 mvp;
  2495. };
  2496. struct main0_out
  2497. {
  2498. float2 uv [[user(locn0)]];
  2499. float4 color [[user(locn1)]];
  2500. float4 gl_Position [[position]];
  2501. };
  2502. struct main0_in
  2503. {
  2504. float2 position [[attribute(0)]];
  2505. float2 texcoord0 [[attribute(1)]];
  2506. float4 color0 [[attribute(2)]];
  2507. };
  2508. vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _19 [[buffer(0)]])
  2509. {
  2510. main0_out out = {};
  2511. out.gl_Position = _19.mvp * float4(in.position, 0.0, 1.0);
  2512. out.uv = in.texcoord0;
  2513. out.color = in.color0;
  2514. return out;
  2515. }
  2516. */
  2517. static const uint8_t _sspine_vs_source_metal_sim[624] = {
  2518. 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
  2519. 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
  2520. 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
  2521. 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
  2522. 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x76,
  2523. 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
  2524. 0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,0x3b,0x0a,0x7d,0x3b,0x0a,
  2525. 0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,
  2526. 0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,
  2527. 0x76,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,
  2528. 0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,
  2529. 0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,
  2530. 0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,
  2531. 0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,
  2532. 0x73,0x69,0x74,0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,
  2533. 0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,
  2534. 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,
  2535. 0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,
  2536. 0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,
  2537. 0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x20,0x5b,0x5b,0x61,0x74,0x74,
  2538. 0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,
  2539. 0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x20,0x5b,
  2540. 0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x32,0x29,0x5d,0x5d,0x3b,
  2541. 0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65,0x78,0x20,0x6d,0x61,0x69,0x6e,
  2542. 0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,
  2543. 0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,
  2544. 0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x76,
  2545. 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x31,0x39,0x20,0x5b,0x5b,
  2546. 0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,
  2547. 0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,
  2548. 0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x67,
  2549. 0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x5f,0x31,0x39,
  2550. 0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,
  2551. 0x2e,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,
  2552. 0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x75,0x76,
  2553. 0x20,0x3d,0x20,0x69,0x6e,0x2e,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,
  2554. 0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,
  2555. 0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,
  2556. 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  2557. };
  2558. /*
  2559. #include <metal_stdlib>
  2560. #include <simd/simd.h>
  2561. using namespace metal;
  2562. struct fs_params
  2563. {
  2564. float pma;
  2565. };
  2566. struct main0_out
  2567. {
  2568. float4 frag_color [[color(0)]];
  2569. };
  2570. struct main0_in
  2571. {
  2572. float2 uv [[user(locn0)]];
  2573. float4 color [[user(locn1)]];
  2574. };
  2575. fragment main0_out main0(main0_in in [[stage_in]], constant fs_params& _53 [[buffer(0)]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]])
  2576. {
  2577. main0_out out = {};
  2578. float4 _28 = tex.sample(smp, in.uv) * in.color;
  2579. float _37 = _28.w;
  2580. out.frag_color = mix(_28, float4(_28.xyz * _37, _37) * in.color, float4(_53.pma));
  2581. return out;
  2582. }
  2583. */
  2584. static const uint8_t _sspine_fs_source_metal_sim[619] = {
  2585. 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
  2586. 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
  2587. 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
  2588. 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
  2589. 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x66,
  2590. 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
  2591. 0x6c,0x6f,0x61,0x74,0x20,0x70,0x6d,0x61,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,
  2592. 0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,
  2593. 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x66,0x72,0x61,0x67,
  2594. 0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x63,0x6f,0x6c,0x6f,0x72,0x28,0x30,
  2595. 0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
  2596. 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
  2597. 0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,
  2598. 0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,
  2599. 0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,
  2600. 0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,
  2601. 0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,
  2602. 0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,
  2603. 0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,
  2604. 0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x66,0x73,0x5f,0x70,
  2605. 0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x35,0x33,0x20,0x5b,0x5b,0x62,0x75,0x66,
  2606. 0x66,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x2c,0x20,0x74,0x65,0x78,0x74,0x75,0x72,
  2607. 0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,0x3e,0x20,0x74,0x65,0x78,0x20,0x5b,
  2608. 0x5b,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x30,0x29,0x5d,0x5d,0x2c,0x20,0x73,
  2609. 0x61,0x6d,0x70,0x6c,0x65,0x72,0x20,0x73,0x6d,0x70,0x20,0x5b,0x5b,0x73,0x61,0x6d,
  2610. 0x70,0x6c,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,
  2611. 0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,
  2612. 0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,
  2613. 0x5f,0x32,0x38,0x20,0x3d,0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,
  2614. 0x28,0x73,0x6d,0x70,0x2c,0x20,0x69,0x6e,0x2e,0x75,0x76,0x29,0x20,0x2a,0x20,0x69,
  2615. 0x6e,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,
  2616. 0x61,0x74,0x20,0x5f,0x33,0x37,0x20,0x3d,0x20,0x5f,0x32,0x38,0x2e,0x77,0x3b,0x0a,
  2617. 0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,
  2618. 0x6f,0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f,0x32,0x38,0x2c,0x20,0x66,0x6c,
  2619. 0x6f,0x61,0x74,0x34,0x28,0x5f,0x32,0x38,0x2e,0x78,0x79,0x7a,0x20,0x2a,0x20,0x5f,
  2620. 0x33,0x37,0x2c,0x20,0x5f,0x33,0x37,0x29,0x20,0x2a,0x20,0x69,0x6e,0x2e,0x63,0x6f,
  2621. 0x6c,0x6f,0x72,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x5f,0x35,0x33,0x2e,
  2622. 0x70,0x6d,0x61,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,
  2623. 0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  2624. };
  2625. #elif defined(SOKOL_WGPU)
  2626. /*
  2627. diagnostic(off, derivative_uniformity);
  2628. struct vs_params {
  2629. /_ @offset(0) _/
  2630. mvp : mat4x4f,
  2631. }
  2632. @group(0) @binding(0) var<uniform> x_19 : vs_params;
  2633. var<private> position_1 : vec2f;
  2634. var<private> uv : vec2f;
  2635. var<private> texcoord0 : vec2f;
  2636. var<private> color : vec4f;
  2637. var<private> color0 : vec4f;
  2638. var<private> gl_Position : vec4f;
  2639. fn main_1() {
  2640. let x_22 : mat4x4f = x_19.mvp;
  2641. let x_26 : vec2f = position_1;
  2642. gl_Position = (x_22 * vec4f(x_26.x, x_26.y, 0.0f, 1.0f));
  2643. let x_38 : vec2f = texcoord0;
  2644. uv = x_38;
  2645. let x_42 : vec4f = color0;
  2646. color = x_42;
  2647. return;
  2648. }
  2649. struct main_out {
  2650. @builtin(position)
  2651. gl_Position : vec4f,
  2652. @location(0)
  2653. uv_1 : vec2f,
  2654. @location(1)
  2655. color_1 : vec4f,
  2656. }
  2657. @vertex
  2658. fn main(@location(0) position_1_param : vec2f, @location(1) texcoord0_param : vec2f, @location(2) color0_param : vec4f) -> main_out {
  2659. position_1 = position_1_param;
  2660. texcoord0 = texcoord0_param;
  2661. color0 = color0_param;
  2662. main_1();
  2663. return main_out(gl_Position, uv, color);
  2664. }
  2665. */
  2666. static const uint8_t _sspine_vs_source_wgsl[1003] = {
  2667. 0x64,0x69,0x61,0x67,0x6e,0x6f,0x73,0x74,0x69,0x63,0x28,0x6f,0x66,0x66,0x2c,0x20,
  2668. 0x64,0x65,0x72,0x69,0x76,0x61,0x74,0x69,0x76,0x65,0x5f,0x75,0x6e,0x69,0x66,0x6f,
  2669. 0x72,0x6d,0x69,0x74,0x79,0x29,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
  2670. 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x20,0x7b,0x0a,0x20,0x20,0x2f,0x2a,
  2671. 0x20,0x40,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,0x20,
  2672. 0x20,0x6d,0x76,0x70,0x20,0x3a,0x20,0x6d,0x61,0x74,0x34,0x78,0x34,0x66,0x2c,0x0a,
  2673. 0x7d,0x0a,0x0a,0x40,0x67,0x72,0x6f,0x75,0x70,0x28,0x30,0x29,0x20,0x40,0x62,0x69,
  2674. 0x6e,0x64,0x69,0x6e,0x67,0x28,0x30,0x29,0x20,0x76,0x61,0x72,0x3c,0x75,0x6e,0x69,
  2675. 0x66,0x6f,0x72,0x6d,0x3e,0x20,0x78,0x5f,0x31,0x39,0x20,0x3a,0x20,0x76,0x73,0x5f,
  2676. 0x70,0x61,0x72,0x61,0x6d,0x73,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,
  2677. 0x76,0x61,0x74,0x65,0x3e,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x5f,0x31,
  2678. 0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,
  2679. 0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x75,0x76,0x20,0x3a,0x20,0x76,0x65,0x63,
  2680. 0x32,0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,
  2681. 0x3e,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x20,0x3a,0x20,0x76,0x65,
  2682. 0x63,0x32,0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,
  2683. 0x65,0x3e,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,
  2684. 0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,
  2685. 0x63,0x6f,0x6c,0x6f,0x72,0x30,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x3b,0x0a,
  2686. 0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x67,0x6c,
  2687. 0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,
  2688. 0x66,0x3b,0x0a,0x0a,0x66,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,0x20,
  2689. 0x7b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,0x32,0x20,0x3a,0x20,0x6d,
  2690. 0x61,0x74,0x34,0x78,0x34,0x66,0x20,0x3d,0x20,0x78,0x5f,0x31,0x39,0x2e,0x6d,0x76,
  2691. 0x70,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,0x36,0x20,0x3a,0x20,
  2692. 0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
  2693. 0x5f,0x31,0x3b,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,
  2694. 0x6e,0x20,0x3d,0x20,0x28,0x78,0x5f,0x32,0x32,0x20,0x2a,0x20,0x76,0x65,0x63,0x34,
  2695. 0x66,0x28,0x78,0x5f,0x32,0x36,0x2e,0x78,0x2c,0x20,0x78,0x5f,0x32,0x36,0x2e,0x79,
  2696. 0x2c,0x20,0x30,0x2e,0x30,0x66,0x2c,0x20,0x31,0x2e,0x30,0x66,0x29,0x29,0x3b,0x0a,
  2697. 0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x33,0x38,0x20,0x3a,0x20,0x76,0x65,0x63,
  2698. 0x32,0x66,0x20,0x3d,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,
  2699. 0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x78,0x5f,0x33,0x38,0x3b,0x0a,0x20,0x20,0x6c,
  2700. 0x65,0x74,0x20,0x78,0x5f,0x34,0x32,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,
  2701. 0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x20,0x20,0x63,0x6f,0x6c,0x6f,
  2702. 0x72,0x20,0x3d,0x20,0x78,0x5f,0x34,0x32,0x3b,0x0a,0x20,0x20,0x72,0x65,0x74,0x75,
  2703. 0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,
  2704. 0x69,0x6e,0x5f,0x6f,0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x40,0x62,0x75,0x69,0x6c,
  2705. 0x74,0x69,0x6e,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x20,0x20,
  2706. 0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3a,0x20,0x76,0x65,
  2707. 0x63,0x34,0x66,0x2c,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,
  2708. 0x28,0x30,0x29,0x0a,0x20,0x20,0x75,0x76,0x5f,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,
  2709. 0x32,0x66,0x2c,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,
  2710. 0x31,0x29,0x0a,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x31,0x20,0x3a,0x20,0x76,
  2711. 0x65,0x63,0x34,0x66,0x2c,0x0a,0x7d,0x0a,0x0a,0x40,0x76,0x65,0x72,0x74,0x65,0x78,
  2712. 0x0a,0x66,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x28,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,
  2713. 0x6f,0x6e,0x28,0x30,0x29,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x5f,0x31,
  2714. 0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x20,
  2715. 0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x31,0x29,0x20,0x74,0x65,0x78,
  2716. 0x63,0x6f,0x6f,0x72,0x64,0x30,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x76,
  2717. 0x65,0x63,0x32,0x66,0x2c,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,
  2718. 0x32,0x29,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,
  2719. 0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x29,0x20,0x2d,0x3e,0x20,0x6d,0x61,0x69,0x6e,
  2720. 0x5f,0x6f,0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,
  2721. 0x6e,0x5f,0x31,0x20,0x3d,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x5f,0x31,
  2722. 0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,
  2723. 0x72,0x64,0x30,0x20,0x3d,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x5f,
  2724. 0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x20,
  2725. 0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,
  2726. 0x20,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,0x3b,0x0a,0x20,0x20,0x72,0x65,
  2727. 0x74,0x75,0x72,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x28,0x67,0x6c,
  2728. 0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x75,0x76,0x2c,0x20,0x63,
  2729. 0x6f,0x6c,0x6f,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
  2730. };
  2731. /*
  2732. diagnostic(off, derivative_uniformity);
  2733. struct fs_params {
  2734. /_ @offset(0) _/
  2735. pma : f32,
  2736. }
  2737. @group(1) @binding(64) var tex : texture_2d<f32>;
  2738. @group(1) @binding(80) var smp : sampler;
  2739. var<private> uv : vec2f;
  2740. var<private> color : vec4f;
  2741. var<private> frag_color : vec4f;
  2742. @group(0) @binding(8) var<uniform> x_53 : fs_params;
  2743. fn main_1() {
  2744. var c0 : vec4f;
  2745. var c1 : vec4f;
  2746. let x_23 : vec2f = uv;
  2747. let x_24 : vec4f = textureSample(tex, smp, x_23);
  2748. let x_27 : vec4f = color;
  2749. c0 = (x_24 * x_27);
  2750. let x_31 : vec4f = c0;
  2751. let x_37 : f32 = c0.w;
  2752. let x_38 : vec3f = (vec3f(x_31.x, x_31.y, x_31.z) * x_37);
  2753. let x_40 : f32 = c0.w;
  2754. let x_45 : vec4f = color;
  2755. c1 = (vec4f(x_38.x, x_38.y, x_38.z, x_40) * x_45);
  2756. let x_49 : vec4f = c0;
  2757. let x_50 : vec4f = c1;
  2758. let x_58 : f32 = x_53.pma;
  2759. frag_color = mix(x_49, x_50, vec4f(x_58, x_58, x_58, x_58));
  2760. return;
  2761. }
  2762. struct main_out {
  2763. @location(0)
  2764. frag_color_1 : vec4f,
  2765. }
  2766. @fragment
  2767. fn main(@location(0) uv_param : vec2f, @location(1) color_param : vec4f) -> main_out {
  2768. uv = uv_param;
  2769. color = color_param;
  2770. main_1();
  2771. return main_out(frag_color);
  2772. }
  2773. */
  2774. static const uint8_t _sspine_fs_source_wgsl[1125] = {
  2775. 0x64,0x69,0x61,0x67,0x6e,0x6f,0x73,0x74,0x69,0x63,0x28,0x6f,0x66,0x66,0x2c,0x20,
  2776. 0x64,0x65,0x72,0x69,0x76,0x61,0x74,0x69,0x76,0x65,0x5f,0x75,0x6e,0x69,0x66,0x6f,
  2777. 0x72,0x6d,0x69,0x74,0x79,0x29,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
  2778. 0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x20,0x7b,0x0a,0x20,0x20,0x2f,0x2a,
  2779. 0x20,0x40,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,0x20,
  2780. 0x20,0x70,0x6d,0x61,0x20,0x3a,0x20,0x66,0x33,0x32,0x2c,0x0a,0x7d,0x0a,0x0a,0x40,
  2781. 0x67,0x72,0x6f,0x75,0x70,0x28,0x31,0x29,0x20,0x40,0x62,0x69,0x6e,0x64,0x69,0x6e,
  2782. 0x67,0x28,0x36,0x34,0x29,0x20,0x76,0x61,0x72,0x20,0x74,0x65,0x78,0x20,0x3a,0x20,
  2783. 0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x5f,0x32,0x64,0x3c,0x66,0x33,0x32,0x3e,0x3b,
  2784. 0x0a,0x0a,0x40,0x67,0x72,0x6f,0x75,0x70,0x28,0x31,0x29,0x20,0x40,0x62,0x69,0x6e,
  2785. 0x64,0x69,0x6e,0x67,0x28,0x38,0x30,0x29,0x20,0x76,0x61,0x72,0x20,0x73,0x6d,0x70,
  2786. 0x20,0x3a,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x3b,0x0a,0x0a,0x76,0x61,0x72,
  2787. 0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x75,0x76,0x20,0x3a,0x20,0x76,
  2788. 0x65,0x63,0x32,0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,
  2789. 0x74,0x65,0x3e,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,
  2790. 0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,
  2791. 0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3a,0x20,0x76,0x65,
  2792. 0x63,0x34,0x66,0x3b,0x0a,0x0a,0x40,0x67,0x72,0x6f,0x75,0x70,0x28,0x30,0x29,0x20,
  2793. 0x40,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x28,0x38,0x29,0x20,0x76,0x61,0x72,0x3c,
  2794. 0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x3e,0x20,0x78,0x5f,0x35,0x33,0x20,0x3a,0x20,
  2795. 0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x3b,0x0a,0x0a,0x66,0x6e,0x20,0x6d,
  2796. 0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,0x20,0x7b,0x0a,0x20,0x20,0x76,0x61,0x72,0x20,
  2797. 0x63,0x30,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x3b,0x0a,0x20,0x20,0x76,0x61,
  2798. 0x72,0x20,0x63,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x3b,0x0a,0x20,0x20,
  2799. 0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,0x33,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,
  2800. 0x20,0x3d,0x20,0x75,0x76,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,
  2801. 0x34,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,0x3d,0x20,0x74,0x65,0x78,0x74,
  2802. 0x75,0x72,0x65,0x53,0x61,0x6d,0x70,0x6c,0x65,0x28,0x74,0x65,0x78,0x2c,0x20,0x73,
  2803. 0x6d,0x70,0x2c,0x20,0x78,0x5f,0x32,0x33,0x29,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,
  2804. 0x20,0x78,0x5f,0x32,0x37,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,0x3d,0x20,
  2805. 0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x63,0x30,0x20,0x3d,0x20,0x28,0x78,
  2806. 0x5f,0x32,0x34,0x20,0x2a,0x20,0x78,0x5f,0x32,0x37,0x29,0x3b,0x0a,0x20,0x20,0x6c,
  2807. 0x65,0x74,0x20,0x78,0x5f,0x33,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,
  2808. 0x3d,0x20,0x63,0x30,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x33,0x37,
  2809. 0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,0x63,0x30,0x2e,0x77,0x3b,0x0a,0x20,
  2810. 0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x33,0x38,0x20,0x3a,0x20,0x76,0x65,0x63,0x33,
  2811. 0x66,0x20,0x3d,0x20,0x28,0x76,0x65,0x63,0x33,0x66,0x28,0x78,0x5f,0x33,0x31,0x2e,
  2812. 0x78,0x2c,0x20,0x78,0x5f,0x33,0x31,0x2e,0x79,0x2c,0x20,0x78,0x5f,0x33,0x31,0x2e,
  2813. 0x7a,0x29,0x20,0x2a,0x20,0x78,0x5f,0x33,0x37,0x29,0x3b,0x0a,0x20,0x20,0x6c,0x65,
  2814. 0x74,0x20,0x78,0x5f,0x34,0x30,0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,0x63,
  2815. 0x30,0x2e,0x77,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x34,0x35,0x20,
  2816. 0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,
  2817. 0x0a,0x20,0x20,0x63,0x31,0x20,0x3d,0x20,0x28,0x76,0x65,0x63,0x34,0x66,0x28,0x78,
  2818. 0x5f,0x33,0x38,0x2e,0x78,0x2c,0x20,0x78,0x5f,0x33,0x38,0x2e,0x79,0x2c,0x20,0x78,
  2819. 0x5f,0x33,0x38,0x2e,0x7a,0x2c,0x20,0x78,0x5f,0x34,0x30,0x29,0x20,0x2a,0x20,0x78,
  2820. 0x5f,0x34,0x35,0x29,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x34,0x39,
  2821. 0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x20,0x3d,0x20,0x63,0x30,0x3b,0x0a,0x20,
  2822. 0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x35,0x30,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,
  2823. 0x66,0x20,0x3d,0x20,0x63,0x31,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,
  2824. 0x35,0x38,0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,0x78,0x5f,0x35,0x33,0x2e,
  2825. 0x70,0x6d,0x61,0x3b,0x0a,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,
  2826. 0x72,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x78,0x5f,0x34,0x39,0x2c,0x20,0x78,0x5f,
  2827. 0x35,0x30,0x2c,0x20,0x76,0x65,0x63,0x34,0x66,0x28,0x78,0x5f,0x35,0x38,0x2c,0x20,
  2828. 0x78,0x5f,0x35,0x38,0x2c,0x20,0x78,0x5f,0x35,0x38,0x2c,0x20,0x78,0x5f,0x35,0x38,
  2829. 0x29,0x29,0x3b,0x0a,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,
  2830. 0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,
  2831. 0x20,0x7b,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x30,
  2832. 0x29,0x0a,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x31,
  2833. 0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x2c,0x0a,0x7d,0x0a,0x0a,0x40,0x66,0x72,
  2834. 0x61,0x67,0x6d,0x65,0x6e,0x74,0x0a,0x66,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x28,0x40,
  2835. 0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x30,0x29,0x20,0x75,0x76,0x5f,0x70,
  2836. 0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x20,0x40,0x6c,
  2837. 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x31,0x29,0x20,0x63,0x6f,0x6c,0x6f,0x72,
  2838. 0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x29,0x20,
  2839. 0x2d,0x3e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,
  2840. 0x75,0x76,0x20,0x3d,0x20,0x75,0x76,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,
  2841. 0x20,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x70,
  2842. 0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,
  2843. 0x3b,0x0a,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x5f,
  2844. 0x6f,0x75,0x74,0x28,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x29,0x3b,
  2845. 0x0a,0x7d,0x0a,0x0a,0x00,
  2846. };
  2847. #elif defined(SOKOL_DUMMY_BACKEND)
  2848. static const char* _sspine_vs_source_dummy = "";
  2849. static const char* _sspine_fs_source_dummy = "";
  2850. #else
  2851. #error "Please define one of SOKOL_GLCORE, SOKOL_GLES3, SOKOL_D3D11, SOKOL_METAL, SOKOL_WGPU or SOKOL_DUMMY_BACKEND!"
  2852. #endif
  2853. // ███████ ████████ ██████ ██ ██ ██████ ████████ ███████
  2854. // ██ ██ ██ ██ ██ ██ ██ ██ ██
  2855. // ███████ ██ ██████ ██ ██ ██ ██ ███████
  2856. // ██ ██ ██ ██ ██ ██ ██ ██ ██
  2857. // ███████ ██ ██ ██ ██████ ██████ ██ ███████
  2858. //
  2859. // >>structs
  2860. #define _sspine_def(val, def) (((val) == 0) ? (def) : (val))
  2861. #define _SSPINE_INIT_COOKIE (0xABBAABBA)
  2862. #define _SSPINE_INVALID_SLOT_INDEX (0)
  2863. #define _SSPINE_DEFAULT_CONTEXT_POOL_SIZE (4)
  2864. #define _SSPINE_DEFAULT_ATLAS_POOL_SIZE (64)
  2865. #define _SSPINE_DEFAULT_SKELETON_POOL_SIZE (64)
  2866. #define _SSPINE_DEFAULT_SKINSET_POOL_SIZE (64)
  2867. #define _SSPINE_DEFAULT_INSTANCE_POOL_SIZE (1024)
  2868. #define _SSPINE_DEFAULT_MAX_VERTICES (1<<16)
  2869. #define _SSPINE_DEFAULT_MAX_COMMANDS (1<<14)
  2870. #define _SSPINE_MAX_TRIGGERED_EVENTS (16)
  2871. #define _SSPINE_SLOT_SHIFT (16)
  2872. #define _SSPINE_MAX_POOL_SIZE (1<<_SSPINE_SLOT_SHIFT)
  2873. #define _SSPINE_SLOT_MASK (_SSPINE_MAX_POOL_SIZE-1)
  2874. typedef struct {
  2875. float mvp[16];
  2876. } _sspine_vsparams_t;
  2877. typedef struct {
  2878. float pma;
  2879. uint8_t _pad[12];
  2880. } _sspine_fsparams_t;
  2881. typedef struct {
  2882. uint32_t id;
  2883. sspine_resource_state state;
  2884. } _sspine_slot_t;
  2885. typedef struct {
  2886. int size;
  2887. int queue_top;
  2888. uint32_t* gen_ctrs;
  2889. int* free_queue;
  2890. } _sspine_pool_t;
  2891. typedef struct {
  2892. _sspine_slot_t slot;
  2893. sspine_atlas_overrides overrides;
  2894. spAtlas* sp_atlas;
  2895. int num_pages;
  2896. } _sspine_atlas_t;
  2897. typedef struct {
  2898. _sspine_pool_t pool;
  2899. _sspine_atlas_t* items;
  2900. } _sspine_atlas_pool_t;
  2901. typedef struct {
  2902. uint32_t id;
  2903. _sspine_atlas_t* ptr;
  2904. } _sspine_atlas_ref_t;
  2905. typedef struct {
  2906. sg_image img;
  2907. sg_sampler smp;
  2908. } _sspine_image_sampler_pair_t;
  2909. typedef struct {
  2910. _sspine_slot_t slot;
  2911. _sspine_atlas_ref_t atlas;
  2912. spSkeletonData* sp_skel_data;
  2913. spAnimationStateData* sp_anim_data;
  2914. struct {
  2915. int cap;
  2916. sspine_vec2* ptr;
  2917. } tform_buf;
  2918. } _sspine_skeleton_t;
  2919. typedef struct {
  2920. _sspine_pool_t pool;
  2921. _sspine_skeleton_t* items;
  2922. } _sspine_skeleton_pool_t;
  2923. typedef struct {
  2924. uint32_t id;
  2925. _sspine_skeleton_t* ptr;
  2926. } _sspine_skeleton_ref_t;
  2927. typedef struct {
  2928. _sspine_slot_t slot;
  2929. _sspine_skeleton_ref_t skel;
  2930. spSkin* sp_skin;
  2931. } _sspine_skinset_t;
  2932. typedef struct {
  2933. _sspine_pool_t pool;
  2934. _sspine_skinset_t* items;
  2935. } _sspine_skinset_pool_t;
  2936. typedef struct {
  2937. uint32_t id;
  2938. _sspine_skinset_t* ptr;
  2939. } _sspine_skinset_ref_t;
  2940. typedef struct {
  2941. _sspine_slot_t slot;
  2942. _sspine_atlas_ref_t atlas;
  2943. _sspine_skeleton_ref_t skel;
  2944. _sspine_skinset_ref_t skinset;
  2945. spSkeleton* sp_skel;
  2946. spAnimationState* sp_anim_state;
  2947. spSkeletonClipping* sp_clip;
  2948. int cur_triggered_event_index;
  2949. sspine_triggered_event_info triggered_events[_SSPINE_MAX_TRIGGERED_EVENTS];
  2950. } _sspine_instance_t;
  2951. typedef struct {
  2952. _sspine_pool_t pool;
  2953. _sspine_instance_t* items;
  2954. } _sspine_instance_pool_t;
  2955. typedef struct {
  2956. sspine_vec2 pos;
  2957. sspine_vec2 uv;
  2958. uint32_t color;
  2959. } _sspine_vertex_t;
  2960. typedef struct {
  2961. _sspine_vertex_t* ptr;
  2962. int index;
  2963. } _sspine_alloc_vertices_result_t;
  2964. typedef struct {
  2965. uint32_t* ptr;
  2966. int index;
  2967. } _sspine_alloc_indices_result_t;
  2968. typedef struct {
  2969. int layer;
  2970. sg_pipeline pip;
  2971. sg_image img;
  2972. sg_sampler smp;
  2973. float pma; // pma = 0.0: use texture color as is, pma = 1.0: multiply texture rgb by texture alpha in fragment shader
  2974. int base_element;
  2975. int num_elements;
  2976. } _sspine_command_t;
  2977. typedef struct {
  2978. _sspine_slot_t slot;
  2979. float transform[16];
  2980. struct {
  2981. int cap;
  2982. int next;
  2983. uint32_t rewind_frame_id;
  2984. _sspine_vertex_t* ptr;
  2985. } vertices;
  2986. struct {
  2987. int cap;
  2988. int next;
  2989. uint32_t rewind_frame_id;
  2990. uint32_t* ptr;
  2991. } indices;
  2992. struct {
  2993. int cap;
  2994. int next;
  2995. uint32_t rewind_frame_id;
  2996. _sspine_command_t* ptr;
  2997. } commands;
  2998. uint32_t update_frame_id;
  2999. sg_buffer vbuf;
  3000. sg_buffer ibuf;
  3001. struct {
  3002. sg_pipeline normal_additive;
  3003. sg_pipeline multiply;
  3004. } pip;
  3005. sg_bindings bind;
  3006. } _sspine_context_t;
  3007. typedef struct {
  3008. _sspine_pool_t pool;
  3009. _sspine_context_t* items;
  3010. } _sspine_context_pool_t;
  3011. typedef struct {
  3012. uint32_t init_cookie;
  3013. uint32_t frame_id;
  3014. sspine_desc desc;
  3015. sspine_context def_ctx_id;
  3016. sspine_context cur_ctx_id;
  3017. _sspine_context_t* cur_ctx; // may be 0!
  3018. sg_shader shd;
  3019. _sspine_context_pool_t context_pool;
  3020. _sspine_atlas_pool_t atlas_pool;
  3021. _sspine_skeleton_pool_t skeleton_pool;
  3022. _sspine_skinset_pool_t skinset_pool;
  3023. _sspine_instance_pool_t instance_pool;
  3024. } _sspine_t;
  3025. static _sspine_t _sspine;
  3026. // dummy spine-c platform implementation functions
  3027. #if defined(__cplusplus)
  3028. extern "C" {
  3029. #endif
  3030. void _spAtlasPage_createTexture(spAtlasPage* self, const char* path) {
  3031. // nothing to do here
  3032. (void)self; (void)path;
  3033. }
  3034. static void _sspine_delete_image_sampler_pair(const _sspine_image_sampler_pair_t* isp);
  3035. void _spAtlasPage_disposeTexture(spAtlasPage* self) {
  3036. _sspine_delete_image_sampler_pair((const _sspine_image_sampler_pair_t*) self->rendererObject);
  3037. }
  3038. char* _spUtil_readFile(const char* path, int* length) {
  3039. (void)path;
  3040. *length = 0;
  3041. return 0;
  3042. }
  3043. #if defined(__cplusplus)
  3044. } // extern "C"
  3045. #endif
  3046. // ██ ██████ ██████ ██████ ██ ███ ██ ██████
  3047. // ██ ██ ██ ██ ██ ██ ████ ██ ██
  3048. // ██ ██ ██ ██ ███ ██ ███ ██ ██ ██ ██ ██ ███
  3049. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3050. // ███████ ██████ ██████ ██████ ██ ██ ████ ██████
  3051. //
  3052. // >>logging
  3053. #if defined(SOKOL_DEBUG)
  3054. #define _SSPINE_LOGITEM_XMACRO(item,msg) #item ": " msg,
  3055. static const char* _sspine_log_messages[] = {
  3056. _SSPINE_LOG_ITEMS
  3057. };
  3058. #undef _SSPINE_LOGITEM_XMACRO
  3059. #endif // SOKOL_DEBUG
  3060. #define _SSPINE_PANIC(code) _sspine_log(SSPINE_LOGITEM_ ##code, 0, __LINE__)
  3061. #define _SSPINE_ERROR(code) _sspine_log(SSPINE_LOGITEM_ ##code, 1, __LINE__)
  3062. #define _SSPINE_WARN(code) _sspine_log(SSPINE_LOGITEM_ ##code, 2, __LINE__)
  3063. #define _SSPINE_INFO(code) _sspine_log(SSPINE_LOGITEM_ ##code, 3, __LINE__)
  3064. static void _sspine_log(sspine_log_item log_item, uint32_t log_level, uint32_t line_nr) {
  3065. if (_sspine.desc.logger.func) {
  3066. #if defined(SOKOL_DEBUG)
  3067. const char* filename = __FILE__;
  3068. const char* message = _sspine_log_messages[log_item];
  3069. #else
  3070. const char* filename = 0;
  3071. const char* message = 0;
  3072. #endif
  3073. _sspine.desc.logger.func("sspine", log_level, (uint32_t)log_item, message, line_nr, filename, _sspine.desc.logger.user_data);
  3074. } else {
  3075. // for log level PANIC it would be 'undefined behaviour' to continue
  3076. if (log_level == 0) {
  3077. abort();
  3078. }
  3079. }
  3080. }
  3081. // ███ ███ ███████ ███ ███ ██████ ██████ ██ ██
  3082. // ████ ████ ██ ████ ████ ██ ██ ██ ██ ██ ██
  3083. // ██ ████ ██ █████ ██ ████ ██ ██ ██ ██████ ████
  3084. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3085. // ██ ██ ███████ ██ ██ ██████ ██ ██ ██
  3086. //
  3087. // >>memory
  3088. static void _sspine_clear(void* ptr, size_t size) {
  3089. SOKOL_ASSERT(ptr && (size > 0));
  3090. memset(ptr, 0, size);
  3091. }
  3092. /* Copy a string into a fixed size buffer with guaranteed zero-
  3093. termination.
  3094. Return false if the string didn't fit into the buffer and had to be clamped.
  3095. FIXME: Currently UTF-8 strings might become invalid if the string
  3096. is clamped, because the last zero-byte might be written into
  3097. the middle of a multi-byte sequence.
  3098. */
  3099. static bool _sspine_strcpy(const char* src, char* dst, int max_len) {
  3100. SOKOL_ASSERT(src && dst && (max_len > 0));
  3101. char* const end = &(dst[max_len-1]);
  3102. char c = 0;
  3103. for (int i = 0; i < max_len; i++) {
  3104. c = *src;
  3105. if (c != 0) {
  3106. src++;
  3107. }
  3108. *dst++ = c;
  3109. }
  3110. // truncated?
  3111. if (c != 0) {
  3112. *end = 0;
  3113. return false;
  3114. } else {
  3115. return true;
  3116. }
  3117. }
  3118. static sspine_string _sspine_string(const char* cstr) {
  3119. sspine_string res;
  3120. _sspine_clear(&res, sizeof(res));
  3121. if (cstr) {
  3122. res.valid = true;
  3123. res.truncated = !_sspine_strcpy(cstr, res.cstr, sizeof(res.cstr));
  3124. res.len = (uint8_t)strlen(res.cstr);
  3125. }
  3126. return res;
  3127. }
  3128. static void* _sspine_malloc(size_t size) {
  3129. SOKOL_ASSERT(size > 0);
  3130. void* ptr;
  3131. if (_sspine.desc.allocator.alloc_fn) {
  3132. ptr = _sspine.desc.allocator.alloc_fn(size, _sspine.desc.allocator.user_data);
  3133. } else {
  3134. ptr = malloc(size);
  3135. }
  3136. if (0 == ptr) {
  3137. _SSPINE_PANIC(MALLOC_FAILED);
  3138. }
  3139. return ptr;
  3140. }
  3141. static void* _sspine_malloc_clear(size_t size) {
  3142. void* ptr = _sspine_malloc(size);
  3143. _sspine_clear(ptr, size);
  3144. return ptr;
  3145. }
  3146. static void _sspine_free(void* ptr) {
  3147. if (_sspine.desc.allocator.free_fn) {
  3148. _sspine.desc.allocator.free_fn(ptr, _sspine.desc.allocator.user_data);
  3149. } else {
  3150. free(ptr);
  3151. }
  3152. }
  3153. // ██████ ███████ ███████ ███████
  3154. // ██ ██ ██ ██ ██
  3155. // ██████ █████ █████ ███████
  3156. // ██ ██ ██ ██ ██
  3157. // ██ ██ ███████ ██ ███████
  3158. //
  3159. // >>refs
  3160. static bool _sspine_atlas_ref_valid(const _sspine_atlas_ref_t* ref) {
  3161. return ref->ptr && (ref->ptr->slot.id == ref->id);
  3162. }
  3163. static bool _sspine_skeleton_ref_valid(const _sspine_skeleton_ref_t* ref) {
  3164. return ref->ptr && (ref->ptr->slot.id == ref->id);
  3165. }
  3166. static bool _sspine_skinset_ref_valid(const _sspine_skinset_ref_t* ref) {
  3167. return ref->ptr && (ref->ptr->slot.id == ref->id);
  3168. }
  3169. static bool _sspine_skeleton_and_deps_valid(_sspine_skeleton_t* skeleton) {
  3170. return skeleton && _sspine_atlas_ref_valid(&skeleton->atlas);
  3171. }
  3172. static bool _sspine_skinset_and_deps_valid(_sspine_skinset_t* skinset) {
  3173. return skinset && _sspine_skeleton_ref_valid(&skinset->skel);
  3174. }
  3175. static bool _sspine_instance_and_deps_valid(_sspine_instance_t* instance) {
  3176. return instance &&
  3177. _sspine_atlas_ref_valid(&instance->atlas) &&
  3178. _sspine_skeleton_ref_valid(&instance->skel) &&
  3179. ((instance->skinset.id == SSPINE_INVALID_ID) || _sspine_skinset_ref_valid(&instance->skinset));
  3180. }
  3181. static sspine_image _sspine_image(uint32_t atlas_id, int index) {
  3182. sspine_image img = { atlas_id, index };
  3183. return img;
  3184. }
  3185. static sspine_atlas_page _sspine_atlas_page(uint32_t atlas_id, int index) {
  3186. sspine_atlas_page page = { atlas_id, index };
  3187. return page;
  3188. }
  3189. static sspine_anim _sspine_anim(uint32_t skeleton_id, int index) {
  3190. sspine_anim anim = { skeleton_id, index };
  3191. return anim;
  3192. }
  3193. static sspine_bone _sspine_bone(uint32_t skeleton_id, int index) {
  3194. sspine_bone bone = { skeleton_id, index };
  3195. return bone;
  3196. }
  3197. static sspine_slot _sspine_slot(uint32_t skeleton_id, int index) {
  3198. sspine_slot slot = { skeleton_id, index };
  3199. return slot;
  3200. }
  3201. static sspine_event _sspine_event(uint32_t skeleton_id, int index) {
  3202. sspine_event event = { skeleton_id, index };
  3203. return event;
  3204. }
  3205. static sspine_iktarget _sspine_iktarget(uint32_t skeleton_id, int index) {
  3206. sspine_iktarget iktarget = { skeleton_id, index };
  3207. return iktarget;
  3208. }
  3209. static sspine_skin _sspine_skin(uint32_t skeleton_id, int index) {
  3210. sspine_skin skin = { skeleton_id, index };
  3211. return skin;
  3212. }
  3213. // ██████ ██████ ██████ ██
  3214. // ██ ██ ██ ██ ██ ██ ██
  3215. // ██████ ██ ██ ██ ██ ██
  3216. // ██ ██ ██ ██ ██ ██
  3217. // ██ ██████ ██████ ███████
  3218. //
  3219. // >>pool
  3220. static void _sspine_init_pool(_sspine_pool_t* pool, int num) {
  3221. SOKOL_ASSERT(pool && (num >= 1));
  3222. // slot 0 is reserved for the 'invalid id', so bump the pool size by 1
  3223. pool->size = num + 1;
  3224. pool->queue_top = 0;
  3225. // generation counters indexable by pool slot index, slot 0 is reserved
  3226. size_t gen_ctrs_size = sizeof(uint32_t) * (size_t)pool->size;
  3227. pool->gen_ctrs = (uint32_t*) _sspine_malloc_clear(gen_ctrs_size);
  3228. // it's not a bug to only reserve 'num' here
  3229. pool->free_queue = (int*) _sspine_malloc_clear(sizeof(int) * (size_t)num);
  3230. // never allocate the zero-th pool item since the invalid id is 0
  3231. for (int i = pool->size-1; i >= 1; i--) {
  3232. pool->free_queue[pool->queue_top++] = i;
  3233. }
  3234. }
  3235. static void _sspine_discard_pool(_sspine_pool_t* pool) {
  3236. SOKOL_ASSERT(pool);
  3237. SOKOL_ASSERT(pool->free_queue);
  3238. _sspine_free(pool->free_queue);
  3239. pool->free_queue = 0;
  3240. SOKOL_ASSERT(pool->gen_ctrs);
  3241. _sspine_free(pool->gen_ctrs);
  3242. pool->gen_ctrs = 0;
  3243. pool->size = 0;
  3244. pool->queue_top = 0;
  3245. }
  3246. static int _sspine_pool_alloc_index(_sspine_pool_t* pool) {
  3247. SOKOL_ASSERT(pool);
  3248. SOKOL_ASSERT(pool->free_queue);
  3249. if (pool->queue_top > 0) {
  3250. int slot_index = pool->free_queue[--pool->queue_top];
  3251. SOKOL_ASSERT((slot_index > 0) && (slot_index < pool->size));
  3252. return slot_index;
  3253. } else {
  3254. // pool exhausted
  3255. return _SSPINE_INVALID_SLOT_INDEX;
  3256. }
  3257. }
  3258. static void _sspine_pool_free_index(_sspine_pool_t* pool, int slot_index) {
  3259. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < pool->size));
  3260. SOKOL_ASSERT(pool);
  3261. SOKOL_ASSERT(pool->free_queue);
  3262. SOKOL_ASSERT(pool->queue_top < pool->size);
  3263. #ifdef SOKOL_DEBUG
  3264. // debug check against double-free
  3265. for (int i = 0; i < pool->queue_top; i++) {
  3266. SOKOL_ASSERT(pool->free_queue[i] != slot_index);
  3267. }
  3268. #endif
  3269. pool->free_queue[pool->queue_top++] = slot_index;
  3270. SOKOL_ASSERT(pool->queue_top <= (pool->size-1));
  3271. }
  3272. /* initialize a pool slot:
  3273. - bump the slot's generation counter
  3274. - create a resource id from the generation counter and slot index
  3275. - set the slot's id to this id
  3276. - set the slot's state to ALLOC
  3277. - return the handle id
  3278. */
  3279. static uint32_t _sspine_slot_init(_sspine_pool_t* pool, _sspine_slot_t* slot, int slot_index) {
  3280. /* FIXME: add handling for an overflowing generation counter,
  3281. for now, just overflow (another option is to disable
  3282. the slot)
  3283. */
  3284. SOKOL_ASSERT(pool && pool->gen_ctrs);
  3285. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < pool->size));
  3286. SOKOL_ASSERT((slot->state == SSPINE_RESOURCESTATE_INITIAL) && (slot->id == SSPINE_INVALID_ID));
  3287. uint32_t ctr = ++pool->gen_ctrs[slot_index];
  3288. slot->id = (ctr<<_SSPINE_SLOT_SHIFT)|(slot_index & _SSPINE_SLOT_MASK);
  3289. slot->state = SSPINE_RESOURCESTATE_ALLOC;
  3290. return slot->id;
  3291. }
  3292. // extract slot index from id
  3293. static int _sspine_slot_index(uint32_t id) {
  3294. int slot_index = (int) (id & _SSPINE_SLOT_MASK);
  3295. SOKOL_ASSERT(_SSPINE_INVALID_SLOT_INDEX != slot_index);
  3296. return slot_index;
  3297. }
  3298. static void _sspine_init_item_pool(_sspine_pool_t* pool, int pool_size, void** items_ptr, size_t item_size_bytes) {
  3299. // NOTE: the pools will have an additional item, since slot 0 is reserved
  3300. SOKOL_ASSERT(pool && (pool->size == 0));
  3301. SOKOL_ASSERT((pool_size > 0) && (pool_size < _SSPINE_MAX_POOL_SIZE));
  3302. SOKOL_ASSERT(items_ptr && (*items_ptr == 0));
  3303. SOKOL_ASSERT(item_size_bytes > 0);
  3304. _sspine_init_pool(pool, pool_size);
  3305. const size_t pool_size_bytes = item_size_bytes * (size_t)pool->size;
  3306. *items_ptr = _sspine_malloc_clear(pool_size_bytes);
  3307. }
  3308. static void _sspine_discard_item_pool(_sspine_pool_t* pool, void** items_ptr) {
  3309. SOKOL_ASSERT(pool && (pool->size != 0));
  3310. SOKOL_ASSERT(items_ptr && (*items_ptr != 0));
  3311. _sspine_free(*items_ptr); *items_ptr = 0;
  3312. _sspine_discard_pool(pool);
  3313. }
  3314. // ██████ ██████ ███ ██ ████████ ███████ ██ ██ ████████
  3315. // ██ ██ ██ ████ ██ ██ ██ ██ ██ ██
  3316. // ██ ██ ██ ██ ██ ██ ██ █████ ███ ██
  3317. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3318. // ██████ ██████ ██ ████ ██ ███████ ██ ██ ██
  3319. //
  3320. // >>context
  3321. static void _sspine_setup_context_pool(int pool_size) {
  3322. _sspine_context_pool_t* p = &_sspine.context_pool;
  3323. _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_context_t));
  3324. }
  3325. static void _sspine_discard_context_pool(void) {
  3326. _sspine_context_pool_t* p = &_sspine.context_pool;
  3327. _sspine_discard_item_pool(&p->pool, (void**)&p->items);
  3328. }
  3329. static sspine_context _sspine_make_context_handle(uint32_t id) {
  3330. sspine_context handle = { id };
  3331. return handle;
  3332. }
  3333. static _sspine_context_t* _sspine_context_at(uint32_t id) {
  3334. SOKOL_ASSERT(SSPINE_INVALID_ID != id);
  3335. const _sspine_context_pool_t* p = &_sspine.context_pool;
  3336. int slot_index = _sspine_slot_index(id);
  3337. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
  3338. return &p->items[slot_index];
  3339. }
  3340. static _sspine_context_t* _sspine_lookup_context(uint32_t id) {
  3341. if (SSPINE_INVALID_ID != id) {
  3342. _sspine_context_t* ctx = _sspine_context_at(id);
  3343. if (ctx->slot.id == id) {
  3344. return ctx;
  3345. }
  3346. }
  3347. return 0;
  3348. }
  3349. static sspine_context _sspine_alloc_context(void) {
  3350. _sspine_context_pool_t* p = &_sspine.context_pool;
  3351. int slot_index = _sspine_pool_alloc_index(&p->pool);
  3352. if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
  3353. uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
  3354. return _sspine_make_context_handle(id);
  3355. } else {
  3356. // pool exhausted
  3357. return _sspine_make_context_handle(SSPINE_INVALID_ID);
  3358. }
  3359. }
  3360. static sspine_resource_state _sspine_init_context(_sspine_context_t* ctx, const sspine_context_desc* desc) {
  3361. SOKOL_ASSERT(ctx && (ctx->slot.state == SSPINE_RESOURCESTATE_ALLOC));
  3362. SOKOL_ASSERT(desc);
  3363. // setup vertex, index and command storage
  3364. ctx->vertices.cap = desc->max_vertices;
  3365. ctx->indices.cap = ctx->vertices.cap * 3;
  3366. ctx->commands.cap = desc->max_commands;
  3367. const size_t vbuf_size = (size_t)ctx->vertices.cap * sizeof(_sspine_vertex_t);
  3368. const size_t ibuf_size = (size_t)ctx->indices.cap * sizeof(uint32_t);
  3369. const size_t cbuf_size = (size_t)ctx->commands.cap * sizeof(_sspine_command_t);
  3370. ctx->vertices.ptr = (_sspine_vertex_t*) _sspine_malloc(vbuf_size);
  3371. ctx->indices.ptr = (uint32_t*) _sspine_malloc(ibuf_size);
  3372. ctx->commands.ptr = (_sspine_command_t*) _sspine_malloc(cbuf_size);
  3373. sg_buffer_desc vbuf_desc;
  3374. _sspine_clear(&vbuf_desc, sizeof(vbuf_desc));
  3375. vbuf_desc.usage.vertex_buffer = true;
  3376. vbuf_desc.usage.stream_update = true;
  3377. vbuf_desc.size = vbuf_size;
  3378. vbuf_desc.label = "sspine-vbuf";
  3379. ctx->vbuf = sg_make_buffer(&vbuf_desc);
  3380. ctx->bind.vertex_buffers[0] = ctx->vbuf;
  3381. sg_buffer_desc ibuf_desc;
  3382. _sspine_clear(&ibuf_desc, sizeof(ibuf_desc));
  3383. ibuf_desc.usage.index_buffer = true;
  3384. ibuf_desc.usage.stream_update = true;
  3385. ibuf_desc.size = ibuf_size;
  3386. ibuf_desc.label = "sspine-ibuf";
  3387. ctx->ibuf = sg_make_buffer(&ibuf_desc);
  3388. ctx->bind.index_buffer = ctx->ibuf;
  3389. // for blend modes, see: https://wiki.libsdl.org/SDL_BlendMode
  3390. //
  3391. // NOTE: we're configuring the blend mode for premultiplied alpha,
  3392. // and then do the premultiplication in the fragment shader
  3393. // if needed
  3394. sg_pipeline_desc pip_desc;
  3395. _sspine_clear(&pip_desc, sizeof(pip_desc));
  3396. pip_desc.shader = _sspine.shd;
  3397. pip_desc.layout.buffers[0].stride = sizeof(_sspine_vertex_t);
  3398. pip_desc.layout.attrs[0].format = SG_VERTEXFORMAT_FLOAT2;
  3399. pip_desc.layout.attrs[1].format = SG_VERTEXFORMAT_FLOAT2;
  3400. pip_desc.layout.attrs[2].format = SG_VERTEXFORMAT_UBYTE4N;
  3401. pip_desc.index_type = SG_INDEXTYPE_UINT32;
  3402. pip_desc.sample_count = desc->sample_count;
  3403. pip_desc.depth.pixel_format = desc->depth_format;
  3404. pip_desc.colors[0].pixel_format = desc->color_format;
  3405. pip_desc.colors[0].write_mask = desc->color_write_mask;
  3406. pip_desc.colors[0].blend.enabled = true;
  3407. pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_ONE;
  3408. pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
  3409. pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ONE;
  3410. pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
  3411. pip_desc.label = "sspine-pip-normal/additive";
  3412. ctx->pip.normal_additive = sg_make_pipeline(&pip_desc);
  3413. pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_ZERO;
  3414. pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_SRC_COLOR;
  3415. pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ZERO;
  3416. pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE;
  3417. pip_desc.label = "sspine-pip-multiply";
  3418. ctx->pip.multiply = sg_make_pipeline(&pip_desc);
  3419. return SSPINE_RESOURCESTATE_VALID;
  3420. }
  3421. static void _sspine_deinit_context(_sspine_context_t* ctx) {
  3422. // NOTE: it's ok to call sg_destroy functions with invalid handles
  3423. sg_destroy_pipeline(ctx->pip.normal_additive);
  3424. sg_destroy_pipeline(ctx->pip.multiply);
  3425. sg_destroy_buffer(ctx->ibuf);
  3426. sg_destroy_buffer(ctx->vbuf);
  3427. if (ctx->commands.ptr) {
  3428. _sspine_free(ctx->commands.ptr);
  3429. ctx->commands.ptr = 0;
  3430. }
  3431. if (ctx->indices.ptr) {
  3432. _sspine_free(ctx->indices.ptr);
  3433. ctx->indices.ptr = 0;
  3434. }
  3435. if (ctx->vertices.ptr) {
  3436. _sspine_free(ctx->vertices.ptr);
  3437. ctx->vertices.ptr = 0;
  3438. }
  3439. }
  3440. static void _sspine_destroy_context(sspine_context ctx_id) {
  3441. _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  3442. if (ctx) {
  3443. _sspine_deinit_context(ctx);
  3444. _sspine_context_pool_t* p = &_sspine.context_pool;
  3445. _sspine_clear(ctx, sizeof(_sspine_context_t));
  3446. _sspine_pool_free_index(&p->pool, _sspine_slot_index(ctx_id.id));
  3447. }
  3448. }
  3449. static void _sspine_destroy_all_contexts(void) {
  3450. _sspine_context_pool_t* p = &_sspine.context_pool;
  3451. for (int i = 0; i < p->pool.size; i++) {
  3452. _sspine_context_t* ctx = &p->items[i];
  3453. _sspine_destroy_context(_sspine_make_context_handle(ctx->slot.id));
  3454. }
  3455. }
  3456. static sspine_context_desc _sspine_context_desc_defaults(const sspine_context_desc* desc) {
  3457. sspine_context_desc res = *desc;
  3458. res.max_vertices = _sspine_def(desc->max_vertices, _SSPINE_DEFAULT_MAX_VERTICES);
  3459. res.max_commands = _sspine_def(desc->max_commands, _SSPINE_DEFAULT_MAX_COMMANDS);
  3460. return res;
  3461. }
  3462. static bool _sspine_is_default_context(sspine_context ctx_id) {
  3463. return ctx_id.id == 0x00010001;
  3464. }
  3465. // █████ ████████ ██ █████ ███████
  3466. // ██ ██ ██ ██ ██ ██ ██
  3467. // ███████ ██ ██ ███████ ███████
  3468. // ██ ██ ██ ██ ██ ██ ██
  3469. // ██ ██ ██ ███████ ██ ██ ███████
  3470. //
  3471. // >>atlas
  3472. static void _sspine_setup_atlas_pool(int pool_size) {
  3473. _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3474. _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_atlas_t));
  3475. }
  3476. static void _sspine_discard_atlas_pool(void) {
  3477. _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3478. _sspine_discard_item_pool(&p->pool, (void**)&p->items);
  3479. }
  3480. static sspine_atlas _sspine_make_atlas_handle(uint32_t id) {
  3481. sspine_atlas handle = { id };
  3482. return handle;
  3483. }
  3484. static _sspine_atlas_t* _sspine_atlas_at(uint32_t id) {
  3485. SOKOL_ASSERT(SSPINE_INVALID_ID != id);
  3486. const _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3487. int slot_index = _sspine_slot_index(id);
  3488. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
  3489. return &p->items[slot_index];
  3490. }
  3491. static _sspine_atlas_t* _sspine_lookup_atlas(uint32_t id) {
  3492. if (SSPINE_INVALID_ID != id) {
  3493. _sspine_atlas_t* atlas = _sspine_atlas_at(id);
  3494. if (atlas->slot.id == id) {
  3495. return atlas;
  3496. }
  3497. }
  3498. return 0;
  3499. }
  3500. static sspine_atlas _sspine_alloc_atlas(void) {
  3501. _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3502. int slot_index = _sspine_pool_alloc_index(&p->pool);
  3503. if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
  3504. uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
  3505. return _sspine_make_atlas_handle(id);
  3506. } else {
  3507. // pool exhausted
  3508. return _sspine_make_atlas_handle(SSPINE_INVALID_ID);
  3509. }
  3510. }
  3511. static const _sspine_image_sampler_pair_t* _sspine_new_image_sampler_pair(sg_image img, sg_sampler smp) {
  3512. _sspine_image_sampler_pair_t* isp = (_sspine_image_sampler_pair_t*) _sspine_malloc_clear(sizeof(_sspine_image_sampler_pair_t));
  3513. SOKOL_ASSERT(isp);
  3514. isp->img = img;
  3515. isp->smp = smp;
  3516. return isp;
  3517. }
  3518. static void _sspine_delete_image_sampler_pair(const _sspine_image_sampler_pair_t* isp) {
  3519. if (isp) {
  3520. sg_destroy_sampler(isp->smp);
  3521. sg_destroy_image(isp->img);
  3522. _sspine_free((void*)isp);
  3523. }
  3524. }
  3525. static sg_image _sspine_image_from_renderer_object(void* renderer_object) {
  3526. SOKOL_ASSERT(renderer_object);
  3527. const _sspine_image_sampler_pair_t* isp = (const _sspine_image_sampler_pair_t*)renderer_object;
  3528. return isp->img;
  3529. }
  3530. static sg_sampler _sspine_sampler_from_renderer_object(void* renderer_object) {
  3531. SOKOL_ASSERT(renderer_object);
  3532. const _sspine_image_sampler_pair_t* isp = (const _sspine_image_sampler_pair_t*)renderer_object;
  3533. return isp->smp;
  3534. }
  3535. static sspine_resource_state _sspine_init_atlas(_sspine_atlas_t* atlas, const sspine_atlas_desc* desc) {
  3536. SOKOL_ASSERT(atlas && (atlas->slot.state == SSPINE_RESOURCESTATE_ALLOC));
  3537. SOKOL_ASSERT(desc);
  3538. SOKOL_ASSERT(atlas->sp_atlas == 0);
  3539. if ((0 == desc->data.ptr) || (0 == desc->data.size)) {
  3540. _SSPINE_ERROR(ATLAS_DESC_NO_DATA);
  3541. return SSPINE_RESOURCESTATE_FAILED;
  3542. }
  3543. atlas->overrides = desc->override;
  3544. // NOTE: Spine doesn't detect when invalid or corrupt data is passed here,
  3545. // not much we can do about this...
  3546. atlas->sp_atlas = spAtlas_create((const char*)desc->data.ptr, (int)desc->data.size, "", 0);
  3547. if (0 == atlas->sp_atlas) {
  3548. _SSPINE_ERROR(SPINE_ATLAS_CREATION_FAILED);
  3549. return SSPINE_RESOURCESTATE_FAILED;
  3550. }
  3551. // allocate a sokol-gfx image and sampler object for each page, but the actual
  3552. // initialization needs to be delegated to the application
  3553. for (spAtlasPage* page = atlas->sp_atlas->pages; page != 0; page = page->next) {
  3554. atlas->num_pages++;
  3555. const sg_image img = sg_alloc_image();
  3556. if (sg_query_image_state(img) != SG_RESOURCESTATE_ALLOC) {
  3557. _SSPINE_ERROR(SG_ALLOC_IMAGE_FAILED);
  3558. return SSPINE_RESOURCESTATE_FAILED;
  3559. }
  3560. const sg_sampler smp = sg_alloc_sampler();
  3561. if (sg_query_sampler_state(smp) != SG_RESOURCESTATE_ALLOC) {
  3562. _SSPINE_ERROR(SG_ALLOC_SAMPLER_FAILED);
  3563. return SSPINE_RESOURCESTATE_FAILED;
  3564. }
  3565. // need to put the image and sampler handle into a heap-alloc unfortunately,
  3566. // because a void* isn't big enough to stash two 32-bit handles into
  3567. // it directly on platforms with 32-bit pointers (like wasm)
  3568. page->rendererObject = (void*) _sspine_new_image_sampler_pair(img, smp);
  3569. if (desc->override.premul_alpha_enabled) {
  3570. // NOTE: -1 is spine-c convention for 'true'
  3571. page->pma = -1;
  3572. } else if (desc->override.premul_alpha_disabled) {
  3573. page->pma = 0;
  3574. }
  3575. }
  3576. return SSPINE_RESOURCESTATE_VALID;
  3577. }
  3578. static void _sspine_deinit_atlas(_sspine_atlas_t* atlas) {
  3579. if (atlas->sp_atlas) {
  3580. spAtlas_dispose(atlas->sp_atlas);
  3581. atlas->sp_atlas = 0;
  3582. }
  3583. }
  3584. static void _sspine_destroy_atlas(sspine_atlas atlas_id) {
  3585. _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
  3586. if (atlas) {
  3587. _sspine_deinit_atlas(atlas);
  3588. _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3589. _sspine_clear(atlas, sizeof(_sspine_atlas_t));
  3590. _sspine_pool_free_index(&p->pool, _sspine_slot_index(atlas_id.id));
  3591. }
  3592. }
  3593. static void _sspine_destroy_all_atlases(void) {
  3594. _sspine_atlas_pool_t* p = &_sspine.atlas_pool;
  3595. for (int i = 0; i < p->pool.size; i++) {
  3596. _sspine_atlas_t* atlas = &p->items[i];
  3597. _sspine_destroy_atlas(_sspine_make_atlas_handle(atlas->slot.id));
  3598. }
  3599. }
  3600. static sspine_atlas_desc _sspine_atlas_desc_defaults(const sspine_atlas_desc* desc) {
  3601. sspine_atlas_desc res = *desc;
  3602. return res;
  3603. }
  3604. static spAtlasPage* _sspine_lookup_atlas_page(uint32_t atlas_id, int page_index) {
  3605. _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id);
  3606. if (atlas) {
  3607. if ((page_index >= 0) && (page_index < atlas->num_pages)) {
  3608. int i = 0;
  3609. for (spAtlasPage* page = atlas->sp_atlas->pages; page != 0; page = page->next, i++) {
  3610. if (i == page_index) {
  3611. return page;
  3612. }
  3613. }
  3614. }
  3615. }
  3616. return 0;
  3617. }
  3618. // ███████ ██ ██ ███████ ██ ███████ ████████ ██████ ███ ██
  3619. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
  3620. // ███████ █████ █████ ██ █████ ██ ██ ██ ██ ██ ██
  3621. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3622. // ███████ ██ ██ ███████ ███████ ███████ ██ ██████ ██ ████
  3623. //
  3624. // >>skeleton
  3625. static void _sspine_setup_skeleton_pool(int pool_size) {
  3626. _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3627. _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_skeleton_t));
  3628. }
  3629. static void _sspine_discard_skeleton_pool(void) {
  3630. _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3631. _sspine_discard_item_pool(&p->pool, (void**)&p->items);
  3632. }
  3633. static sspine_skeleton _sspine_make_skeleton_handle(uint32_t id) {
  3634. sspine_skeleton handle = { id };
  3635. return handle;
  3636. }
  3637. static _sspine_skeleton_t* _sspine_skeleton_at(uint32_t id) {
  3638. SOKOL_ASSERT(SSPINE_INVALID_ID != id);
  3639. const _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3640. int slot_index = _sspine_slot_index(id);
  3641. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
  3642. return &p->items[slot_index];
  3643. }
  3644. static _sspine_skeleton_t* _sspine_lookup_skeleton(uint32_t id) {
  3645. if (SSPINE_INVALID_ID != id) {
  3646. _sspine_skeleton_t* skeleton = _sspine_skeleton_at(id);
  3647. if (skeleton->slot.id == id) {
  3648. return skeleton;
  3649. }
  3650. }
  3651. return 0;
  3652. }
  3653. static sspine_skeleton _sspine_alloc_skeleton(void) {
  3654. _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3655. int slot_index = _sspine_pool_alloc_index(&p->pool);
  3656. if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
  3657. uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
  3658. return _sspine_make_skeleton_handle(id);
  3659. } else {
  3660. // pool exhausted
  3661. return _sspine_make_skeleton_handle(SSPINE_INVALID_ID);
  3662. }
  3663. }
  3664. static sspine_resource_state _sspine_init_skeleton(_sspine_skeleton_t* skeleton, const sspine_skeleton_desc* desc) {
  3665. SOKOL_ASSERT(skeleton && (skeleton->slot.state == SSPINE_RESOURCESTATE_ALLOC));
  3666. SOKOL_ASSERT(desc);
  3667. if ((0 == desc->json_data) && ((0 == desc->binary_data.ptr) || (0 == desc->binary_data.size))) {
  3668. _SSPINE_ERROR(SKELETON_DESC_NO_DATA);
  3669. return SSPINE_RESOURCESTATE_FAILED;
  3670. }
  3671. if (desc->atlas.id == SSPINE_INVALID_ID) {
  3672. _SSPINE_ERROR(SKELETON_DESC_NO_ATLAS);
  3673. return SSPINE_RESOURCESTATE_FAILED;
  3674. }
  3675. skeleton->atlas.id = desc->atlas.id;
  3676. skeleton->atlas.ptr = _sspine_lookup_atlas(skeleton->atlas.id);
  3677. if (!_sspine_atlas_ref_valid(&skeleton->atlas)) {
  3678. _SSPINE_ERROR(SKELETON_ATLAS_NOT_VALID);
  3679. return SSPINE_RESOURCESTATE_FAILED;
  3680. }
  3681. _sspine_atlas_t* atlas = skeleton->atlas.ptr;
  3682. if (SSPINE_RESOURCESTATE_VALID != atlas->slot.state) {
  3683. _SSPINE_ERROR(SKELETON_ATLAS_NOT_VALID);
  3684. return SSPINE_RESOURCESTATE_FAILED;
  3685. }
  3686. SOKOL_ASSERT(atlas->sp_atlas);
  3687. if (desc->json_data) {
  3688. spSkeletonJson* skel_json = spSkeletonJson_create(atlas->sp_atlas);
  3689. SOKOL_ASSERT(skel_json);
  3690. skel_json->scale = desc->prescale;
  3691. skeleton->sp_skel_data = spSkeletonJson_readSkeletonData(skel_json, desc->json_data);
  3692. spSkeletonJson_dispose(skel_json); skel_json = 0;
  3693. if (0 == skeleton->sp_skel_data) {
  3694. _SSPINE_ERROR(CREATE_SKELETON_DATA_FROM_JSON_FAILED);
  3695. return SSPINE_RESOURCESTATE_FAILED;
  3696. }
  3697. } else {
  3698. spSkeletonBinary* skel_bin = spSkeletonBinary_create(atlas->sp_atlas);
  3699. SOKOL_ASSERT(skel_bin);
  3700. skel_bin->scale = desc->prescale;
  3701. skeleton->sp_skel_data = spSkeletonBinary_readSkeletonData(skel_bin, (const unsigned char*)desc->binary_data.ptr, (int)desc->binary_data.size);
  3702. spSkeletonBinary_dispose(skel_bin); skel_bin = 0;
  3703. if (0 == skeleton->sp_skel_data) {
  3704. _SSPINE_ERROR(CREATE_SKELETON_DATA_FROM_BINARY_FAILED);
  3705. return SSPINE_RESOURCESTATE_FAILED;
  3706. }
  3707. }
  3708. SOKOL_ASSERT(skeleton->sp_skel_data);
  3709. skeleton->sp_anim_data = spAnimationStateData_create(skeleton->sp_skel_data);
  3710. SOKOL_ASSERT(skeleton->sp_anim_data);
  3711. skeleton->sp_anim_data->defaultMix = desc->anim_default_mix;
  3712. // get the max number of vertices in any mesh attachment
  3713. int max_vertex_count = 4; // number of vertices in a 'region attachment' (a 2-triangle quad)
  3714. const spSkeletonData* sp_skel_data = skeleton->sp_skel_data;
  3715. for (int skinIndex = 0; skinIndex < sp_skel_data->skinsCount; skinIndex++) {
  3716. const spSkin* sp_skin = sp_skel_data->skins[skinIndex];
  3717. const spSkinEntry* skin_entry = spSkin_getAttachments(sp_skin);
  3718. if (skin_entry) do {
  3719. if (skin_entry->attachment) {
  3720. if (skin_entry->attachment->type == SP_ATTACHMENT_MESH) {
  3721. const spMeshAttachment* mesh_attachment = (spMeshAttachment*)skin_entry->attachment;
  3722. // worldVerticesLength is number of floats
  3723. SOKOL_ASSERT((mesh_attachment->super.worldVerticesLength & 1) == 0);
  3724. const int num_vertices = mesh_attachment->super.worldVerticesLength / 2;
  3725. if (num_vertices > max_vertex_count) {
  3726. max_vertex_count = num_vertices;
  3727. }
  3728. }
  3729. }
  3730. } while ((skin_entry = skin_entry->next) != 0);
  3731. }
  3732. // allocate a shared vertex transform buffer (big enough to hold vertices for biggest mesh attachment)
  3733. skeleton->tform_buf.cap = max_vertex_count;
  3734. skeleton->tform_buf.ptr = (sspine_vec2*) _sspine_malloc((size_t)skeleton->tform_buf.cap * sizeof(sspine_vec2));
  3735. return SSPINE_RESOURCESTATE_VALID;
  3736. }
  3737. static void _sspine_deinit_skeleton(_sspine_skeleton_t* skeleton) {
  3738. if (skeleton->tform_buf.ptr) {
  3739. _sspine_free(skeleton->tform_buf.ptr);
  3740. skeleton->tform_buf.ptr = 0;
  3741. }
  3742. if (skeleton->sp_anim_data) {
  3743. spAnimationStateData_dispose(skeleton->sp_anim_data);
  3744. skeleton->sp_anim_data = 0;
  3745. }
  3746. if (skeleton->sp_skel_data) {
  3747. spSkeletonData_dispose(skeleton->sp_skel_data);
  3748. skeleton->sp_skel_data = 0;
  3749. }
  3750. }
  3751. static void _sspine_destroy_skeleton(sspine_skeleton skeleton_id) {
  3752. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  3753. if (skeleton) {
  3754. _sspine_deinit_skeleton(skeleton);
  3755. _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3756. _sspine_clear(skeleton, sizeof(_sspine_skeleton_t));
  3757. _sspine_pool_free_index(&p->pool, _sspine_slot_index(skeleton_id.id));
  3758. }
  3759. }
  3760. static void _sspine_destroy_all_skeletons(void) {
  3761. _sspine_skeleton_pool_t* p = &_sspine.skeleton_pool;
  3762. for (int i = 0; i < p->pool.size; i++) {
  3763. _sspine_skeleton_t* skeleton = &p->items[i];
  3764. _sspine_destroy_skeleton(_sspine_make_skeleton_handle(skeleton->slot.id));
  3765. }
  3766. }
  3767. static sspine_skeleton_desc _sspine_skeleton_desc_defaults(const sspine_skeleton_desc* desc) {
  3768. sspine_skeleton_desc res = *desc;
  3769. res.prescale = _sspine_def(desc->prescale, 1.0f);
  3770. res.anim_default_mix = _sspine_def(desc->anim_default_mix, 0.2f);
  3771. return res;
  3772. }
  3773. static spBoneData* _sspine_lookup_bone_data(uint32_t skeleton_id, int bone_index) {
  3774. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  3775. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  3776. SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->bones);
  3777. if ((bone_index >= 0) && (bone_index <= skeleton->sp_skel_data->bonesCount)) {
  3778. return skeleton->sp_skel_data->bones[bone_index];
  3779. }
  3780. }
  3781. return 0;
  3782. }
  3783. static spSlotData* _sspine_lookup_slot_data(uint32_t skeleton_id, int slot_index) {
  3784. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  3785. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  3786. SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->slots);
  3787. if ((slot_index >= 0) && (slot_index <= skeleton->sp_skel_data->slotsCount)) {
  3788. return skeleton->sp_skel_data->slots[slot_index];
  3789. }
  3790. }
  3791. return 0;
  3792. }
  3793. static spEventData* _sspine_lookup_event_data(uint32_t skeleton_id, int event_index) {
  3794. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  3795. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  3796. SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->events);
  3797. if ((event_index >= 0) && (event_index < skeleton->sp_skel_data->eventsCount)) {
  3798. return skeleton->sp_skel_data->events[event_index];
  3799. }
  3800. }
  3801. return 0;
  3802. }
  3803. static spIkConstraintData* _sspine_lookup_ikconstraint_data(uint32_t skeleton_id, int iktarget_index) {
  3804. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  3805. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  3806. SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->ikConstraints);
  3807. if ((iktarget_index >= 0) && (iktarget_index < skeleton->sp_skel_data->ikConstraintsCount)) {
  3808. return skeleton->sp_skel_data->ikConstraints[iktarget_index];
  3809. }
  3810. }
  3811. return 0;
  3812. }
  3813. static spSkin* _sspine_lookup_skin(uint32_t skeleton_id, int skin_index) {
  3814. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  3815. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  3816. SOKOL_ASSERT(skeleton->sp_skel_data && skeleton->sp_skel_data->skins);
  3817. if ((skin_index >= 0) && (skin_index < skeleton->sp_skel_data->skinsCount)) {
  3818. return skeleton->sp_skel_data->skins[skin_index];
  3819. }
  3820. }
  3821. return 0;
  3822. }
  3823. // ███████ ██ ██ ██ ███ ██ ███████ ███████ ████████
  3824. // ██ ██ ██ ██ ████ ██ ██ ██ ██
  3825. // ███████ █████ ██ ██ ██ ██ ███████ █████ ██
  3826. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3827. // ███████ ██ ██ ██ ██ ████ ███████ ███████ ██
  3828. //
  3829. // >>skinset
  3830. static void _sspine_setup_skinset_pool(int pool_size) {
  3831. _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3832. _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_skinset_t));
  3833. }
  3834. static void _sspine_discard_skinset_pool(void) {
  3835. _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3836. _sspine_discard_item_pool(&p->pool, (void**)&p->items);
  3837. }
  3838. static sspine_skinset _sspine_make_skinset_handle(uint32_t id) {
  3839. sspine_skinset handle = { id };
  3840. return handle;
  3841. }
  3842. static _sspine_skinset_t* _sspine_skinset_at(uint32_t id) {
  3843. SOKOL_ASSERT(SSPINE_INVALID_ID != id);
  3844. const _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3845. int slot_index = _sspine_slot_index(id);
  3846. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
  3847. return &p->items[slot_index];
  3848. }
  3849. static _sspine_skinset_t* _sspine_lookup_skinset(uint32_t id) {
  3850. if (SSPINE_INVALID_ID != id) {
  3851. _sspine_skinset_t* skinset = _sspine_skinset_at(id);
  3852. if (skinset->slot.id == id) {
  3853. return skinset;
  3854. }
  3855. }
  3856. return 0;
  3857. }
  3858. static sspine_skinset _sspine_alloc_skinset(void) {
  3859. _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3860. int slot_index = _sspine_pool_alloc_index(&p->pool);
  3861. if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
  3862. uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
  3863. return _sspine_make_skinset_handle(id);
  3864. } else {
  3865. // pool exhausted
  3866. return _sspine_make_skinset_handle(SSPINE_INVALID_ID);
  3867. }
  3868. }
  3869. static sspine_resource_state _sspine_init_skinset(_sspine_skinset_t* skinset, const sspine_skinset_desc* desc) {
  3870. SOKOL_ASSERT(skinset && (skinset->slot.state == SSPINE_RESOURCESTATE_ALLOC));
  3871. SOKOL_ASSERT(desc);
  3872. if (desc->skeleton.id == SSPINE_INVALID_ID) {
  3873. _SSPINE_ERROR(SKINSET_DESC_NO_SKELETON);
  3874. return SSPINE_RESOURCESTATE_FAILED;
  3875. }
  3876. skinset->skel.id = desc->skeleton.id;
  3877. skinset->skel.ptr = _sspine_lookup_skeleton(desc->skeleton.id);
  3878. if (!_sspine_skeleton_ref_valid(&skinset->skel)) {
  3879. _SSPINE_ERROR(SKINSET_SKELETON_NOT_VALID);
  3880. return SSPINE_RESOURCESTATE_FAILED;
  3881. }
  3882. _sspine_skeleton_t* skel = skinset->skel.ptr;
  3883. if (SSPINE_RESOURCESTATE_VALID != skel->slot.state) {
  3884. _SSPINE_ERROR(SKINSET_SKELETON_NOT_VALID);
  3885. return SSPINE_RESOURCESTATE_FAILED;
  3886. }
  3887. SOKOL_ASSERT(skel->sp_skel_data);
  3888. skinset->sp_skin = spSkin_create("skinset");
  3889. for (int i = 0; i < SSPINE_MAX_SKINSET_SKINS; i++) {
  3890. if (desc->skins[i].skeleton_id != SSPINE_INVALID_ID) {
  3891. spSkin* skin = _sspine_lookup_skin(desc->skins[i].skeleton_id, desc->skins[i].index);
  3892. if (0 == skin) {
  3893. _SSPINE_ERROR(SKINSET_INVALID_SKIN_HANDLE);
  3894. return SSPINE_RESOURCESTATE_FAILED;
  3895. }
  3896. spSkin_addSkin(skinset->sp_skin, skin);
  3897. }
  3898. }
  3899. return SSPINE_RESOURCESTATE_VALID;
  3900. }
  3901. static void _sspine_deinit_skinset(_sspine_skinset_t* skinset) {
  3902. if (skinset->sp_skin) {
  3903. spSkin_clear(skinset->sp_skin);
  3904. spSkin_dispose(skinset->sp_skin);
  3905. skinset->sp_skin = 0;
  3906. }
  3907. }
  3908. static void _sspine_destroy_skinset(sspine_skinset skinset_id) {
  3909. _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
  3910. if (skinset) {
  3911. _sspine_deinit_skinset(skinset);
  3912. _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3913. _sspine_clear(skinset, sizeof(_sspine_skinset_t));
  3914. _sspine_pool_free_index(&p->pool, _sspine_slot_index(skinset_id.id));
  3915. }
  3916. }
  3917. static void _sspine_destroy_all_skinsets(void) {
  3918. _sspine_skinset_pool_t* p = &_sspine.skinset_pool;
  3919. for (int i = 0; i < p->pool.size; i++) {
  3920. _sspine_skinset_t* skinset = &p->items[i];
  3921. _sspine_destroy_skinset(_sspine_make_skinset_handle(skinset->slot.id));
  3922. }
  3923. }
  3924. static sspine_skinset_desc _sspine_skinset_desc_defaults(const sspine_skinset_desc* desc) {
  3925. sspine_skinset_desc res = *desc;
  3926. return res;
  3927. }
  3928. // ██ ███ ██ ███████ ████████ █████ ███ ██ ██████ ███████
  3929. // ██ ████ ██ ██ ██ ██ ██ ████ ██ ██ ██
  3930. // ██ ██ ██ ██ ███████ ██ ███████ ██ ██ ██ ██ █████
  3931. // ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
  3932. // ██ ██ ████ ███████ ██ ██ ██ ██ ████ ██████ ███████
  3933. //
  3934. // >>instance
  3935. static void _sspine_setup_instance_pool(int pool_size) {
  3936. _sspine_instance_pool_t* p = &_sspine.instance_pool;
  3937. _sspine_init_item_pool(&p->pool, pool_size, (void**)&p->items, sizeof(_sspine_instance_t));
  3938. }
  3939. static void _sspine_discard_instance_pool(void) {
  3940. _sspine_instance_pool_t* p = &_sspine.instance_pool;
  3941. _sspine_discard_item_pool(&p->pool, (void**)&p->items);
  3942. }
  3943. static sspine_instance _sspine_make_instance_handle(uint32_t id) {
  3944. sspine_instance handle = { id };
  3945. return handle;
  3946. }
  3947. static _sspine_instance_t* _sspine_instance_at(uint32_t id) {
  3948. SOKOL_ASSERT(SSPINE_INVALID_ID != id);
  3949. const _sspine_instance_pool_t* p = &_sspine.instance_pool;
  3950. int slot_index = _sspine_slot_index(id);
  3951. SOKOL_ASSERT((slot_index > _SSPINE_INVALID_SLOT_INDEX) && (slot_index < p->pool.size));
  3952. return &p->items[slot_index];
  3953. }
  3954. static _sspine_instance_t* _sspine_lookup_instance(uint32_t id) {
  3955. if (SSPINE_INVALID_ID != id) {
  3956. _sspine_instance_t* instance = _sspine_instance_at(id);
  3957. if (instance->slot.id == id) {
  3958. return instance;
  3959. }
  3960. }
  3961. return 0;
  3962. }
  3963. static sspine_instance _sspine_alloc_instance(void) {
  3964. _sspine_instance_pool_t* p = &_sspine.instance_pool;
  3965. sspine_instance res;
  3966. int slot_index = _sspine_pool_alloc_index(&p->pool);
  3967. if (_SSPINE_INVALID_SLOT_INDEX != slot_index) {
  3968. uint32_t id = _sspine_slot_init(&p->pool, &p->items[slot_index].slot, slot_index);
  3969. res = _sspine_make_instance_handle(id);
  3970. } else {
  3971. // pool exhausted
  3972. res = _sspine_make_instance_handle(SSPINE_INVALID_ID);
  3973. }
  3974. return res;
  3975. }
  3976. static void _sspine_rewind_triggered_events(_sspine_instance_t* instance) {
  3977. instance->cur_triggered_event_index = 0;
  3978. _sspine_clear(instance->triggered_events, sizeof(instance->triggered_events));
  3979. }
  3980. static sspine_triggered_event_info* _sspine_next_triggered_event_info(_sspine_instance_t* instance) {
  3981. if (instance->cur_triggered_event_index < _SSPINE_MAX_TRIGGERED_EVENTS) {
  3982. return &instance->triggered_events[instance->cur_triggered_event_index++];
  3983. } else {
  3984. return 0;
  3985. }
  3986. }
  3987. static void _sspine_event_listener(spAnimationState* sp_anim_state, spEventType sp_event_type, spTrackEntry* sp_track_entry, spEvent* sp_event) {
  3988. if (sp_event_type == SP_ANIMATION_EVENT) {
  3989. SOKOL_ASSERT(sp_anim_state && sp_track_entry && sp_event); (void)sp_track_entry;
  3990. SOKOL_ASSERT(sp_event->data && sp_event->data->name);
  3991. _sspine_instance_t* instance = _sspine_lookup_instance((uint32_t)(uintptr_t)sp_anim_state->userData);
  3992. if (_sspine_instance_and_deps_valid(instance)) {
  3993. sspine_triggered_event_info* info = _sspine_next_triggered_event_info(instance);
  3994. if (info) {
  3995. // FIXME: this sucks, but we really need the event index
  3996. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(instance->skel.id);
  3997. SOKOL_ASSERT(skeleton && skeleton->sp_skel_data->events);
  3998. const spEventData* sp_event_data = sp_event->data;
  3999. for (int i = 0; i < skeleton->sp_skel_data->eventsCount; i++) {
  4000. if (sp_event_data == skeleton->sp_skel_data->events[i]) {
  4001. info->event = _sspine_event(skeleton->slot.id, i);
  4002. break;
  4003. }
  4004. }
  4005. SOKOL_ASSERT(info->event.skeleton_id != SSPINE_INVALID_ID);
  4006. info->valid = true;
  4007. info->time = sp_event->time;
  4008. info->int_value = sp_event->intValue;
  4009. info->float_value = sp_event->floatValue;
  4010. info->volume = sp_event->volume;
  4011. info->balance = sp_event->balance;
  4012. info->string_value = _sspine_string(sp_event->stringValue);
  4013. if (info->string_value.truncated) {
  4014. _SSPINE_WARN(STRING_TRUNCATED);
  4015. }
  4016. }
  4017. }
  4018. }
  4019. }
  4020. static sspine_resource_state _sspine_init_instance(_sspine_instance_t* instance, const sspine_instance_desc* desc) {
  4021. SOKOL_ASSERT(instance && (instance->slot.state == SSPINE_RESOURCESTATE_ALLOC));
  4022. SOKOL_ASSERT(desc);
  4023. if (desc->skeleton.id == SSPINE_INVALID_ID) {
  4024. _SSPINE_ERROR(INSTANCE_DESC_NO_SKELETON);
  4025. return SSPINE_RESOURCESTATE_FAILED;
  4026. }
  4027. instance->skel.id = desc->skeleton.id;
  4028. instance->skel.ptr = _sspine_lookup_skeleton(instance->skel.id);
  4029. if (!_sspine_skeleton_ref_valid(&instance->skel)) {
  4030. _SSPINE_ERROR(INSTANCE_SKELETON_NOT_VALID);
  4031. return SSPINE_RESOURCESTATE_FAILED;
  4032. }
  4033. _sspine_skeleton_t* skel = instance->skel.ptr;
  4034. if (SSPINE_RESOURCESTATE_VALID != skel->slot.state) {
  4035. _SSPINE_ERROR(INSTANCE_SKELETON_NOT_VALID);
  4036. return SSPINE_RESOURCESTATE_FAILED;
  4037. }
  4038. instance->atlas = skel->atlas;
  4039. if (!_sspine_atlas_ref_valid(&instance->atlas)) {
  4040. _SSPINE_ERROR(INSTANCE_ATLAS_NOT_VALID);
  4041. return SSPINE_RESOURCESTATE_FAILED;
  4042. }
  4043. if (SSPINE_RESOURCESTATE_VALID != instance->atlas.ptr->slot.state) {
  4044. _SSPINE_ERROR(INSTANCE_ATLAS_NOT_VALID);
  4045. return SSPINE_RESOURCESTATE_FAILED;
  4046. }
  4047. SOKOL_ASSERT(skel->sp_skel_data);
  4048. SOKOL_ASSERT(skel->sp_anim_data);
  4049. instance->sp_skel = spSkeleton_create(skel->sp_skel_data);
  4050. if (0 == instance->sp_skel) {
  4051. _SSPINE_ERROR(SPINE_SKELETON_CREATION_FAILED);
  4052. return SSPINE_RESOURCESTATE_FAILED;
  4053. }
  4054. instance->sp_anim_state = spAnimationState_create(skel->sp_anim_data);
  4055. if (0 == instance->sp_anim_state) {
  4056. _SSPINE_ERROR(SPINE_ANIMATIONSTATE_CREATION_FAILED);
  4057. return SSPINE_RESOURCESTATE_FAILED;
  4058. }
  4059. instance->sp_clip = spSkeletonClipping_create();
  4060. if (0 == instance->sp_clip) {
  4061. _SSPINE_ERROR(SPINE_SKELETONCLIPPING_CREATION_FAILED);
  4062. return SSPINE_RESOURCESTATE_FAILED;
  4063. }
  4064. instance->sp_anim_state->userData = (void*)(uintptr_t)instance->slot.id;
  4065. instance->sp_anim_state->listener = _sspine_event_listener;
  4066. spSkeleton_setToSetupPose(instance->sp_skel);
  4067. spAnimationState_update(instance->sp_anim_state, 0.0f);
  4068. spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
  4069. spSkeleton_update(instance->sp_skel, 0.0f);
  4070. spSkeleton_updateWorldTransform(instance->sp_skel, SP_PHYSICS_UPDATE);
  4071. return SSPINE_RESOURCESTATE_VALID;
  4072. }
  4073. static void _sspine_deinit_instance(_sspine_instance_t* instance) {
  4074. if (instance->sp_clip) {
  4075. spSkeletonClipping_dispose(instance->sp_clip);
  4076. instance->sp_clip = 0;
  4077. }
  4078. if (instance->sp_anim_state) {
  4079. spAnimationState_dispose(instance->sp_anim_state);
  4080. instance->sp_anim_state = 0;
  4081. }
  4082. if (instance->sp_skel) {
  4083. spSkeleton_dispose(instance->sp_skel);
  4084. instance->sp_skel = 0;
  4085. }
  4086. }
  4087. static void _sspine_destroy_instance(sspine_instance instance_id) {
  4088. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4089. if (instance) {
  4090. _sspine_deinit_instance(instance);
  4091. _sspine_instance_pool_t* p = &_sspine.instance_pool;
  4092. _sspine_clear(instance, sizeof(_sspine_instance_t));
  4093. _sspine_pool_free_index(&p->pool, _sspine_slot_index(instance_id.id));
  4094. }
  4095. }
  4096. static void _sspine_destroy_all_instances(void) {
  4097. _sspine_instance_pool_t* p = &_sspine.instance_pool;
  4098. for (int i = 0; i < p->pool.size; i++) {
  4099. _sspine_instance_t* instance = &p->items[i];
  4100. _sspine_destroy_instance(_sspine_make_instance_handle(instance->slot.id));
  4101. }
  4102. }
  4103. static spAnimation* _sspine_lookup_skeleton_anim(uint32_t skeleton_id, int anim_index) {
  4104. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id);
  4105. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  4106. SOKOL_ASSERT(skeleton->sp_skel_data);
  4107. if ((anim_index >= 0) && (anim_index < skeleton->sp_skel_data->animationsCount)) {
  4108. return skeleton->sp_skel_data->animations[anim_index];
  4109. }
  4110. }
  4111. return 0;
  4112. }
  4113. static spAnimation* _sspine_lookup_instance_anim(uint32_t instance_id, uint32_t skeleton_id, int anim_index) {
  4114. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
  4115. if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
  4116. SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->data);
  4117. if ((anim_index >= 0) && (anim_index < instance->sp_skel->data->animationsCount)) {
  4118. return instance->sp_skel->data->animations[anim_index];
  4119. }
  4120. }
  4121. return 0;
  4122. }
  4123. static spBone* _sspine_lookup_bone(uint32_t instance_id, uint32_t skeleton_id, int bone_index) {
  4124. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
  4125. if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
  4126. SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->bones);
  4127. if ((bone_index >= 0) && (bone_index <= instance->sp_skel->bonesCount)) {
  4128. return instance->sp_skel->bones[bone_index];
  4129. }
  4130. }
  4131. return 0;
  4132. }
  4133. static spSlot* _sspine_lookup_slot(uint32_t instance_id, uint32_t skeleton_id, int slot_index) {
  4134. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
  4135. if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
  4136. SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->slots);
  4137. if ((slot_index >= 0) && (slot_index <= instance->sp_skel->slotsCount)) {
  4138. return instance->sp_skel->slots[slot_index];
  4139. }
  4140. }
  4141. return 0;
  4142. }
  4143. static spIkConstraint* _sspine_lookup_ikconstraint(uint32_t instance_id, uint32_t skeleton_id, int iktarget_index) {
  4144. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id);
  4145. if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skeleton_id)) {
  4146. SOKOL_ASSERT(instance->sp_skel && instance->sp_skel->ikConstraints);
  4147. if ((iktarget_index >= 0) && (iktarget_index < instance->sp_skel->ikConstraintsCount)) {
  4148. return instance->sp_skel->ikConstraints[iktarget_index];
  4149. }
  4150. }
  4151. return 0;
  4152. }
  4153. static sspine_instance_desc _sspine_instance_desc_defaults(const sspine_instance_desc* desc) {
  4154. sspine_instance_desc res = *desc;
  4155. return res;
  4156. }
  4157. // ██████ ██████ █████ ██ ██
  4158. // ██ ██ ██ ██ ██ ██ ██ ██
  4159. // ██ ██ ██████ ███████ ██ █ ██
  4160. // ██ ██ ██ ██ ██ ██ ██ ███ ██
  4161. // ██████ ██ ██ ██ ██ ███ ███
  4162. //
  4163. // >>draw
  4164. static void _sspine_check_rewind_commands(_sspine_context_t* ctx) {
  4165. if (_sspine.frame_id != ctx->commands.rewind_frame_id) {
  4166. ctx->commands.next = 0;
  4167. ctx->commands.rewind_frame_id = _sspine.frame_id;
  4168. }
  4169. }
  4170. static _sspine_command_t* _sspine_next_command(_sspine_context_t* ctx) {
  4171. _sspine_check_rewind_commands(ctx);
  4172. if (ctx->commands.next < ctx->commands.cap) {
  4173. return &(ctx->commands.ptr[ctx->commands.next++]);
  4174. } else {
  4175. _SSPINE_ERROR(COMMAND_BUFFER_FULL);
  4176. return 0;
  4177. }
  4178. }
  4179. static _sspine_command_t* _sspine_cur_command(_sspine_context_t* ctx) {
  4180. _sspine_check_rewind_commands(ctx);
  4181. if (ctx->commands.next > 0) {
  4182. return &ctx->commands.ptr[ctx->commands.next - 1];
  4183. } else {
  4184. return 0;
  4185. }
  4186. }
  4187. static void _sspine_check_rewind_vertices(_sspine_context_t* ctx) {
  4188. if (_sspine.frame_id != ctx->vertices.rewind_frame_id) {
  4189. ctx->vertices.next = 0;
  4190. ctx->vertices.rewind_frame_id = _sspine.frame_id;
  4191. }
  4192. }
  4193. static _sspine_alloc_vertices_result_t _sspine_alloc_vertices(_sspine_context_t* ctx, int num) {
  4194. _sspine_check_rewind_vertices(ctx);
  4195. _sspine_alloc_vertices_result_t res;
  4196. _sspine_clear(&res, sizeof(res));
  4197. if ((ctx->vertices.next + num) <= ctx->vertices.cap) {
  4198. res.ptr = &(ctx->vertices.ptr[ctx->vertices.next]);
  4199. res.index = ctx->vertices.next;
  4200. ctx->vertices.next += num;
  4201. } else {
  4202. _SSPINE_ERROR(VERTEX_BUFFER_FULL);
  4203. }
  4204. return res;
  4205. }
  4206. static void _sspine_check_rewind_indices(_sspine_context_t* ctx) {
  4207. if (_sspine.frame_id != ctx->indices.rewind_frame_id) {
  4208. ctx->indices.next = 0;
  4209. ctx->indices.rewind_frame_id = _sspine.frame_id;
  4210. }
  4211. }
  4212. static _sspine_alloc_indices_result_t _sspine_alloc_indices(_sspine_context_t* ctx, int num) {
  4213. _sspine_check_rewind_indices(ctx);
  4214. _sspine_alloc_indices_result_t res;
  4215. _sspine_clear(&res, sizeof(res));
  4216. if ((ctx->indices.next + num) <= ctx->indices.cap) {
  4217. res.ptr = &(ctx->indices.ptr[ctx->indices.next]);
  4218. res.index = ctx->indices.next;
  4219. ctx->indices.next += num;
  4220. } else {
  4221. _SSPINE_ERROR(INDEX_BUFFER_FULL);
  4222. }
  4223. return res;
  4224. }
  4225. static void _sspine_draw_instance(_sspine_context_t* ctx, _sspine_instance_t* instance, int layer) {
  4226. SOKOL_ASSERT(_sspine_instance_and_deps_valid(instance));
  4227. SOKOL_ASSERT(instance->sp_skel);
  4228. SOKOL_ASSERT(instance->sp_anim_state);
  4229. SOKOL_ASSERT(instance->sp_clip);
  4230. // see: https://github.com/EsotericSoftware/spine-runtimes/blob/4.1/spine-sdl/src/spine-sdl-c.c
  4231. const spSkeleton* sp_skel = instance->sp_skel;
  4232. float* tform_buf = (float*)instance->skel.ptr->tform_buf.ptr;
  4233. const int max_tform_buf_verts = instance->skel.ptr->tform_buf.cap;
  4234. SOKOL_UNUSED(max_tform_buf_verts); // only used in asserts
  4235. const int tform_buf_stride = 2; // each element is 2 floats
  4236. spSkeletonClipping* sp_clip = instance->sp_clip;
  4237. for (int slot_index = 0; slot_index < sp_skel->slotsCount; slot_index++) {
  4238. spSlot* sp_slot = sp_skel->drawOrder[slot_index];
  4239. if (!sp_slot->attachment) {
  4240. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4241. continue;
  4242. }
  4243. // early out if the slot alpha is 0 or the bone is not active
  4244. // FIXME: does alpha 0 actually mean 'invisible' for all blend modes?
  4245. if ((sp_slot->color.a == 0) || (!sp_slot->bone->active)) {
  4246. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4247. continue;
  4248. }
  4249. int num_vertices = 0;
  4250. float* uvs = 0;
  4251. float* vertices = 0;
  4252. int num_indices = 0;
  4253. const uint16_t* indices = 0;
  4254. const spColor* att_color = 0;
  4255. sg_image img = { SG_INVALID_ID };
  4256. sg_sampler smp = { SG_INVALID_ID };
  4257. bool premul_alpha = false;
  4258. if (sp_slot->attachment->type == SP_ATTACHMENT_REGION) {
  4259. static const uint16_t quad_indices[] = { 0, 1, 2, 2, 3, 0 };
  4260. spRegionAttachment* region = (spRegionAttachment*)sp_slot->attachment;
  4261. att_color = &region->color;
  4262. // FIXME(?) early out if the slot alpha is 0
  4263. if (att_color->a == 0) {
  4264. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4265. continue;
  4266. }
  4267. spRegionAttachment_computeWorldVertices(region, sp_slot, tform_buf, 0, tform_buf_stride);
  4268. vertices = tform_buf;
  4269. num_vertices = 4;
  4270. indices = &quad_indices[0];
  4271. num_indices = 6;
  4272. uvs = region->uvs;
  4273. const spAtlasPage* sp_page = ((spAtlasRegion*)region->rendererObject)->page;
  4274. img = _sspine_image_from_renderer_object(sp_page->rendererObject);
  4275. smp = _sspine_sampler_from_renderer_object(sp_page->rendererObject);
  4276. premul_alpha = sp_page->pma != 0;
  4277. } else if (sp_slot->attachment->type == SP_ATTACHMENT_MESH) {
  4278. spMeshAttachment* mesh = (spMeshAttachment*)sp_slot->attachment;
  4279. att_color = &mesh->color;
  4280. // FIXME(?) early out if the slot alpha is 0
  4281. if (att_color->a == 0) {
  4282. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4283. continue;
  4284. }
  4285. const int num_floats = mesh->super.worldVerticesLength;
  4286. num_vertices = num_floats / 2;
  4287. SOKOL_ASSERT(num_vertices <= max_tform_buf_verts);
  4288. spVertexAttachment_computeWorldVertices(&mesh->super, sp_slot, 0, num_floats, tform_buf, 0, tform_buf_stride);
  4289. vertices = tform_buf;
  4290. indices = mesh->triangles;
  4291. num_indices = mesh->trianglesCount; // actually indicesCount???
  4292. uvs = mesh->uvs;
  4293. const spAtlasPage* sp_page = ((spAtlasRegion*)mesh->rendererObject)->page;
  4294. img = _sspine_image_from_renderer_object(sp_page->rendererObject);
  4295. smp = _sspine_sampler_from_renderer_object(sp_page->rendererObject);
  4296. premul_alpha = sp_page->pma != 0;
  4297. } else if (sp_slot->attachment->type == SP_ATTACHMENT_CLIPPING) {
  4298. spClippingAttachment* clip_attachment = (spClippingAttachment*) sp_slot->attachment;
  4299. spSkeletonClipping_clipStart(sp_clip, sp_slot, clip_attachment);
  4300. continue;
  4301. } else {
  4302. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4303. continue;
  4304. }
  4305. SOKOL_ASSERT(vertices && (num_vertices > 0));
  4306. SOKOL_ASSERT(indices && (num_indices > 0));
  4307. SOKOL_ASSERT(uvs);
  4308. SOKOL_ASSERT(img.id != SG_INVALID_ID);
  4309. SOKOL_ASSERT(smp.id != SG_INVALID_ID);
  4310. if (spSkeletonClipping_isClipping(sp_clip)) {
  4311. spSkeletonClipping_clipTriangles(sp_clip, tform_buf, num_vertices * 2, (uint16_t*)indices, num_indices, uvs, tform_buf_stride);
  4312. vertices = sp_clip->clippedVertices->items;
  4313. num_vertices = sp_clip->clippedVertices->size / 2;
  4314. uvs = sp_clip->clippedUVs->items;
  4315. indices = sp_clip->clippedTriangles->items;
  4316. num_indices = sp_clip->clippedTriangles->size;
  4317. }
  4318. SOKOL_ASSERT(vertices);
  4319. SOKOL_ASSERT(indices);
  4320. SOKOL_ASSERT(uvs);
  4321. // there might be no geometry to render after clipping
  4322. if ((0 == num_vertices) || (0 == num_indices)) {
  4323. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4324. continue;
  4325. }
  4326. const _sspine_alloc_vertices_result_t dst_vertices = _sspine_alloc_vertices(ctx, num_vertices);
  4327. const _sspine_alloc_indices_result_t dst_indices = _sspine_alloc_indices(ctx, num_indices);
  4328. if ((0 == dst_vertices.ptr) || (0 == dst_indices.ptr)) {
  4329. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4330. continue;
  4331. }
  4332. // write transformed and potentially clipped vertices and indices
  4333. const uint8_t r = (uint8_t)(sp_skel->color.r * sp_slot->color.r * att_color->r * 255.0f);
  4334. const uint8_t g = (uint8_t)(sp_skel->color.g * sp_slot->color.g * att_color->g * 255.0f);
  4335. const uint8_t b = (uint8_t)(sp_skel->color.b * sp_slot->color.b * att_color->b * 255.0f);
  4336. const uint8_t a = (uint8_t)(sp_skel->color.a * sp_slot->color.a * att_color->a * 255.0f);
  4337. const uint32_t color = (((uint32_t)a<<24) | ((uint32_t)b<<16) | ((uint32_t)g<<8) | (uint32_t)r);
  4338. for (int vi = 0; vi < num_vertices; vi++) {
  4339. dst_vertices.ptr[vi].pos.x = vertices[vi*2];
  4340. dst_vertices.ptr[vi].pos.y = vertices[vi*2 + 1];
  4341. dst_vertices.ptr[vi].color = color;
  4342. dst_vertices.ptr[vi].uv.x = uvs[vi*2];
  4343. dst_vertices.ptr[vi].uv.y = uvs[vi*2 + 1];
  4344. }
  4345. for (int ii = 0; ii < num_indices; ii++) {
  4346. dst_indices.ptr[ii] = (uint32_t)indices[ii] + (uint32_t)dst_vertices.index;
  4347. }
  4348. sg_pipeline pip = { SG_INVALID_ID };
  4349. // NOTE: pma == 0.0: use color from texture as is
  4350. // pma == 1.0: multiply texture rgb by texture alpha in fragment shader
  4351. float pma = 0.0f;
  4352. switch (sp_slot->data->blendMode) {
  4353. case SP_BLEND_MODE_NORMAL:
  4354. case SP_BLEND_MODE_ADDITIVE:
  4355. case SP_BLEND_MODE_SCREEN:
  4356. pip = ctx->pip.normal_additive;
  4357. pma = premul_alpha ? 0.0f : 1.0f; // NOT A BUG
  4358. break;
  4359. case SP_BLEND_MODE_MULTIPLY:
  4360. pip = ctx->pip.multiply;
  4361. pma = 0.0f; // always use texture color as is
  4362. break;
  4363. }
  4364. // write new draw command, or merge with current draw command
  4365. _sspine_command_t* cur_cmd = _sspine_cur_command(ctx);
  4366. if (cur_cmd
  4367. && (cur_cmd->layer == layer)
  4368. && (cur_cmd->pip.id == pip.id)
  4369. && (cur_cmd->img.id == img.id)
  4370. && (cur_cmd->smp.id == smp.id)
  4371. && (cur_cmd->pma == pma))
  4372. {
  4373. // merge with current command
  4374. cur_cmd->num_elements += num_indices;
  4375. } else {
  4376. // record a new command
  4377. _sspine_command_t* cmd_ptr = _sspine_next_command(ctx);
  4378. if (cmd_ptr) {
  4379. cmd_ptr->layer = layer;
  4380. cmd_ptr->pip = pip;
  4381. cmd_ptr->img = img;
  4382. cmd_ptr->smp = smp;
  4383. cmd_ptr->pma = pma;
  4384. cmd_ptr->base_element = dst_indices.index;
  4385. cmd_ptr->num_elements = num_indices;
  4386. }
  4387. }
  4388. spSkeletonClipping_clipEnd(sp_clip, sp_slot);
  4389. }
  4390. spSkeletonClipping_clipEnd2(sp_clip);
  4391. }
  4392. // compute orthographic projection matrix
  4393. static void _sspine_layer_transform_to_proj(const sspine_layer_transform* tform, float* res) {
  4394. const float left = -tform->origin.x;
  4395. const float right = tform->size.x - tform->origin.x;
  4396. const float top = -tform->origin.y;
  4397. const float bottom = tform->size.y - tform->origin.y;
  4398. const float znear = -1.0f;
  4399. const float zfar = 1.0f;
  4400. res[0] = 2.0f / (right - left);
  4401. res[1] = 0.0f;
  4402. res[2] = 0.0f;
  4403. res[3] = 0.0f;
  4404. res[4] = 0.0f;
  4405. res[5] = 2.0f / (top - bottom);
  4406. res[6] = 0.0f;
  4407. res[7] = 0.0f;
  4408. res[8] = 0.0f;
  4409. res[9] = 0.0f;
  4410. res[10] = -2.0f / (zfar - znear);
  4411. res[11] = 0.0f;
  4412. res[12] = -(right + left) / (right - left);
  4413. res[13] = -(top + bottom) / (top - bottom);
  4414. res[14] = -(zfar + znear) / (zfar - znear);
  4415. res[15] = 1.0f;
  4416. }
  4417. static _sspine_vsparams_t _sspine_compute_vsparams(const sspine_layer_transform* tform) {
  4418. _sspine_vsparams_t p;
  4419. _sspine_clear(&p, sizeof(p));
  4420. _sspine_layer_transform_to_proj(tform, p.mvp);
  4421. return p;
  4422. }
  4423. static void _sspine_draw_layer(_sspine_context_t* ctx, int layer, const sspine_layer_transform* tform) {
  4424. if ((ctx->vertices.next > 0) && (ctx->commands.next > 0)) {
  4425. sg_push_debug_group("sokol-spine");
  4426. if (ctx->update_frame_id != _sspine.frame_id) {
  4427. ctx->update_frame_id = _sspine.frame_id;
  4428. const sg_range vtx_range = { ctx->vertices.ptr, (size_t)ctx->vertices.next * sizeof(_sspine_vertex_t) };
  4429. sg_update_buffer(ctx->vbuf, &vtx_range);
  4430. const sg_range idx_range = { ctx->indices.ptr, (size_t)ctx->indices.next * sizeof(uint32_t) };
  4431. sg_update_buffer(ctx->ibuf, &idx_range);
  4432. }
  4433. _sspine_vsparams_t vsparams = _sspine_compute_vsparams(tform);
  4434. const sg_range vsparams_range = { &vsparams, sizeof(vsparams) };
  4435. _sspine_fsparams_t fsparams;
  4436. _sspine_clear(&fsparams, sizeof(fsparams));
  4437. const sg_range fsparams_range = { &fsparams, sizeof(fsparams) };
  4438. uint32_t cur_pip_id = SG_INVALID_ID;
  4439. uint32_t cur_img_id = SG_INVALID_ID;
  4440. uint32_t cur_smp_id = SG_INVALID_ID;
  4441. float cur_pma = -1.0f;
  4442. for (int i = 0; i < ctx->commands.next; i++) {
  4443. const _sspine_command_t* cmd = &ctx->commands.ptr[i];
  4444. const bool img_valid = sg_query_image_state(cmd->img) == SG_RESOURCESTATE_VALID;
  4445. const bool smp_valid = sg_query_sampler_state(cmd->smp) == SG_RESOURCESTATE_VALID;
  4446. if ((layer == cmd->layer) && img_valid && smp_valid) {
  4447. if (cur_pip_id != cmd->pip.id) {
  4448. sg_apply_pipeline(cmd->pip);
  4449. cur_pip_id = cmd->pip.id;
  4450. sg_apply_uniforms(0, &vsparams_range);
  4451. cur_img_id = SG_INVALID_ID;
  4452. }
  4453. if ((cur_img_id != cmd->img.id) || (cur_smp_id != cmd->smp.id)) {
  4454. ctx->bind.images[0] = cmd->img;
  4455. ctx->bind.samplers[0] = cmd->smp;
  4456. sg_apply_bindings(&ctx->bind);
  4457. cur_img_id = cmd->img.id;
  4458. cur_smp_id = cmd->smp.id;
  4459. }
  4460. if (cur_pma != cmd->pma) {
  4461. fsparams.pma = cmd->pma;
  4462. sg_apply_uniforms(1, &fsparams_range);
  4463. cur_pma = cmd->pma;
  4464. }
  4465. if (cmd->num_elements > 0) {
  4466. sg_draw(cmd->base_element, cmd->num_elements, 1);
  4467. }
  4468. }
  4469. }
  4470. sg_pop_debug_group();
  4471. }
  4472. }
  4473. // ███ ███ ██ ███████ ██████
  4474. // ████ ████ ██ ██ ██
  4475. // ██ ████ ██ ██ ███████ ██
  4476. // ██ ██ ██ ██ ██ ██
  4477. // ██ ██ ██ ███████ ██████
  4478. //
  4479. // >>misc
  4480. // return sspine_desc with patched defaults
  4481. static sspine_desc _sspine_desc_defaults(const sspine_desc* desc) {
  4482. SOKOL_ASSERT((desc->allocator.alloc_fn && desc->allocator.free_fn) || (!desc->allocator.alloc_fn && !desc->allocator.free_fn));
  4483. sspine_desc res = *desc;
  4484. res.max_vertices = _sspine_def(desc->max_vertices, _SSPINE_DEFAULT_MAX_VERTICES);
  4485. res.max_commands = _sspine_def(desc->max_commands, _SSPINE_DEFAULT_MAX_COMMANDS);
  4486. res.context_pool_size = _sspine_def(desc->context_pool_size, _SSPINE_DEFAULT_CONTEXT_POOL_SIZE);
  4487. res.atlas_pool_size = _sspine_def(desc->atlas_pool_size, _SSPINE_DEFAULT_ATLAS_POOL_SIZE);
  4488. res.skeleton_pool_size = _sspine_def(desc->skeleton_pool_size, _SSPINE_DEFAULT_SKELETON_POOL_SIZE);
  4489. res.skinset_pool_size = _sspine_def(desc->skinset_pool_size, _SSPINE_DEFAULT_SKINSET_POOL_SIZE);
  4490. res.instance_pool_size = _sspine_def(desc->instance_pool_size, _SSPINE_DEFAULT_INSTANCE_POOL_SIZE);
  4491. return res;
  4492. }
  4493. static sspine_context_desc _sspine_as_context_desc(const sspine_desc* desc) {
  4494. sspine_context_desc ctx_desc;
  4495. _sspine_clear(&ctx_desc, sizeof(ctx_desc));
  4496. ctx_desc.max_vertices = desc->max_vertices;
  4497. ctx_desc.max_commands = desc->max_commands;
  4498. ctx_desc.color_format = desc->color_format;
  4499. ctx_desc.depth_format = desc->depth_format;
  4500. ctx_desc.sample_count = desc->sample_count;
  4501. ctx_desc.color_write_mask = desc->color_write_mask;
  4502. return ctx_desc;
  4503. }
  4504. static sg_filter _sspine_as_sampler_filter(spAtlasFilter filter) {
  4505. switch (filter) {
  4506. case SP_ATLAS_UNKNOWN_FILTER: return _SG_FILTER_DEFAULT;
  4507. case SP_ATLAS_NEAREST: return SG_FILTER_NEAREST;
  4508. case SP_ATLAS_LINEAR: return SG_FILTER_LINEAR;
  4509. case SP_ATLAS_MIPMAP: return SG_FILTER_LINEAR;
  4510. case SP_ATLAS_MIPMAP_NEAREST_NEAREST: return SG_FILTER_NEAREST;
  4511. case SP_ATLAS_MIPMAP_LINEAR_NEAREST: return SG_FILTER_LINEAR;
  4512. case SP_ATLAS_MIPMAP_NEAREST_LINEAR: return SG_FILTER_NEAREST;
  4513. case SP_ATLAS_MIPMAP_LINEAR_LINEAR: return SG_FILTER_LINEAR;
  4514. default: return SG_FILTER_LINEAR;
  4515. }
  4516. }
  4517. static sg_filter _sspine_as_sampler_mipmap_filter(spAtlasFilter filter) {
  4518. switch (filter) {
  4519. case SP_ATLAS_UNKNOWN_FILTER:
  4520. return _SG_FILTER_DEFAULT;
  4521. case SP_ATLAS_NEAREST:
  4522. case SP_ATLAS_LINEAR:
  4523. case SP_ATLAS_MIPMAP:
  4524. case SP_ATLAS_MIPMAP_NEAREST_NEAREST:
  4525. case SP_ATLAS_MIPMAP_LINEAR_NEAREST:
  4526. return SG_FILTER_NEAREST;
  4527. case SP_ATLAS_MIPMAP_NEAREST_LINEAR:
  4528. case SP_ATLAS_MIPMAP_LINEAR_LINEAR:
  4529. return SG_FILTER_LINEAR;
  4530. default:
  4531. return SG_FILTER_NEAREST;
  4532. }
  4533. }
  4534. static sg_wrap _sspine_as_sampler_wrap(spAtlasWrap wrap) {
  4535. switch (wrap) {
  4536. case SP_ATLAS_MIRROREDREPEAT: return SG_WRAP_MIRRORED_REPEAT;
  4537. case SP_ATLAS_CLAMPTOEDGE: return SG_WRAP_CLAMP_TO_EDGE;
  4538. case SP_ATLAS_REPEAT: return SG_WRAP_REPEAT;
  4539. default: return _SG_WRAP_DEFAULT;
  4540. }
  4541. }
  4542. static void _sspine_init_image_info(const _sspine_atlas_t* atlas, int index, sspine_image_info* info, bool with_overrides) {
  4543. spAtlasPage* page = _sspine_lookup_atlas_page(atlas->slot.id, index);
  4544. SOKOL_ASSERT(page);
  4545. SOKOL_ASSERT(page->name);
  4546. info->valid = true;
  4547. info->sgimage = _sspine_image_from_renderer_object(page->rendererObject);
  4548. info->sgsampler = _sspine_sampler_from_renderer_object(page->rendererObject);
  4549. if (with_overrides && (atlas->overrides.min_filter != _SG_FILTER_DEFAULT)) {
  4550. info->min_filter = atlas->overrides.min_filter;
  4551. } else {
  4552. info->min_filter = _sspine_as_sampler_filter(page->minFilter);
  4553. }
  4554. if (with_overrides && (atlas->overrides.mag_filter != _SG_FILTER_DEFAULT)) {
  4555. info->mag_filter = atlas->overrides.mag_filter;
  4556. } else {
  4557. info->mag_filter = _sspine_as_sampler_filter(page->magFilter);
  4558. }
  4559. if (with_overrides && (atlas->overrides.mipmap_filter != _SG_FILTER_DEFAULT)) {
  4560. info->mipmap_filter = atlas->overrides.mipmap_filter;
  4561. } else {
  4562. info->mipmap_filter = _sspine_as_sampler_mipmap_filter(page->minFilter);
  4563. }
  4564. if (with_overrides && (atlas->overrides.wrap_u != _SG_WRAP_DEFAULT)) {
  4565. info->wrap_u = atlas->overrides.wrap_u;
  4566. } else {
  4567. info->wrap_u = _sspine_as_sampler_wrap(page->uWrap);
  4568. }
  4569. if (with_overrides && (atlas->overrides.wrap_v != _SG_WRAP_DEFAULT)) {
  4570. info->wrap_v = atlas->overrides.wrap_v;
  4571. } else {
  4572. info->wrap_v = _sspine_as_sampler_wrap(page->vWrap);
  4573. }
  4574. info->width = page->width;
  4575. info->height = page->height;
  4576. // NOTE: override already happened in atlas init
  4577. info->premul_alpha = page->pma != 0;
  4578. info->filename = _sspine_string(page->name);
  4579. if (info->filename.truncated) {
  4580. _SSPINE_WARN(STRING_TRUNCATED);
  4581. }
  4582. }
  4583. static void _sspine_init_shared(void) {
  4584. sg_shader_desc shd_desc;
  4585. _sspine_clear(&shd_desc, sizeof(shd_desc));
  4586. shd_desc.attrs[0].glsl_name = "position";
  4587. shd_desc.attrs[1].glsl_name = "texcoord0";
  4588. shd_desc.attrs[2].glsl_name = "color0";
  4589. shd_desc.attrs[0].hlsl_sem_name = "TEXCOORD";
  4590. shd_desc.attrs[0].hlsl_sem_index = 0;
  4591. shd_desc.attrs[1].hlsl_sem_name = "TEXCOORD";
  4592. shd_desc.attrs[1].hlsl_sem_index = 1;
  4593. shd_desc.attrs[2].hlsl_sem_name = "TEXCOORD";
  4594. shd_desc.attrs[2].hlsl_sem_index = 2;
  4595. shd_desc.uniform_blocks[0].stage = SG_SHADERSTAGE_VERTEX;
  4596. shd_desc.uniform_blocks[0].size = sizeof(_sspine_vsparams_t);
  4597. shd_desc.uniform_blocks[0].layout = SG_UNIFORMLAYOUT_STD140;
  4598. shd_desc.uniform_blocks[0].hlsl_register_b_n = 0;
  4599. shd_desc.uniform_blocks[0].msl_buffer_n = 0;
  4600. shd_desc.uniform_blocks[0].wgsl_group0_binding_n = 0;
  4601. shd_desc.uniform_blocks[0].glsl_uniforms[0].glsl_name = "vs_params";
  4602. shd_desc.uniform_blocks[0].glsl_uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
  4603. shd_desc.uniform_blocks[0].glsl_uniforms[0].array_count = 4;
  4604. shd_desc.uniform_blocks[1].stage = SG_SHADERSTAGE_FRAGMENT;
  4605. shd_desc.uniform_blocks[1].size = 16;
  4606. shd_desc.uniform_blocks[1].layout = SG_UNIFORMLAYOUT_STD140;
  4607. shd_desc.uniform_blocks[1].hlsl_register_b_n = 0;
  4608. shd_desc.uniform_blocks[1].msl_buffer_n = 0;
  4609. shd_desc.uniform_blocks[1].wgsl_group0_binding_n = 8;
  4610. shd_desc.uniform_blocks[1].glsl_uniforms[0].glsl_name = "fs_params";
  4611. shd_desc.uniform_blocks[1].glsl_uniforms[0].type = SG_UNIFORMTYPE_FLOAT4;
  4612. shd_desc.uniform_blocks[1].glsl_uniforms[0].array_count = 1;
  4613. shd_desc.images[0].stage = SG_SHADERSTAGE_FRAGMENT;
  4614. shd_desc.images[0].image_type = SG_IMAGETYPE_2D;
  4615. shd_desc.images[0].sample_type = SG_IMAGESAMPLETYPE_FLOAT;
  4616. shd_desc.images[0].hlsl_register_t_n = 0;
  4617. shd_desc.images[0].msl_texture_n = 0;
  4618. shd_desc.images[0].wgsl_group1_binding_n = 64;
  4619. shd_desc.samplers[0].stage = SG_SHADERSTAGE_FRAGMENT;
  4620. shd_desc.samplers[0].sampler_type = SG_SAMPLERTYPE_FILTERING;
  4621. shd_desc.samplers[0].hlsl_register_s_n = 0;
  4622. shd_desc.samplers[0].msl_sampler_n = 0;
  4623. shd_desc.samplers[0].wgsl_group1_binding_n = 80;
  4624. shd_desc.image_sampler_pairs[0].stage = SG_SHADERSTAGE_FRAGMENT;
  4625. shd_desc.image_sampler_pairs[0].image_slot = 0;
  4626. shd_desc.image_sampler_pairs[0].sampler_slot = 0;
  4627. shd_desc.image_sampler_pairs[0].glsl_name = "tex_smp";
  4628. shd_desc.label = "sspine-shader";
  4629. #if defined(SOKOL_GLCORE)
  4630. shd_desc.vertex_func.source = (const char*)_sspine_vs_source_glsl410;
  4631. shd_desc.fragment_func.source = (const char*)_sspine_fs_source_glsl410;
  4632. #elif defined(SOKOL_GLES3)
  4633. shd_desc.vertex_func.source = (const char*)_sspine_vs_source_glsl300es;
  4634. shd_desc.fragment_func.source = (const char*)_sspine_fs_source_glsl300es;
  4635. #elif defined(SOKOL_METAL)
  4636. shd_desc.vertex_func.entry = "main0";
  4637. shd_desc.fragment_func.entry = "main0";
  4638. switch (sg_query_backend()) {
  4639. case SG_BACKEND_METAL_MACOS:
  4640. shd_desc.vertex_func.bytecode = SG_RANGE(_sspine_vs_bytecode_metal_macos);
  4641. shd_desc.fragment_func.bytecode = SG_RANGE(_sspine_fs_bytecode_metal_macos);
  4642. break;
  4643. case SG_BACKEND_METAL_IOS:
  4644. shd_desc.vertex_func.bytecode = SG_RANGE(_sspine_vs_bytecode_metal_ios);
  4645. shd_desc.fragment_func.bytecode = SG_RANGE(_sspine_fs_bytecode_metal_ios);
  4646. break;
  4647. default:
  4648. shd_desc.vertex_func.source = (const char*)_sspine_vs_source_metal_sim;
  4649. shd_desc.fragment_func.source = (const char*)_sspine_fs_source_metal_sim;
  4650. break;
  4651. }
  4652. #elif defined(SOKOL_D3D11)
  4653. shd_desc.vertex_func.bytecode = SG_RANGE(_sspine_vs_bytecode_hlsl4);
  4654. shd_desc.fragment_func.bytecode = SG_RANGE(_sspine_fs_bytecode_hlsl4);
  4655. #elif defined(SOKOL_WGPU)
  4656. shd_desc.vertex_func.source = (const char*)_sspine_vs_source_wgsl;
  4657. shd_desc.fragment_func.source = (const char*)_sspine_fs_source_wgsl;
  4658. #else
  4659. shd_desc.vertex_func.source = _sspine_vs_source_dummy;
  4660. shd_desc.fragment_func.source = _sspine_fs_source_dummy;
  4661. #endif
  4662. _sspine.shd = sg_make_shader(&shd_desc);
  4663. }
  4664. static void _sspine_destroy_shared(void) {
  4665. sg_destroy_shader(_sspine.shd);
  4666. }
  4667. // called from inside sokol-gfx sg_commit()
  4668. static void _sspine_commit_listener_func(void* userdata) {
  4669. (void)userdata;
  4670. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4671. _sspine.frame_id++;
  4672. }
  4673. static sg_commit_listener _sspine_make_commit_listener(void) {
  4674. sg_commit_listener commit_listener = { _sspine_commit_listener_func, 0 };
  4675. return commit_listener;
  4676. }
  4677. // ██████ ██ ██ ██████ ██ ██ ██████
  4678. // ██ ██ ██ ██ ██ ██ ██ ██ ██
  4679. // ██████ ██ ██ ██████ ██ ██ ██
  4680. // ██ ██ ██ ██ ██ ██ ██ ██
  4681. // ██ ██████ ██████ ███████ ██ ██████
  4682. //
  4683. // >>public
  4684. SOKOL_API_IMPL void sspine_setup(const sspine_desc* desc) {
  4685. SOKOL_ASSERT(desc);
  4686. spBone_setYDown(1);
  4687. _sspine_clear(&_sspine, sizeof(_sspine));
  4688. _sspine.init_cookie = _SSPINE_INIT_COOKIE;
  4689. _sspine.desc = _sspine_desc_defaults(desc);
  4690. _sspine_init_shared();
  4691. // important, need to setup the frame id with a non-zero value,
  4692. // otherwise updates won't trigger in the first frame
  4693. _sspine.frame_id = 1;
  4694. _sspine_setup_context_pool(_sspine.desc.context_pool_size);
  4695. _sspine_setup_atlas_pool(_sspine.desc.atlas_pool_size);
  4696. _sspine_setup_skeleton_pool(_sspine.desc.skeleton_pool_size);
  4697. _sspine_setup_skinset_pool(_sspine.desc.skinset_pool_size);
  4698. _sspine_setup_instance_pool(_sspine.desc.instance_pool_size);
  4699. const sspine_context_desc ctx_desc = _sspine_as_context_desc(&_sspine.desc);
  4700. _sspine.def_ctx_id = sspine_make_context(&ctx_desc);
  4701. SOKOL_ASSERT(_sspine_is_default_context(_sspine.def_ctx_id));
  4702. sspine_set_context(_sspine.def_ctx_id);
  4703. if (!sg_add_commit_listener(_sspine_make_commit_listener())) {
  4704. _SSPINE_ERROR(ADD_COMMIT_LISTENER_FAILED);
  4705. }
  4706. }
  4707. SOKOL_API_IMPL void sspine_shutdown(void) {
  4708. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4709. sg_remove_commit_listener(_sspine_make_commit_listener());
  4710. _sspine_destroy_all_instances();
  4711. _sspine_destroy_all_skinsets();
  4712. _sspine_destroy_all_skeletons();
  4713. _sspine_destroy_all_atlases();
  4714. _sspine_destroy_all_contexts();
  4715. _sspine_discard_instance_pool();
  4716. _sspine_discard_skinset_pool();
  4717. _sspine_discard_skeleton_pool();
  4718. _sspine_discard_atlas_pool();
  4719. _sspine_discard_context_pool();
  4720. _sspine_destroy_shared();
  4721. _sspine.init_cookie = 0;
  4722. }
  4723. SOKOL_API_IMPL sspine_context sspine_make_context(const sspine_context_desc* desc) {
  4724. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4725. SOKOL_ASSERT(desc);
  4726. const sspine_context_desc desc_def = _sspine_context_desc_defaults(desc);
  4727. sspine_context ctx_id = _sspine_alloc_context();
  4728. _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  4729. if (ctx) {
  4730. ctx->slot.state = _sspine_init_context(ctx, &desc_def);
  4731. SOKOL_ASSERT((ctx->slot.state == SSPINE_RESOURCESTATE_VALID) || (ctx->slot.state == SSPINE_RESOURCESTATE_FAILED));
  4732. if (ctx->slot.state == SSPINE_RESOURCESTATE_FAILED) {
  4733. _sspine_deinit_context(ctx);
  4734. }
  4735. } else {
  4736. ctx->slot.state = SSPINE_RESOURCESTATE_FAILED;
  4737. _SSPINE_ERROR(CONTEXT_POOL_EXHAUSTED);
  4738. }
  4739. return ctx_id;
  4740. }
  4741. SOKOL_API_IMPL void sspine_destroy_context(sspine_context ctx_id) {
  4742. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4743. if (_sspine_is_default_context(ctx_id)) {
  4744. _SSPINE_ERROR(CANNOT_DESTROY_DEFAULT_CONTEXT);
  4745. return;
  4746. }
  4747. _sspine_destroy_context(ctx_id);
  4748. // re-validate the current context pointer (this will return a nullptr
  4749. // if we just destroyed the current context)
  4750. _sspine.cur_ctx = _sspine_lookup_context(_sspine.cur_ctx_id.id);
  4751. }
  4752. SOKOL_API_IMPL void sspine_set_context(sspine_context ctx_id) {
  4753. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4754. if (_sspine_is_default_context(ctx_id)) {
  4755. _sspine.cur_ctx_id = _sspine.def_ctx_id;
  4756. } else {
  4757. _sspine.cur_ctx_id = ctx_id;
  4758. }
  4759. // this will return null if the handle isn't valid
  4760. _sspine.cur_ctx = _sspine_lookup_context(_sspine.cur_ctx_id.id);
  4761. }
  4762. SOKOL_API_IMPL sspine_context sspine_get_context(void) {
  4763. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4764. return _sspine.cur_ctx_id;
  4765. }
  4766. SOKOL_API_IMPL sspine_context sspine_default_context(void) {
  4767. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4768. return _sspine_make_context_handle(0x00010001);
  4769. }
  4770. SOKOL_API_IMPL sspine_context_info sspine_get_context_info(sspine_context ctx_id) {
  4771. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4772. sspine_context_info res;
  4773. _sspine_clear(&res, sizeof(res));
  4774. const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  4775. if (ctx) {
  4776. res.num_vertices = ctx->vertices.next;
  4777. res.num_indices = ctx->indices.next;
  4778. res.num_commands = ctx->commands.next;
  4779. }
  4780. return res;
  4781. }
  4782. SOKOL_API_IMPL void sspine_set_skinset(sspine_instance instance_id, sspine_skinset skinset_id) {
  4783. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4784. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4785. _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
  4786. if (_sspine_instance_and_deps_valid(instance) && _sspine_skinset_and_deps_valid(skinset) && (instance->skel.id == skinset->skel.id)) {
  4787. SOKOL_ASSERT(instance->sp_skel);
  4788. SOKOL_ASSERT(instance->sp_anim_state);
  4789. SOKOL_ASSERT(skinset->sp_skin);
  4790. spSkeleton_setSkin(instance->sp_skel, 0);
  4791. spSkeleton_setSkin(instance->sp_skel, skinset->sp_skin);
  4792. spSkeleton_setSlotsToSetupPose(instance->sp_skel);
  4793. spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
  4794. }
  4795. }
  4796. SOKOL_API_IMPL void sspine_update_instance(sspine_instance instance_id, float delta_time) {
  4797. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4798. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4799. if (_sspine_instance_and_deps_valid(instance)) {
  4800. SOKOL_ASSERT(instance->sp_skel);
  4801. SOKOL_ASSERT(instance->sp_anim_state);
  4802. _sspine_rewind_triggered_events(instance);
  4803. spAnimationState_update(instance->sp_anim_state, delta_time);
  4804. spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
  4805. spSkeleton_update(instance->sp_skel, delta_time);
  4806. spSkeleton_updateWorldTransform(instance->sp_skel, SP_PHYSICS_UPDATE);
  4807. }
  4808. }
  4809. SOKOL_API_IMPL int sspine_num_triggered_events(sspine_instance instance_id) {
  4810. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4811. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4812. if (_sspine_instance_and_deps_valid(instance)) {
  4813. SOKOL_ASSERT((instance->cur_triggered_event_index >= 0) && (instance->cur_triggered_event_index <= _SSPINE_MAX_TRIGGERED_EVENTS));
  4814. return instance->cur_triggered_event_index;
  4815. }
  4816. return 0;
  4817. }
  4818. SOKOL_API_IMPL sspine_triggered_event_info sspine_get_triggered_event_info(sspine_instance instance_id, int triggered_event_index) {
  4819. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4820. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4821. sspine_triggered_event_info res;
  4822. _sspine_clear(&res, sizeof(res));
  4823. if (_sspine_instance_and_deps_valid(instance)) {
  4824. if ((triggered_event_index >= 0) && (triggered_event_index < instance->cur_triggered_event_index)) {
  4825. res = instance->triggered_events[triggered_event_index];
  4826. }
  4827. }
  4828. return res;
  4829. }
  4830. SOKOL_API_IMPL void sspine_draw_instance_in_layer(sspine_instance instance_id, int layer) {
  4831. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4832. _sspine_context_t* ctx = _sspine.cur_ctx;
  4833. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4834. if (ctx && _sspine_instance_and_deps_valid(instance)) {
  4835. _sspine_draw_instance(ctx, instance, layer);
  4836. }
  4837. }
  4838. SOKOL_API_IMPL sspine_mat4 sspine_layer_transform_to_mat4(const sspine_layer_transform* tform) {
  4839. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4840. sspine_mat4 res;
  4841. _sspine_layer_transform_to_proj(tform, res.m);
  4842. return res;
  4843. }
  4844. SOKOL_API_IMPL void sspine_context_draw_instance_in_layer(sspine_context ctx_id, sspine_instance instance_id, int layer) {
  4845. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4846. _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  4847. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4848. if (ctx && _sspine_instance_and_deps_valid(instance)) {
  4849. _sspine_draw_instance(ctx, instance, layer);
  4850. }
  4851. }
  4852. SOKOL_API_IMPL void sspine_draw_layer(int layer, const sspine_layer_transform* tform) {
  4853. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4854. SOKOL_ASSERT(tform);
  4855. _sspine_context_t* ctx = _sspine.cur_ctx;
  4856. if (ctx) {
  4857. _sspine_draw_layer(ctx, layer, tform);
  4858. }
  4859. }
  4860. SOKOL_API_IMPL void sspine_context_draw_layer(sspine_context ctx_id, int layer, const sspine_layer_transform* tform) {
  4861. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4862. SOKOL_ASSERT(tform);
  4863. _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  4864. if (ctx) {
  4865. _sspine_draw_layer(ctx, layer, tform);
  4866. }
  4867. }
  4868. SOKOL_API_IMPL sspine_atlas sspine_make_atlas(const sspine_atlas_desc* desc) {
  4869. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4870. SOKOL_ASSERT(desc);
  4871. const sspine_atlas_desc desc_def = _sspine_atlas_desc_defaults(desc);
  4872. sspine_atlas atlas_id = _sspine_alloc_atlas();
  4873. _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
  4874. if (atlas) {
  4875. atlas->slot.state = _sspine_init_atlas(atlas, &desc_def);
  4876. SOKOL_ASSERT((atlas->slot.state == SSPINE_RESOURCESTATE_VALID) || (atlas->slot.state == SSPINE_RESOURCESTATE_FAILED));
  4877. if (atlas->slot.state == SSPINE_RESOURCESTATE_FAILED) {
  4878. _sspine_deinit_atlas(atlas);
  4879. }
  4880. } else {
  4881. _SSPINE_ERROR(ATLAS_POOL_EXHAUSTED);
  4882. }
  4883. return atlas_id;
  4884. }
  4885. SOKOL_API_IMPL void sspine_destroy_atlas(sspine_atlas atlas_id) {
  4886. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4887. _sspine_destroy_atlas(atlas_id);
  4888. }
  4889. SOKOL_API_IMPL sspine_skeleton sspine_make_skeleton(const sspine_skeleton_desc* desc) {
  4890. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4891. SOKOL_ASSERT(desc);
  4892. const sspine_skeleton_desc desc_def = _sspine_skeleton_desc_defaults(desc);
  4893. sspine_skeleton skeleton_id = _sspine_alloc_skeleton();
  4894. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  4895. if (skeleton) {
  4896. skeleton->slot.state = _sspine_init_skeleton(skeleton, &desc_def);
  4897. SOKOL_ASSERT((skeleton->slot.state == SSPINE_RESOURCESTATE_VALID) || (skeleton->slot.state == SSPINE_RESOURCESTATE_FAILED));
  4898. if (skeleton->slot.state == SSPINE_RESOURCESTATE_FAILED) {
  4899. _sspine_deinit_skeleton(skeleton);
  4900. }
  4901. } else {
  4902. _SSPINE_ERROR(SKELETON_POOL_EXHAUSTED);
  4903. }
  4904. return skeleton_id;
  4905. }
  4906. SOKOL_API_IMPL void sspine_destroy_skeleton(sspine_skeleton skeleton_id) {
  4907. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4908. _sspine_destroy_skeleton(skeleton_id);
  4909. }
  4910. SOKOL_API_IMPL sspine_skinset sspine_make_skinset(const sspine_skinset_desc* desc) {
  4911. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4912. SOKOL_ASSERT(desc);
  4913. const sspine_skinset_desc desc_def = _sspine_skinset_desc_defaults(desc);
  4914. sspine_skinset skinset_id = _sspine_alloc_skinset();
  4915. _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
  4916. if (skinset) {
  4917. skinset->slot.state = _sspine_init_skinset(skinset, &desc_def);
  4918. SOKOL_ASSERT((skinset->slot.state == SSPINE_RESOURCESTATE_VALID) || (skinset->slot.state == SSPINE_RESOURCESTATE_FAILED));
  4919. if (skinset->slot.state == SSPINE_RESOURCESTATE_FAILED) {
  4920. _sspine_deinit_skinset(skinset);
  4921. }
  4922. } else {
  4923. _SSPINE_ERROR(SKINSET_POOL_EXHAUSTED);
  4924. }
  4925. return skinset_id;
  4926. }
  4927. SOKOL_API_IMPL void sspine_destroy_skinset(sspine_skinset skinset_id) {
  4928. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4929. _sspine_destroy_skinset(skinset_id);
  4930. }
  4931. SOKOL_API_IMPL sspine_instance sspine_make_instance(const sspine_instance_desc* desc) {
  4932. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4933. SOKOL_ASSERT(desc);
  4934. const sspine_instance_desc desc_def = _sspine_instance_desc_defaults(desc);
  4935. sspine_instance instance_id = _sspine_alloc_instance();
  4936. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4937. if (instance) {
  4938. instance->slot.state = _sspine_init_instance(instance, &desc_def);
  4939. SOKOL_ASSERT((instance->slot.state == SSPINE_RESOURCESTATE_VALID) || (instance->slot.state == SSPINE_RESOURCESTATE_FAILED));
  4940. if (instance->slot.state == SSPINE_RESOURCESTATE_FAILED) {
  4941. _sspine_deinit_instance(instance);
  4942. }
  4943. } else {
  4944. _SSPINE_ERROR(INSTANCE_POOL_EXHAUSTED);
  4945. }
  4946. return instance_id;
  4947. }
  4948. SOKOL_API_IMPL void sspine_destroy_instance(sspine_instance instance_id) {
  4949. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4950. _sspine_destroy_instance(instance_id);
  4951. }
  4952. SOKOL_API_IMPL sspine_resource_state sspine_get_context_resource_state(sspine_context ctx_id) {
  4953. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4954. const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
  4955. if (ctx) {
  4956. return ctx->slot.state;
  4957. } else {
  4958. return SSPINE_RESOURCESTATE_INVALID;
  4959. }
  4960. }
  4961. SOKOL_API_IMPL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas_id) {
  4962. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4963. const _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
  4964. if (atlas) {
  4965. return atlas->slot.state;
  4966. } else {
  4967. return SSPINE_RESOURCESTATE_INVALID;
  4968. }
  4969. }
  4970. SOKOL_API_IMPL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton_id) {
  4971. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4972. const _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  4973. if (skeleton) {
  4974. return skeleton->slot.state;
  4975. } else {
  4976. return SSPINE_RESOURCESTATE_INVALID;
  4977. }
  4978. }
  4979. SOKOL_API_IMPL sspine_resource_state sspine_get_skinset_resource_state(sspine_skinset skinset_id) {
  4980. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4981. const _sspine_skinset_t* skinset = _sspine_lookup_skinset(skinset_id.id);
  4982. if (skinset) {
  4983. return skinset->slot.state;
  4984. } else {
  4985. return SSPINE_RESOURCESTATE_INVALID;
  4986. }
  4987. }
  4988. SOKOL_API_IMPL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance_id) {
  4989. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4990. const _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  4991. if (instance) {
  4992. return instance->slot.state;
  4993. } else {
  4994. return SSPINE_RESOURCESTATE_INVALID;
  4995. }
  4996. }
  4997. SOKOL_API_IMPL bool sspine_context_valid(sspine_context ctx_id) {
  4998. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  4999. return sspine_get_context_resource_state(ctx_id) == SSPINE_RESOURCESTATE_VALID;
  5000. }
  5001. SOKOL_API_IMPL bool sspine_atlas_valid(sspine_atlas atlas_id) {
  5002. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5003. return sspine_get_atlas_resource_state(atlas_id) == SSPINE_RESOURCESTATE_VALID;
  5004. }
  5005. SOKOL_API_IMPL bool sspine_skeleton_valid(sspine_skeleton skeleton_id) {
  5006. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5007. return sspine_get_skeleton_resource_state(skeleton_id) == SSPINE_RESOURCESTATE_VALID;
  5008. }
  5009. SOKOL_API_IMPL bool sspine_skinset_valid(sspine_skinset skinset_id) {
  5010. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5011. return sspine_get_skinset_resource_state(skinset_id) == SSPINE_RESOURCESTATE_VALID;
  5012. }
  5013. SOKOL_API_IMPL bool sspine_instance_valid(sspine_instance instance_id) {
  5014. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5015. return sspine_get_instance_resource_state(instance_id) == SSPINE_RESOURCESTATE_VALID;
  5016. }
  5017. SOKOL_API_IMPL sspine_atlas sspine_get_skeleton_atlas(sspine_skeleton skeleton_id) {
  5018. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5019. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5020. sspine_atlas res;
  5021. _sspine_clear(&res, sizeof(res));
  5022. if (skeleton) {
  5023. res.id = skeleton->atlas.id;
  5024. }
  5025. return res;
  5026. }
  5027. SOKOL_API_IMPL sspine_skeleton sspine_get_instance_skeleton(sspine_instance instance_id) {
  5028. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5029. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5030. sspine_skeleton res;
  5031. _sspine_clear(&res, sizeof(res));
  5032. if (instance) {
  5033. res.id = instance->skel.id;
  5034. }
  5035. return res;
  5036. }
  5037. SOKOL_API_IMPL int sspine_num_images(sspine_atlas atlas_id) {
  5038. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5039. _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
  5040. if (atlas) {
  5041. return atlas->num_pages;
  5042. }
  5043. return 0;
  5044. }
  5045. SOKOL_API_IMPL sspine_image sspine_image_by_index(sspine_atlas atlas_id, int index) {
  5046. return _sspine_image(atlas_id.id, index);
  5047. }
  5048. SOKOL_API_IMPL bool sspine_image_valid(sspine_image image) {
  5049. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5050. _sspine_atlas_t* atlas = _sspine_lookup_atlas(image.atlas_id);
  5051. return atlas && (image.index >= 0) && (image.index < atlas->num_pages);
  5052. }
  5053. SOKOL_API_IMPL bool sspine_image_equal(sspine_image first, sspine_image second) {
  5054. return (first.atlas_id == second.atlas_id) && (first.index == second.index);
  5055. }
  5056. SOKOL_API_IMPL sspine_image_info sspine_get_image_info(sspine_image image) {
  5057. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5058. _sspine_atlas_t* atlas = _sspine_lookup_atlas(image.atlas_id);
  5059. sspine_image_info img_info;
  5060. _sspine_clear(&img_info, sizeof(img_info));
  5061. if (atlas && (image.index >= 0) && (image.index < atlas->num_pages)) {
  5062. _sspine_init_image_info(atlas, image.index, &img_info, true);
  5063. }
  5064. return img_info;
  5065. }
  5066. SOKOL_API_IMPL int sspine_num_atlas_pages(sspine_atlas atlas_id) {
  5067. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5068. _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
  5069. if (atlas) {
  5070. return atlas->num_pages;
  5071. } else {
  5072. return 0;
  5073. }
  5074. }
  5075. SOKOL_API_IMPL sspine_atlas_page sspine_atlas_page_by_index(sspine_atlas atlas_id, int index) {
  5076. return _sspine_atlas_page(atlas_id.id, index);
  5077. }
  5078. SOKOL_API_IMPL bool sspine_atlas_page_valid(sspine_atlas_page page) {
  5079. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5080. _sspine_atlas_t* atlas = _sspine_lookup_atlas(page.atlas_id);
  5081. if (atlas) {
  5082. return (page.index >= 0) && (page.index < atlas->num_pages);
  5083. }
  5084. return false;
  5085. }
  5086. SOKOL_API_IMPL bool sspine_atlas_page_equal(sspine_atlas_page first, sspine_atlas_page second) {
  5087. return (first.atlas_id == second.atlas_id) && (first.index == second.index);
  5088. }
  5089. SOKOL_API_IMPL sspine_atlas_page_info sspine_get_atlas_page_info(sspine_atlas_page page) {
  5090. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5091. sspine_atlas_page_info res;
  5092. _sspine_clear(&res, sizeof(res));
  5093. const spAtlasPage* sp_page = _sspine_lookup_atlas_page(page.atlas_id, page.index);
  5094. if (sp_page) {
  5095. // at this point, atlas is guaranteed to be valid
  5096. const _sspine_atlas_t* atlas = _sspine_lookup_atlas(page.atlas_id);
  5097. res.valid = true;
  5098. res.atlas.id = page.atlas_id;
  5099. // write image info without overrides
  5100. _sspine_init_image_info(atlas, page.index, &res.image, false);
  5101. // ...and provide the overrides separately
  5102. res.overrides = atlas->overrides;
  5103. }
  5104. return res;
  5105. }
  5106. SOKOL_API_IMPL void sspine_set_position(sspine_instance instance_id, sspine_vec2 position) {
  5107. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5108. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5109. if (_sspine_instance_and_deps_valid(instance)) {
  5110. SOKOL_ASSERT(instance->sp_skel);
  5111. instance->sp_skel->x = position.x;
  5112. instance->sp_skel->y = position.y;
  5113. }
  5114. }
  5115. SOKOL_API_IMPL void sspine_set_scale(sspine_instance instance_id, sspine_vec2 scale) {
  5116. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5117. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5118. if (instance) {
  5119. SOKOL_ASSERT(instance->sp_skel);
  5120. instance->sp_skel->scaleX = scale.x;
  5121. instance->sp_skel->scaleY = scale.y;
  5122. }
  5123. }
  5124. SOKOL_API_IMPL void sspine_set_color(sspine_instance instance_id, sspine_color color) {
  5125. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5126. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5127. if (instance) {
  5128. SOKOL_ASSERT(instance->sp_skel);
  5129. instance->sp_skel->color.r = color.r;
  5130. instance->sp_skel->color.g = color.g;
  5131. instance->sp_skel->color.b = color.b;
  5132. instance->sp_skel->color.a = color.a;
  5133. }
  5134. }
  5135. SOKOL_API_IMPL sspine_vec2 sspine_get_position(sspine_instance instance_id) {
  5136. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5137. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5138. sspine_vec2 v = { 0.0f, 0.0f };
  5139. if (instance) {
  5140. SOKOL_ASSERT(instance->sp_skel);
  5141. v.x = instance->sp_skel->x;
  5142. v.y = instance->sp_skel->y;
  5143. }
  5144. return v;
  5145. }
  5146. SOKOL_API_IMPL sspine_vec2 sspine_get_scale(sspine_instance instance_id) {
  5147. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5148. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5149. sspine_vec2 v = { 0.0f, 0.0f };
  5150. if (instance) {
  5151. SOKOL_ASSERT(instance->sp_skel);
  5152. v.x = instance->sp_skel->scaleX;
  5153. v.y = instance->sp_skel->scaleY;
  5154. }
  5155. return v;
  5156. }
  5157. SOKOL_API_IMPL sspine_color sspine_get_color(sspine_instance instance_id) {
  5158. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5159. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5160. sspine_color c = { 0.0f, 0.0f, 0.0f, 0.0f };
  5161. if (instance) {
  5162. SOKOL_ASSERT(instance->sp_skel);
  5163. c.r = instance->sp_skel->color.r;
  5164. c.g = instance->sp_skel->color.g;
  5165. c.b = instance->sp_skel->color.b;
  5166. c.a = instance->sp_skel->color.a;
  5167. }
  5168. return c;
  5169. }
  5170. SOKOL_API_IMPL int sspine_num_anims(sspine_skeleton skeleton_id) {
  5171. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5172. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5173. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5174. SOKOL_ASSERT(skeleton->sp_skel_data);
  5175. return skeleton->sp_skel_data->animationsCount;
  5176. }
  5177. return 0;
  5178. }
  5179. SOKOL_API_IMPL sspine_anim sspine_anim_by_name(sspine_skeleton skeleton_id, const char* name) {
  5180. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5181. SOKOL_ASSERT(name);
  5182. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5183. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5184. // NOTE: there's a spSkeletonData_findAnimation function, but that doesn't
  5185. // give us access to the index, so we'll need to do the loop ourselves
  5186. SOKOL_ASSERT(skeleton->sp_skel_data);
  5187. const spSkeletonData* sp_skel_data = skeleton->sp_skel_data;
  5188. const int num_anims = sp_skel_data->animationsCount;
  5189. SOKOL_ASSERT(sp_skel_data->animations);
  5190. for (int i = 0; i < num_anims; i++) {
  5191. SOKOL_ASSERT(sp_skel_data->animations[i]);
  5192. SOKOL_ASSERT(sp_skel_data->animations[i]->name);
  5193. if (0 == strcmp(sp_skel_data->animations[i]->name, name)) {
  5194. return _sspine_anim(skeleton_id.id, i);
  5195. }
  5196. }
  5197. }
  5198. return _sspine_anim(0, 0);
  5199. }
  5200. SOKOL_API_IMPL sspine_anim sspine_anim_by_index(sspine_skeleton skeleton_id, int index) {
  5201. return _sspine_anim(skeleton_id.id, index);
  5202. }
  5203. SOKOL_API_IMPL bool sspine_anim_valid(sspine_anim anim) {
  5204. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5205. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(anim.skeleton_id);
  5206. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5207. SOKOL_ASSERT(skeleton->sp_skel_data);
  5208. return (anim.index >= 0) && (anim.index < skeleton->sp_skel_data->animationsCount);
  5209. }
  5210. return false;
  5211. }
  5212. SOKOL_API_IMPL bool sspine_anim_equal(sspine_anim first, sspine_anim second) {
  5213. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5214. }
  5215. SOKOL_API_IMPL sspine_anim_info sspine_get_anim_info(sspine_anim anim) {
  5216. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5217. sspine_anim_info res;
  5218. _sspine_clear(&res, sizeof(res));
  5219. const spAnimation* sp_anim = _sspine_lookup_skeleton_anim(anim.skeleton_id, anim.index);
  5220. if (sp_anim) {
  5221. res.valid = true;
  5222. res.index = anim.index;
  5223. res.duration = sp_anim->duration;
  5224. res.name = _sspine_string(sp_anim->name);
  5225. if (res.name.truncated) {
  5226. _SSPINE_WARN(STRING_TRUNCATED);
  5227. }
  5228. }
  5229. return res;
  5230. }
  5231. SOKOL_API_IMPL void sspine_clear_animation_tracks(sspine_instance instance_id) {
  5232. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5233. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5234. if (_sspine_instance_and_deps_valid(instance)) {
  5235. SOKOL_ASSERT(instance->sp_anim_state);
  5236. spAnimationState_clearTracks(instance->sp_anim_state);
  5237. }
  5238. }
  5239. SOKOL_API_IMPL void sspine_clear_animation_track(sspine_instance instance_id, int track_index) {
  5240. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5241. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5242. if (_sspine_instance_and_deps_valid(instance)) {
  5243. SOKOL_ASSERT(instance->sp_anim_state);
  5244. spAnimationState_clearTrack(instance->sp_anim_state, track_index);
  5245. }
  5246. }
  5247. SOKOL_API_IMPL void sspine_set_animation(sspine_instance instance_id, sspine_anim anim, int track_index, bool loop) {
  5248. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5249. spAnimation* sp_anim = _sspine_lookup_instance_anim(instance_id.id, anim.skeleton_id, anim.index);
  5250. if (sp_anim) {
  5251. // NOTE: at this point, instance is guaranteed to be valid
  5252. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5253. SOKOL_ASSERT(instance);
  5254. spAnimationState_setAnimation(instance->sp_anim_state, track_index, sp_anim, loop?1:0);
  5255. }
  5256. }
  5257. SOKOL_API_IMPL void sspine_add_animation(sspine_instance instance_id, sspine_anim anim, int track_index, bool loop, float delay) {
  5258. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5259. spAnimation* sp_anim = _sspine_lookup_instance_anim(instance_id.id, anim.skeleton_id, anim.index);
  5260. if (sp_anim) {
  5261. // NOTE: at this point, instance is guaranteed to be valid
  5262. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5263. SOKOL_ASSERT(instance);
  5264. SOKOL_ASSERT(instance->sp_anim_state);
  5265. spAnimationState_addAnimation(instance->sp_anim_state, track_index, sp_anim, loop?1:0, delay);
  5266. }
  5267. }
  5268. SOKOL_API_IMPL void sspine_set_empty_animation(sspine_instance instance_id, int track_index, float mix_duration) {
  5269. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5270. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5271. if (_sspine_instance_and_deps_valid(instance)) {
  5272. SOKOL_ASSERT(instance->sp_anim_state);
  5273. spAnimationState_setEmptyAnimation(instance->sp_anim_state, track_index, mix_duration);
  5274. }
  5275. }
  5276. SOKOL_API_IMPL void sspine_add_empty_animation(sspine_instance instance_id, int track_index, float mix_duration, float delay) {
  5277. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5278. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5279. if (_sspine_instance_and_deps_valid(instance)) {
  5280. SOKOL_ASSERT(instance->sp_anim_state);
  5281. spAnimationState_addEmptyAnimation(instance->sp_anim_state, track_index, mix_duration, delay);
  5282. }
  5283. }
  5284. SOKOL_API_IMPL int sspine_num_bones(sspine_skeleton skeleton_id) {
  5285. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5286. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5287. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5288. SOKOL_ASSERT(skeleton->sp_skel_data);
  5289. return skeleton->sp_skel_data->bonesCount;
  5290. }
  5291. return 0;
  5292. }
  5293. SOKOL_API_IMPL sspine_bone sspine_bone_by_name(sspine_skeleton skeleton_id, const char* name) {
  5294. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5295. SOKOL_ASSERT(name);
  5296. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5297. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5298. SOKOL_ASSERT(skeleton->sp_skel_data);
  5299. spBoneData* sp_bone_data = spSkeletonData_findBone(skeleton->sp_skel_data, name);
  5300. if (sp_bone_data) {
  5301. return _sspine_bone(skeleton_id.id, sp_bone_data->index);
  5302. }
  5303. }
  5304. return _sspine_bone(0, 0);
  5305. }
  5306. SOKOL_API_IMPL sspine_bone sspine_bone_by_index(sspine_skeleton skeleton_id, int index) {
  5307. return _sspine_bone(skeleton_id.id, index);
  5308. }
  5309. SOKOL_API_IMPL bool sspine_bone_valid(sspine_bone bone) {
  5310. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5311. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(bone.skeleton_id);
  5312. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5313. SOKOL_ASSERT(skeleton->sp_skel_data);
  5314. return (bone.index >= 0) && (bone.index < skeleton->sp_skel_data->bonesCount);
  5315. }
  5316. return false;
  5317. }
  5318. SOKOL_API_IMPL bool sspine_bone_equal(sspine_bone first, sspine_bone second) {
  5319. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5320. }
  5321. SOKOL_API_IMPL sspine_bone_info sspine_get_bone_info(sspine_bone bone) {
  5322. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5323. sspine_bone_info res;
  5324. _sspine_clear(&res, sizeof(res));
  5325. const spBoneData* sp_bone_data = _sspine_lookup_bone_data(bone.skeleton_id, bone.index);
  5326. if (sp_bone_data) {
  5327. SOKOL_ASSERT(sp_bone_data->index == bone.index);
  5328. SOKOL_ASSERT(sp_bone_data->name);
  5329. res.valid = true;
  5330. res.index = sp_bone_data->index;
  5331. if (sp_bone_data->parent) {
  5332. res.parent_bone = _sspine_bone(bone.skeleton_id, sp_bone_data->parent->index);
  5333. }
  5334. res.length = sp_bone_data->length;
  5335. res.pose.position.x = sp_bone_data->x;
  5336. res.pose.position.y = sp_bone_data->y;
  5337. res.pose.rotation = sp_bone_data->rotation;
  5338. res.pose.scale.x = sp_bone_data->scaleX;
  5339. res.pose.scale.y = sp_bone_data->scaleY;
  5340. res.pose.shear.x = sp_bone_data->shearX;
  5341. res.pose.shear.y = sp_bone_data->shearY;
  5342. res.color.r = sp_bone_data->color.r;
  5343. res.color.g = sp_bone_data->color.g;
  5344. res.color.b = sp_bone_data->color.b;
  5345. res.color.a = sp_bone_data->color.a;
  5346. res.name = _sspine_string(sp_bone_data->name);
  5347. if (res.name.truncated) {
  5348. _SSPINE_WARN(STRING_TRUNCATED);
  5349. }
  5350. }
  5351. return res;
  5352. }
  5353. SOKOL_API_IMPL void sspine_set_bone_transform(sspine_instance instance_id, sspine_bone bone, const sspine_bone_transform* transform) {
  5354. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5355. SOKOL_ASSERT(transform);
  5356. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5357. if (sp_bone) {
  5358. sp_bone->x = transform->position.x;
  5359. sp_bone->y = transform->position.y;
  5360. sp_bone->rotation = transform->rotation;
  5361. sp_bone->scaleX = transform->scale.x;
  5362. sp_bone->scaleY = transform->scale.y;
  5363. sp_bone->shearX = transform->shear.x;
  5364. sp_bone->shearY = transform->shear.y;
  5365. }
  5366. }
  5367. SOKOL_API_IMPL void sspine_set_bone_position(sspine_instance instance_id, sspine_bone bone, sspine_vec2 position) {
  5368. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5369. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5370. if (sp_bone) {
  5371. sp_bone->x = position.x;
  5372. sp_bone->y = position.y;
  5373. }
  5374. }
  5375. SOKOL_API_IMPL void sspine_set_bone_rotation(sspine_instance instance_id, sspine_bone bone, float rotation) {
  5376. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5377. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5378. if (sp_bone) {
  5379. sp_bone->rotation = rotation;
  5380. }
  5381. }
  5382. SOKOL_API_IMPL void sspine_set_bone_scale(sspine_instance instance_id, sspine_bone bone, sspine_vec2 scale) {
  5383. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5384. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5385. if (sp_bone) {
  5386. sp_bone->scaleX = scale.x;
  5387. sp_bone->scaleY = scale.y;
  5388. }
  5389. }
  5390. SOKOL_API_IMPL void sspine_set_bone_shear(sspine_instance instance_id, sspine_bone bone, sspine_vec2 shear) {
  5391. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5392. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5393. if (sp_bone) {
  5394. sp_bone->shearX = shear.x;
  5395. sp_bone->shearY = shear.y;
  5396. }
  5397. }
  5398. SOKOL_API_IMPL sspine_bone_transform sspine_get_bone_transform(sspine_instance instance_id, sspine_bone bone) {
  5399. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5400. sspine_bone_transform res;
  5401. _sspine_clear(&res, sizeof(res));
  5402. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5403. if (sp_bone) {
  5404. res.position.x = sp_bone->x;
  5405. res.position.y = sp_bone->y;
  5406. res.rotation = sp_bone->rotation;
  5407. res.scale.x = sp_bone->scaleX;
  5408. res.scale.y = sp_bone->scaleY;
  5409. res.shear.x = sp_bone->shearX;
  5410. res.shear.y = sp_bone->shearY;
  5411. }
  5412. return res;
  5413. }
  5414. SOKOL_API_IMPL sspine_vec2 sspine_get_bone_position(sspine_instance instance_id, sspine_bone bone) {
  5415. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5416. sspine_vec2 res;
  5417. _sspine_clear(&res, sizeof(res));
  5418. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5419. if (sp_bone) {
  5420. res.x = sp_bone->x;
  5421. res.y = sp_bone->y;
  5422. }
  5423. return res;
  5424. }
  5425. SOKOL_API_IMPL float sspine_get_bone_rotation(sspine_instance instance_id, sspine_bone bone) {
  5426. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5427. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5428. if (sp_bone) {
  5429. return sp_bone->rotation;
  5430. } else {
  5431. return 0.0f;
  5432. }
  5433. }
  5434. SOKOL_API_IMPL sspine_vec2 sspine_get_bone_scale(sspine_instance instance_id, sspine_bone bone) {
  5435. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5436. sspine_vec2 res;
  5437. _sspine_clear(&res, sizeof(res));
  5438. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5439. if (sp_bone) {
  5440. res.x = sp_bone->scaleX;
  5441. res.y = sp_bone->scaleY;
  5442. }
  5443. return res;
  5444. }
  5445. SOKOL_API_IMPL sspine_vec2 sspine_get_bone_shear(sspine_instance instance_id, sspine_bone bone) {
  5446. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5447. sspine_vec2 res;
  5448. _sspine_clear(&res, sizeof(res));
  5449. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5450. if (sp_bone) {
  5451. res.x = sp_bone->shearX;
  5452. res.y = sp_bone->shearY;
  5453. }
  5454. return res;
  5455. }
  5456. SOKOL_API_IMPL sspine_vec2 sspine_get_bone_world_position(sspine_instance instance_id, sspine_bone bone) {
  5457. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5458. sspine_vec2 res;
  5459. _sspine_clear(&res, sizeof(res));
  5460. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5461. if (sp_bone) {
  5462. res.x = sp_bone->worldX;
  5463. res.y = sp_bone->worldY;
  5464. }
  5465. return res;
  5466. }
  5467. SOKOL_API_IMPL sspine_vec2 sspine_bone_local_to_world(sspine_instance instance_id, sspine_bone bone, sspine_vec2 local_pos) {
  5468. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5469. sspine_vec2 res;
  5470. _sspine_clear(&res, sizeof(res));
  5471. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5472. if (sp_bone) {
  5473. spBone_localToWorld(sp_bone, local_pos.x, local_pos.y, &res.x, &res.y);
  5474. }
  5475. return res;
  5476. }
  5477. SOKOL_API_IMPL sspine_vec2 sspine_bone_world_to_local(sspine_instance instance_id, sspine_bone bone, sspine_vec2 world_pos) {
  5478. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5479. sspine_vec2 res;
  5480. _sspine_clear(&res, sizeof(res));
  5481. spBone* sp_bone = _sspine_lookup_bone(instance_id.id, bone.skeleton_id, bone.index);
  5482. if (sp_bone) {
  5483. spBone_worldToLocal(sp_bone, world_pos.x, world_pos.y, &res.x, &res.y);
  5484. }
  5485. return res;
  5486. }
  5487. SOKOL_API_IMPL int sspine_num_slots(sspine_skeleton skeleton_id) {
  5488. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5489. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5490. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5491. SOKOL_ASSERT(skeleton->sp_skel_data);
  5492. return skeleton->sp_skel_data->slotsCount;
  5493. }
  5494. return 0;
  5495. }
  5496. SOKOL_API_IMPL sspine_slot sspine_slot_by_name(sspine_skeleton skeleton_id, const char* name) {
  5497. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5498. SOKOL_ASSERT(name);
  5499. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5500. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5501. SOKOL_ASSERT(skeleton->sp_skel_data);
  5502. spSlotData* sp_slot_data = spSkeletonData_findSlot(skeleton->sp_skel_data, name);
  5503. if (sp_slot_data) {
  5504. return _sspine_slot(skeleton_id.id, sp_slot_data->index);
  5505. }
  5506. }
  5507. return _sspine_slot(0, 0);
  5508. }
  5509. SOKOL_API_IMPL sspine_slot sspine_slot_by_index(sspine_skeleton skeleton_id, int index) {
  5510. return _sspine_slot(skeleton_id.id, index);
  5511. }
  5512. SOKOL_API_IMPL bool sspine_slot_valid(sspine_slot slot) {
  5513. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5514. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(slot.skeleton_id);
  5515. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5516. SOKOL_ASSERT(skeleton->sp_skel_data);
  5517. return (slot.index >= 0) && (slot.index < skeleton->sp_skel_data->slotsCount);
  5518. }
  5519. return false;
  5520. }
  5521. SOKOL_API_IMPL bool sspine_slot_equal(sspine_slot first, sspine_slot second) {
  5522. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5523. }
  5524. SOKOL_API_IMPL sspine_slot_info sspine_get_slot_info(sspine_slot slot) {
  5525. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5526. sspine_slot_info res;
  5527. _sspine_clear(&res, sizeof(res));
  5528. const spSlotData* sp_slot_data = _sspine_lookup_slot_data(slot.skeleton_id, slot.index);
  5529. if (sp_slot_data) {
  5530. SOKOL_ASSERT(sp_slot_data->index == slot.index);
  5531. SOKOL_ASSERT(sp_slot_data->name);
  5532. SOKOL_ASSERT(sp_slot_data->boneData);
  5533. res.valid = true;
  5534. res.index = sp_slot_data->index;
  5535. res.bone = _sspine_bone(slot.skeleton_id, sp_slot_data->boneData->index);
  5536. res.color.r = sp_slot_data->color.r;
  5537. res.color.g = sp_slot_data->color.g;
  5538. res.color.b = sp_slot_data->color.b;
  5539. res.color.a = sp_slot_data->color.a;
  5540. res.attachment_name = _sspine_string(sp_slot_data->attachmentName);
  5541. if (res.attachment_name.truncated) {
  5542. _SSPINE_WARN(STRING_TRUNCATED);
  5543. }
  5544. res.name = _sspine_string(sp_slot_data->name);
  5545. if (res.name.truncated) {
  5546. _SSPINE_WARN(STRING_TRUNCATED);
  5547. }
  5548. }
  5549. return res;
  5550. }
  5551. SOKOL_API_IMPL void sspine_set_slot_color(sspine_instance instance_id, sspine_slot slot, sspine_color color) {
  5552. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5553. spSlot* sp_slot = _sspine_lookup_slot(instance_id.id, slot.skeleton_id, slot.index);
  5554. if (sp_slot) {
  5555. sp_slot->color.r = color.r;
  5556. sp_slot->color.g = color.g;
  5557. sp_slot->color.b = color.b;
  5558. sp_slot->color.a = color.a;
  5559. }
  5560. }
  5561. SOKOL_API_IMPL sspine_color sspine_get_slot_color(sspine_instance instance_id, sspine_slot slot) {
  5562. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5563. sspine_color color;
  5564. _sspine_clear(&color, sizeof(color));
  5565. spSlot* sp_slot = _sspine_lookup_slot(instance_id.id, slot.skeleton_id, slot.index);
  5566. if (sp_slot) {
  5567. color.r = sp_slot->color.r;
  5568. color.g = sp_slot->color.g;
  5569. color.b = sp_slot->color.b;
  5570. color.a = sp_slot->color.a;
  5571. }
  5572. return color;
  5573. }
  5574. SOKOL_API_IMPL int sspine_num_events(sspine_skeleton skeleton_id) {
  5575. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5576. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5577. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5578. SOKOL_ASSERT(skeleton->sp_skel_data);
  5579. return skeleton->sp_skel_data->eventsCount;
  5580. }
  5581. return 0;
  5582. }
  5583. SOKOL_API_IMPL sspine_event sspine_event_by_name(sspine_skeleton skeleton_id, const char* name) {
  5584. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5585. SOKOL_ASSERT(name);
  5586. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5587. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5588. SOKOL_ASSERT(skeleton->sp_skel_data);
  5589. SOKOL_ASSERT(skeleton->sp_skel_data->events);
  5590. // spEventData has no embedded index, so we need to loop over the events
  5591. for (int i = 0; i < skeleton->sp_skel_data->eventsCount; i++) {
  5592. SOKOL_ASSERT(skeleton->sp_skel_data->events[i]);
  5593. SOKOL_ASSERT(skeleton->sp_skel_data->events[i]->name);
  5594. if (0 == strcmp(skeleton->sp_skel_data->events[i]->name, name)) {
  5595. return _sspine_event(skeleton_id.id, i);
  5596. }
  5597. }
  5598. }
  5599. return _sspine_event(0, 0);
  5600. }
  5601. SOKOL_API_IMPL sspine_event sspine_event_by_index(sspine_skeleton skeleton_id, int index) {
  5602. return _sspine_event(skeleton_id.id, index);
  5603. }
  5604. SOKOL_API_IMPL bool sspine_event_valid(sspine_event event) {
  5605. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5606. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(event.skeleton_id);
  5607. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5608. SOKOL_ASSERT(skeleton->sp_skel_data);
  5609. return (event.index >= 0) && (event.index < skeleton->sp_skel_data->eventsCount);
  5610. }
  5611. return false;
  5612. }
  5613. SOKOL_API_IMPL bool sspine_event_equal(sspine_event first, sspine_event second) {
  5614. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5615. }
  5616. SOKOL_API_IMPL sspine_event_info sspine_get_event_info(sspine_event event) {
  5617. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5618. sspine_event_info res;
  5619. _sspine_clear(&res, sizeof(res));
  5620. const spEventData* sp_event_data = _sspine_lookup_event_data(event.skeleton_id, event.index);
  5621. if (sp_event_data) {
  5622. res.valid = true;
  5623. res.index = event.index;
  5624. res.int_value = sp_event_data->intValue;
  5625. res.float_value = sp_event_data->floatValue;
  5626. res.volume = sp_event_data->volume;
  5627. res.balance = sp_event_data->balance;
  5628. res.name = _sspine_string(sp_event_data->name);
  5629. if (res.name.truncated) {
  5630. _SSPINE_WARN(STRING_TRUNCATED);
  5631. }
  5632. res.string_value = _sspine_string(sp_event_data->stringValue);
  5633. if (res.string_value.truncated) {
  5634. _SSPINE_WARN(STRING_TRUNCATED);
  5635. }
  5636. res.audio_path = _sspine_string(sp_event_data->audioPath);
  5637. if (res.audio_path.truncated) {
  5638. _SSPINE_WARN(STRING_TRUNCATED);
  5639. }
  5640. }
  5641. return res;
  5642. }
  5643. SOKOL_API_IMPL int sspine_num_iktargets(sspine_skeleton skeleton_id) {
  5644. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5645. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5646. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5647. SOKOL_ASSERT(skeleton->sp_skel_data);
  5648. return skeleton->sp_skel_data->ikConstraintsCount;
  5649. }
  5650. return 0;
  5651. }
  5652. SOKOL_API_IMPL sspine_iktarget sspine_iktarget_by_name(sspine_skeleton skeleton_id, const char* name) {
  5653. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5654. SOKOL_ASSERT(name);
  5655. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5656. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5657. SOKOL_ASSERT(skeleton->sp_skel_data);
  5658. SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints);
  5659. // spIkConstraintData has no embedded index, so we need to loop over the events
  5660. for (int i = 0; i < skeleton->sp_skel_data->ikConstraintsCount; i++) {
  5661. SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints[i]);
  5662. SOKOL_ASSERT(skeleton->sp_skel_data->ikConstraints[i]->name);
  5663. if (0 == strcmp(skeleton->sp_skel_data->ikConstraints[i]->name, name)) {
  5664. return _sspine_iktarget(skeleton_id.id, i);
  5665. }
  5666. }
  5667. }
  5668. return _sspine_iktarget(0, 0);
  5669. }
  5670. SOKOL_API_IMPL sspine_iktarget sspine_iktarget_by_index(sspine_skeleton skeleton_id, int index) {
  5671. return _sspine_iktarget(skeleton_id.id, index);
  5672. }
  5673. SOKOL_API_IMPL bool sspine_iktarget_valid(sspine_iktarget iktarget) {
  5674. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5675. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(iktarget.skeleton_id);
  5676. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5677. SOKOL_ASSERT(skeleton->sp_skel_data);
  5678. return (iktarget.index >= 0) && (iktarget.index < skeleton->sp_skel_data->ikConstraintsCount);
  5679. }
  5680. return false;
  5681. }
  5682. SOKOL_API_IMPL bool sspine_iktarget_equal(sspine_iktarget first, sspine_iktarget second) {
  5683. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5684. }
  5685. SOKOL_API_IMPL sspine_iktarget_info sspine_get_iktarget_info(sspine_iktarget iktarget) {
  5686. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5687. sspine_iktarget_info res;
  5688. _sspine_clear(&res, sizeof(res));
  5689. const spIkConstraintData* ik_data = _sspine_lookup_ikconstraint_data(iktarget.skeleton_id, iktarget.index);
  5690. if (ik_data) {
  5691. res.valid = true;
  5692. res.index = iktarget.index;
  5693. res.target_bone = _sspine_bone(iktarget.skeleton_id, ik_data->target->index);
  5694. res.name = _sspine_string(ik_data->name);
  5695. if (res.name.truncated) {
  5696. _SSPINE_WARN(STRING_TRUNCATED);
  5697. }
  5698. }
  5699. return res;
  5700. }
  5701. SOKOL_API_IMPL void sspine_set_iktarget_world_pos(sspine_instance instance_id, sspine_iktarget iktarget, sspine_vec2 world_pos) {
  5702. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5703. spIkConstraint* ik_data = _sspine_lookup_ikconstraint(instance_id.id, iktarget.skeleton_id, iktarget.index);
  5704. if (ik_data) {
  5705. spBone* bone = ik_data->target;
  5706. spBone* parent_bone = bone->parent;
  5707. if (parent_bone) {
  5708. spBone_worldToLocal(parent_bone, world_pos.x, world_pos.y, &bone->x, &bone->y);
  5709. }
  5710. }
  5711. }
  5712. SOKOL_API_IMPL int sspine_num_skins(sspine_skeleton skeleton_id) {
  5713. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5714. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5715. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5716. SOKOL_ASSERT(skeleton->sp_skel_data);
  5717. return skeleton->sp_skel_data->skinsCount;
  5718. }
  5719. return 0;
  5720. }
  5721. SOKOL_API_IMPL sspine_skin sspine_skin_by_name(sspine_skeleton skeleton_id, const char* name) {
  5722. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5723. SOKOL_ASSERT(name);
  5724. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
  5725. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5726. SOKOL_ASSERT(skeleton->sp_skel_data);
  5727. SOKOL_ASSERT(skeleton->sp_skel_data->skins);
  5728. // spSkin has no embedded index, so we need to loop over the skins
  5729. for (int i = 0; i < skeleton->sp_skel_data->skinsCount; i++) {
  5730. SOKOL_ASSERT(skeleton->sp_skel_data->skins[i]);
  5731. SOKOL_ASSERT(skeleton->sp_skel_data->skins[i]->name);
  5732. if (0 == strcmp(skeleton->sp_skel_data->skins[i]->name, name)) {
  5733. return _sspine_skin(skeleton_id.id, i);
  5734. }
  5735. }
  5736. }
  5737. return _sspine_skin(0, 0);
  5738. }
  5739. SOKOL_API_IMPL sspine_skin sspine_skin_by_index(sspine_skeleton skeleton_id, int index) {
  5740. return _sspine_skin(skeleton_id.id, index);
  5741. }
  5742. SOKOL_API_IMPL bool sspine_skin_valid(sspine_skin skin) {
  5743. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5744. _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skin.skeleton_id);
  5745. if (_sspine_skeleton_and_deps_valid(skeleton)) {
  5746. SOKOL_ASSERT(skeleton->sp_skel_data);
  5747. return (skin.index >= 0) && (skin.index < skeleton->sp_skel_data->skinsCount);
  5748. }
  5749. return false;
  5750. }
  5751. SOKOL_API_IMPL bool sspine_skin_equal(sspine_skin first, sspine_skin second) {
  5752. return (first.skeleton_id == second.skeleton_id) && (first.index == second.index);
  5753. }
  5754. SOKOL_API_IMPL sspine_skin_info sspine_get_skin_info(sspine_skin skin) {
  5755. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5756. sspine_skin_info res;
  5757. _sspine_clear(&res, sizeof(res));
  5758. const spSkin* sp_skin = _sspine_lookup_skin(skin.skeleton_id, skin.index);
  5759. if (sp_skin) {
  5760. res.valid = true;
  5761. res.index = skin.index;
  5762. res.name = _sspine_string(sp_skin->name);
  5763. if (res.name.truncated) {
  5764. _SSPINE_WARN(STRING_TRUNCATED);
  5765. }
  5766. }
  5767. return res;
  5768. }
  5769. SOKOL_SPINE_API_DECL void sspine_set_skin(sspine_instance instance_id, sspine_skin skin) {
  5770. SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
  5771. _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
  5772. if (_sspine_instance_and_deps_valid(instance) && (instance->skel.id == skin.skeleton_id)) {
  5773. SOKOL_ASSERT(instance->sp_skel);
  5774. SOKOL_ASSERT(instance->sp_anim_state);
  5775. // clear any currently set skinset
  5776. instance->skinset.id = SSPINE_INVALID_ID;
  5777. instance->skinset.ptr = 0;
  5778. spSkin* sp_skin = _sspine_lookup_skin(skin.skeleton_id, skin.index);
  5779. if (sp_skin) {
  5780. spSkeleton_setSkin(instance->sp_skel, 0);
  5781. spSkeleton_setSkin(instance->sp_skel, sp_skin);
  5782. spSkeleton_setSlotsToSetupPose(instance->sp_skel);
  5783. spAnimationState_apply(instance->sp_anim_state, instance->sp_skel);
  5784. }
  5785. }
  5786. }
  5787. #endif // SOKOL_SPINE_IMPL
  5788. #endif // SOKOL_SPINE_INCLUDED