gs.h 322 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373
  1. /*==============================================================================================================
  2. * Copyright (c) 2020 John Jackson
  3. * Gunslinger: A simple, header-only c99 multi-media framework
  4. * File: gs.h
  5. * Github: https://github.com/MrFrenik/gunslinger
  6. * All Rights Reserved
  7. * MIT License
  8. * May all those that this source may reach be blessed by the LORD and find peace and joy in life.
  9. * Everyone who drinks of this water will be thirsty again; but whoever drinks of the water
  10. * that I will give him shall never thirst; John 4:13-14
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  12. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
  13. * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
  14. * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  15. * The above copyright notice and this permission notice shall be included in all
  16. * copies or substantial portions of the Software.
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  18. * TO THE WARRANTIES OF MECHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  20. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. =================================================================================================================*/
  23. #ifndef GS_H
  24. #define GS_H
  25. /*═█═════════════════════════════════════════════════════════════════════════════════════█═╗
  26. ████ ██████╗ ██╗ ██╗███╗ ██╗███████╗██╗ ██╗███╗ ██╗ ██████╗ ███████╗██████╗ ██████═█
  27. █║█ ██╔════╝ ██║ ██║████╗ ██║██╔════╝██║ ██║████╗ ██║██╔════╝ ██╔════╝██╔══██╗ ██═████
  28. ███ ██║ ███╗██║ ██║██╔██╗ ██║███████╗██║ ██║██╔██╗ ██║██║ ███╗█████╗ ██████╔╝ █████═██
  29. ╚██ ██║ ██║██║ ██║██║╚██╗██║╚════██║██║ ██║██║╚██╗██║██║ ██║██╔══╝ ██╔══██╗ ███ █╝█
  30. █║█ ╚██████╔╝╚██████╔╝██║ ╚████║███████║███████╗██║██║ ╚████║╚██████╔╝███████╗██║ ██║ ██═████
  31. ████ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ █═█═██
  32. ╚═██════════════════════════════════════════════════════════════════════════════════════██═╝*/
  33. /*
  34. Gunslinger is a header-only, c99 framework for multi-media applications and tools.
  35. USAGE: (IMPORTANT)
  36. =================================================================================================================
  37. Before including, define the gunslinger implementation like this:
  38. #define GS_IMPL
  39. in EXACTLY ONE C or C++ file that includes this header, BEFORE the
  40. include, like this:
  41. #define GS_IMPL
  42. #include "gs.h"
  43. All other files should just #include "gs.h" without the #define.
  44. (Thanks to SB for the template for this instructional message. I was too lazy to come up with my own wording.)
  45. NOTE:
  46. All main interface stuff in here, then system implementations can be in separate header files
  47. All provided implementations will be in impl/xxx.h
  48. This is just to keep everything from being in one huge file
  49. ================================================================================================================
  50. Contained within (Contents):
  51. * GS_APPLICATION
  52. * GS_UTIL
  53. * GS_CONTAINERS
  54. * GS_ASSET_TYPES
  55. * GS_MATH
  56. * GS_LEXER
  57. * GS_PLATFORM
  58. * GS_GRAPHICS
  59. * GS_AUDIO
  60. ================================================================================================================
  61. GS_APPLICATION:
  62. Gunslinger is a framework that expects to take flow control over your app and calls into your code
  63. at certain sync points. These points are 'init', 'update', and 'shutdown'. When creating your application,
  64. you provide certain information to the framework via a `gs_app_desc_t` descriptor object. Gunslinger acts as the
  65. main entry point to your application, so instead of defining "main" as you typically would for a c/c++ program,
  66. you instead implement the `gs_main` function that will be called by gunslinger. This last bit is optional and
  67. a different method for entry is covered, however this is the most convenient way to use the framework.
  68. Basic Example Application:
  69. #define GS_IMPL
  70. #include "gs.h"
  71. void my_init(void* app) {
  72. // Do your initialization
  73. }
  74. void my_update(void* app) {
  75. // Do your updates
  76. }
  77. void my_shutdown(void* app) {
  78. // Do your shutdown
  79. }
  80. gs_app_desc_t gs_main(int32_t argc, char** argv) {
  81. return (gs_app_desc_t) {
  82. .init = my_init, // Function pointer to call into your init code
  83. .update = my_update, // Function pointer to call into your update code
  84. .shutdown = my_shutdown // Function pointer to call into your shutdown code
  85. };
  86. }
  87. If you do not provide information for any of this information, defaults will be provided by the framework.
  88. Therefore, it is possible to return a completely empty app descriptor back to the framework to run:
  89. gs_app_desc_t gs_main(int32_t argc, char** argv) {
  90. return (gs_app_desc_t){0};
  91. }
  92. NOTE:
  93. In addition to function callbacks, there are quite a few options available to provide for this descriptor,
  94. such as window width, window height, window flags, window title, etc. Refer to the section for gs_app_desc_t
  95. further in the code for all provided options.
  96. It's also possible to define GS_NO_HIJACK_MAIN for your application. This will make it so gunslinger will not be
  97. the main entry point to your application. You will instead be responsible for creating a gunslinger instance and
  98. passing in your application description to it.
  99. #define GS_NO_HIJACK_MAIN
  100. int32_t main(int32_t argv, char** argc)
  101. {
  102. gs_app_desc_t app = {0}; // Fill this with whatever your app needs
  103. gs_create(app); // Create instance of framework and run
  104. while (gs_app()->is_running) {
  105. gs_frame();
  106. }
  107. return 0;
  108. }
  109. NOTE:
  110. Lastly, while it is possible to use gunslinger without it controlling the main application loop, this isn't recommended.
  111. Internally, gunslinger does its best to handle the boiler plate drudge work of implementing (in correct order)
  112. the various layers required for a basic hardware accelerated multi-media application program to work. This involves allocating
  113. memory for internal data structures for these layers as well initializing them in a particular order so they can inter-operate
  114. as expected. If you're interested in taking care of this yourself, look at the `gs_frame()` function to get a feeling
  115. for how this is being handled.
  116. GS_MATH:
  117. Gunslinger includes utilities for common graphics/game related math structures. These aren't required to be used, however they are
  118. used internally for certain function calls in various APIs. Where possible, I've tried to add as much redundancy as possible to
  119. the APIs so that these structures are not required if you prefer.
  120. * common utils:
  121. - interpolation
  122. * Vectors:
  123. - gs_vec2: float[2]
  124. - gs_vec3: float[3]
  125. - gs_vec4: float[4]
  126. * vector ops:
  127. - dot product
  128. - normalize
  129. - add/subtract (component wise)
  130. - multiply
  131. - cross product
  132. - length
  133. *Quaternions:
  134. - gs_quat: float[4]
  135. * quaternion ops:
  136. - add/subtract/multiply
  137. - inverse
  138. - conjugate
  139. - angle/axis | axis/angle
  140. - to euler | from euler
  141. - to mat4
  142. *Mat4x4:
  143. - gs_mat4: float[16]
  144. * mat4 ops:
  145. - add/subtract/multiply
  146. - transpose
  147. - inverse
  148. - homogenous transformations:
  149. - rotation
  150. - scale
  151. - translate
  152. - view:
  153. - lookat
  154. - projection:
  155. - orthographic
  156. - perspective
  157. *VQS:
  158. - gs_vqs: gs_vec3, gs_quat, gs_vec3
  159. (SPECIAL NOTE):
  160. `gs_vqs` is a transform structure that's commonly used in games/physics sims, especially with complex child/parent hierarchies. It stands for
  161. `Vector-Quaternion-Scalar` to denote its internal components. Typically this encodes position, rotation (in quaternion), and a uniform scale
  162. for transformation. Gunslinger uses non-uniform scale in the form of a gs_vec3.
  163. gs_vqs xform = {0};
  164. xform.position = gs_v3(...);
  165. xform.rotation = gs_quat(...);
  166. xform.scale = gs_v3(...);
  167. This structure can then be converted into a final form float[16] mat4x4 for any typical homogenous graphics transformations:
  168. gs_mat4 model = gs_vqs_to_mat4(&xform);
  169. The real power in VQS transforms is the ability to easily encode parent/child hierarchies. This is done using the two functions
  170. `gs_vqs_absolute_transform` and `gs_vqs_relative_transform`:
  171. gs_vqs parent = ...;
  172. gs_vqs child = ...; {
  173. gs_vqs relative = gs_vqs_relative_transform(&child, &parent); // Get relative transform with respect to parent
  174. gs_vqs absolute = gs_vqs_absolute_transform(&local, &parent); // Get absolute transform with respect to local
  175. GS_UTIL:
  176. memory allocation
  177. hashing(32/64 bit)
  178. siphash (hash generic bytes)
  179. string utils
  180. file utils
  181. GS_CONTAINERS:
  182. gs_dyn_array:
  183. Inspired GREATLY from Shawn Barret's "stretchy buffer" implementation. A generic, dynamic array of type T,
  184. which is defined by the user:
  185. gs_dyn_array(float) arr = NULL; // Dynamic array of type float
  186. This works by using the macro `gs_dyn_array(T)`, which evaluates to `T*`. The dynamic array stores a bit of header information
  187. right before the actual array in memory for a table to describe properties of the array:
  188. [header][actual array data]
  189. The header is a structure of uint32_t[2]:
  190. typedef struct gs_array_header_t {
  191. uint32_t size;
  192. uint32_t capacity;
  193. } gs_array_header_t;
  194. The array can be randomly accessed using the [] operator, just like any regular c array. There are also provided functions for accessing
  195. information using this provided table. This dynamic structure is the baseline for all other containers provided in gunslinger.
  196. Array Usage:
  197. gs_dyn_array(float) arr = NULL; // Create dynamic array of type float.
  198. gs_dyn_array_push(arr, 10.f); // Push value into back of array. Will dynamically grow/initialize on demand.
  199. float v = arr[0]; // Gets value of array data at index 0;
  200. float* vp = &arr[0]; // Gets pointer reference of array data at index 0;
  201. uint32_t sz = gs_dyn_array_size(arr); // Gets size of array. Return 0 if NULL.
  202. uint32_t cap = gs_dyn_array_capacity(arr); // Gets capacity of array. Return 0 if NULL.
  203. bool is_empty = gs_dyn_array_empty(arr); // Returns whether array is empty. Return true if NULL.
  204. gs_dyn_array_reserve(arr, 10); // Reserves internal space in the array for N, non-initialized elements.
  205. gs_dyn_array_clear(arr); // Clears all elements. Simply sets array size to 0.
  206. gs_dyn_array_free(arr); // Frees array data calling `gs_free` internally.
  207. gs_hash_table: generic hash table of key:K and val:V
  208. Inspired GREATLY from Shawn Barret's "stb_ds.h" implementation. A generic hash table of K,V which is defined
  209. by the user:
  210. gs_hash_table(uint32_t, float) ht = NULL; // Creates a hash table with K = uint32_t, V = float
  211. Internally, the hash table uses a 64-bit siphash to hash generic byte data to an unsigned 64-bit key. This means it's possible to pass up
  212. arbitrary data to the hash table and it will hash accordingly, such as structures:
  213. typedef struct key_t {
  214. uint32_t id0;
  215. uint64_t id1;
  216. } key_t;
  217. gs_hash_table(key_t, float) ht = NULL; // Create hash table with K = key_t, V = float
  218. Inserting into the array with "complex" types is as simple as:
  219. key_t k = {.ido0 = 5, .id1 = 32}; // Create structure for "key"
  220. gs_hash_table_insert(ht, k, 5.f); // Insert into hash table using key
  221. float v = gs_hash_table_get(ht, k); // Get data at key
  222. It is possible to return a reference to the data using `gs_hash_table_getp()`. However, keep in mind that this comes with the
  223. danger that the reference could be lost IF the internal data array grows or shrinks in between you caching the pointer
  224. and using it.
  225. float* val = gs_hash_table_getp(ht, k); // Cache pointer to internal data. Dangerous game.
  226. gs_hash_table_insert(ht, new_key); // At this point, your pointer could be invalidated due to growing internal array.
  227. Hash tables provide iterators to iterate the data:
  228. for (
  229. gs_hash_table_iter it = 0;
  230. gs_hash_table_iter_valid(ht, it);
  231. gs_hash_table_iter_advance(ht, it)
  232. ) {
  233. float v = gs_hash_table_iter_get(ht, it); // Get value using iterator
  234. float* vp = gs_hash_table_iter_getp(ht, it); // Get value pointer using iterator
  235. key_t k = gs_hash_table_iter_getk(ht, it); // Get key using iterator
  236. key_t* kp = gs_hash_table_iter_getkp(ht, it); // Get key pointer using iterator
  237. }
  238. Hash Table Usage:
  239. gs_hash_table(uint32_t, float) ht = NULL; // Create hash table with key = uint32_t, val = float
  240. gs_hash_table_insert(ht, 64, 3.145f); // Insert key/val pair {64, 3.145f} into hash table. Will dynamically grow/init on demand.
  241. bool exists = gs_hash_table_key_exists(ht, 64); // Use to query whether or not a key exists in the table.
  242. float v = gs_hash_table_get(ht, 64); // Get value at key = 64. Will crash if not available.
  243. float* vp = gs_hash_table_get(ht, 64); // Get pointer reference to data at key = 64. Will crash if not available.
  244. bool is_empty = gs_hash_table_empty(ht); // Returns whether hash table is empty. Returns true if NULL.
  245. uint32_t sz = gs_hash_table_size(ht); // Get size of hash table. Returns 0 if NULL.
  246. uint32_t cap = gs_hash_table_capacity(ht); // Get capacity of hash table. Returns 0 if NULL.
  247. gs_hash_table_clear(ht); // Clears all elements. Sets size to 0.
  248. gs_hash_table_free(ht); // Frees hash table internal data calling `gs_free` internally.
  249. gs_slot_array:
  250. Slot arrays are internally just dynamic arrays but alleviate the issue with losing references to internal
  251. data when the arrays grow. Slot arrays therefore hold two internals arrays:
  252. gs_dyn_array(T) your_data;
  253. gs_dyn_array(uint32_t) indirection_array;
  254. The indirection array takes an opaque uint32_t handle and then dereferences it to find the actual index
  255. for the data you're interested in. Just like dynamic arrays, they are NULL initialized and then
  256. allocated/initialized internally upon use:
  257. gs_slot_array(float) arr = NULL; // Slot array with internal 'float' data
  258. uint32_t hndl = gs_slot_array_insert(arr, 3.145f); // Inserts your data into the slot array, returns handle to you
  259. float val = gs_slot_array_get(arr, hndl); // Returns copy of data to you using handle as lookup
  260. It is possible to return a reference to the data using `gs_slot_array_getp()`. However, keep in mind that this comes with the
  261. danger that the reference could be lost IF the internal data array grows or shrinks in between you caching the pointer
  262. and using it.
  263. float* val = gs_slot_array_getp(arr, hndl); // Cache pointer to internal data. Dangerous game.
  264. gs_slot_array_insert(arr, 5.f); // At this point, your pointer could be invalidated due to growing internal array.
  265. Slot arrays provide iterators to iterate the data:
  266. for (
  267. gs_slot_array_iter it = 0;
  268. gs_slot_array_iter_valid(sa, it);
  269. gs_slot_array_iter_advance(sa, it)
  270. ) {
  271. float v = gs_slot_array_iter_get(sa, it); // Get value using iterator
  272. float* vp = gs_slot_array_iter_getp(sa, it); // Get value pointer using iterator
  273. }
  274. Slot Array Usage:
  275. gs_slot_array(float) sa = NULL; // Create slot array with internal 'float' data
  276. uint32_t hndl = gs_slot_array_insert(sa, 3.145); // Insert data into slot array. Returns uint32_t handle. Init/Grow on demand.
  277. float v = gs_slot_array_get(sa, hndl); // Get data at hndl.
  278. float* vp = gs_slot_array_getp(sa, hndl); // Get pointer reference at hndl. Dangerous.
  279. uint32_t sz = gs_slot_array_size(sa); // Size of slot array. Returns 0 if NULL.
  280. uint32_t cap = gs_slot_array_capacity(sa); // Capacity of slot array. Returns 0 if NULL.
  281. gs_slot_array_empty(sa); // Returns whether slot array is empty. Returns true if NULL.
  282. gs_slot_array_clear(sa); // Clears array. Sets size to 0.
  283. gs_slot_array_free(sa); // Frees array memory. Calls `gs_free` internally.
  284. gs_slot_map:
  285. Works exactly the same, functionally, as gs_slot_array, however allows the user to use one more layer of indirection by
  286. hashing any data as a key type. Also worth note, the slot map does not return a handle to the user. Instead, the user is
  287. expected to use the key to access data.
  288. gs_slot_map(float, uint64_t) sm = NULL; // Slot map with key = float, val = uint64_t
  289. gs_slot_map_insert(sm, 1.f, 32); // Insert data into slot map.
  290. uint64_t v = gs_slot_map_get(sm, 1.f); // Returns copy of data to you at key `1.f`
  291. Like the slot array, it is possible to return a reference via pointer using `gs_slot_map_getp()`. Again, this comes with the same
  292. danger of losing references if not careful about growing the internal data.
  293. uint64_t* v = gs_slot_map_getp(sm, 1.f); // Cache pointer to data
  294. gs_slot_map_insert(sm, 2.f, 10); // Possibly have just invalidated your previous pointer
  295. Slot maps provide iterators to iterate the data:
  296. for (
  297. gs_slot_map_iter it = 0;
  298. gs_slot_map_iter_valid(sm, it);
  299. gs_slot_map_iter_advance(sm, it)
  300. ) {
  301. uint64_t v = gs_slot_map_iter_get(sm, it); // Get value using iterator
  302. uint64_t* vp = gs_slot_map_iter_getp(sm, it); // Get value pointer using iterator
  303. float k = gs_slot_map_iter_get_key(sm, it); // Get key using iterator
  304. float* kp = gs_slot_map_iter_get_keyp(sm, it); // Get key pointer using iterator
  305. }
  306. Slot Map Usage:
  307. gs_slot_map(float, uint64_t) sm = NULL; // Create slot map with K = float, V = uint64_t
  308. uint32_t hndl = gs_slot_map_insert(sm, 3.145f, 32); // Insert data into slot map. Init/Grow on demand.
  309. uint64_t v = gs_slot_map_get(sm, 3.145f); // Get data at key.
  310. uint64_t* vp = gs_slot_map_getp(sm, 3.145f); // Get pointer reference at hndl. Dangerous.
  311. uint32_t sz = gs_slot_map_size(sm); // Size of slot map. Returns 0 if NULL.
  312. uint32_t cap = gs_slot_map_capacity(sm); // Capacity of slot map. Returns 0 if NULL.
  313. gs_slot_map_empty(sm); // Returns whether slot map is empty. Returns true if NULL.
  314. gs_slot_map_clear(sm); // Clears map. Sets size to 0.
  315. gs_slot_map_free(sm); // Frees map memory. Calls `gs_free` internally.
  316. GS_PLATFORM:
  317. By default, Gunslinger supports (via included GLFW) the following platforms:
  318. - Win32
  319. - OSX
  320. - Linux
  321. To define your own custom implementation and not use the included glfw implementation, define GS_PLATFORM_IMPL_CUSTOM in your
  322. project. Gunslinger will see this and leave the implementation of the platform API up to you:
  323. // For custom platform implementation
  324. #define GS_PLATFORM_IMPL_CUSTOM
  325. Internally, the platform interface holds the following data:
  326. gs_platform_settings_t settings; // Settings for platform, including video driver settings
  327. gs_platform_time_t time; // Time structure, used to query frame time, delta time, render time
  328. gs_platform_input_t input; // Input struture, used to query input state for mouse, keyboard, controllers
  329. gs_slot_array(void*) windows; // Slot array of raw platform window data and handles
  330. void* cursors[GS_PLATFORM_CURSOR_COUNT]; // Raw platform cursors
  331. void* user_data; // Specific user data (for custom implementations)
  332. Upon creation, the framework will create a main window for you and then store its handle with slot id 0. All platform related window
  333. query functions require passing in an opaque uint32_t handle to get the actual data internally. There is a convenience function available for
  334. querying the main window handle created for you:
  335. uint32_t main_window_hndl = gs_platform_main_window();
  336. Internally, the platform layer queries the platform backend and updates its exposed gs_platform_input_t data structure for you to use. Several
  337. utility functions exist:
  338. gs_platform_key_down(gs_platform_keycode) // Checks to see if a key is held down (pressed last frame and this frame)
  339. gs_platform_key_released(gs_platform_keycode) // Checks to see if a key was released this frame
  340. gs_platform_key_pressed(gs_platform_keycode) // Checks to see if a key was pressed this frame (not pressed last frame)
  341. gs_platform_mouse_down(gs_platform_mouse_button_code) // Checks to see if mouse button is held down
  342. gs_platform_mouse_pressed(gs_platform_mouse_button_code) // Checks to see if mouse button was pressed this frame (not pressed last frame)
  343. gs_platform_mouse_released(gs_platform_mouse_button_code) // Checks to see if mouse button was released this frame
  344. GS_AUDIO:
  345. By default, Gunslinger includes and uses miniaudio for its audio backend.
  346. To define your own custom implementation and not use the included miniaudio implementation, define GS_AUDIO_IMPL_CUSTOM in your
  347. project. Gunslinger will see this and leave the implementation of the audio API up to you:
  348. // For custom audio implementation
  349. #define GS_AUDIO_IMPL_CUSTOM
  350. GS_GRAPHICS:
  351. // For custom graphics implementation
  352. #define GS_GRAPHICS_IMPL_CUSTOM
  353. */
  354. /*===== Gunslinger Include ======*/
  355. // #ifdef __cplusplus
  356. // extern "C" {
  357. // #endif
  358. /*========================
  359. // Defines
  360. ========================*/
  361. #include <stdarg.h> // valist
  362. #include <stddef.h> // ptrdiff_t
  363. #include <stdlib.h> // malloc, realloc, free
  364. #include <stdint.h> // standard types
  365. #include <limits.h> // INT32_MAX, UINT32_MAX
  366. #include <string.h> // memset
  367. #include <float.h> // FLT_MAX
  368. #include <stdio.h> // FILE
  369. #include <time.h> // time
  370. #include <ctype.h> // tolower
  371. #include <math.h> // floor, acos, sin, sqrt, tan
  372. #include <assert.h> // assert
  373. #include <malloc.h> // alloca/_alloca
  374. /*===========================================================
  375. // gs_inline, gs_global, gs_local_persist, gs_force_inline
  376. ===========================================================*/
  377. #ifndef gs_inline
  378. #define gs_inline static inline
  379. #endif
  380. #ifndef gs_local_persist
  381. #define gs_local_persist static
  382. #endif
  383. #ifndef gs_global
  384. #define gs_global static
  385. #endif
  386. #if (defined _WIN32 || defined _WIN64)
  387. #define gs_force_inline gs_inline
  388. #elif (defined __APPLE__ || defined _APPLE)
  389. #define gs_force_inline static __attribute__((always_inline))
  390. #else
  391. #define gs_force_inline gs_inline
  392. #endif
  393. #define GS_INLINE gs_force_inline
  394. #define GS_GLOBAL gs_global
  395. #define GS_LOCAL_PERSIST gs_local_persist
  396. #ifdef __cplusplus
  397. #pragma warning(disable:4996)
  398. #endif
  399. /*===================
  400. // GS_API_DECL
  401. ===================*/
  402. #ifdef GS_API_DLL_EXPORT
  403. #ifdef __cplusplus
  404. #define GS_API_EXTERN extern "C" __declspec(dllexport)
  405. #else
  406. #define GS_API_EXTERN extern __declspec(dllexport)
  407. #endif
  408. #else
  409. #ifdef __cplusplus
  410. #define GS_API_EXTERN extern "C"
  411. #else
  412. #define GS_API_EXTERN extern
  413. #endif
  414. #endif
  415. #define GS_API_DECL GS_API_EXTERN
  416. #define GS_API_PRIVATE GS_API_EXTERN
  417. /*===================
  418. // PLATFORM DEFINES
  419. ===================*/
  420. /* Platform Android */
  421. #if (defined __ANDROID__)
  422. #define GS_PLATFORM_ANDROID
  423. /* Platform Apple */
  424. #elif (defined __APPLE__ || defined _APPLE)
  425. #define GS_PLATFORM_APPLE
  426. /* Platform Windows */
  427. #elif (defined _WIN32 || defined _WIN64)
  428. #define __USE_MINGW_ANSI_STDIO 1
  429. // Necessary windows defines before including windows.h, because it's retarded.
  430. #define OEMRESOURCE
  431. #define GS_PLATFORM_WIN
  432. #define GS_PLATFORM_WINDOWS
  433. #include <windows.h>
  434. #define WIN32_LEAN_AND_MEAN
  435. /* Platform Linux */
  436. #elif (defined linux || defined _linux || defined __linux__)
  437. #define GS_PLATFORM_LINUX
  438. /* Platform Emscripten */
  439. #elif (defined __EMSCRIPTEN__)
  440. #define GS_PLATFORM_WEB
  441. /* Else - Platform Undefined and Unsupported or custom */
  442. #endif
  443. /*============================================================
  444. // C primitive types
  445. ============================================================*/
  446. #ifndef __cplusplus
  447. #define false 0
  448. #define true 1
  449. #endif
  450. #ifdef __cplusplus
  451. typedef bool b8;
  452. #else
  453. #ifndef __bool_true_false_are_defined
  454. typedef _Bool bool;
  455. #endif
  456. typedef bool b8;
  457. #endif
  458. typedef size_t usize;
  459. typedef uint8_t u8;
  460. typedef int8_t s8;
  461. typedef uint16_t u16;
  462. typedef int16_t s16;
  463. typedef uint32_t u32;
  464. typedef int32_t s32;
  465. typedef s32 b32;
  466. typedef uint64_t u64;
  467. typedef int64_t s64;
  468. typedef float f32;
  469. typedef double f64;
  470. typedef const char* const_str;
  471. typedef int32_t bool32_t;
  472. typedef float float32_t;
  473. typedef double float64_t;
  474. typedef bool32_t bool32;
  475. #define uint16_max UINT16_MAX
  476. #define uint32_max UINT32_MAX
  477. #define int32_max INT32_MAX
  478. #define float_max FLT_MAX
  479. #define float_min FLT_MIN
  480. /*============================================================
  481. // gs utils
  482. ============================================================*/
  483. /** @defgroup gs_util Common Utils
  484. * Gunslinger Common Utils
  485. * @{
  486. */
  487. // Helper macro for compiling to nothing
  488. #define gs_empty_instruction(...)
  489. #define gs_array_size(__ARR) sizeof(__ARR) / sizeof(__ARR[0])
  490. #ifndef gs_assert
  491. #define gs_assert assert
  492. #endif
  493. #if defined (__cplusplus)
  494. #define gs_default_val() {}
  495. #else
  496. #define gs_default_val() {0}
  497. #endif
  498. // Helper macro for an in place for-range loop
  499. #define gs_for_range_i(__COUNT)\
  500. for (uint32_t i = 0; i < __COUNT; ++i)
  501. // Helper macro for an in place for-range loop
  502. #define gs_for_range_j(__COUNT)\
  503. for (uint32_t j = 0; j < __COUNT; ++j)
  504. #define gs_for_range(__COUNT)\
  505. for(uint32_t gs_macro_token_paste(__T, __LINE__) = 0;\
  506. gs_macro_token_paste(__T, __LINE__) < __COUNT;\
  507. ++(gs_macro_token_paste(__T, __LINE__)))
  508. #define gs_max(A, B) ((A) > (B) ? (A) : (B))
  509. #define gs_min(A, B) ((A) < (B) ? (A) : (B))
  510. #define gs_clamp(V, MIN, MAX) ((V) > (MAX) ? (MAX) : (V) < (MIN) ? (MIN) : (V))
  511. #define gs_is_nan(V) ((V) != (V))
  512. // Helpful macro for casting one type to another
  513. #define gs_cast(A, B) ((A*)(B))
  514. #ifdef __cplusplus
  515. #define gs_ctor(TYPE, ...) (TYPE {__VA_ARGS__})
  516. #else
  517. #define gs_ctor(TYPE, ...) ((TYPE){__VA_ARGS__})
  518. #endif
  519. // Helpful marco for calculating offset (in bytes) of an element from a given structure type
  520. #define gs_offset(TYPE, ELEMENT) ((size_t)(&(((TYPE*)(0))->ELEMENT)))
  521. // macro for turning any given type into a const char* of itself
  522. #define gs_to_str(TYPE) ((const char*)#TYPE)
  523. #define gs_macro_token_paste(X, Y) X##Y
  524. #define gs_macro_cat(X, Y) gs_macro_token_paste(X, Y)
  525. #define gs_timed_action(INTERVAL, ...)\
  526. do {\
  527. static uint32_t gs_macro_cat(gs_macro_cat(__T, __LINE__), t) = 0;\
  528. if (gs_macro_cat(gs_macro_cat(__T, __LINE__), t)++ > INTERVAL) {\
  529. gs_macro_cat(gs_macro_cat(__T, __LINE__), t) = 0;\
  530. __VA_ARGS__\
  531. }\
  532. } while (0)
  533. #define gs_int2voidp(I) (void*)(uintptr_t)(I)
  534. #define gs_if(INIT, CHECK, ...)\
  535. do {\
  536. INIT;\
  537. if (CHECK)\
  538. {\
  539. __VA_ARGS__\
  540. }\
  541. } while (0)
  542. //=== Logging ===//
  543. #define gs_log_info(MESSAGE, ...) gs_println("LOG::%s::%s(%zu)::" MESSAGE, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
  544. #define gs_log_success(MESSAGE, ...) gs_println("SUCCESS::%s::%s(%zu)::" MESSAGE, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
  545. #define gs_log_warning(MESSAGE, ...) gs_println("WARNING::%s::%s(%zu)::" MESSAGE, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
  546. #define gs_log_error(MESSAGE, ...) do {gs_println("ERROR::%s::%s(%zu)::" MESSAGE, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);\
  547. gs_assert(false);\
  548. } while (0)
  549. /*===================================
  550. // Memory Allocation Utils
  551. ===================================*/
  552. // Operating system function pointer
  553. typedef struct gs_os_api_s
  554. {
  555. void* (* malloc)(size_t sz);
  556. void (* free)(void* ptr);
  557. void* (* realloc)(void* ptr, size_t sz);
  558. void* (* calloc)(size_t num, size_t sz);
  559. void* (* alloca)(size_t sz);
  560. void* (* malloc_init)(size_t sz);
  561. char* (* strdup)(const char* str);
  562. } gs_os_api_t;
  563. // TODO(john): Check if all defaults need to be set, in case gs context will not be used
  564. GS_API_DECL
  565. void* _gs_malloc_init_impl(size_t sz);
  566. // Default memory allocations
  567. #ifndef GS_NO_OS_MEMORY_ALLOC_DEFAULT
  568. #define gs_malloc malloc
  569. #define gs_free free
  570. #define gs_realloc realloc
  571. #define gs_calloc calloc
  572. #define gs_alloca malloc
  573. #define gs_malloc_init(__T) (__T*)_gs_malloc_init_impl(sizeof(__T))
  574. #endif
  575. GS_API_DECL gs_os_api_t
  576. gs_os_api_new_default();
  577. #ifndef gs_os_api_new
  578. #define gs_os_api_new gs_os_api_new_default
  579. #endif
  580. #ifndef gs_malloc
  581. #define gs_malloc(__SZ) (gs_ctx()->os.malloc(__SZ))
  582. #endif
  583. #ifndef gs_malloc_init
  584. #define gs_malloc_init(__T) ((__T*)gs_ctx()->os.malloc_init(sizeof(__T)))
  585. #endif
  586. #ifndef gs_free
  587. #define gs_free(__MEM) (gs_ctx()->os.free(__MEM))
  588. #endif
  589. #ifndef gs_realloc
  590. #define gs_realloc(__MEM, __AZ) (gs_ctx()->os.realloc(__MEM, __AZ))
  591. #endif
  592. #ifndef gs_calloc
  593. #define gs_calloc(__NUM, __SZ) (gs_ctx()->os.calloc(__NUM, __SZ))
  594. #endif
  595. #ifndef gs_alloca
  596. #define gs_alloca(__SZ) (gs_ctx()->os.alloca(__SZ))
  597. #endif
  598. #ifndef gs_strdup
  599. #define gs_strdup(__STR) (gs_ctx()->os.strdup(__STR))
  600. #endif
  601. // Modified from: https://stackoverflow.com/questions/11815894/how-to-read-write-arbitrary-bits-in-c-c
  602. #define gs_bit_mask(INDEX, SIZE)\
  603. (((1u << (SIZE)) - 1u) << (INDEX))
  604. #define gs_write_bits(DATA, INDEX, SIZE, VAL)\
  605. ((DATA) = (((DATA) & (~BIT_MASK((INDEX), (SIZE)))) | (((VAL) << (INDEX)) & (BIT_MASK((INDEX), (SIZE))))))
  606. #define gs_read_bits(DATA, INDEX, SIZE)\
  607. (((DATA) & BIT_MASK((INDEX), (SIZE))) >> (INDEX))
  608. /*============================================================
  609. // Result
  610. ============================================================*/
  611. typedef enum gs_result
  612. {
  613. GS_RESULT_SUCCESS,
  614. GS_RESULT_IN_PROGRESS,
  615. GS_RESULT_INCOMPLETE,
  616. GS_RESULT_FAILURE
  617. } gs_result;
  618. /*===================================
  619. // Resource Handles
  620. ===================================*/
  621. // Useful typedefs for typesafe, internal resource handles
  622. #define gs_handle(TYPE)\
  623. gs_handle_##TYPE
  624. #define gs_handle_decl(TYPE)\
  625. typedef struct {uint32_t id;} gs_handle(TYPE);\
  626. gs_inline\
  627. gs_handle(TYPE) gs_handle_invalid_##TYPE()\
  628. {\
  629. gs_handle(TYPE) h;\
  630. h.id = UINT32_MAX;\
  631. return h;\
  632. }\
  633. \
  634. gs_inline\
  635. gs_handle(TYPE) gs_handle_create_##TYPE(uint32_t id)\
  636. {\
  637. gs_handle(TYPE) h;\
  638. h.id = id;\
  639. return h;\
  640. }
  641. #define gs_handle_invalid(__TYPE)\
  642. gs_handle_invalid_##__TYPE()
  643. #define gs_handle_create(__TYPE, __ID)\
  644. gs_handle_create_##__TYPE(__ID)
  645. #define gs_handle_is_valid(HNDL)\
  646. ((HNDL.id) != UINT32_MAX)
  647. /*===================================
  648. // Color
  649. ===================================*/
  650. #define gs_hsv(...) gs_hsv_ctor(__VA_ARGS__)
  651. #define gs_color(...) gs_color_ctor(__VA_ARGS__)
  652. typedef struct gs_hsv_t
  653. {
  654. union
  655. {
  656. float hsv[3];
  657. struct
  658. {
  659. float h, s, v;
  660. };
  661. };
  662. } gs_hsv_t;
  663. gs_force_inline
  664. gs_hsv_t gs_hsv_ctor(float h, float s, float v)
  665. {
  666. gs_hsv_t hsv;
  667. hsv.h = h;
  668. hsv.s = s;
  669. hsv.v = v;
  670. return hsv;
  671. }
  672. typedef struct gs_color_t
  673. {
  674. union
  675. {
  676. uint8_t rgba[4];
  677. struct
  678. {
  679. uint8_t r, g, b, a;
  680. };
  681. };
  682. } gs_color_t;
  683. gs_force_inline
  684. gs_color_t gs_color_ctor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
  685. {
  686. gs_color_t color;
  687. color.r = r;
  688. color.g = g;
  689. color.b = b;
  690. color.a = a;
  691. return color;
  692. }
  693. #define GS_COLOR_BLACK gs_color(0, 0, 0, 255)
  694. #define GS_COLOR_WHITE gs_color(255, 255, 255, 255)
  695. #define GS_COLOR_RED gs_color(255, 0, 0, 255)
  696. #define GS_COLOR_GREEN gs_color(0, 255, 0, 255)
  697. #define GS_COLOR_BLUE gs_color(0, 0, 255, 255)
  698. #define GS_COLOR_ORANGE gs_color(255, 100, 0, 255)
  699. #define GS_COLOR_YELLOW gs_color(255, 255, 0, 255)
  700. #define GS_COLOR_PURPLE gs_color(128, 0, 128, 255)
  701. #define GS_COLOR_MAROON gs_color(128, 0, 0, 255)
  702. #define GS_COLOR_BROWN gs_color(165, 42, 42, 255)
  703. #define GS_COLOR_MAGENTA gs_color(255, 0, 255, 255)
  704. gs_force_inline
  705. gs_color_t gs_color_alpha(gs_color_t c, uint8_t a)
  706. {
  707. return gs_color(c.r, c.g, c.b, a);
  708. }
  709. gs_force_inline gs_hsv_t
  710. gs_rgb2hsv(gs_color_t in)
  711. {
  712. float ir = (float)in.r / 255.f;
  713. float ig = (float)in.g / 255.f;
  714. float ib = (float)in.b / 255.f;
  715. float ia = (float)in.a / 255.f;
  716. gs_hsv_t out = gs_default_val();
  717. double min, max, delta;
  718. min = ir < ig ? ir : ig;
  719. min = min < ib ? min : ib;
  720. max = ir > ig ? ir : ig;
  721. max = max > ib ? max : ib;
  722. out.v = max; // v
  723. delta = max - min;
  724. if (delta < 0.00001)
  725. {
  726. out.s = 0;
  727. out.h = 0; // undefined, maybe nan?
  728. return out;
  729. }
  730. if(max > 0.0)
  731. { // NOTE: if Max is == 0, this divide would cause a crash
  732. out.s = (delta / max); // s
  733. }
  734. else
  735. {
  736. // if max is 0, then r = g = b = 0
  737. // s = 0, h is undefined
  738. out.s = 0.0;
  739. out.h = NAN; // its now undefined
  740. return out;
  741. }
  742. if(ir >= max) // > is bogus, just keeps compilor happy
  743. out.h = (ig - ib) / delta; // between yellow & magenta
  744. else
  745. if( ig >= max )
  746. out.h = 2.0 + ( ib - ir ) / delta; // between cyan & yellow
  747. else
  748. out.h = 4.0 + ( ir - ig ) / delta; // between magenta & cyan
  749. out.h *= 60.0; // degrees
  750. if( out.h < 0.0 )
  751. out.h += 360.0;
  752. return out;
  753. }
  754. gs_force_inline gs_color_t
  755. gs_hsv2rgb(gs_hsv_t in)
  756. {
  757. double hh, p, q, t, ff;
  758. long i;
  759. gs_color_t out;
  760. if(in.s <= 0.0) { // < is bogus, just shuts up warnings
  761. out.r = in.v * 255;
  762. out.g = in.v * 255;
  763. out.b = in.v * 255;
  764. out.a = 255;
  765. return out;
  766. }
  767. hh = in.h;
  768. if(hh >= 360.0) hh = 0.0;
  769. hh /= 60.0;
  770. i = (long)hh;
  771. ff = hh - i;
  772. p = in.v * (1.0 - in.s);
  773. q = in.v * (1.0 - (in.s * ff));
  774. t = in.v * (1.0 - (in.s * (1.0 - ff)));
  775. uint8_t iv = in.v * 255;
  776. uint8_t it = t * 255;
  777. uint8_t ip = p * 255;
  778. uint8_t iq = q * 255;
  779. switch(i)
  780. {
  781. case 0:
  782. out.r = iv;
  783. out.g = it;
  784. out.b = ip;
  785. break;
  786. case 1:
  787. out.r = iq;
  788. out.g = iv;
  789. out.b = ip;
  790. break;
  791. case 2:
  792. out.r = ip;
  793. out.g = iv;
  794. out.b = it;
  795. break;
  796. case 3:
  797. out.r = ip;
  798. out.g = iq;
  799. out.b = iv;
  800. break;
  801. case 4:
  802. out.r = it;
  803. out.g = ip;
  804. out.b = iv;
  805. break;
  806. case 5:
  807. default:
  808. out.r = iv;
  809. out.g = ip;
  810. out.b = iq;
  811. break;
  812. }
  813. return out;
  814. }
  815. /*===================================
  816. // String Utils
  817. ===================================*/
  818. gs_force_inline uint32_t
  819. gs_string_length(const char* txt)
  820. {
  821. uint32_t sz = 0;
  822. while (txt != NULL && txt[ sz ] != '\0')
  823. {
  824. sz++;
  825. }
  826. return sz;
  827. }
  828. #define gs_strlen gs_string_length
  829. // Expects null terminated strings
  830. gs_force_inline b32
  831. gs_string_compare_equal
  832. (
  833. const char* txt,
  834. const char* cmp
  835. )
  836. {
  837. // Grab sizes of both strings
  838. uint32_t a_sz = gs_string_length(txt);
  839. uint32_t b_sz = gs_string_length(cmp);
  840. // Return false if sizes do not match
  841. if (a_sz != b_sz)
  842. {
  843. return false;
  844. }
  845. for(uint32_t i = 0; i < a_sz; ++i)
  846. {
  847. if (*txt++ != *cmp++)
  848. {
  849. return false;
  850. }
  851. };
  852. return true;
  853. }
  854. gs_force_inline b32
  855. gs_string_compare_equal_n
  856. (
  857. const char* txt,
  858. const char* cmp,
  859. uint32_t n
  860. )
  861. {
  862. uint32_t a_sz = gs_string_length(txt);
  863. uint32_t b_sz = gs_string_length(cmp);
  864. // Not enough characters to do operation
  865. if (a_sz < n || b_sz < n)
  866. {
  867. return false;
  868. }
  869. for (uint32_t i = 0; i < n; ++i)
  870. {
  871. if (*txt++ != *cmp++)
  872. {
  873. return false;
  874. }
  875. };
  876. return true;
  877. }
  878. gs_force_inline void
  879. gs_util_str_to_lower
  880. (
  881. const char* src,
  882. char* buffer,
  883. size_t buffer_sz
  884. )
  885. {
  886. size_t src_sz = gs_string_length(src);
  887. size_t len = gs_min(src_sz, buffer_sz-1);
  888. for (uint32_t i = 0; i < len; ++i) {
  889. buffer[i] = tolower(src[i]);
  890. }
  891. if (len) buffer[len] = '\0';
  892. }
  893. gs_force_inline b32
  894. gs_util_str_is_numeric(const char* str)
  895. {
  896. const char* at = str;
  897. while (at && *at)
  898. {
  899. while (*at == '\n' || *at == '\t' || *at == ' ' || *at == '\r') at++;;
  900. char c = *at++;
  901. if (c < '0' || c > '9')
  902. {
  903. return false;
  904. }
  905. }
  906. return true;
  907. }
  908. // Will return a null buffer if file does not exist or allocation fails
  909. GS_API_DECL char*
  910. gs_read_file_contents_into_string_null_term (const char* file_path, const char* mode, size_t* _sz);
  911. gs_force_inline
  912. b32 gs_util_file_exists(const char* file_path)
  913. {
  914. FILE* fp = fopen(file_path, "r");
  915. if (fp)
  916. {
  917. fclose(fp);
  918. return true;
  919. }
  920. return false;
  921. }
  922. gs_force_inline
  923. void gs_util_get_file_extension
  924. (
  925. char* buffer,
  926. uint32_t buffer_size,
  927. const char* file_path
  928. )
  929. {
  930. // assumes that buffer and buffer_size is non-zero
  931. const char* extension = strrchr(file_path, '.');
  932. if (extension) {
  933. uint32_t extension_len = strlen(extension+1);
  934. uint32_t len = (extension_len >= buffer_size) ? buffer_size - 1 : extension_len;
  935. memcpy(buffer, extension+1, len);
  936. buffer[len] = '\0';
  937. } else {
  938. buffer[0] = '\0';
  939. }
  940. }
  941. gs_force_inline
  942. void gs_util_get_dir_from_file
  943. (
  944. char* buffer,
  945. uint32_t buffer_size,
  946. const char* file_path
  947. )
  948. {
  949. uint32_t str_len = gs_string_length(file_path);
  950. const char* end = (file_path + str_len);
  951. for (uint32_t i = 0; i < str_len; ++i)
  952. {
  953. if (file_path[i] == '/' || file_path[i] == '\\')
  954. {
  955. end = &file_path[i];
  956. }
  957. }
  958. size_t dir_len = end - file_path;
  959. memcpy(buffer, file_path, gs_min(buffer_size, dir_len + 1));
  960. if (dir_len + 1 <= buffer_size) {
  961. buffer[dir_len] = '\0';
  962. }
  963. }
  964. gs_force_inline
  965. void gs_util_get_file_name
  966. (
  967. char* buffer,
  968. uint32_t buffer_size,
  969. const char* file_path
  970. )
  971. {
  972. uint32_t str_len = gs_string_length(file_path);
  973. const char* file_start = file_path;
  974. const char* file_end = (file_path + str_len);
  975. for (uint32_t i = 0; i < str_len; ++i)
  976. {
  977. if (file_path[i] == '/' || file_path[i] == '\\')
  978. {
  979. file_start = &file_path[i + 1];
  980. }
  981. else if (file_path[i] == '.')
  982. {
  983. file_end = &file_path[i];
  984. }
  985. }
  986. size_t dir_len = file_end - file_start;
  987. memcpy(buffer, file_start, gs_min(buffer_size, dir_len + 1));
  988. if (dir_len + 1 <= buffer_size) {
  989. buffer[dir_len] = '\0';
  990. }
  991. }
  992. gs_force_inline
  993. void gs_util_string_substring
  994. (
  995. const char* src,
  996. char* dst,
  997. size_t sz,
  998. uint32_t start,
  999. uint32_t end
  1000. )
  1001. {
  1002. uint32_t str_len = gs_string_length(src);
  1003. if (end > str_len) {
  1004. end = str_len;
  1005. }
  1006. if (start > str_len) {
  1007. start = str_len;
  1008. }
  1009. const char* at = src + start;
  1010. const char* e = src + end;
  1011. uint32_t ct = 0;
  1012. while (at && *at != '\0' && at != e)
  1013. {
  1014. dst[ ct ] = *at;
  1015. at++;
  1016. ct++;
  1017. }
  1018. }
  1019. gs_force_inline
  1020. void gs_util_string_remove_character
  1021. (
  1022. const char* src,
  1023. char* buffer,
  1024. uint32_t buffer_size,
  1025. char delimiter
  1026. )
  1027. {
  1028. uint32_t ct = 0;
  1029. uint32_t str_len = gs_string_length(src);
  1030. const char* at = src;
  1031. while (at && *at != '\0' && ct < buffer_size)
  1032. {
  1033. char c = *at;
  1034. if (c != delimiter) {
  1035. buffer[ ct ] = c;
  1036. ct++;
  1037. }
  1038. at++;
  1039. }
  1040. }
  1041. gs_force_inline
  1042. void gs_util_string_replace(
  1043. char* buffer,
  1044. size_t buffer_sz,
  1045. const char* replace,
  1046. char fallback
  1047. )
  1048. {
  1049. // Replace all characters with characters of keyword, then the rest replace with spaces
  1050. size_t len = gs_string_length(replace);
  1051. for (uint32_t c = 0; c < buffer_sz; ++c)
  1052. {
  1053. if (c < len)
  1054. {
  1055. buffer[c] = replace[c];
  1056. }
  1057. else
  1058. {
  1059. buffer[c] = fallback;
  1060. }
  1061. }
  1062. }
  1063. gs_force_inline
  1064. void gs_util_string_replace_delim
  1065. (
  1066. const char* source_str,
  1067. char* buffer,
  1068. uint32_t buffer_size,
  1069. char delimiter,
  1070. char replace
  1071. )
  1072. {
  1073. uint32_t str_len = gs_string_length(source_str);
  1074. const char* at = source_str;
  1075. while (at && *at != '\0')
  1076. {
  1077. char c = *at;
  1078. if (c == delimiter) {
  1079. c = replace;
  1080. }
  1081. buffer[(at - source_str)] = c;
  1082. at++;
  1083. }
  1084. }
  1085. GS_API_DECL char*
  1086. gs_util_string_concat(char* s1, const char* s2);
  1087. gs_force_inline
  1088. void gs_util_normalize_path
  1089. (
  1090. const char* path,
  1091. char* buffer,
  1092. uint32_t buffer_size
  1093. )
  1094. {
  1095. // Normalize the path somehow...
  1096. }
  1097. // Custom printf defines
  1098. #ifndef gs_printf
  1099. #ifdef __MINGW32__
  1100. #define gs_printf(__FMT, ...) __mingw_printf(__FMT, ##__VA_ARGS__)
  1101. #elif (defined GS_PLATFORM_ANDROID)
  1102. #include <android/log.h>
  1103. #define gs_printf(__FMT, ...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __FMT, ## __VA_ARGS__))
  1104. #else
  1105. gs_force_inline void
  1106. gs_printf
  1107. (
  1108. const char* fmt,
  1109. ...
  1110. )
  1111. {
  1112. va_list args;
  1113. va_start (args, fmt);
  1114. vprintf(fmt, args);
  1115. va_end(args);
  1116. }
  1117. #endif
  1118. #endif
  1119. #define gs_println(__FMT, ...)\
  1120. do {\
  1121. gs_printf(__FMT, ## __VA_ARGS__);\
  1122. gs_printf("\n");\
  1123. } while (0)
  1124. #ifndef gs_fprintf
  1125. gs_force_inline
  1126. void gs_fprintf
  1127. (
  1128. FILE* fp,
  1129. const char* fmt,
  1130. ...
  1131. )
  1132. {
  1133. va_list args;
  1134. va_start (args, fmt);
  1135. vfprintf(fp, fmt, args);
  1136. va_end(args);
  1137. }
  1138. #endif
  1139. gs_force_inline
  1140. void gs_fprintln
  1141. (
  1142. FILE* fp,
  1143. const char* fmt,
  1144. ...
  1145. )
  1146. {
  1147. va_list args;
  1148. va_start(args, fmt);
  1149. vfprintf(fp, fmt, args);
  1150. va_end(args);
  1151. gs_fprintf(fp, "\n");
  1152. }
  1153. gs_force_inline
  1154. void gs_fprintln_t
  1155. (
  1156. FILE* fp,
  1157. uint32_t tabs,
  1158. const char* fmt,
  1159. ...
  1160. )
  1161. {
  1162. va_list args;
  1163. va_start(args, fmt);
  1164. for (uint32_t i = 0; i < tabs; ++i)
  1165. {
  1166. gs_fprintf(fp, "\t");
  1167. }
  1168. vfprintf(fp, fmt, args);
  1169. va_end(args);
  1170. gs_fprintf(fp, "\n");
  1171. }
  1172. #ifdef __MINGW32__
  1173. #define gs_snprintf(__NAME, __SZ, __FMT, ...) __mingw_snprintf(__NAME, __SZ, __FMT, ## __VA_ARGS__)
  1174. #else
  1175. gs_force_inline
  1176. void gs_snprintf
  1177. (
  1178. char* buffer,
  1179. size_t buffer_size,
  1180. const char* fmt,
  1181. ...
  1182. )
  1183. {
  1184. va_list args;
  1185. va_start(args, fmt);
  1186. vsnprintf(buffer, buffer_size, fmt, args);
  1187. va_end(args);
  1188. }
  1189. #endif
  1190. #define gs_transient_buffer(__N, __SZ)\
  1191. char __N[__SZ] = gs_default_val();\
  1192. memset(__N, 0, __SZ);
  1193. #define gs_snprintfc(__NAME, __SZ, __FMT, ...)\
  1194. char __NAME[__SZ] = gs_default_val();\
  1195. gs_snprintf(__NAME, __SZ, __FMT, ## __VA_ARGS__);
  1196. gs_force_inline
  1197. uint32_t gs_util_safe_truncate_u64(uint64_t value)
  1198. {
  1199. gs_assert(value <= 0xFFFFFFFF);
  1200. uint32_t result = (uint32_t)value;
  1201. return result;
  1202. }
  1203. gs_force_inline
  1204. uint32_t gs_hash_uint32_t(uint32_t x)
  1205. {
  1206. x = ((x >> 16) ^ x) * 0x45d9f3b;
  1207. x = ((x >> 16) ^ x) * 0x45d9f3b;
  1208. x = (x >> 16) ^ x;
  1209. return x;
  1210. }
  1211. #define gs_hash_u32_ip(__X, __OUT)\
  1212. do {\
  1213. __OUT = ((__X >> 16) ^ __X) * 0x45d9f3b;\
  1214. __OUT = ((__OUT >> 16) ^ __OUT) * 0x45d9f3b;\
  1215. __OUT = (__OUT >> 16) ^ __OUT;\
  1216. } while (0)
  1217. gs_force_inline
  1218. uint32_t gs_hash_u64(uint64_t x)
  1219. {
  1220. x = (x ^ (x >> 31) ^ (x >> 62)) * UINT64_C(0x319642b2d24d8ec3);
  1221. x = (x ^ (x >> 27) ^ (x >> 54)) * UINT64_C(0x96de1b173f119089);
  1222. x = x ^ (x >> 30) ^ (x >> 60);
  1223. return (uint32_t)x;
  1224. }
  1225. // Note(john): source: http://www.cse.yorku.ca/~oz/hash.html
  1226. // djb2 hash by dan bernstein
  1227. gs_force_inline
  1228. uint32_t gs_hash_str(const char* str)
  1229. {
  1230. uint32_t hash = 5381;
  1231. s32 c;
  1232. while ((c = *str++))
  1233. {
  1234. hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  1235. }
  1236. return hash;
  1237. }
  1238. gs_force_inline
  1239. uint64_t gs_hash_str64(const char* str)
  1240. {
  1241. uint32_t hash1 = 5381;
  1242. uint32_t hash2 = 52711;
  1243. uint32_t i = gs_string_length(str);
  1244. while(i--)
  1245. {
  1246. char c = str[ i ];
  1247. hash1 = (hash1 * 33) ^ c;
  1248. hash2 = (hash2 * 33) ^ c;
  1249. }
  1250. return (hash1 >> 0) * 4096 + (hash2 >> 0);
  1251. }
  1252. gs_force_inline
  1253. bool gs_compare_bytes(void* b0, void* b1, size_t len)
  1254. {
  1255. return 0 == memcmp(b0, b1, len);
  1256. }
  1257. // Hash generic bytes using (ripped directly from Sean Barret's stb_ds.h)
  1258. #define GS_SIZE_T_BITS ((sizeof(size_t)) * 8)
  1259. #define GS_SIPHASH_C_ROUNDS 1
  1260. #define GS_SIPHASH_D_ROUNDS 1
  1261. #define gs_rotate_left(__V, __N) (((__V) << (__N)) | ((__V) >> (GS_SIZE_T_BITS - (__N))))
  1262. #define gs_rotate_right(__V, __N) (((__V) >> (__N)) | ((__V) << (GS_SIZE_T_BITS - (__N))))
  1263. #ifdef _MSC_VER
  1264. #pragma warning(push)
  1265. #pragma warning(disable:4127) // conditional expression is constant, for do..while(0) and sizeof()==
  1266. #endif
  1267. gs_force_inline
  1268. size_t gs_hash_siphash_bytes(void *p, size_t len, size_t seed)
  1269. {
  1270. unsigned char *d = (unsigned char *) p;
  1271. size_t i,j;
  1272. size_t v0,v1,v2,v3, data;
  1273. // hash that works on 32- or 64-bit registers without knowing which we have
  1274. // (computes different results on 32-bit and 64-bit platform)
  1275. // derived from siphash, but on 32-bit platforms very different as it uses 4 32-bit state not 4 64-bit
  1276. v0 = ((((size_t) 0x736f6d65 << 16) << 16) + 0x70736575) ^ seed;
  1277. v1 = ((((size_t) 0x646f7261 << 16) << 16) + 0x6e646f6d) ^ ~seed;
  1278. v2 = ((((size_t) 0x6c796765 << 16) << 16) + 0x6e657261) ^ seed;
  1279. v3 = ((((size_t) 0x74656462 << 16) << 16) + 0x79746573) ^ ~seed;
  1280. #ifdef STBDS_TEST_SIPHASH_2_4
  1281. // hardcoded with key material in the siphash test vectors
  1282. v0 ^= 0x0706050403020100ull ^ seed;
  1283. v1 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
  1284. v2 ^= 0x0706050403020100ull ^ seed;
  1285. v3 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
  1286. #endif
  1287. #define gs_sipround() \
  1288. do { \
  1289. v0 += v1; v1 = gs_rotate_left(v1, 13); v1 ^= v0; v0 = gs_rotate_left(v0,GS_SIZE_T_BITS/2); \
  1290. v2 += v3; v3 = gs_rotate_left(v3, 16); v3 ^= v2; \
  1291. v2 += v1; v1 = gs_rotate_left(v1, 17); v1 ^= v2; v2 = gs_rotate_left(v2,GS_SIZE_T_BITS/2); \
  1292. v0 += v3; v3 = gs_rotate_left(v3, 21); v3 ^= v0; \
  1293. } while (0)
  1294. for (i=0; i+sizeof(size_t) <= len; i += sizeof(size_t), d += sizeof(size_t)) {
  1295. data = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
  1296. data |= (size_t) (d[4] | (d[5] << 8) | (d[6] << 16) | (d[7] << 24)) << 16 << 16; // discarded if size_t == 4
  1297. v3 ^= data;
  1298. for (j=0; j < GS_SIPHASH_C_ROUNDS; ++j)
  1299. gs_sipround();
  1300. v0 ^= data;
  1301. }
  1302. data = len << (GS_SIZE_T_BITS-8);
  1303. switch (len - i) {
  1304. case 7: data |= ((size_t) d[6] << 24) << 24; // fall through
  1305. case 6: data |= ((size_t) d[5] << 20) << 20; // fall through
  1306. case 5: data |= ((size_t) d[4] << 16) << 16; // fall through
  1307. case 4: data |= (d[3] << 24); // fall through
  1308. case 3: data |= (d[2] << 16); // fall through
  1309. case 2: data |= (d[1] << 8); // fall through
  1310. case 1: data |= d[0]; // fall through
  1311. case 0: break;
  1312. }
  1313. v3 ^= data;
  1314. for (j=0; j < GS_SIPHASH_C_ROUNDS; ++j)
  1315. gs_sipround();
  1316. v0 ^= data;
  1317. v2 ^= 0xff;
  1318. for (j=0; j < GS_SIPHASH_D_ROUNDS; ++j)
  1319. gs_sipround();
  1320. #if 0
  1321. return v0^v1^v2^v3;
  1322. #else
  1323. return v1^v2^v3; // slightly stronger since v0^v3 in above cancels out final round operation? I tweeted at the authors of SipHash about this but they didn't reply
  1324. #endif
  1325. }
  1326. gs_force_inline
  1327. size_t gs_hash_murmur3(void *p, size_t len, size_t seed)
  1328. {
  1329. const uint8_t* data = (const uint8_t*)p;
  1330. size_t h = seed ^ len;
  1331. for (uint32_t i = 0; i < len / 4; ++i) {
  1332. uint32_t k = *(uint32_t*)(data + i * 4);
  1333. k *= 0xcc9e2d51;
  1334. k = (k << 15) | (k >> (32 - 15));
  1335. k *= 0x1b873593;
  1336. h ^= k;
  1337. h = (h << 13) | (h >> (32 - 13));
  1338. h = h * 5 + 0xe6546b64;
  1339. }
  1340. // Handle remaining bytes
  1341. const uint8_t* tail = data + (len & ~3);
  1342. uint32_t k1 = 0;
  1343. switch (len & 3) {
  1344. case 3: k1 ^= tail[2] << 16;
  1345. case 2: k1 ^= tail[1] << 8;
  1346. case 1: k1 ^= tail[0];
  1347. k1 *= 0xcc9e2d51;
  1348. k1 = (k1 << 15) | (k1 >> (32 - 15));
  1349. k1 *= 0x1b873593;
  1350. h ^= k1;
  1351. }
  1352. h ^= h >> 16;
  1353. h *= 0x85ebca6b;
  1354. h ^= h >> 13;
  1355. h *= 0xc2b2ae35;
  1356. h ^= h >> 16;
  1357. return h;
  1358. }
  1359. gs_force_inline
  1360. size_t gs_hash_bytes(void *p, size_t len, size_t seed)
  1361. {
  1362. #if 1
  1363. return gs_hash_siphash_bytes(p, len, seed);
  1364. #else
  1365. return gs_hash_murmur3(p, len, seed);
  1366. #endif
  1367. }
  1368. #ifdef _MSC_VER
  1369. #pragma warning(pop)
  1370. #endif
  1371. /* Resource Loading Util */
  1372. GS_API_DECL bool32_t gs_util_load_texture_data_from_file(const char* file_path, int32_t* width, int32_t* height, uint32_t* num_comps, void** data, bool32_t flip_vertically_on_load);
  1373. GS_API_DECL bool32_t gs_util_load_texture_data_from_memory(const void* memory, size_t sz, int32_t* width, int32_t* height, uint32_t* num_comps, void** data, bool32_t flip_vertically_on_load);
  1374. /** @} */ // end of gs_util
  1375. /*========================
  1376. // GS_CONTAINERS
  1377. ========================*/
  1378. /** @defgroup gs_containers Containers
  1379. * Gunslinger Containers
  1380. * @{
  1381. */
  1382. /*========================
  1383. // Byte Buffer
  1384. ========================*/
  1385. /** @defgroup gs_byte_buffer Byte Buffer
  1386. * @ingroup gs_containers
  1387. * Byte Buffer
  1388. */
  1389. #define GS_BYTE_BUFFER_DEFAULT_CAPCITY 1024
  1390. /** @addtogroup gs_byte_buffer
  1391. */
  1392. typedef struct gs_byte_buffer_t
  1393. {
  1394. uint8_t* data; // Buffer that actually holds all relevant byte data
  1395. uint32_t size; // Current size of the stored buffer data
  1396. uint32_t position; // Current read/write position in the buffer
  1397. uint32_t capacity; // Current max capacity for the buffer
  1398. } gs_byte_buffer_t;
  1399. // Generic "write" function for a byte buffer
  1400. #define gs_byte_buffer_write(__BB, __T, __VAL)\
  1401. do {\
  1402. gs_byte_buffer_t* __BUFFER = __BB;\
  1403. if (!__BUFFER || !__BUFFER->data) break;\
  1404. usize __SZ = sizeof(__T);\
  1405. usize __TWS = __BUFFER->position + __SZ;\
  1406. if (__TWS >= (usize)__BUFFER->capacity)\
  1407. {\
  1408. usize __CAP = __BUFFER->capacity * 2;\
  1409. while(__CAP < __TWS)\
  1410. {\
  1411. __CAP *= 2;\
  1412. }\
  1413. uint8_t* __OLD_DATA = __BUFFER->data;\
  1414. uint32_t __OLD_POS = __BUFFER->position;\
  1415. uint32_t __OLD_SIZE = __BUFFER->size;\
  1416. gs_byte_buffer_resize(__BUFFER, __CAP);\
  1417. if (__BUFFER->data == NULL) {\
  1418. __BUFFER->data = __OLD_DATA;\
  1419. __BUFFER->position = __OLD_POS;\
  1420. __BUFFER->size = __OLD_SIZE;\
  1421. break;\
  1422. }\
  1423. }\
  1424. if (!__BUFFER || !__BUFFER->data || __BUFFER->position + sizeof(__T) > __BUFFER->capacity) break;\
  1425. *(__T*)(__BUFFER->data + __BUFFER->position) = __VAL;\
  1426. __BUFFER->position += (uint32_t)__SZ;\
  1427. __BUFFER->size += (uint32_t)__SZ;\
  1428. } while (0)
  1429. // Generic "read" function
  1430. #define gs_byte_buffer_read(__BUFFER, __T, __VAL_P)\
  1431. do {\
  1432. __T* __V = (__T*)(__VAL_P);\
  1433. gs_byte_buffer_t* __BB = (__BUFFER);\
  1434. *(__V) = *(__T*)(__BB->data + __BB->position);\
  1435. __BB->position += sizeof(__T);\
  1436. } while (0)
  1437. // Defines variable and sets value from buffer in place
  1438. // Use to construct a new variable
  1439. #define gs_byte_buffer_readc(__BUFFER, __T, __NAME)\
  1440. __T __NAME = gs_default_val();\
  1441. gs_byte_buffer_read((__BUFFER), __T, &__NAME);
  1442. #define gs_byte_buffer_read_bulkc(__BUFFER, __T, __NAME, __SZ)\
  1443. __T __NAME = gs_default_val();\
  1444. __T* gs_macro_cat(__NAME, __LINE__) = &(__NAME);\
  1445. gs_byte_buffer_read_bulk(__BUFFER, (void**)&gs_macro_cat(__NAME, __LINE__), __SZ);
  1446. GS_API_DECL void gs_byte_buffer_init(gs_byte_buffer_t* buffer);
  1447. GS_API_DECL gs_byte_buffer_t gs_byte_buffer_new();
  1448. GS_API_DECL void gs_byte_buffer_free(gs_byte_buffer_t* buffer);
  1449. GS_API_DECL void gs_byte_buffer_clear(gs_byte_buffer_t* buffer);
  1450. GS_API_DECL bool gs_byte_buffer_empty(gs_byte_buffer_t* buffer);
  1451. GS_API_DECL size_t gs_byte_buffer_size(gs_byte_buffer_t* buffer);
  1452. GS_API_DECL void gs_byte_buffer_resize(gs_byte_buffer_t* buffer, size_t sz);
  1453. GS_API_DECL void gs_byte_buffer_seek_to_beg(gs_byte_buffer_t* buffer);
  1454. GS_API_DECL void gs_byte_buffer_seek_to_end(gs_byte_buffer_t* buffer);
  1455. GS_API_DECL void gs_byte_buffer_advance_position(gs_byte_buffer_t* buffer, size_t sz);
  1456. GS_API_DECL void gs_byte_buffer_write_str(gs_byte_buffer_t* buffer, const char* str); // Expects a null terminated string
  1457. GS_API_DECL void gs_byte_buffer_read_str(gs_byte_buffer_t* buffer, char* str); // Expects an allocated string
  1458. GS_API_DECL void gs_byte_buffer_write_bulk(gs_byte_buffer_t* buffer, void* src, size_t sz);
  1459. GS_API_DECL void gs_byte_buffer_read_bulk(gs_byte_buffer_t* buffer, void** dst, size_t sz);
  1460. GS_API_DECL gs_result gs_byte_buffer_write_to_file(gs_byte_buffer_t* buffer, const char* output_path); // Assumes that the output directory exists
  1461. GS_API_DECL gs_result gs_byte_buffer_read_from_file(gs_byte_buffer_t* buffer, const char* file_path); // Assumes an allocated byte buffer
  1462. GS_API_DECL void gs_byte_buffer_memset(gs_byte_buffer_t* buffer, uint8_t val);
  1463. /*====================//
  1464. //=== Static Array ===//
  1465. ======================*/
  1466. #define gs_array(__T, __N)\
  1467. struct {\
  1468. __T data[__N];\
  1469. size_t size;\
  1470. }
  1471. #define gs_array_capacity(__Q) (sizeof((__Q).data) / sizeof((__Q).data[0]))
  1472. #define gs_array_push(__Q, __V)\
  1473. do {\
  1474. const size_t cap = gs_array_capacity((__Q));\
  1475. if ((__Q).size < cap) {\
  1476. (__Q).data[(__Q).size++] = (__V);\
  1477. }\
  1478. } while (0)
  1479. #define gs_array_pop(__Q)\
  1480. do {\
  1481. if ((__Q).size) {\
  1482. const size_t cap = gs_array_capacity((__Q));\
  1483. (__Q).size--;\
  1484. }\
  1485. } while (0)
  1486. #define gs_array_empty(__Q) (__Q).size ? false : true
  1487. #define gs_array_clear(__Q) do {(__Q).size = 0;} while (0)
  1488. #define gs_array_back(__Q)\
  1489. !gs_array_empty(__Q) ? &__Q.data[__Q.size - 1] : NULL
  1490. /*=============================//
  1491. //=== Static Circular Queue ===//
  1492. ===============================*/
  1493. #define gs_cqueue(__T, __N)\
  1494. struct {\
  1495. __T data[__N];\
  1496. size_t size;\
  1497. size_t head;\
  1498. }
  1499. #define gs_cqueue_size(__Q) ((__Q).size)
  1500. #define gs_cqueue_capacity(__Q) (sizeof((__Q).data) / sizeof((__Q).data[0]))
  1501. #define gs_cqueue_push(__Q, __V)\
  1502. do {\
  1503. const size_t cap = gs_cqueue_capacity((__Q));\
  1504. if ((__Q).size < cap) {\
  1505. (__Q).data[((__Q).head + (__Q).size++) % cap] = (__V);\
  1506. }\
  1507. } while (0)
  1508. #define gs_cqueue_pop(__Q)\
  1509. do {\
  1510. if ((__Q).size) {\
  1511. const size_t cap = gs_cqueue_capacity((__Q));\
  1512. (__Q).size--;\
  1513. (__Q).head = ((__Q).head + 1) % cap;\
  1514. }\
  1515. else {\
  1516. (__Q).head = 0;\
  1517. }\
  1518. } while (0)
  1519. #define gs_cqueue_peek(__Q) (__Q).size ? &(__Q).data[(__Q).head] : NULL
  1520. #define gs_cqueue_empty(__Q) (__Q).size ? false : true
  1521. #define gs_cqueue_clear(__Q)\
  1522. do {\
  1523. (__Q).size = 0;\
  1524. (__Q).head = 0;\
  1525. } while (0)
  1526. /*===================================
  1527. // Dynamic Array
  1528. ===================================*/
  1529. /** @defgroup gs_dyn_array Dynamic Array
  1530. * @ingroup gs_containers
  1531. * Dynamic Array
  1532. */
  1533. /** @addtogroup gs_dyn_array
  1534. */
  1535. typedef struct gs_dyn_array
  1536. {
  1537. int32_t size;
  1538. int32_t capacity;
  1539. } gs_dyn_array;
  1540. #define gs_dyn_array_head(__ARR)\
  1541. ((gs_dyn_array*)((uint8_t*)(__ARR) - sizeof(gs_dyn_array)))
  1542. #define gs_dyn_array_size(__ARR)\
  1543. (__ARR == NULL ? 0 : gs_dyn_array_head((__ARR))->size)
  1544. #define gs_dyn_array_capacity(__ARR)\
  1545. (__ARR == NULL ? 0 : gs_dyn_array_head((__ARR))->capacity)
  1546. #define gs_dyn_array_full(__ARR)\
  1547. ((gs_dyn_array_size((__ARR)) == gs_dyn_array_capacity((__ARR))))
  1548. #define gs_dyn_array_byte_size(__ARR)\
  1549. (gs_dyn_array_size((__ARR)) * sizeof(*__ARR))
  1550. GS_API_DECL void*
  1551. gs_dyn_array_resize_impl(void* arr, size_t sz, size_t amount);
  1552. #define gs_dyn_array_need_grow(__ARR, __N)\
  1553. ((__ARR) == 0 || gs_dyn_array_size(__ARR) + (__N) >= gs_dyn_array_capacity(__ARR))
  1554. #define gs_dyn_array_grow(__ARR)\
  1555. gs_dyn_array_resize_impl((__ARR), sizeof(*(__ARR)), gs_dyn_array_capacity(__ARR) ? gs_dyn_array_capacity(__ARR) * 2 : 1)
  1556. #define gs_dyn_array_grow_size(__ARR, __SZ )\
  1557. gs_dyn_array_resize_impl((__ARR), (__SZ ), gs_dyn_array_capacity(__ARR) ? gs_dyn_array_capacity(__ARR) * 2 : 1)
  1558. GS_API_DECL void**
  1559. gs_dyn_array_init(void** arr, size_t val_len);
  1560. GS_API_DECL void
  1561. gs_dyn_array_push_data(void** arr, void* val, size_t val_len);
  1562. gs_force_inline
  1563. void gs_dyn_array_set_data_i(void** arr, void* val, size_t val_len, uint32_t offset)
  1564. {
  1565. memcpy(((char*)(*arr)) + offset * val_len, val, val_len);
  1566. }
  1567. #define gs_dyn_array_push(__ARR, __ARRVAL)\
  1568. do {\
  1569. gs_dyn_array_init((void**)&(__ARR), sizeof(*(__ARR)));\
  1570. if (!(__ARR) || ((__ARR) && gs_dyn_array_need_grow(__ARR, 1))) {\
  1571. *((void **)&(__ARR)) = gs_dyn_array_grow(__ARR); \
  1572. }\
  1573. (__ARR)[gs_dyn_array_size(__ARR)] = (__ARRVAL);\
  1574. gs_dyn_array_head(__ARR)->size++;\
  1575. } while(0)
  1576. #define gs_dyn_array_reserve(__ARR, __AMOUNT)\
  1577. do {\
  1578. if ((!__ARR)) gs_dyn_array_init((void**)&(__ARR), sizeof(*(__ARR)));\
  1579. if ((!__ARR) || (size_t)__AMOUNT > gs_dyn_array_capacity(__ARR)) {\
  1580. *((void **)&(__ARR)) = gs_dyn_array_resize_impl(__ARR, sizeof(*__ARR), __AMOUNT);\
  1581. }\
  1582. } while(0)
  1583. #define gs_dyn_array_empty(__ARR)\
  1584. (gs_dyn_array_init((void**)&(__ARR), sizeof(*(__ARR))), (gs_dyn_array_size(__ARR) == 0))
  1585. #define gs_dyn_array_pop(__ARR)\
  1586. do {\
  1587. if (__ARR && !gs_dyn_array_empty(__ARR)) {\
  1588. gs_dyn_array_head(__ARR)->size -= 1;\
  1589. }\
  1590. } while (0)
  1591. #define gs_dyn_array_back(__ARR)\
  1592. *(__ARR + (gs_dyn_array_size(__ARR) ? gs_dyn_array_size(__ARR) - 1 : 0))
  1593. #define gs_dyn_array_for(__ARR, __T, __IT_NAME)\
  1594. for (__T* __IT_NAME = __ARR; __IT_NAME != gs_dyn_array_back(__ARR); ++__IT_NAME)
  1595. #define gs_dyn_array_new(__T)\
  1596. ((__T*)gs_dyn_array_resize_impl(NULL, sizeof(__T), 0))
  1597. #define gs_dyn_array_clear(__ARR)\
  1598. do {\
  1599. if (__ARR) {\
  1600. gs_dyn_array_head(__ARR)->size = 0;\
  1601. }\
  1602. } while (0)
  1603. #define gs_dyn_array(__T) __T*
  1604. #define gs_dyn_array_free(__ARR)\
  1605. do {\
  1606. if (__ARR) {\
  1607. gs_free(gs_dyn_array_head(__ARR));\
  1608. (__ARR) = NULL;\
  1609. }\
  1610. } while (0)
  1611. /*===================================
  1612. // Static Array
  1613. ===================================*/
  1614. /*===================================
  1615. // Hash Table
  1616. ===================================*/
  1617. /*
  1618. If using struct for keys, requires struct to be word-aligned.
  1619. */
  1620. #define GS_HASH_TABLE_HASH_SEED 0x31415296
  1621. #define GS_HASH_TABLE_INVALID_INDEX UINT32_MAX
  1622. typedef enum gs_hash_table_entry_state {
  1623. GS_HASH_TABLE_ENTRY_INACTIVE = 0x00,
  1624. GS_HASH_TABLE_ENTRY_ACTIVE = 0x01
  1625. } gs_hash_table_entry_state;
  1626. typedef size_t (*gs_hash_func_t)(void*, size_t, size_t);
  1627. #define __gs_hash_table_entry(__HMK, __HMV)\
  1628. struct {\
  1629. __HMK key;\
  1630. __HMV val;\
  1631. size_t hash;\
  1632. gs_hash_table_entry_state state;\
  1633. }
  1634. #define gs_hash_table(__HMK, __HMV)\
  1635. struct {\
  1636. __gs_hash_table_entry(__HMK, __HMV)* data;\
  1637. __HMK tmp_key;\
  1638. __HMV tmp_val;\
  1639. size_t stride;\
  1640. size_t klpvl;\
  1641. size_t tmp_idx;\
  1642. gs_hash_func_t hash_func;\
  1643. }*
  1644. // Need a way to create a temporary key so I can take the address of it
  1645. #define gs_hash_table_new(__K, __V)\
  1646. NULL
  1647. GS_API_DECL void
  1648. __gs_hash_table_init_impl(void** ht, size_t sz);
  1649. #define gs_hash_table_init_ex(__HT, __K, __V, __HFUNC)\
  1650. do {\
  1651. size_t entry_sz = sizeof(*__HT->data);\
  1652. size_t ht_sz = sizeof(*__HT);\
  1653. __gs_hash_table_init_impl((void**)&(__HT), ht_sz);\
  1654. memset((__HT), 0, ht_sz);\
  1655. gs_dyn_array_reserve(__HT->data, 2);\
  1656. __HT->data[0].state = GS_HASH_TABLE_ENTRY_INACTIVE;\
  1657. __HT->data[1].state = GS_HASH_TABLE_ENTRY_INACTIVE;\
  1658. uintptr_t d0 = (uintptr_t)&((__HT)->data[0]);\
  1659. uintptr_t d1 = (uintptr_t)&((__HT)->data[1]);\
  1660. ptrdiff_t diff = (d1 - d0);\
  1661. ptrdiff_t klpvl = (uintptr_t)&(__HT->data[0].state) - (uintptr_t)(&__HT->data[0]);\
  1662. (__HT)->stride = (size_t)(diff);\
  1663. (__HT)->klpvl = (size_t)(klpvl);\
  1664. (__HT)->hash_func = (__HFUNC);\
  1665. } while (0)
  1666. // Internal helper to compute hash with optional custom function
  1667. gs_force_inline
  1668. size_t __gs_hash_table_compute_hash(gs_hash_func_t hash_func, void* key, size_t key_len, size_t seed)
  1669. {
  1670. if (hash_func) {
  1671. return hash_func(key, key_len, seed);
  1672. }
  1673. return gs_hash_bytes(key, key_len, seed);
  1674. }
  1675. #define gs_hash_table_init(__HT, __K, __V)\
  1676. gs_hash_table_init_ex(__HT, __K, __V, gs_hash_bytes)
  1677. #define gs_hash_table_reserve(_HT, _KT, _VT, _CT)\
  1678. do {\
  1679. if ((_HT) == NULL) {\
  1680. gs_hash_table_init((_HT), _KT, _VT);\
  1681. }\
  1682. gs_dyn_array_reserve((_HT)->data, _CT);\
  1683. } while (0)
  1684. #define gs_hash_table_size(__HT)\
  1685. ((__HT) != NULL ? gs_dyn_array_size((__HT)->data) : 0)
  1686. #define gs_hash_table_capacity(__HT)\
  1687. ((__HT) != NULL ? gs_dyn_array_capacity((__HT)->data) : 0)
  1688. #define gs_hash_table_load_factor(__HT)\
  1689. (gs_hash_table_capacity(__HT) ? (float)(gs_hash_table_size(__HT)) / (float)(gs_hash_table_capacity(__HT)) : 0.f)
  1690. #define gs_hash_table_grow(__HT, __C)\
  1691. ((__HT)->data = gs_dyn_array_resize_impl((__HT)->data, sizeof(*((__HT)->data)), (__C)))
  1692. #define gs_hash_table_empty(__HT)\
  1693. ((__HT) != NULL ? gs_dyn_array_size((__HT)->data) == 0 : true)
  1694. #define gs_hash_table_clear(__HT)\
  1695. do {\
  1696. if ((__HT) != NULL) {\
  1697. uint32_t capacity = gs_dyn_array_capacity((__HT)->data);\
  1698. for (uint32_t i = 0; i < capacity; ++i) {\
  1699. (__HT)->data[i].state = GS_HASH_TABLE_ENTRY_INACTIVE;\
  1700. }\
  1701. /*memset((__HT)->data, 0, gs_dyn_array_capacity((__HT)->data) * );*/\
  1702. gs_dyn_array_clear((__HT)->data);\
  1703. }\
  1704. } while (0)
  1705. #define gs_hash_table_free(__HT)\
  1706. do {\
  1707. if ((__HT) != NULL) {\
  1708. gs_dyn_array_free((__HT)->data);\
  1709. (__HT)->data = NULL;\
  1710. gs_free(__HT);\
  1711. (__HT) = NULL;\
  1712. }\
  1713. } while (0)
  1714. // Find available slot to insert k/v pair into
  1715. #define gs_hash_table_insert(__HT, __HMK, __HMV)\
  1716. do {\
  1717. /* Check for null hash table, init if necessary */\
  1718. if ((__HT) == NULL) {\
  1719. gs_hash_table_init((__HT), (__HMK), (__HMV));\
  1720. }\
  1721. \
  1722. /* Grow table if necessary */\
  1723. uint32_t __CAP = gs_hash_table_capacity(__HT);\
  1724. float __LF = gs_hash_table_load_factor(__HT);\
  1725. if (__LF >= 0.5f || !__CAP)\
  1726. {\
  1727. uint32_t NEW_CAP = __CAP ? __CAP * 2 : 2;\
  1728. size_t ENTRY_SZ = sizeof((__HT)->tmp_key) + sizeof((__HT)->tmp_val) + sizeof(size_t) + sizeof(gs_hash_table_entry_state);\
  1729. gs_dyn_array_reserve((__HT)->data, NEW_CAP);\
  1730. /**((void **)&(__HT->data)) = gs_dyn_array_resize_impl(__HT->data, ENTRY_SZ, NEW_CAP);*/\
  1731. /* Iterate through data and set state to null, from __CAP -> __CAP * 2 */\
  1732. /* Memset here instead */\
  1733. for (uint32_t __I = __CAP; __I < NEW_CAP; ++__I) {\
  1734. (__HT)->data[__I].state = GS_HASH_TABLE_ENTRY_INACTIVE;\
  1735. }\
  1736. __CAP = gs_hash_table_capacity(__HT);\
  1737. }\
  1738. \
  1739. /* Get hash of key */\
  1740. (__HT)->tmp_key = (__HMK);\
  1741. size_t __HSH = __gs_hash_table_compute_hash((__HT)->hash_func, (void*)&((__HT)->tmp_key), sizeof((__HT)->tmp_key), GS_HASH_TABLE_HASH_SEED);\
  1742. size_t __HSH_IDX = __HSH % __CAP;\
  1743. (__HT)->tmp_key = (__HT)->data[__HSH_IDX].key;\
  1744. uint32_t c = 0;\
  1745. \
  1746. /* Find valid idx and place data */\
  1747. while (\
  1748. c < __CAP\
  1749. && __HSH != __gs_hash_table_compute_hash((__HT)->hash_func, (void*)&(__HT)->tmp_key, sizeof((__HT)->tmp_key), GS_HASH_TABLE_HASH_SEED)\
  1750. && (__HT)->data[__HSH_IDX].state == GS_HASH_TABLE_ENTRY_ACTIVE)\
  1751. {\
  1752. __HSH_IDX = ((__HSH_IDX + 1) % __CAP);\
  1753. (__HT)->tmp_key = (__HT)->data[__HSH_IDX].key;\
  1754. ++c;\
  1755. }\
  1756. (__HT)->data[__HSH_IDX].key = (__HMK);\
  1757. (__HT)->data[__HSH_IDX].val = (__HMV);\
  1758. (__HT)->data[__HSH_IDX].hash = __HSH;\
  1759. (__HT)->data[__HSH_IDX].state = GS_HASH_TABLE_ENTRY_ACTIVE;\
  1760. (__HT)->tmp_idx = __HSH_IDX;\
  1761. gs_dyn_array_head((__HT)->data)->size++;\
  1762. } while (0)
  1763. // Need size difference between two entries
  1764. // Need size of key + val
  1765. gs_force_inline
  1766. uint32_t gs_hash_table_get_key_index_func(void** data, void* key, size_t key_len,
  1767. size_t val_len, size_t stride, size_t klpvl, gs_hash_func_t hash_func)
  1768. {
  1769. if (!data || !key) return GS_HASH_TABLE_INVALID_INDEX;
  1770. // Need a better way to handle this. Can't do it like this anymore.
  1771. // Need to fix this. Seriously messing me up.
  1772. uint32_t capacity = gs_dyn_array_capacity(*data);
  1773. uint32_t size = gs_dyn_array_size(*data);
  1774. if (!capacity || !size) return (size_t)GS_HASH_TABLE_INVALID_INDEX;
  1775. size_t idx = (size_t)GS_HASH_TABLE_INVALID_INDEX;
  1776. // size_t hash = (size_t)gs_hash_bytes(key, key_len, GS_HASH_TABLE_HASH_SEED);
  1777. size_t hash = (size_t)hash_func(key, key_len, GS_HASH_TABLE_HASH_SEED);
  1778. size_t hash_idx = (hash % capacity);
  1779. // Iterate through data
  1780. for (size_t i = hash_idx, c = 0; c < capacity; ++c, i = ((i + 1) % capacity)) {
  1781. size_t offset = (i * stride);
  1782. gs_hash_table_entry_state state = *(gs_hash_table_entry_state*)((char*)(*data) + offset + (klpvl));
  1783. // Early out inactive slots immediately
  1784. if (state != GS_HASH_TABLE_ENTRY_ACTIVE) continue;
  1785. size_t stored_hash = *(size_t*)((char*)(*data) + offset + (klpvl) - sizeof(size_t));
  1786. // Quick hash comparison first
  1787. if (hash != stored_hash) continue;
  1788. // Byte comparison
  1789. void* k = ((char*)(*data) + (offset));
  1790. if (gs_compare_bytes(k, key, key_len)) {
  1791. idx = i;
  1792. break;
  1793. }
  1794. }
  1795. return (uint32_t)idx;
  1796. }
  1797. // Get key at index
  1798. #define gs_hash_table_getk(__HT, __I)\
  1799. (((__HT))->data[(__I)].key)
  1800. // Get val at index
  1801. #define gs_hash_table_geti(__HT, __I)\
  1802. ((__HT)->data[(__I)].val)
  1803. // Could search for the index in the macro instead now. Does this help me?
  1804. #define gs_hash_table_get(__HT, __HTK)\
  1805. ((__HT)->tmp_key = (__HTK),\
  1806. (gs_hash_table_geti((__HT),\
  1807. gs_hash_table_get_key_index_func((void**)&(__HT)->data, (void*)&((__HT)->tmp_key),\
  1808. sizeof((__HT)->tmp_key), sizeof((__HT)->tmp_val), (__HT)->stride, (__HT)->klpvl, (__HT)->hash_func))))
  1809. #define gs_hash_table_getp(__HT, __HTK)\
  1810. (\
  1811. (__HT)->tmp_key = (__HTK),\
  1812. ((__HT)->tmp_idx = (uint32_t)gs_hash_table_get_key_index_func((void**)&(__HT->data), (void*)&(__HT->tmp_key), sizeof(__HT->tmp_key),\
  1813. sizeof(__HT->tmp_val), __HT->stride, __HT->klpvl, __HT->hash_func)),\
  1814. ((__HT)->tmp_idx != GS_HASH_TABLE_INVALID_INDEX ? &gs_hash_table_geti((__HT), (__HT)->tmp_idx) : NULL)\
  1815. )
  1816. #define _gs_hash_table_key_exists_internal(__HT, __HTK)\
  1817. ((__HT)->tmp_key = (__HTK),\
  1818. (__HT)->tmp_idx = gs_hash_table_get_key_index_func((void**)&(__HT->data), (void*)&(__HT->tmp_key), sizeof(__HT->tmp_key),\
  1819. sizeof(__HT->tmp_val), __HT->stride, __HT->klpvl, __HT->hash_func), ((__HT->tmp_idx) != GS_HASH_TABLE_INVALID_INDEX))
  1820. // uint32_t gs_hash_table_get_key_index_func(void** data, void* key, size_t key_len, size_t val_len, size_t stride, size_t klpvl)
  1821. #define gs_hash_table_exists(__HT, __HTK)\
  1822. (__HT && _gs_hash_table_key_exists_internal((__HT), (__HTK)))
  1823. #define gs_hash_table_key_exists(__HT, __HTK)\
  1824. (gs_hash_table_exists((__HT), (__HTK)))
  1825. #define gs_hash_table_erase(__HT, __HTK)\
  1826. do {\
  1827. if ((__HT))\
  1828. {\
  1829. /* Get idx for key */\
  1830. (__HT)->tmp_key = (__HTK);\
  1831. uint32_t __IDX = gs_hash_table_get_key_index_func((void**)&(__HT)->data, (void*)&((__HT)->tmp_key), sizeof((__HT)->tmp_key), sizeof((__HT)->tmp_val), (__HT)->stride, (__HT)->klpvl, (__HT)->hash_func);\
  1832. if (__IDX != GS_HASH_TABLE_INVALID_INDEX) {\
  1833. (__HT)->data[__IDX].state = GS_HASH_TABLE_ENTRY_INACTIVE;\
  1834. if (gs_dyn_array_head((__HT)->data)->size) gs_dyn_array_head((__HT)->data)->size--;\
  1835. }\
  1836. }\
  1837. } while (0)
  1838. /*===== Hash Table Iterator ====*/
  1839. typedef uint32_t gs_hash_table_iter;
  1840. typedef gs_hash_table_iter gs_hash_table_iter_t;
  1841. gs_force_inline
  1842. uint32_t __gs_find_first_valid_iterator(void* data, size_t key_len, size_t val_len, uint32_t idx, size_t stride, size_t klpvl)
  1843. {
  1844. uint32_t it = (uint32_t)idx;
  1845. for (; it < (uint32_t)gs_dyn_array_capacity(data); ++it)
  1846. {
  1847. size_t offset = (it * stride);
  1848. gs_hash_table_entry_state state = *(gs_hash_table_entry_state*)((uint8_t*)data + offset + (klpvl));
  1849. if (state == GS_HASH_TABLE_ENTRY_ACTIVE)
  1850. {
  1851. break;
  1852. }
  1853. }
  1854. return it;
  1855. }
  1856. /* Find first valid iterator idx */
  1857. #define gs_hash_table_iter_new(__HT)\
  1858. (__HT ? __gs_find_first_valid_iterator((__HT)->data, sizeof((__HT)->tmp_key), sizeof((__HT)->tmp_val), 0, (__HT)->stride, (__HT)->klpvl) : 0)
  1859. #define gs_hash_table_iter_valid(__HT, __IT)\
  1860. ((__IT) < gs_hash_table_capacity((__HT)))
  1861. // Have to be able to do this for hash table...
  1862. gs_force_inline
  1863. void __gs_hash_table_iter_advance_func(void** data, size_t key_len, size_t val_len, uint32_t* it, size_t stride, size_t klpvl)
  1864. {
  1865. (*it)++;
  1866. for (; *it < (uint32_t)gs_dyn_array_capacity(*data); ++*it)
  1867. {
  1868. size_t offset = (size_t)(*it * stride);
  1869. gs_hash_table_entry_state state = *(gs_hash_table_entry_state*)((uint8_t*)*data + offset + (klpvl));
  1870. if (state == GS_HASH_TABLE_ENTRY_ACTIVE)
  1871. {
  1872. break;
  1873. }
  1874. }
  1875. }
  1876. #define gs_hash_table_find_valid_iter(__HT, __IT)\
  1877. ((__IT) = __gs_find_first_valid_iterator((void**)&(__HT)->data, sizeof((__HT)->tmp_key), sizeof((__HT)->tmp_val), (__IT), (__HT)->stride, (__HT)->klpvl))
  1878. #define gs_hash_table_iter_advance(__HT, __IT)\
  1879. (__gs_hash_table_iter_advance_func((void**)&(__HT)->data, sizeof((__HT)->tmp_key), sizeof((__HT)->tmp_val), &(__IT), (__HT)->stride, (__HT)->klpvl))
  1880. #define gs_hash_table_iter_get(__HT, __IT)\
  1881. gs_hash_table_geti(__HT, __IT)
  1882. #define gs_hash_table_iter_getp(__HT, __IT)\
  1883. (&(gs_hash_table_geti(__HT, __IT)))
  1884. #define gs_hash_table_iter_getk(__HT, __IT)\
  1885. (gs_hash_table_getk(__HT, __IT))
  1886. #define gs_hash_table_iter_getkp(__HT, __IT)\
  1887. (&(gs_hash_table_getk(__HT, __IT)))
  1888. /*==================
  1889. //=== Hash Set ===//
  1890. ==================*/
  1891. #define GS_HASH_SET_HASH_SEED 0x31415296
  1892. #define GS_HASH_SET_INVALID_INDEX UINT32_MAX
  1893. #define GS_HASH_SET_MAX_PROBE 64
  1894. #define GS_HASH_SET_MAX_LOAD_FACTOR 0.75f
  1895. typedef enum gs_hash_set_entry_state
  1896. {
  1897. GS_HASH_SET_ENTRY_INACTIVE = 0x00,
  1898. GS_HASH_SET_ENTRY_ACTIVE = 0x01
  1899. } gs_hash_set_entry_state;
  1900. #define __gs_hash_set_entry(__T)\
  1901. struct\
  1902. {\
  1903. __T val;\
  1904. gs_hash_set_entry_state state;\
  1905. }
  1906. #define gs_hash_set(__T)\
  1907. struct {\
  1908. __gs_hash_set_entry(__T)* data;\
  1909. __T tmp_val;\
  1910. size_t stride;\
  1911. size_t klpvl;\
  1912. size_t tmp_idx;\
  1913. gs_hash_func_t hash_func;\
  1914. }*
  1915. #define gs_hash_set_new(T)\
  1916. NULL
  1917. GS_API_DECL void
  1918. __gs_hash_set_init_impl( void** ht, size_t sz );
  1919. #define gs_hash_set_init_ex(__S, __T, __HFUNC)\
  1920. do {\
  1921. size_t entry_sz = sizeof(*__S->data);\
  1922. size_t ht_sz = sizeof(*__S);\
  1923. __gs_hash_set_init_impl((void**)&(__S), ht_sz);\
  1924. memset((__S), 0, ht_sz);\
  1925. gs_dyn_array_reserve(__S->data, 2);\
  1926. __S->data[0].state = GS_HASH_SET_ENTRY_INACTIVE;\
  1927. __S->data[1].state = GS_HASH_SET_ENTRY_INACTIVE;\
  1928. uintptr_t d0 = (uintptr_t)&((__S)->data[0]);\
  1929. uintptr_t d1 = (uintptr_t)&((__S)->data[1]);\
  1930. ptrdiff_t diff = (d1 - d0);\
  1931. ptrdiff_t klpvl = (uintptr_t)&(__S->data[0].state) - (uintptr_t)(&__S->data[0]);\
  1932. (__S)->hash_func = __HFUNC;\
  1933. (__S)->stride = (size_t)(diff);\
  1934. (__S)->klpvl = (size_t)(klpvl);\
  1935. } while (0)
  1936. #define gs_hash_set_init(__S, __T)\
  1937. gs_hash_set_init_ex(__S, __T, gs_hash_bytes)
  1938. #define gs_hash_set_reserve(__S, __T, __CT)\
  1939. do {\
  1940. if ((__S) == NULL) {\
  1941. gs_hash_set_init((__S), __T);\
  1942. }\
  1943. gs_dyn_array_reserve((__S)->data, __CT);\
  1944. } while (0)
  1945. #define gs_hash_set_size(__S)\
  1946. ((__S) != NULL ? gs_dyn_array_size((__S)->data) : 0)
  1947. #define gs_hash_set_capacity(__S)\
  1948. ((__S) != NULL ? gs_dyn_array_capacity((__S)->data) : 0)
  1949. #define gs_hash_set_load_factor(__S)\
  1950. (gs_hash_set_capacity(__S) ? (float)(gs_hash_set_size(__S)) / (float)(gs_hash_set_capacity(__S)) : 0.f)
  1951. #define gs_hash_set_grow(__S, __C)\
  1952. ((__S)->data = gs_dyn_array_resize_impl((__S)->data, sizeof(*((__S)->data)), (__C)))
  1953. #define gs_hash_set_empty(__S)\
  1954. ((__S) != NULL ? gs_dyn_array_size((__S)->data) == 0 : true)
  1955. #define gs_hash_set_clear(__S)\
  1956. do {\
  1957. if ((__S) != NULL) {\
  1958. uint32_t capacity = gs_dyn_array_capacity((__S)->data);\
  1959. memset((__S)->data, 0, gs_dyn_array_capacity((__S)->data) * sizeof(*(__S)->data));\
  1960. gs_dyn_array_clear((__S)->data);\
  1961. }\
  1962. } while (0)
  1963. #define gs_hash_set_free(__S)\
  1964. do {\
  1965. if ((__S) != NULL) {\
  1966. gs_dyn_array_free((__S)->data);\
  1967. (__S)->data = NULL;\
  1968. gs_free(__S);\
  1969. (__S) = NULL;\
  1970. }\
  1971. } while (0)
  1972. #define gs_hash_set_hash_idx(_I, _C, _CAP)\
  1973. ((_I + _C) % _CAP)
  1974. gs_force_inline
  1975. uint32_t gs_hash_set_get_key_index_func(void** data, void* key, size_t key_len, size_t stride, size_t klpvl, gs_hash_func_t hfunc)
  1976. {
  1977. if (!data || !key) return GS_HASH_SET_INVALID_INDEX;
  1978. uint32_t capacity = gs_dyn_array_capacity(*data);
  1979. uint32_t size = gs_dyn_array_size(*data);
  1980. if (!capacity || !size) return (size_t)GS_HASH_SET_INVALID_INDEX;
  1981. size_t idx = (size_t)GS_HASH_SET_INVALID_INDEX;
  1982. size_t hash = (size_t)hfunc(key, key_len, GS_HASH_SET_HASH_SEED);
  1983. size_t hash_idx = (hash % capacity);
  1984. size_t c = 0;
  1985. size_t max_probe = GS_HASH_SET_MAX_PROBE;
  1986. // Iterate through data
  1987. for (size_t i = hash_idx; c < max_probe; ++c, i = ((i + c) % capacity)) {
  1988. size_t offset = (i * stride);
  1989. void* k = ((char*)(*data) + (offset));
  1990. size_t kh = hfunc(k, key_len, GS_HASH_SET_HASH_SEED);
  1991. bool comp = gs_compare_bytes(k, key, key_len);
  1992. gs_hash_set_entry_state state = *(gs_hash_set_entry_state*)((char*)(*data) + offset + (klpvl));
  1993. if (comp && hash == kh && state == GS_HASH_SET_ENTRY_ACTIVE) {
  1994. idx = i;
  1995. break;
  1996. }
  1997. }
  1998. return (uint32_t)idx;
  1999. }
  2000. gs_force_inline
  2001. void gs_hash_set_rehash(void** data, void** new_data, size_t new_cap, size_t key_len, size_t stride, size_t klpvl, gs_hash_func_t hfunc)
  2002. {
  2003. if (!data | !new_data) return;
  2004. uint32_t capacity = gs_dyn_array_capacity(*data);
  2005. if (new_cap <= capacity) return;
  2006. for (uint32_t i = 0; i < capacity; ++i) {
  2007. // Get original data
  2008. size_t offset = (i * stride);
  2009. // If this entry is inactive, then continue
  2010. if (*((gs_hash_set_entry_state*)((char*)(*data) + offset + (klpvl))) == GS_HASH_SET_ENTRY_INACTIVE) {
  2011. continue;
  2012. }
  2013. void* k = ((char*)(*data) + offset);
  2014. size_t kh = hfunc(k, key_len, GS_HASH_SET_HASH_SEED);
  2015. // Hash idx into new data with new capacity
  2016. uint32_t c = 0;
  2017. size_t hash_idx = (kh % new_cap);
  2018. /* Find valid idx and place data */
  2019. while (
  2020. c < new_cap
  2021. && *((gs_hash_set_entry_state*)((char*)(*new_data) + (hash_idx * stride) + (klpvl))) == GS_HASH_SET_ENTRY_ACTIVE
  2022. ) {
  2023. ++c;
  2024. hash_idx = ((hash_idx + c)) % new_cap;
  2025. }
  2026. // Set new data in new array
  2027. size_t noff = hash_idx * stride;
  2028. uint32_t tmp = 20;
  2029. memcpy((void*)(((uint8_t*)(*new_data)) + noff), k, key_len);
  2030. *((gs_hash_set_entry_state*)((char*)(*new_data) + (hash_idx * stride) + klpvl)) = GS_HASH_SET_ENTRY_ACTIVE;
  2031. }
  2032. }
  2033. // Find available slot to insert k/v pair into
  2034. #define gs_hash_set_insert(__S, __T)\
  2035. do {\
  2036. /* Check for null hash table, init if necessary */\
  2037. if ((__S) == NULL) {\
  2038. gs_hash_set_init((__S), (__T));\
  2039. }\
  2040. \
  2041. /* Grow table if necessary */\
  2042. uint32_t __CAP = gs_hash_set_capacity(__S);\
  2043. float __LF = gs_hash_set_load_factor(__S);\
  2044. if (__LF >= GS_HASH_SET_MAX_LOAD_FACTOR || !__CAP)\
  2045. {\
  2046. uint32_t NEW_CAP = __CAP ? __CAP * 2 : 2;\
  2047. size_t ENTRY_SZ = sizeof((__S)->tmp_val) + sizeof(gs_hash_set_entry_state);\
  2048. void* new_data = gs_calloc(NEW_CAP * 2, ENTRY_SZ);\
  2049. /*Rehash data, reserve, copy, free*/\
  2050. gs_hash_set_rehash((void**)&(__S)->data, (void**)&new_data, NEW_CAP, sizeof((__S)->tmp_val), (__S)->stride, (__S)->klpvl, (__S)->hash_func);\
  2051. gs_dyn_array_reserve((__S)->data, NEW_CAP);\
  2052. memcpy((__S)->data, new_data, NEW_CAP * ENTRY_SZ);\
  2053. __CAP = gs_hash_set_capacity(__S);\
  2054. gs_free(new_data);\
  2055. }\
  2056. \
  2057. /* Get hash of key */\
  2058. (__S)->tmp_val = (__T);\
  2059. size_t __HSH = (__S)->hash_func((void*)&((__S)->tmp_val), sizeof((__S)->tmp_val), GS_HASH_SET_HASH_SEED);\
  2060. size_t __HSH_IDX = __HSH % __CAP;\
  2061. uint32_t c = 0;\
  2062. bool exists = false;\
  2063. \
  2064. /* Find valid idx and place data */\
  2065. while (c < __CAP) {\
  2066. /*If active entry*/\
  2067. if (__S->data[__HSH_IDX].state == GS_HASH_SET_ENTRY_ACTIVE) {\
  2068. if (gs_compare_bytes((void*)&(__S->tmp_val), (void*)&((__S)->data[__HSH_IDX].val), sizeof((__S)->tmp_val))) {\
  2069. exists = true;\
  2070. break;\
  2071. }\
  2072. ++c;\
  2073. __HSH_IDX = ((__HSH_IDX + c) % __CAP);\
  2074. }\
  2075. /*Inactive entry, so break*/\
  2076. else {\
  2077. break;\
  2078. }\
  2079. }\
  2080. if (!exists) {\
  2081. (__S)->data[__HSH_IDX].val = (__T);\
  2082. (__S)->data[__HSH_IDX].state = GS_HASH_SET_ENTRY_ACTIVE;\
  2083. gs_dyn_array_head((__S)->data)->size++;\
  2084. }\
  2085. } while (0)
  2086. // Get val at index
  2087. #define gs_hash_set_geti(__S, __I)\
  2088. ((__S)->data[(__I)].val)
  2089. // Could search for the index in the macro instead now. Does this help me?
  2090. #define gs_hash_set_get(__S, __SK)\
  2091. ((__S)->tmp_val = (__SK),\
  2092. (gs_hash_set_geti((__S),\
  2093. gs_hash_set_get_key_index_func((void**)&(__S)->data, (void*)&((__S)->tmp_val),\
  2094. sizeof((__S)->tmp_val), (__S)->stride, (__S)->klpvl, (__S)->hash_func))))
  2095. #define gs_hash_set_getp(__S, __SK)\
  2096. (\
  2097. (__S)->tmp_val = (__SK),\
  2098. ((__S)->tmp_idx = (uint32_t)gs_hash_set_get_key_index_func((void**)&(__S->data), (void*)&(__S->tmp_val), sizeof(__S->tmp_val),\
  2099. __S->stride, __S->klpvl, __S->hash_func)),\
  2100. ((__S)->tmp_idx != GS_HASH_SET_INVALID_INDEX ? &gs_hash_set_geti((__S), (__S)->tmp_idx) : NULL)\
  2101. )
  2102. #define _gs_hash_set_key_exists_internal(__S, __SK)\
  2103. ((__S)->tmp_val = (__SK),\
  2104. (gs_hash_set_get_key_index_func((void**)&(__S->data), (void*)&(__S->tmp_val), sizeof(__S->tmp_val),\
  2105. __S->stride, __S->klpvl, __S->hash_func) != GS_HASH_SET_INVALID_INDEX))
  2106. #define gs_hash_set_exists(__S, __SK)\
  2107. (__S && _gs_hash_set_key_exists_internal((__S), (__SK)))
  2108. #define gs_hash_set_key_exists(__S, __SK)\
  2109. (gs_hash_set_exists((__S), (__SK)))
  2110. #define gs_hash_set_erase(__S, __SK)\
  2111. do {\
  2112. if ((__S))\
  2113. {\
  2114. /* Get idx for key */\
  2115. (__S)->tmp_val = (__SK);\
  2116. uint32_t __IDX = gs_hash_set_get_key_index_func((void**)&(__S)->data, (void*)&((__S)->tmp_val), sizeof((__S)->tmp_val), (__S)->stride, (__S)->klpvl, (__S)->hash_func);\
  2117. if (__IDX != GS_HASH_SET_INVALID_INDEX) {\
  2118. (__S)->data[__IDX].state = GS_HASH_SET_ENTRY_INACTIVE;\
  2119. if (gs_dyn_array_head((__S)->data)->size) gs_dyn_array_head((__S)->data)->size--;\
  2120. }\
  2121. }\
  2122. } while (0)
  2123. gs_force_inline
  2124. bool _gs_hash_set_is_subset_of_internal(void** s0, void** s1, size_t key_len, size_t stride, size_t klpvl, gs_hash_func_t hfunc)
  2125. {
  2126. // If sz0 > sz1, then cannot be subset
  2127. uint32_t sz0 = gs_dyn_array_size(*s0);
  2128. uint32_t sz1 = gs_dyn_array_size(*s1);
  2129. if (sz0 > sz1) return false;
  2130. // If there exists an element in s0 not in s1, then not a subset
  2131. uint32_t c0 = gs_dyn_array_capacity(*s0);
  2132. uint32_t c1 = gs_dyn_array_capacity(*s1);
  2133. for (uint32_t i = 0; i < c0; ++i) {
  2134. // Continue past invalid entry
  2135. size_t offset = (i * stride);
  2136. gs_hash_set_entry_state state = *(gs_hash_set_entry_state*)((char*)(*s0) + offset + (klpvl));
  2137. if (state == GS_HASH_SET_ENTRY_INACTIVE) {
  2138. continue;
  2139. }
  2140. // Valid entry, check against s1
  2141. void* k0 = ((char*)(*s0) + (offset));
  2142. size_t kh = hfunc(k0, key_len, GS_HASH_SET_HASH_SEED);
  2143. uint32_t hidx = (kh % c1); // Hash idx into super set
  2144. uint32_t cc = 0;
  2145. bool found = false;
  2146. while (
  2147. !found &&
  2148. cc < GS_HASH_SET_MAX_PROBE
  2149. ) {
  2150. // Not active entry
  2151. size_t o1 = hidx * stride; // New offset
  2152. gs_hash_set_entry_state es = *((gs_hash_set_entry_state*)((char*)(*s1) + (hidx * stride) + (klpvl)));
  2153. void* k1 = ((char*)(*s1) + (o1));
  2154. // Found
  2155. if (es == GS_HASH_SET_ENTRY_ACTIVE && gs_compare_bytes(k0, k1, key_len)) {
  2156. found = true;
  2157. break;
  2158. }
  2159. // Continue
  2160. ++cc;
  2161. hidx = ((hidx + cc)) % c1;
  2162. }
  2163. if (!found) return false;
  2164. }
  2165. return true;
  2166. }
  2167. #define gs_hash_set_is_subset_of(__S0, __S1)\
  2168. (__S0 && __S1 &&\
  2169. sizeof((__S0)->tmp_val) == sizeof((__S1)->tmp_val) &&\
  2170. (__S0)->stride == (__S1)->stride &&\
  2171. (__S0)->klpvl == (__S1)->klpvl &&\
  2172. _gs_hash_set_is_subset_of_internal((void**)&(__S0)->data, (void**)&(__S1)->data,\
  2173. sizeof((__S0)->tmp_val), (__S0)->stride, (__S0)->klpvl, (__S0)->hfunc))
  2174. /*===== Set Iterator ====*/
  2175. typedef uint32_t gs_hash_set_iter;
  2176. typedef gs_hash_set_iter gs_hash_set_iter_t;
  2177. gs_force_inline
  2178. uint32_t __gs_hash_set_find_first_valid_iterator(void* data, uint32_t idx, size_t stride, size_t klpvl)
  2179. {
  2180. uint32_t it = (uint32_t)idx;
  2181. for (; it < (uint32_t)gs_dyn_array_capacity(data); ++it) {
  2182. size_t offset = (it * stride);
  2183. gs_hash_set_entry_state state = *(gs_hash_set_entry_state*)((uint8_t*)data + offset + (klpvl));
  2184. if (state == GS_HASH_SET_ENTRY_ACTIVE) {
  2185. break;
  2186. }
  2187. }
  2188. return it;
  2189. }
  2190. /* Find first valid iterator idx */
  2191. #define gs_hash_set_iter_new(__S)\
  2192. (__S ? __gs_hash_set_find_first_valid_iterator((__S)->data, 0, (__S)->stride, (__S)->klpvl) : 0)
  2193. #define gs_hash_set_iter_valid(__S, __IT)\
  2194. ((__IT) < gs_hash_set_capacity((__S)))
  2195. gs_force_inline
  2196. void __gs_hash_set_iter_advance_func(void** data, uint32_t* it, size_t stride, size_t klpvl)
  2197. {
  2198. (*it)++;
  2199. for (; *it < (uint32_t)gs_dyn_array_capacity(*data); ++*it) {
  2200. size_t offset = (size_t)(*it * stride);
  2201. gs_hash_set_entry_state state = *(gs_hash_set_entry_state*)((uint8_t*)*data + offset + (klpvl));
  2202. if (state == GS_HASH_SET_ENTRY_ACTIVE) {
  2203. break;
  2204. }
  2205. }
  2206. }
  2207. #define gs_hash_set_find_valid_iter(__S, __IT)\
  2208. ((__IT) = __gs_hash_set_find_first_valid_iterator((void**)&(__S)->data, (__IT), (__S)->stride, (__S)->klpvl))
  2209. #define gs_hash_set_iter_advance(__S, __IT)\
  2210. (__gs_hash_set_iter_advance_func((void**)&(__S)->data, &(__IT), (__S)->stride, (__S)->klpvl))
  2211. #define gs_hash_set_iter_get(__S, __IT)\
  2212. gs_hash_set_geti(__S, __IT)
  2213. #define gs_hash_set_iter_getp(__S, __IT)\
  2214. (&(gs_hash_set_geti(__S, __IT)))
  2215. #define gs_hash_set_iter_getk(__S, __IT)\
  2216. (gs_hash_set_getk(__S, __IT))
  2217. #define gs_hash_set_iter_getkp(__S, __IT)\
  2218. (&(gs_hash_set_getk(__S, __IT)))
  2219. /*===================================
  2220. // Slot Array
  2221. ===================================*/
  2222. #define GS_SLOT_ARRAY_INVALID_HANDLE UINT32_MAX
  2223. #define gs_slot_array_handle_valid(__SA, __ID)\
  2224. ((__SA) && __ID < gs_dyn_array_size((__SA)->indices) && (__SA)->indices[__ID] != GS_SLOT_ARRAY_INVALID_HANDLE)
  2225. typedef struct __gs_slot_array_dummy_header {
  2226. gs_dyn_array(uint32_t) indices;
  2227. gs_dyn_array(uint32_t) data;
  2228. } __gs_slot_array_dummy_header;
  2229. #define gs_slot_array(__T)\
  2230. struct\
  2231. {\
  2232. gs_dyn_array(uint32_t) indices;\
  2233. gs_dyn_array(__T) data;\
  2234. __T tmp;\
  2235. }*
  2236. #define gs_slot_array_new(__T)\
  2237. NULL
  2238. gs_force_inline
  2239. uint32_t __gs_slot_array_find_next_available_index(gs_dyn_array(uint32_t) indices)
  2240. {
  2241. uint32_t idx = GS_SLOT_ARRAY_INVALID_HANDLE;
  2242. for (uint32_t i = 0; i < (uint32_t)gs_dyn_array_size(indices); ++i)
  2243. {
  2244. uint32_t handle = indices[i];
  2245. if (handle == GS_SLOT_ARRAY_INVALID_HANDLE)
  2246. {
  2247. idx = i;
  2248. break;
  2249. }
  2250. }
  2251. if (idx == GS_SLOT_ARRAY_INVALID_HANDLE)
  2252. {
  2253. idx = gs_dyn_array_size(indices);
  2254. }
  2255. return idx;
  2256. }
  2257. GS_API_DECL void**
  2258. gs_slot_array_init(void** sa, size_t sz);
  2259. #define gs_slot_array_init_all(__SA)\
  2260. (gs_slot_array_init((void**)&(__SA), sizeof(*(__SA))), gs_dyn_array_init((void**)&((__SA)->indices), sizeof(uint32_t)),\
  2261. gs_dyn_array_init((void**)&((__SA)->data), sizeof((__SA)->tmp)))
  2262. gs_force_inline
  2263. uint32_t gs_slot_array_insert_func(void** indices, void** data, void* val, size_t val_len, uint32_t* ip)
  2264. {
  2265. // Find next available index
  2266. u32 idx = __gs_slot_array_find_next_available_index((uint32_t*)*indices);
  2267. if (idx == gs_dyn_array_size(*indices)) {
  2268. uint32_t v = 0;
  2269. gs_dyn_array_push_data(indices, &v, sizeof(uint32_t));
  2270. idx = gs_dyn_array_size(*indices) - 1;
  2271. }
  2272. // Push data to array
  2273. gs_dyn_array_push_data(data, val, val_len);
  2274. // Set data in indices
  2275. uint32_t bi = gs_dyn_array_size(*data) - 1;
  2276. gs_dyn_array_set_data_i(indices, &bi, sizeof(uint32_t), idx);
  2277. if (ip){
  2278. *ip = idx;
  2279. }
  2280. return idx;
  2281. }
  2282. #define gs_slot_array_reserve(__SA, __NUM)\
  2283. do {\
  2284. gs_slot_array_init_all(__SA);\
  2285. gs_dyn_array_reserve((__SA)->data, __NUM);\
  2286. gs_dyn_array_reserve((__SA)->indices, __NUM);\
  2287. } while (0)
  2288. #define gs_slot_array_insert(__SA, __VAL)\
  2289. (gs_slot_array_init_all(__SA), (__SA)->tmp = (__VAL),\
  2290. gs_slot_array_insert_func((void**)&((__SA)->indices), (void**)&((__SA)->data), (void*)&((__SA)->tmp), sizeof(((__SA)->tmp)), NULL))
  2291. #define gs_slot_array_insert_hp(__SA, __VAL, __hp)\
  2292. (gs_slot_array_init_all(__SA), (__SA)->tmp = (__VAL),\
  2293. gs_slot_array_insert_func((void**)&((__SA)->indices), (void**)&((__SA)->data), &((__SA)->tmp), sizeof(((__SA)->tmp)), (__hp)))
  2294. #define gs_slot_array_insert_no_init(__SA, __VAL)\
  2295. ((__SA)->tmp = (__VAL), gs_slot_array_insert_func((void**)&((__SA)->indices), (void**)&((__SA)->data), &((__SA)->tmp), sizeof(((__SA)->tmp)), NULL))
  2296. #define gs_slot_array_size(__SA)\
  2297. ((__SA) == NULL ? 0 : gs_dyn_array_size((__SA)->data))
  2298. #define gs_slot_array_empty(__SA)\
  2299. (gs_slot_array_size(__SA) == 0)
  2300. #define gs_slot_array_clear(__SA)\
  2301. do {\
  2302. if ((__SA) != NULL) {\
  2303. gs_dyn_array_clear((__SA)->data);\
  2304. gs_dyn_array_clear((__SA)->indices);\
  2305. }\
  2306. } while (0)
  2307. #define gs_slot_array_exists(__SA, __SID)\
  2308. ((__SA) && (__SID) < (uint32_t)gs_dyn_array_size((__SA)->indices) && (__SA)->indices[__SID] != GS_SLOT_ARRAY_INVALID_HANDLE)
  2309. #define gs_slot_array_get(__SA, __SID)\
  2310. ((__SA)->data[(__SA)->indices[(__SID) % gs_dyn_array_size(((__SA)->indices))]])
  2311. #define gs_slot_array_getp(__SA, __SID)\
  2312. (&(gs_slot_array_get(__SA, (__SID))))
  2313. #define gs_slot_array_free(__SA)\
  2314. do {\
  2315. if ((__SA) != NULL) {\
  2316. gs_dyn_array_free((__SA)->data);\
  2317. gs_dyn_array_free((__SA)->indices);\
  2318. (__SA)->indices = NULL;\
  2319. (__SA)->data = NULL;\
  2320. gs_free((__SA));\
  2321. (__SA) = NULL;\
  2322. }\
  2323. } while (0)
  2324. #define gs_slot_array_erase(__SA, __id)\
  2325. do {\
  2326. uint32_t __H0 = (__id) /*% gs_dyn_array_size((__SA)->indices)*/;\
  2327. if (gs_slot_array_size(__SA) == 1) {\
  2328. gs_slot_array_clear(__SA);\
  2329. }\
  2330. else if (!gs_slot_array_handle_valid(__SA, __H0)) {\
  2331. gs_println("Warning: Attempting to erase invalid slot array handle (%zu)", __H0);\
  2332. }\
  2333. else {\
  2334. uint32_t __OG_DATA_IDX = (__SA)->indices[__H0];\
  2335. /* Iterate through handles until last index of data found */\
  2336. uint32_t __H = 0;\
  2337. for (uint32_t __I = 0; __I < gs_dyn_array_size((__SA)->indices); ++__I)\
  2338. {\
  2339. if ((__SA)->indices[__I] == gs_dyn_array_size((__SA)->data) - 1)\
  2340. {\
  2341. __H = __I;\
  2342. break;\
  2343. }\
  2344. }\
  2345. \
  2346. /* Swap and pop data */\
  2347. (__SA)->data[__OG_DATA_IDX] = gs_dyn_array_back((__SA)->data);\
  2348. gs_dyn_array_pop((__SA)->data);\
  2349. \
  2350. /* Point new handle, Set og handle to invalid */\
  2351. (__SA)->indices[__H] = __OG_DATA_IDX;\
  2352. (__SA)->indices[__H0] = GS_SLOT_ARRAY_INVALID_HANDLE;\
  2353. }\
  2354. } while (0)
  2355. /*=== Slot Array Iterator ===*/
  2356. // Slot array iterator new
  2357. typedef uint32_t gs_slot_array_iter;
  2358. typedef gs_slot_array_iter gs_slot_array_iter_t;
  2359. #define gs_slot_array_iter_valid(__SA, __IT)\
  2360. (__SA && gs_slot_array_exists(__SA, __IT))
  2361. gs_force_inline
  2362. void _gs_slot_array_iter_advance_func(gs_dyn_array(uint32_t) indices, uint32_t* it)
  2363. {
  2364. if (!indices) {
  2365. *it = GS_SLOT_ARRAY_INVALID_HANDLE;
  2366. return;
  2367. }
  2368. (*it)++;
  2369. for (; *it < (uint32_t)gs_dyn_array_size(indices); ++*it)
  2370. {\
  2371. if (indices[*it] != GS_SLOT_ARRAY_INVALID_HANDLE)\
  2372. {\
  2373. break;\
  2374. }\
  2375. }\
  2376. }
  2377. gs_force_inline
  2378. uint32_t _gs_slot_array_iter_find_first_valid_index(gs_dyn_array(uint32_t) indices)
  2379. {
  2380. if (!indices) return GS_SLOT_ARRAY_INVALID_HANDLE;
  2381. for (uint32_t i = 0; i < (uint32_t)gs_dyn_array_size(indices); ++i)
  2382. {
  2383. if (indices[i] != GS_SLOT_ARRAY_INVALID_HANDLE)
  2384. {
  2385. return i;
  2386. }
  2387. }
  2388. return GS_SLOT_ARRAY_INVALID_HANDLE;
  2389. }
  2390. #define gs_slot_array_iter_new(__SA) (_gs_slot_array_iter_find_first_valid_index((__SA) ? (__SA)->indices : 0))
  2391. #define gs_slot_array_iter_advance(__SA, __IT)\
  2392. _gs_slot_array_iter_advance_func((__SA) ? (__SA)->indices : NULL, &(__IT))
  2393. #define gs_slot_array_iter_get(__SA, __IT)\
  2394. gs_slot_array_get(__SA, __IT)
  2395. #define gs_slot_array_iter_getp(__SA, __IT)\
  2396. gs_slot_array_getp(__SA, __IT)
  2397. /*===================================
  2398. // Slot Map
  2399. ===================================*/
  2400. #define gs_slot_map(__SMK, __SMV)\
  2401. struct {\
  2402. gs_hash_table(__SMK, uint32_t) ht;\
  2403. gs_slot_array(__SMV) sa;\
  2404. }*
  2405. #define gs_slot_map_new(__SMK, __SMV)\
  2406. NULL
  2407. GS_API_DECL void**
  2408. gs_slot_map_init(void** sm);
  2409. // Could return something, I believe?
  2410. #define gs_slot_map_insert(__SM, __SMK, __SMV)\
  2411. do {\
  2412. gs_slot_map_init((void**)&(__SM));\
  2413. uint32_t __H = gs_slot_array_insert((__SM)->sa, ((__SMV)));\
  2414. gs_hash_table_insert((__SM)->ht, (__SMK), __H);\
  2415. } while (0)
  2416. #define gs_slot_map_get(__SM, __SMK)\
  2417. (gs_slot_array_get((__SM)->sa, gs_hash_table_get((__SM)->ht, (__SMK))))
  2418. #define gs_slot_map_getp(__SM, __SMK)\
  2419. (gs_slot_array_getp((__SM)->sa, gs_hash_table_get((__SM)->ht, (__SMK))))
  2420. #define gs_slot_map_size(__SM)\
  2421. (gs_slot_array_size((__SM)->sa))
  2422. #define gs_slot_map_clear(__SM)\
  2423. do {\
  2424. if ((__SM) != NULL) {\
  2425. gs_hash_table_clear((__SM)->ht);\
  2426. gs_slot_array_clear((__SM)->sa);\
  2427. }\
  2428. } while (0)
  2429. #define gs_slot_map_erase(__SM, __SMK)\
  2430. do {\
  2431. uint32_t __K = gs_hash_table_get((__SM)->ht, (__SMK));\
  2432. gs_hash_table_erase((__SM)->ht, (__SMK));\
  2433. gs_slot_array_erase((__SM)->sa, __K);\
  2434. } while (0)
  2435. #define gs_slot_map_free(__SM)\
  2436. do {\
  2437. if (__SM != NULL) {\
  2438. gs_hash_table_free((__SM)->ht);\
  2439. gs_slot_array_free((__SM)->sa);\
  2440. gs_free((__SM));\
  2441. (__SM) = NULL;\
  2442. }\
  2443. } while (0)
  2444. #define gs_slot_map_capacity(__SM)\
  2445. (gs_hash_table_capacity((__SM)->ht))
  2446. /*=== Slot Map Iterator ===*/
  2447. typedef uint32_t gs_slot_map_iter;
  2448. /* Find first valid iterator idx */
  2449. #define gs_slot_map_iter_new(__SM)\
  2450. gs_hash_table_iter_new((__SM)->ht)
  2451. #define gs_slot_map_iter_valid(__SM, __IT)\
  2452. ((__IT) < gs_hash_table_capacity((__SM)->ht))
  2453. #define gs_slot_map_iter_advance(__SM, __IT)\
  2454. __gs_hash_table_iter_advance_func((void**)&((__SM)->ht->data), sizeof((__SM)->ht->tmp_key), sizeof((__SM)->ht->tmp_val), &(__IT), (__SM)->ht->stride, (__SM)->ht->klpvl)
  2455. #define gs_slot_map_iter_getk(__SM, __IT)\
  2456. gs_hash_table_iter_getk((__SM)->ht, (__IT))
  2457. //(gs_hash_table_find_valid_iter(__SM->ht, __IT), gs_hash_table_geti((__SM)->ht, (__IT)))
  2458. #define gs_slot_map_iter_getkp(__SM, __IT)\
  2459. (gs_hash_table_find_valid_iter(__SM->ht, __IT), &(gs_hash_table_geti((__SM)->ht, (__IT))))
  2460. #define gs_slot_map_iter_get(__SM, __IT)\
  2461. ((__SM)->sa->data[gs_hash_table_iter_get((__SM)->ht, (__IT))])
  2462. // ((__SM)->sa->data[gs_hash_table_geti((__SM)->ht, (__IT))])
  2463. // (gs_hash_table_find_valid_iter(__SM->ht, __IT), (__SM)->sa->data[gs_hash_table_geti((__SM)->ht, (__IT))])
  2464. #define gs_slot_map_iter_getp(__SM, __IT)\
  2465. (&((__SM)->sa->data[gs_hash_table_geti((__SM)->ht, (__IT))]))
  2466. // (gs_hash_table_find_valid_iter(__SM->ht, __IT), &((__SM)->sa->data[gs_hash_table_geti((__SM)->ht, (__IT))]))
  2467. /*===================================
  2468. // Priority Queue
  2469. ===================================*/
  2470. // Min heap
  2471. #define gs_pqueue(__T)\
  2472. struct\
  2473. {\
  2474. gs_dyn_array(__T) data;\
  2475. gs_dyn_array(int32_t) priority;\
  2476. __T tmp;\
  2477. }*
  2478. #define gs_pqueue_parent_idx(I) gs_max((uint32_t)(ceil(((float)I / 2.f) - 1)), 0)
  2479. #define gs_pqueue_child_left_idx(I) ((I * 2) + 1)
  2480. #define gs_pqueue_child_right_idx(I) ((I * 2) + 2)
  2481. GS_API_DECL void**
  2482. gs_pqueue_init(void** pq, size_t sz);
  2483. #define gs_pqueue_init_all(__PQ, __V)\
  2484. (gs_pqueue_init((void**)&(__PQ), sizeof(*(__PQ))), gs_dyn_array_init((void**)&((__PQ)->priority), sizeof(int32_t)),\
  2485. gs_dyn_array_init((void**)&((__PQ)->data), sizeof(__V)))
  2486. #define gs_pqueue_size(__PQ)\
  2487. gs_dyn_array_size((__PQ)->data)
  2488. #define gs_pqueue_capacity(__PQ)\
  2489. gs_dyn_array_capacity((__PQ)->data)
  2490. #define gs_pqueue_clear(__PQ)\
  2491. do {\
  2492. gs_dyn_array_clear((__PQ)->data);\
  2493. gs_dyn_array_clear((__PQ)->priority);\
  2494. } while (0)
  2495. #define gs_pqueue_empty(__PQ)\
  2496. (!(__PQ) || !gs_pqueue_size(__PQ))
  2497. #define __gs_pqueue_swp(__PQ, __I0, __I1, __SZ)\
  2498. do {\
  2499. /* Move data */\
  2500. {\
  2501. const size_t sz = (__SZ);\
  2502. memmove(&((__PQ)->tmp), &((__PQ)->data[__I0]), sz);\
  2503. memmove(&((__PQ)->data[__I0]), &((__PQ)->data[__I1]), sz);\
  2504. memmove(&((__PQ)->data[__I1]), &((__PQ)->tmp), sz);\
  2505. }\
  2506. /* Move priority */\
  2507. {\
  2508. int32_t tmp = 0;\
  2509. const size_t sz = sizeof(int32_t);\
  2510. memmove(&tmp, &((__PQ)->priority[__I0]), sz);\
  2511. memmove(&((__PQ)->priority[__I0]), &((__PQ)->priority[__I1]), sz);\
  2512. memmove(&((__PQ)->priority[__I1]), &tmp, sz);\
  2513. }\
  2514. } while (0)
  2515. #define gs_pqueue_push(__PQ, __V, __PRI)\
  2516. do {\
  2517. /*Init*/\
  2518. gs_pqueue_init_all((__PQ), (__V));\
  2519. /*Push to end of array*/\
  2520. gs_dyn_array_push((__PQ)->data, (__V));\
  2521. gs_dyn_array_push((__PQ)->priority, (__PRI));\
  2522. /*Compare and sort up*/\
  2523. const size_t dsize = sizeof(__V);\
  2524. int32_t i = gs_max(gs_pqueue_size((__PQ)) - 1, 0);\
  2525. while (i)\
  2526. {\
  2527. /* Look at parent, compare, then swap indices with parent */\
  2528. int32_t pidx = gs_pqueue_parent_idx(i);\
  2529. if ((__PQ)->priority[pidx] > __PRI) {\
  2530. __gs_pqueue_swp(__PQ, i, pidx, dsize);\
  2531. }\
  2532. else {\
  2533. break;\
  2534. }\
  2535. i = pidx;\
  2536. }\
  2537. } while (0)
  2538. #if 0
  2539. /*
  2540. Need to call into another function to return what I need... Not sure how to do this, since I need to know what TYPE to return...
  2541. */
  2542. #define gs_pqueue_pop(__PQ)\
  2543. (\
  2544. __gs_pqueue_pop_internal(\
  2545. (void**)&(__PQ),\
  2546. &(__PQ)->tmp,\
  2547. (void**)(&(__PQ)->data),\
  2548. (__PQ)->priority,\
  2549. gs_pqueue_size((__PQ)),\
  2550. sizeof((__PQ)->tmp)\
  2551. ),\
  2552. (__PQ)->tmp = (__PQ)->data[gs_pqueue_size((__PQ)) - 1],\
  2553. (gs_dyn_array_head((__PQ)->data))->size--,\
  2554. (gs_dyn_array_head((__PQ)->priority))->size--,\
  2555. (__PQ)->tmp\
  2556. )
  2557. #endif
  2558. #if 1
  2559. /*
  2560. No return.
  2561. */
  2562. #define gs_pqueue_pop(__PQ)\
  2563. do {\
  2564. /* Swap elements */\
  2565. if (gs_pqueue_empty((__PQ))) break;\
  2566. __gs_pqueue_swp(__PQ, 0, gs_pqueue_size((__PQ)) - 1, sizeof((__PQ)->tmp));\
  2567. \
  2568. int32_t i = 0;\
  2569. int32_t c = 0;\
  2570. int32_t psz = gs_dyn_array_size((__PQ)->priority) - 1;\
  2571. for (int32_t i = 0; gs_pqueue_child_left_idx(i) < psz; i = c)\
  2572. {\
  2573. /* Set child to smaller of two */\
  2574. c = gs_pqueue_child_left_idx(i);\
  2575. \
  2576. /* Set to right child if valid and less priority */\
  2577. if ((c + 1) < psz && (__PQ)->priority[c + 1] < (__PQ)->priority[c]) {\
  2578. c++;\
  2579. }\
  2580. \
  2581. /* Check to swp, if necessary */\
  2582. if ((__PQ)->priority[i] > (__PQ)->priority[c]) {\
  2583. __gs_pqueue_swp((__PQ), i, c, sizeof((__PQ)->tmp));\
  2584. }\
  2585. /* Otherwise, we're done */\
  2586. else\
  2587. {\
  2588. break;\
  2589. }\
  2590. }\
  2591. (gs_dyn_array_head((__PQ)->data))->size--;\
  2592. (gs_dyn_array_head((__PQ)->priority))->size--;\
  2593. } while (0)
  2594. #endif
  2595. #if 1
  2596. /*
  2597. */
  2598. GS_API_PRIVATE void
  2599. __gs_pqueue_pop_internal(void** pqueue, void* tmp, void** data, int32_t* priority, int32_t pq_sz, size_t d_sz);
  2600. #endif
  2601. #define gs_pqueue_peek(__PQ)\
  2602. (__PQ)->data[0]
  2603. #define gs_pqueue_peekp(__PQ)\
  2604. &((__PQ)->data[0])
  2605. #define gs_pqueue_peek_pri(__PQ)\
  2606. (__PQ)->priority[0]
  2607. #define gs_pqueue_free(__PQ)\
  2608. do {\
  2609. if ((__PQ) && (__PQ)->data) gs_dyn_array_free((__PQ)->data);\
  2610. if ((__PQ) && (__PQ)->priority) gs_dyn_array_free((__PQ)->priority);\
  2611. if ((__PQ)) gs_free((__PQ));\
  2612. } while (0)
  2613. /*=== Priority Queue Iterator ===*/
  2614. typedef uint32_t gs_pqueue_iter;
  2615. typedef gs_pqueue_iter gs_pqueue_iter_t;
  2616. #define gs_pqueue_iter_new(__PQ) 0
  2617. #define gs_pqueue_iter_valid(__PQ, __IT)\
  2618. ((__IT) < gs_pqueue_size((__PQ)))
  2619. #define gs_pqueue_iter_advance(__PQ, __IT) ++(__IT)
  2620. #define gs_pqueue_iter_get(__PQ, __IT)\
  2621. (__PQ)->data[(__IT)]
  2622. #define gs_pqueue_iter_getp(__PQ, __IT)\
  2623. &(__PQ)->data[(__IT)]
  2624. #define gs_pqueue_iter_get_pri(__PQ, __IT)\
  2625. (__PQ)->priority[(__IT)]
  2626. #define gs_pqueue_iter_get_prip(__PQ, __IT)\
  2627. &(__PQ)->priority[(__IT)]
  2628. /*===================================
  2629. // Command Buffer
  2630. ===================================*/
  2631. typedef struct gs_command_buffer_t
  2632. {
  2633. uint32_t num_commands;
  2634. gs_byte_buffer_t commands;
  2635. } gs_command_buffer_t;
  2636. gs_force_inline
  2637. gs_command_buffer_t gs_command_buffer_new()
  2638. {
  2639. gs_command_buffer_t cb = gs_default_val();
  2640. cb.commands = gs_byte_buffer_new();
  2641. return cb;
  2642. }
  2643. #define gs_command_buffer_write(__CB, __CT, __C, __T, __VAL)\
  2644. do {\
  2645. gs_command_buffer_t* __cb = (__CB);\
  2646. __cb->num_commands++;\
  2647. gs_byte_buffer_write(&__cb->commands, __CT, (__C));\
  2648. gs_byte_buffer_write(&__cb->commands, __T, (__VAL));\
  2649. } while (0)
  2650. gs_force_inline
  2651. void gs_command_buffer_clear(gs_command_buffer_t* cb)
  2652. {
  2653. cb->num_commands = 0;
  2654. gs_byte_buffer_clear(&cb->commands);
  2655. }
  2656. gs_force_inline
  2657. void gs_command_buffer_free(gs_command_buffer_t* cb)
  2658. {
  2659. gs_byte_buffer_free(&cb->commands);
  2660. }
  2661. #define gs_command_buffer_readc(__CB, __T, __NAME)\
  2662. __T __NAME = gs_default_val();\
  2663. gs_byte_buffer_read(&(__CB)->commands, __T, &__NAME);
  2664. #ifndef GS_NO_SHORT_NAME
  2665. typedef gs_command_buffer_t gs_cmdbuf;
  2666. #endif
  2667. /** @} */ // end of gs_containers
  2668. /*========================
  2669. // GS_MEMORY
  2670. ========================*/
  2671. /** @defgroup gs_memory Memory
  2672. * Gunslinger Memory
  2673. * @{
  2674. */
  2675. #define gs_ptr_add(P, BYTES) \
  2676. (((uint8_t*)P + (BYTES)))
  2677. typedef struct gs_memory_block_t {
  2678. uint8_t* data;
  2679. size_t size;
  2680. } gs_memory_block_t;
  2681. GS_API_DECL gs_memory_block_t gs_memory_block_new(size_t sz);
  2682. GS_API_DECL void gs_memory_block_free(gs_memory_block_t* mem);
  2683. GS_API_DECL size_t gs_memory_calc_padding(size_t base_address, size_t alignment);
  2684. GS_API_DECL size_t gs_memory_calc_padding_w_header(size_t base_address, size_t alignment, size_t header_sz);
  2685. /*================================================================================
  2686. // Linear Allocator
  2687. ================================================================================*/
  2688. typedef struct gs_linear_allocator_t {
  2689. uint8_t* memory;
  2690. size_t total_size;
  2691. size_t offset;
  2692. } gs_linear_allocator_t;
  2693. GS_API_DECL gs_linear_allocator_t gs_linear_allocator_new(size_t sz);
  2694. GS_API_DECL void gs_linear_allocator_free(gs_linear_allocator_t* la);
  2695. GS_API_DECL void* gs_linear_allocator_allocate(gs_linear_allocator_t* la, size_t sz, size_t alignment);
  2696. GS_API_DECL void gs_linear_allocator_clear(gs_linear_allocator_t* la);
  2697. /*================================================================================
  2698. // Stack Allocator
  2699. ================================================================================*/
  2700. typedef struct gs_stack_allocator_header_t {
  2701. uint32_t size;
  2702. } gs_stack_allocator_header_t;
  2703. typedef struct gs_stack_allocator_t {
  2704. gs_memory_block_t memory;
  2705. size_t offset;
  2706. } gs_stack_allocator_t;
  2707. GS_API_DECL gs_stack_allocator_t gs_stack_allocator_new(size_t sz);
  2708. GS_API_DECL void gs_stack_allocator_free(gs_stack_allocator_t* sa);
  2709. GS_API_DECL void* gs_stack_allocator_allocate(gs_stack_allocator_t* sa, size_t sz);
  2710. GS_API_DECL void* gs_stack_allocator_peek(gs_stack_allocator_t* sa);
  2711. GS_API_DECL void* gs_stack_allocator_pop(gs_stack_allocator_t* sa);
  2712. GS_API_DECL void gs_stack_allocator_clear(gs_stack_allocator_t* sa);
  2713. /*================================================================================
  2714. // Heap Allocator
  2715. ================================================================================*/
  2716. #ifndef GS_HEAP_ALLOC_DEFAULT_SIZE
  2717. #define GS_HEAP_ALLOC_DEFAULT_SIZE 1024 * 1024 * 20
  2718. #endif
  2719. #ifndef GS_HEAP_ALLOC_DEFAULT_CAPCITY
  2720. #define GS_HEAP_ALLOC_DEFAULT_CAPCITY 1024
  2721. #endif
  2722. typedef struct gs_heap_allocator_header_t {
  2723. struct gs_heap_allocator_header_t* next;
  2724. struct gs_heap_allocator_header_t* prev;
  2725. size_t size;
  2726. } gs_heap_allocator_header_t;
  2727. typedef struct gs_heap_allocator_free_block_t {
  2728. gs_heap_allocator_header_t* header;
  2729. size_t size;
  2730. } gs_heap_allocator_free_block_t;
  2731. typedef struct gs_heap_allocator_t {
  2732. gs_heap_allocator_header_t* memory;
  2733. gs_heap_allocator_free_block_t* free_blocks;
  2734. uint32_t free_block_count;
  2735. uint32_t free_block_capacity;
  2736. } gs_heap_allocator_t;
  2737. GS_API_DECL gs_heap_allocator_t gs_heap_allocate_new();
  2738. GS_API_DECL void gs_heap_allocator_free(gs_heap_allocator_t* ha);
  2739. GS_API_DECL void* gs_heap_allocator_allocate(gs_heap_allocator_t* ha, size_t sz);
  2740. GS_API_DECL void gs_heap_allocator_deallocate(gs_heap_allocator_t* ha, void* memory);
  2741. /*================================================================================
  2742. // Pool Allocator
  2743. ================================================================================*/
  2744. /*================================================================================
  2745. // Paged Allocator
  2746. ================================================================================*/
  2747. typedef struct gs_paged_allocator_block_t {
  2748. struct gs_paged_allocator_block_t* next;
  2749. } gs_paged_allocator_block_t;
  2750. typedef struct gs_paged_allocator_page_t {
  2751. struct gs_paged_allocator_page_t* next;
  2752. struct gs_paged_allocator_block_t* data;
  2753. } gs_paged_allocator_page_t;
  2754. typedef struct gs_paged_allocator_t {
  2755. uint32_t block_size;
  2756. uint32_t blocks_per_page;
  2757. gs_paged_allocator_page_t* pages;
  2758. uint32_t page_count;
  2759. gs_paged_allocator_block_t* free_list;
  2760. } gs_paged_allocator_t;
  2761. GS_API_DECL gs_paged_allocator_t gs_paged_allocator_new(size_t element_size, size_t elements_per_page);
  2762. GS_API_DECL void gs_paged_allocator_free(gs_paged_allocator_t* pa);
  2763. GS_API_DECL void* gs_paged_allocator_allocate(gs_paged_allocator_t* pa);
  2764. GS_API_DECL void gs_paged_allocator_deallocate(gs_paged_allocator_t* pa, void* data);
  2765. GS_API_DECL void gs_paged_allocator_clear(gs_paged_allocator_t* pa);
  2766. /** @} */ // end of gs_memory
  2767. /*========================
  2768. // GS_MATH
  2769. ========================*/
  2770. /** @defgroup gs_math Math
  2771. * Gunslinger Math
  2772. * @{
  2773. */
  2774. // Defines
  2775. #define GS_EPSILON (1e-6)
  2776. #define GS_PI 3.1415926535897932
  2777. #define GS_TAU 2.0 * GS_PI
  2778. // Useful Utility
  2779. #define gs_v2(...) gs_vec2_ctor(__VA_ARGS__)
  2780. #define gs_v3(...) gs_vec3_ctor(__VA_ARGS__)
  2781. #define gs_v4(...) gs_vec4_ctor(__VA_ARGS__)
  2782. #define gs_quat(...) gs_quat_ctor(__VA_ARGS__)
  2783. #define gs_v2s(__S) gs_vec2_ctor((__S), (__S))
  2784. #define gs_v3s(__S) gs_vec3_ctor((__S), (__S), (__S))
  2785. #define gs_v4s(__S) gs_vec4_ctor((__S), (__S), (__S), (__S))
  2786. #define gs_v4_xy_v(__X, __Y, __V) gs_vec4_ctor((__X), (__Y), (__V).x, (__V).y)
  2787. #define gs_v4_xyz_s(__XYZ, __S) gs_vec4_ctor((__XYZ).x, (__XYZ).y, (__XYZ).z, (__S))
  2788. #define GS_XAXIS gs_v3(1.f, 0.f, 0.f)
  2789. #define GS_YAXIS gs_v3(0.f, 1.f, 0.f)
  2790. #define GS_ZAXIS gs_v3(0.f, 0.f, 1.f)
  2791. /*================================================================================
  2792. // Useful Common Math Functions
  2793. ================================================================================*/
  2794. #define gs_rad2deg(__R)\
  2795. (float)((__R * 180.0f) / GS_PI)
  2796. #define gs_deg2rad(__D)\
  2797. (float)((__D * GS_PI) / 180.0f)
  2798. // Interpolation
  2799. // Source: https://codeplea.com/simple-interpolation
  2800. // Returns v based on t
  2801. gs_inline float
  2802. gs_interp_linear(float a, float b, float t)
  2803. {
  2804. return (a + t * (b - a));
  2805. }
  2806. // Returns t based on v
  2807. gs_inline float
  2808. gs_interp_linear_inv(float a, float b, float v)
  2809. {
  2810. return (v - a) / (b - a);
  2811. }
  2812. gs_inline float
  2813. gs_interp_smoothstep(float a, float b, float t)
  2814. {
  2815. return gs_interp_linear(a, b, t * t * (3.0f - 2.0f * t));
  2816. }
  2817. gs_inline float
  2818. gs_interp_cosine(float a, float b, float t)
  2819. {
  2820. return gs_interp_linear(a, b, (float)-cos(GS_PI * t) * 0.5f + 0.5f);
  2821. }
  2822. gs_inline float
  2823. gs_interp_acceleration(float a, float b, float t)
  2824. {
  2825. return gs_interp_linear(a, b, t * t);
  2826. }
  2827. gs_inline float
  2828. gs_interp_deceleration(float a, float b, float t)
  2829. {
  2830. return gs_interp_linear(a, b, 1.0f - (1.0f - t) * (1.0f - t));
  2831. }
  2832. gs_inline float
  2833. gs_round(float val)
  2834. {
  2835. return (float)floor(val + 0.5f);
  2836. }
  2837. gs_inline float
  2838. gs_map_range(float input_start, float input_end, float output_start, float output_end, float val)
  2839. {
  2840. float slope = (output_end - output_start) / (input_end - input_start);
  2841. return (output_start + (slope * (val - input_start)));
  2842. }
  2843. // Easings from: https://github.com/raysan5/raylib/blob/ea0f6c7a26f3a61f3be542aa8f066ce033766a9f/examples/others/easings.h
  2844. gs_inline
  2845. float gs_ease_cubic_in(float t, float b, float c, float d)
  2846. {
  2847. t /= d;
  2848. return (c*t*t*t + b);
  2849. }
  2850. gs_inline
  2851. float gs_ease_cubic_out(float t, float b, float c, float d)
  2852. {
  2853. t = t/d - 1.0f;
  2854. return (c*(t*t*t + 1.0f) + b);
  2855. }
  2856. gs_inline
  2857. float gs_ease_cubic_in_out(float t, float b, float c, float d)
  2858. {
  2859. if ((t/=d/2.0f) < 1.0f)
  2860. {
  2861. return (c/2.0f*t*t*t + b);
  2862. }
  2863. t -= 2.0f;
  2864. return (c/2.0f*(t*t*t + 2.0f) + b);
  2865. }
  2866. /*================================================================================
  2867. // Vec2
  2868. ================================================================================*/
  2869. /** @brief struct gs_vec2 in gs math */
  2870. typedef struct
  2871. {
  2872. union
  2873. {
  2874. f32 xy[2];
  2875. struct
  2876. {
  2877. f32 x, y;
  2878. };
  2879. };
  2880. } gs_vec2_t;
  2881. typedef gs_vec2_t gs_vec2;
  2882. gs_inline gs_vec2
  2883. gs_vec2_ctor(f32 _x, f32 _y)
  2884. {
  2885. gs_vec2 v;
  2886. v.x = _x;
  2887. v.y = _y;
  2888. return v;
  2889. }
  2890. gs_inline bool
  2891. gs_vec2_nan(gs_vec2 v)
  2892. {
  2893. if (v.x != v.x || v.y != v.y) return true;
  2894. return false;
  2895. }
  2896. gs_inline gs_vec2
  2897. gs_vec2_add(gs_vec2 v0, gs_vec2 v1)
  2898. {
  2899. return gs_vec2_ctor(v0.x + v1.x, v0.y + v1.y);
  2900. }
  2901. gs_inline gs_vec2
  2902. gs_vec2_sub(gs_vec2 v0, gs_vec2 v1)
  2903. {
  2904. return gs_vec2_ctor(v0.x - v1.x, v0.y - v1.y);
  2905. }
  2906. gs_inline gs_vec2
  2907. gs_vec2_mul(gs_vec2 v0, gs_vec2 v1)
  2908. {
  2909. return gs_vec2_ctor(v0.x * v1.x, v0.y * v1.y);
  2910. }
  2911. gs_inline gs_vec2
  2912. gs_vec2_div(gs_vec2 v0, gs_vec2 v1)
  2913. {
  2914. return gs_vec2_ctor(v0.x / v1.x, v0.y / v1.y);
  2915. }
  2916. gs_inline bool
  2917. gs_vec2_equals(gs_vec2 v0, gs_vec2 v1)
  2918. {
  2919. return (v0.x == v1.x && v0.y == v1.y);
  2920. }
  2921. gs_inline gs_vec2
  2922. gs_vec2_scale(gs_vec2 v, f32 s)
  2923. {
  2924. return gs_vec2_ctor(v.x * s, v.y * s);
  2925. }
  2926. gs_inline f32
  2927. gs_vec2_dot(gs_vec2 v0, gs_vec2 v1)
  2928. {
  2929. return (f32)(v0.x * v1.x + v0.y * v1.y);
  2930. }
  2931. gs_inline f32
  2932. gs_vec2_len(gs_vec2 v)
  2933. {
  2934. return (f32)sqrt(gs_vec2_dot(v, v));
  2935. }
  2936. gs_inline gs_vec2
  2937. gs_vec2_project_onto(gs_vec2 v0, gs_vec2 v1)
  2938. {
  2939. f32 dot = gs_vec2_dot(v0, v1);
  2940. f32 len = gs_vec2_dot(v1, v1);
  2941. // Orthogonal, so return v1
  2942. if (len == 0.f) return v1;
  2943. return gs_vec2_scale(v1, dot / len);
  2944. }
  2945. gs_inline gs_vec2 gs_vec2_norm(gs_vec2 v)
  2946. {
  2947. f32 len = gs_vec2_len(v);
  2948. return gs_vec2_scale(v, len != 0.f ? 1.0f / gs_vec2_len(v) : 1.f);
  2949. }
  2950. gs_inline
  2951. f32 gs_vec2_dist(gs_vec2 a, gs_vec2 b)
  2952. {
  2953. f32 dx = (a.x - b.x);
  2954. f32 dy = (a.y - b.y);
  2955. return (float)(sqrt(dx * dx + dy * dy));
  2956. }
  2957. gs_inline
  2958. f32 gs_vec2_dist2(gs_vec2 a, gs_vec2 b)
  2959. {
  2960. f32 dx = (a.x - b.x);
  2961. f32 dy = (a.y - b.y);
  2962. return (float)(dx * dx + dy * dy);
  2963. }
  2964. gs_inline
  2965. f32 gs_vec2_cross(gs_vec2 a, gs_vec2 b)
  2966. {
  2967. return a.x * b.y - a.y * b.x;
  2968. }
  2969. gs_inline
  2970. f32 gs_vec2_angle(gs_vec2 a, gs_vec2 b)
  2971. {
  2972. return (float)acos(gs_vec2_dot(a, b) / (gs_vec2_len(a) * gs_vec2_len(b)));
  2973. }
  2974. gs_inline
  2975. b32 gs_vec2_equal(gs_vec2 a, gs_vec2 b)
  2976. {
  2977. return (a.x == b.x && a.y == b.y);
  2978. }
  2979. /*================================================================================
  2980. // Vec3
  2981. ================================================================================*/
  2982. typedef struct
  2983. {
  2984. union
  2985. {
  2986. f32 xyz[3];
  2987. struct
  2988. {
  2989. f32 x, y, z;
  2990. };
  2991. };
  2992. } gs_vec3_t;
  2993. typedef gs_vec3_t gs_vec3;
  2994. gs_inline gs_vec3
  2995. gs_vec3_ctor(f32 _x, f32 _y, f32 _z)
  2996. {
  2997. gs_vec3 v;
  2998. v.x = _x;
  2999. v.y = _y;
  3000. v.z = _z;
  3001. return v;
  3002. }
  3003. gs_inline bool
  3004. gs_vec3_eq(gs_vec3 v0, gs_vec3 v1)
  3005. {
  3006. return (v0.x == v1.x && v0.y == v1.y && v0.z == v1.z);
  3007. }
  3008. gs_inline gs_vec3
  3009. gs_vec3_add(gs_vec3 v0, gs_vec3 v1)
  3010. {
  3011. return gs_vec3_ctor(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z);
  3012. }
  3013. gs_inline gs_vec3
  3014. gs_vec3_sub(gs_vec3 v0, gs_vec3 v1)
  3015. {
  3016. return gs_vec3_ctor(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z);
  3017. }
  3018. gs_inline gs_vec3
  3019. gs_vec3_mul(gs_vec3 v0, gs_vec3 v1)
  3020. {
  3021. return gs_vec3_ctor(v0.x * v1.x, v0.y * v1.y, v0.z * v1.z);
  3022. }
  3023. gs_inline gs_vec3
  3024. gs_vec3_div(gs_vec3 v0, gs_vec3 v1)
  3025. {
  3026. return gs_vec3_ctor(v0.x / v1.x, v0.y / v1.y, v0.z / v1.z);
  3027. }
  3028. gs_inline gs_vec3
  3029. gs_vec3_scale(gs_vec3 v, f32 s)
  3030. {
  3031. return gs_vec3_ctor(v.x * s, v.y * s, v.z * s);
  3032. }
  3033. gs_inline gs_vec3
  3034. gs_vec3_neg(gs_vec3 v)
  3035. {
  3036. return gs_vec3_scale(v, -1.f);
  3037. }
  3038. gs_inline f32
  3039. gs_vec3_dot(gs_vec3 v0, gs_vec3 v1)
  3040. {
  3041. f32 dot = (f32)((v0.x * v1.x) + (v0.y * v1.y) + v0.z * v1.z);
  3042. return dot;
  3043. }
  3044. gs_inline bool
  3045. gs_vec3_same_dir(gs_vec3 v0, gs_vec3 v1)
  3046. {
  3047. return (gs_vec3_dot(v0, v1) > 0.f);
  3048. }
  3049. gs_inline gs_vec3
  3050. gs_vec3_sign(gs_vec3 v)
  3051. {
  3052. return (gs_vec3_ctor(
  3053. v.x < 0.f ? -1.f : v.x > 0.f ? 1.f : 0.f,
  3054. v.y < 0.f ? -1.f : v.y > 0.f ? 1.f : 0.f,
  3055. v.z < 0.f ? -1.f : v.z > 0.f ? 1.f : 0.f
  3056. ));
  3057. }
  3058. gs_inline float
  3059. gs_vec3_signX(gs_vec3 v)
  3060. {
  3061. return (v.x < 0.f ? -1.f : v.x > 0.f ? 1.f : 0.f);
  3062. }
  3063. gs_inline float
  3064. gs_vec3_signY(gs_vec3 v)
  3065. {
  3066. return (v.y < 0.f ? -1.f : v.y > 0.f ? 1.f : 0.f);
  3067. }
  3068. gs_inline float
  3069. gs_vec3_signZ(gs_vec3 v)
  3070. {
  3071. return (v.z < 0.f ? -1.f : v.z > 0.f ? 1.f : 0.f);
  3072. }
  3073. gs_inline f32
  3074. gs_vec3_len(gs_vec3 v)
  3075. {
  3076. return (f32)sqrt(gs_vec3_dot(v, v));
  3077. }
  3078. gs_inline f32
  3079. gs_vec3_len2(gs_vec3 v)
  3080. {
  3081. return (f32)(gs_vec3_dot(v, v));
  3082. }
  3083. gs_inline gs_vec3
  3084. gs_vec3_project_onto(gs_vec3 v0, gs_vec3 v1)
  3085. {
  3086. f32 dot = gs_vec3_dot(v0, v1);
  3087. f32 len = gs_vec3_dot(v1, v1);
  3088. // Orthogonal, so return v1
  3089. if (len == 0.f) return v1;
  3090. return gs_vec3_scale(v1, dot / len);
  3091. }
  3092. gs_inline bool
  3093. gs_vec3_nan(gs_vec3 v)
  3094. {
  3095. if (v.x != v.x || v.y != v.y || v.z != v.z) return true;
  3096. return false;
  3097. }
  3098. gs_inline
  3099. f32 gs_vec3_dist2(gs_vec3 a, gs_vec3 b)
  3100. {
  3101. f32 dx = (a.x - b.x);
  3102. f32 dy = (a.y - b.y);
  3103. f32 dz = (a.z - b.z);
  3104. return (dx * dx + dy * dy + dz * dz);
  3105. }
  3106. gs_inline
  3107. f32 gs_vec3_dist(gs_vec3 a, gs_vec3 b)
  3108. {
  3109. return sqrt(gs_vec3_dist2(a, b));
  3110. }
  3111. gs_inline gs_vec3
  3112. gs_vec3_norm(gs_vec3 v)
  3113. {
  3114. f32 len = gs_vec3_len(v);
  3115. return len == 0.f ? v : gs_vec3_scale(v, 1.f / len);
  3116. }
  3117. gs_inline gs_vec3
  3118. gs_vec3_cross(gs_vec3 v0, gs_vec3 v1)
  3119. {
  3120. return gs_vec3_ctor
  3121. (
  3122. v0.y * v1.z - v0.z * v1.y,
  3123. v0.z * v1.x - v0.x * v1.z,
  3124. v0.x * v1.y - v0.y * v1.x
  3125. );
  3126. }
  3127. gs_inline void gs_vec3_scale_ip(gs_vec3* vp, f32 s)
  3128. {
  3129. vp->x *= s;
  3130. vp->y *= s;
  3131. vp->z *= s;
  3132. }
  3133. gs_inline float gs_vec3_angle_between(gs_vec3 v0, gs_vec3 v1)
  3134. {
  3135. return acosf(gs_vec3_dot(v0, v1));
  3136. }
  3137. gs_inline float gs_vec3_angle_between_signed(gs_vec3 v0, gs_vec3 v1)
  3138. {
  3139. return asinf(gs_vec3_len(gs_vec3_cross(v0, v1)));
  3140. }
  3141. gs_inline gs_vec3 gs_vec3_triple_cross_product(gs_vec3 a, gs_vec3 b, gs_vec3 c)
  3142. {
  3143. return gs_vec3_sub((gs_vec3_scale(b, gs_vec3_dot(c, a))), (gs_vec3_scale(a, gs_vec3_dot(c, b))));
  3144. }
  3145. /*================================================================================
  3146. // Vec4
  3147. ================================================================================*/
  3148. typedef struct
  3149. {
  3150. union
  3151. {
  3152. f32 xyzw[4];
  3153. struct
  3154. {
  3155. f32 x, y, z, w;
  3156. };
  3157. };
  3158. } gs_vec4_t;
  3159. typedef gs_vec4_t gs_vec4;
  3160. gs_inline gs_vec4
  3161. gs_vec4_ctor(f32 _x, f32 _y, f32 _z, f32 _w)
  3162. {
  3163. gs_vec4 v;
  3164. v.x = _x;
  3165. v.y = _y;
  3166. v.z = _z;
  3167. v.w = _w;
  3168. return v;
  3169. }
  3170. gs_inline gs_vec4
  3171. gs_vec4_add(gs_vec4 v0, gs_vec4 v1)
  3172. {
  3173. return gs_vec4_ctor(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w);
  3174. }
  3175. gs_inline gs_vec4
  3176. gs_vec4_sub(gs_vec4 v0, gs_vec4 v1)
  3177. {
  3178. return gs_vec4_ctor(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w);
  3179. }
  3180. gs_inline gs_vec4
  3181. gs_vec4_mul(gs_vec4 v0, gs_vec4 v1)
  3182. {
  3183. return gs_vec4_ctor(v0.x * v1.x, v0.y * v1.y, v0.z * v1.z, v0.w * v1.w);
  3184. }
  3185. gs_inline gs_vec4
  3186. gs_vec4_div(gs_vec4 v0, gs_vec4 v1)
  3187. {
  3188. return gs_vec4_ctor(v0.x / v1.x, v0.y / v1.y, v0.z / v1.z, v0.w / v1.w);
  3189. }
  3190. gs_inline gs_vec4
  3191. gs_vec4_scale(gs_vec4 v, f32 s)
  3192. {
  3193. return gs_vec4_ctor(v.x * s, v.y * s, v.z * s, v.w * s);
  3194. }
  3195. gs_inline f32
  3196. gs_vec4_dot(gs_vec4 v0, gs_vec4 v1)
  3197. {
  3198. return (f32)(v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w);
  3199. }
  3200. gs_inline f32
  3201. gs_vec4_len(gs_vec4 v)
  3202. {
  3203. return (f32)sqrt(gs_vec4_dot(v, v));
  3204. }
  3205. gs_inline gs_vec4
  3206. gs_vec4_project_onto(gs_vec4 v0, gs_vec4 v1)
  3207. {
  3208. f32 dot = gs_vec4_dot(v0, v1);
  3209. f32 len = gs_vec4_dot(v1, v1);
  3210. // Orthogonal, so return v1
  3211. if (len == 0.f) return v1;
  3212. return gs_vec4_scale(v1, dot / len);
  3213. }
  3214. gs_inline gs_vec4
  3215. gs_vec4_norm(gs_vec4 v)
  3216. {
  3217. return gs_vec4_scale(v, 1.0f / gs_vec4_len(v));
  3218. }
  3219. gs_inline f32
  3220. gs_vec4_dist(gs_vec4 v0, gs_vec4 v1)
  3221. {
  3222. f32 dx = (v0.x - v1.x);
  3223. f32 dy = (v0.y - v1.y);
  3224. f32 dz = (v0.z - v1.z);
  3225. f32 dw = (v0.w - v1.w);
  3226. return (float)(sqrt(dx * dx + dy * dy + dz * dz + dw * dw));
  3227. }
  3228. /*================================================================================
  3229. // Useful Vector Functions
  3230. ================================================================================*/
  3231. gs_inline
  3232. gs_vec3 gs_v4tov3(gs_vec4 v)
  3233. {
  3234. return gs_v3(v.x, v.y, v.z);
  3235. }
  3236. gs_inline
  3237. gs_vec2 gs_v3tov2(gs_vec3 v)
  3238. {
  3239. return gs_v2(v.x, v.y);
  3240. }
  3241. gs_inline
  3242. gs_vec3 gs_v2tov3(gs_vec2 v)
  3243. {
  3244. return gs_v3(v.x, v.y, 0.f);
  3245. }
  3246. /*================================================================================
  3247. // Mat3x3
  3248. ================================================================================*/
  3249. /*
  3250. Matrices are stored in linear, contiguous memory and assume a column-major ordering.
  3251. */
  3252. typedef struct gs_mat3 {
  3253. f32 m[9];
  3254. } gs_mat3;
  3255. gs_inline gs_mat3 gs_mat3_diag(float val)
  3256. {
  3257. gs_mat3 m = gs_default_val();
  3258. m.m[0 + 0 * 3] = val;
  3259. m.m[1 + 1 * 3] = val;
  3260. m.m[2 + 2 * 3] = val;
  3261. return m;
  3262. }
  3263. #define gs_mat3_identity()\
  3264. gs_mat3_diag(1.f)
  3265. gs_inline gs_mat3
  3266. gs_mat3_mul(gs_mat3 m0, gs_mat3 m1)
  3267. {
  3268. gs_mat3 m = gs_default_val();
  3269. for (u32 y = 0; y < 3; ++y)
  3270. {
  3271. for (u32 x = 0; x < 3; ++x)
  3272. {
  3273. f32 sum = 0.0f;
  3274. for (u32 e = 0; e < 3; ++e)
  3275. {
  3276. sum += m0.m[x + e * 3] * m1.m[e + y * 3];
  3277. }
  3278. m.m[x + y * 3] = sum;
  3279. }
  3280. }
  3281. return m;
  3282. }
  3283. gs_inline gs_vec3
  3284. gs_mat3_mul_vec3(gs_mat3 m, gs_vec3 v)
  3285. {
  3286. return gs_vec3_ctor(
  3287. m.m[0] * v.x + m.m[1] * v.y + m.m[2] * v.z,
  3288. m.m[3] * v.x + m.m[4] * v.y + m.m[5] * v.z,
  3289. m.m[6] * v.x + m.m[7] * v.y + m.m[8] * v.z
  3290. );
  3291. }
  3292. gs_inline gs_mat3
  3293. gs_mat3_scale(float x, float y, float z)
  3294. {
  3295. gs_mat3 m = gs_default_val();
  3296. m.m[0] = x;
  3297. m.m[4] = y;
  3298. m.m[8] = z;
  3299. return m;
  3300. }
  3301. gs_inline gs_mat3
  3302. gs_mat3_rotate(float radians, float x, float y, float z)
  3303. {
  3304. gs_mat3 m = gs_default_val();
  3305. float s = sinf(radians), c = cosf(radians), c1 = 1.f - c;
  3306. float xy = x * y;
  3307. float yz = y * z;
  3308. float zx = z * x;
  3309. float xs = x * s;
  3310. float ys = y * s;
  3311. float zs = z * s;
  3312. m.m[0] = c1 * x * x + c; m.m[1] = c1 * xy - zs; m.m[2] = c1 * zx + ys;
  3313. m.m[3] = c1 * xy + zs; m.m[4] = c1 * y * y + c; m.m[5] = c1 * yz - xs;
  3314. m.m[6] = c1 * zx - ys; m.m[7] = c1 * yz + xs; m.m[8] = c1 * z * z + c;
  3315. return m;
  3316. }
  3317. gs_inline gs_mat3
  3318. gs_mat3_rotatev(float radians, gs_vec3 axis)
  3319. {
  3320. return gs_mat3_rotate(radians, axis.x, axis.y, axis.z);
  3321. }
  3322. // Turn quaternion into mat3
  3323. gs_inline gs_mat3
  3324. gs_mat3_rotateq(gs_vec4 q)
  3325. {
  3326. gs_mat3 m = gs_default_val();
  3327. float x2 = q.x * q.x, y2 = q.y * q.y, z2 = q.z * q.z, w2 = q.w * q.w;
  3328. float xz = q.x *q.z, xy = q.x * q.y, yz = q.y * q.z, wz = q.w * q.z, wy = q.w * q.y, wx = q.w * q.x;
  3329. m.m[0] = 1 - 2 * (y2 + z2); m.m[1] = 2 * (xy + wz); m.m[2] = 2 * (xz - wy);
  3330. m.m[3] = 2 * (xy - wz); m.m[4] = 1 - 2 * (x2 + z2); m.m[5] = 2 * (yz + wx);
  3331. m.m[6] = 2 * (xz + wy); m.m[7] = 2 * (yz - wx); m.m[8] = 1 - 2 * (x2 + y2);
  3332. return m;
  3333. }
  3334. gs_inline gs_mat3
  3335. gs_mat3_rsq(gs_vec4 q, gs_vec3 s)
  3336. {
  3337. gs_mat3 mr = gs_mat3_rotateq(q);
  3338. gs_mat3 ms = gs_mat3_scale(s.x, s.y, s.z);
  3339. return gs_mat3_mul(mr, ms);
  3340. }
  3341. gs_inline gs_mat3
  3342. gs_mat3_inverse(gs_mat3 m)
  3343. {
  3344. gs_mat3 r = gs_default_val();
  3345. double det = (double)(m.m[0 * 3 + 0] * (m.m[1 * 3 + 1] * m.m[2 * 3 + 2] - m.m[2 * 3 + 1] * m.m[1 * 3 + 2]) -
  3346. m.m[0 * 3 + 1] * (m.m[1 * 3 + 0] * m.m[2 * 3 + 2] - m.m[1 * 3 + 2] * m.m[2 * 3 + 0]) +
  3347. m.m[0 * 3 + 2] * (m.m[1 * 3 + 0] * m.m[2 * 3 + 1] - m.m[1 * 3 + 1] * m.m[2 * 3 + 0]));
  3348. double inv_det = det ? 1.0 / det : 0.0;
  3349. r.m[0 * 3 + 0] = (m.m[1 * 3 + 1] * m.m[2 * 3 + 2] - m.m[2 * 3 + 1] * m.m[1 * 3 + 2]) * inv_det;
  3350. r.m[0 * 3 + 1] = (m.m[0 * 3 + 2] * m.m[2 * 3 + 1] - m.m[0 * 3 + 1] * m.m[2 * 3 + 2]) * inv_det;
  3351. r.m[0 * 3 + 2] = (m.m[0 * 3 + 1] * m.m[1 * 3 + 2] - m.m[0 * 3 + 2] * m.m[1 * 3 + 1]) * inv_det;
  3352. r.m[1 * 3 + 0] = (m.m[1 * 3 + 2] * m.m[2 * 3 + 0] - m.m[1 * 3 + 0] * m.m[2 * 3 + 2]) * inv_det;
  3353. r.m[1 * 3 + 1] = (m.m[0 * 3 + 0] * m.m[2 * 3 + 2] - m.m[0 * 3 + 2] * m.m[2 * 3 + 0]) * inv_det;
  3354. r.m[1 * 3 + 2] = (m.m[1 * 3 + 0] * m.m[0 * 3 + 2] - m.m[0 * 3 + 0] * m.m[1 * 3 + 2]) * inv_det;
  3355. r.m[2 * 3 + 0] = (m.m[1 * 3 + 0] * m.m[2 * 3 + 1] - m.m[2 * 3 + 0] * m.m[1 * 3 + 1]) * inv_det;
  3356. r.m[2 * 3 + 1] = (m.m[2 * 3 + 0] * m.m[0 * 3 + 1] - m.m[0 * 3 + 0] * m.m[2 * 3 + 1]) * inv_det;
  3357. r.m[2 * 3 + 2] = (m.m[0 * 3 + 0] * m.m[1 * 3 + 1] - m.m[1 * 3 + 0] * m.m[0 * 3 + 1]) * inv_det;
  3358. return r;
  3359. }
  3360. /*================================================================================
  3361. // Mat4x4
  3362. ================================================================================*/
  3363. /*
  3364. Matrices are stored in linear, contiguous memory and assume a column-major ordering.
  3365. */
  3366. typedef struct gs_mat4
  3367. {
  3368. union {
  3369. gs_vec4 rows[4];
  3370. float m[4][4];
  3371. float elements[16];
  3372. struct {
  3373. gs_vec4 right, up, dir, position;
  3374. } v;
  3375. };
  3376. } gs_mat4_t;
  3377. typedef gs_mat4_t gs_mat4;
  3378. gs_inline gs_mat4
  3379. gs_mat4_diag(f32 val)
  3380. {
  3381. gs_mat4 m;
  3382. memset(m.elements, 0, sizeof(m.elements));
  3383. m.elements[0 + 0 * 4] = val;
  3384. m.elements[1 + 1 * 4] = val;
  3385. m.elements[2 + 2 * 4] = val;
  3386. m.elements[3 + 3 * 4] = val;
  3387. return m;
  3388. }
  3389. #define gs_mat4_identity()\
  3390. gs_mat4_diag(1.0f)
  3391. gs_inline gs_mat4
  3392. gs_mat4_ctor() {
  3393. gs_mat4 mat = gs_default_val();
  3394. return mat;
  3395. }
  3396. gs_inline
  3397. gs_mat4 gs_mat4_elem(const float* elements)
  3398. {
  3399. gs_mat4 mat = gs_mat4_ctor();
  3400. memcpy(mat.elements, elements, sizeof(f32) * 16);
  3401. return mat;
  3402. }
  3403. gs_inline gs_mat4
  3404. gs_mat4_mul(gs_mat4 m0, gs_mat4 m1)
  3405. {
  3406. gs_mat4 m_res = gs_mat4_ctor();
  3407. for (u32 y = 0; y < 4; ++y)
  3408. {
  3409. for (u32 x = 0; x < 4; ++x)
  3410. {
  3411. f32 sum = 0.0f;
  3412. for (u32 e = 0; e < 4; ++e)
  3413. {
  3414. sum += m0.elements[x + e * 4] * m1.elements[e + y * 4];
  3415. }
  3416. m_res.elements[x + y * 4] = sum;
  3417. }
  3418. }
  3419. return m_res;
  3420. }
  3421. gs_inline
  3422. gs_mat4 gs_mat4_mul_list(uint32_t count, ...)
  3423. {
  3424. va_list ap;
  3425. gs_mat4 m = gs_mat4_identity();
  3426. va_start(ap, count);
  3427. for (uint32_t i = 0; i < count; ++i) {
  3428. m = gs_mat4_mul(m, va_arg(ap, gs_mat4));
  3429. }
  3430. va_end(ap);
  3431. return m;
  3432. }
  3433. gs_inline
  3434. void gs_mat4_set_elements(gs_mat4* m, float* elements, uint32_t count)
  3435. {
  3436. for (u32 i = 0; i < count; ++i)
  3437. {
  3438. m->elements[i] = elements[i];
  3439. }
  3440. }
  3441. gs_inline
  3442. gs_mat4 gs_mat4_ortho_norm(const gs_mat4* m)
  3443. {
  3444. gs_mat4 r = *m;
  3445. r.v.right = gs_vec4_norm(r.v.right);
  3446. r.v.up = gs_vec4_norm(r.v.up);
  3447. r.v.dir = gs_vec4_norm(r.v.dir);
  3448. return r;
  3449. }
  3450. gs_inline
  3451. gs_mat4 gs_mat4_transpose(gs_mat4 m)
  3452. {
  3453. gs_mat4 t = gs_mat4_identity();
  3454. // First row
  3455. t.elements[0 * 4 + 0] = m.elements[0 * 4 + 0];
  3456. t.elements[1 * 4 + 0] = m.elements[0 * 4 + 1];
  3457. t.elements[2 * 4 + 0] = m.elements[0 * 4 + 2];
  3458. t.elements[3 * 4 + 0] = m.elements[0 * 4 + 3];
  3459. // Second row
  3460. t.elements[0 * 4 + 1] = m.elements[1 * 4 + 0];
  3461. t.elements[1 * 4 + 1] = m.elements[1 * 4 + 1];
  3462. t.elements[2 * 4 + 1] = m.elements[1 * 4 + 2];
  3463. t.elements[3 * 4 + 1] = m.elements[1 * 4 + 3];
  3464. // Third row
  3465. t.elements[0 * 4 + 2] = m.elements[2 * 4 + 0];
  3466. t.elements[1 * 4 + 2] = m.elements[2 * 4 + 1];
  3467. t.elements[2 * 4 + 2] = m.elements[2 * 4 + 2];
  3468. t.elements[3 * 4 + 2] = m.elements[2 * 4 + 3];
  3469. // Fourth row
  3470. t.elements[0 * 4 + 3] = m.elements[3 * 4 + 0];
  3471. t.elements[1 * 4 + 3] = m.elements[3 * 4 + 1];
  3472. t.elements[2 * 4 + 3] = m.elements[3 * 4 + 2];
  3473. t.elements[3 * 4 + 3] = m.elements[3 * 4 + 3];
  3474. return t;
  3475. }
  3476. gs_inline
  3477. gs_mat4 gs_mat4_inverse(gs_mat4 m)
  3478. {
  3479. gs_mat4 res = gs_mat4_identity();
  3480. f32 temp[16];
  3481. temp[0] = m.elements[5] * m.elements[10] * m.elements[15] -
  3482. m.elements[5] * m.elements[11] * m.elements[14] -
  3483. m.elements[9] * m.elements[6] * m.elements[15] +
  3484. m.elements[9] * m.elements[7] * m.elements[14] +
  3485. m.elements[13] * m.elements[6] * m.elements[11] -
  3486. m.elements[13] * m.elements[7] * m.elements[10];
  3487. temp[4] = -m.elements[4] * m.elements[10] * m.elements[15] +
  3488. m.elements[4] * m.elements[11] * m.elements[14] +
  3489. m.elements[8] * m.elements[6] * m.elements[15] -
  3490. m.elements[8] * m.elements[7] * m.elements[14] -
  3491. m.elements[12] * m.elements[6] * m.elements[11] +
  3492. m.elements[12] * m.elements[7] * m.elements[10];
  3493. temp[8] = m.elements[4] * m.elements[9] * m.elements[15] -
  3494. m.elements[4] * m.elements[11] * m.elements[13] -
  3495. m.elements[8] * m.elements[5] * m.elements[15] +
  3496. m.elements[8] * m.elements[7] * m.elements[13] +
  3497. m.elements[12] * m.elements[5] * m.elements[11] -
  3498. m.elements[12] * m.elements[7] * m.elements[9];
  3499. temp[12] = -m.elements[4] * m.elements[9] * m.elements[14] +
  3500. m.elements[4] * m.elements[10] * m.elements[13] +
  3501. m.elements[8] * m.elements[5] * m.elements[14] -
  3502. m.elements[8] * m.elements[6] * m.elements[13] -
  3503. m.elements[12] * m.elements[5] * m.elements[10] +
  3504. m.elements[12] * m.elements[6] * m.elements[9];
  3505. temp[1] = -m.elements[1] * m.elements[10] * m.elements[15] +
  3506. m.elements[1] * m.elements[11] * m.elements[14] +
  3507. m.elements[9] * m.elements[2] * m.elements[15] -
  3508. m.elements[9] * m.elements[3] * m.elements[14] -
  3509. m.elements[13] * m.elements[2] * m.elements[11] +
  3510. m.elements[13] * m.elements[3] * m.elements[10];
  3511. temp[5] = m.elements[0] * m.elements[10] * m.elements[15] -
  3512. m.elements[0] * m.elements[11] * m.elements[14] -
  3513. m.elements[8] * m.elements[2] * m.elements[15] +
  3514. m.elements[8] * m.elements[3] * m.elements[14] +
  3515. m.elements[12] * m.elements[2] * m.elements[11] -
  3516. m.elements[12] * m.elements[3] * m.elements[10];
  3517. temp[9] = -m.elements[0] * m.elements[9] * m.elements[15] +
  3518. m.elements[0] * m.elements[11] * m.elements[13] +
  3519. m.elements[8] * m.elements[1] * m.elements[15] -
  3520. m.elements[8] * m.elements[3] * m.elements[13] -
  3521. m.elements[12] * m.elements[1] * m.elements[11] +
  3522. m.elements[12] * m.elements[3] * m.elements[9];
  3523. temp[13] = m.elements[0] * m.elements[9] * m.elements[14] -
  3524. m.elements[0] * m.elements[10] * m.elements[13] -
  3525. m.elements[8] * m.elements[1] * m.elements[14] +
  3526. m.elements[8] * m.elements[2] * m.elements[13] +
  3527. m.elements[12] * m.elements[1] * m.elements[10] -
  3528. m.elements[12] * m.elements[2] * m.elements[9];
  3529. temp[2] = m.elements[1] * m.elements[6] * m.elements[15] -
  3530. m.elements[1] * m.elements[7] * m.elements[14] -
  3531. m.elements[5] * m.elements[2] * m.elements[15] +
  3532. m.elements[5] * m.elements[3] * m.elements[14] +
  3533. m.elements[13] * m.elements[2] * m.elements[7] -
  3534. m.elements[13] * m.elements[3] * m.elements[6];
  3535. temp[6] = -m.elements[0] * m.elements[6] * m.elements[15] +
  3536. m.elements[0] * m.elements[7] * m.elements[14] +
  3537. m.elements[4] * m.elements[2] * m.elements[15] -
  3538. m.elements[4] * m.elements[3] * m.elements[14] -
  3539. m.elements[12] * m.elements[2] * m.elements[7] +
  3540. m.elements[12] * m.elements[3] * m.elements[6];
  3541. temp[10] = m.elements[0] * m.elements[5] * m.elements[15] -
  3542. m.elements[0] * m.elements[7] * m.elements[13] -
  3543. m.elements[4] * m.elements[1] * m.elements[15] +
  3544. m.elements[4] * m.elements[3] * m.elements[13] +
  3545. m.elements[12] * m.elements[1] * m.elements[7] -
  3546. m.elements[12] * m.elements[3] * m.elements[5];
  3547. temp[14] = -m.elements[0] * m.elements[5] * m.elements[14] +
  3548. m.elements[0] * m.elements[6] * m.elements[13] +
  3549. m.elements[4] * m.elements[1] * m.elements[14] -
  3550. m.elements[4] * m.elements[2] * m.elements[13] -
  3551. m.elements[12] * m.elements[1] * m.elements[6] +
  3552. m.elements[12] * m.elements[2] * m.elements[5];
  3553. temp[3] = -m.elements[1] * m.elements[6] * m.elements[11] +
  3554. m.elements[1] * m.elements[7] * m.elements[10] +
  3555. m.elements[5] * m.elements[2] * m.elements[11] -
  3556. m.elements[5] * m.elements[3] * m.elements[10] -
  3557. m.elements[9] * m.elements[2] * m.elements[7] +
  3558. m.elements[9] * m.elements[3] * m.elements[6];
  3559. temp[7] = m.elements[0] * m.elements[6] * m.elements[11] -
  3560. m.elements[0] * m.elements[7] * m.elements[10] -
  3561. m.elements[4] * m.elements[2] * m.elements[11] +
  3562. m.elements[4] * m.elements[3] * m.elements[10] +
  3563. m.elements[8] * m.elements[2] * m.elements[7] -
  3564. m.elements[8] * m.elements[3] * m.elements[6];
  3565. temp[11] = -m.elements[0] * m.elements[5] * m.elements[11] +
  3566. m.elements[0] * m.elements[7] * m.elements[9] +
  3567. m.elements[4] * m.elements[1] * m.elements[11] -
  3568. m.elements[4] * m.elements[3] * m.elements[9] -
  3569. m.elements[8] * m.elements[1] * m.elements[7] +
  3570. m.elements[8] * m.elements[3] * m.elements[5];
  3571. temp[15] = m.elements[0] * m.elements[5] * m.elements[10] -
  3572. m.elements[0] * m.elements[6] * m.elements[9] -
  3573. m.elements[4] * m.elements[1] * m.elements[10] +
  3574. m.elements[4] * m.elements[2] * m.elements[9] +
  3575. m.elements[8] * m.elements[1] * m.elements[6] -
  3576. m.elements[8] * m.elements[2] * m.elements[5];
  3577. float determinant = m.elements[0] * temp[0] + m.elements[1] * temp[4] + m.elements[2] * temp[8] + m.elements[3] * temp[12];
  3578. determinant = 1.0f / determinant;
  3579. for (int i = 0; i < 4 * 4; i++)
  3580. res.elements[i] = (float)(temp[i] * (float)determinant);
  3581. return res;
  3582. }
  3583. /*
  3584. f32 l : left
  3585. f32 r : right
  3586. f32 b : bottom
  3587. f32 t : top
  3588. f32 n : near
  3589. f32 f : far
  3590. */
  3591. gs_inline gs_mat4
  3592. gs_mat4_ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
  3593. {
  3594. gs_mat4 m_res = gs_mat4_identity();
  3595. // Main diagonal
  3596. m_res.elements[0 + 0 * 4] = 2.0f / (r - l);
  3597. m_res.elements[1 + 1 * 4] = 2.0f / (t - b);
  3598. m_res.elements[2 + 2 * 4] = -2.0f / (f - n);
  3599. // Last column
  3600. m_res.elements[0 + 3 * 4] = -(r + l) / (r - l);
  3601. m_res.elements[1 + 3 * 4] = -(t + b) / (t - b);
  3602. m_res.elements[2 + 3 * 4] = -(f + n) / (f - n);
  3603. return m_res;
  3604. }
  3605. gs_inline gs_mat4
  3606. gs_mat4_perspective(f32 fov, f32 asp_ratio, f32 n, f32 f)
  3607. {
  3608. // Zero matrix
  3609. gs_mat4 m_res = gs_mat4_ctor();
  3610. f32 q = 1.0f / (float)tan(gs_deg2rad(0.5f * fov));
  3611. f32 a = q / asp_ratio;
  3612. f32 b = (n + f) / (n - f);
  3613. f32 c = (2.0f * n * f) / (n - f);
  3614. m_res.elements[0 + 0 * 4] = a;
  3615. m_res.elements[1 + 1 * 4] = q;
  3616. m_res.elements[2 + 2 * 4] = b;
  3617. m_res.elements[2 + 3 * 4] = c;
  3618. m_res.elements[3 + 2 * 4] = -1.0f;
  3619. return m_res;
  3620. }
  3621. gs_inline gs_mat4
  3622. gs_mat4_translatev(const gs_vec3 v)
  3623. {
  3624. gs_mat4 m_res = gs_mat4_identity();
  3625. m_res.elements[0 + 4 * 3] = v.x;
  3626. m_res.elements[1 + 4 * 3] = v.y;
  3627. m_res.elements[2 + 4 * 3] = v.z;
  3628. return m_res;
  3629. }
  3630. gs_inline gs_mat4
  3631. gs_mat4_translate(float x, float y, float z)
  3632. {
  3633. return gs_mat4_translatev(gs_v3(x, y, z));
  3634. }
  3635. gs_inline gs_mat4
  3636. gs_mat4_scalev(const gs_vec3 v)
  3637. {
  3638. gs_mat4 m_res = gs_mat4_identity();
  3639. m_res.elements[0 + 0 * 4] = v.x;
  3640. m_res.elements[1 + 1 * 4] = v.y;
  3641. m_res.elements[2 + 2 * 4] = v.z;
  3642. return m_res;
  3643. }
  3644. gs_inline gs_mat4
  3645. gs_mat4_scale(float x, float y, float z)
  3646. {
  3647. return (gs_mat4_scalev(gs_v3(x, y, z)));
  3648. }
  3649. // Assumes normalized axis
  3650. gs_inline gs_mat4
  3651. gs_mat4_rotatev(float angle, gs_vec3 axis)
  3652. {
  3653. gs_mat4 m_res = gs_mat4_identity();
  3654. float a = angle;
  3655. float c = (float)cos(a);
  3656. float s = (float)sin(a);
  3657. gs_vec3 naxis = gs_vec3_norm(axis);
  3658. float x = naxis.x;
  3659. float y = naxis.y;
  3660. float z = naxis.z;
  3661. //First column
  3662. m_res.elements[0 + 0 * 4] = x * x * (1 - c) + c;
  3663. m_res.elements[1 + 0 * 4] = x * y * (1 - c) + z * s;
  3664. m_res.elements[2 + 0 * 4] = x * z * (1 - c) - y * s;
  3665. //Second column
  3666. m_res.elements[0 + 1 * 4] = x * y * (1 - c) - z * s;
  3667. m_res.elements[1 + 1 * 4] = y * y * (1 - c) + c;
  3668. m_res.elements[2 + 1 * 4] = y * z * (1 - c) + x * s;
  3669. //Third column
  3670. m_res.elements[0 + 2 * 4] = x * z * (1 - c) + y * s;
  3671. m_res.elements[1 + 2 * 4] = y * z * (1 - c) - x * s;
  3672. m_res.elements[2 + 2 * 4] = z * z * (1 - c) + c;
  3673. return m_res;
  3674. }
  3675. gs_inline gs_mat4
  3676. gs_mat4_rotate(float angle, float x, float y, float z)
  3677. {
  3678. return gs_mat4_rotatev(angle, gs_v3(x, y, z));
  3679. }
  3680. gs_inline gs_mat4
  3681. gs_mat4_look_at(gs_vec3 position, gs_vec3 target, gs_vec3 up)
  3682. {
  3683. gs_vec3 f = gs_vec3_norm(gs_vec3_sub(target, position));
  3684. gs_vec3 s = gs_vec3_norm(gs_vec3_cross(f, up));
  3685. gs_vec3 u = gs_vec3_cross(s, f);
  3686. gs_mat4 m_res = gs_mat4_identity();
  3687. m_res.elements[0 * 4 + 0] = s.x;
  3688. m_res.elements[1 * 4 + 0] = s.y;
  3689. m_res.elements[2 * 4 + 0] = s.z;
  3690. m_res.elements[0 * 4 + 1] = u.x;
  3691. m_res.elements[1 * 4 + 1] = u.y;
  3692. m_res.elements[2 * 4 + 1] = u.z;
  3693. m_res.elements[0 * 4 + 2] = -f.x;
  3694. m_res.elements[1 * 4 + 2] = -f.y;
  3695. m_res.elements[2 * 4 + 2] = -f.z;
  3696. m_res.elements[3 * 4 + 0] = -gs_vec3_dot(s, position);;
  3697. m_res.elements[3 * 4 + 1] = -gs_vec3_dot(u, position);
  3698. m_res.elements[3 * 4 + 2] = gs_vec3_dot(f, position);
  3699. return m_res;
  3700. }
  3701. // Modified from github.com/CedricGuillemet/ImGuizmo/blob/master/ImGuizmo.cpp
  3702. gs_inline
  3703. void gs_mat4_decompose(const gs_mat4* m, float* translation, float* rotation, float* scale)
  3704. {
  3705. gs_mat4 mat = *m;
  3706. scale[0] = gs_vec4_len(mat.v.right);
  3707. scale[1] = gs_vec4_len(mat.v.up);
  3708. scale[2] = gs_vec4_len(mat.v.dir);
  3709. mat = gs_mat4_ortho_norm(&mat);
  3710. rotation[0] = gs_rad2deg(atan2f(mat.m[1][2], mat.m[2][2]));
  3711. rotation[1] = gs_rad2deg(atan2f(-mat.m[0][2], sqrtf(mat.m[1][2] * mat.m[1][2] +
  3712. mat.m[2][2] * mat.m[2][2])));
  3713. rotation[2] = gs_rad2deg(atan2f(mat.m[0][1], mat.m[0][0]));
  3714. translation[0] = mat.v.position.x;
  3715. translation[1] = mat.v.position.y;
  3716. translation[2] = mat.v.position.z;
  3717. }
  3718. // Modified from github.com/CedricGuillemet/ImGuizmo/blob/master/ImGuizmo.cpp
  3719. gs_inline
  3720. gs_mat4 gs_mat4_recompose(const float* translation, const float* rotation, const float* scale)
  3721. {
  3722. gs_mat4 mat = gs_mat4_identity();
  3723. gs_vec3 direction_unary[3] = {
  3724. GS_XAXIS,
  3725. GS_YAXIS,
  3726. GS_ZAXIS
  3727. };
  3728. gs_mat4 rot[3] = {gs_mat4_identity(), gs_mat4_identity(), gs_mat4_identity()};
  3729. for (uint32_t i = 0; i < 3; ++i) {
  3730. rot[i] = gs_mat4_rotatev(gs_deg2rad(rotation[i]), direction_unary[i]);
  3731. }
  3732. mat = gs_mat4_mul_list(3, rot[2], rot[1], rot[0]);
  3733. float valid_scale[3] = gs_default_val();
  3734. for (uint32_t i = 0; i < 3; ++i) {
  3735. valid_scale[i] = fabsf(scale[i]) < GS_EPSILON ? 0.001f : scale[i];
  3736. }
  3737. mat.v.right = gs_vec4_scale(mat.v.right, valid_scale[0]);
  3738. mat.v.up = gs_vec4_scale(mat.v.up, valid_scale[1]);
  3739. mat.v.dir = gs_vec4_scale(mat.v.dir, valid_scale[2]);
  3740. mat.v.position = gs_v4(translation[0], translation[1], translation[2], 1.f);
  3741. return mat;
  3742. }
  3743. gs_inline
  3744. gs_vec4 gs_mat4_mul_vec4(gs_mat4 m, gs_vec4 v)
  3745. {
  3746. return gs_vec4_ctor
  3747. (
  3748. m.elements[0 + 4 * 0] * v.x + m.elements[0 + 4 * 1] * v.y + m.elements[0 + 4 * 2] * v.z + m.elements[0 + 4 * 3] * v.w,
  3749. m.elements[1 + 4 * 0] * v.x + m.elements[1 + 4 * 1] * v.y + m.elements[1 + 4 * 2] * v.z + m.elements[1 + 4 * 3] * v.w,
  3750. m.elements[2 + 4 * 0] * v.x + m.elements[2 + 4 * 1] * v.y + m.elements[2 + 4 * 2] * v.z + m.elements[2 + 4 * 3] * v.w,
  3751. m.elements[3 + 4 * 0] * v.x + m.elements[3 + 4 * 1] * v.y + m.elements[3 + 4 * 2] * v.z + m.elements[3 + 4 * 3] * v.w
  3752. );
  3753. }
  3754. gs_inline
  3755. gs_vec3 gs_mat4_mul_vec3(gs_mat4 m, gs_vec3 v)
  3756. {
  3757. return gs_v4tov3(gs_mat4_mul_vec4(m, gs_v4_xyz_s(v, 1.f)));
  3758. }
  3759. /*================================================================================
  3760. // Quaternion
  3761. ================================================================================*/
  3762. typedef struct
  3763. {
  3764. union
  3765. {
  3766. struct {
  3767. union {
  3768. gs_vec3 xyz;
  3769. gs_vec3 axis;
  3770. } axis;
  3771. float a;
  3772. } aa;
  3773. gs_vec4 v;
  3774. f32 xyzw[4];
  3775. struct
  3776. {
  3777. f32 x, y, z, w;
  3778. };
  3779. };
  3780. } gs_quat_t;
  3781. typedef gs_quat_t gs_quat;
  3782. gs_inline
  3783. gs_quat gs_quat_default()
  3784. {
  3785. gs_quat q;
  3786. q.x = 0.f;
  3787. q.y = 0.f;
  3788. q.z = 0.f;
  3789. q.w = 1.f;
  3790. return q;
  3791. }
  3792. gs_inline
  3793. gs_quat gs_quat_ctor(f32 _x, f32 _y, f32 _z, f32 _w)
  3794. {
  3795. gs_quat q;
  3796. q.x = _x;
  3797. q.y = _y;
  3798. q.z = _z;
  3799. q.w = _w;
  3800. return q;
  3801. }
  3802. gs_inline gs_quat
  3803. gs_quat_add(gs_quat q0, gs_quat q1)
  3804. {
  3805. return gs_quat_ctor(q0.x + q1.x, q0.y + q1.y, q0.z + q1.z, q0.w + q1.w);
  3806. }
  3807. gs_inline gs_quat
  3808. gs_quat_sub(gs_quat q0, gs_quat q1)
  3809. {
  3810. return gs_quat_ctor(q0.x - q1.x, q0.y - q1.y, q0.z - q1.z, q0.w - q1.w);
  3811. }
  3812. gs_inline gs_quat
  3813. gs_quat_mul(gs_quat q0, gs_quat q1)
  3814. {
  3815. return gs_quat_ctor(
  3816. q0.w * q1.x + q1.w * q0.x + q0.y * q1.z - q1.y * q0.z,
  3817. q0.w * q1.y + q1.w * q0.y + q0.z * q1.x - q1.z * q0.x,
  3818. q0.w * q1.z + q1.w * q0.z + q0.x * q1.y - q1.x * q0.y,
  3819. q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z
  3820. );
  3821. }
  3822. gs_inline
  3823. gs_quat gs_quat_mul_list(u32 count, ...)
  3824. {
  3825. va_list ap;
  3826. gs_quat q = gs_quat_default();
  3827. va_start(ap, count);
  3828. for (u32 i = 0; i < count; ++i)
  3829. {
  3830. q = gs_quat_mul(q, va_arg(ap, gs_quat));
  3831. }
  3832. va_end(ap);
  3833. return q;
  3834. }
  3835. gs_inline gs_quat
  3836. gs_quat_mul_quat(gs_quat q0, gs_quat q1)
  3837. {
  3838. return gs_quat_ctor(
  3839. q0.w * q1.x + q1.w * q0.x + q0.y * q1.z - q1.y * q0.z,
  3840. q0.w * q1.y + q1.w * q0.y + q0.z * q1.x - q1.z * q0.x,
  3841. q0.w * q1.z + q1.w * q0.z + q0.x * q1.y - q1.x * q0.y,
  3842. q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z
  3843. );
  3844. }
  3845. gs_inline
  3846. gs_quat gs_quat_scale(gs_quat q, f32 s)
  3847. {
  3848. return gs_quat_ctor(q.x * s, q.y * s, q.z * s, q.w * s);
  3849. }
  3850. gs_inline f32
  3851. gs_quat_dot(gs_quat q0, gs_quat q1)
  3852. {
  3853. return (f32)(q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w);
  3854. }
  3855. gs_inline
  3856. gs_quat gs_quat_conjugate(gs_quat q)
  3857. {
  3858. return (gs_quat_ctor(-q.x, -q.y, -q.z, q.w));
  3859. }
  3860. gs_inline f32
  3861. gs_quat_len(gs_quat q)
  3862. {
  3863. return (f32)sqrt(gs_quat_dot(q, q));
  3864. }
  3865. gs_inline gs_quat
  3866. gs_quat_norm(gs_quat q)
  3867. {
  3868. return gs_quat_scale(q, 1.0f / gs_quat_len(q));
  3869. }
  3870. gs_inline gs_quat
  3871. gs_quat_cross(gs_quat q0, gs_quat q1)
  3872. {
  3873. return gs_quat_ctor (
  3874. q0.x * q1.x + q0.x * q1.w + q0.y * q1.z - q0.z * q1.y,
  3875. q0.w * q1.y + q0.y * q1.w + q0.z * q1.x - q0.x * q1.z,
  3876. q0.w * q1.z + q0.z * q1.w + q0.x * q1.y - q0.y * q1.x,
  3877. q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z
  3878. );
  3879. }
  3880. // Inverse := Conjugate / Dot;
  3881. gs_inline
  3882. gs_quat gs_quat_inverse(gs_quat q)
  3883. {
  3884. return (gs_quat_scale(gs_quat_conjugate(q), 1.0f / gs_quat_dot(q, q)));
  3885. }
  3886. gs_inline gs_quat
  3887. gs_quat_angle_axis(f32 rad, gs_vec3 axis)
  3888. {
  3889. // Normalize axis
  3890. gs_vec3 a = gs_vec3_norm(axis);
  3891. // Get scalar
  3892. f32 half_angle = 0.5f * rad;
  3893. f32 s = (float)sin(half_angle);
  3894. return gs_quat_ctor(a.x * s, a.y * s, a.z * s, (float)cos(half_angle));
  3895. }
  3896. gs_inline gs_vec3
  3897. gs_quat_rotate(gs_quat q, gs_vec3 v)
  3898. {
  3899. // nVidia SDK implementation
  3900. gs_vec3 qvec = gs_vec3_ctor(q.x, q.y, q.z);
  3901. gs_vec3 uv = gs_vec3_cross(qvec, v);
  3902. gs_vec3 uuv = gs_vec3_cross(qvec, uv);
  3903. uv = gs_vec3_scale(uv, 2.f * q.w);
  3904. uuv = gs_vec3_scale(uuv, 2.f);
  3905. return (gs_vec3_add(v, gs_vec3_add(uv, uuv)));
  3906. }
  3907. gs_inline gs_vec3
  3908. gs_quat_forward(gs_quat q)
  3909. {
  3910. return gs_quat_rotate(q, gs_v3(0.f, 0.f, -1.f));
  3911. }
  3912. gs_inline gs_vec3
  3913. gs_quat_backward(gs_quat q)
  3914. {
  3915. return gs_quat_rotate(q, gs_v3(0.f, 0.f, 1.f));
  3916. }
  3917. gs_inline gs_vec3
  3918. gs_quat_left(gs_quat q)
  3919. {
  3920. return gs_quat_rotate(q, gs_v3(-1.f, 0.f, 0.f));
  3921. }
  3922. gs_inline gs_vec3
  3923. gs_quat_right(gs_quat q)
  3924. {
  3925. return gs_quat_rotate(q, gs_v3(1.f, 0.f, 0.f));
  3926. }
  3927. gs_inline gs_vec3
  3928. gs_quat_up(gs_quat q)
  3929. {
  3930. return gs_quat_rotate(q, gs_v3(0.f, 1.f, 0.f));
  3931. }
  3932. gs_inline gs_vec3
  3933. gs_quat_down(gs_quat q)
  3934. {
  3935. return gs_quat_rotate(q, gs_v3(0.f, -1.f, 0.f));
  3936. }
  3937. gs_inline gs_quat
  3938. gs_quat_from_to_rotation(gs_vec3 src, gs_vec3 dst)
  3939. {
  3940. src = gs_vec3_norm(src);
  3941. dst = gs_vec3_norm(dst);
  3942. const float d = gs_vec3_dot(src, dst);
  3943. if (d >= 1.f)
  3944. {
  3945. return gs_quat_default();
  3946. }
  3947. else if (d <= -1.f)
  3948. {
  3949. // Orthonormalize, find axis of rotation
  3950. gs_vec3 axis = gs_vec3_cross(src, GS_XAXIS);
  3951. if (gs_vec3_len2(axis) < 1e-6)
  3952. {
  3953. axis = gs_vec3_cross(src, GS_YAXIS);
  3954. }
  3955. return gs_quat_angle_axis((float)GS_PI, gs_vec3_norm(axis));
  3956. }
  3957. else
  3958. {
  3959. const float s = sqrtf(gs_vec3_len2(src) * gs_vec3_len2(dst)) +
  3960. gs_vec3_dot(src, dst);
  3961. gs_vec3 axis = gs_vec3_cross(src, dst);
  3962. return gs_quat_norm(gs_quat_ctor(axis.x, axis.y, axis.z, s));
  3963. }
  3964. }
  3965. gs_inline
  3966. gs_quat gs_quat_look_rotation(gs_vec3 position, gs_vec3 target, gs_vec3 up)
  3967. {
  3968. const gs_vec3 forward = gs_vec3_norm(gs_vec3_sub(position, target));
  3969. const gs_quat q0 = gs_quat_from_to_rotation(GS_ZAXIS, forward);
  3970. if (gs_vec3_len2(gs_vec3_cross(forward, up)) < 1e-6)
  3971. {
  3972. return q0;
  3973. }
  3974. const gs_vec3 new_up = gs_quat_rotate(q0, up);
  3975. const gs_quat q1 = gs_quat_from_to_rotation(new_up, up);
  3976. return gs_quat_mul(q1, q0);
  3977. }
  3978. gs_inline
  3979. gs_quat gs_quat_slerp(gs_quat a, gs_quat b, f32 t)
  3980. {
  3981. f32 c = gs_quat_dot(a, b);
  3982. gs_quat end = b;
  3983. if (c < 0.0f)
  3984. {
  3985. // Reverse all signs
  3986. c *= -1.0f;
  3987. end.x *= -1.0f;
  3988. end.y *= -1.0f;
  3989. end.z *= -1.0f;
  3990. end.w *= -1.0f;
  3991. }
  3992. // Calculate coefficients
  3993. f32 sclp, sclq;
  3994. if ((1.0f - c) > 0.0001f)
  3995. {
  3996. f32 omega = (float)acosf(c);
  3997. f32 s = (float)sinf(omega);
  3998. sclp = (float)sinf((1.0f - t) * omega) / s;
  3999. sclq = (float)sinf(t * omega) / s;
  4000. }
  4001. else
  4002. {
  4003. sclp = 1.0f - t;
  4004. sclq = t;
  4005. }
  4006. gs_quat q;
  4007. q.x = sclp * a.x + sclq * end.x;
  4008. q.y = sclp * a.y + sclq * end.y;
  4009. q.z = sclp * a.z + sclq * end.z;
  4010. q.w = sclp * a.w + sclq * end.w;
  4011. return q;
  4012. }
  4013. #define quat_axis_angle(__AXS, __ANG)\
  4014. gs_quat_angle_axis(__ANG, __AXS)
  4015. /*
  4016. * @brief Convert given quaternion param into equivalent 4x4 rotation matrix
  4017. * @note: From http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
  4018. */
  4019. gs_inline gs_mat4 gs_quat_to_mat4(gs_quat _q)
  4020. {
  4021. gs_mat4 mat = gs_mat4_identity();
  4022. gs_quat q = gs_quat_norm(_q);
  4023. f32 xx = q.x * q.x;
  4024. f32 yy = q.y * q.y;
  4025. f32 zz = q.z * q.z;
  4026. f32 xy = q.x * q.y;
  4027. f32 xz = q.x * q.z;
  4028. f32 yz = q.y * q.z;
  4029. f32 wx = q.w * q.x;
  4030. f32 wy = q.w * q.y;
  4031. f32 wz = q.w * q.z;
  4032. mat.elements[0 * 4 + 0] = 1.0f - 2.0f * (yy + zz);
  4033. mat.elements[1 * 4 + 0] = 2.0f * (xy - wz);
  4034. mat.elements[2 * 4 + 0] = 2.0f * (xz + wy);
  4035. mat.elements[0 * 4 + 1] = 2.0f * (xy + wz);
  4036. mat.elements[1 * 4 + 1] = 1.0f - 2.0f * (xx + zz);
  4037. mat.elements[2 * 4 + 1] = 2.0f * (yz - wx);
  4038. mat.elements[0 * 4 + 2] = 2.0f * (xz - wy);
  4039. mat.elements[1 * 4 + 2] = 2.0f * (yz + wx);
  4040. mat.elements[2 * 4 + 2] = 1.0f - 2.0f * (xx + yy);
  4041. return mat;
  4042. }
  4043. gs_inline
  4044. gs_quat gs_quat_from_euler(f32 yaw_deg, f32 pitch_deg, f32 roll_deg)
  4045. {
  4046. f32 yaw = gs_deg2rad(yaw_deg);
  4047. f32 pitch = gs_deg2rad(pitch_deg);
  4048. f32 roll = gs_deg2rad(roll_deg);
  4049. gs_quat q;
  4050. f32 cy = (float)cos(yaw * 0.5f);
  4051. f32 sy = (float)sin(yaw * 0.5f);
  4052. f32 cr = (float)cos(roll * 0.5f);
  4053. f32 sr = (float)sin(roll * 0.5f);
  4054. f32 cp = (float)cos(pitch * 0.5f);
  4055. f32 sp = (float)sin(pitch * 0.5f);
  4056. q.x = cy * sr * cp - sy * cr * sp;
  4057. q.y = cy * cr * sp + sy * sr * cp;
  4058. q.z = sy * cr * cp - cy * sr * sp;
  4059. q.w = cy * cr * cp + sy * sr * sp;
  4060. return q;
  4061. }
  4062. gs_inline
  4063. float gs_quat_pitch(gs_quat* q)
  4064. {
  4065. return atan2(2.0f * q->y * q->z + q->w * q->x, q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z);
  4066. }
  4067. gs_inline
  4068. float gs_quat_yaw(gs_quat* q)
  4069. {
  4070. return asin(-2.0f * (q->x * q->z - q->w * q->y));
  4071. }
  4072. gs_inline
  4073. float gs_quat_roll(gs_quat* q)
  4074. {
  4075. return atan2(2.0f * q->x * q->y + q->z * q->w, q->x * q->x + q->w * q->w - q->y * q->y - q->z * q->z);
  4076. }
  4077. gs_inline
  4078. gs_vec3 gs_quat_to_euler(gs_quat* q)
  4079. {
  4080. return gs_v3(gs_quat_yaw(q), gs_quat_pitch(q), gs_quat_roll(q));
  4081. }
  4082. /*================================================================================
  4083. // Transform (Non-Uniform Scalar VQS)
  4084. ================================================================================*/
  4085. /*
  4086. - This follows a traditional 'VQS' structure for complex object transformations,
  4087. however it differs from the standard in that it allows for non-uniform
  4088. scaling in the form of a vec3.
  4089. */
  4090. // Source: https://www.eurosis.org/cms/files/conf/gameon-asia/gameon-asia2007/R-SESSION/G1.pdf
  4091. typedef struct
  4092. {
  4093. union {
  4094. gs_vec3 position;
  4095. gs_vec3 translation;
  4096. };
  4097. gs_quat rotation;
  4098. gs_vec3 scale;
  4099. } gs_vqs_t;
  4100. typedef gs_vqs_t gs_vqs;
  4101. gs_inline gs_vqs
  4102. gs_vqs_ctor(gs_vec3 tns, gs_quat rot, gs_vec3 scl)
  4103. {
  4104. gs_vqs t;
  4105. t.position = tns;
  4106. t.rotation = rot;
  4107. t.scale = scl;
  4108. return t;
  4109. }
  4110. gs_inline gs_vqs
  4111. gs_vqs_default()
  4112. {
  4113. gs_vqs t = gs_vqs_ctor
  4114. (
  4115. gs_vec3_ctor(0.0f, 0.0f, 0.0f),
  4116. gs_quat_ctor(0.0f, 0.0f, 0.0f, 1.0f),
  4117. gs_vec3_ctor(1.0f, 1.0f, 1.0f)
  4118. );
  4119. return t;
  4120. }
  4121. // AbsScale = ParentScale * LocalScale
  4122. // AbsRot = LocalRot * ParentRot
  4123. // AbsTrans = ParentPos + [ParentRot * (ParentScale * LocalPos)]
  4124. gs_inline gs_vqs
  4125. gs_vqs_absolute_transform(const gs_vqs* local, const gs_vqs* parent)
  4126. {
  4127. if (!local || !parent) {
  4128. return gs_vqs_default();
  4129. }
  4130. // Normalized rotations
  4131. gs_quat p_rot_norm = gs_quat_norm(parent->rotation);
  4132. gs_quat l_rot_norm = gs_quat_norm(local->rotation);
  4133. // Scale
  4134. gs_vec3 scl = gs_vec3_mul(local->scale, parent->scale);
  4135. // Rotation
  4136. gs_quat rot = gs_quat_norm(gs_quat_mul(p_rot_norm, l_rot_norm));
  4137. // position
  4138. gs_vec3 tns = gs_vec3_add(parent->position, gs_quat_rotate(p_rot_norm, gs_vec3_mul(parent->scale, local->position)));
  4139. return gs_vqs_ctor(tns, rot, scl);
  4140. }
  4141. // RelScale = AbsScale / ParentScale
  4142. // RelRot = Inverse(ParentRot) * AbsRot
  4143. // RelTrans = [Inverse(ParentRot) * (AbsPos - ParentPosition)] / ParentScale;
  4144. gs_inline gs_vqs
  4145. gs_vqs_relative_transform(const gs_vqs* absolute, const gs_vqs* parent)
  4146. {
  4147. if (!absolute || !parent) {
  4148. return gs_vqs_default();
  4149. }
  4150. // Get inverse rotation normalized
  4151. gs_quat p_rot_inv = gs_quat_norm(gs_quat_inverse(parent->rotation));
  4152. // Normalized abs rotation
  4153. gs_quat a_rot_norm = gs_quat_norm(absolute->rotation);
  4154. // Scale
  4155. gs_vec3 scl = gs_vec3_div(absolute->scale, parent->scale);
  4156. // Rotation
  4157. gs_quat rot = gs_quat_norm(gs_quat_mul(p_rot_inv, a_rot_norm));
  4158. // position
  4159. gs_vec3 tns = gs_vec3_div(gs_quat_rotate(p_rot_inv, gs_vec3_sub(absolute->position, parent->position)), parent->scale);
  4160. return gs_vqs_ctor(tns, rot, scl);
  4161. }
  4162. gs_inline gs_mat4
  4163. gs_vqs_to_mat4(const gs_vqs* transform)
  4164. {
  4165. gs_mat4 mat = gs_mat4_identity();
  4166. gs_mat4 trans = gs_mat4_translatev(transform->position);
  4167. gs_mat4 rot = gs_quat_to_mat4(transform->rotation);
  4168. gs_mat4 scl = gs_mat4_scalev(transform->scale);
  4169. mat = gs_mat4_mul(mat, trans);
  4170. mat = gs_mat4_mul(mat, rot);
  4171. mat = gs_mat4_mul(mat, scl);
  4172. return mat;
  4173. }
  4174. gs_inline gs_vqs
  4175. gs_vqs_from_mat4(const gs_mat4* m)
  4176. {
  4177. gs_vec3 translation = gs_v3s(0.f), rotation = gs_v3s(0.f), scale = gs_v3s(1.f);
  4178. gs_mat4_decompose(m, (float*)&translation, (float*)&rotation, (float*)&scale);
  4179. return gs_vqs_ctor(
  4180. translation,
  4181. gs_quat_from_euler(rotation.x, rotation.y, rotation.z),
  4182. scale
  4183. );
  4184. }
  4185. gs_inline gs_vec3
  4186. gs_vqs_forward(const gs_vqs* transform)
  4187. {
  4188. return (gs_quat_rotate(transform->rotation, gs_v3(0.0f, 0.0f, -1.0f)));
  4189. }
  4190. gs_inline gs_vec3
  4191. gs_vqs_backward(const gs_vqs* transform)
  4192. {
  4193. return (gs_quat_rotate(transform->rotation, gs_v3(0.0f, 0.0f, 1.0f)));
  4194. }
  4195. gs_inline gs_vec3
  4196. gs_vqs_left(const gs_vqs* transform)
  4197. {
  4198. return (gs_quat_rotate(transform->rotation, gs_v3(-1.0f, 0.0f, 0.0f)));
  4199. }
  4200. gs_inline gs_vec3
  4201. gs_vqs_right(const gs_vqs* transform)
  4202. {
  4203. return (gs_quat_rotate(transform->rotation, gs_v3(1.0f, 0.0f, 0.0f)));
  4204. }
  4205. gs_inline gs_vec3
  4206. gs_vqs_up(const gs_vqs* transform)
  4207. {
  4208. return (gs_quat_rotate(transform->rotation, gs_v3(0.0f, 1.0f, 0.0f)));
  4209. }
  4210. gs_inline gs_vec3
  4211. gs_vqs_down(const gs_vqs* transform)
  4212. {
  4213. return (gs_quat_rotate(transform->rotation, gs_v3(0.0f, -1.0f, 0.0f)));
  4214. }
  4215. /*================================================================================
  4216. // Random
  4217. ================================================================================*/
  4218. // From: https://github.com/ESultanik/mtwister
  4219. #define GS_STATE_VECTOR_LENGTH 624
  4220. #define GS_STATE_VECTOR_M 397 /* changes to STATE_VECTOR_LENGTH also require changes to this */
  4221. typedef struct gs_mt_rand_t
  4222. {
  4223. uint64_t mt[GS_STATE_VECTOR_LENGTH];
  4224. int32_t index;
  4225. } gs_mt_rand_t;
  4226. GS_API_DECL gs_mt_rand_t gs_rand_seed(uint64_t seed);
  4227. GS_API_DECL int64_t gs_rand_gen_long(gs_mt_rand_t* rand);
  4228. GS_API_DECL double gs_rand_gen(gs_mt_rand_t* rand);
  4229. GS_API_DECL double gs_rand_gen_range(gs_mt_rand_t* rand, double min, double max);
  4230. GS_API_DECL int64_t gs_rand_gen_range_long(gs_mt_rand_t* rand, int32_t min, int32_t max);
  4231. GS_API_DECL gs_color_t gs_rand_gen_color(gs_mt_rand_t* rand);
  4232. #ifndef GS_NO_SHORT_NAME
  4233. typedef gs_mt_rand_t gs_rand;
  4234. #endif
  4235. /*================================================================================
  4236. // Coroutine (Light wrapper around Minicoro)
  4237. ================================================================================*/
  4238. #define MCO_MALLOC gs_malloc
  4239. #define MCO_FREE gs_free
  4240. #include "external/minicoro/minicoro.h"
  4241. typedef mco_coro gs_coro_t;
  4242. typedef mco_desc gs_coro_desc_t;
  4243. typedef mco_result gs_coro_result;
  4244. // Result
  4245. #define GS_CORO_SUCCESS MCO_SUCCESS
  4246. #define GS_CORO_GENERIC_ERROR MCO_GENERIC_ERROR
  4247. #define GS_CORO_INVALID_POINTER MCO_INVALID_POINTER
  4248. #define GS_CORO_INVALID_COROUTINE MCO_INVALID_COROUTINE
  4249. #define GS_CORO_NOT_SUSPENDED MCO_NOT_SUSPENDED
  4250. #define GS_CORO_NOT_RUNNING MCO_NOT_RUNNING
  4251. #define GS_CORO_MAKE_CONTEXT_ERROR MCO_MAKE_CONTEXT_ERROR
  4252. #define GS_CORO_SWITCH_CONTEXT_ERROR MCO_SWITCH_CONTEXT_ERROR
  4253. #define GS_CORO_NOT_ENOUGH_SPACE MCO_NOT_ENOUGH_SPACE
  4254. #define GS_CORO_OUT_OF_MEMORY MCO_OUT_OF_MEMORY
  4255. #define GS_CORO_INVALID_ARGUMENTS MCO_INVALID_ARGUMENTS
  4256. #define GS_CORO_INVALID_OPERATION MCO_INVALID_OPERATION
  4257. #define GS_CORO_STACK_OVERFLOW MCO_STACK_OVERFLOW
  4258. // State
  4259. #define GS_CORO_DEAD MCO_DEAD // The coroutine has finished normally or was uninitialized before finishing.
  4260. #define GS_CORO_NORMAL MCO_NORMAL // The coroutine is active but not running (that is, it has resumed another coroutine).
  4261. #define GS_CORO_RUNNING MCO_RUNNING // The coroutine is active and running
  4262. #define GS_CORO_SUSPENDED MCO_SUSPENDED // The coroutine is suspended (in a call to yield, or it has not started running yet).
  4263. // Functions
  4264. #define gs_coro_desc_init(DESC, V) mco_desc_init((DESC), (V))
  4265. #define gs_coro_init(CO, DESC) mco_init((CO), (DESC))
  4266. #define gs_coro_uninit(CO) mco_uninit((CO))
  4267. #define gs_coro_create(CO, DESC) mco_create((CO), (DESC))
  4268. #define gs_coro_destroy(CO) mco_destroy((CO))
  4269. #define gs_coro_yield(CO) mco_yield((CO))
  4270. #define gs_coro_resume(CO) mco_resume((CO))
  4271. #define gs_coro_result_description(RES) mco_result_description((RES))
  4272. #define gs_coro_status(CO) mco_status((CO))
  4273. /*================================================================================
  4274. // Scheduler
  4275. ================================================================================*/
  4276. #include "external/sched/sched.h"
  4277. #ifdef GS_PLATFORM_WINDOWS
  4278. #define gs_thread_local __declspec(thread)
  4279. #else
  4280. #define gs_thread_local __thread
  4281. #endif
  4282. #define GS_SCHED_DEFAULT SCHED_DEFAULT
  4283. #define gs_sched_fp_t sched_run
  4284. #define gs_sched_task_t struct sched_task
  4285. #define gs_sched_task_partition_t struct sched_task_partition
  4286. #define gs_scheduler_t struct scheduler
  4287. #define gs_sched_profiling_t struct sched_profiling
  4288. #define gs_scheduler_init scheduler_init
  4289. #define gs_scheduler_start scheduler_start
  4290. #define gs_scheduler_add scheduler_add
  4291. #define gs_scheduler_join scheduler_join
  4292. #define gs_scheduler_wait scheduler_wait
  4293. #define gs_scheduler_stop scheduler_stop
  4294. #define gs_sched_task_done sched_task_done
  4295. #define gs_atomic_int_t int32_t
  4296. GS_API_DECL uint32_t
  4297. gs_atomic_cmp_swp(volatile uint32_t *dst, uint32_t swap, uint32_t cmp);
  4298. GS_API_DECL int32_t
  4299. gs_atomic_add(volatile int32_t *dst, int32_t value);
  4300. /*================================================================================
  4301. // Noise
  4302. ================================================================================*/
  4303. // Perlin noise
  4304. GS_API_DECL float gs_perlin1(float x);
  4305. GS_API_DECL float gs_perlin2(float x, float y);
  4306. GS_API_DECL float gs_perlin3(float x, float y, float z);
  4307. GS_API_DECL float gs_perlin4(float x, float y, float z, float w);
  4308. // Perlin periodic noise
  4309. GS_API_DECL float gs_perlin1p(float x, int32_t px);
  4310. GS_API_DECL float gs_perlin2p(float x, float y, int32_t px, int32_t py);
  4311. GS_API_DECL float gs_perlin3p(float x, float y, float z, int32_t px, int32_t py, int32_t pz);
  4312. GS_API_DECL float gs_perlin4p(float x, float y, float z, float w, int32_t px, int32_t py, int32_t pz, int32_t pw);
  4313. /*================================================================================
  4314. // Camera
  4315. ================================================================================*/
  4316. typedef enum gs_projection_type
  4317. {
  4318. GS_PROJECTION_TYPE_ORTHOGRAPHIC,
  4319. GS_PROJECTION_TYPE_PERSPECTIVE
  4320. } gs_projection_type;
  4321. typedef struct gs_camera_t
  4322. {
  4323. gs_vqs transform;
  4324. float fov;
  4325. float aspect_ratio;
  4326. float near_plane;
  4327. float far_plane;
  4328. float ortho_scale;
  4329. gs_projection_type proj_type;
  4330. } gs_camera_t;
  4331. GS_API_DECL gs_camera_t gs_camera_default();
  4332. GS_API_DECL gs_camera_t gs_camera_perspective();
  4333. GS_API_DECL gs_mat4 gs_camera_get_view(const gs_camera_t* cam);
  4334. GS_API_DECL gs_mat4 gs_camera_get_proj(const gs_camera_t* cam, int32_t view_width, int32_t view_height);
  4335. GS_API_DECL gs_mat4 gs_camera_get_view_projection(const gs_camera_t* cam, int32_t view_width, int32_t view_height);
  4336. GS_API_DECL gs_vec3 gs_camera_forward(const gs_camera_t* cam);
  4337. GS_API_DECL gs_vec3 gs_camera_backward(const gs_camera_t* cam);
  4338. GS_API_DECL gs_vec3 gs_camera_up(const gs_camera_t* cam);
  4339. GS_API_DECL gs_vec3 gs_camera_down(const gs_camera_t* cam);
  4340. GS_API_DECL gs_vec3 gs_camera_right(const gs_camera_t* cam);
  4341. GS_API_DECL gs_vec3 gs_camera_left(const gs_camera_t* cam);
  4342. GS_API_DECL gs_vec3 gs_camera_screen_to_world(const gs_camera_t* cam, gs_vec3 coords, int32_t view_x, int32_t view_y, int32_t view_width, int32_t view_height);
  4343. GS_API_DECL gs_vec3 gs_camera_world_to_screen(const gs_camera_t* cam, gs_vec3 coords, int32_t view_width, int32_t view_height);
  4344. GS_API_DECL void gs_camera_offset_orientation(gs_camera_t* cam, float yaw, float picth);
  4345. /*================================================================================
  4346. // Utils
  4347. ================================================================================*/
  4348. // AABBs
  4349. /*
  4350. min is top left of rect,
  4351. max is bottom right
  4352. */
  4353. /*
  4354. typedef struct gs_aabb_t
  4355. {
  4356. gs_vec2 min;
  4357. gs_vec2 max;
  4358. } gs_aabb_t;
  4359. // Collision Resolution: Minimum Translation Vector
  4360. gs_force_inline
  4361. gs_vec2 gs_aabb_aabb_mtv(gs_aabb_t* a0, gs_aabb_t* a1)
  4362. {
  4363. gs_vec2 diff = gs_v2(a0->min.x - a1->min.x, a0->min.y - a1->min.y);
  4364. f32 l, r, b, t;
  4365. gs_vec2 mtv = gs_v2(0.f, 0.f);
  4366. l = a1->min.x - a0->max.x;
  4367. r = a1->max.x - a0->min.x;
  4368. b = a1->min.y - a0->max.y;
  4369. t = a1->max.y - a0->min.y;
  4370. mtv.x = fabsf(l) > r ? r : l;
  4371. mtv.y = fabsf(b) > t ? t : b;
  4372. if ( fabsf(mtv.x) <= fabsf(mtv.y)) {
  4373. mtv.y = 0.f;
  4374. } else {
  4375. mtv.x = 0.f;
  4376. }
  4377. return mtv;
  4378. }
  4379. // 2D AABB collision detection (rect. vs. rect.)
  4380. gs_force_inline
  4381. b32 gs_aabb_vs_aabb(gs_aabb_t* a, gs_aabb_t* b)
  4382. {
  4383. if (a->max.x > b->min.x &&
  4384. a->max.y > b->min.y &&
  4385. a->min.x < b->max.x &&
  4386. a->min.y < b->max.y)
  4387. {
  4388. return true;
  4389. }
  4390. return false;
  4391. }
  4392. gs_force_inline
  4393. gs_vec4 gs_aabb_window_coords(gs_aabb_t* aabb, gs_camera_t* camera, gs_vec2 window_size)
  4394. {
  4395. // AABB of the player
  4396. gs_vec4 bounds = gs_default_val();
  4397. gs_vec4 tl = gs_v4(aabb->min.x, aabb->min.y, 0.f, 1.f);
  4398. gs_vec4 br = gs_v4(aabb->max.x, aabb->max.y, 0.f, 1.f);
  4399. gs_mat4 view_mtx = gs_camera_get_view(camera);
  4400. gs_mat4 proj_mtx = gs_camera_get_proj(camera, (int32_t)window_size.x, (int32_t)window_size.y);
  4401. gs_mat4 vp = gs_mat4_mul(proj_mtx, view_mtx);
  4402. // Transform verts
  4403. tl = gs_mat4_mul_vec4(vp, tl);
  4404. br = gs_mat4_mul_vec4(vp, br);
  4405. // Perspective divide
  4406. tl = gs_vec4_scale(tl, 1.f / tl.w);
  4407. br = gs_vec4_scale(br, 1.f / br.w);
  4408. // NDC [0.f, 1.f] and NDC
  4409. tl.x = (tl.x * 0.5f + 0.5f);
  4410. tl.y = (tl.y * 0.5f + 0.5f);
  4411. br.x = (br.x * 0.5f + 0.5f);
  4412. br.y = (br.y * 0.5f + 0.5f);
  4413. // Window Space
  4414. tl.x = tl.x * window_size.x;
  4415. tl.y = gs_map_range(1.f, 0.f, 0.f, 1.f, tl.y) * window_size.y;
  4416. br.x = br.x * window_size.x;
  4417. br.y = gs_map_range(1.f, 0.f, 0.f, 1.f, br.y) * window_size.y;
  4418. bounds = gs_v4(tl.x, tl.y, br.x, br.y);
  4419. return bounds;
  4420. }
  4421. */
  4422. /** @} */ // end of gs_math
  4423. /*========================
  4424. // GS_LEXER
  4425. ========================*/
  4426. //==== [ Token ] ============================================================//
  4427. typedef enum gs_token_type
  4428. {
  4429. GS_TOKEN_UNKNOWN = 0x00,
  4430. GS_TOKEN_LPAREN,
  4431. GS_TOKEN_RPAREN,
  4432. GS_TOKEN_LTHAN,
  4433. GS_TOKEN_GTHAN,
  4434. GS_TOKEN_SEMICOLON,
  4435. GS_TOKEN_COLON,
  4436. GS_TOKEN_COMMA,
  4437. GS_TOKEN_EQUAL,
  4438. GS_TOKEN_EEQUAL,
  4439. GS_TOKEN_NEQUAL,
  4440. GS_TOKEN_LEQUAL,
  4441. GS_TOKEN_GEQUAL,
  4442. GS_TOKEN_NOT,
  4443. GS_TOKEN_HASH,
  4444. GS_TOKEN_PIPE,
  4445. GS_TOKEN_AMPERSAND,
  4446. GS_TOKEN_AND,
  4447. GS_TOKEN_OR,
  4448. GS_TOKEN_XOR,
  4449. GS_TOKEN_NEGATE,
  4450. GS_TOKEN_LBRACE,
  4451. GS_TOKEN_RBRACE,
  4452. GS_TOKEN_LBRACKET,
  4453. GS_TOKEN_RBRACKET,
  4454. GS_TOKEN_MINUS,
  4455. GS_TOKEN_PLUS,
  4456. GS_TOKEN_ASTERISK,
  4457. GS_TOKEN_BSLASH,
  4458. GS_TOKEN_FSLASH,
  4459. GS_TOKEN_QMARK,
  4460. GS_TOKEN_SPACE,
  4461. GS_TOKEN_PERCENT,
  4462. GS_TOKEN_DOLLAR,
  4463. GS_TOKEN_NEWLINE,
  4464. GS_TOKEN_TAB,
  4465. GS_TOKEN_UNDERSCORE,
  4466. GS_TOKEN_SINGLE_LINE_COMMENT,
  4467. GS_TOKEN_MULTI_LINE_COMMENT,
  4468. GS_TOKEN_IDENTIFIER,
  4469. GS_TOKEN_SINGLE_QUOTE,
  4470. GS_TOKEN_DOUBLE_QUOTE,
  4471. GS_TOKEN_STRING,
  4472. GS_TOKEN_PERIOD,
  4473. GS_TOKEN_NUMBER,
  4474. GS_TOKEN_KEYWORD,
  4475. GS_TOKEN_COUNT // Max tokens accounted for
  4476. } gs_token_type;
  4477. typedef struct gs_token_t
  4478. {
  4479. const char* text;
  4480. gs_token_type type;
  4481. uint32_t len;
  4482. uint32_t line;
  4483. } gs_token_t;
  4484. GS_API_DECL gs_token_t gs_token_invalid_token();
  4485. GS_API_DECL bool gs_token_compare_type(const gs_token_t* t, gs_token_type type);
  4486. GS_API_DECL bool gs_token_compare_text(const gs_token_t* t, const char* match);
  4487. GS_API_DECL void gs_token_print_text(const gs_token_t* t);
  4488. GS_API_DECL void gs_token_debug_print(const gs_token_t* t);
  4489. GS_API_DECL const char* gs_token_type_to_str(gs_token_type type);
  4490. GS_API_DECL bool gs_char_is_end_of_line(char c);
  4491. GS_API_DECL bool gs_char_is_white_space(char c);
  4492. GS_API_DECL bool gs_char_is_alpha(char c);
  4493. GS_API_DECL bool gs_char_is_numeric(char c);
  4494. //==== [ Lexer ] ============================================================//
  4495. typedef struct gs_lexer_t
  4496. {
  4497. const char* at;
  4498. const char* contents;
  4499. gs_token_t current_token;
  4500. bool (* can_lex)(struct gs_lexer_t* lex);
  4501. void (* eat_white_space)(struct gs_lexer_t* lex);
  4502. gs_token_t (* next_token)(struct gs_lexer_t*);
  4503. bool32 skip_white_space;
  4504. size_t size; // Optional
  4505. size_t contents_size; // Optional
  4506. uint32_t line; // Line number
  4507. } gs_lexer_t;
  4508. GS_API_DECL void gs_lexer_set_contents(gs_lexer_t* lex, const char* contents);
  4509. GS_API_DECL gs_token_t gs_lexer_next_token(gs_lexer_t* lex);
  4510. GS_API_DECL bool gs_lexer_can_lex(gs_lexer_t* lex);
  4511. GS_API_DECL gs_token_t gs_lexer_current_token(const gs_lexer_t* lex);
  4512. GS_API_DECL bool gs_lexer_require_token_text(gs_lexer_t* lex, const char* match);
  4513. GS_API_DECL bool gs_lexer_require_token_type(gs_lexer_t* lex, gs_token_type type);
  4514. GS_API_DECL bool gs_lexer_current_token_compare_type(const gs_lexer_t* lex, gs_token_type type);
  4515. GS_API_DECL gs_token_t gs_lexer_peek(gs_lexer_t* lex);
  4516. GS_API_DECL bool gs_lexer_find_next_token_type(gs_lexer_t* lex, gs_token_type type);
  4517. GS_API_DECL gs_token_t gs_lexer_advance_before_next_token_type(gs_lexer_t* lex, gs_token_type type);
  4518. // C specific functions for lexing
  4519. GS_API_DECL gs_lexer_t gs_lexer_c_ctor(const char* contents);
  4520. GS_API_DECL bool gs_lexer_c_can_lex(gs_lexer_t* lex);
  4521. GS_API_DECL void gs_lexer_c_eat_white_space(gs_lexer_t* lex);
  4522. GS_API_DECL gs_token_t gs_lexer_c_next_token(gs_lexer_t* lex);
  4523. /*========================
  4524. // GS_PLATFORM
  4525. ========================*/
  4526. /** @defgroup gs_platform Platform
  4527. * Gunslinger Platform
  4528. * @{
  4529. */
  4530. /*============================================================
  4531. // Platform Time
  4532. ============================================================*/
  4533. typedef struct gs_platform_time_t
  4534. {
  4535. float max_fps;
  4536. float elapsed;
  4537. float previous;
  4538. float update;
  4539. float render;
  4540. float delta;
  4541. float frame;
  4542. } gs_platform_time_t;
  4543. /*============================================================
  4544. // Platform UUID
  4545. ============================================================*/
  4546. #define GS_UUID_STR_SIZE_CONSTANT 32
  4547. // 33 characters, all set to 0
  4548. #define gs_uuid_temp_str_buffer()\
  4549. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  4550. typedef struct gs_uuid_t
  4551. {
  4552. uint8_t bytes[16];
  4553. } gs_uuid_t;
  4554. /*============================================================
  4555. // Platform Window
  4556. ============================================================*/
  4557. #define GS_WINDOW_FLAGS_NO_RESIZE 0x01
  4558. #define GS_WINDOW_FLAGS_FULLSCREEN 0x02
  4559. #define GS_WINDOW_FLAGS_INVISIBLE 0x03
  4560. // Should have an internal resource cache of window handles (controlled by the platform api)
  4561. typedef struct gs_platform_window_desc_t
  4562. {
  4563. const char* title;
  4564. uint32_t width;
  4565. uint32_t height;
  4566. uint32_t flags;
  4567. uint32_t num_samples; // Multisamples (if 0, then disabled)
  4568. uint32_t monitor_index;
  4569. bool32 vsync;
  4570. float frame_rate;
  4571. } gs_platform_window_desc_t;
  4572. typedef struct gs_platform_window_s
  4573. {
  4574. void* hndl;
  4575. gs_vec2 framebuffer_size;
  4576. gs_vec2 window_size;
  4577. gs_vec2 window_position;
  4578. } gs_platform_window_t;
  4579. typedef enum gs_platform_cursor
  4580. {
  4581. GS_PLATFORM_CURSOR_ARROW,
  4582. GS_PLATFORM_CURSOR_IBEAM,
  4583. GS_PLATFORM_CURSOR_SIZE_NW_SE,
  4584. GS_PLATFORM_CURSOR_SIZE_NE_SW,
  4585. GS_PLATFORM_CURSOR_SIZE_NS,
  4586. GS_PLATFORM_CURSOR_SIZE_WE,
  4587. GS_PLATFORM_CURSOR_SIZE_ALL,
  4588. GS_PLATFORM_CURSOR_HAND,
  4589. GS_PLATFORM_CURSOR_NO,
  4590. GS_PLATFORM_CURSOR_COUNT
  4591. } gs_platform_cursor;
  4592. typedef enum gs_platform_keycode
  4593. {
  4594. GS_KEYCODE_INVALID,
  4595. GS_KEYCODE_SPACE,
  4596. GS_KEYCODE_APOSTROPHE, /* ' */
  4597. GS_KEYCODE_COMMA, /* , */
  4598. GS_KEYCODE_MINUS, /* - */
  4599. GS_KEYCODE_PERIOD, /* . */
  4600. GS_KEYCODE_SLASH, /* / */
  4601. GS_KEYCODE_0,
  4602. GS_KEYCODE_1,
  4603. GS_KEYCODE_2,
  4604. GS_KEYCODE_3,
  4605. GS_KEYCODE_4,
  4606. GS_KEYCODE_5,
  4607. GS_KEYCODE_6,
  4608. GS_KEYCODE_7,
  4609. GS_KEYCODE_8,
  4610. GS_KEYCODE_9,
  4611. GS_KEYCODE_SEMICOLON, /* ; */
  4612. GS_KEYCODE_EQUAL, /* = */
  4613. GS_KEYCODE_A,
  4614. GS_KEYCODE_B,
  4615. GS_KEYCODE_C,
  4616. GS_KEYCODE_D,
  4617. GS_KEYCODE_E,
  4618. GS_KEYCODE_F,
  4619. GS_KEYCODE_G,
  4620. GS_KEYCODE_H,
  4621. GS_KEYCODE_I,
  4622. GS_KEYCODE_J,
  4623. GS_KEYCODE_K,
  4624. GS_KEYCODE_L,
  4625. GS_KEYCODE_M,
  4626. GS_KEYCODE_N,
  4627. GS_KEYCODE_O,
  4628. GS_KEYCODE_P,
  4629. GS_KEYCODE_Q,
  4630. GS_KEYCODE_R,
  4631. GS_KEYCODE_S,
  4632. GS_KEYCODE_T,
  4633. GS_KEYCODE_U,
  4634. GS_KEYCODE_V,
  4635. GS_KEYCODE_W,
  4636. GS_KEYCODE_X,
  4637. GS_KEYCODE_Y,
  4638. GS_KEYCODE_Z,
  4639. GS_KEYCODE_LEFT_BRACKET, /* [ */
  4640. GS_KEYCODE_BACKSLASH, /* \ */
  4641. GS_KEYCODE_RIGHT_BRACKET, /* ] */
  4642. GS_KEYCODE_GRAVE_ACCENT, /* ` */
  4643. GS_KEYCODE_WORLD_1, /* non-US #1 */
  4644. GS_KEYCODE_WORLD_2, /* non-US #2 */
  4645. GS_KEYCODE_ESC,
  4646. GS_KEYCODE_ENTER,
  4647. GS_KEYCODE_TAB,
  4648. GS_KEYCODE_BACKSPACE,
  4649. GS_KEYCODE_INSERT,
  4650. GS_KEYCODE_DELETE,
  4651. GS_KEYCODE_RIGHT,
  4652. GS_KEYCODE_LEFT,
  4653. GS_KEYCODE_DOWN,
  4654. GS_KEYCODE_UP,
  4655. GS_KEYCODE_PAGE_UP,
  4656. GS_KEYCODE_PAGE_DOWN,
  4657. GS_KEYCODE_HOME,
  4658. GS_KEYCODE_END,
  4659. GS_KEYCODE_CAPS_LOCK,
  4660. GS_KEYCODE_SCROLL_LOCK,
  4661. GS_KEYCODE_NUM_LOCK,
  4662. GS_KEYCODE_PRINT_SCREEN,
  4663. GS_KEYCODE_PAUSE,
  4664. GS_KEYCODE_F1,
  4665. GS_KEYCODE_F2,
  4666. GS_KEYCODE_F3,
  4667. GS_KEYCODE_F4,
  4668. GS_KEYCODE_F5,
  4669. GS_KEYCODE_F6,
  4670. GS_KEYCODE_F7,
  4671. GS_KEYCODE_F8,
  4672. GS_KEYCODE_F9,
  4673. GS_KEYCODE_F10,
  4674. GS_KEYCODE_F11,
  4675. GS_KEYCODE_F12,
  4676. GS_KEYCODE_F13,
  4677. GS_KEYCODE_F14,
  4678. GS_KEYCODE_F15,
  4679. GS_KEYCODE_F16,
  4680. GS_KEYCODE_F17,
  4681. GS_KEYCODE_F18,
  4682. GS_KEYCODE_F19,
  4683. GS_KEYCODE_F20,
  4684. GS_KEYCODE_F21,
  4685. GS_KEYCODE_F22,
  4686. GS_KEYCODE_F23,
  4687. GS_KEYCODE_F24,
  4688. GS_KEYCODE_F25,
  4689. GS_KEYCODE_KP_0,
  4690. GS_KEYCODE_KP_1,
  4691. GS_KEYCODE_KP_2,
  4692. GS_KEYCODE_KP_3,
  4693. GS_KEYCODE_KP_4,
  4694. GS_KEYCODE_KP_5,
  4695. GS_KEYCODE_KP_6,
  4696. GS_KEYCODE_KP_7,
  4697. GS_KEYCODE_KP_8,
  4698. GS_KEYCODE_KP_9,
  4699. GS_KEYCODE_KP_DECIMAL,
  4700. GS_KEYCODE_KP_DIVIDE,
  4701. GS_KEYCODE_KP_MULTIPLY,
  4702. GS_KEYCODE_KP_SUBTRACT,
  4703. GS_KEYCODE_KP_ADD,
  4704. GS_KEYCODE_KP_ENTER,
  4705. GS_KEYCODE_KP_EQUAL,
  4706. GS_KEYCODE_LEFT_SHIFT,
  4707. GS_KEYCODE_LEFT_CONTROL,
  4708. GS_KEYCODE_LEFT_ALT,
  4709. GS_KEYCODE_LEFT_SUPER,
  4710. GS_KEYCODE_RIGHT_SHIFT,
  4711. GS_KEYCODE_RIGHT_CONTROL,
  4712. GS_KEYCODE_RIGHT_ALT,
  4713. GS_KEYCODE_RIGHT_SUPER,
  4714. GS_KEYCODE_MENU,
  4715. GS_KEYCODE_COUNT
  4716. } gs_platform_keycode;
  4717. #define GS_KEYCODE_LCTRL GS_KEYCODE_LEFT_CONTROL
  4718. #define GS_KEYCODE_RCTRL GS_KEYCODE_RIGHT_CONTROL
  4719. #define GS_KEYCODE_LSHIFT GS_KEYCODE_LEFT_SHIFT
  4720. #define GS_KEYCODE_RSHIFT GS_KEYCODE_RIGHT_SHIFT
  4721. #define GS_KEYCODE_LALT GS_KEYCODE_LEFT_ALT
  4722. #define GS_KEYCODE_RALT GS_KEYCODE_RIGHT_ALT
  4723. typedef enum gs_platform_mouse_button_code
  4724. {
  4725. GS_MOUSE_LBUTTON,
  4726. GS_MOUSE_RBUTTON,
  4727. GS_MOUSE_MBUTTON,
  4728. GS_MOUSE_BUTTON_CODE_COUNT
  4729. } gs_platform_mouse_button_code;
  4730. typedef struct gs_platform_mouse_t
  4731. {
  4732. b32 button_map[GS_MOUSE_BUTTON_CODE_COUNT];
  4733. b32 prev_button_map[GS_MOUSE_BUTTON_CODE_COUNT];
  4734. gs_vec2 position;
  4735. gs_vec2 delta;
  4736. gs_vec2 wheel;
  4737. b32 moved_this_frame;
  4738. b32 locked;
  4739. } gs_platform_mouse_t;
  4740. enum
  4741. {
  4742. GS_PLATFORM_GAMEPAD_BUTTON_A = 0x00,
  4743. GS_PLATFORM_GAMEPAD_BUTTON_B,
  4744. GS_PLATFORM_GAMEPAD_BUTTON_X,
  4745. GS_PLATFORM_GAMEPAD_BUTTON_Y,
  4746. GS_PLATFORM_GAMEPAD_BUTTON_LBUMPER,
  4747. GS_PLATFORM_GAMEPAD_BUTTON_RBUMPER,
  4748. GS_PLATFORM_GAMEPAD_BUTTON_BACK,
  4749. GS_PLATFORM_GAMEPAD_BUTTON_START,
  4750. GS_PLATFORM_GAMEPAD_BUTTON_GUIDE,
  4751. GS_PLATFORM_GAMEPAD_BUTTON_LTHUMB,
  4752. GS_PLATFORM_GAMEPAD_BUTTON_RTHUMB,
  4753. GS_PLATFORM_GAMEPAD_BUTTON_DPUP,
  4754. GS_PLATFORM_GAMEPAD_BUTTON_DPRIGHT,
  4755. GS_PLATFORM_GAMEPAD_BUTTON_DPDOWN,
  4756. GS_PLATFORM_GAMEPAD_BUTTON_DPLEFT,
  4757. GS_PLATFORM_GAMEPAD_BUTTON_COUNT
  4758. };
  4759. #define GS_PLATFORM_GAMEPAD_BUTTON_LAST GS_PLATFORM_GAMEPAD_BUTTON_DPLEFT
  4760. #define GS_PLATFORM_GAMEPAD_BUTTON_CROSS GS_PLATFORM_GAMEPAD_BUTTON_A
  4761. #define GS_PLATFORM_GAMEPAD_BUTTON_CIRCLE GS_PLATFORM_GAMEPAD_BUTTON_B
  4762. #define GS_PLATFORM_GAMEPAD_BUTTON_SQUARE GS_PLATFORM_GAMEPAD_BUTTON_X
  4763. #define GS_PLATFORM_GAMEPAD_BUTTON_TRIANGLE GS_PLATFORM_GAMEPAD_BUTTON_Y
  4764. enum
  4765. {
  4766. GS_PLATFORM_JOYSTICK_AXIS_LEFT_X = 0x00,
  4767. GS_PLATFORM_JOYSTICK_AXIS_LEFT_Y,
  4768. GS_PLATFORM_JOYSTICK_AXIS_RIGHT_X,
  4769. GS_PLATFORM_JOYSTICK_AXIS_RIGHT_Y,
  4770. GS_PLATFORM_JOYSTICK_AXIS_LTRIGGER,
  4771. GS_PLATFORM_JOYSTICK_AXIS_RTRIGGER,
  4772. GS_PLATFORM_JOYSTICK_AXIS_COUNT
  4773. };
  4774. #define GS_PLATFORM_GAMEPAD_MAX 16
  4775. typedef struct gs_platform_gamepad_t
  4776. {
  4777. int16_t buttons[GS_PLATFORM_GAMEPAD_BUTTON_COUNT];
  4778. float axes[GS_PLATFORM_JOYSTICK_AXIS_COUNT];
  4779. int16_t present;
  4780. } gs_platform_gamepad_t;
  4781. #define GS_PLATFORM_MAX_TOUCH 5
  4782. typedef struct gs_platform_touchpoint_t
  4783. {
  4784. size_t id;
  4785. gs_vec2 position;
  4786. gs_vec2 delta;
  4787. uint16_t changed;
  4788. uint16_t pressed;
  4789. uint16_t down;
  4790. } gs_platform_touchpoint_t;
  4791. typedef struct gs_platform_touch_t
  4792. {
  4793. gs_platform_touchpoint_t points[GS_PLATFORM_MAX_TOUCH];
  4794. uint16_t size; // Current number of touches active
  4795. } gs_platform_touch_t;
  4796. typedef struct gs_platform_input_t
  4797. {
  4798. b32 key_map[GS_KEYCODE_COUNT];
  4799. b32 prev_key_map[GS_KEYCODE_COUNT];
  4800. gs_platform_mouse_t mouse;
  4801. gs_platform_touch_t touch;
  4802. gs_platform_gamepad_t gamepads[GS_PLATFORM_GAMEPAD_MAX];
  4803. } gs_platform_input_t;
  4804. // Enumeration of all platform types
  4805. typedef enum gs_platform_type
  4806. {
  4807. GS_PLATFORM_TYPE_UNKNOWN = 0,
  4808. GS_PLATFORM_TYPE_WINDOWS,
  4809. GS_PLATFORM_TYPE_LINUX,
  4810. GS_PLATFORM_TYPE_MAC,
  4811. GS_PLATFORM_TYPE_ANDROID,
  4812. GS_PLATFORM_TYPE_IOS,
  4813. GS_PLATFORM_TYPE_HTML5,
  4814. GS_PLATFORM_TYPE_RPI
  4815. } gs_platform_type;
  4816. typedef enum gs_platform_video_driver_type
  4817. {
  4818. GS_PLATFORM_VIDEO_DRIVER_TYPE_NONE = 0,
  4819. GS_PLATFORM_VIDEO_DRIVER_TYPE_OPENGL,
  4820. GS_PLATFORM_VIDEO_DRIVER_TYPE_OPENGLES,
  4821. GS_PLATFORM_VIDEO_DRIVER_TYPE_DIRECTX,
  4822. GS_PLATFORM_VIDEO_DRIVER_TYPE_VULKAN,
  4823. GS_PLATFORM_VIDEO_DRIVER_TYPE_METAL,
  4824. GS_PLATFORM_VIDEO_DRIVER_TYPE_SOFTWARE
  4825. } gs_platform_video_driver_type;
  4826. typedef enum gs_opengl_compatibility_flags
  4827. {
  4828. GS_OPENGL_COMPATIBILITY_FLAGS_LEGACY = 0,
  4829. GS_OPENGL_COMPATIBILITY_FLAGS_CORE = 1 << 1,
  4830. GS_OPENGL_COMPATIBILITY_FLAGS_COMPATIBILITY = 1 << 2,
  4831. GS_OPENGL_COMPATIBILITY_FLAGS_FORWARD = 1 << 3,
  4832. GS_OPENGL_COMPATIBILITY_FLAGS_ES = 1 << 4,
  4833. } gs_opengl_compatibility_flags;
  4834. // A structure that contains OpenGL video settings
  4835. typedef struct gs_opengl_video_settings_t
  4836. {
  4837. gs_opengl_compatibility_flags compability_flags;
  4838. uint32_t major_version;
  4839. uint32_t minor_version;
  4840. uint8_t multi_sampling_count;
  4841. void* ctx;
  4842. } gs_opengl_video_settings_t;
  4843. typedef union gs_graphics_api_settings_t
  4844. {
  4845. gs_opengl_video_settings_t opengl;
  4846. bool32 debug;
  4847. } gs_graphics_api_settings_t;
  4848. typedef struct gs_platform_video_settings_t
  4849. {
  4850. gs_graphics_api_settings_t graphics;
  4851. gs_platform_video_driver_type driver;
  4852. b32 vsync_enabled;
  4853. } gs_platform_video_settings_t;
  4854. typedef struct gs_platform_settings_t
  4855. {
  4856. gs_platform_video_settings_t video;
  4857. } gs_platform_settings_t;
  4858. typedef enum gs_platform_event_type
  4859. {
  4860. GS_PLATFORM_EVENT_MOUSE,
  4861. GS_PLATFORM_EVENT_KEY,
  4862. GS_PLATFORM_EVENT_TEXT,
  4863. GS_PLATFORM_EVENT_WINDOW,
  4864. GS_PLATFORM_EVENT_TOUCH,
  4865. GS_PLATFORM_EVENT_APP
  4866. } gs_platform_event_type;
  4867. typedef enum gs_platform_key_modifier_type
  4868. {
  4869. GS_PLATFORM_KEY_MODIFIER_NONE = 0x00,
  4870. GS_PLATFORM_KEY_MODIFIER_SHIFT = 0x01,
  4871. GS_PLATFORM_KEY_MODIFIER_CONTROL = 0x02,
  4872. GS_PLATFORM_KEY_MODIFIER_ALT = 0x04
  4873. } gs_platform_key_modifier_type;
  4874. typedef enum gs_platform_key_action_type
  4875. {
  4876. GS_PLATFORM_KEY_PRESSED,
  4877. GS_PLATFORM_KEY_DOWN,
  4878. GS_PLATFORM_KEY_RELEASED
  4879. } gs_platform_key_action_type;
  4880. typedef struct gs_platform_key_event_t
  4881. {
  4882. int32_t codepoint;
  4883. gs_platform_keycode keycode;
  4884. gs_platform_key_action_type action;
  4885. gs_platform_key_modifier_type modifier;
  4886. } gs_platform_key_event_t;
  4887. typedef enum gs_platform_mousebutton_action_type
  4888. {
  4889. GS_PLATFORM_MOUSE_BUTTON_PRESSED,
  4890. GS_PLATFORM_MOUSE_BUTTON_DOWN,
  4891. GS_PLATFORM_MOUSE_BUTTON_RELEASED,
  4892. GS_PLATFORM_MOUSE_MOVE,
  4893. GS_PLATFORM_MOUSE_ENTER,
  4894. GS_PLATFORM_MOUSE_LEAVE,
  4895. GS_PLATFORM_MOUSE_WHEEL
  4896. } gs_platform_mousebutton_action_type;
  4897. typedef struct gs_platform_mouse_event_t
  4898. {
  4899. int32_t codepoint;
  4900. union {
  4901. gs_platform_mouse_button_code button;
  4902. gs_vec2 wheel;
  4903. gs_vec2 move;
  4904. };
  4905. gs_platform_mousebutton_action_type action;
  4906. } gs_platform_mouse_event_t;
  4907. typedef enum gs_platform_window_action_type
  4908. {
  4909. GS_PLATFORM_WINDOW_RESIZE,
  4910. GS_PLATFORM_WINDOW_LOSE_FOCUS,
  4911. GS_PLATFORM_WINDOW_GAIN_FOCUS,
  4912. GS_PLATFORM_WINDOW_CREATE,
  4913. GS_PLATFORM_WINDOW_DESTROY
  4914. } gs_platform_window_action_type;
  4915. typedef struct gs_platform_window_event_t
  4916. {
  4917. uint32_t hndl;
  4918. gs_platform_window_action_type action;
  4919. } gs_platform_window_event_t;
  4920. typedef struct gs_platform_text_event_t
  4921. {
  4922. uint32_t codepoint;
  4923. } gs_platform_text_event_t;
  4924. typedef enum gs_platform_touch_action_type
  4925. {
  4926. GS_PLATFORM_TOUCH_DOWN,
  4927. GS_PLATFORM_TOUCH_UP,
  4928. GS_PLATFORM_TOUCH_MOVE,
  4929. GS_PLATFORM_TOUCH_CANCEL
  4930. } gs_platform_touch_action_type;
  4931. typedef struct gs_platform_point_event_data_t {
  4932. uintptr_t id;
  4933. gs_vec2 position;
  4934. uint16_t changed;
  4935. } gs_platform_point_event_data_t;
  4936. typedef struct gs_platform_touch_event_t
  4937. {
  4938. gs_platform_touch_action_type action;
  4939. gs_platform_point_event_data_t point;
  4940. } gs_platform_touch_event_t;
  4941. typedef enum gs_platform_app_action_type
  4942. {
  4943. GS_PLATFORM_APP_START,
  4944. GS_PLATFORM_APP_PAUSE,
  4945. GS_PLATFORM_APP_RESUME,
  4946. GS_PLATFORM_APP_STOP
  4947. } gs_platform_app_action_type;
  4948. typedef struct gs_platform_app_event_t
  4949. {
  4950. gs_platform_app_action_type action;
  4951. } gs_platform_app_event_t;
  4952. // Platform events
  4953. typedef struct gs_platform_event_t
  4954. {
  4955. gs_platform_event_type type;
  4956. union {
  4957. gs_platform_key_event_t key;
  4958. gs_platform_mouse_event_t mouse;
  4959. gs_platform_window_event_t window;
  4960. gs_platform_touch_event_t touch;
  4961. gs_platform_app_event_t app;
  4962. gs_platform_text_event_t text;
  4963. };
  4964. uint32_t idx;
  4965. } gs_platform_event_t;
  4966. // Necessary function pointer typedefs
  4967. typedef void (* gs_dropped_files_callback_t)(void*, int32_t count, const char** file_paths);
  4968. typedef void (* gs_window_close_callback_t)(void*);
  4969. typedef void (* gs_character_callback_t)(void*, uint32_t code_point);
  4970. typedef void (* gs_framebuffer_resize_callback_t)(void*, int32_t width, int32_t height);
  4971. /*===============================================================================================
  4972. // Platform Interface
  4973. ===============================================================================================*/
  4974. struct gs_platform_interface_s;
  4975. typedef struct gs_platform_t
  4976. {
  4977. // Settings for platform, including video
  4978. gs_platform_settings_t settings;
  4979. // Time
  4980. gs_platform_time_t time;
  4981. // Input
  4982. gs_platform_input_t input;
  4983. // Window data and handles
  4984. gs_slot_array(gs_platform_window_t) windows;
  4985. // Events that user can poll
  4986. gs_dyn_array(gs_platform_event_t) events;
  4987. // Cursors
  4988. void* cursors[GS_PLATFORM_CURSOR_COUNT];
  4989. // Specific user data (for custom implementations)
  4990. void* user_data;
  4991. // Optional api for stable access across .dll boundaries
  4992. struct gs_platform_interface_s* api;
  4993. } gs_platform_t;
  4994. /*===============================================================================================
  4995. // Platform API
  4996. ===============================================================================================*/
  4997. /* == Platform Default API == */
  4998. // Platform Create / Destroy
  4999. GS_API_DECL gs_platform_t* gs_platform_create();
  5000. GS_API_DECL void gs_platform_destroy(gs_platform_t* platform);
  5001. // Platform Init / Update / Shutdown
  5002. GS_API_DECL void gs_platform_update(gs_platform_t* platform); // Update platform layer
  5003. // Platform Util
  5004. GS_API_DECL const gs_platform_time_t* gs_platform_time();
  5005. GS_API_DECL float gs_platform_delta_time();
  5006. GS_API_DECL float gs_platform_frame_time();
  5007. // Platform UUID
  5008. GS_API_DECL gs_uuid_t gs_platform_uuid_generate();
  5009. GS_API_DECL void gs_platform_uuid_to_string(char* temp_buffer, const gs_uuid_t* uuid); // Expects a temp buffer with at least 32 bytes
  5010. GS_API_DECL uint32_t gs_platform_uuid_hash(const gs_uuid_t* uuid);
  5011. // Platform Input
  5012. GS_API_DECL gs_platform_input_t* gs_platform_input();
  5013. GS_API_DECL void gs_platform_update_input(gs_platform_input_t* input);
  5014. GS_API_DECL void gs_platform_press_key(gs_platform_keycode code);
  5015. GS_API_DECL void gs_platform_release_key(gs_platform_keycode code);
  5016. GS_API_DECL bool gs_platform_was_key_down(gs_platform_keycode code);
  5017. GS_API_DECL void gs_platform_press_mouse_button(gs_platform_mouse_button_code code);
  5018. GS_API_DECL void gs_platform_release_mouse_button(gs_platform_mouse_button_code code);
  5019. GS_API_DECL bool gs_platform_was_mouse_down(gs_platform_mouse_button_code code);
  5020. GS_API_DECL void gs_platform_press_touch(uint32_t idx);
  5021. GS_API_DECL void gs_platform_release_touch(uint32_t idx);
  5022. GS_API_DECL bool gs_platform_was_touch_down(uint32_t idx);
  5023. GS_API_DECL bool gs_platform_key_pressed(gs_platform_keycode code);
  5024. GS_API_DECL bool gs_platform_key_down(gs_platform_keycode code);
  5025. GS_API_DECL bool gs_platform_key_released(gs_platform_keycode code);
  5026. GS_API_DECL bool gs_platform_touch_pressed(uint32_t idx);
  5027. GS_API_DECL bool gs_platform_touch_down(uint32_t idx);
  5028. GS_API_DECL bool gs_platform_touch_released(uint32_t idx);
  5029. GS_API_DECL bool gs_platform_mouse_pressed(gs_platform_mouse_button_code code);
  5030. GS_API_DECL bool gs_platform_mouse_down(gs_platform_mouse_button_code code);
  5031. GS_API_DECL bool gs_platform_mouse_released(gs_platform_mouse_button_code code);
  5032. GS_API_DECL gs_vec2 gs_platform_mouse_deltav();
  5033. GS_API_DECL void gs_platform_mouse_delta(float* x, float* y);
  5034. GS_API_DECL gs_vec2 gs_platform_mouse_positionv();
  5035. GS_API_DECL void gs_platform_mouse_position(int32_t* x, int32_t* y);
  5036. GS_API_DECL void gs_platform_mouse_wheel(float* x, float* y);
  5037. GS_API_DECL gs_vec2 gs_platform_mouse_wheelv();
  5038. GS_API_DECL bool gs_platform_mouse_moved();
  5039. GS_API_DECL bool gs_platform_mouse_locked();
  5040. GS_API_DECL gs_vec2 gs_platform_touch_deltav(uint32_t idx);
  5041. GS_API_DECL void gs_platform_touch_delta(uint32_t idx, float* x, float* y);
  5042. GS_API_DECL gs_vec2 gs_platform_touch_positionv(uint32_t idx);
  5043. GS_API_DECL void gs_platform_touch_position(uint32_t idx, float* x, float* y);
  5044. // Platform Events
  5045. GS_API_DECL bool gs_platform_poll_events(gs_platform_event_t* evt, bool32_t consume);
  5046. GS_API_DECL void gs_platform_add_event(gs_platform_event_t* evt);
  5047. // Platform Window
  5048. GS_API_DECL uint32_t gs_platform_window_create(const gs_platform_window_desc_t* desc);
  5049. GS_API_DECL uint32_t gs_platform_main_window();
  5050. GS_API_DECL void gs_platform_window_make_current(uint32_t hndl); // Binds context (main thread only)
  5051. GS_API_DECL void gs_platform_window_make_current_raw(void* win); // Binds context (can be on separate thread with raw handle)
  5052. typedef struct gs_platform_file_stats_s
  5053. {
  5054. uint64_t modified_time;
  5055. uint64_t creation_time;
  5056. uint64_t access_time;
  5057. } gs_platform_file_stats_t;
  5058. // Platform File IO (this all needs to be made available for impl rewrites)
  5059. GS_API_DECL char* gs_platform_read_file_contents_default_impl(const char* file_path, const char* mode, size_t* sz);
  5060. GS_API_DECL gs_result gs_platform_write_file_contents_default_impl(const char* file_path, const char* mode, void* data, size_t data_size);
  5061. GS_API_DECL bool gs_platform_file_exists_default_impl(const char* file_path);
  5062. GS_API_DECL bool gs_platform_dir_exists_default_impl(const char* dir_path);
  5063. GS_API_DECL int32_t gs_platform_mkdir_default_impl(const char* dir_path, int32_t opt);
  5064. GS_API_DECL int32_t gs_platform_file_size_in_bytes_default_impl(const char* file_path);
  5065. GS_API_DECL void gs_platform_file_extension_default_impl(char* buffer, size_t buffer_sz, const char* file_path);
  5066. GS_API_DECL int32_t gs_platform_file_delete_default_impl(const char* file_path);
  5067. GS_API_DECL int32_t gs_platform_file_copy_default_impl(const char* src_path, const char* dst_path);
  5068. GS_API_DECL int32_t gs_platform_file_compare_time(uint64_t time_a, uint64_t time_b);
  5069. GS_API_DECL gs_platform_file_stats_t gs_platform_file_stats(const char* file_path);
  5070. GS_API_DECL void* gs_platform_library_load_default_impl(const char* lib_path);
  5071. GS_API_DECL void gs_platform_library_unload_default_impl(void* lib);
  5072. GS_API_DECL void* gs_platform_library_proc_address_default_impl(void* lib, const char* func);
  5073. // Default file implementations
  5074. #ifndef gs_platform_read_file_contents
  5075. #define gs_platform_read_file_contents gs_platform_read_file_contents_default_impl
  5076. #endif
  5077. #ifndef gs_platform_write_file_contents
  5078. #define gs_platform_write_file_contents gs_platform_write_file_contents_default_impl
  5079. #endif
  5080. #ifndef gs_platform_file_exists
  5081. #define gs_platform_file_exists gs_platform_file_exists_default_impl
  5082. #endif
  5083. #ifndef gs_platform_dir_exists
  5084. #define gs_platform_dir_exists gs_platform_dir_exists_default_impl
  5085. #endif
  5086. #ifndef gs_platform_mkdir
  5087. #define gs_platform_mkdir gs_platform_mkdir_default_impl
  5088. #endif
  5089. #ifndef gs_platform_file_exists
  5090. #define gs_platform_file_exists gs_platform_file_exists_default_impl
  5091. #endif
  5092. #ifndef gs_platform_file_size_in_bytes
  5093. #define gs_platform_file_size_in_bytes gs_platform_file_size_in_bytes_default_impl
  5094. #endif
  5095. #ifndef gs_platform_file_extension
  5096. #define gs_platform_file_extension gs_platform_file_extension_default_impl
  5097. #endif
  5098. #ifndef gs_platform_file_delete
  5099. #define gs_platform_file_delete gs_platform_file_delete_default_impl
  5100. #endif
  5101. #ifndef gs_platform_file_copy
  5102. #define gs_platform_file_copy gs_platform_file_copy_default_impl
  5103. #endif
  5104. #ifndef gs_platform_library_load
  5105. #define gs_platform_library_load gs_platform_library_load_default_impl
  5106. #endif
  5107. #ifndef gs_platform_library_unload
  5108. #define gs_platform_library_unload gs_platform_library_unload_default_impl
  5109. #endif
  5110. #ifndef gs_platform_library_proc_addresss
  5111. #define gs_platform_library_proc_address gs_platform_library_proc_address_default_impl
  5112. #endif
  5113. /* == Platform Dependent API == */
  5114. GS_API_DECL void gs_platform_init(gs_platform_t* platform); // Initialize platform layer
  5115. GS_API_DECL void gs_platform_shutdown(gs_platform_t* platform); // Shutdown platform layer
  5116. GS_API_DECL void gs_platform_update_internal(gs_platform_t* platform);
  5117. // Platform Util
  5118. GS_API_DECL double gs_platform_elapsed_time(); // Returns time in ms since initialization of platform
  5119. GS_API_DECL void gs_platform_sleep(float ms); // Sleeps platform for time in ms
  5120. // Platform Video
  5121. GS_API_DECL void gs_platform_enable_vsync(int32_t enabled);
  5122. // Platform Input
  5123. GS_API_DECL void gs_platform_process_input(gs_platform_input_t* input);
  5124. GS_API_DECL uint32_t gs_platform_key_to_codepoint(gs_platform_keycode code);
  5125. GS_API_DECL gs_platform_keycode gs_platform_codepoint_to_key(uint32_t code);
  5126. GS_API_DECL void gs_platform_mouse_set_position(uint32_t handle, float x, float y);
  5127. GS_API_DECL void gs_platform_lock_mouse(uint32_t handle, bool32_t lock);
  5128. GS_API_DECL gs_platform_window_t gs_platform_window_create_internal(const gs_platform_window_desc_t* desc);
  5129. GS_API_DECL void gs_platform_window_swap_buffer(uint32_t handle);
  5130. GS_API_DECL gs_vec2 gs_platform_window_sizev(uint32_t handle);
  5131. GS_API_DECL void gs_platform_window_size(uint32_t handle, uint32_t* width, uint32_t* height);
  5132. GS_API_DECL uint32_t gs_platform_window_width(uint32_t handle);
  5133. GS_API_DECL uint32_t gs_platform_window_height(uint32_t handle);
  5134. GS_API_DECL bool32_t gs_platform_window_fullscreen(uint32_t handle);
  5135. GS_API_DECL gs_vec2 gs_platform_window_positionv(uint32_t handle);
  5136. GS_API_DECL void gs_platform_window_position(uint32_t handle, uint32_t* x, uint32_t* y);
  5137. GS_API_DECL void gs_platform_set_window_size(uint32_t handle, uint32_t width, uint32_t height);
  5138. GS_API_DECL void gs_platform_set_window_sizev(uint32_t handle, gs_vec2 v);
  5139. GS_API_DECL void gs_platform_set_window_fullscreen(uint32_t handle, bool32_t fullscreen);
  5140. GS_API_DECL void gs_platform_set_window_position(uint32_t handle, uint32_t x, uint32_t y);
  5141. GS_API_DECL void gs_platform_set_window_positionv(uint32_t handle, gs_vec2 v);
  5142. GS_API_DECL void gs_platform_set_cursor(uint32_t handle, gs_platform_cursor cursor);
  5143. GS_API_DECL void* gs_platform_raw_window_handle(uint32_t handle);
  5144. GS_API_DECL gs_vec2 gs_platform_framebuffer_sizev(uint32_t handle);
  5145. GS_API_DECL void gs_platform_framebuffer_size(uint32_t handle, uint32_t* w, uint32_t* h);
  5146. GS_API_DECL uint32_t gs_platform_framebuffer_width(uint32_t handle);
  5147. GS_API_DECL uint32_t gs_platform_framebuffer_height(uint32_t handle);
  5148. GS_API_DECL gs_vec2 gs_platform_monitor_sizev(uint32_t id);
  5149. GS_API_DECL void gs_platform_window_set_clipboard(uint32_t handle, const char* str);
  5150. GS_API_DECL const char* gs_platform_window_get_clipboard(uint32_t handle);
  5151. // Platform callbacks
  5152. GS_API_DECL void gs_platform_set_framebuffer_resize_callback(uint32_t handle, gs_framebuffer_resize_callback_t cb);
  5153. GS_API_DECL void gs_platform_set_dropped_files_callback(uint32_t handle, gs_dropped_files_callback_t cb);
  5154. GS_API_DECL void gs_platform_set_window_close_callback(uint32_t handle, gs_window_close_callback_t cb);
  5155. GS_API_DECL void gs_platform_set_character_callback(uint32_t handle, gs_character_callback_t cb);
  5156. /*
  5157. typedef struct gs_platform_interface_s
  5158. {
  5159. } gs_platform_interface_t;
  5160. */
  5161. /** @} */ // end of gs_platform
  5162. /*=============================
  5163. // GS_AUDIO
  5164. =============================*/
  5165. /** @defgroup gs_audio Audio
  5166. * Gunslinger Audio
  5167. * @{
  5168. */
  5169. typedef enum gs_audio_file_type
  5170. {
  5171. GS_OGG = 0x00,
  5172. GS_WAV,
  5173. GS_MP3
  5174. } gs_audio_file_type;
  5175. /*==================
  5176. // Audio Source
  5177. ==================*/
  5178. typedef struct gs_audio_source_t
  5179. {
  5180. int32_t channels;
  5181. int32_t sample_rate;
  5182. void* samples;
  5183. int32_t sample_count;
  5184. } gs_audio_source_t;
  5185. gs_handle_decl(gs_audio_source_t);
  5186. typedef struct gs_audio_instance_decl_t
  5187. {
  5188. gs_handle(gs_audio_source_t) src;
  5189. float volume;
  5190. float pitch;
  5191. bool32_t loop;
  5192. bool32_t persistent;
  5193. bool32_t playing;
  5194. double sample_position;
  5195. void* user_data;
  5196. } gs_audio_instance_decl_t;
  5197. typedef gs_audio_instance_decl_t gs_audio_instance_t;
  5198. gs_handle_decl(gs_audio_instance_t);
  5199. typedef void (* gs_audio_commit)(int16_t* output, uint32_t num_channels, uint32_t sample_rate, uint32_t frame_count);
  5200. /*=============================
  5201. // Audio Interface
  5202. =============================*/
  5203. typedef struct gs_audio_t
  5204. {
  5205. // Audio source data cache
  5206. gs_slot_array(gs_audio_source_t) sources;
  5207. // Audio instance data cache
  5208. gs_slot_array(gs_audio_instance_t) instances;
  5209. // Max global volume setting
  5210. float max_audio_volume;
  5211. // Min global volume setting
  5212. float min_audio_volume;
  5213. // Samples to actually write to hardware
  5214. void* sample_out;
  5215. // Custom user commit function
  5216. gs_audio_commit commit;
  5217. // User data for custom impl
  5218. void* user_data;
  5219. } gs_audio_t;
  5220. /*=============================
  5221. // Audio API
  5222. =============================*/
  5223. /* Audio Create, Destroy, Init, Shutdown, Submit */
  5224. GS_API_DECL gs_audio_t* gs_audio_create();
  5225. GS_API_DECL void gs_audio_destroy(gs_audio_t* audio);
  5226. GS_API_DECL gs_result gs_audio_init(gs_audio_t* audio);
  5227. GS_API_DECL gs_result gs_audio_shutdown(gs_audio_t* audio);
  5228. // Register commit function
  5229. GS_API_DECL void gs_audio_register_commit(gs_audio_commit commit);
  5230. /* Audio create source */
  5231. GS_API_DECL gs_handle(gs_audio_source_t) gs_audio_load_from_file(const char* file_path);
  5232. /* Audio create instance */
  5233. GS_API_DECL gs_handle(gs_audio_instance_t) gs_audio_instance_create(gs_audio_instance_decl_t* decl);
  5234. /* Locking audio thread (optional) */
  5235. GS_API_DECL void gs_audio_mutex_lock(gs_audio_t* audio);
  5236. GS_API_DECL void gs_audio_mutex_unlock(gs_audio_t* audio);
  5237. /* Audio play instance */
  5238. GS_API_DECL void gs_audio_play_source_with_pitch(gs_handle(gs_audio_source_t) src, float volume, float pitch);
  5239. GS_API_DECL void gs_audio_play_source(gs_handle(gs_audio_source_t) src, float volume);
  5240. GS_API_DECL void gs_audio_play(gs_handle(gs_audio_instance_t) inst);
  5241. GS_API_DECL void gs_audio_pause(gs_handle(gs_audio_instance_t) inst);
  5242. GS_API_DECL void gs_audio_stop(gs_handle(gs_audio_instance_t) inst);
  5243. GS_API_DECL void gs_audio_restart(gs_handle(gs_audio_instance_t) inst);
  5244. GS_API_DECL bool32_t gs_audio_is_playing(gs_handle(gs_audio_instance_t) inst);
  5245. /* Audio instance data */
  5246. GS_API_DECL void gs_audio_set_instance_data(gs_handle(gs_audio_instance_t) inst, gs_audio_instance_decl_t decl);
  5247. GS_API_DECL gs_audio_instance_decl_t gs_audio_get_instance_data(gs_handle(gs_audio_instance_t) inst);
  5248. GS_API_DECL float gs_audio_get_volume(gs_handle(gs_audio_instance_t) inst);
  5249. GS_API_DECL void gs_audio_set_volume(gs_handle(gs_audio_instance_t) inst, float volume);
  5250. /* Audio source data */
  5251. GS_API_DECL gs_audio_source_t* gs_audio_get_source_data(gs_handle(gs_audio_source_t) src);
  5252. GS_API_DECL void gs_audio_get_runtime(gs_handle(gs_audio_source_t) src, int32_t* minutes, int32_t* seconds);
  5253. GS_API_DECL void gs_audio_convert_to_runtime(int32_t sample_count, int32_t sample_rate, int32_t num_channels, int32_t position, int32_t* minutes_out, int32_t* seconds_out);
  5254. GS_API_DECL int32_t gs_audio_get_sample_count(gs_handle(gs_audio_source_t) src);
  5255. GS_API_DECL int32_t gs_audio_get_sample_rate(gs_handle(gs_audio_source_t) src);
  5256. GS_API_DECL int32_t gs_audio_get_num_channels(gs_handle(gs_audio_source_t) src);
  5257. /* Resource Loading */
  5258. GS_API_DECL bool32_t gs_audio_load_ogg_data_from_file(const char* file_path, int32_t* sample_count, int32_t* channels, int32_t* sample_rate, void** samples);
  5259. GS_API_DECL bool32_t gs_audio_load_wav_data_from_file(const char* file_path, int32_t* sample_count, int32_t* channels, int32_t* sample_rate, void** samples);
  5260. GS_API_DECL bool32_t gs_audio_load_mp3_data_from_file(const char* file_path, int32_t* sample_count, int32_t* channels, int32_t* sample_rate, void** samples);
  5261. /* Short name definitions for convenience */
  5262. #ifndef GS_NO_SHORT_NAME
  5263. /* Resources */
  5264. #define gsa_src gs_handle(gs_audio_source_t)
  5265. #define gsa_inst gs_handle(gs_audio_instance_t)
  5266. #define gsa_instdecl gs_audio_instance_decl_t
  5267. /* Create */
  5268. #define gsa_create gs_audio_create
  5269. #define gsa_destroy gs_audio_destroy
  5270. #define gsa_init gs_audio_init
  5271. #define gsa_shutdown gs_audio_shutdown
  5272. #define gsa_submit gs_audio_submit
  5273. /* Source */
  5274. #define gsa_load gs_audio_load_from_file
  5275. /* Instance */
  5276. #define gsa_make_inst gs_audio_instance_create
  5277. /* Audio play instance */
  5278. #define gsa_isplaying gs_audio_is_playing
  5279. #define gsa_play gs_audio_play
  5280. #define gsa_play_src gs_audio_play_source
  5281. #define gsa_pause gs_audio_pause
  5282. #define gsa_restart gs_audio_restart
  5283. #endif
  5284. /** @} */ // end of gs_audio
  5285. /*=============================
  5286. // GS_GRAPHICS
  5287. =============================*/
  5288. /** @defgroup gs_graphics Graphics
  5289. * Gunslinger Graphics
  5290. * @{
  5291. */
  5292. // Graphics Pipeline
  5293. // Main graphics resources:
  5294. // Shader description: vertex, fragment, compute, geometry, tesselation
  5295. // Texture Description: texture, depth, render target
  5296. // Buffer Description: vertex, index, uniform, frame, pixel
  5297. // Pipeline Description: vert-layout, shader, bindables, render states
  5298. // Pass Description: render pass, action on render targets (clear, set viewport, etc.)
  5299. /* Useful macro for forcing enum decl to be uint32_t type with default = 0x00 for quick init */
  5300. #define gs_enum_decl(NAME, ...)\
  5301. typedef enum NAME {\
  5302. _gs_##NAME##_default = 0x0,\
  5303. __VA_ARGS__,\
  5304. _gs_##NAME##_count,\
  5305. _gs_##NAME##_force_u32 = 0x7fffffff\
  5306. } NAME;
  5307. #define gs_enum_count(NAME)\
  5308. _gs_##NAME##_count
  5309. /* Shader Stage Type */
  5310. gs_enum_decl(gs_graphics_shader_stage_type,
  5311. GS_GRAPHICS_SHADER_STAGE_VERTEX,
  5312. GS_GRAPHICS_SHADER_STAGE_FRAGMENT,
  5313. GS_GRAPHICS_SHADER_STAGE_COMPUTE
  5314. );
  5315. /* Winding Order Type */
  5316. gs_enum_decl(gs_graphics_winding_order_type,
  5317. GS_GRAPHICS_WINDING_ORDER_CW,
  5318. GS_GRAPHICS_WINDING_ORDER_CCW
  5319. );
  5320. /* Face Culling Type */
  5321. gs_enum_decl(gs_graphics_face_culling_type,
  5322. GS_GRAPHICS_FACE_CULLING_FRONT,
  5323. GS_GRAPHICS_FACE_CULLING_BACK,
  5324. GS_GRAPHICS_FACE_CULLING_FRONT_AND_BACK
  5325. );
  5326. /* Blend Equation Type */
  5327. gs_enum_decl(gs_graphics_blend_equation_type,
  5328. GS_GRAPHICS_BLEND_EQUATION_ADD,
  5329. GS_GRAPHICS_BLEND_EQUATION_SUBTRACT,
  5330. GS_GRAPHICS_BLEND_EQUATION_REVERSE_SUBTRACT,
  5331. GS_GRAPHICS_BLEND_EQUATION_MIN,
  5332. GS_GRAPHICS_BLEND_EQUATION_MAX
  5333. );
  5334. /* Blend Mode Type */
  5335. gs_enum_decl(gs_graphics_blend_mode_type,
  5336. GS_GRAPHICS_BLEND_MODE_ZERO,
  5337. GS_GRAPHICS_BLEND_MODE_ONE,
  5338. GS_GRAPHICS_BLEND_MODE_SRC_COLOR,
  5339. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_SRC_COLOR,
  5340. GS_GRAPHICS_BLEND_MODE_DST_COLOR,
  5341. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_DST_COLOR,
  5342. GS_GRAPHICS_BLEND_MODE_SRC_ALPHA,
  5343. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_SRC_ALPHA,
  5344. GS_GRAPHICS_BLEND_MODE_DST_ALPHA,
  5345. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_DST_ALPHA,
  5346. GS_GRAPHICS_BLEND_MODE_CONSTANT_COLOR,
  5347. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_CONSTANT_COLOR,
  5348. GS_GRAPHICS_BLEND_MODE_CONSTANT_ALPHA,
  5349. GS_GRAPHICS_BLEND_MODE_ONE_MINUS_CONSTANT_ALPHA
  5350. );
  5351. /* Shader Language Type */
  5352. gs_enum_decl(gs_graphics_shader_language_type,
  5353. GS_GRAPHICS_SHADER_LANGUAGE_GLSL
  5354. );
  5355. /* Push Constant Type */
  5356. // Really don't want to handle "auto-merging" of data types
  5357. /* Uniform Type */
  5358. gs_enum_decl(gs_graphics_uniform_type,
  5359. GS_GRAPHICS_UNIFORM_FLOAT,
  5360. GS_GRAPHICS_UNIFORM_INT,
  5361. GS_GRAPHICS_UNIFORM_VEC2,
  5362. GS_GRAPHICS_UNIFORM_VEC3,
  5363. GS_GRAPHICS_UNIFORM_VEC4,
  5364. GS_GRAPHICS_UNIFORM_MAT4,
  5365. GS_GRAPHICS_UNIFORM_SAMPLER2D,
  5366. GS_GRAPHICS_UNIFORM_SAMPLER2DSHADOW,
  5367. GS_GRAPHICS_UNIFORM_USAMPLER2D,
  5368. GS_GRAPHICS_UNIFORM_SAMPLERCUBE,
  5369. GS_GRAPHICS_UNIFORM_IMAGE2D_RGBA32F,
  5370. GS_GRAPHICS_UNIFORM_BLOCK
  5371. );
  5372. /* Uniform Block Usage Type */
  5373. gs_enum_decl(gs_graphics_uniform_block_usage_type,
  5374. GS_GRAPHICS_UNIFORM_BLOCK_USAGE_STATIC, // Default of 0x00 is static
  5375. GS_GRAPHICS_UNIFORM_BLOCK_USAGE_PUSH_CONSTANT
  5376. );
  5377. /* Sampler Type */
  5378. gs_enum_decl(gs_graphics_sampler_type,
  5379. GS_GRAPHICS_SAMPLER_2D
  5380. );
  5381. /* Primitive Type */
  5382. gs_enum_decl(gs_graphics_primitive_type,
  5383. GS_GRAPHICS_PRIMITIVE_LINES,
  5384. GS_GRAPHICS_PRIMITIVE_TRIANGLES,
  5385. GS_GRAPHICS_PRIMITIVE_QUADS
  5386. );
  5387. /* Vertex Atribute Type */
  5388. gs_enum_decl(gs_graphics_vertex_attribute_type,
  5389. GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT4,
  5390. GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT3,
  5391. GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2,
  5392. GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT,
  5393. GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT4,
  5394. GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT3,
  5395. GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT2,
  5396. GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT,
  5397. GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE4,
  5398. GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE3,
  5399. GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE2,
  5400. GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE
  5401. );
  5402. /* Buffer Type */
  5403. gs_enum_decl(gs_graphics_buffer_type,
  5404. GS_GRAPHICS_BUFFER_VERTEX,
  5405. GS_GRAPHICS_BUFFER_INDEX,
  5406. GS_GRAPHICS_BUFFER_FRAME,
  5407. GS_GRAPHICS_BUFFER_UNIFORM,
  5408. GS_GRAPHICS_BUFFER_UNIFORM_CONSTANT,
  5409. GS_GRAPHICS_BUFFER_SHADER_STORAGE,
  5410. GS_GRAPHICS_BUFFER_SAMPLER
  5411. );
  5412. /* Buffer Usage Type */
  5413. gs_enum_decl(gs_graphics_buffer_usage_type,
  5414. GS_GRAPHICS_BUFFER_USAGE_STATIC,
  5415. GS_GRAPHICS_BUFFER_USAGE_STREAM,
  5416. GS_GRAPHICS_BUFFER_USAGE_DYNAMIC
  5417. );
  5418. /* Buffer Update Type */
  5419. gs_enum_decl(gs_graphics_buffer_update_type,
  5420. GS_GRAPHICS_BUFFER_UPDATE_RECREATE,
  5421. GS_GRAPHICS_BUFFER_UPDATE_SUBDATA
  5422. );
  5423. gs_enum_decl(gs_graphics_access_type,
  5424. GS_GRAPHICS_ACCESS_READ_ONLY,
  5425. GS_GRAPHICS_ACCESS_WRITE_ONLY,
  5426. GS_GRAPHICS_ACCESS_READ_WRITE
  5427. );
  5428. gs_enum_decl(gs_graphics_buffer_flags,
  5429. GS_GRAPHICS_BUFFER_FLAG_MAP_PERSISTENT,
  5430. GS_GRAPHICS_BUFFER_FLAG_MAP_COHERENT
  5431. );
  5432. //=== Texture ===//
  5433. typedef enum
  5434. {
  5435. GS_GRAPHICS_TEXTURE_2D = 0x00,
  5436. GS_GRAPHICS_TEXTURE_CUBEMAP
  5437. } gs_graphics_texture_type;
  5438. typedef enum
  5439. {
  5440. GS_GRAPHICS_TEXTURE_CUBEMAP_POSITIVE_X = 0x00,
  5441. GS_GRAPHICS_TEXTURE_CUBEMAP_NEGATIVE_X,
  5442. GS_GRAPHICS_TEXTURE_CUBEMAP_POSITIVE_Y,
  5443. GS_GRAPHICS_TEXTURE_CUBEMAP_NEGATIVE_Y,
  5444. GS_GRAPHICS_TEXTURE_CUBEMAP_POSITIVE_Z,
  5445. GS_GRAPHICS_TEXTURE_CUBEMAP_NEGATIVE_Z
  5446. } gs_graphics_cubemap_face_type;
  5447. gs_enum_decl(gs_graphics_texture_format_type,
  5448. GS_GRAPHICS_TEXTURE_FORMAT_RGBA8,
  5449. GS_GRAPHICS_TEXTURE_FORMAT_RGB8,
  5450. GS_GRAPHICS_TEXTURE_FORMAT_RG8,
  5451. GS_GRAPHICS_TEXTURE_FORMAT_R16UI,
  5452. GS_GRAPHICS_TEXTURE_FORMAT_R32UI,
  5453. GS_GRAPHICS_TEXTURE_FORMAT_R32F,
  5454. GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F,
  5455. GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F,
  5456. GS_GRAPHICS_TEXTURE_FORMAT_A8,
  5457. GS_GRAPHICS_TEXTURE_FORMAT_R8,
  5458. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8,
  5459. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16,
  5460. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24,
  5461. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F,
  5462. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8,
  5463. GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8,
  5464. GS_GRAPHICS_TEXTURE_FORMAT_STENCIL8
  5465. );
  5466. gs_enum_decl(gs_graphics_texture_wrapping_type,
  5467. GS_GRAPHICS_TEXTURE_WRAP_REPEAT,
  5468. GS_GRAPHICS_TEXTURE_WRAP_MIRRORED_REPEAT,
  5469. GS_GRAPHICS_TEXTURE_WRAP_CLAMP_TO_EDGE,
  5470. GS_GRAPHICS_TEXTURE_WRAP_CLAMP_TO_BORDER
  5471. );
  5472. gs_enum_decl(gs_graphics_texture_filtering_type,
  5473. GS_GRAPHICS_TEXTURE_FILTER_NEAREST,
  5474. GS_GRAPHICS_TEXTURE_FILTER_LINEAR
  5475. );
  5476. //=== Clear ===//
  5477. gs_enum_decl(gs_graphics_clear_flag,
  5478. GS_GRAPHICS_CLEAR_COLOR = 0x01,
  5479. GS_GRAPHICS_CLEAR_DEPTH = 0x02,
  5480. GS_GRAPHICS_CLEAR_STENCIL = 0x04,
  5481. GS_GRAPHICS_CLEAR_NONE = 0x08
  5482. );
  5483. #define GS_GRAPHICS_CLEAR_ALL\
  5484. GS_GRAPHICS_CLEAR_COLOR |\
  5485. GS_GRAPHICS_CLEAR_DEPTH |\
  5486. GS_GRAPHICS_CLEAR_STENCIL
  5487. //=== Bind Type ===//
  5488. gs_enum_decl(gs_graphics_bind_type,
  5489. GS_GRAPHICS_BIND_VERTEX_BUFFER,
  5490. GS_GRAPHICS_BIND_INDEX_BUFFER,
  5491. GS_GRAPHICS_BIND_UNIFORM_BUFFER,
  5492. GS_GRAPHICS_BIND_STORAGE_BUFFER,
  5493. GS_GRAPHICS_BIND_IMAGE_BUFFER,
  5494. GS_GRAPHICS_BIND_UNIFORM
  5495. );
  5496. /* Depth Function Type */
  5497. gs_enum_decl(gs_graphics_depth_func_type, // Default value of 0x00 means depth is disabled
  5498. GS_GRAPHICS_DEPTH_FUNC_NEVER,
  5499. GS_GRAPHICS_DEPTH_FUNC_LESS,
  5500. GS_GRAPHICS_DEPTH_FUNC_EQUAL,
  5501. GS_GRAPHICS_DEPTH_FUNC_LEQUAL,
  5502. GS_GRAPHICS_DEPTH_FUNC_GREATER,
  5503. GS_GRAPHICS_DEPTH_FUNC_NOTEQUAL,
  5504. GS_GRAPHICS_DEPTH_FUNC_GEQUAL,
  5505. GS_GRAPHICS_DEPTH_FUNC_ALWAYS
  5506. );
  5507. gs_enum_decl(gs_graphics_depth_mask_type, // Default value 0x00 means depth writing enabled
  5508. GS_GRAPHICS_DEPTH_MASK_ENABLED,
  5509. GS_GRAPHICS_DEPTH_MASK_DISABLED
  5510. );
  5511. /* Stencil Function Type */
  5512. gs_enum_decl(gs_graphics_stencil_func_type,
  5513. GS_GRAPHICS_STENCIL_FUNC_NEVER, // Default value of 0x00 means stencil is disabled
  5514. GS_GRAPHICS_STENCIL_FUNC_LESS,
  5515. GS_GRAPHICS_STENCIL_FUNC_EQUAL,
  5516. GS_GRAPHICS_STENCIL_FUNC_LEQUAL,
  5517. GS_GRAPHICS_STENCIL_FUNC_GREATER,
  5518. GS_GRAPHICS_STENCIL_FUNC_NOTEQUAL,
  5519. GS_GRAPHICS_STENCIL_FUNC_GEQUAL,
  5520. GS_GRAPHICS_STENCIL_FUNC_ALWAYS
  5521. );
  5522. /* Stencil Op Type */
  5523. gs_enum_decl(gs_graphics_stencil_op_type, // Default value of 0x00 means keep is used
  5524. GS_GRAPHICS_STENCIL_OP_KEEP,
  5525. GS_GRAPHICS_STENCIL_OP_ZERO,
  5526. GS_GRAPHICS_STENCIL_OP_REPLACE,
  5527. GS_GRAPHICS_STENCIL_OP_INCR,
  5528. GS_GRAPHICS_STENCIL_OP_INCR_WRAP,
  5529. GS_GRAPHICS_STENCIL_OP_DECR,
  5530. GS_GRAPHICS_STENCIL_OP_DECR_WRAP,
  5531. GS_GRAPHICS_STENCIL_OP_INVERT
  5532. );
  5533. /* Internal Graphics Resource Handles */
  5534. gs_handle_decl(gs_graphics_shader_t);
  5535. gs_handle_decl(gs_graphics_texture_t);
  5536. gs_handle_decl(gs_graphics_vertex_buffer_t);
  5537. gs_handle_decl(gs_graphics_index_buffer_t);
  5538. gs_handle_decl(gs_graphics_uniform_buffer_t);
  5539. gs_handle_decl(gs_graphics_storage_buffer_t);
  5540. gs_handle_decl(gs_graphics_framebuffer_t);
  5541. gs_handle_decl(gs_graphics_uniform_t);
  5542. gs_handle_decl(gs_graphics_renderpass_t);
  5543. gs_handle_decl(gs_graphics_pipeline_t);
  5544. /* Graphics Shader Source Desc */
  5545. typedef struct gs_graphics_shader_source_desc_t
  5546. {
  5547. gs_graphics_shader_stage_type type; // Shader stage type (vertex, fragment, tesselation, geometry, compute)
  5548. const char* source; // Source for shader
  5549. } gs_graphics_shader_source_desc_t;
  5550. /* Graphics Shader Desc */
  5551. typedef struct gs_graphics_shader_desc_t
  5552. {
  5553. gs_graphics_shader_source_desc_t* sources; // Array of shader source descriptions
  5554. size_t size; // Size in bytes of shader source desc array
  5555. char name[64]; // Optional (for logging and debugging mainly)
  5556. } gs_graphics_shader_desc_t;
  5557. #define GS_GRAPHICS_TEXTURE_DATA_MAX 6
  5558. /* Graphics Texture Desc */
  5559. typedef struct gs_graphics_texture_desc_t
  5560. {
  5561. gs_graphics_texture_type type;
  5562. uint32_t width; // Width of texture in texels
  5563. uint32_t height; // Height of texture in texels
  5564. uint32_t depth; // Depth of texture
  5565. void* data[GS_GRAPHICS_TEXTURE_DATA_MAX]; // Texture data to upload (can be null)
  5566. gs_graphics_texture_format_type format; // Format of texture data (rgba32, rgba8, rgba32f, r8, depth32f, etc...)
  5567. gs_graphics_texture_wrapping_type wrap_s; // Wrapping type for s axis of texture
  5568. gs_graphics_texture_wrapping_type wrap_t; // Wrapping type for t axis of texture
  5569. gs_graphics_texture_wrapping_type wrap_r; // Wrapping type for r axis of texture
  5570. gs_graphics_texture_filtering_type min_filter; // Minification filter for texture
  5571. gs_graphics_texture_filtering_type mag_filter; // Magnification filter for texture
  5572. gs_graphics_texture_filtering_type mip_filter; // Mip filter for texture
  5573. gs_vec2 offset; // Offset for updates
  5574. uint32_t num_mips; // Number of mips to generate (default 0 is disable mip generation)
  5575. struct {
  5576. uint32_t x; // X offset in texels to start read
  5577. uint32_t y; // Y offset in texels to start read
  5578. uint32_t width; // Width in texels for texture
  5579. uint32_t height; // Height in texels for texture
  5580. size_t size; // Size in bytes for data to be read
  5581. } read;
  5582. uint16_t flip_y; // Whether or not y is flipped
  5583. } gs_graphics_texture_desc_t;
  5584. /* Graphics Uniform Layout Desc */
  5585. typedef struct gs_graphics_uniform_layout_desc_t
  5586. {
  5587. gs_graphics_uniform_type type; // Type of field
  5588. char fname[64]; // Name of field (required for implicit APIs, like OpenGL/ES)
  5589. uint32_t count; // Count variable (used for arrays such as glUniformXXXv)
  5590. } gs_graphics_uniform_layout_desc_t;
  5591. /* Graphics Uniform Desc */
  5592. typedef struct gs_graphics_uniform_desc_t
  5593. {
  5594. gs_graphics_shader_stage_type stage;
  5595. char name[64]; // Name of uniform (required for OpenGL/ES, WebGL)
  5596. gs_graphics_uniform_layout_desc_t* layout; // Layout array for uniform data
  5597. size_t layout_size; // Size of uniform data in bytes
  5598. } gs_graphics_uniform_desc_t;
  5599. typedef struct gs_graphics_buffer_update_desc_t
  5600. {
  5601. gs_graphics_buffer_update_type type;
  5602. size_t offset;
  5603. } gs_graphics_buffer_update_desc_t;
  5604. /* Graphics Buffer Desc General */
  5605. typedef struct gs_graphics_buffer_base_desc_t
  5606. {
  5607. void * data;
  5608. size_t size;
  5609. gs_graphics_buffer_usage_type usage;
  5610. } gs_graphics_buffer_base_desc_t;
  5611. typedef struct gs_graphics_vertex_buffer_desc_t
  5612. {
  5613. void* data;
  5614. size_t size;
  5615. gs_graphics_buffer_usage_type usage;
  5616. gs_graphics_buffer_update_desc_t update;
  5617. } gs_graphics_vertex_buffer_desc_t;
  5618. typedef gs_graphics_vertex_buffer_desc_t gs_graphics_index_buffer_desc_t;
  5619. typedef struct gs_graphics_uniform_buffer_desc_t
  5620. {
  5621. void* data;
  5622. size_t size;
  5623. gs_graphics_buffer_usage_type usage;
  5624. const char* name;
  5625. gs_graphics_shader_stage_type stage;
  5626. gs_graphics_buffer_update_desc_t update;
  5627. } gs_graphics_uniform_buffer_desc_t;
  5628. typedef struct gs_graphics_storage_buffer_desc_t
  5629. {
  5630. void* data;
  5631. void* map;
  5632. size_t size;
  5633. char name[64];
  5634. gs_graphics_buffer_usage_type usage;
  5635. gs_graphics_access_type access;
  5636. gs_graphics_buffer_flags flags;
  5637. gs_graphics_buffer_update_desc_t update;
  5638. } gs_graphics_storage_buffer_desc_t;
  5639. typedef struct gs_graphics_framebuffer_desc_t
  5640. {
  5641. void* data;
  5642. } gs_graphics_framebuffer_desc_t;
  5643. /* Graphics Clear Action */
  5644. typedef struct gs_graphics_clear_action_t
  5645. {
  5646. gs_graphics_clear_flag flag; // Flag to be set (clear color, clear depth, clear stencil, clear all)
  5647. union
  5648. {
  5649. float color[4]; // Clear color value
  5650. float depth; // Clear depth value
  5651. int32_t stencil; // Clear stencil value
  5652. };
  5653. } gs_graphics_clear_action_t;
  5654. /* Graphics Clear Desc */
  5655. typedef struct gs_graphics_clear_desc_t
  5656. {
  5657. gs_graphics_clear_action_t* actions; // Clear action array
  5658. size_t size; // Size
  5659. } gs_graphics_clear_desc_t;
  5660. /* Graphics Render Pass Desc */
  5661. typedef struct gs_graphics_renderpass_desc_t
  5662. {
  5663. gs_handle(gs_graphics_framebuffer_t) fbo; // Default is set to invalid for backbuffer
  5664. gs_handle(gs_graphics_texture_t)* color; // Array of color attachments to be bound (useful for MRT, if supported)
  5665. size_t color_size; // Size of color attachment array
  5666. gs_handle(gs_graphics_texture_t) depth; // Depth attachment to be bound
  5667. gs_handle(gs_graphics_texture_t) stencil; // Depth attachment to be bound
  5668. } gs_graphics_renderpass_desc_t;
  5669. /*
  5670. // If you want to write to a color attachment, you have to have a frame buffer attached that isn't the backbuffer
  5671. */
  5672. typedef enum gs_graphics_vertex_data_type
  5673. {
  5674. GS_GRAPHICS_VERTEX_DATA_INTERLEAVED = 0x00,
  5675. GS_GRAPHICS_VERTEX_DATA_NONINTERLEAVED
  5676. } gs_graphics_vertex_data_type;
  5677. typedef struct gs_graphics_bind_vertex_buffer_desc_t {
  5678. gs_handle(gs_graphics_vertex_buffer_t) buffer;
  5679. size_t offset;
  5680. gs_graphics_vertex_data_type data_type;
  5681. } gs_graphics_bind_vertex_buffer_desc_t;
  5682. typedef struct gs_graphics_bind_index_buffer_desc_t {
  5683. gs_handle(gs_graphics_index_buffer_t) buffer;
  5684. } gs_graphics_bind_index_buffer_desc_t;
  5685. typedef struct gs_graphics_bind_image_buffer_desc_t {
  5686. gs_handle(gs_graphics_texture_t) tex;
  5687. uint32_t binding;
  5688. gs_graphics_access_type access;
  5689. } gs_graphics_bind_image_buffer_desc_t;
  5690. typedef struct gs_graphics_bind_uniform_buffer_desc_t {
  5691. gs_handle(gs_graphics_uniform_buffer_t) buffer;
  5692. uint32_t binding;
  5693. struct {
  5694. size_t offset; // Specify an offset for ranged binds.
  5695. size_t size; // Specify size for ranged binds.
  5696. } range;
  5697. } gs_graphics_bind_uniform_buffer_desc_t;
  5698. // All this needs to be unified...
  5699. typedef struct gs_graphics_bind_storage_buffer_desc_t {
  5700. gs_handle(gs_graphics_storage_buffer_t) buffer;
  5701. uint32_t binding;
  5702. struct {
  5703. size_t offset; // Specify an offset for ranged binds.
  5704. size_t size; // Specify size for ranged binds.
  5705. } range;
  5706. } gs_graphics_bind_storage_buffer_desc_t;
  5707. typedef struct gs_graphics_bind_uniform_desc_t {
  5708. gs_handle(gs_graphics_uniform_t) uniform;
  5709. void* data;
  5710. uint32_t binding; // Base binding for samplers?
  5711. } gs_graphics_bind_uniform_desc_t;
  5712. /* Graphics Binding Desc */
  5713. typedef struct gs_graphics_bind_desc_t
  5714. {
  5715. struct {
  5716. gs_graphics_bind_vertex_buffer_desc_t* desc; // Array of vertex buffer declarations (NULL by default)
  5717. size_t size; // Size of array in bytes (optional if only one)
  5718. } vertex_buffers;
  5719. struct {
  5720. gs_graphics_bind_index_buffer_desc_t* desc; // Array of index buffer declarations (NULL by default)
  5721. size_t size; // Size of array in bytes (optional if only one)
  5722. } index_buffers;
  5723. struct {
  5724. gs_graphics_bind_uniform_buffer_desc_t* desc; // Array of uniform buffer declarations (NULL by default)
  5725. size_t size; // Size of array in bytes (optional if only one)
  5726. } uniform_buffers;
  5727. struct {
  5728. gs_graphics_bind_uniform_desc_t* desc; // Array of uniform declarations (NULL by default)
  5729. size_t size; // Size of array in bytes (optional if one)
  5730. } uniforms;
  5731. struct {
  5732. gs_graphics_bind_image_buffer_desc_t* desc;
  5733. size_t size;
  5734. } image_buffers;
  5735. struct {
  5736. gs_graphics_bind_storage_buffer_desc_t* desc;
  5737. size_t size;
  5738. } storage_buffers;
  5739. } gs_graphics_bind_desc_t;
  5740. /* Graphics Blend State Desc */
  5741. typedef struct gs_graphics_blend_state_desc_t
  5742. {
  5743. gs_graphics_blend_equation_type func; // Equation function to use for blend ops
  5744. gs_graphics_blend_mode_type src; // Source blend mode
  5745. gs_graphics_blend_mode_type dst; // Destination blend mode
  5746. } gs_graphics_blend_state_desc_t;
  5747. /* Graphics Depth State Desc */
  5748. typedef struct gs_graphics_depth_state_desc_t
  5749. {
  5750. gs_graphics_depth_func_type func; // Function to set for depth test
  5751. gs_graphics_depth_mask_type mask; // Whether or not writing is enabled/disabled
  5752. } gs_graphics_depth_state_desc_t;
  5753. /* Graphics Stencil State Desc */
  5754. typedef struct gs_graphics_stencil_state_desc_t
  5755. {
  5756. gs_graphics_stencil_func_type func; // Function to set for stencil test
  5757. uint32_t ref; // Specifies reference val for stencil test
  5758. uint32_t comp_mask; // Specifies mask that is ANDed with both ref val and stored stencil val
  5759. uint32_t write_mask; // Specifies mask that is ANDed with both ref val and stored stencil val
  5760. gs_graphics_stencil_op_type sfail; // Action to take when stencil test fails
  5761. gs_graphics_stencil_op_type dpfail; // Action to take when stencil test passes but depth test fails
  5762. gs_graphics_stencil_op_type dppass; // Action to take when both stencil test passes and either depth passes or is not enabled
  5763. } gs_graphics_stencil_state_desc_t;
  5764. /* Graphics Raster State Desc */
  5765. typedef struct gs_graphics_raster_state_desc_t
  5766. {
  5767. gs_graphics_face_culling_type face_culling; // Face culling mode to be used (front, back, front and back)
  5768. gs_graphics_winding_order_type winding_order; // Winding order mode to be used (ccw, cw)
  5769. gs_graphics_primitive_type primitive; // Primitive type for drawing (lines, quads, triangles, triangle strip)
  5770. gs_handle(gs_graphics_shader_t) shader; // Shader to bind and use (might be in bindables later on, not sure)
  5771. size_t index_buffer_element_size; // Element size of index buffer (used for parsing internal data)
  5772. } gs_graphics_raster_state_desc_t;
  5773. /* Graphics Compute State Desc */
  5774. typedef struct gs_graphics_compute_state_desc_t
  5775. {
  5776. gs_handle(gs_graphics_shader_t) shader; // Compute shader to bind
  5777. } gs_graphics_compute_state_desc_t;
  5778. /* Graphics Vertex Attribute Desc */
  5779. typedef struct gs_graphics_vertex_attribute_desc_t {
  5780. char name[64]; // Attribute name (required for lower versions of OpenGL and ES)
  5781. gs_graphics_vertex_attribute_type format; // Format for vertex attribute
  5782. size_t stride; // Total stride of vertex layout (optional, calculated by default)
  5783. size_t offset; // Offset of this vertex from base pointer of data (optional, calaculated by default)
  5784. size_t divisor; // Used for instancing. (optional, default = 0x00 for no instancing)
  5785. uint32_t buffer_idx; // Vertex buffer to use (optional, default = 0x00)
  5786. } gs_graphics_vertex_attribute_desc_t;
  5787. /* Graphics Vertex Layout Desc */
  5788. typedef struct gs_graphics_vertex_layout_desc_t {
  5789. gs_graphics_vertex_attribute_desc_t* attrs; // Vertex attribute array
  5790. size_t size; // Size in bytes of vertex attribute array
  5791. } gs_graphics_vertex_layout_desc_t;
  5792. /* Graphics Pipeline Desc */
  5793. typedef struct gs_graphics_pipeline_desc_t
  5794. {
  5795. gs_graphics_blend_state_desc_t blend; // Blend state desc for pipeline
  5796. gs_graphics_depth_state_desc_t depth; // Depth state desc for pipeline
  5797. gs_graphics_raster_state_desc_t raster; // Raster state desc for pipeline
  5798. gs_graphics_stencil_state_desc_t stencil; // Stencil state desc for pipeline
  5799. gs_graphics_compute_state_desc_t compute; // Compute state desc for pipeline
  5800. gs_graphics_vertex_layout_desc_t layout; // Vertex layout desc for pipeline
  5801. } gs_graphics_pipeline_desc_t;
  5802. /* Graphics Draw Desc */
  5803. typedef struct gs_graphics_draw_desc_t
  5804. {
  5805. uint32_t start;
  5806. uint32_t count;
  5807. uint32_t instances;
  5808. uint32_t base_vertex;
  5809. struct {
  5810. uint32_t start;
  5811. uint32_t end;
  5812. } range;
  5813. } gs_graphics_draw_desc_t;
  5814. gs_inline gs_handle(gs_graphics_renderpass_t)
  5815. __gs_renderpass_default_impl()
  5816. {
  5817. gs_handle(gs_graphics_renderpass_t) hndl = gs_default_val();
  5818. return hndl;
  5819. }
  5820. // Convenience define for default render pass to back buffer
  5821. #define GS_GRAPHICS_RENDER_PASS_DEFAULT __gs_renderpass_default_impl()
  5822. typedef struct gs_graphics_info_t
  5823. {
  5824. uint32_t major_version;
  5825. uint32_t minor_version;
  5826. uint32_t max_texture_units;
  5827. uint32_t max_ssbo_block_size;
  5828. struct {
  5829. bool32 available;
  5830. uint32_t max_work_group_count[3];
  5831. uint32_t max_work_group_size[3];
  5832. uint32_t max_work_group_invocations;
  5833. } compute;
  5834. } gs_graphics_info_t;
  5835. /*==========================
  5836. // Graphics Interface
  5837. ==========================*/
  5838. typedef struct gs_graphics_t
  5839. {
  5840. void* user_data; // For internal use
  5841. gs_graphics_info_t info; // Used for querying by user for features
  5842. struct {
  5843. // Create
  5844. gs_handle(gs_graphics_texture_t) (* texture_create)(const gs_graphics_texture_desc_t* desc);
  5845. gs_handle(gs_graphics_uniform_t) (* uniform_create)(const gs_graphics_uniform_desc_t* desc);
  5846. gs_handle(gs_graphics_shader_t) (* shader_create)(const gs_graphics_shader_desc_t* desc);
  5847. gs_handle(gs_graphics_vertex_buffer_t) (* vertex_buffer_create)(const gs_graphics_vertex_buffer_desc_t* desc);
  5848. gs_handle(gs_graphics_index_buffer_t) (* index_buffer_create)(const gs_graphics_index_buffer_desc_t* desc);
  5849. gs_handle(gs_graphics_uniform_buffer_t) (* uniform_buffer_create)(const gs_graphics_uniform_buffer_desc_t* desc);
  5850. gs_handle(gs_graphics_storage_buffer_t) (* storage_buffer_create)(const gs_graphics_storage_buffer_desc_t* desc);
  5851. gs_handle(gs_graphics_framebuffer_t) (* framebuffer_create)(const gs_graphics_framebuffer_desc_t* desc);
  5852. gs_handle(gs_graphics_renderpass_t) (* renderpass_create)(const gs_graphics_renderpass_desc_t* desc);
  5853. gs_handle(gs_graphics_pipeline_t) (* pipeline_create)(const gs_graphics_pipeline_desc_t* desc);
  5854. // Destroy
  5855. void (* texture_destroy)(gs_handle(gs_graphics_texture_t) hndl);
  5856. void (* uniform_destroy)(gs_handle(gs_graphics_uniform_t) hndl);
  5857. void (* shader_destroy)(gs_handle(gs_graphics_shader_t) hndl);
  5858. void (* vertex_buffer_destroy)(gs_handle(gs_graphics_vertex_buffer_t) hndl);
  5859. void (* index_buffer_destroy)(gs_handle(gs_graphics_index_buffer_t) hndl);
  5860. void (* uniform_buffer_destroy)(gs_handle(gs_graphics_uniform_buffer_t) hndl);
  5861. void (* storage_buffer_destroy)(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5862. void (* framebuffer_destroy)(gs_handle(gs_graphics_framebuffer_t) hndl);
  5863. void (* renderpass_destroy)(gs_handle(gs_graphics_renderpass_t) hndl);
  5864. void (* pipeline_destroy)(gs_handle(gs_graphics_pipeline_t) hndl);
  5865. // Resource Updates (main thread only)
  5866. void (* vertex_buffer_update)(gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc);
  5867. void (* index_buffer_update)(gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc);
  5868. void (* storage_buffer_update)(gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc);
  5869. void (* texture_update)(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc);
  5870. void (* texture_read)(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc);
  5871. // Util
  5872. void* (* storage_buffer_map_get)(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5873. void* (* storage_buffer_lock)(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t sz);
  5874. void (* storage_buffer_unlock)(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5875. void (* storage_buffer_get_data)(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t stride, void* out);
  5876. // Submission (Main Thread)
  5877. void (* command_buffer_submit)(gs_command_buffer_t* cb);
  5878. } api; // Interface for stable access across .dll boundaries
  5879. } gs_graphics_t;
  5880. /*==========================
  5881. // Graphics API
  5882. ==========================*/
  5883. #define gs_graphics() gs_ctx()->graphics
  5884. // Graphics Interface Creation / Initialization / Shutdown / Destruction
  5885. GS_API_DECL gs_graphics_t* gs_graphics_create();
  5886. GS_API_DECL void gs_graphics_destroy(gs_graphics_t* graphics);
  5887. GS_API_DECL void gs_graphics_init(gs_graphics_t* graphics);
  5888. GS_API_DECL void gs_graphics_shutdown(gs_graphics_t* graphics);
  5889. // Graphics Info Object Query
  5890. GS_API_DECL gs_graphics_info_t* gs_graphics_info();
  5891. // Resource Creation
  5892. // Create
  5893. GS_API_DECL gs_handle(gs_graphics_texture_t) gs_graphics_texture_create(const gs_graphics_texture_desc_t* desc);
  5894. GS_API_DECL gs_handle(gs_graphics_uniform_t) gs_graphics_uniform_create(const gs_graphics_uniform_desc_t* desc);
  5895. GS_API_DECL gs_handle(gs_graphics_shader_t) gs_graphics_shader_create(const gs_graphics_shader_desc_t* desc);
  5896. GS_API_DECL gs_handle(gs_graphics_vertex_buffer_t) gs_graphics_vertex_buffer_create(const gs_graphics_vertex_buffer_desc_t* desc);
  5897. GS_API_DECL gs_handle(gs_graphics_index_buffer_t) gs_graphics_index_buffer_create(const gs_graphics_index_buffer_desc_t* desc);
  5898. GS_API_DECL gs_handle(gs_graphics_uniform_buffer_t) gs_graphics_uniform_buffer_create(const gs_graphics_uniform_buffer_desc_t* desc);
  5899. GS_API_DECL gs_handle(gs_graphics_storage_buffer_t) gs_graphics_storage_buffer_create(const gs_graphics_storage_buffer_desc_t* desc);
  5900. GS_API_DECL gs_handle(gs_graphics_framebuffer_t) gs_graphics_framebuffer_create(const gs_graphics_framebuffer_desc_t* desc);
  5901. GS_API_DECL gs_handle(gs_graphics_renderpass_t) gs_graphics_renderpass_create(const gs_graphics_renderpass_desc_t* desc);
  5902. GS_API_DECL gs_handle(gs_graphics_pipeline_t) gs_graphics_pipeline_create(const gs_graphics_pipeline_desc_t* desc);
  5903. // Destroy
  5904. GS_API_DECL void gs_graphics_texture_destroy(gs_handle(gs_graphics_texture_t) hndl);
  5905. GS_API_DECL void gs_graphics_uniform_destroy(gs_handle(gs_graphics_uniform_t) hndl);
  5906. GS_API_DECL void gs_graphics_shader_destroy(gs_handle(gs_graphics_shader_t) hndl);
  5907. GS_API_DECL void gs_graphics_vertex_buffer_destroy(gs_handle(gs_graphics_vertex_buffer_t) hndl);
  5908. GS_API_DECL void gs_graphics_index_buffer_destroy(gs_handle(gs_graphics_index_buffer_t) hndl);
  5909. GS_API_DECL void gs_graphics_uniform_buffer_destroy(gs_handle(gs_graphics_uniform_buffer_t) hndl);
  5910. GS_API_DECL void gs_graphics_storage_buffer_destroy(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5911. GS_API_DECL void gs_graphics_framebuffer_destroy(gs_handle(gs_graphics_framebuffer_t) hndl);
  5912. GS_API_DECL void gs_graphics_renderpass_destroy(gs_handle(gs_graphics_renderpass_t) hndl);
  5913. GS_API_DECL void gs_graphics_pipeline_destroy(gs_handle(gs_graphics_pipeline_t) hndl);
  5914. // Resource Updates (main thread only)
  5915. GS_API_DECL void gs_graphics_vertex_buffer_update(gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc);
  5916. GS_API_DECL void gs_graphics_index_buffer_update(gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc);
  5917. GS_API_DECL void gs_graphics_storage_buffer_update(gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc);
  5918. GS_API_DECL void gs_graphics_texture_update(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc);
  5919. GS_API_DECL void gs_graphics_texture_read(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc);
  5920. // Resource Queries
  5921. GS_API_DECL void gs_graphics_pipeline_desc_query(gs_handle(gs_graphics_pipeline_t) hndl, gs_graphics_pipeline_desc_t* out);
  5922. GS_API_DECL void gs_graphics_texture_desc_query(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* out);
  5923. GS_API_DECL size_t gs_graphics_uniform_size_query(gs_handle(gs_graphics_uniform_t) hndl);
  5924. // Util
  5925. GS_API_DECL void* gs_graphics_storage_buffer_map_get(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5926. GS_API_DECL void* gs_graphics_storage_buffer_lock(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t sz);
  5927. GS_API_DECL void gs_graphics_storage_buffer_unlock(gs_handle(gs_graphics_storage_buffer_t) hndl);
  5928. GS_API_DECL void gs_graphics_storage_buffer_get_data(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t stride, void* out);
  5929. // Resource In-Flight Update
  5930. GS_API_DECL void gs_graphics_texture_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc);
  5931. GS_API_DECL void gs_graphics_vertex_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc);
  5932. GS_API_DECL void gs_graphics_index_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc);
  5933. GS_API_DECL void gs_graphics_uniform_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_uniform_buffer_t) hndl, gs_graphics_uniform_buffer_desc_t* desc);
  5934. GS_API_DECL void gs_graphics_storage_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc);
  5935. // Pipeline / Pass / Bind / Draw
  5936. GS_API_DECL void gs_graphics_renderpass_begin(gs_command_buffer_t* cb, gs_handle(gs_graphics_renderpass_t) hndl);
  5937. GS_API_DECL void gs_graphics_renderpass_end(gs_command_buffer_t* cb);
  5938. GS_API_DECL void gs_graphics_set_viewport(gs_command_buffer_t* cb, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
  5939. GS_API_DECL void gs_graphics_set_view_scissor(gs_command_buffer_t* cb, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
  5940. GS_API_DECL void gs_graphics_clear(gs_command_buffer_t* cb, gs_graphics_clear_desc_t* desc);
  5941. GS_API_DECL void gs_graphics_pipeline_bind(gs_command_buffer_t* cb, gs_handle(gs_graphics_pipeline_t) hndl);
  5942. GS_API_DECL void gs_graphics_apply_bindings(gs_command_buffer_t* cb, gs_graphics_bind_desc_t* binds);
  5943. GS_API_DECL void gs_graphics_draw(gs_command_buffer_t* cb, gs_graphics_draw_desc_t* desc);
  5944. GS_API_DECL void gs_graphics_dispatch_compute(gs_command_buffer_t* cb, uint32_t num_x_groups, uint32_t num_y_groups, uint32_t num_z_groups);
  5945. // Submission (Main Thread)
  5946. #define gs_graphics_command_buffer_submit(CB) gs_graphics()->api.command_buffer_submit((CB))
  5947. #ifndef GS_NO_SHORT_NAME
  5948. typedef gs_handle(gs_graphics_shader_t) gs_shader_t;
  5949. typedef gs_handle(gs_graphics_texture_t) gs_texture_t;
  5950. typedef gs_handle(gs_graphics_renderpass_t) gs_renderpass_t;
  5951. typedef gs_handle(gs_graphics_framebuffer_t) gs_framebuffer_t;
  5952. typedef gs_handle(gs_graphics_pipeline_t) gs_pipeline_t;
  5953. typedef gs_handle(gs_graphics_vertex_buffer_t) gs_vbo_t;
  5954. typedef gs_handle(gs_graphics_index_buffer_t) gs_ibo_t;
  5955. typedef gs_handle(gs_graphics_uniform_buffer_t) gs_ubo_t;
  5956. typedef gs_handle(gs_graphics_uniform_t) gs_uniform_t;
  5957. typedef gs_handle(gs_graphics_storage_buffer_t) gs_ssbo_t;
  5958. #endif
  5959. /** @} */ // end of gs_graphics
  5960. /*==========================
  5961. // GS_ASSET_TYPES
  5962. ==========================*/
  5963. /** @addtogroup gs_util
  5964. * @{
  5965. */
  5966. // Texture
  5967. typedef struct gs_asset_texture_t
  5968. {
  5969. gs_handle(gs_graphics_texture_t) hndl;
  5970. gs_graphics_texture_desc_t desc;
  5971. } gs_asset_texture_t;
  5972. GS_API_DECL bool gs_asset_texture_load_from_file(const char* path, void* out, gs_graphics_texture_desc_t* desc, bool32_t flip_on_load, bool32_t keep_data);
  5973. GS_API_DECL bool gs_asset_texture_load_from_memory(const void* memory, size_t sz, void* out, gs_graphics_texture_desc_t* desc, bool32_t flip_on_load, bool32_t keep_data);
  5974. // Font
  5975. typedef struct gs_baked_char_t
  5976. {
  5977. uint32_t codepoint;
  5978. uint16_t x0, y0, x1, y1;
  5979. float xoff, yoff, advance;
  5980. uint32_t width, height;
  5981. } gs_baked_char_t;
  5982. typedef struct gs_asset_font_t
  5983. {
  5984. void* font_info;
  5985. gs_baked_char_t glyphs[96];
  5986. gs_asset_texture_t texture;
  5987. float ascent;
  5988. float descent;
  5989. float line_gap;
  5990. } gs_asset_font_t;
  5991. GS_API_DECL bool gs_asset_font_load_from_file(const char* path, void* out, uint32_t point_size);
  5992. GS_API_DECL bool gs_asset_font_load_from_memory(const void* memory, size_t sz, void* out, uint32_t point_size);
  5993. GS_API_DECL gs_vec2 gs_asset_font_text_dimensions(const gs_asset_font_t* font, const char* text, int32_t len);
  5994. GS_API_DECL gs_vec2 gs_asset_font_text_dimensions_ex(const gs_asset_font_t* fp, const char* text, int32_t len, bool32_t include_past_baseline);
  5995. GS_API_DECL float gs_asset_font_max_height(const gs_asset_font_t* font);
  5996. // Audio
  5997. typedef struct gs_asset_audio_t
  5998. {
  5999. gs_handle(gs_audio_source_t) hndl;
  6000. } gs_asset_audio_t;
  6001. GS_API_DECL bool gs_asset_audio_load_from_file(const char* path, void* out);
  6002. // Mesh
  6003. gs_enum_decl(gs_asset_mesh_attribute_type,
  6004. GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION,
  6005. GS_ASSET_MESH_ATTRIBUTE_TYPE_NORMAL,
  6006. GS_ASSET_MESH_ATTRIBUTE_TYPE_TANGENT,
  6007. GS_ASSET_MESH_ATTRIBUTE_TYPE_JOINT,
  6008. GS_ASSET_MESH_ATTRIBUTE_TYPE_WEIGHT,
  6009. GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD,
  6010. GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR,
  6011. GS_ASSET_MESH_ATTRIBUTE_TYPE_UINT
  6012. );
  6013. typedef struct gs_asset_mesh_layout_t {
  6014. gs_asset_mesh_attribute_type type; // Type of attribute
  6015. uint32_t idx; // Optional index (for joint/weight/texcoord/color)
  6016. } gs_asset_mesh_layout_t;
  6017. typedef struct gs_asset_mesh_decl_t
  6018. {
  6019. gs_asset_mesh_layout_t* layout; // Mesh attribute layout array
  6020. size_t layout_size; // Size of mesh attribute layout array in bytes
  6021. size_t index_buffer_element_size; // Size of index data size in bytes
  6022. } gs_asset_mesh_decl_t;
  6023. typedef struct gs_asset_mesh_primitive_t
  6024. {
  6025. gs_handle(gs_graphics_vertex_buffer_t) vbo;
  6026. gs_handle(gs_graphics_index_buffer_t) ibo;
  6027. uint32_t count;
  6028. } gs_asset_mesh_primitive_t;
  6029. typedef struct gs_asset_mesh_t
  6030. {
  6031. gs_dyn_array(gs_asset_mesh_primitive_t) primitives;
  6032. } gs_asset_mesh_t;
  6033. // Structured/packed raw mesh data
  6034. typedef struct gs_asset_mesh_raw_data_t
  6035. {
  6036. uint32_t prim_count;
  6037. size_t* vertex_sizes;
  6038. size_t* index_sizes;
  6039. void** vertices;
  6040. void** indices;
  6041. } gs_asset_mesh_raw_data_t;
  6042. GS_API_DECL bool gs_asset_mesh_load_from_file(const char* path, void* out, gs_asset_mesh_decl_t* decl, void* data_out, size_t data_size);
  6043. GS_API_DECL bool gs_util_load_gltf_data_from_file(const char* path, gs_asset_mesh_decl_t* decl, gs_asset_mesh_raw_data_t** out, uint32_t* mesh_count);
  6044. GS_API_DECL bool gs_util_load_gltf_data_from_memory(const void* memory, size_t sz, gs_asset_mesh_decl_t* decl, gs_asset_mesh_raw_data_t** out, uint32_t* mesh_count);
  6045. /** @} */ // end of gs_util
  6046. // Material
  6047. // How to do this? Materials really are utility types...
  6048. // So should they be relegated to a utility file?
  6049. /*
  6050. gs_util_material?
  6051. */
  6052. // Pipeline
  6053. // Uniform
  6054. /*
  6055. // Could pass in a mesh decl? Then it'll just give you back packed vertex/index data for each primitive?
  6056. GS_API_DECL gs_util_load_gltf_from_file(const char* path, gs_asset_mesh_decl_t* decl, uint32_t* primitive_count, void*** verticies, size_t** vertex_sizes, void*** indices, size_t** index_sizes);
  6057. To use:
  6058. // For primitives
  6059. uint32_t prim_count = 0;
  6060. size_t* vertex_sizes = NULL;
  6061. size_t* index_sizes = NULL;
  6062. float** vertices = NULL;
  6063. uint32_t** indices = NULL;
  6064. gs_asset_mesh_raw_data_t data = {};
  6065. gs_util_load_gltf_from_file("path", &decl, &data);
  6066. */
  6067. /*==========================
  6068. // GS_ENGINE / GS_APP
  6069. ==========================*/
  6070. /** @defgroup gs_app App/Engine
  6071. * Gunslinger App/Engine
  6072. * @{
  6073. */
  6074. // Application descriptor for user application
  6075. typedef struct gs_app_desc_t
  6076. {
  6077. void (* init)();
  6078. void (* update)();
  6079. void (* shutdown)();
  6080. gs_platform_window_desc_t window;
  6081. bool32 is_running;
  6082. bool32 debug_gfx;
  6083. void* user_data;
  6084. int32_t argc;
  6085. char** argv;
  6086. // Platform specific data
  6087. #ifdef GS_PLATFORM_ANDROID
  6088. struct {
  6089. void* activity;
  6090. const char* internal_data_path;
  6091. } android;
  6092. #endif
  6093. } gs_app_desc_t;
  6094. /*
  6095. Game Context:
  6096. * This is the main context for the gunslinger framework. Holds pointers to
  6097. all interfaces registered with the framework, including the description
  6098. for your application.
  6099. */
  6100. typedef struct gs_context_t
  6101. {
  6102. gs_platform_t* platform;
  6103. gs_graphics_t* graphics;
  6104. gs_audio_t* audio;
  6105. gs_app_desc_t app;
  6106. gs_os_api_t os;
  6107. gs_atomic_int_t lock;
  6108. } gs_context_t;
  6109. typedef struct gs_t
  6110. {
  6111. gs_context_t ctx;
  6112. void (* shutdown)();
  6113. } gs_t;
  6114. /* Desc */
  6115. GS_API_DECL gs_t*
  6116. gs_create(gs_app_desc_t app_desc);
  6117. /* Desc */
  6118. GS_API_DECL void
  6119. gs_destroy();
  6120. /* Desc */
  6121. GS_API_DECL gs_t*
  6122. gs_instance();
  6123. /* Desc */
  6124. GS_API_DECL void
  6125. gs_set_instance(gs_t* gs);
  6126. /* Desc */
  6127. GS_API_DECL gs_context_t*
  6128. gs_ctx();
  6129. /* Desc */
  6130. GS_API_DECL gs_app_desc_t*
  6131. gs_app();
  6132. /* Desc */
  6133. GS_API_DECL void
  6134. gs_frame();
  6135. /* Desc */
  6136. GS_API_DECL void
  6137. gs_quit();
  6138. /* Desc */
  6139. GS_API_DECL gs_app_desc_t
  6140. gs_main(int32_t argc, char** argv);
  6141. #define gs_subsystem(__T)\
  6142. (gs_instance()->ctx.__T)
  6143. #define gs_user_data(__T)\
  6144. (__T*)(gs_instance()->ctx.app.user_data)
  6145. /** @} */ // end of gs_app
  6146. /*==================================================================================================================================
  6147. // ===== Gunslinger Implementation ============================================================================================== //
  6148. ==================================================================================================================================*/
  6149. #ifdef GS_IMPL
  6150. /*=============================
  6151. // GS_PLATFORM
  6152. =============================*/
  6153. // Default provided platform implementations (these will be removed eventually)
  6154. #ifndef GS_PLATFORM_IMPL_CUSTOM
  6155. #if (defined GS_PLATFORM_WIN || defined GS_PLATFORM_APPLE || defined GS_PLATFORM_LINUX)
  6156. #define GS_PLATFORM_IMPL_GLFW
  6157. #elif (defined GS_PLATFORM_WEB)
  6158. #define GS_PLATFORM_IMPL_EMSCRIPTEN
  6159. #elif (defined GS_PLATFORM_ANDROID)
  6160. #define GS_PLATFORM_IMPL_ANDROID
  6161. #endif
  6162. #endif
  6163. #ifdef GS_PLATFORM_IMPL_FILE
  6164. #include GS_PLATFORM_IMPL_FILE
  6165. #endif
  6166. #include "impl/gs_platform_impl.h"
  6167. /*=============================
  6168. // GS_GRAPHICS
  6169. =============================*/
  6170. #ifndef GS_GRAPHICS_IMPL_CUSTOM
  6171. #if (defined GS_PLATFORM_WIN || defined GS_PLATFORM_APPLE || defined GS_PLATFORM_LINUX)
  6172. #define GS_GRAPHICS_IMPL_OPENGL_CORE
  6173. #else
  6174. #define GS_GRAPHICS_IMPL_OPENGL_ES
  6175. #endif
  6176. #endif
  6177. #include "impl/gs_graphics_impl.h"
  6178. // Resource Creation
  6179. GS_API_DECL gs_handle(gs_graphics_texture_t)
  6180. gs_graphics_texture_create(const gs_graphics_texture_desc_t* desc)
  6181. {
  6182. return gs_graphics()->api.texture_create(desc);
  6183. }
  6184. GS_API_DECL gs_handle(gs_graphics_uniform_t)
  6185. gs_graphics_uniform_create(const gs_graphics_uniform_desc_t* desc)
  6186. {
  6187. return gs_graphics()->api.uniform_create(desc);
  6188. }
  6189. GS_API_DECL gs_handle(gs_graphics_shader_t)
  6190. gs_graphics_shader_create(const gs_graphics_shader_desc_t* desc)
  6191. {
  6192. return gs_graphics()->api.shader_create(desc);
  6193. }
  6194. GS_API_DECL gs_handle(gs_graphics_vertex_buffer_t)
  6195. gs_graphics_vertex_buffer_create(const gs_graphics_vertex_buffer_desc_t* desc)
  6196. {
  6197. return gs_graphics()->api.vertex_buffer_create(desc);
  6198. }
  6199. GS_API_DECL gs_handle(gs_graphics_index_buffer_t)
  6200. gs_graphics_index_buffer_create(const gs_graphics_index_buffer_desc_t* desc)
  6201. {
  6202. return gs_graphics()->api.index_buffer_create(desc);
  6203. }
  6204. GS_API_DECL gs_handle(gs_graphics_uniform_buffer_t)
  6205. gs_graphics_uniform_buffer_create(const gs_graphics_uniform_buffer_desc_t* desc)
  6206. {
  6207. return gs_graphics()->api.uniform_buffer_create(desc);
  6208. }
  6209. GS_API_DECL gs_handle(gs_graphics_storage_buffer_t)
  6210. gs_graphics_storage_buffer_create(const gs_graphics_storage_buffer_desc_t* desc)
  6211. {
  6212. return gs_graphics()->api.storage_buffer_create(desc);
  6213. }
  6214. GS_API_DECL gs_handle(gs_graphics_framebuffer_t)
  6215. gs_graphics_framebuffer_create(const gs_graphics_framebuffer_desc_t* desc)
  6216. {
  6217. return gs_graphics()->api.framebuffer_create(desc);
  6218. }
  6219. GS_API_DECL gs_handle(gs_graphics_renderpass_t)
  6220. gs_graphics_renderpass_create(const gs_graphics_renderpass_desc_t* desc)
  6221. {
  6222. return gs_graphics()->api.renderpass_create(desc);
  6223. }
  6224. GS_API_DECL gs_handle(gs_graphics_pipeline_t)
  6225. gs_graphics_pipeline_create(const gs_graphics_pipeline_desc_t* desc)
  6226. {
  6227. return gs_graphics()->api.pipeline_create(desc);
  6228. }
  6229. // Destroy
  6230. GS_API_DECL void
  6231. gs_graphics_texture_destroy(gs_handle(gs_graphics_texture_t) hndl)
  6232. {
  6233. gs_graphics()->api.texture_destroy(hndl);
  6234. }
  6235. GS_API_DECL void
  6236. gs_graphics_uniform_destroy(gs_handle(gs_graphics_uniform_t) hndl)
  6237. {
  6238. gs_graphics()->api.uniform_destroy(hndl);
  6239. }
  6240. GS_API_DECL void
  6241. gs_graphics_shader_destroy(gs_handle(gs_graphics_shader_t) hndl)
  6242. {
  6243. gs_graphics()->api.shader_destroy(hndl);
  6244. }
  6245. GS_API_DECL void
  6246. gs_graphics_vertex_buffer_destroy(gs_handle(gs_graphics_vertex_buffer_t) hndl)
  6247. {
  6248. gs_graphics()->api.vertex_buffer_destroy(hndl);
  6249. }
  6250. GS_API_DECL void
  6251. gs_graphics_index_buffer_destroy(gs_handle(gs_graphics_index_buffer_t) hndl)
  6252. {
  6253. gs_graphics()->api.index_buffer_destroy(hndl);
  6254. }
  6255. GS_API_DECL void
  6256. gs_graphics_uniform_buffer_destroy(gs_handle(gs_graphics_uniform_buffer_t) hndl)
  6257. {
  6258. gs_graphics()->api.uniform_buffer_destroy(hndl);
  6259. }
  6260. GS_API_DECL void
  6261. gs_graphics_storage_buffer_destroy(gs_handle(gs_graphics_storage_buffer_t) hndl)
  6262. {
  6263. gs_graphics()->api.storage_buffer_destroy(hndl);
  6264. }
  6265. GS_API_DECL void
  6266. gs_graphics_framebuffer_destroy(gs_handle(gs_graphics_framebuffer_t) hndl)
  6267. {
  6268. gs_graphics()->api.framebuffer_destroy(hndl);
  6269. }
  6270. GS_API_DECL void
  6271. gs_graphics_renderpass_destroy(gs_handle(gs_graphics_renderpass_t) hndl)
  6272. {
  6273. gs_graphics()->api.renderpass_destroy(hndl);
  6274. }
  6275. GS_API_DECL void
  6276. gs_graphics_pipeline_destroy(gs_handle(gs_graphics_pipeline_t) hndl)
  6277. {
  6278. gs_graphics()->api.pipeline_destroy(hndl);
  6279. }
  6280. // Resource Updates (main thread only)
  6281. GS_API_DECL void
  6282. gs_graphics_vertex_buffer_update(gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc)
  6283. {
  6284. gs_graphics()->api.vertex_buffer_update(hndl, desc);
  6285. }
  6286. GS_API_DECL void
  6287. gs_graphics_index_buffer_update(gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc)
  6288. {
  6289. gs_graphics()->api.index_buffer_update(hndl, desc);
  6290. }
  6291. GS_API_DECL void
  6292. gs_graphics_storage_buffer_update(gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc)
  6293. {
  6294. gs_graphics()->api.storage_buffer_update(hndl, desc);
  6295. }
  6296. GS_API_DECL void
  6297. gs_graphics_texture_update(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc)
  6298. {
  6299. gs_graphics()->api.texture_update(hndl, desc);
  6300. }
  6301. GS_API_DECL void
  6302. gs_graphics_texture_read(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc)
  6303. {
  6304. return gs_graphics()->api.texture_read(hndl, desc);
  6305. }
  6306. GS_API_DECL void*
  6307. gs_graphics_storage_buffer_map_get(gs_handle(gs_graphics_storage_buffer_t) hndl)
  6308. {
  6309. return gs_graphics()->api.storage_buffer_map_get(hndl);
  6310. }
  6311. GS_API_DECL void
  6312. gs_graphics_storage_buffer_unlock(gs_handle(gs_graphics_storage_buffer_t) hndl)
  6313. {
  6314. return gs_graphics()->api.storage_buffer_unlock(hndl);
  6315. }
  6316. GS_API_DECL void*
  6317. gs_graphics_storage_buffer_lock(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t sz)
  6318. {
  6319. return gs_graphics()->api.storage_buffer_lock(hndl, offset, sz);
  6320. }
  6321. GS_API_DECL void
  6322. gs_graphics_storage_buffer_get_data(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t sz, void* out)
  6323. {
  6324. return gs_graphics()->api.storage_buffer_get_data(hndl, offset, sz, out);
  6325. }
  6326. /*=============================
  6327. // GS_AUDIO
  6328. =============================*/
  6329. #ifndef GS_AUDIO_IMPL_CUSTOM
  6330. #define GS_AUDIO_IMPL_MINIAUDIO
  6331. #endif
  6332. #include "impl/gs_audio_impl.h"
  6333. /*==========================
  6334. // GS_OS
  6335. ==========================*/
  6336. GS_API_DECL
  6337. void* _gs_malloc_init_impl(size_t sz)
  6338. {
  6339. void* data = gs_malloc(sz);
  6340. memset(data, 0, sz);
  6341. return data;
  6342. }
  6343. GS_API_DECL gs_os_api_t
  6344. gs_os_api_new_default()
  6345. {
  6346. gs_os_api_t os = gs_default_val();
  6347. os.malloc = malloc;
  6348. os.malloc_init = _gs_malloc_init_impl;
  6349. os.free = free;
  6350. os.realloc = realloc;
  6351. os.calloc = calloc;
  6352. os.strdup = strdup;
  6353. #ifdef GS_PLATFORM_WIN
  6354. os.alloca = malloc;
  6355. #else
  6356. os.alloca = malloc;
  6357. #endif
  6358. return os;
  6359. }
  6360. /*========================
  6361. // gs_byte_buffer
  6362. ========================*/
  6363. void gs_byte_buffer_init(gs_byte_buffer_t* buffer)
  6364. {
  6365. buffer->data = (uint8_t*)gs_malloc(GS_BYTE_BUFFER_DEFAULT_CAPCITY);
  6366. buffer->capacity = GS_BYTE_BUFFER_DEFAULT_CAPCITY;
  6367. buffer->size = 0;
  6368. buffer->position = 0;
  6369. }
  6370. gs_byte_buffer_t gs_byte_buffer_new()
  6371. {
  6372. gs_byte_buffer_t buffer;
  6373. gs_byte_buffer_init(&buffer);
  6374. return buffer;
  6375. }
  6376. void gs_byte_buffer_free(gs_byte_buffer_t* buffer)
  6377. {
  6378. if (buffer && buffer->data) {
  6379. gs_free(buffer->data);
  6380. }
  6381. }
  6382. void gs_byte_buffer_clear(gs_byte_buffer_t* buffer)
  6383. {
  6384. buffer->size = 0;
  6385. buffer->position = 0;
  6386. }
  6387. bool gs_byte_buffer_empty(gs_byte_buffer_t* buffer)
  6388. {
  6389. return (buffer->size == 0);
  6390. }
  6391. size_t gs_byte_buffer_size(gs_byte_buffer_t* buffer)
  6392. {
  6393. return buffer->size;
  6394. }
  6395. void gs_byte_buffer_resize(gs_byte_buffer_t* buffer, size_t sz)
  6396. {
  6397. if (!buffer) return;
  6398. uint8_t* data = (uint8_t*)gs_realloc(buffer->data, sz);
  6399. if (data == NULL) {
  6400. gs_log_warning("gs_byte_buffer_resize: realloc failed for size %zu. Keeping old buffer.", sz);
  6401. return;
  6402. }
  6403. buffer->data = data;
  6404. buffer->capacity = (uint32_t)sz;
  6405. }
  6406. void gs_byte_buffer_copy_contents(gs_byte_buffer_t* dst, gs_byte_buffer_t* src)
  6407. {
  6408. gs_byte_buffer_seek_to_beg(dst);
  6409. gs_byte_buffer_seek_to_beg(src);
  6410. gs_byte_buffer_write_bulk(dst, src->data, src->size);
  6411. }
  6412. void gs_byte_buffer_seek_to_beg(gs_byte_buffer_t* buffer)
  6413. {
  6414. buffer->position = 0;
  6415. }
  6416. void gs_byte_buffer_seek_to_end(gs_byte_buffer_t* buffer)
  6417. {
  6418. buffer->position = buffer->size;
  6419. }
  6420. void gs_byte_buffer_advance_position(gs_byte_buffer_t* buffer, size_t sz)
  6421. {
  6422. buffer->position += (uint32_t)sz;
  6423. }
  6424. void gs_byte_buffer_write_bulk(gs_byte_buffer_t* buffer, void* src, size_t size)
  6425. {
  6426. if (!buffer || !src || !size) return;
  6427. // Check for necessary resize
  6428. size_t total_write_size = buffer->position + size;
  6429. if (total_write_size >= (size_t)buffer->capacity)
  6430. {
  6431. size_t capacity = buffer->capacity * 2;
  6432. while(capacity <= total_write_size)
  6433. {
  6434. capacity *= 2;
  6435. }
  6436. uint8_t* old_data = buffer->data;
  6437. gs_byte_buffer_resize(buffer, capacity);
  6438. if (buffer->data == NULL) {
  6439. buffer->data = old_data;
  6440. return;
  6441. }
  6442. }
  6443. // Safety check before memcpy
  6444. if (!buffer->data) return;
  6445. // memcpy data
  6446. memcpy((buffer->data + buffer->position), src, size);
  6447. buffer->size += (uint32_t)size;
  6448. buffer->position += (uint32_t)size;
  6449. }
  6450. void gs_byte_buffer_read_bulk(gs_byte_buffer_t* buffer, void** dst, size_t size)
  6451. {
  6452. memcpy(*dst, (buffer->data + buffer->position), size);
  6453. buffer->position += (uint32_t)size;
  6454. }
  6455. void gs_byte_buffer_write_str(gs_byte_buffer_t* buffer, const char* str)
  6456. {
  6457. // Write size of string
  6458. uint32_t str_len = gs_string_length(str);
  6459. gs_byte_buffer_write(buffer, uint16_t, str_len);
  6460. size_t i;
  6461. for (i = 0; i < str_len; ++i)
  6462. {
  6463. gs_byte_buffer_write(buffer, uint8_t, str[i]);
  6464. }
  6465. }
  6466. void gs_byte_buffer_read_str(gs_byte_buffer_t* buffer, char* str)
  6467. {
  6468. // Read in size of string from buffer
  6469. uint16_t sz;
  6470. gs_byte_buffer_read(buffer, uint16_t, &sz);
  6471. uint32_t i;
  6472. for (i = 0; i < sz; ++i)
  6473. {
  6474. gs_byte_buffer_read(buffer, uint8_t, &str[i]);
  6475. }
  6476. str[i] = '\0';
  6477. }
  6478. gs_result
  6479. gs_byte_buffer_write_to_file
  6480. (
  6481. gs_byte_buffer_t* buffer,
  6482. const char* output_path
  6483. )
  6484. {
  6485. return gs_platform_write_file_contents(output_path, "wb", buffer->data, buffer->size);
  6486. }
  6487. gs_result
  6488. gs_byte_buffer_read_from_file
  6489. (
  6490. gs_byte_buffer_t* buffer,
  6491. const char* file_path
  6492. )
  6493. {
  6494. if (!buffer) return GS_RESULT_FAILURE;
  6495. if (buffer->data) {
  6496. gs_byte_buffer_free(buffer);
  6497. }
  6498. buffer->data = (u8*)gs_platform_read_file_contents(file_path, "rb", (size_t*)&buffer->size);
  6499. if (!buffer->data) {
  6500. gs_assert(false);
  6501. return GS_RESULT_FAILURE;
  6502. }
  6503. buffer->position = 0;
  6504. buffer->capacity = buffer->size;
  6505. return GS_RESULT_SUCCESS;
  6506. }
  6507. GS_API_DECL void gs_byte_buffer_memset(gs_byte_buffer_t* buffer, uint8_t val)
  6508. {
  6509. memset(buffer->data, val, buffer->capacity);
  6510. }
  6511. /*========================
  6512. // Dynamic Array
  6513. ========================*/
  6514. GS_API_DECL void*
  6515. gs_dyn_array_resize_impl(void* arr, size_t sz, size_t amount)
  6516. {
  6517. size_t capacity;
  6518. if (arr) {
  6519. capacity = amount;
  6520. } else {
  6521. capacity = 0;
  6522. }
  6523. // Create new gs_dyn_array with just the header information
  6524. gs_dyn_array* data = (gs_dyn_array*)gs_realloc(arr ? gs_dyn_array_head(arr) : 0, capacity * sz + sizeof(gs_dyn_array));
  6525. if (data) {
  6526. if (!arr) {
  6527. data->size = 0;
  6528. }
  6529. data->capacity = (int32_t)capacity;
  6530. return ((int32_t*)data + 2);
  6531. }
  6532. return NULL;
  6533. }
  6534. GS_API_DECL void**
  6535. gs_dyn_array_init(void** arr, size_t val_len)
  6536. {
  6537. if (*arr == NULL) {
  6538. gs_dyn_array* data = (gs_dyn_array*)gs_malloc(val_len + sizeof(gs_dyn_array)); // Allocate capacity of one
  6539. data->size = 0;
  6540. data->capacity = 1;
  6541. *arr = ((int32_t*)data + 2);
  6542. }
  6543. return arr;
  6544. }
  6545. GS_API_DECL void
  6546. gs_dyn_array_push_data(void** arr, void* val, size_t val_len)
  6547. {
  6548. if (*arr == NULL) {
  6549. gs_dyn_array_init(arr, val_len);
  6550. }
  6551. if (gs_dyn_array_need_grow(*arr, 1))
  6552. {
  6553. int32_t capacity = gs_dyn_array_capacity(*arr) * 2;
  6554. // Create new gs_dyn_array with just the header information
  6555. gs_dyn_array* data = (gs_dyn_array*)gs_realloc(gs_dyn_array_head(*arr), capacity * val_len + sizeof(gs_dyn_array));
  6556. if (data) {
  6557. data->capacity = capacity;
  6558. *arr = ((int32_t*)data + 2);
  6559. }
  6560. }
  6561. size_t offset = gs_dyn_array_size(*arr);
  6562. memcpy(((uint8_t*)(*arr)) + offset * val_len, val, val_len);
  6563. gs_dyn_array_head(*arr)->size++;
  6564. }
  6565. /*========================
  6566. // Hash Table
  6567. ========================*/
  6568. GS_API_DECL void
  6569. __gs_hash_table_init_impl(void** ht, size_t sz)
  6570. {
  6571. *ht = gs_malloc(sz);
  6572. }
  6573. /*========================
  6574. // Hash Set
  6575. ========================*/
  6576. GS_API_DECL void
  6577. __gs_hash_set_init_impl(void** hs, size_t sz)
  6578. {
  6579. *hs = gs_malloc(sz);
  6580. }
  6581. /*========================
  6582. // Slot Array
  6583. ========================*/
  6584. GS_API_DECL void**
  6585. gs_slot_array_init(void** sa, size_t sz)
  6586. {
  6587. if (*sa == NULL) {
  6588. *sa = gs_malloc(sz);
  6589. memset(*sa, 0, sz);
  6590. return sa;
  6591. }
  6592. else {
  6593. return NULL;
  6594. }
  6595. }
  6596. /*========================
  6597. // Slot Map
  6598. ========================*/
  6599. GS_API_DECL void**
  6600. gs_slot_map_init(void** sm)
  6601. {
  6602. if (*sm == NULL) {
  6603. (*sm) = gs_malloc(sizeof(size_t) * 2);\
  6604. memset((*sm), 0, sizeof(size_t) * 2);\
  6605. return sm;
  6606. }
  6607. return NULL;
  6608. }
  6609. /*========================
  6610. // Priotity Queue
  6611. ========================*/
  6612. GS_API_DECL void**
  6613. gs_pqueue_init(void** pq, size_t sz)
  6614. {
  6615. if (*pq == NULL) {
  6616. (*pq) = gs_malloc(sz);
  6617. memset((*pq), 0, sz);
  6618. return pq;
  6619. }
  6620. return NULL;
  6621. }
  6622. GS_API_PRIVATE void
  6623. __gs_pqueue_pop_internal(void** pqueue, void* tmp, void** data, int32_t* priority, int32_t pq_sz, size_t d_sz)
  6624. {
  6625. // TODO(): Remove these checks for perf
  6626. if (!pqueue || !tmp || !data || !priority || !pq_sz || !d_sz) return;
  6627. #define __SWP(__I0, __I1)\
  6628. do {\
  6629. {\
  6630. size_t i0 = d_sz * (__I0);\
  6631. size_t i1 = d_sz * (__I1);\
  6632. uint8_t** d = (uint8_t**)data;\
  6633. memcpy(tmp, ((char*)*(d)) + i0, d_sz);\
  6634. memcpy(((char*)(*d)) + i0, ((char*)(*d)) + i1, d_sz);\
  6635. memcpy(((char*)(*d)) + i1, tmp, d_sz);\
  6636. }\
  6637. {\
  6638. int32_t t = 0;\
  6639. uint32_t i0 = (__I0);\
  6640. uint32_t i1 = (__I1);\
  6641. uint32_t sz = sizeof(int32_t);\
  6642. memcpy(&t, ((char*)((priority)) + i0), sz);\
  6643. memcpy((char*)((priority) + i0), (char*)((priority) + i1), sz);\
  6644. memcpy((char*)((priority) + i1), &t, sz);\
  6645. }\
  6646. } while (0)
  6647. // Swap elements internal
  6648. __SWP(0, pq_sz - 1);
  6649. // Work down list from top until priority is sorted
  6650. // THIS PART IS FUCKED
  6651. // return;
  6652. int32_t i = 0;
  6653. int32_t c = 0;
  6654. int32_t nwsz = pq_sz - 1; // Right up until the last item we removed
  6655. int32_t psz = gs_dyn_array_size(priority) - 1;
  6656. // int32_t* pa = priority;
  6657. for (int32_t i = 0; gs_pqueue_child_left_idx(i) < psz; i = c)
  6658. {
  6659. // Set child to smaller of two
  6660. c = gs_pqueue_child_left_idx(i);
  6661. // if (c >= psz) break;
  6662. // Set to right child if valid and less priority
  6663. if ((c + 1) < psz && priority[c + 1] < priority[c]) {
  6664. c++;
  6665. }
  6666. // Check to swp, if necessary
  6667. if (priority[i] > priority[c]) {
  6668. __SWP(i, c);
  6669. }
  6670. // Otherwise, we're done
  6671. else
  6672. {
  6673. break;
  6674. }
  6675. }
  6676. // gs_println("P: %d", priority[nwsz - 1]);
  6677. }
  6678. /*========================
  6679. // GS_MEMORY
  6680. ========================*/
  6681. // typedef struct gs_memory_block_t {
  6682. // uint8_t* data;
  6683. // size_t size;
  6684. // } gs_memory_block_t;
  6685. GS_API_DECL gs_memory_block_t gs_memory_block_new(size_t sz)
  6686. {
  6687. gs_memory_block_t mem = gs_default_val();
  6688. mem.data = (uint8_t*)gs_malloc(sz);
  6689. memset(mem.data, 0, sz);
  6690. mem.size = sz;
  6691. return mem;
  6692. }
  6693. GS_API_DECL void gs_memory_block_free(gs_memory_block_t* mem)
  6694. {
  6695. gs_assert(mem);
  6696. gs_assert(mem->data);
  6697. gs_free(mem->data);
  6698. mem->data = NULL;
  6699. mem->size = 0;
  6700. }
  6701. // Modified from: https://github.com/mtrebi/memory-allocators/blob/master/includes/Utils.h
  6702. GS_API_DECL size_t gs_memory_calc_padding(size_t base_address, size_t alignment)
  6703. {
  6704. size_t mult = (base_address / alignment) + 1;
  6705. size_t aligned_addr = mult * alignment;
  6706. size_t padding = aligned_addr - base_address;
  6707. return padding;
  6708. }
  6709. GS_API_DECL size_t gs_memory_calc_padding_w_header(size_t base_address, size_t alignment, size_t header_sz)
  6710. {
  6711. size_t padding = gs_memory_calc_padding(base_address, alignment);
  6712. size_t needed_space = header_sz;
  6713. if (padding < needed_space) {
  6714. needed_space -= padding;
  6715. if (needed_space % alignment > 0) {
  6716. padding += alignment * (1 + (needed_space / alignment));
  6717. } else {
  6718. padding += alignment * (needed_space / alignment);
  6719. }
  6720. }
  6721. return padding;
  6722. }
  6723. /*================================================================================
  6724. // Linear Allocator
  6725. ================================================================================*/
  6726. // typedef struct gs_linear_allocator_t {
  6727. // uint8_t* memory;
  6728. // size_t total_size;
  6729. // size_t offset;
  6730. // } gs_linear_allocator_t;
  6731. GS_API_DECL gs_linear_allocator_t gs_linear_allocator_new(size_t sz)
  6732. {
  6733. gs_linear_allocator_t la = gs_default_val();
  6734. la.memory = (uint8_t*)gs_malloc(sz);
  6735. memset(la.memory, 0, sz);
  6736. la.offset = 0;
  6737. la.total_size = sz;
  6738. return la;
  6739. }
  6740. GS_API_DECL void gs_linear_allocator_free(gs_linear_allocator_t* la)
  6741. {
  6742. gs_assert(la);
  6743. gs_assert(la->memory);
  6744. gs_free(la->memory);
  6745. la->memory = NULL;
  6746. }
  6747. GS_API_DECL void* gs_linear_allocator_allocate(gs_linear_allocator_t* la, size_t sz, size_t alignment)
  6748. {
  6749. gs_assert(la);
  6750. size_t padding = 0;
  6751. size_t padding_address = 0;
  6752. size_t cur_address = (size_t)la->memory + la->offset;
  6753. // Calculate alignment required
  6754. if (alignment != 0 && la->offset % alignment != 0) {
  6755. padding = gs_memory_calc_padding(cur_address, alignment);
  6756. }
  6757. // Cannot allocate (not enough memory available)
  6758. if (la->offset + padding + sz > la->total_size) {
  6759. return NULL;
  6760. }
  6761. // Allocate and return pointer
  6762. la->offset += padding;
  6763. size_t next_address = cur_address + padding;
  6764. la->offset += sz;
  6765. return (void*)next_address;
  6766. }
  6767. GS_API_DECL void gs_linear_allocator_clear(gs_linear_allocator_t* la)
  6768. {
  6769. gs_assert(la);
  6770. la->offset = 0;
  6771. }
  6772. /*================================================================================
  6773. // Stack Allocator
  6774. ================================================================================*/
  6775. GS_API_DECL gs_stack_allocator_t gs_stack_allocator_new(size_t sz)
  6776. {
  6777. gs_stack_allocator_t alloc = gs_default_val();
  6778. alloc.memory = gs_memory_block_new(sz);
  6779. return alloc;
  6780. }
  6781. GS_API_DECL void gs_stack_allocator_free(gs_stack_allocator_t* sa)
  6782. {
  6783. gs_stack_allocator_clear(sa);
  6784. gs_memory_block_free(&sa->memory);
  6785. }
  6786. GS_API_DECL void* gs_stack_allocator_allocate(gs_stack_allocator_t* sa, size_t sz)
  6787. {
  6788. // Not enough memory available
  6789. size_t total_size = sz + sizeof(gs_stack_allocator_header_t);
  6790. if (total_size > (size_t)sa->memory.size - sa->offset) {
  6791. return NULL;
  6792. }
  6793. // Create new entry and push
  6794. size_t header_addr = (size_t)(sa->memory.data + sa->offset + sz);
  6795. gs_stack_allocator_header_t* header = (gs_stack_allocator_header_t*)(sa->memory.data + sa->offset + sz);
  6796. uint8_t* data = (uint8_t*)(sa->memory.data + sa->offset);
  6797. header->size = (uint32_t)sz;
  6798. // Add this to the memory size
  6799. sa->offset += total_size;
  6800. // Return data
  6801. return data;
  6802. }
  6803. GS_API_DECL void* gs_stack_allocator_pop(gs_stack_allocator_t* sa)
  6804. {
  6805. // If no entries left, then cannot pop
  6806. if (sa->offset == 0) {
  6807. return NULL;
  6808. }
  6809. // Move current size back
  6810. gs_stack_allocator_header_t* header = (gs_stack_allocator_header_t*)(sa->memory.data + sa->offset - sizeof(gs_stack_allocator_header_t));
  6811. void* data = (uint8_t*)(sa->memory.data + sa->offset - sizeof(gs_stack_allocator_header_t) - header->size);
  6812. size_t total_sz = (size_t)header->size + sizeof(gs_stack_allocator_header_t);
  6813. // Set offset back
  6814. sa->offset -= total_sz;
  6815. // Return data
  6816. return (void*)data;
  6817. }
  6818. GS_API_DECL void* gs_stack_allocator_peek(gs_stack_allocator_t* sa)
  6819. {
  6820. if (sa->offset == 0) {
  6821. return NULL;
  6822. }
  6823. gs_stack_allocator_header_t* header = (gs_stack_allocator_header_t*)(sa->memory.data + sa->offset - sizeof(gs_stack_allocator_header_t));
  6824. return (void*)(sa->memory.data + sa->offset - sizeof(gs_stack_allocator_header_t) - (size_t)header->size);
  6825. }
  6826. GS_API_DECL void gs_stack_allocator_clear(gs_stack_allocator_t* sa)
  6827. {
  6828. // Clear offset
  6829. sa->offset = 0;
  6830. }
  6831. /*================================================================================
  6832. // Paged Allocator
  6833. ================================================================================*/
  6834. GS_API_DECL gs_paged_allocator_t gs_paged_allocator_new(size_t block_size, size_t blocks_per_page)
  6835. {
  6836. gs_paged_allocator_t pa = gs_default_val();
  6837. pa.block_size = block_size;
  6838. pa.blocks_per_page = blocks_per_page;
  6839. pa.pages = NULL;
  6840. pa.page_count = 0;
  6841. pa.free_list = NULL;
  6842. return pa;
  6843. }
  6844. GS_API_DECL void gs_paged_allocator_free(gs_paged_allocator_t* pa)
  6845. {
  6846. gs_paged_allocator_clear(pa);
  6847. }
  6848. GS_API_DECL void* gs_paged_allocator_allocate(gs_paged_allocator_t* pa)
  6849. {
  6850. if (pa->free_list)
  6851. {
  6852. gs_paged_allocator_block_t* data = pa->free_list;
  6853. pa->free_list = data->next;
  6854. return data;
  6855. }
  6856. else
  6857. {
  6858. gs_paged_allocator_page_t* page = (gs_paged_allocator_page_t*)_gs_malloc_init_impl(pa->block_size * pa->blocks_per_page + sizeof(gs_paged_allocator_page_t));
  6859. pa->page_count++;
  6860. page->next = pa->pages;
  6861. page->data = (gs_paged_allocator_block_t*)gs_ptr_add(page, sizeof(gs_paged_allocator_page_t));
  6862. pa->pages = page;
  6863. // #define gs_ptr_add(P, BYTES) \
  6864. // (((uint8_t*)P + (BYTES)))
  6865. uint32_t bppmo = pa->blocks_per_page - 1;
  6866. for (uint32_t i = 0; i < bppmo; ++i)
  6867. {
  6868. gs_paged_allocator_block_t* node = (gs_paged_allocator_block_t*)gs_ptr_add(page->data, pa->block_size * i);
  6869. gs_paged_allocator_block_t* next = (gs_paged_allocator_block_t*)gs_ptr_add(page->data, pa->block_size * (i + 1));
  6870. node->next = next;
  6871. }
  6872. gs_paged_allocator_block_t* last = (gs_paged_allocator_block_t*)gs_ptr_add(page->data, pa->block_size * bppmo);
  6873. last->next = NULL;
  6874. pa->free_list = page->data->next;
  6875. return page->data;
  6876. }
  6877. }
  6878. GS_API_DECL void gs_paged_allocator_deallocate(gs_paged_allocator_t* pa, void* data)
  6879. {
  6880. ((gs_paged_allocator_block_t*)data)->next = pa->free_list;
  6881. pa->free_list = ((gs_paged_allocator_block_t*)data);
  6882. }
  6883. GS_API_DECL void gs_paged_allocator_clear(gs_paged_allocator_t* pa)
  6884. {
  6885. gs_paged_allocator_page_t* page = pa->pages;
  6886. for (uint32_t i = 0; i < pa->page_count; ++i)
  6887. {
  6888. gs_paged_allocator_page_t* next = page->next;
  6889. gs_free(page);
  6890. page = next;
  6891. }
  6892. pa->free_list = NULL;
  6893. pa->page_count = 0;
  6894. }
  6895. /*================================================================================
  6896. // Heap Allocator
  6897. ================================================================================*/
  6898. // #ifndef GS_HEAP_ALLOC_DEFAULT_SIZE
  6899. // #define GS_HEAP_ALLOC_DEFAULT_SIZE 1024 * 1024 * 20
  6900. // #endif
  6901. // #ifndef GS_HEAP_ALLOC_DEFAULT_CAPCITY
  6902. // #define GS_HEAP_ALLOC_DEFAULT_CAPCITY 1024
  6903. // #endif
  6904. // typedef struct gs_heap_allocator_header_t {
  6905. // struct gs_heap_allocator_header_t* next;
  6906. // struct gs_heap_allocator_header_t* prev;
  6907. // size_t size;
  6908. // } gs_heap_allocator_header_t;
  6909. // typedef struct gs_heap_allocator_free_block_t {
  6910. // gs_heap_allocator_header_t* header;
  6911. // size_t size;
  6912. // } gs_heap_allocator_free_block_t;
  6913. // typedef struct gs_heap_allocator_t {
  6914. // gs_heap_allocator_header_t* memory;
  6915. // gs_heap_allocator_free_block_t* free_blocks;
  6916. // uint32_t free_block_count;
  6917. // uint32_t free_block_capacity;
  6918. // } gs_heap_allocator_t;
  6919. GS_API_DECL gs_heap_allocator_t gs_heap_allocate_new()
  6920. {
  6921. gs_heap_allocator_t ha = gs_default_val();
  6922. ha.memory = (gs_heap_allocator_header_t*)_gs_malloc_init_impl(GS_HEAP_ALLOC_DEFAULT_SIZE);
  6923. ha.memory->next = NULL;
  6924. ha.memory->prev = NULL;
  6925. ha.memory->size = GS_HEAP_ALLOC_DEFAULT_SIZE;
  6926. ha.free_blocks = (gs_heap_allocator_free_block_t*)_gs_malloc_init_impl(sizeof(gs_heap_allocator_free_block_t) * GS_HEAP_ALLOC_DEFAULT_CAPCITY);
  6927. ha.free_block_count = 1;
  6928. ha.free_block_capacity = GS_HEAP_ALLOC_DEFAULT_CAPCITY;
  6929. ha.free_blocks->header = ha.memory;
  6930. ha.free_blocks->size = GS_HEAP_ALLOC_DEFAULT_SIZE;
  6931. return ha;
  6932. }
  6933. GS_API_DECL void gs_heap_allocator_free(gs_heap_allocator_t* ha)
  6934. {
  6935. gs_free(ha->memory);
  6936. gs_free(ha->free_blocks);
  6937. ha->memory = NULL;
  6938. ha->free_blocks = NULL;
  6939. }
  6940. GS_API_DECL void* gs_heap_allocator_allocate(gs_heap_allocator_t* ha, size_t sz)
  6941. {
  6942. size_t size_needed = sz + sizeof(gs_heap_allocator_header_t);
  6943. gs_heap_allocator_free_block_t* first_fit = NULL;
  6944. for (uint32_t i = 0; i < ha->free_block_count; ++i)
  6945. {
  6946. gs_heap_allocator_free_block_t* block = ha->free_blocks + i;
  6947. if (block->size >= size_needed)
  6948. {
  6949. first_fit = block;
  6950. break;
  6951. }
  6952. }
  6953. if (!first_fit) {
  6954. return NULL;
  6955. }
  6956. gs_heap_allocator_header_t* node = first_fit->header;
  6957. gs_heap_allocator_header_t* new_node = (gs_heap_allocator_header_t*)gs_ptr_add(node, size_needed);
  6958. node->size = size_needed;
  6959. first_fit->size -= size_needed;
  6960. first_fit->header = new_node;
  6961. new_node->next = node->next;
  6962. if (node->next) {
  6963. node->next->prev = new_node;
  6964. }
  6965. node->next = new_node;
  6966. new_node->prev = node;
  6967. return gs_ptr_add(node, sizeof(gs_heap_allocator_header_t));
  6968. }
  6969. GS_API_DECL void
  6970. gs_heap_allocator_deallocate(gs_heap_allocator_t* ha, void* memory)
  6971. {
  6972. // Fill this out...
  6973. }
  6974. /*========================
  6975. // Util
  6976. ========================*/
  6977. GS_API_DECL char*
  6978. gs_util_string_concat(char* s1, const char* s2)
  6979. {
  6980. const size_t a = strlen(s1);
  6981. const size_t b = strlen(s2);
  6982. const size_t ab = a + b + 1;
  6983. s1 = (char*)gs_realloc((void*)s1, ab);
  6984. memcpy(s1 + a, s2, b + 1);
  6985. return s1;
  6986. }
  6987. /*========================
  6988. // Random
  6989. ========================*/
  6990. /* An implementation of the MT19937 Algorithm for the Mersenne Twister
  6991. * by Evan Sultanik. Based upon the pseudocode in: M. Matsumoto and
  6992. * T. Nishimura, "Mersenne Twister: A 623-dimensionally
  6993. * equidistributed uniform pseudorandom number generator," ACM
  6994. * Transactions on Modeling and Computer Simulation Vol. 8, No. 1,
  6995. * January pp.3-30 1998.
  6996. *
  6997. * http://www.sultanik.com/Mersenne_twister
  6998. */
  6999. #define GS_RAND_UPPER_MASK 0x80000000
  7000. #define GS_RAND_LOWER_MASK 0x7fffffff
  7001. #define GS_RAND_TEMPERING_MASK_B 0x9d2c5680
  7002. #define GS_RAND_TEMPERING_MASK_C 0xefc60000
  7003. GS_API_PRIVATE void
  7004. _gs_rand_seed_impl(gs_mt_rand_t* rand, uint64_t seed)
  7005. {
  7006. /* set initial seeds to mt[STATE_VECTOR_LENGTH] using the generator
  7007. * from Line 25 of Table 1 in: Donald Knuth, "The Art of Computer
  7008. * Programming," Vol. 2 (2nd Ed.) pp.102.
  7009. */
  7010. rand->mt[0] = seed & 0xffffffff;
  7011. for (rand->index = 1; rand->index < GS_STATE_VECTOR_LENGTH; rand->index++)
  7012. {
  7013. rand->mt[rand->index] = (6069 * rand->mt[rand->index-1]) & 0xffffffff;
  7014. }
  7015. }
  7016. GS_API_DECL gs_mt_rand_t
  7017. gs_rand_seed(uint64_t seed)
  7018. {
  7019. gs_mt_rand_t rand;
  7020. _gs_rand_seed_impl(&rand, seed);
  7021. return rand;
  7022. }
  7023. GS_API_DECL int64_t
  7024. gs_rand_gen_long(gs_mt_rand_t* rand)
  7025. {
  7026. uint64_t y;
  7027. static uint64_t mag[2] = {0x0, 0x9908b0df}; /* mag[x] = x * 0x9908b0df for x = 0,1 */
  7028. if(rand->index >= GS_STATE_VECTOR_LENGTH || rand->index < 0) {
  7029. /* generate GS_STATE_VECTOR_LENGTH words at a time */
  7030. int kk;
  7031. if(rand->index >= GS_STATE_VECTOR_LENGTH+1 || rand->index < 0) {
  7032. _gs_rand_seed_impl(rand, 4357);
  7033. }
  7034. for(kk=0; kk<GS_STATE_VECTOR_LENGTH-GS_STATE_VECTOR_M; kk++) {
  7035. y = (rand->mt[kk] & GS_RAND_UPPER_MASK) | (rand->mt[kk+1] & GS_RAND_LOWER_MASK);
  7036. rand->mt[kk] = rand->mt[kk+GS_STATE_VECTOR_M] ^ (y >> 1) ^ mag[y & 0x1];
  7037. }
  7038. for(; kk<GS_STATE_VECTOR_LENGTH-1; kk++) {
  7039. y = (rand->mt[kk] & GS_RAND_UPPER_MASK) | (rand->mt[kk+1] & GS_RAND_LOWER_MASK);
  7040. rand->mt[kk] = rand->mt[kk+(GS_STATE_VECTOR_M-GS_STATE_VECTOR_LENGTH)] ^ (y >> 1) ^ mag[y & 0x1];
  7041. }
  7042. y = (rand->mt[GS_STATE_VECTOR_LENGTH-1] & GS_RAND_UPPER_MASK) | (rand->mt[0] & GS_RAND_LOWER_MASK);
  7043. rand->mt[GS_STATE_VECTOR_LENGTH-1] = rand->mt[GS_STATE_VECTOR_M-1] ^ (y >> 1) ^ mag[y & 0x1];
  7044. rand->index = 0;
  7045. }
  7046. y = rand->mt[rand->index++];
  7047. y ^= (y >> 11);
  7048. y ^= (y << 7) & GS_RAND_TEMPERING_MASK_B;
  7049. y ^= (y << 15) & GS_RAND_TEMPERING_MASK_C;
  7050. y ^= (y >> 18);
  7051. return y;
  7052. }
  7053. GS_API_DECL double
  7054. gs_rand_gen(gs_mt_rand_t* rand)
  7055. {
  7056. return((double)gs_rand_gen_long(rand) / (uint64_t)0xffffffff);
  7057. }
  7058. GS_API_DECL int64_t
  7059. gs_rand_gen_range_long(gs_mt_rand_t* rand, int32_t min, int32_t max)
  7060. {
  7061. return (int64_t)(floorf(gs_rand_gen_range(rand, (double)min, (double)max)));
  7062. }
  7063. GS_API_DECL double
  7064. gs_rand_gen_range(gs_mt_rand_t* rand, double min, double max)
  7065. {
  7066. return gs_map_range(0.0, 1.0, min, max, gs_rand_gen(rand));
  7067. }
  7068. GS_API_DECL gs_color_t
  7069. gs_rand_gen_color(gs_mt_rand_t* rand)
  7070. {
  7071. gs_color_t c = gs_default_val();
  7072. c.r = (uint8_t)gs_rand_gen_range_long(rand, 0, 255);
  7073. c.g = (uint8_t)gs_rand_gen_range_long(rand, 0, 255);
  7074. c.b = (uint8_t)gs_rand_gen_range_long(rand, 0, 255);
  7075. c.a = (uint8_t)gs_rand_gen_range_long(rand, 0, 255);
  7076. return c;
  7077. }
  7078. /*================================================================================
  7079. // Coroutine
  7080. ================================================================================*/
  7081. // Light wrapper around Minicoro
  7082. #define MINICORO_IMPL
  7083. #include "external/minicoro/minicoro.h"
  7084. /*================================================================================
  7085. // Scheduler
  7086. ================================================================================*/
  7087. #define SCHED_IMPLEMENTATION
  7088. #include "external/sched/sched.h"
  7089. /* ---------------------------------------------------------------
  7090. * ATOMIC
  7091. * ---------------------------------------------------------------*/
  7092. #if defined(_WIN32) && !(defined(__MINGW32__) || defined(__MINGW64__))
  7093. #include <intrin.h>
  7094. void _ReadWriteBarrier();
  7095. #pragma intrinsic(_ReadWriteBarrier)
  7096. #pragma intrinsic(_InterlockedCompareExchange)
  7097. #pragma intrinsic(_InterlockedExchangeAdd)
  7098. #endif
  7099. GS_API_DECL uint32_t
  7100. gs_atomic_cmp_swp(volatile uint32_t *dst, uint32_t swap, uint32_t cmp)
  7101. {
  7102. /* Atomically performs: if (*dst == swapTp){ *dst = swapTo;}
  7103. * return old *dst (so if sucessfull return cmp) */
  7104. #if defined(_WIN32) && !(defined(__MINGW32__) || defined(__MINGW64__))
  7105. /* assumes two's complement - unsigned /signed conversion leads to same bit pattern */
  7106. return _InterlockedCompareExchange((volatile long*)dst, swap, cmp);
  7107. #else
  7108. return __sync_val_compare_and_swap(dst, cmp, swap);
  7109. #endif
  7110. }
  7111. GS_API_DECL gs_atomic_int_t
  7112. gs_atomic_add(volatile gs_atomic_int_t *dst, int32_t value)
  7113. {
  7114. /* Atomically performs: tmp = *dst: *dst += value; return tmp; */
  7115. #if defined(_WIN32) && !(defined(__MINGW32__) || defined(__MINGW64__))
  7116. return _InterlockedExchangeAdd((long*)dst, value);
  7117. #else
  7118. return (sched_int)__sync_add_and_fetch(dst, value);
  7119. #endif
  7120. }
  7121. /*================================================================================
  7122. // Noise
  7123. ================================================================================*/
  7124. #define SG_NOISE_IMPL
  7125. #include "external/sg_noise/sg_noise.h"
  7126. // Perlin noise
  7127. GS_API_DECL float
  7128. gs_perlin1(float x)
  7129. {
  7130. return sg_noise1(x);
  7131. }
  7132. GS_API_DECL float
  7133. gs_perlin2(float x, float y)
  7134. {
  7135. return sg_noise2(x, y);
  7136. }
  7137. GS_API_DECL float
  7138. gs_perlin3(float x, float y, float z)
  7139. {
  7140. return sg_noise3(x, y, z);
  7141. }
  7142. GS_API_DECL float
  7143. gs_perlin4(float x, float y, float z, float w)
  7144. {
  7145. return sg_noise4(x, y, z, w);
  7146. }
  7147. // Perlin periodic noise
  7148. GS_API_DECL float
  7149. gs_perlin1p(float x, int32_t px)
  7150. {
  7151. return sg_pnoise1(x, px);
  7152. }
  7153. GS_API_DECL float
  7154. gs_perlin2p(float x, float y, int32_t px, int32_t py)
  7155. {
  7156. return sg_pnoise2(x, y, px, py);
  7157. }
  7158. GS_API_DECL float
  7159. gs_perlin3p(float x, float y, float z, int32_t px, int32_t py, int32_t pz)
  7160. {
  7161. return sg_pnoise3(x, y, z, px, py, pz);
  7162. }
  7163. GS_API_DECL float
  7164. gs_perlin4p(float x, float y, float z, float w, int32_t px, int32_t py, int32_t pz, int32_t pw)
  7165. {
  7166. return sg_pnoise4(x, y, z, w, px, py, pz, pw);
  7167. }
  7168. /*=============================
  7169. // Camera
  7170. =============================*/
  7171. GS_API_DECL gs_camera_t
  7172. gs_camera_default()
  7173. {
  7174. // Construct default camera parameters
  7175. gs_camera_t cam = gs_default_val();
  7176. cam.transform = gs_vqs_default();
  7177. cam.transform.position.z = 1.f;
  7178. cam.fov = 60.f;
  7179. cam.near_plane = 0.1f;
  7180. cam.far_plane = 1000.f;
  7181. cam.ortho_scale = 1.f;
  7182. cam.proj_type = GS_PROJECTION_TYPE_ORTHOGRAPHIC;
  7183. return cam;
  7184. }
  7185. GS_API_DECL gs_camera_t
  7186. gs_camera_perspective()
  7187. {
  7188. gs_camera_t cam = gs_camera_default();
  7189. cam.proj_type = GS_PROJECTION_TYPE_PERSPECTIVE;
  7190. cam.transform.position.z = 1.f;
  7191. return cam;
  7192. }
  7193. GS_API_DECL gs_vec3
  7194. gs_camera_forward(const gs_camera_t* cam)
  7195. {
  7196. return (gs_quat_rotate(cam->transform.rotation, gs_v3(0.0f, 0.0f, -1.0f)));
  7197. }
  7198. GS_API_DECL gs_vec3
  7199. gs_camera_backward(const gs_camera_t* cam)
  7200. {
  7201. return (gs_quat_rotate(cam->transform.rotation, gs_v3(0.0f, 0.0f, 1.0f)));
  7202. }
  7203. GS_API_DECL gs_vec3
  7204. gs_camera_up(const gs_camera_t* cam)
  7205. {
  7206. return (gs_quat_rotate(cam->transform.rotation, gs_v3(0.0f, 1.0f, 0.0f)));
  7207. }
  7208. GS_API_DECL gs_vec3
  7209. gs_camera_down(const gs_camera_t* cam)
  7210. {
  7211. return (gs_quat_rotate(cam->transform.rotation, gs_v3(0.0f, -1.0f, 0.0f)));
  7212. }
  7213. GS_API_DECL gs_vec3
  7214. gs_camera_right(const gs_camera_t* cam)
  7215. {
  7216. return (gs_quat_rotate(cam->transform.rotation, gs_v3(1.0f, 0.0f, 0.0f)));
  7217. }
  7218. GS_API_DECL gs_vec3
  7219. gs_camera_left(const gs_camera_t* cam)
  7220. {
  7221. return (gs_quat_rotate(cam->transform.rotation, gs_v3(-1.0f, 0.0f, 0.0f)));
  7222. }
  7223. GS_API_DECL gs_vec3
  7224. gs_camera_world_to_screen(const gs_camera_t* cam, gs_vec3 coords, int32_t view_width, int32_t view_height)
  7225. {
  7226. // Transform world coords to screen coords to place billboarded UI elements in world
  7227. gs_mat4 vp = gs_camera_get_view_projection(cam, view_width, view_height);
  7228. gs_vec4 p4 = gs_v4(coords.x, coords.y, coords.z, 1.f);
  7229. p4 = gs_mat4_mul_vec4(vp, p4);
  7230. p4.x /= p4.w;
  7231. p4.y /= p4.w;
  7232. p4.z /= p4.w;
  7233. // Bring into ndc
  7234. p4.x = p4.x * 0.5f + 0.5f;
  7235. p4.y = p4.y * 0.5f + 0.5f;
  7236. // Bring into screen space
  7237. p4.x = p4.x * (float)view_width;
  7238. p4.y = gs_map_range(1.f, 0.f, 0.f, 1.f, p4.y) * (float)view_height;
  7239. return gs_v3(p4.x, p4.y, p4.z);
  7240. }
  7241. GS_API_DECL gs_vec3
  7242. gs_camera_screen_to_world(const gs_camera_t* cam, gs_vec3 coords, s32 view_x, s32 view_y, s32 view_width, s32 view_height)
  7243. {
  7244. gs_vec3 wc = gs_default_val();
  7245. // Get inverse of view projection from camera
  7246. gs_mat4 inverse_vp = gs_mat4_inverse(gs_camera_get_view_projection(cam, view_width, view_height));
  7247. f32 w_x = (f32)coords.x - (f32)view_x;
  7248. f32 w_y = (f32)coords.y - (f32)view_y;
  7249. f32 w_z = (f32)coords.z;
  7250. // Transform from ndc
  7251. gs_vec4 in;
  7252. in.x = (w_x / (f32)view_width) * 2.f - 1.f;
  7253. in.y = 1.f - (w_y / (f32)view_height) * 2.f;
  7254. in.z = 2.f * w_z - 1.f;
  7255. in.w = 1.f;
  7256. // To world coords
  7257. gs_vec4 out = gs_mat4_mul_vec4(inverse_vp, in);
  7258. if (out.w == 0.f)
  7259. {
  7260. // Avoid div by zero
  7261. return wc;
  7262. }
  7263. out.w = fabsf(out.w) > GS_EPSILON ? 1.f / out.w : 0.0001f;
  7264. wc = gs_v3(
  7265. out.x * out.w,
  7266. out.y * out.w,
  7267. out.z * out.w
  7268. );
  7269. return wc;
  7270. }
  7271. GS_API_DECL gs_mat4
  7272. gs_camera_get_view_projection(const gs_camera_t* cam, s32 view_width, s32 view_height)
  7273. {
  7274. gs_mat4 view = gs_camera_get_view(cam);
  7275. gs_mat4 proj = gs_camera_get_proj(cam, view_width, view_height);
  7276. return gs_mat4_mul(proj, view);
  7277. }
  7278. GS_API_DECL gs_mat4
  7279. gs_camera_get_view(const gs_camera_t* cam)
  7280. {
  7281. gs_vec3 up = gs_camera_up(cam);
  7282. gs_vec3 forward = gs_camera_forward(cam);
  7283. gs_vec3 target = gs_vec3_add(forward, cam->transform.position);
  7284. return gs_mat4_look_at(cam->transform.position, target, up);
  7285. }
  7286. GS_API_DECL gs_mat4
  7287. gs_camera_get_proj(const gs_camera_t* cam, s32 view_width, s32 view_height)
  7288. {
  7289. gs_mat4 proj_mat = gs_mat4_identity();
  7290. switch(cam->proj_type)
  7291. {
  7292. case GS_PROJECTION_TYPE_PERSPECTIVE:
  7293. {
  7294. proj_mat = gs_mat4_perspective(cam->fov, (f32)view_width / (f32)view_height, cam->near_plane, cam->far_plane);
  7295. } break;
  7296. // Don't like this...
  7297. case GS_PROJECTION_TYPE_ORTHOGRAPHIC:
  7298. {
  7299. f32 _ar = (f32)view_width / (f32)view_height;
  7300. f32 distance = 0.5f * (cam->far_plane - cam->near_plane);
  7301. const f32 ortho_scale = cam->ortho_scale;
  7302. const f32 aspect_ratio = _ar;
  7303. proj_mat = gs_mat4_ortho
  7304. (
  7305. -ortho_scale * aspect_ratio,
  7306. ortho_scale * aspect_ratio,
  7307. -ortho_scale,
  7308. ortho_scale,
  7309. -distance,
  7310. distance
  7311. );
  7312. } break;
  7313. }
  7314. return proj_mat;
  7315. }
  7316. GS_API_DECL void
  7317. gs_camera_offset_orientation(gs_camera_t* cam, f32 yaw, f32 pitch)
  7318. {
  7319. gs_quat x = gs_quat_angle_axis(gs_deg2rad(yaw), gs_v3(0.f, 1.f, 0.f)); // Absolute up
  7320. gs_quat y = gs_quat_angle_axis(gs_deg2rad(pitch), gs_camera_right(cam)); // Relative right
  7321. cam->transform.rotation = gs_quat_mul(gs_quat_mul(x, y), cam->transform.rotation);
  7322. }
  7323. /*=============================
  7324. // GS_UTIL
  7325. =============================*/
  7326. #define STBI_MALLOC(sz) gs_malloc(sz)
  7327. #define STBI_REALLOC(p,newsz) gs_realloc(p,newsz)
  7328. #define STBI_FREE(p) gs_free(p)
  7329. #ifndef GS_NO_STB_RECT_PACK
  7330. #define STB_RECT_PACK_IMPLEMENTATION
  7331. #endif
  7332. #ifndef GS_NO_STB_TRUETYPE
  7333. // #define STBTT_RASTERIZER_VERSION 0
  7334. #define STB_TRUETYPE_IMPLEMENTATION
  7335. #endif
  7336. #ifndef GS_NO_STB_DEFINE
  7337. #define STB_DEFINE
  7338. #endif
  7339. #ifndef GS_NO_STB_IMAGE
  7340. #define STB_IMAGE_IMPLEMENTATION
  7341. // #define STB_IMAGE_WRITE_IMPLEMENTATION
  7342. #endif
  7343. // #ifndef GS_NO_STB_DS_DEFINE
  7344. // #define STB_DS_IMPLEMENTATION
  7345. // #endif
  7346. #ifndef GS_NO_CGLTF
  7347. #define CGLTF_IMPLEMENTATION
  7348. #endif
  7349. // STB
  7350. #ifdef GS_STB_INCLUDE
  7351. #include "external/stb/stb.h"
  7352. #endif
  7353. #include "external/stb/stb_rect_pack.h"
  7354. #include "external/stb/stb_truetype.h"
  7355. #include "external/stb/stb_image.h"
  7356. // #include "external/stb/stb_ds.h"
  7357. // CGLTF
  7358. #include "external/cgltf/cgltf.h"
  7359. GS_API_DECL char*
  7360. gs_read_file_contents_into_string_null_term
  7361. (
  7362. const char* file_path,
  7363. const char* mode,
  7364. size_t* _sz
  7365. )
  7366. {
  7367. char* buffer = 0;
  7368. FILE* fp = fopen(file_path, mode);
  7369. size_t sz = 0;
  7370. if (fp)
  7371. {
  7372. fseek(fp, 0, SEEK_END);
  7373. sz = ftell(fp);
  7374. fseek(fp, 0, SEEK_SET);
  7375. buffer = (char*)gs_malloc(sz + 1);
  7376. if (buffer)
  7377. {
  7378. fread(buffer, 1, sz, fp);
  7379. }
  7380. fclose(fp);
  7381. buffer[sz] = '\0';
  7382. if (_sz) *_sz = sz;
  7383. }
  7384. return buffer;
  7385. }
  7386. bool32_t gs_util_load_texture_data_from_file(const char* file_path, int32_t* width, int32_t* height, uint32_t* num_comps, void** data, bool32_t flip_vertically_on_load)
  7387. {
  7388. size_t len = 0;
  7389. char* file_data = gs_platform_read_file_contents(file_path, "rb", &len);
  7390. gs_assert(file_data);
  7391. bool32_t ret = gs_util_load_texture_data_from_memory(file_data, len, width, height, num_comps, data, flip_vertically_on_load);
  7392. if (!ret) {
  7393. gs_println("Warning: could not load texture: %s", file_path);
  7394. }
  7395. gs_free(file_data);
  7396. return ret;
  7397. }
  7398. GS_API_DECL bool32_t
  7399. gs_util_load_texture_data_from_memory(const void* memory, size_t sz, int32_t* width, int32_t* height, uint32_t* num_comps, void** data, bool32_t flip_vertically_on_load)
  7400. {
  7401. // Load texture data
  7402. stbi_set_flip_vertically_on_load(flip_vertically_on_load);
  7403. *data = stbi_load_from_memory((const stbi_uc*)memory, (int32_t)sz, (int32_t*)width, (int32_t*)height, (int32_t*)num_comps, STBI_rgb_alpha);
  7404. if (!*data) {
  7405. gs_free(*data);
  7406. return false;
  7407. }
  7408. return true;
  7409. }
  7410. /*==========================
  7411. // GS_ASSET_TYPES
  7412. ==========================*/
  7413. GS_API_DECL bool
  7414. gs_asset_texture_load_from_file(const char* path, void* out, gs_graphics_texture_desc_t* desc, bool32_t flip_on_load, bool32_t keep_data)
  7415. {
  7416. gs_asset_texture_t* t = (gs_asset_texture_t*)out;
  7417. memset(&t->desc, 0, sizeof(gs_graphics_texture_desc_t));
  7418. if (desc) {
  7419. t->desc = *desc;
  7420. } else {
  7421. t->desc.format = GS_GRAPHICS_TEXTURE_FORMAT_RGBA8;
  7422. t->desc.min_filter = GS_GRAPHICS_TEXTURE_FILTER_LINEAR;
  7423. t->desc.mag_filter = GS_GRAPHICS_TEXTURE_FILTER_LINEAR;
  7424. t->desc.wrap_s = GS_GRAPHICS_TEXTURE_WRAP_REPEAT;
  7425. t->desc.wrap_t = GS_GRAPHICS_TEXTURE_WRAP_REPEAT;
  7426. }
  7427. // Load texture data
  7428. FILE* f = fopen(path, "rb");
  7429. if (!f) {
  7430. return false;
  7431. }
  7432. int32_t comp = 0;
  7433. stbi_set_flip_vertically_on_load(t->desc.flip_y);
  7434. *t->desc.data = (uint8_t*)stbi_load_from_file(f, (int32_t*)&t->desc.width, (int32_t*)&t->desc.height, (int32_t*)&comp, STBI_rgb_alpha);
  7435. if (!*t->desc.data) {
  7436. fclose(f);
  7437. return false;
  7438. }
  7439. t->hndl = gs_graphics_texture_create(&t->desc);
  7440. if (!keep_data) {
  7441. gs_free(*t->desc.data);
  7442. *t->desc.data = NULL;
  7443. }
  7444. fclose(f);
  7445. return true;
  7446. }
  7447. /*
  7448. bool gs_asset_texture_load_from_file(const char* path, void* out, gs_graphics_texture_desc_t* desc, bool32_t flip_on_load, bool32_t keep_data)
  7449. {
  7450. size_t len = 0;
  7451. char* file_data = gs_platform_read_file_contents(path, "rb", &len);
  7452. gs_assert(file_data);
  7453. bool32_t ret = gs_asset_texture_load_from_memory(file_data, len, out, desc, flip_on_load, keep_data);
  7454. gs_free(file_data);
  7455. return ret;
  7456. }
  7457. */
  7458. bool gs_asset_texture_load_from_memory(const void* memory, size_t sz, void* out, gs_graphics_texture_desc_t* desc, bool32_t flip_on_load, bool32_t keep_data)
  7459. {
  7460. gs_asset_texture_t* t = (gs_asset_texture_t*)out;
  7461. memset(&t->desc, 0, sizeof(gs_graphics_texture_desc_t));
  7462. if (desc) {
  7463. t->desc = *desc;
  7464. } else {
  7465. t->desc.format = GS_GRAPHICS_TEXTURE_FORMAT_RGBA8;
  7466. t->desc.min_filter = GS_GRAPHICS_TEXTURE_FILTER_LINEAR;
  7467. t->desc.mag_filter = GS_GRAPHICS_TEXTURE_FILTER_LINEAR;
  7468. t->desc.wrap_s = GS_GRAPHICS_TEXTURE_WRAP_REPEAT;
  7469. t->desc.wrap_t = GS_GRAPHICS_TEXTURE_WRAP_REPEAT;
  7470. }
  7471. // Load texture data
  7472. int32_t num_comps = 0;
  7473. bool32_t loaded = gs_util_load_texture_data_from_memory(memory, sz, (int32_t*)&t->desc.width,
  7474. (int32_t*)&t->desc.height, (uint32_t*)&num_comps, t->desc.data, t->desc.flip_y);
  7475. if (!loaded) {
  7476. return false;
  7477. }
  7478. t->hndl = gs_graphics_texture_create(&t->desc);
  7479. if (!keep_data) {
  7480. gs_free(*t->desc.data);
  7481. *t->desc.data = NULL;
  7482. }
  7483. return true;
  7484. }
  7485. bool gs_asset_font_load_from_file(const char* path, void* out, uint32_t point_size)
  7486. {
  7487. size_t len = 0;
  7488. char* ttf = gs_platform_read_file_contents(path, "rb", &len);
  7489. if (!point_size) {
  7490. gs_println("Warning: Font: %s: Point size not declared. Setting to default 16.", path);
  7491. point_size = 16;
  7492. }
  7493. bool ret = gs_asset_font_load_from_memory(ttf, len, out, point_size);
  7494. if (!ret) {
  7495. gs_println("Font Failed to Load: %s", path);
  7496. } else {
  7497. gs_println("Font Successfully Loaded: %s", path);
  7498. }
  7499. gs_free(ttf);
  7500. return ret;
  7501. }
  7502. bool gs_asset_font_load_from_memory(const void* memory, size_t sz, void* out, uint32_t point_size)
  7503. {
  7504. gs_asset_font_t* f = (gs_asset_font_t*)out;
  7505. if (!point_size) {
  7506. gs_println("Warning: Font: Point size not declared. Setting to default 16.");
  7507. point_size = 16;
  7508. }
  7509. // Poor attempt at an auto resized texture
  7510. const uint32_t point_wh = gs_max(point_size, 32);
  7511. const uint32_t w = (point_wh/32 * 512) + (point_wh/32 * 512) % 512;
  7512. const uint32_t h = (point_wh/32 * 512) + (point_wh/32 * 512) % 512;
  7513. const uint32_t num_comps = 4;
  7514. u8* alpha_bitmap = (uint8_t*)gs_malloc(w * h);
  7515. u8* flipmap = (uint8_t*)gs_malloc(w * h * num_comps);
  7516. memset(alpha_bitmap, 0, w * h);
  7517. memset(flipmap, 0, w * h * num_comps);
  7518. s32 v = stbtt_BakeFontBitmap((u8*)memory, 0, (float)point_size, alpha_bitmap, w, h, 32, 96, (stbtt_bakedchar*)f->glyphs); // no guarantee this fits!
  7519. // Flip texture
  7520. u32 r = h - 1;
  7521. for (u32 i = 0; i < h; ++i)
  7522. {
  7523. for (u32 j = 0; j < w; ++j)
  7524. {
  7525. u32 i0 = i * w + j;
  7526. u32 i1 = i * w * num_comps + j * num_comps;
  7527. u8 a = alpha_bitmap[i0];
  7528. flipmap[i1 + 0] = 255;
  7529. flipmap[i1 + 1] = 255;
  7530. flipmap[i1 + 2] = 255;
  7531. flipmap[i1 + 3] = a;
  7532. }
  7533. r--;
  7534. }
  7535. gs_graphics_texture_desc_t desc = gs_default_val();
  7536. desc.width = w;
  7537. desc.height = h;
  7538. *desc.data = flipmap;
  7539. desc.format = GS_GRAPHICS_TEXTURE_FORMAT_RGBA8;
  7540. desc.min_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  7541. desc.mag_filter = GS_GRAPHICS_TEXTURE_FILTER_NEAREST;
  7542. // Generate atlas texture for bitmap with bitmap data
  7543. f->texture.hndl = gs_graphics_texture_create(&desc);
  7544. f->texture.desc = desc;
  7545. *f->texture.desc.data = NULL;
  7546. bool success = false;
  7547. if (v <= 0) {
  7548. gs_println("Font Failed to Load, Baked Texture Was Too Small: %d", v);
  7549. }
  7550. else {
  7551. gs_println("Font Successfully Loaded: %d", v);
  7552. success = true;
  7553. }
  7554. gs_free(alpha_bitmap);
  7555. gs_free(flipmap);
  7556. return success;
  7557. }
  7558. GS_API_DECL float gs_asset_font_max_height(const gs_asset_font_t* fp)
  7559. {
  7560. if (!fp) return 0.f;
  7561. float h = 0.f, x = 0.f, y = 0.f;
  7562. const char* txt = "1l`'f()ABCDEFGHIJKLMNOjPQqSTU!";
  7563. while (txt[0] != '\0')
  7564. {
  7565. char c = txt[0];
  7566. if (c >= 32 && c <= 127)
  7567. {
  7568. stbtt_aligned_quad q = gs_default_val();
  7569. stbtt_GetBakedQuad((stbtt_bakedchar*)fp->glyphs, fp->texture.desc.width, fp->texture.desc.height, c - 32, &x, &y, &q, 1);
  7570. h = gs_max(gs_max(h, fabsf(q.y0)), fabsf(q.y1));
  7571. }
  7572. txt++;
  7573. };
  7574. return h;
  7575. }
  7576. GS_API_DECL gs_vec2 gs_asset_font_text_dimensions(const gs_asset_font_t* fp, const char* text, int32_t len)
  7577. {
  7578. return gs_asset_font_text_dimensions_ex(fp, text, len, 0);
  7579. }
  7580. GS_API_DECL gs_vec2 gs_asset_font_text_dimensions_ex(const gs_asset_font_t* fp, const char* text, int32_t len, bool32_t include_past_baseline)
  7581. {
  7582. gs_vec2 dimensions = gs_v2s(0.f);
  7583. if (!fp || !text) return dimensions;
  7584. float x = 0.f;
  7585. float y = 0.f;
  7586. float y_under = 0;
  7587. while (text[0] != '\0' && len--)
  7588. {
  7589. char c = text[0];
  7590. if (c >= 32 && c <= 127)
  7591. {
  7592. stbtt_aligned_quad q = gs_default_val();
  7593. stbtt_GetBakedQuad((stbtt_bakedchar*)fp->glyphs, fp->texture.desc.width, fp->texture.desc.height, c - 32, &x, &y, &q, 1);
  7594. dimensions.x = gs_max(dimensions.x, x);
  7595. dimensions.y = gs_max(dimensions.y, fabsf(q.y0));
  7596. if (include_past_baseline)
  7597. y_under = gs_max(y_under, fabsf(q.y1));
  7598. }
  7599. text++;
  7600. };
  7601. if (include_past_baseline)
  7602. dimensions.y += y_under;
  7603. return dimensions;
  7604. }
  7605. // Audio
  7606. bool gs_asset_audio_load_from_file(const char* path, void* out)
  7607. {
  7608. gs_asset_audio_t* a = (gs_asset_audio_t*)out;
  7609. a->hndl = gs_audio_load_from_file(path);
  7610. return gs_handle_is_valid(a->hndl);
  7611. }
  7612. bool gs_util_load_gltf_data_from_file(const char* path, gs_asset_mesh_decl_t* decl, gs_asset_mesh_raw_data_t** out, uint32_t* mesh_count)
  7613. {
  7614. // Use cgltf like a boss
  7615. cgltf_options options = gs_default_val();
  7616. size_t len = 0;
  7617. char* file_data = gs_platform_read_file_contents(path, "rb", &len);
  7618. gs_println("Loading GLTF: %s", path);
  7619. cgltf_data* data = NULL;
  7620. cgltf_result result = cgltf_parse(&options, file_data, (cgltf_size)len, &data);
  7621. gs_free(file_data);
  7622. if (result != cgltf_result_success) {
  7623. gs_println("Mesh:LoadFromFile:Failed load gltf");
  7624. cgltf_free(data);
  7625. return false;
  7626. }
  7627. // Load buffers as well
  7628. result = cgltf_load_buffers(&options, data, path);
  7629. if (result != cgltf_result_success) {
  7630. cgltf_free(data);
  7631. gs_println("Mesh:LoadFromFile:Failed to load buffers");
  7632. return false;
  7633. }
  7634. // Type of index data
  7635. size_t index_element_size = decl ? decl->index_buffer_element_size : 0;
  7636. // Temporary structures
  7637. gs_dyn_array(gs_vec3) positions = NULL;
  7638. gs_dyn_array(gs_vec3) normals = NULL;
  7639. gs_dyn_array(gs_vec3) tangents = NULL;
  7640. gs_dyn_array(gs_color_t) colors = NULL;
  7641. gs_dyn_array(gs_vec2) uvs = NULL;
  7642. gs_dyn_array(gs_asset_mesh_layout_t) layouts = NULL;
  7643. gs_byte_buffer_t v_data = gs_byte_buffer_new();
  7644. gs_byte_buffer_t i_data = gs_byte_buffer_new();
  7645. // Allocate memory for buffers
  7646. *mesh_count = data->meshes_count;
  7647. *out = (gs_asset_mesh_raw_data_t*)gs_malloc(data->meshes_count * sizeof(gs_asset_mesh_raw_data_t));
  7648. memset(*out, 0, sizeof(gs_asset_mesh_raw_data_t) * data->meshes_count);
  7649. // Iterate through meshes in data
  7650. for (uint32_t i = 0; i < data->meshes_count; ++i)
  7651. {
  7652. // Initialize mesh data
  7653. gs_asset_mesh_raw_data_t* mesh = out[i];
  7654. mesh->prim_count = data->meshes[i].primitives_count;
  7655. mesh->vertex_sizes = (size_t*)gs_malloc(sizeof(size_t) * mesh->prim_count);
  7656. mesh->index_sizes = (size_t*)gs_malloc(sizeof(size_t) * mesh->prim_count);
  7657. mesh->vertices = (void**)gs_malloc(sizeof(size_t) * mesh->prim_count);
  7658. mesh->indices = (void**)gs_malloc(sizeof(size_t) * mesh->prim_count);
  7659. // For each primitive in mesh
  7660. for (uint32_t p = 0; p < data->meshes[i].primitives_count; ++p)
  7661. {
  7662. // Clear temp data from previous use
  7663. gs_dyn_array_clear(positions);
  7664. gs_dyn_array_clear(normals);
  7665. gs_dyn_array_clear(tangents);
  7666. gs_dyn_array_clear(uvs);
  7667. gs_dyn_array_clear(colors);
  7668. gs_dyn_array_clear(layouts);
  7669. gs_byte_buffer_clear(&v_data);
  7670. gs_byte_buffer_clear(&i_data);
  7671. #define __GLTF_PUSH_ATTR(ATTR, TYPE, COUNT, ARR, ARR_TYPE, LAYOUTS, LAYOUT_TYPE)\
  7672. do {\
  7673. int32_t N = 0;\
  7674. TYPE* BUF = (TYPE*)ATTR->buffer_view->buffer->data + ATTR->buffer_view->offset/sizeof(TYPE) + ATTR->offset/sizeof(TYPE);\
  7675. gs_assert(BUF);\
  7676. TYPE V[COUNT] = gs_default_val();\
  7677. /* For each vertex */\
  7678. for (uint32_t k = 0; k < ATTR->count; k++)\
  7679. {\
  7680. /* For each element */\
  7681. for (int l = 0; l < COUNT; l++) {\
  7682. V[l] = BUF[N + l];\
  7683. }\
  7684. N += (int32_t)(ATTR->stride/sizeof(TYPE));\
  7685. /* Add to temp data array */\
  7686. ARR_TYPE ELEM = gs_default_val();\
  7687. memcpy((void*)&ELEM, (void*)V, sizeof(ARR_TYPE));\
  7688. gs_dyn_array_push(ARR, ELEM);\
  7689. }\
  7690. /* Push into layout */\
  7691. gs_asset_mesh_layout_t LAYOUT = gs_default_val();\
  7692. LAYOUT.type = LAYOUT_TYPE;\
  7693. gs_dyn_array_push(LAYOUTS, LAYOUT);\
  7694. } while (0)
  7695. // For each attribute in primitive
  7696. for (uint32_t a = 0; a < data->meshes[i].primitives[p].attributes_count; ++a)
  7697. {
  7698. // Accessor for attribute data
  7699. cgltf_accessor* attr = data->meshes[i].primitives[p].attributes[a].data;
  7700. // Switch on type for reading data
  7701. switch (data->meshes[i].primitives[p].attributes[a].type)
  7702. {
  7703. case cgltf_attribute_type_position: {
  7704. __GLTF_PUSH_ATTR(attr, float, 3, positions, gs_vec3, layouts, GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION);
  7705. } break;
  7706. case cgltf_attribute_type_normal: {
  7707. __GLTF_PUSH_ATTR(attr, float, 3, normals, gs_vec3, layouts, GS_ASSET_MESH_ATTRIBUTE_TYPE_NORMAL);
  7708. } break;
  7709. case cgltf_attribute_type_tangent: {
  7710. __GLTF_PUSH_ATTR(attr, float, 3, tangents, gs_vec3, layouts, GS_ASSET_MESH_ATTRIBUTE_TYPE_TANGENT);
  7711. } break;
  7712. case cgltf_attribute_type_texcoord: {
  7713. __GLTF_PUSH_ATTR(attr, float, 2, uvs, gs_vec2, layouts, GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD);
  7714. } break;
  7715. case cgltf_attribute_type_color: {
  7716. __GLTF_PUSH_ATTR(attr, uint8_t, 4, colors, gs_color_t, layouts, GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR);
  7717. } break;
  7718. // Not sure what to do with these for now
  7719. case cgltf_attribute_type_joints:
  7720. {
  7721. // Push into layout
  7722. gs_asset_mesh_layout_t layout = gs_default_val();
  7723. layout.type = GS_ASSET_MESH_ATTRIBUTE_TYPE_JOINT;
  7724. gs_dyn_array_push(layouts, layout);
  7725. } break;
  7726. case cgltf_attribute_type_weights:
  7727. {
  7728. // Push into layout
  7729. gs_asset_mesh_layout_t layout = gs_default_val();
  7730. layout.type = GS_ASSET_MESH_ATTRIBUTE_TYPE_WEIGHT;
  7731. gs_dyn_array_push(layouts, layout);
  7732. } break;
  7733. // Shouldn't hit here...
  7734. default:
  7735. {
  7736. } break;
  7737. }
  7738. }
  7739. // Indices for primitive
  7740. cgltf_accessor* acc = data->meshes[i].primitives[p].indices;
  7741. #define __GLTF_PUSH_IDX(BB, ACC, TYPE)\
  7742. do {\
  7743. int32_t n = 0;\
  7744. TYPE* buf = (TYPE*)acc->buffer_view->buffer->data + acc->buffer_view->offset/sizeof(TYPE) + acc->offset/sizeof(TYPE);\
  7745. gs_assert(buf);\
  7746. TYPE v = 0;\
  7747. /* For each index */\
  7748. for (uint32_t k = 0; k < acc->count; k++) {\
  7749. /* For each element */\
  7750. for (int l = 0; l < 1; l++) {\
  7751. v = buf[n + l];\
  7752. }\
  7753. n += (int32_t)(acc->stride/sizeof(TYPE));\
  7754. /* Add to temp positions array */\
  7755. switch (index_element_size) {\
  7756. case 0: gs_byte_buffer_write(BB, uint16_t, (uint16_t)v); break;\
  7757. case 2: gs_byte_buffer_write(BB, uint16_t, (uint16_t)v); break;\
  7758. case 4: gs_byte_buffer_write(BB, uint32_t, (uint32_t)v); break;\
  7759. }\
  7760. }\
  7761. } while (0)
  7762. // If indices are available
  7763. if (acc)
  7764. {
  7765. switch (acc->component_type)
  7766. {
  7767. case cgltf_component_type_r_8: __GLTF_PUSH_IDX(&i_data, acc, int8_t); break;
  7768. case cgltf_component_type_r_8u: __GLTF_PUSH_IDX(&i_data, acc, uint8_t); break;
  7769. case cgltf_component_type_r_16: __GLTF_PUSH_IDX(&i_data, acc, int16_t); break;
  7770. case cgltf_component_type_r_16u: __GLTF_PUSH_IDX(&i_data, acc, uint16_t); break;
  7771. case cgltf_component_type_r_32u: __GLTF_PUSH_IDX(&i_data, acc, uint32_t); break;
  7772. case cgltf_component_type_r_32f: __GLTF_PUSH_IDX(&i_data, acc, float); break;
  7773. // Shouldn't hit here
  7774. default: {
  7775. } break;
  7776. }
  7777. }
  7778. else
  7779. {
  7780. // Iterate over positions size, then just push back indices
  7781. for (uint32_t i = 0; i < gs_dyn_array_size(positions); ++i)
  7782. {
  7783. switch (index_element_size)
  7784. {
  7785. default:
  7786. case 0: gs_byte_buffer_write(&i_data, uint16_t, (uint16_t)i); break;
  7787. case 2: gs_byte_buffer_write(&i_data, uint16_t, (uint16_t)i); break;
  7788. case 4: gs_byte_buffer_write(&i_data, uint32_t, (uint32_t)i); break;
  7789. }
  7790. }
  7791. }
  7792. bool warnings[gs_enum_count(gs_asset_mesh_attribute_type)] = gs_default_val();
  7793. // Grab mesh layout pointer to use
  7794. gs_asset_mesh_layout_t* layoutp = decl ? decl->layout : layouts;
  7795. uint32_t layout_ct = decl ? decl->layout_size / sizeof(gs_asset_mesh_layout_t) : gs_dyn_array_size(layouts);
  7796. // Iterate layout to fill data buffers according to provided layout
  7797. {
  7798. uint32_t vct = 0;
  7799. vct = gs_max(vct, gs_dyn_array_size(positions));
  7800. vct = gs_max(vct, gs_dyn_array_size(colors));
  7801. vct = gs_max(vct, gs_dyn_array_size(uvs));
  7802. vct = gs_max(vct, gs_dyn_array_size(normals));
  7803. vct = gs_max(vct, gs_dyn_array_size(tangents));
  7804. #define __GS_GLTF_WRITE_DATA(IT, VDATA, ARR, ARR_TYPE, ARR_DEF_VAL, LAYOUT_TYPE)\
  7805. do {\
  7806. /* Grab data at index, if available */\
  7807. if (IT < gs_dyn_array_size(ARR)) {\
  7808. gs_byte_buffer_write(&(VDATA), ARR_TYPE, ARR[IT]);\
  7809. }\
  7810. else {\
  7811. /* Write default value and give warning.*/\
  7812. gs_byte_buffer_write(&(VDATA), ARR_TYPE, ARR_DEF_VAL);\
  7813. if (!warnings[LAYOUT_TYPE]) {\
  7814. gs_println("Warning:Mesh:LoadFromFile:%s:Index out of range.", #LAYOUT_TYPE);\
  7815. warnings[LAYOUT_TYPE] = true;\
  7816. }\
  7817. }\
  7818. } while (0)
  7819. for (uint32_t it = 0; it < vct; ++it)
  7820. {
  7821. // For each attribute in layout
  7822. for (uint32_t l = 0; l < layout_ct; ++l)
  7823. {
  7824. switch (layoutp[l].type)
  7825. {
  7826. case GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION: {
  7827. __GS_GLTF_WRITE_DATA(it, v_data, positions, gs_vec3, gs_v3(0.f, 0.f, 0.f), GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION);
  7828. } break;
  7829. case GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD: {
  7830. __GS_GLTF_WRITE_DATA(it, v_data, uvs, gs_vec2, gs_v2(0.f, 0.f), GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD);
  7831. } break;
  7832. case GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR: {
  7833. __GS_GLTF_WRITE_DATA(it, v_data, colors, gs_color_t, GS_COLOR_WHITE, GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR);
  7834. } break;
  7835. case GS_ASSET_MESH_ATTRIBUTE_TYPE_NORMAL: {
  7836. __GS_GLTF_WRITE_DATA(it, v_data, normals, gs_vec3, gs_v3(0.f, 0.f, 1.f), GS_ASSET_MESH_ATTRIBUTE_TYPE_NORMAL);
  7837. } break;
  7838. case GS_ASSET_MESH_ATTRIBUTE_TYPE_TANGENT: {
  7839. __GS_GLTF_WRITE_DATA(it, v_data, tangents, gs_vec3, gs_v3(0.f, 1.f, 0.f), GS_ASSET_MESH_ATTRIBUTE_TYPE_TANGENT);
  7840. } break;
  7841. default:
  7842. {
  7843. } break;
  7844. }
  7845. }
  7846. }
  7847. }
  7848. // Add to out data
  7849. mesh->vertices[p] = gs_malloc(v_data.size);
  7850. mesh->indices[p] = gs_malloc(i_data.size);
  7851. mesh->vertex_sizes[p] = v_data.size;
  7852. mesh->index_sizes[p] = i_data.size;
  7853. // Copy data
  7854. memcpy(mesh->vertices[p], v_data.data, v_data.size);
  7855. memcpy(mesh->indices[p], i_data.data, i_data.size);
  7856. }
  7857. }
  7858. // Free all data at the end
  7859. cgltf_free(data);
  7860. gs_dyn_array_free(positions);
  7861. gs_dyn_array_free(normals);
  7862. gs_dyn_array_free(tangents);
  7863. gs_dyn_array_free(colors);
  7864. gs_dyn_array_free(uvs);
  7865. gs_dyn_array_free(layouts);
  7866. gs_byte_buffer_free(&v_data);
  7867. gs_byte_buffer_free(&i_data);
  7868. return true;
  7869. }
  7870. bool gs_asset_mesh_load_from_file(const char* path, void* out, gs_asset_mesh_decl_t* decl, void* data_out, size_t data_size)
  7871. {
  7872. // Cast mesh data to use
  7873. gs_asset_mesh_t* mesh = (gs_asset_mesh_t*)out;
  7874. if (!gs_platform_file_exists(path)) {
  7875. gs_println("Warning:MeshLoadFromFile:File does not exist: %s", path);
  7876. return false;
  7877. }
  7878. // Mesh data to fill out
  7879. uint32_t mesh_count = 0;
  7880. gs_asset_mesh_raw_data_t* meshes = NULL;
  7881. // Get file extension from path
  7882. gs_transient_buffer(file_ext, 32);
  7883. gs_platform_file_extension(file_ext, 32, path);
  7884. // GLTF
  7885. if (gs_string_compare_equal(file_ext, "gltf"))
  7886. {
  7887. gs_util_load_gltf_data_from_file(path, decl, &meshes, &mesh_count);
  7888. }
  7889. else
  7890. {
  7891. gs_println("Warning:MeshLoadFromFile:File extension not supported: %s, file: %s", file_ext, path);
  7892. return false;
  7893. }
  7894. // For now, handle meshes with only single mesh count
  7895. if (mesh_count != 1) {
  7896. // Error
  7897. // Free all the memory
  7898. return false;
  7899. }
  7900. // Process all mesh data, add meshes
  7901. for (uint32_t i = 0; i < mesh_count; ++i)
  7902. {
  7903. gs_asset_mesh_raw_data_t* m = &meshes[i];
  7904. for (uint32_t p = 0; p < m->prim_count; ++p)
  7905. {
  7906. // Construct primitive
  7907. gs_asset_mesh_primitive_t prim = gs_default_val();
  7908. prim.count = m->index_sizes[p] / sizeof(uint16_t);
  7909. // Vertex buffer decl
  7910. gs_graphics_vertex_buffer_desc_t vdesc = gs_default_val();
  7911. vdesc.data = m->vertices[p];
  7912. vdesc.size = m->vertex_sizes[p];
  7913. // Construct vertex buffer for primitive
  7914. prim.vbo = gs_graphics_vertex_buffer_create(&vdesc);
  7915. // Index buffer decl
  7916. gs_graphics_index_buffer_desc_t idesc = gs_default_val();
  7917. idesc.data = m->indices[p];
  7918. idesc.size = m->index_sizes[p];
  7919. // Construct index buffer for primitive
  7920. prim.ibo = gs_graphics_index_buffer_create(&idesc);
  7921. // Add primitive to mesh
  7922. gs_dyn_array_push(mesh->primitives, prim);
  7923. }
  7924. }
  7925. // Free all mesh data
  7926. return true;
  7927. }
  7928. /*========================
  7929. // GS_LEXER
  7930. ========================*/
  7931. //==== [ Token ] ============================================================//
  7932. GS_API_DECL gs_token_t gs_token_invalid_token()
  7933. {
  7934. gs_token_t t = gs_default_val();
  7935. t.text = "";
  7936. t.type = GS_TOKEN_UNKNOWN;
  7937. t.len = 0;
  7938. return t;
  7939. }
  7940. GS_API_DECL bool gs_token_compare_type(const gs_token_t* t, gs_token_type type)
  7941. {
  7942. return (t->type == type);
  7943. }
  7944. GS_API_DECL bool gs_token_compare_text(const gs_token_t* t, const char* match)
  7945. {
  7946. if (t->len != gs_string_length(match)) return false;
  7947. return (gs_string_compare_equal_n(t->text, match, t->len));
  7948. }
  7949. GS_API_DECL void gs_token_print_text(const gs_token_t* t)
  7950. {
  7951. gs_println("%.*s\n", t->len, t->text);
  7952. }
  7953. GS_API_DECL void gs_token_debug_print(const gs_token_t* t)
  7954. {
  7955. gs_println("%s: %.*s", gs_token_type_to_str(t->type), t->len, t->text);
  7956. }
  7957. GS_API_DECL const char* gs_token_type_to_str(gs_token_type type)
  7958. {
  7959. switch (type)
  7960. {
  7961. default:
  7962. case GS_TOKEN_UNKNOWN: return gs_to_str(GS_TOKEN_UNKNOWN); break;
  7963. case GS_TOKEN_LPAREN: return gs_to_str(GS_TOKEN_LPAREN); break;
  7964. case GS_TOKEN_RPAREN: return gs_to_str(GS_TOKEN_RPAREN); break;
  7965. case GS_TOKEN_LTHAN: return gs_to_str(GS_TOKEN_LTHAN); break;
  7966. case GS_TOKEN_GTHAN: return gs_to_str(GS_TOKEN_GTHAN); break;
  7967. case GS_TOKEN_SEMICOLON: return gs_to_str(GS_TOKEN_SEMICOLON); break;
  7968. case GS_TOKEN_COLON: return gs_to_str(GS_TOKEN_COLON); break;
  7969. case GS_TOKEN_COMMA: return gs_to_str(GS_TOKEN_COMMA); break;
  7970. case GS_TOKEN_EQUAL: return gs_to_str(GS_TOKEN_EQUAL); break;
  7971. case GS_TOKEN_NOT: return gs_to_str(GS_TOKEN_NOT); break;
  7972. case GS_TOKEN_HASH: return gs_to_str(GS_TOKEN_HASH); break;
  7973. case GS_TOKEN_PIPE: return gs_to_str(GS_TOKEN_PIPE); break;
  7974. case GS_TOKEN_AMPERSAND:return gs_to_str(GS_TOKEN_AMPERSAND); break;
  7975. case GS_TOKEN_LBRACE: return gs_to_str(GS_TOKEN_LBRACE); break;
  7976. case GS_TOKEN_RBRACE: return gs_to_str(GS_TOKEN_RBRACE); break;
  7977. case GS_TOKEN_LBRACKET: return gs_to_str(GS_TOKEN_LBRACKET); break;
  7978. case GS_TOKEN_RBRACKET: return gs_to_str(GS_TOKEN_RBRACKET); break;
  7979. case GS_TOKEN_MINUS: return gs_to_str(GS_TOKEN_MINUS); break;
  7980. case GS_TOKEN_PLUS: return gs_to_str(GS_TOKEN_PLUS); break;
  7981. case GS_TOKEN_ASTERISK: return gs_to_str(GS_TOKEN_ASTERISK); break;
  7982. case GS_TOKEN_BSLASH: return gs_to_str(GS_TOKEN_BLASH); break;
  7983. case GS_TOKEN_FSLASH: return gs_to_str(GS_TOKEN_FLASH); break;
  7984. case GS_TOKEN_QMARK: return gs_to_str(GS_TOKEN_QMARK); break;
  7985. case GS_TOKEN_DOLLAR: return gs_to_str(GS_TOKEN_DOLLAR); break;
  7986. case GS_TOKEN_SPACE: return gs_to_str(GS_TOKEN_SPACE); break;
  7987. case GS_TOKEN_NEWLINE: return gs_to_str(GS_TOKEN_NEWLINE); break;
  7988. case GS_TOKEN_TAB: return gs_to_str(GS_TOKEN_TAB); break;
  7989. case GS_TOKEN_SINGLE_LINE_COMMENT: return gs_to_str(GS_TOKEN_SINGLE_LINE_COMMENT); break;
  7990. case GS_TOKEN_MULTI_LINE_COMMENT: return gs_to_str(GS_TOKEN_MULTI_LINE_COMMENT); break;
  7991. case GS_TOKEN_IDENTIFIER: return gs_to_str(GS_TOKEN_IDENTIFIER); break;
  7992. case GS_TOKEN_NUMBER: return gs_to_str(GS_TOKEN_NUMBER); break;
  7993. case GS_TOKEN_PERIOD: return gs_to_str(GS_TOKEN_PERIOD); break;
  7994. case GS_TOKEN_STRING: return gs_to_str(GS_TOKEN_STRING); break;
  7995. }
  7996. }
  7997. GS_API_DECL bool gs_char_is_null_term(char c)
  7998. {
  7999. return (c == '\0');
  8000. }
  8001. GS_API_DECL bool gs_char_is_end_of_line(char c)
  8002. {
  8003. return (c == '\n' || c == '\r');
  8004. }
  8005. GS_API_DECL bool gs_char_is_white_space(char c)
  8006. {
  8007. return (c == '\t' || c == ' ' || gs_char_is_end_of_line(c));
  8008. }
  8009. GS_API_DECL bool gs_char_is_alpha(char c)
  8010. {
  8011. return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
  8012. }
  8013. GS_API_DECL bool gs_char_is_numeric(char c)
  8014. {
  8015. return (c >= '0' && c <= '9');
  8016. }
  8017. //==== [ Lexer ] ============================================================//
  8018. GS_API_DECL void gs_lexer_set_contents(gs_lexer_t* lex, const char* contents)
  8019. {
  8020. lex->at = contents;
  8021. lex->current_token = gs_token_invalid_token();
  8022. }
  8023. GS_API_DECL bool gs_lexer_c_can_lex(gs_lexer_t* lex)
  8024. {
  8025. bool size_pass = lex->contents_size ? lex->size < lex->contents_size : true;
  8026. return (size_pass && lex->at && !gs_char_is_null_term(*(lex->at)));
  8027. }
  8028. GS_API_DECL void gs_lexer_set_token(gs_lexer_t* lex, gs_token_t token)
  8029. {
  8030. lex->at = token.text;
  8031. lex->current_token = token;
  8032. }
  8033. GS_API_DECL void gs_lexer_c_eat_white_space(gs_lexer_t* lex)
  8034. {
  8035. for (;;)
  8036. {
  8037. if (gs_char_is_white_space(*lex->at))
  8038. {
  8039. if (gs_char_is_end_of_line(*lex->at)) {lex->line++;}
  8040. lex->at++;
  8041. }
  8042. // Single line comment
  8043. else if ((lex->at[0] == '/') && (lex->at[1]) && (lex->at[1] == '/'))
  8044. {
  8045. lex->at += 2;
  8046. while (*lex->at && !gs_char_is_end_of_line(*lex->at))
  8047. {
  8048. lex->at++;
  8049. }
  8050. }
  8051. // Multi-line comment
  8052. else if ((lex->at[0] == '/') && (lex->at[1]) && (lex->at[1] == '*'))
  8053. {
  8054. lex->at += 2;
  8055. while (lex->at[0] && lex->at[1] && !(lex->at[0] == '*' && lex->at[1] == '/'))
  8056. {
  8057. // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;}
  8058. lex->at++;
  8059. }
  8060. if (lex->at[0] == '*')
  8061. {
  8062. lex->at++;
  8063. }
  8064. }
  8065. else
  8066. {
  8067. break;
  8068. }
  8069. }
  8070. }
  8071. GS_API_DECL gs_token_t
  8072. gs_lexer_c_next_token(gs_lexer_t* lex)
  8073. {
  8074. if (lex->skip_white_space)
  8075. {
  8076. lex->eat_white_space(lex);
  8077. }
  8078. gs_token_t t = gs_token_invalid_token();
  8079. t.text = lex->at;
  8080. t.len = 1;
  8081. if (lex->can_lex(lex))
  8082. {
  8083. char c = *lex->at;
  8084. switch (c)
  8085. {
  8086. case '(': {t.type = GS_TOKEN_LPAREN; lex->at++;} break;
  8087. case ')': {t.type = GS_TOKEN_RPAREN; lex->at++;} break;
  8088. case '<': {t.type = GS_TOKEN_LTHAN; lex->at++;} break;
  8089. case '>': {t.type = GS_TOKEN_GTHAN; lex->at++;} break;
  8090. case ';': {t.type = GS_TOKEN_SEMICOLON; lex->at++;} break;
  8091. case ':': {t.type = GS_TOKEN_COLON; lex->at++;} break;
  8092. case ',': {t.type = GS_TOKEN_COMMA; lex->at++;} break;
  8093. case '=': {t.type = GS_TOKEN_EQUAL; lex->at++;} break;
  8094. case '!': {t.type = GS_TOKEN_NOT; lex->at++;} break;
  8095. case '#': {t.type = GS_TOKEN_HASH; lex->at++;} break;
  8096. case '|': {t.type = GS_TOKEN_PIPE; lex->at++;} break;
  8097. case '&': {t.type = GS_TOKEN_AMPERSAND; lex->at++;} break;
  8098. case '{': {t.type = GS_TOKEN_LBRACE; lex->at++;} break;
  8099. case '}': {t.type = GS_TOKEN_RBRACE; lex->at++;} break;
  8100. case '[': {t.type = GS_TOKEN_LBRACKET; lex->at++;} break;
  8101. case ']': {t.type = GS_TOKEN_RBRACKET; lex->at++;} break;
  8102. case '+': {t.type = GS_TOKEN_PLUS; lex->at++;} break;
  8103. case '*': {t.type = GS_TOKEN_ASTERISK; lex->at++;} break;
  8104. case '\\': {t.type = GS_TOKEN_BSLASH; lex->at++;} break;
  8105. case '?': {t.type = GS_TOKEN_QMARK; lex->at++;} break;
  8106. case '%': {t.type = GS_TOKEN_PERCENT; lex->at++;} break;
  8107. case '$': {t.type = GS_TOKEN_DOLLAR; lex->at++;} break;
  8108. case ' ': {t.type = GS_TOKEN_SPACE; lex->at++;} break;
  8109. case '\n': {t.type = GS_TOKEN_NEWLINE; lex->at++;} break;
  8110. case '\r': {t.type = GS_TOKEN_NEWLINE; lex->at++;} break;
  8111. case '\t': {t.type = GS_TOKEN_TAB; lex->at++;} break;
  8112. case '.': {t.type = GS_TOKEN_PERIOD; lex->at++;} break;
  8113. case '-':
  8114. {
  8115. if (lex->at[1] && !gs_char_is_numeric(lex->at[1]))
  8116. {
  8117. t.type = GS_TOKEN_MINUS;
  8118. lex->at++;
  8119. }
  8120. else
  8121. {
  8122. lex->at++;
  8123. uint32_t num_decimals = 0;
  8124. while (
  8125. lex->at[0] &&
  8126. (gs_char_is_numeric(lex->at[0]) ||
  8127. (lex->at[0] == '.' && num_decimals == 0) ||
  8128. lex->at[0] == 'f')
  8129. )
  8130. {
  8131. // Grab decimal
  8132. num_decimals = lex->at[0] == '.' ? num_decimals + 1 : num_decimals;
  8133. //Increment
  8134. lex->at++;
  8135. }
  8136. t.len = lex->at - t.text;
  8137. t.type = GS_TOKEN_NUMBER;
  8138. }
  8139. } break;
  8140. case '/':
  8141. {
  8142. // Single line comment
  8143. if ((lex->at[0] == '/') && (lex->at[1]) && (lex->at[1] == '/'))
  8144. {
  8145. lex->at += 2;
  8146. while (lex->at[0] && !gs_char_is_end_of_line(lex->at[0]))
  8147. {
  8148. lex->at++;
  8149. }
  8150. t.len = lex->at - t.text;
  8151. t.type = GS_TOKEN_SINGLE_LINE_COMMENT;
  8152. }
  8153. // Multi line comment
  8154. else if ((lex->at[0] == '/') && (lex->at[1]) && (lex->at[1] == '*'))
  8155. {
  8156. lex->at += 2;
  8157. while (lex->can_lex(lex))
  8158. {
  8159. // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;}
  8160. if (lex->at[0] == '*' && lex->at[1] == '/')
  8161. {
  8162. lex->at += 2;
  8163. break;
  8164. }
  8165. lex->at++;
  8166. }
  8167. t.len = lex->at - t.text;
  8168. t.type = GS_TOKEN_MULTI_LINE_COMMENT;
  8169. }
  8170. // it's just a forward slash
  8171. else
  8172. {
  8173. t.type = GS_TOKEN_FSLASH;
  8174. lex->at++;
  8175. }
  8176. } break;
  8177. case '"':
  8178. {
  8179. // Move forward after finding first quotation
  8180. lex->at++;
  8181. while (lex->at && *lex->at != '"')
  8182. {
  8183. // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;}
  8184. if (lex->at[0] == '\\' && lex->at[1])
  8185. {
  8186. lex->at++;
  8187. }
  8188. lex->at++;
  8189. }
  8190. //Move past quotation
  8191. lex->at++;
  8192. t.len = lex->at - t.text;
  8193. t.type = GS_TOKEN_STRING;
  8194. } break;
  8195. // Alpha/Numeric/Identifier
  8196. default:
  8197. {
  8198. if ((gs_char_is_alpha(c) || c == '_') && c != '-')
  8199. {
  8200. while (
  8201. gs_char_is_alpha(lex->at[0]) ||
  8202. gs_char_is_numeric(lex->at[0]) ||
  8203. lex->at[0] == '_'
  8204. )
  8205. {
  8206. lex->at++;
  8207. }
  8208. t.len = lex->at - t.text;
  8209. t.type = GS_TOKEN_IDENTIFIER;
  8210. }
  8211. else if (gs_char_is_numeric(c) && c != '-')
  8212. {
  8213. uint32_t num_decimals = 0;
  8214. while (
  8215. gs_char_is_numeric(lex->at[0]) ||
  8216. (lex->at[0] == '.' && num_decimals == 0) ||
  8217. lex->at[0] == 'f'
  8218. )
  8219. {
  8220. // Grab decimal
  8221. num_decimals = lex->at[0] == '.' ? num_decimals + 1 : num_decimals;
  8222. //Increment
  8223. lex->at++;
  8224. }
  8225. t.len = lex->at - t.text;
  8226. t.type = GS_TOKEN_NUMBER;
  8227. }
  8228. else
  8229. {
  8230. t.type = GS_TOKEN_UNKNOWN;
  8231. lex->at++;
  8232. }
  8233. } break;
  8234. }
  8235. }
  8236. // Set current token for lex
  8237. lex->current_token = t;
  8238. // Record size
  8239. lex->size += t.len;
  8240. return t;
  8241. }
  8242. GS_API_DECL gs_token_t gs_lexer_next_token(gs_lexer_t* lex)
  8243. {
  8244. return lex->next_token(lex);
  8245. }
  8246. GS_API_DECL bool gs_lexer_can_lex(gs_lexer_t* lex)
  8247. {
  8248. return lex->can_lex(lex);
  8249. }
  8250. GS_API_DECL gs_token_t gs_lexer_current_token(const gs_lexer_t* lex)
  8251. {
  8252. return lex->current_token;
  8253. }
  8254. GS_API_DECL bool gs_lexer_current_token_compare_type(const gs_lexer_t* lex, gs_token_type type)
  8255. {
  8256. return (lex->current_token.type == type);
  8257. }
  8258. GS_API_DECL gs_token_t gs_lexer_peek(gs_lexer_t* lex)
  8259. {
  8260. // Store current at and current token
  8261. const char* at = lex->at;
  8262. gs_token_t cur_t = gs_lexer_current_token(lex);
  8263. // Get next token
  8264. gs_token_t next_t = lex->next_token(lex);
  8265. // Reset
  8266. lex->current_token = cur_t;
  8267. lex->at = at;
  8268. // Return
  8269. return next_t;
  8270. }
  8271. // Check to see if token type of next valid token matches 'match'. Restores place in lex if not.
  8272. GS_API_DECL bool gs_lexer_require_token_text(gs_lexer_t* lex, const char* match)
  8273. {
  8274. // Store current position and token
  8275. const char* at = lex->at;
  8276. gs_token_t cur_t = lex->current_token;
  8277. // Get next token
  8278. gs_token_t next_t = lex->next_token(lex);
  8279. // Compare token text
  8280. if (gs_token_compare_text(&next_t, match))
  8281. {
  8282. return true;
  8283. }
  8284. // Error
  8285. gs_println("error::gs_lexer_require_token_text::%.*s, expected: %s", cur_t.len, cur_t.text, match);
  8286. // Reset
  8287. lex->at = at;
  8288. lex->current_token = cur_t;
  8289. return false;
  8290. }
  8291. GS_API_DECL bool gs_lexer_require_token_type(gs_lexer_t* lex, gs_token_type type)
  8292. {
  8293. // Store current position and token
  8294. const char* at = lex->at;
  8295. gs_token_t cur_t = lex->current_token;
  8296. // Get next token
  8297. gs_token_t next_t = lex->next_token(lex);
  8298. // Compare token type
  8299. if (gs_token_compare_type(&next_t, type))
  8300. {
  8301. return true;
  8302. }
  8303. // Error
  8304. // gs_println("error::gs_lexer_require_token_type::%s, expected: %s", gs_token_type_to_str(next_t.type), gs_token_type_to_str(type));
  8305. // Reset
  8306. lex->at = at;
  8307. lex->current_token = cur_t;
  8308. return false;
  8309. }
  8310. // Advances until next token of given type is found
  8311. GS_API_DECL bool gs_lexer_find_next_token_type(gs_lexer_t* lex, gs_token_type type)
  8312. {
  8313. gs_token_t t = lex->next_token(lex);
  8314. while (lex->can_lex(lex))
  8315. {
  8316. if (gs_token_compare_type(&t, type))
  8317. {
  8318. return true;
  8319. }
  8320. t = lex->next_token(lex);
  8321. }
  8322. return false;
  8323. }
  8324. GS_API_DECL gs_token_t
  8325. gs_lexer_advance_before_next_token_type(gs_lexer_t* lex, gs_token_type type)
  8326. {
  8327. gs_token_t t = lex->current_token;
  8328. gs_token_t peek_t = gs_lexer_peek(lex);
  8329. // Continue right up until required token type
  8330. while (!gs_token_compare_type(&peek_t, type))
  8331. {
  8332. t = lex->next_token(lex);
  8333. peek_t = gs_lexer_peek(lex);
  8334. }
  8335. return t;
  8336. }
  8337. GS_API_DECL gs_lexer_t
  8338. gs_lexer_c_ctor(const char* contents)
  8339. {
  8340. gs_lexer_t lex = gs_default_val();
  8341. lex.contents = contents;
  8342. lex.at = contents;
  8343. lex.can_lex = gs_lexer_c_can_lex;
  8344. lex.eat_white_space = gs_lexer_c_eat_white_space;
  8345. lex.next_token = gs_lexer_c_next_token;
  8346. lex.skip_white_space = true;
  8347. return lex;
  8348. }
  8349. /*=============================
  8350. // GS_ENGINE
  8351. =============================*/
  8352. GS_API_DECL void
  8353. gs_default_app_func();
  8354. GS_API_DECL void
  8355. gs_default_main_window_close_callback(void* window);
  8356. // Global instance of gunslinger framework (...THERE CAN ONLY BE ONE)
  8357. gs_global gs_t* _gs_instance = gs_default_val();
  8358. GS_API_DECL gs_t*
  8359. gs_create(gs_app_desc_t app_desc)
  8360. {
  8361. if (gs_instance() == NULL)
  8362. {
  8363. // Check app desc for defaults
  8364. if (app_desc.window.width == 0) app_desc.window.width = 800;
  8365. if (app_desc.window.height == 0) app_desc.window.height = 600;
  8366. if (app_desc.window.title == 0) app_desc.window.title = "App";
  8367. if (app_desc.window.frame_rate <= 0.f) app_desc.window.frame_rate = 60.f;
  8368. if (app_desc.update == NULL) app_desc.update = &gs_default_app_func;
  8369. if (app_desc.shutdown == NULL) app_desc.shutdown = &gs_default_app_func;
  8370. if (app_desc.init == NULL) app_desc.init = &gs_default_app_func;
  8371. // Set up os api before all?
  8372. gs_os_api_t os = gs_os_api_new();
  8373. // Construct instance and set
  8374. _gs_instance = (gs_t*)os.malloc(sizeof(gs_t));
  8375. memset(_gs_instance, 0, sizeof(gs_t));
  8376. gs_instance()->ctx.lock = SCHED_PIPE_INVALID;
  8377. // Set os api now allocated
  8378. gs_instance()->ctx.os = os;
  8379. // Set application description for framework
  8380. gs_instance()->ctx.app = app_desc;
  8381. // Set up function pointers
  8382. gs_instance()->shutdown = &gs_destroy;
  8383. // Need to have video settings passed down from user
  8384. gs_subsystem(platform) = gs_platform_create();
  8385. // Enable graphics API debugging
  8386. gs_subsystem(platform)->settings.video.graphics.debug = app_desc.debug_gfx;
  8387. // Default initialization for platform here
  8388. gs_platform_init(gs_subsystem(platform));
  8389. // Set frame rate for application
  8390. gs_subsystem(platform)->time.max_fps = app_desc.window.frame_rate;
  8391. // Construct main window
  8392. gs_platform_window_create(&app_desc.window);
  8393. // Set vsync for video
  8394. gs_platform_enable_vsync(app_desc.window.vsync);
  8395. // Construct graphics api
  8396. gs_subsystem(graphics) = gs_graphics_create();
  8397. // Initialize graphics here
  8398. gs_graphics_init(gs_subsystem(graphics));
  8399. // Construct audio api
  8400. gs_subsystem(audio) = gs_audio_create();
  8401. // Initialize audio
  8402. gs_audio_init(gs_subsystem(audio));
  8403. // Initialize application and set to running
  8404. app_desc.init();
  8405. gs_ctx()->app.is_running = true;
  8406. // Set default callback for when main window close button is pressed
  8407. gs_platform_set_window_close_callback(gs_platform_main_window(), &gs_default_main_window_close_callback);
  8408. }
  8409. return gs_instance();
  8410. }
  8411. GS_API_DECL void
  8412. gs_set_instance(gs_t* gs)
  8413. {
  8414. _gs_instance = gs;
  8415. }
  8416. GS_API_DECL gs_t*
  8417. gs_instance()
  8418. {
  8419. return _gs_instance;
  8420. }
  8421. GS_API_DECL gs_context_t*
  8422. gs_ctx()
  8423. {
  8424. return &gs_instance()->ctx;
  8425. }
  8426. GS_API_DECL gs_app_desc_t*
  8427. gs_app()
  8428. {
  8429. return &gs_instance()->ctx.app;
  8430. }
  8431. // Define main frame function for framework to step
  8432. GS_API_DECL void
  8433. gs_frame()
  8434. {
  8435. // Remove these...
  8436. static uint32_t curr_ticks = 0;
  8437. static uint32_t prev_ticks = 0;
  8438. // Cache platform pointer
  8439. gs_platform_t* platform = gs_subsystem(platform);
  8440. // Cache times at start of frame
  8441. platform->time.elapsed = (float)gs_platform_elapsed_time();
  8442. platform->time.update = platform->time.elapsed - platform->time.previous;
  8443. platform->time.previous = platform->time.elapsed;
  8444. // Update platform and process input
  8445. gs_platform_update(platform);
  8446. if (!gs_instance()->ctx.app.is_running) {
  8447. gs_instance()->shutdown();
  8448. return;
  8449. }
  8450. // Process application context
  8451. gs_instance()->ctx.app.update();
  8452. if (!gs_instance()->ctx.app.is_running) {
  8453. gs_instance()->shutdown();
  8454. return;
  8455. }
  8456. // Clear all platform events
  8457. gs_dyn_array_clear(platform->events);
  8458. // NOTE(John): This won't work forever. Must change eventually.
  8459. // Swap all platform window buffers? Sure...
  8460. for
  8461. (
  8462. gs_slot_array_iter it = 0;
  8463. gs_slot_array_iter_valid(platform->windows, it);
  8464. gs_slot_array_iter_advance(platform->windows, it)
  8465. )
  8466. {
  8467. gs_platform_window_swap_buffer(it);
  8468. }
  8469. // Frame locking (not sure if this should be done here, but it is what it is)
  8470. platform->time.elapsed = (float)gs_platform_elapsed_time();
  8471. platform->time.render = platform->time.elapsed - platform->time.previous;
  8472. platform->time.previous = platform->time.elapsed;
  8473. platform->time.frame = platform->time.update + platform->time.render; // Total frame time
  8474. platform->time.delta = platform->time.frame / 1000.f;
  8475. float target = (1000.f / platform->time.max_fps);
  8476. if (platform->time.frame < target)
  8477. {
  8478. gs_platform_sleep((float)(target - platform->time.frame));
  8479. platform->time.elapsed = (float)gs_platform_elapsed_time();
  8480. double wait_time = platform->time.elapsed - platform->time.previous;
  8481. platform->time.previous = platform->time.elapsed;
  8482. platform->time.frame += wait_time;
  8483. platform->time.delta = platform->time.frame / 1000.f;
  8484. }
  8485. }
  8486. void gs_destroy()
  8487. {
  8488. // Shutdown application
  8489. gs_ctx()->app.shutdown();
  8490. gs_ctx()->app.is_running = false;
  8491. // Shutdown subsystems
  8492. gs_graphics_shutdown(gs_subsystem(graphics));
  8493. gs_graphics_destroy(gs_subsystem(graphics));
  8494. gs_audio_shutdown(gs_subsystem(audio));
  8495. gs_audio_destroy(gs_subsystem(audio));
  8496. gs_platform_shutdown(gs_subsystem(platform));
  8497. gs_platform_destroy(gs_subsystem(platform));
  8498. }
  8499. GS_API_DECL void
  8500. gs_default_app_func()
  8501. {
  8502. // Nothing...
  8503. }
  8504. GS_API_DECL void
  8505. gs_default_main_window_close_callback(void* window)
  8506. {
  8507. gs_instance()->ctx.app.is_running = false;
  8508. }
  8509. void gs_quit()
  8510. {
  8511. #ifndef GS_PLATFORM_WEB
  8512. gs_instance()->ctx.app.is_running = false;
  8513. #endif
  8514. }
  8515. #undef GS_IMPL
  8516. #endif // GS_IMPL
  8517. #endif // GS_H
  8518. /*
  8519. Layout decl
  8520. // Pipeline should have layout desc for vertices?
  8521. // Or should it have layout for EACH buffer?
  8522. non-interleaved vertex data
  8523. have to be able to specific stride/offset for vertex layouts
  8524. What are ways to interleave data?
  8525. layout descriptor?
  8526. gs_vertex_attribute_type layouts[] =
  8527. {
  8528. };
  8529. // Need to codify strides/offsets/divisors
  8530. // This can hold multiple layouts
  8531. gs_vertex_layout_desc_t layout =
  8532. {
  8533. .layouts = layouts,
  8534. .size = sizeof(layouts)
  8535. };
  8536. Don't want to have to make user calculate strides, right?
  8537. // If you don't provide manual stride/offset, then it'll calculate it for you based on layout?
  8538. #version 330 core
  8539. layout (location = 0) in vec2 aPos;
  8540. layout (location = 1) in vec3 aColor;
  8541. layout (location = 2) in vec2 aOffset;
  8542. out vec3 fColor;
  8543. void main()
  8544. {
  8545. gl_Position = vec4(aPos + aOffset, 0.0, 1.0);
  8546. fColor = aColor;
  8547. }
  8548. typedef struct gs_vertex_attribute_layout_desc_t {
  8549. gs_vertex_attribute_type format;
  8550. size_t stride;
  8551. size_t offset;
  8552. size_t divisor;
  8553. } gs_vertex_attribute_layout_desc_t;
  8554. gs_vertex_attribute_layout_desc_t layout[] = {
  8555. {.format = GS_VERTEX_ATTRIBUTE_FLOAT2},
  8556. {.format = GS_VERTEX_ATTRIBUTE_FLOAT3},
  8557. {.format = GS_VERTEX_ATTRIBUTE_FLOAT2, .stride = 2 * sizeof(float), .offset = 0, .divisor = 1}
  8558. };
  8559. What about non-interleaved data? Almost would need to provide an offset.
  8560. It's specific to the data itself, so have to provide manual offsets for data in binding data
  8561. gs_graphics_bind_desc_t binds[] = {
  8562. {.type = GS_GRAPHICS_BIND_VERTEX_BUFFER, .buffer = , .offset = };
  8563. }
  8564. gs_graphics_bind_desc_t binds[] = {
  8565. (gs_graphics_bind_desc_t){.type = GS_GRAPHICS_BIND_VERTEX_BUFFER, .buffer = vbo, .offset = ...},
  8566. (gs_graphics_bind_desc_t){.type = GS_GRAPHICS_BIND_VERTEX_BUFFER, .buffer = vbo, .offset = ...},
  8567. };
  8568. .layout = {
  8569. .attributes = &(){
  8570. {.format = GS_VERTEX_ATTRIBUTE_FLOAT2},
  8571. {.format = GS_VERTEX_ATTRIBUTE_FLOAT2},
  8572. {.format = GS_VERTEX_ATTRIBUTE_FLOAT4, .stride = 64, .offset =, .divisor = }
  8573. }
  8574. };
  8575. sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
  8576. .shader = shd,
  8577. .layout = {
  8578. .attrs = {
  8579. [0].format=SG_VERTEXFORMAT_FLOAT3,
  8580. [1].format=SG_VERTEXFORMAT_FLOAT4
  8581. }
  8582. }
  8583. });
  8584. .layout = {
  8585. .attrs = attrs,
  8586. .attr_size = sizeof(attrs),
  8587. .strides = strides,
  8588. .stride_size = sizeof(strides),
  8589. }
  8590. sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){
  8591. .layout = {
  8592. .buffers = {
  8593. [0] = { .stride = 28 },
  8594. [1] = { .stride = 12, .step_func=SG_VERTEXSTEP_PER_INSTANCE }
  8595. },
  8596. .attrs = {
  8597. [0] = { .offset = 0, .format=SG_VERTEXFORMAT_FLOAT3, .buffer_index=0 },
  8598. [1] = { .offset = 12, .format=SG_VERTEXFORMAT_FLOAT4, .buffer_index=0 },
  8599. [2] = { .offset = 0, .format=SG_VERTEXFORMAT_FLOAT3, .buffer_index=1 }
  8600. }
  8601. },
  8602. .shader = shd,
  8603. .index_type = SG_INDEXTYPE_UINT16,
  8604. .depth_stencil = {
  8605. .depth_compare_func = SG_COMPAREFUNC_LESS_EQUAL,
  8606. .depth_write_enabled = true
  8607. },
  8608. .rasterizer.cull_mode = SG_CULLMODE_BACK
  8609. });
  8610. float quadVertices[] = {
  8611. // positions // colors
  8612. -0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
  8613. 0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
  8614. -0.05f, -0.05f, 0.0f, 0.0f, 1.0f,
  8615. -0.05f, 0.05f, 1.0f, 0.0f, 0.0f,
  8616. 0.05f, -0.05f, 0.0f, 1.0f, 0.0f,
  8617. 0.05f, 0.05f, 0.0f, 1.0f, 1.0f
  8618. };
  8619. // also set instance data
  8620. glEnableVertexAttribArray(2);
  8621. glBindBuffer(GL_ARRAY_BUFFER, instanceVBO); // this attribute comes from a different vertex buffer
  8622. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
  8623. glBindBuffer(GL_ARRAY_BUFFER, 0);
  8624. glVertexAttribDivisor(2, 1); // tell OpenGL this is an instanced vertex attribute.
  8625. gltf loading
  8626. Mesh Attributes:
  8627. cgltf_attribute_type_invalid,
  8628. cgltf_attribute_type_position,
  8629. cgltf_attribute_type_normal,
  8630. cgltf_attribute_type_tangent,
  8631. cgltf_attribute_type_texcoord,
  8632. cgltf_attribute_type_color,
  8633. cgltf_attribute_type_joints,
  8634. cgltf_attribute_type_weights,
  8635. Primitive types:
  8636. cgltf_primitive_type_points,
  8637. cgltf_primitive_type_lines,
  8638. cgltf_primitive_type_line_loop,
  8639. cgltf_primitive_type_line_strip,
  8640. cgltf_primitive_type_triangles,
  8641. cgltf_primitive_type_triangle_strip,
  8642. cgltf_primitive_type_triangle_fan,
  8643. For each mesh:
  8644. For each primitive:
  8645. For each attribute:
  8646. Get data and push into mesh definition
  8647. Is there a way to have the user be able to specify a layout and then use that for the mesh?
  8648. gs_enum_decl(gs_asset_mesh_attribute_type,
  8649. GS_ASSET_MESH_ATTRIBUTE_TYPE_POSITION,
  8650. GS_ASSET_MESH_ATTRIBUTE_TYPE_NORMAL,
  8651. GS_ASSET_MESH_ATTRIBUTE_TYPE_TANGENT,
  8652. GS_ASSET_MESH_ATTRIBUTE_TYPE_JOINT,
  8653. GS_ASSET_MESH_ATTRIBUTE_TYPE_WEIGHT,
  8654. GS_ASSET_MESH_ATTRIBUTE_TYPE_TEXCOORD,
  8655. GS_ASSET_MESH_ATTRIBUTE_TYPE_COLOR
  8656. });
  8657. typedef struct gs_asset_mesh_layout_t {
  8658. gs_asset_mesh_attribute_type type; // Type of attribute
  8659. uint32_t idx; // Optional index (for joint/weight/texcoord/color)
  8660. } gs_asset_mesh_layout_t;
  8661. typedef struct gs_asset_mesh_decl_t
  8662. {
  8663. gs_asset_mesh_layout_t* layout; // Mesh attribute layout array
  8664. size_t layout_size; // Size of mesh attribute layout array in bytes
  8665. } gs_asset_mesh_decl_t;
  8666. // Mesh holds...what?
  8667. // A pipeline? Shouldn't have to.
  8668. // Material? Nope.
  8669. // It's just mesh data. (so an index/vertex buffer)
  8670. typedef struct gs_asset_mesh_t
  8671. {
  8672. gs_handle(gs_graphics_buffer_t) vbo;
  8673. gs_handle(gs_graphics_buffer_t) ibo;
  8674. } gs_asset_mesh_t;
  8675. void gs_asset_mesh_load_from_file(const char* path, void* out, gs_asset_mesh_decl_t* decl, void* data_out, size_t data_size)
  8676. {
  8677. gs_asset_mesh_t* mesh = (gs_asset_mesh_t*)out;
  8678. // Parse gltf data
  8679. }
  8680. Does this need to line up with a pipeline? Not necessarily, right?
  8681. // At LEAST position is required to be passed in for the layout, so maybe it's not necessary
  8682. // to provide this in the layout?
  8683. // Can you duplicate? I don't think so...
  8684. gs_asset_mesh_attribute_type layout[] =
  8685. {
  8686. POSITION,
  8687. NORMAL,
  8688. TANGENT,
  8689. JOINTS_XXX,
  8690. WEIGHTS_XXX,
  8691. TEXCOORD_XXX,
  8692. COLOR_XXX
  8693. };
  8694. gs_asset_mesh_t mesh = gs_asset_load_gltf(path, layout, sizeof(layout));
  8695. // Do you HAVE to have certain attributes for a mesh to make any sense? For instance, do you HAVE to have position?
  8696. // What if position is NOT the first attribute layout for your vertex attribute?
  8697. // Need to fill out data for each attribute, then interleave?
  8698. ^()
  8699. {
  8700. For each mesh:
  8701. For each primitive:
  8702. For each attribute:
  8703. Get data and push into mesh definition
  8704. }
  8705. main update for web? android? probably want to move to different "main" implementations:
  8706. gs_win32_main
  8707. gs_glfw_linux_main
  8708. gs_glfw_osx_main
  8709. gs_glfw_win32_main
  8710. gs_glfw_emsc_main
  8711. Each platform should define its own main function, control its own loop, reach into application code, then
  8712. run how it needs to.
  8713. int main(int32_t argc, char** argv)
  8714. {
  8715. emscripten_set_main_loop(gs_create(gs_main(argc, argv))->run(), 0, true);
  8716. }
  8717. */