ui_shared.cpp 263 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323
  1. //
  2. // string allocation/managment
  3. // leave this at the top of all UI_xxxx files for PCH reasons...
  4. //
  5. #include "../server/exe_headers.h"
  6. #include "ui_local.h"
  7. //rww - added for ui ghoul2 models
  8. #define UI_SHARED_CPP
  9. #include "../game/anims.h"
  10. #include "../cgame/animtable.h"
  11. #include "ui_shared.h"
  12. #include "menudef.h"
  13. void UI_LoadMenus(const char *menuFile, qboolean reset);
  14. #ifdef _XBOX
  15. #include "../win32/glw_win_dx8.h"
  16. #include "../renderer/tr_lightmanager.h"
  17. //MAP HACK!
  18. extern cvar_t *cl_mapname;
  19. void Menu_MapHack(int key);
  20. //JLF DEMOCODE MPMOVED
  21. //support for attract mode demo timer
  22. #define DEMO_TIME_MAX 45000 //g_demoTimeBeforeStart
  23. int g_demoLastKeypress = 0; //milliseconds
  24. bool g_ReturnToSplash = false;
  25. bool g_runningDemo = false;
  26. void G_DemoStart();
  27. void G_DemoEnd();
  28. void G_DemoKeypress();
  29. void PlayDemo();
  30. void UpdateDemoTimer();
  31. bool TestDemoTimer();
  32. //END DEMOCODE
  33. //JLF used by sliders MPMOVED
  34. #define TICK_COUNT 16
  35. //JLF MORE PROTOTYPES MPMOVED
  36. qboolean Item_SetFocus(itemDef_t *item, float x, float y);
  37. qboolean Item_HandleAction(itemDef_t * item);
  38. qboolean Item_HandleSelectionNext(itemDef_t * item);
  39. qboolean Item_HandleSelectionPrev(itemDef_t * item);
  40. #endif
  41. extern vmCvar_t ui_char_color_red;
  42. extern vmCvar_t ui_char_color_green;
  43. extern vmCvar_t ui_char_color_blue;
  44. void *UI_Alloc( int size );
  45. void Controls_GetConfig( void );
  46. void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount);
  47. void Item_Init(itemDef_t *item);
  48. void Item_InitControls(itemDef_t *item);
  49. qboolean Item_Parse(itemDef_t *item);
  50. void Item_RunScript(itemDef_t *item, const char *s);
  51. void Item_SetupKeywordHash(void);
  52. void Item_Text_AutoWrapped_Paint(itemDef_t *item);
  53. void Item_UpdatePosition(itemDef_t *item);
  54. void Item_ValidateTypeData(itemDef_t *item);
  55. void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t);
  56. itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p);
  57. itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name);
  58. void Menu_Paint(menuDef_t *menu, qboolean forcePaint);
  59. void Menu_SetupKeywordHash(void);
  60. void Menus_ShowItems(const char *menuName);
  61. qboolean ParseRect(const char **p, rectDef_t *r);
  62. const char *String_Alloc(const char *p);
  63. void ToWindowCoords(float *x, float *y, windowDef_t *window);
  64. void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle);
  65. int Item_ListBox_ThumbDrawPosition(itemDef_t *item);
  66. int Item_ListBox_ThumbPosition(itemDef_t *item);
  67. int Item_ListBox_MaxScroll(itemDef_t *item);
  68. static qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) ;
  69. static qboolean Item_Paint(itemDef_t *item, qboolean bDraw);
  70. int Item_TextScroll_ThumbDrawPosition ( itemDef_t *item );
  71. static void Item_TextScroll_BuildLines ( itemDef_t* item );
  72. qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag) ;
  73. //static qboolean debugMode = qfalse;
  74. static qboolean g_waitingForKey = qfalse;
  75. static qboolean g_editingField = qfalse;
  76. static itemDef_t *g_bindItem = NULL;
  77. static itemDef_t *g_editItem = NULL;
  78. static itemDef_t *itemCapture = NULL; // item that has the mouse captured ( if any )
  79. #define DOUBLE_CLICK_DELAY 300
  80. static int lastListBoxClickTime = 0;
  81. static void (*captureFunc) (void *p) = NULL;
  82. static void *captureData = NULL;
  83. //const char defaultString[10] = {"default"};
  84. #ifndef _XBOX
  85. #ifdef CGAME
  86. #define MEM_POOL_SIZE 128 * 1024
  87. #else
  88. #define MEM_POOL_SIZE 1024 * 1024
  89. #endif
  90. #endif // _XBOX
  91. #define SCROLL_TIME_START 500
  92. #define SCROLL_TIME_ADJUST 150
  93. #define SCROLL_TIME_ADJUSTOFFSET 40
  94. #define SCROLL_TIME_FLOOR 20
  95. typedef struct scrollInfo_s {
  96. int nextScrollTime;
  97. int nextAdjustTime;
  98. int adjustValue;
  99. int scrollKey;
  100. float xStart;
  101. float yStart;
  102. itemDef_t *item;
  103. qboolean scrollDir;
  104. } scrollInfo_t;
  105. static scrollInfo_t scrollInfo;
  106. #ifndef _XBOX
  107. static char memoryPool[MEM_POOL_SIZE];
  108. #endif
  109. static int allocPoint, outOfMemory;
  110. displayContextDef_t *DC = NULL;
  111. menuDef_t Menus[MAX_MENUS]; // defined menus
  112. int menuCount = 0; // how many
  113. menuDef_t *menuStack[MAX_OPEN_MENUS];
  114. int openMenuCount = 0;
  115. static int strPoolIndex = 0;
  116. static char strPool[STRING_POOL_SIZE];
  117. typedef struct stringDef_s {
  118. struct stringDef_s *next;
  119. const char *str;
  120. } stringDef_t;
  121. #define HASH_TABLE_SIZE 2048
  122. static int strHandleCount = 0;
  123. static stringDef_t *strHandle[HASH_TABLE_SIZE];
  124. typedef struct itemFlagsDef_s {
  125. char *string;
  126. int value;
  127. } itemFlagsDef_t;
  128. itemFlagsDef_t itemFlags [] = {
  129. "WINDOW_INACTIVE", WINDOW_INACTIVE,
  130. NULL, NULL
  131. };
  132. char *styles [] = {
  133. "WINDOW_STYLE_EMPTY",
  134. "WINDOW_STYLE_FILLED",
  135. "WINDOW_STYLE_GRADIENT",
  136. "WINDOW_STYLE_SHADER",
  137. "WINDOW_STYLE_TEAMCOLOR",
  138. "WINDOW_STYLE_CINEMATIC",
  139. NULL
  140. };
  141. char *types [] = {
  142. "ITEM_TYPE_TEXT",
  143. "ITEM_TYPE_BUTTON",
  144. "ITEM_TYPE_RADIOBUTTON",
  145. "ITEM_TYPE_CHECKBOX",
  146. "ITEM_TYPE_EDITFIELD",
  147. "ITEM_TYPE_COMBO",
  148. "ITEM_TYPE_LISTBOX",
  149. "ITEM_TYPE_MODEL",
  150. "ITEM_TYPE_OWNERDRAW",
  151. "ITEM_TYPE_NUMERICFIELD",
  152. "ITEM_TYPE_SLIDER",
  153. "ITEM_TYPE_YESNO",
  154. "ITEM_TYPE_MULTI",
  155. "ITEM_TYPE_BIND",
  156. "ITEM_TYPE_TEXTSCROLL",
  157. NULL
  158. };
  159. char *alignment [] = {
  160. "ITEM_ALIGN_LEFT",
  161. "ITEM_ALIGN_CENTER",
  162. "ITEM_ALIGN_RIGHT",
  163. NULL
  164. };
  165. /*
  166. ==================
  167. Init_Display
  168. Initializes the display with a structure to all the drawing routines
  169. ==================
  170. */
  171. void Init_Display(displayContextDef_t *dc)
  172. {
  173. DC = dc;
  174. }
  175. /*
  176. ==================
  177. Window_Init
  178. Initializes a window structure ( windowDef_t ) with defaults
  179. ==================
  180. */
  181. void Window_Init(Window *w)
  182. {
  183. memset(w, 0, sizeof(windowDef_t));
  184. w->borderSize = 1;
  185. w->foreColor[0] = w->foreColor[1] = w->foreColor[2] = w->foreColor[3] = 1.0;
  186. // w->cinematic = -1;
  187. }
  188. /*
  189. =================
  190. PC_SourceError
  191. =================
  192. */
  193. #ifndef _XBOX
  194. void PC_SourceError(int handle, char *format, ...)
  195. {
  196. int line;
  197. char filename[128];
  198. va_list argptr;
  199. static char string[4096];
  200. va_start (argptr, format);
  201. vsprintf (string, format, argptr);
  202. va_end (argptr);
  203. filename[0] = '\0';
  204. line = 0;
  205. Com_Printf(S_COLOR_RED "ERROR: %s, line %d: %s\n", filename, line, string);
  206. }
  207. #endif
  208. /*
  209. =================
  210. PC_ParseStringMem
  211. =================
  212. */
  213. //static vector<string> RetryPool;
  214. //void AddMenuPackageRetryKey(const char *psSPPackage)
  215. //{
  216. // RetryPool.push_back(psSPPackage);
  217. //}
  218. qboolean PC_ParseStringMem(const char **out)
  219. {
  220. const char *temp;
  221. if (PC_ParseString(&temp))
  222. {
  223. return qfalse;
  224. }
  225. *(out) = String_Alloc(temp);
  226. return qtrue;
  227. }
  228. /*
  229. =================
  230. PC_ParseRect
  231. =================
  232. */
  233. qboolean PC_ParseRect(rectDef_t *r)
  234. {
  235. if (!PC_ParseFloat(&r->x))
  236. {
  237. if (!PC_ParseFloat(&r->y))
  238. {
  239. if (!PC_ParseFloat(&r->w))
  240. {
  241. if (!PC_ParseFloat(&r->h))
  242. {
  243. return qtrue;
  244. }
  245. }
  246. }
  247. }
  248. return qfalse;
  249. }
  250. /*
  251. =================
  252. PC_Script_Parse
  253. =================
  254. */
  255. qboolean PC_Script_Parse(const char **out)
  256. {
  257. char script[4096];
  258. // pc_token_t token;
  259. char *token2;
  260. script[0]=0;
  261. // scripts start with { and have ; separated command lists.. commands are command, arg..
  262. // basically we want everything between the { } as it will be interpreted at run time
  263. token2 = PC_ParseExt();
  264. if (!token2)
  265. {
  266. return qfalse;
  267. }
  268. if (*token2 !='{')
  269. {
  270. return qfalse;
  271. }
  272. while ( 1 )
  273. {
  274. token2 = PC_ParseExt();
  275. if (!token2)
  276. {
  277. return qfalse;
  278. }
  279. if (*token2 =='}') // End of the script?
  280. {
  281. *out = String_Alloc(script);
  282. return qtrue;
  283. }
  284. if (*(token2 +1) != '\0')
  285. {
  286. Q_strcat(script, sizeof(script), va("\"%s\"", token2));
  287. }
  288. else
  289. {
  290. Q_strcat(script, sizeof(script), token2);
  291. }
  292. Q_strcat(script, sizeof(script), " ");
  293. }
  294. }
  295. //--------------------------------------------------------------------------------------------
  296. // Menu Keyword Parse functions
  297. //--------------------------------------------------------------------------------------------
  298. /*
  299. =================
  300. MenuParse_font
  301. =================
  302. */
  303. qboolean MenuParse_font( itemDef_t *item)
  304. {
  305. menuDef_t *menu = (menuDef_t*)item;
  306. if (!PC_ParseStringMem(&menu->font))
  307. {
  308. return qfalse;
  309. }
  310. if (!DC->Assets.fontRegistered)
  311. {
  312. DC->Assets.qhMediumFont = DC->registerFont(menu->font);
  313. DC->Assets.fontRegistered = qtrue;
  314. }
  315. return qtrue;
  316. }
  317. /*
  318. =================
  319. MenuParse_name
  320. =================
  321. */
  322. qboolean MenuParse_name(itemDef_t *item)
  323. {
  324. menuDef_t *menu = (menuDef_t*)item;
  325. if (!PC_ParseStringMem((const char **) &menu->window.name))
  326. {
  327. return qfalse;
  328. }
  329. // if (Q_stricmp(menu->window.name, "main") == 0)
  330. // {
  331. // default main as having focus
  332. // menu->window.flags |= WINDOW_HASFOCUS;
  333. // }
  334. return qtrue;
  335. }
  336. /*
  337. =================
  338. MenuParse_fullscreen
  339. =================
  340. */
  341. qboolean MenuParse_fullscreen( itemDef_t *item )
  342. {
  343. menuDef_t *menu = (menuDef_t*)item;
  344. if (PC_ParseInt((int *) &menu->fullScreen))
  345. {
  346. return qfalse;
  347. }
  348. return qtrue;
  349. }
  350. /*
  351. =================
  352. MenuParse_rect
  353. =================
  354. */
  355. qboolean MenuParse_rect( itemDef_t *item)
  356. {
  357. menuDef_t *menu = (menuDef_t*)item;
  358. if (!PC_ParseRect(&menu->window.rect))
  359. {
  360. return qfalse;
  361. }
  362. return qtrue;
  363. }
  364. /*
  365. =================
  366. MenuParse_style
  367. =================
  368. */
  369. qboolean MenuParse_style( itemDef_t *item)
  370. {
  371. int i;
  372. const char *tempStr;
  373. menuDef_t *menu = (menuDef_t*)item;
  374. if (PC_ParseString(&tempStr))
  375. {
  376. return qfalse;
  377. }
  378. i=0;
  379. while (styles[i])
  380. {
  381. if (Q_stricmp(tempStr,styles[i])==0)
  382. {
  383. menu->window.style = i;
  384. break;
  385. }
  386. i++;
  387. }
  388. if (styles[i] == NULL)
  389. {
  390. PC_ParseWarning(va("Unknown menu style value '%s'",tempStr));
  391. }
  392. return qtrue;
  393. }
  394. /*
  395. =================
  396. MenuParse_visible
  397. =================
  398. */
  399. qboolean MenuParse_visible( itemDef_t *item )
  400. {
  401. int i;
  402. menuDef_t *menu = (menuDef_t*)item;
  403. if (PC_ParseInt(&i))
  404. {
  405. return qfalse;
  406. }
  407. if (i)
  408. {
  409. menu->window.flags |= WINDOW_VISIBLE;
  410. }
  411. return qtrue;
  412. }
  413. /*
  414. =================
  415. MenuParse_ignoreescape
  416. =================
  417. */
  418. qboolean MenuParse_ignoreescape( itemDef_t *item )
  419. {
  420. int i;
  421. menuDef_t *menu = (menuDef_t*)item;
  422. if (PC_ParseInt(&i))
  423. {
  424. return qfalse;
  425. }
  426. if (i)
  427. {
  428. menu->window.flags |= WINDOW_IGNORE_ESCAPE;
  429. }
  430. return qtrue;
  431. }
  432. /*
  433. =================
  434. MenuParse_onOpen
  435. =================
  436. */
  437. qboolean MenuParse_onOpen( itemDef_t *item)
  438. {
  439. menuDef_t *menu = (menuDef_t*)item;
  440. if (!PC_Script_Parse(&menu->onOpen))
  441. {
  442. return qfalse;
  443. }
  444. return qtrue;
  445. }
  446. /*
  447. =================
  448. MenuParse_onClose
  449. =================
  450. */
  451. qboolean MenuParse_onClose( itemDef_t *item )
  452. {
  453. menuDef_t *menu = (menuDef_t*)item;
  454. if (!PC_Script_Parse(&menu->onClose))
  455. {
  456. return qfalse;
  457. }
  458. return qtrue;
  459. }
  460. //JLFACCEPT MPMOVED
  461. /*
  462. =================
  463. MenuParse_onAccept
  464. =================
  465. */
  466. qboolean MenuParse_onAccept( itemDef_t *item )
  467. {
  468. menuDef_t *menu = (menuDef_t*)item;
  469. if (!PC_Script_Parse(&menu->onAccept))
  470. {
  471. return qfalse;
  472. }
  473. return qtrue;
  474. }
  475. /*
  476. =================
  477. MenuParse_onESC
  478. =================
  479. */
  480. qboolean MenuParse_onESC( itemDef_t *item )
  481. {
  482. menuDef_t *menu = (menuDef_t*)item;
  483. if (!PC_Script_Parse(&menu->onESC))
  484. {
  485. return qfalse;
  486. }
  487. return qtrue;
  488. }
  489. qboolean MenuParse_xScript( itemDef_t *item )
  490. {
  491. menuDef_t *menu = (menuDef_t*)item;
  492. if (!PC_Script_Parse(&menu->xScript))
  493. {
  494. return qfalse;
  495. }
  496. return qtrue;
  497. }
  498. qboolean MenuParse_yScript( itemDef_t *item )
  499. {
  500. menuDef_t *menu = (menuDef_t*)item;
  501. if (!PC_Script_Parse(&menu->yScript))
  502. {
  503. return qfalse;
  504. }
  505. return qtrue;
  506. }
  507. qboolean MenuParse_whiteScript( itemDef_t *item )
  508. {
  509. menuDef_t *menu = (menuDef_t*)item;
  510. if (!PC_Script_Parse(&menu->whiteScript))
  511. {
  512. return qfalse;
  513. }
  514. return qtrue;
  515. }
  516. /*
  517. =================
  518. MenuParse_border
  519. =================
  520. */
  521. qboolean MenuParse_border( itemDef_t *item)
  522. {
  523. menuDef_t *menu = (menuDef_t*)item;
  524. if (PC_ParseInt(&menu->window.border))
  525. {
  526. return qfalse;
  527. }
  528. return qtrue;
  529. }
  530. /*
  531. =================
  532. MenuParse_borderSize
  533. =================
  534. */
  535. qboolean MenuParse_borderSize( itemDef_t *item)
  536. {
  537. menuDef_t *menu = (menuDef_t*)item;
  538. if (PC_ParseFloat(&menu->window.borderSize))
  539. {
  540. return qfalse;
  541. }
  542. return qtrue;
  543. }
  544. /*
  545. =================
  546. MenuParse_backcolor
  547. =================
  548. */
  549. qboolean MenuParse_backcolor( itemDef_t *item )
  550. {
  551. int i;
  552. float f;
  553. menuDef_t *menu = (menuDef_t*)item;
  554. for (i = 0; i < 4; i++)
  555. {
  556. if (PC_ParseFloat(&f))
  557. {
  558. return qfalse;
  559. }
  560. menu->window.backColor[i] = f;
  561. }
  562. return qtrue;
  563. }
  564. /*
  565. =================
  566. MenuParse_forecolor
  567. =================
  568. */
  569. qboolean MenuParse_forecolor( itemDef_t *item)
  570. {
  571. int i;
  572. float f;
  573. menuDef_t *menu = (menuDef_t*)item;
  574. for (i = 0; i < 4; i++)
  575. {
  576. if (PC_ParseFloat(&f))
  577. {
  578. return qfalse;
  579. }
  580. if (f < 0)
  581. { //special case for player color
  582. menu->window.flags |= WINDOW_PLAYERCOLOR;
  583. return qtrue;
  584. }
  585. menu->window.foreColor[i] = f;
  586. menu->window.flags |= WINDOW_FORECOLORSET;
  587. }
  588. return qtrue;
  589. }
  590. /*
  591. =================
  592. MenuParse_bordercolor
  593. =================
  594. */
  595. qboolean MenuParse_bordercolor( itemDef_t *item )
  596. {
  597. int i;
  598. float f;
  599. menuDef_t *menu = (menuDef_t*)item;
  600. for (i = 0; i < 4; i++)
  601. {
  602. if (PC_ParseFloat(&f))
  603. {
  604. return qfalse;
  605. }
  606. menu->window.borderColor[i] = f;
  607. }
  608. return qtrue;
  609. }
  610. /*
  611. =================
  612. MenuParse_focuscolor
  613. =================
  614. */
  615. qboolean MenuParse_focuscolor( itemDef_t *item)
  616. {
  617. int i;
  618. float f;
  619. menuDef_t *menu = (menuDef_t*)item;
  620. for (i = 0; i < 4; i++)
  621. {
  622. if (PC_ParseFloat(&f))
  623. {
  624. return qfalse;
  625. }
  626. menu->focusColor[i] = f;
  627. }
  628. return qtrue;
  629. }
  630. /*
  631. =================
  632. MenuParse_focuscolor
  633. =================
  634. */
  635. qboolean MenuParse_appearanceIncrement( itemDef_t *item)
  636. {
  637. menuDef_t *menu = (menuDef_t*)item;
  638. if (PC_ParseFloat(&menu->appearanceIncrement))
  639. {
  640. return qfalse;
  641. }
  642. return qtrue;
  643. }
  644. /*
  645. =================
  646. MenuParse_descAlignment
  647. =================
  648. */
  649. qboolean MenuParse_descAlignment( itemDef_t *item)
  650. {
  651. menuDef_t *menu = (menuDef_t*)item;
  652. const char *tempStr;
  653. int i;
  654. if (PC_ParseString(&tempStr))
  655. {
  656. return qfalse;
  657. }
  658. i=0;
  659. while (alignment[i])
  660. {
  661. if (Q_stricmp(tempStr,alignment[i])==0)
  662. {
  663. menu->descAlignment = i;
  664. break;
  665. }
  666. i++;
  667. }
  668. if (alignment[i] == NULL)
  669. {
  670. PC_ParseWarning(va("Unknown desc alignment value '%s'",tempStr));
  671. }
  672. return qtrue;
  673. }
  674. /*
  675. =================
  676. MenuParse_descTextStyle
  677. =================
  678. */
  679. qboolean MenuParse_descTextStyle( itemDef_t *item)
  680. {
  681. menuDef_t *menu = (menuDef_t*)item;
  682. if (PC_ParseInt(&menu->descTextStyle))
  683. {
  684. return qfalse;
  685. }
  686. return qtrue;
  687. }
  688. /*
  689. =================
  690. MenuParse_descX
  691. =================
  692. */
  693. qboolean MenuParse_descX( itemDef_t *item)
  694. {
  695. menuDef_t *menu = (menuDef_t*)item;
  696. if (PC_ParseInt(&menu->descX))
  697. {
  698. return qfalse;
  699. }
  700. return qtrue;
  701. }
  702. /*
  703. =================
  704. MenuParse_descY
  705. =================
  706. */
  707. qboolean MenuParse_descY( itemDef_t *item)
  708. {
  709. menuDef_t *menu = (menuDef_t*)item;
  710. if (PC_ParseInt(&menu->descY))
  711. {
  712. return qfalse;
  713. }
  714. return qtrue;
  715. }
  716. /*
  717. =================
  718. MenuParse_descScale
  719. =================
  720. */
  721. qboolean MenuParse_descScale( itemDef_t *item)
  722. {
  723. menuDef_t *menu = (menuDef_t*)item;
  724. if (PC_ParseFloat(&menu->descScale))
  725. {
  726. return qfalse;
  727. }
  728. return qtrue;
  729. }
  730. /*
  731. =================
  732. MenuParse_descColor
  733. =================
  734. */
  735. qboolean MenuParse_descColor( itemDef_t *item)
  736. {
  737. int i;
  738. float f;
  739. menuDef_t *menu = (menuDef_t*)item;
  740. for (i = 0; i < 4; i++)
  741. {
  742. if (PC_ParseFloat(&f))
  743. {
  744. return qfalse;
  745. }
  746. menu->descColor[i] = f;
  747. }
  748. return qtrue;
  749. }
  750. /*
  751. =================
  752. MenuParse_disablecolor
  753. =================
  754. */
  755. qboolean MenuParse_disablecolor( itemDef_t *item)
  756. {
  757. int i;
  758. float f;
  759. menuDef_t *menu = (menuDef_t*)item;
  760. for (i = 0; i < 4; i++)
  761. {
  762. if (PC_ParseFloat(&f))
  763. {
  764. return qfalse;
  765. }
  766. menu->disableColor[i] = f;
  767. }
  768. return qtrue;
  769. }
  770. /*
  771. =================
  772. MenuParse_outlinecolor
  773. =================
  774. */
  775. /*
  776. qboolean MenuParse_outlinecolor( itemDef_t *item)
  777. {
  778. menuDef_t *menu = (menuDef_t*)item;
  779. if (PC_ParseColor(&menu->window.outlineColor))
  780. {
  781. return qfalse;
  782. }
  783. return qtrue;
  784. }
  785. */
  786. /*
  787. =================
  788. MenuParse_background
  789. =================
  790. */
  791. qboolean MenuParse_background( itemDef_t *item)
  792. {
  793. const char *buff;
  794. menuDef_t *menu = (menuDef_t*)item;
  795. if (PC_ParseString(&buff))
  796. {
  797. return qfalse;
  798. }
  799. menu->window.background = ui.R_RegisterShaderNoMip(buff);
  800. return qtrue;
  801. }
  802. /*
  803. =================
  804. MenuParse_cinematic
  805. =================
  806. */
  807. /*
  808. qboolean MenuParse_cinematic( itemDef_t *item)
  809. {
  810. menuDef_t *menu = (menuDef_t*)item;
  811. if (!PC_ParseStringMem((const char **) &menu->window.cinematicName))
  812. {
  813. return qfalse;
  814. }
  815. return qtrue;
  816. }
  817. */
  818. /*
  819. =================
  820. MenuParse_ownerdrawFlag
  821. =================
  822. */
  823. qboolean MenuParse_ownerdrawFlag( itemDef_t *item)
  824. {
  825. int i;
  826. menuDef_t *menu = (menuDef_t*)item;
  827. if (PC_ParseInt(&i))
  828. {
  829. return qfalse;
  830. }
  831. menu->window.ownerDrawFlags |= i;
  832. return qtrue;
  833. }
  834. /*
  835. =================
  836. MenuParse_ownerdraw
  837. =================
  838. */
  839. qboolean MenuParse_ownerdraw( itemDef_t *item)
  840. {
  841. menuDef_t *menu = (menuDef_t*)item;
  842. if (PC_ParseInt(&menu->window.ownerDraw))
  843. {
  844. return qfalse;
  845. }
  846. return qtrue;
  847. }
  848. /*
  849. =================
  850. MenuParse_popup
  851. =================
  852. */
  853. qboolean MenuParse_popup( itemDef_t *item)
  854. {
  855. menuDef_t *menu = (menuDef_t*)item;
  856. menu->window.flags |= WINDOW_POPUP;
  857. return qtrue;
  858. }
  859. /*
  860. =================
  861. MenuParse_outOfBounds
  862. =================
  863. */
  864. qboolean MenuParse_outOfBounds( itemDef_t *item)
  865. {
  866. menuDef_t *menu = (menuDef_t*)item;
  867. menu->window.flags |= WINDOW_OOB_CLICK;
  868. return qtrue;
  869. }
  870. /*
  871. =================
  872. MenuParse_soundLoop
  873. =================
  874. */
  875. qboolean MenuParse_soundLoop( itemDef_t *item)
  876. {
  877. menuDef_t *menu = (menuDef_t*)item;
  878. if (!PC_ParseStringMem((const char **) &menu->soundName))
  879. {
  880. return qfalse;
  881. }
  882. return qtrue;
  883. }
  884. /*
  885. ================
  886. MenuParse_fadeClamp
  887. ================
  888. */
  889. qboolean MenuParse_fadeClamp( itemDef_t *item)
  890. {
  891. menuDef_t *menu = (menuDef_t*)item;
  892. if (PC_ParseFloat(&menu->fadeClamp))
  893. {
  894. return qfalse;
  895. }
  896. return qtrue;
  897. }
  898. /*
  899. ================
  900. MenuParse_fadeAmount
  901. ================
  902. */
  903. qboolean MenuParse_fadeAmount( itemDef_t *item)
  904. {
  905. menuDef_t *menu = (menuDef_t*)item;
  906. if (PC_ParseFloat(&menu->fadeAmount))
  907. {
  908. return qfalse;
  909. }
  910. return qtrue;
  911. }
  912. /*
  913. ================
  914. MenuParse_fadeCycle
  915. ================
  916. */
  917. qboolean MenuParse_fadeCycle( itemDef_t *item)
  918. {
  919. menuDef_t *menu = (menuDef_t*)item;
  920. if (PC_ParseInt(&menu->fadeCycle))
  921. {
  922. return qfalse;
  923. }
  924. return qtrue;
  925. }
  926. /*
  927. ================
  928. MenuParse_itemDef
  929. ================
  930. */
  931. qboolean MenuParse_itemDef( itemDef_t *item)
  932. {
  933. menuDef_t *menu = (menuDef_t*)item;
  934. if (menu->itemCount < MAX_MENUITEMS)
  935. {
  936. // Hack. Check for a levelname after "itemDef" - if so, only parse it
  937. // if we're on that level. Avoids loading wedge all over the place.
  938. const char *token;
  939. if (PC_ParseString(&token))
  940. return qfalse;
  941. // Check for non-brace could be "protocol" or "wedge":
  942. if (*token != '{')
  943. {
  944. const char *mapname = Cvar_VariableString( "mapname" );
  945. // Wedge should only be loaded in t2_wedge:
  946. if( (Q_stricmp(token, "wedge") == 0) && // itemDef is wedge
  947. (Q_stricmp(mapname, "t2_wedge") != 0) ) // not t2_wedge
  948. {
  949. // Skip this itemDef entirely, but don't fail:
  950. PC_SkipBracedSection();
  951. return qtrue;
  952. }
  953. // C3PO should only be loaded in tier2, and academy3:
  954. if( (Q_stricmp(token, "protocol") == 0) && // itemDef is c3po
  955. (!strstr(mapname, "t2_")) && // not a t2 level
  956. (Q_stricmp(mapname, "academy3") != 0) ) // not academy3
  957. {
  958. // Skip this itemDef entirely, but don't fail:
  959. PC_SkipBracedSection();
  960. return qtrue;
  961. }
  962. // OK. We're on the right level. Eat the real '{':
  963. PC_ParseString(&token);
  964. if (*token != '{')
  965. return qfalse;
  966. }
  967. menu->items[menu->itemCount] = (struct itemDef_s *) UI_Alloc(sizeof(itemDef_t));
  968. Item_Init(menu->items[menu->itemCount]);
  969. if (!Item_Parse(menu->items[menu->itemCount]))
  970. {
  971. return qfalse;
  972. }
  973. Item_InitControls(menu->items[menu->itemCount]);
  974. menu->items[menu->itemCount++]->parent = menu;
  975. }
  976. else
  977. {
  978. PC_ParseWarning(va("Exceeded item/menu max of %d", MAX_MENUITEMS));
  979. }
  980. return qtrue;
  981. }
  982. #define KEYWORDHASH_SIZE 512
  983. typedef struct keywordHash_s
  984. {
  985. char *keyword;
  986. qboolean (*func)(itemDef_t *item);
  987. struct keywordHash_s *next;
  988. } keywordHash_t;
  989. keywordHash_t menuParseKeywords[] = {
  990. {"appearanceIncrement", MenuParse_appearanceIncrement},
  991. {"backcolor", MenuParse_backcolor, },
  992. {"background", MenuParse_background, },
  993. {"border", MenuParse_border, },
  994. {"bordercolor", MenuParse_bordercolor, },
  995. {"borderSize", MenuParse_borderSize, },
  996. // {"cinematic", MenuParse_cinematic, },
  997. {"descAlignment", MenuParse_descAlignment },
  998. {"descTextStyle", MenuParse_descTextStyle },
  999. {"desccolor", MenuParse_descColor },
  1000. {"descX", MenuParse_descX },
  1001. {"descY", MenuParse_descY },
  1002. {"descScale", MenuParse_descScale },
  1003. {"disablecolor", MenuParse_disablecolor, },
  1004. {"fadeClamp", MenuParse_fadeClamp, },
  1005. {"fadeCycle", MenuParse_fadeCycle, },
  1006. {"fadeAmount", MenuParse_fadeAmount, },
  1007. {"focuscolor", MenuParse_focuscolor, },
  1008. {"font", MenuParse_font, },
  1009. {"forecolor", MenuParse_forecolor, },
  1010. {"fullscreen", MenuParse_fullscreen, },
  1011. {"itemDef", MenuParse_itemDef, },
  1012. {"name", MenuParse_name, },
  1013. {"onClose", MenuParse_onClose, },
  1014. //JLFACCEPT MPMOVED
  1015. {"onAccept", MenuParse_onAccept, },
  1016. {"onESC", MenuParse_onESC, },
  1017. {"xScript", MenuParse_xScript, },
  1018. {"yScript", MenuParse_yScript, },
  1019. {"whiteScript", MenuParse_whiteScript, },
  1020. {"onOpen", MenuParse_onOpen, },
  1021. // {"outlinecolor", MenuParse_outlinecolor, },
  1022. {"outOfBoundsClick", MenuParse_outOfBounds, },
  1023. {"ownerdraw", MenuParse_ownerdraw, },
  1024. {"ownerdrawFlag", MenuParse_ownerdrawFlag,},
  1025. {"popup", MenuParse_popup, },
  1026. {"rect", MenuParse_rect, },
  1027. {"soundLoop", MenuParse_soundLoop, },
  1028. {"style", MenuParse_style, },
  1029. {"visible", MenuParse_visible, },
  1030. {"ignoreescape", MenuParse_ignoreescape, },
  1031. {NULL, NULL, }
  1032. };
  1033. keywordHash_t *menuParseKeywordHash[KEYWORDHASH_SIZE];
  1034. /*
  1035. ================
  1036. KeywordHash_Key
  1037. ================
  1038. */
  1039. int KeywordHash_Key(const char *keyword)
  1040. {
  1041. int register hash, i;
  1042. hash = 0;
  1043. for (i = 0; keyword[i] != '\0'; i++) {
  1044. if (keyword[i] >= 'A' && keyword[i] <= 'Z')
  1045. hash += (keyword[i] + ('a' - 'A')) * (119 + i);
  1046. else
  1047. hash += keyword[i] * (119 + i);
  1048. }
  1049. hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE-1);
  1050. return hash;
  1051. }
  1052. /*
  1053. ================
  1054. KeywordHash_Add
  1055. ================
  1056. */
  1057. void KeywordHash_Add(keywordHash_t *table[], keywordHash_t *key)
  1058. {
  1059. int hash;
  1060. hash = KeywordHash_Key(key->keyword);
  1061. key->next = table[hash];
  1062. table[hash] = key;
  1063. }
  1064. /*
  1065. ===============
  1066. KeywordHash_Find
  1067. ===============
  1068. */
  1069. keywordHash_t *KeywordHash_Find(keywordHash_t *table[], const char *keyword)
  1070. {
  1071. keywordHash_t *key;
  1072. int hash;
  1073. hash = KeywordHash_Key(keyword);
  1074. for (key = table[hash]; key; key = key->next)
  1075. {
  1076. if (!Q_stricmp(key->keyword, keyword))
  1077. return key;
  1078. }
  1079. return NULL;
  1080. }
  1081. /*
  1082. ================
  1083. hashForString
  1084. return a hash value for the string
  1085. ================
  1086. */
  1087. static long hashForString(const char *str)
  1088. {
  1089. int i;
  1090. long hash;
  1091. char letter;
  1092. hash = 0;
  1093. i = 0;
  1094. while (str[i] != '\0')
  1095. {
  1096. letter = tolower((unsigned char)str[i]);
  1097. hash+=(long)(letter)*(i+119);
  1098. i++;
  1099. }
  1100. hash &= (HASH_TABLE_SIZE-1);
  1101. return hash;
  1102. }
  1103. /*
  1104. =================
  1105. String_Alloc
  1106. =================
  1107. */
  1108. const char *String_Alloc(const char *p)
  1109. {
  1110. int len;
  1111. long hash;
  1112. stringDef_t *str, *last;
  1113. static const char *staticNULL = "";
  1114. if (p == NULL)
  1115. {
  1116. return NULL;
  1117. }
  1118. if (*p == 0)
  1119. {
  1120. return staticNULL;
  1121. }
  1122. hash = hashForString(p);
  1123. str = strHandle[hash];
  1124. while (str)
  1125. {
  1126. if (strcmp(p, str->str) == 0)
  1127. {
  1128. return str->str;
  1129. }
  1130. str = str->next;
  1131. }
  1132. len = strlen(p);
  1133. if (len + strPoolIndex + 1 < STRING_POOL_SIZE)
  1134. {
  1135. int ph = strPoolIndex;
  1136. strcpy(&strPool[strPoolIndex], p);
  1137. strPoolIndex += len + 1;
  1138. str = strHandle[hash];
  1139. last = str;
  1140. while (last && last->next)
  1141. {
  1142. last = last->next;
  1143. }
  1144. str = (stringDef_s *) UI_Alloc( sizeof(stringDef_t));
  1145. str->next = NULL;
  1146. str->str = &strPool[ph];
  1147. if (last)
  1148. {
  1149. last->next = str;
  1150. }
  1151. else
  1152. {
  1153. strHandle[hash] = str;
  1154. }
  1155. return &strPool[ph];
  1156. }
  1157. else
  1158. {
  1159. Com_Printf("WARNING: Ran out of strPool space\n");
  1160. }
  1161. return NULL;
  1162. }
  1163. /*
  1164. =================
  1165. String_Report
  1166. =================
  1167. */
  1168. void String_Report(void)
  1169. {
  1170. float f;
  1171. Com_Printf("Memory/String Pool Info\n");
  1172. Com_Printf("----------------\n");
  1173. f = strPoolIndex;
  1174. f /= STRING_POOL_SIZE;
  1175. f *= 100;
  1176. Com_Printf("String Pool is %.1f%% full, %i bytes out of %i used.\n", f, strPoolIndex, STRING_POOL_SIZE);
  1177. #ifdef _XBOX
  1178. Com_Printf("Memory Pool is using %i bytes.\n", allocPoint);
  1179. #else
  1180. f = allocPoint;
  1181. f /= MEM_POOL_SIZE;
  1182. f *= 100;
  1183. Com_Printf("Memory Pool is %.1f%% full, %i bytes out of %i used.\n", f, allocPoint, MEM_POOL_SIZE);
  1184. #endif
  1185. }
  1186. /*
  1187. =================
  1188. String_Init
  1189. =================
  1190. */
  1191. void String_Init(void)
  1192. {
  1193. int i;
  1194. for (i = 0; i < HASH_TABLE_SIZE; i++)
  1195. {
  1196. strHandle[i] = 0;
  1197. }
  1198. strHandleCount = 0;
  1199. strPoolIndex = 0;
  1200. UI_InitMemory();
  1201. Item_SetupKeywordHash();
  1202. Menu_SetupKeywordHash();
  1203. if (DC && DC->getBindingBuf)
  1204. {
  1205. Controls_GetConfig();
  1206. }
  1207. }
  1208. //---------------------------------------------------------------------------------------------------------
  1209. // Memory
  1210. //---------------------------------------------------------------------------------------------------------
  1211. /*
  1212. ===============
  1213. UI_Alloc
  1214. ===============
  1215. */
  1216. void *UI_Alloc( int size )
  1217. {
  1218. #ifdef _XBOX
  1219. allocPoint += size;
  1220. return Z_Malloc(size, TAG_UI_ALLOC, qfalse, 4);
  1221. #else
  1222. char *p;
  1223. if ( allocPoint + size > MEM_POOL_SIZE )
  1224. {
  1225. outOfMemory = qtrue;
  1226. if (DC->Print)
  1227. {
  1228. DC->Print("UI_Alloc: Failure. Out of memory!\n");
  1229. }
  1230. return NULL;
  1231. }
  1232. p = &memoryPool[allocPoint];
  1233. allocPoint += ( size + 15 ) & ~15;
  1234. return p;
  1235. #endif
  1236. }
  1237. /*
  1238. ===============
  1239. UI_InitMemory
  1240. ===============
  1241. */
  1242. void UI_InitMemory( void )
  1243. {
  1244. allocPoint = 0;
  1245. outOfMemory = qfalse;
  1246. #ifdef _XBOX
  1247. Z_TagFree(TAG_UI_ALLOC);
  1248. #endif
  1249. }
  1250. /*
  1251. ===============
  1252. Menu_ItemsMatchingGroup
  1253. ===============
  1254. */
  1255. int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name)
  1256. {
  1257. int i;
  1258. int count = 0;
  1259. for (i = 0; i < menu->itemCount; i++)
  1260. {
  1261. if ((!menu->items[i]->window.name) && (!menu->items[i]->window.group))
  1262. {
  1263. Com_Printf(S_COLOR_YELLOW"WARNING: item has neither name or group\n");
  1264. continue;
  1265. }
  1266. if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0))
  1267. {
  1268. count++;
  1269. }
  1270. }
  1271. return count;
  1272. }
  1273. /*
  1274. ===============
  1275. Menu_GetMatchingItemByNumber
  1276. ===============
  1277. */
  1278. itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name)
  1279. {
  1280. int i;
  1281. int count = 0;
  1282. for (i = 0; i < menu->itemCount; i++)
  1283. {
  1284. if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0))
  1285. {
  1286. if (count == index)
  1287. {
  1288. return menu->items[i];
  1289. }
  1290. count++;
  1291. }
  1292. }
  1293. return NULL;
  1294. }
  1295. /*
  1296. ===============
  1297. Menu_FadeItemByName
  1298. ===============
  1299. */
  1300. void Menu_FadeItemByName(menuDef_t *menu, const char *p, qboolean fadeOut)
  1301. {
  1302. itemDef_t *item;
  1303. int i;
  1304. int count = Menu_ItemsMatchingGroup(menu, p);
  1305. for (i = 0; i < count; i++)
  1306. {
  1307. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1308. if (item != NULL)
  1309. {
  1310. if (fadeOut)
  1311. {
  1312. item->window.flags |= (WINDOW_FADINGOUT | WINDOW_VISIBLE);
  1313. item->window.flags &= ~WINDOW_FADINGIN;
  1314. }
  1315. else
  1316. {
  1317. item->window.flags |= (WINDOW_VISIBLE | WINDOW_FADINGIN);
  1318. item->window.flags &= ~WINDOW_FADINGOUT;
  1319. }
  1320. }
  1321. }
  1322. }
  1323. /*
  1324. ==========
  1325. Menu_SetItemDecorationByName
  1326. ==========
  1327. */
  1328. void Menu_SetItemDecorationByName(menuDef_t* menu, const char *p, qboolean bShow)
  1329. {
  1330. itemDef_t *item;
  1331. int i;
  1332. int count;
  1333. count = Menu_ItemsMatchingGroup(menu, p);
  1334. if (!count)
  1335. {
  1336. Com_Printf(S_COLOR_YELLOW"WARNING: Menu_SetItemDecorationByName - unable to locate any items named :%s\n",p);
  1337. }
  1338. for (i = 0; i < count; i++)
  1339. {
  1340. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1341. if (item != NULL)
  1342. {
  1343. if (bShow)
  1344. {
  1345. item->window.flags |= WINDOW_DECORATION;
  1346. }
  1347. else
  1348. {
  1349. item->window.flags &= ~WINDOW_DECORATION;
  1350. }
  1351. }
  1352. }
  1353. }
  1354. /*
  1355. ===============
  1356. Menu_ShowItemByName
  1357. ===============
  1358. */
  1359. void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow)
  1360. {
  1361. itemDef_t *item;
  1362. int i;
  1363. int count;
  1364. count = Menu_ItemsMatchingGroup(menu, p);
  1365. if (!count)
  1366. {
  1367. Com_Printf(S_COLOR_YELLOW"WARNING: Menu_ShowItemByName - unable to locate any items named :%s\n",p);
  1368. }
  1369. for (i = 0; i < count; i++)
  1370. {
  1371. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1372. if (item != NULL)
  1373. {
  1374. if (bShow)
  1375. {
  1376. item->window.flags |= WINDOW_VISIBLE;
  1377. }
  1378. else
  1379. {
  1380. item->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
  1381. // stop cinematics playing in the window
  1382. /*
  1383. if (item->window.cinematic >= 0)
  1384. {
  1385. DC->stopCinematic(item->window.cinematic);
  1386. item->window.cinematic = -1;
  1387. }
  1388. */
  1389. }
  1390. }
  1391. }
  1392. }
  1393. /*
  1394. ===============
  1395. Menu_GetFocused
  1396. ===============
  1397. */
  1398. menuDef_t *Menu_GetFocused(void)
  1399. {
  1400. int i;
  1401. for (i = 0; i < menuCount; i++)
  1402. {
  1403. if ((Menus[i].window.flags & WINDOW_HASFOCUS) && (Menus[i].window.flags & WINDOW_VISIBLE))
  1404. {
  1405. return &Menus[i];
  1406. }
  1407. }
  1408. return NULL;
  1409. }
  1410. /*
  1411. ===============
  1412. Menus_OpenByName
  1413. ===============
  1414. */
  1415. void Menus_OpenByName(const char *p)
  1416. {
  1417. Menus_ActivateByName(p);
  1418. }
  1419. /*
  1420. ===============
  1421. Menus_FindByName
  1422. ===============
  1423. */
  1424. menuDef_t *Menus_FindByName(const char *p)
  1425. {
  1426. int i;
  1427. for (i = 0; i < menuCount; i++)
  1428. {
  1429. if (Q_stricmp(Menus[i].window.name, p) == 0)
  1430. {
  1431. return &Menus[i];
  1432. }
  1433. }
  1434. return NULL;
  1435. }
  1436. /*
  1437. ===============
  1438. Menu_RunCloseScript
  1439. ===============
  1440. */
  1441. static void Menu_RunCloseScript(menuDef_t *menu)
  1442. {
  1443. if (menu && menu->window.flags & WINDOW_VISIBLE && menu->onClose)
  1444. {
  1445. itemDef_t item;
  1446. item.parent = menu;
  1447. Item_RunScript(&item, menu->onClose);
  1448. }
  1449. }
  1450. /*
  1451. ===============
  1452. Item_ActivateByName
  1453. ===============
  1454. */
  1455. void Item_ActivateByName(const char *menuName,const char *itemName)
  1456. {
  1457. itemDef_t *item;
  1458. menuDef_t *menu;
  1459. menu = Menus_FindByName(menuName);
  1460. item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) menu, itemName);
  1461. if (item != NULL)
  1462. {
  1463. item->window.flags &= ~WINDOW_INACTIVE;
  1464. }
  1465. }
  1466. /*
  1467. ===============
  1468. Menus_CloseByName
  1469. ===============
  1470. */
  1471. void Menus_CloseByName(const char *p)
  1472. {
  1473. menuDef_t *menu = Menus_FindByName(p);
  1474. // If the menu wasnt found just exit
  1475. if (menu == NULL)
  1476. {
  1477. return;
  1478. }
  1479. // Run the close script for the menu
  1480. Menu_RunCloseScript(menu);
  1481. // If this window had the focus then take it away
  1482. if ( menu->window.flags & WINDOW_HASFOCUS )
  1483. {
  1484. // If there is something still in the open menu list then
  1485. // set it to have focus now
  1486. if ( openMenuCount )
  1487. {
  1488. // Subtract one from the open menu count to prepare to
  1489. // remove the top menu from the list
  1490. openMenuCount -= 1;
  1491. // Set the top menu to have focus now
  1492. menuStack[openMenuCount]->window.flags |= WINDOW_HASFOCUS;
  1493. // Remove the top menu from the list
  1494. menuStack[openMenuCount] = NULL;
  1495. }
  1496. }
  1497. // Window is now invisible and doenst have focus
  1498. menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
  1499. }
  1500. /*
  1501. ===============
  1502. Menu_FindItemByName
  1503. ===============
  1504. */
  1505. itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p)
  1506. {
  1507. int i;
  1508. if (menu == NULL || p == NULL)
  1509. {
  1510. return NULL;
  1511. }
  1512. for (i = 0; i < menu->itemCount; i++)
  1513. {
  1514. if (Q_stricmp(p, menu->items[i]->window.name) == 0)
  1515. {
  1516. return menu->items[i];
  1517. }
  1518. }
  1519. return NULL;
  1520. }
  1521. /*
  1522. ===============
  1523. Menu_FindVisibleItemByName
  1524. ===============
  1525. */
  1526. itemDef_t *Menu_FindVisibleItemByName(menuDef_t *menu, const char *p)
  1527. {
  1528. int i;
  1529. if (menu == NULL || p == NULL)
  1530. {
  1531. return NULL;
  1532. }
  1533. for (i = 0; i < menu->itemCount; i++)
  1534. {
  1535. if (Q_stricmp(p, menu->items[i]->window.name) == 0)
  1536. {
  1537. if (menu->items[i]->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_ENABLE))
  1538. {
  1539. continue;
  1540. }
  1541. if (menu->items[i]->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_SHOW))
  1542. {
  1543. continue;
  1544. }
  1545. if ( !(menu->items[i]->window.flags & WINDOW_VISIBLE) )
  1546. {
  1547. continue;
  1548. }
  1549. return menu->items[i];
  1550. }
  1551. }
  1552. return NULL;
  1553. }
  1554. /*
  1555. =================
  1556. Menu_ClearFocus
  1557. =================
  1558. */
  1559. itemDef_t *Menu_ClearFocus(menuDef_t *menu)
  1560. {
  1561. int i;
  1562. itemDef_t *ret = NULL;
  1563. if (menu == NULL)
  1564. {
  1565. return NULL;
  1566. }
  1567. for (i = 0; i < menu->itemCount; i++)
  1568. {
  1569. if (menu->items[i]->window.flags & WINDOW_HASFOCUS)
  1570. {
  1571. ret = menu->items[i];
  1572. menu->items[i]->window.flags &= ~WINDOW_HASFOCUS;
  1573. if (menu->items[i]->leaveFocus)
  1574. {
  1575. Item_RunScript(menu->items[i], menu->items[i]->leaveFocus);
  1576. }
  1577. }
  1578. }
  1579. return ret;
  1580. }
  1581. // Set all the items within a given menu, with the given itemName, to the given shader
  1582. void Menu_SetItemBackground(const menuDef_t *menu,const char *itemName, const char *background)
  1583. {
  1584. itemDef_t *item;
  1585. int j, count;
  1586. if (!menu) // No menu???
  1587. {
  1588. return;
  1589. }
  1590. count = Menu_ItemsMatchingGroup( (menuDef_t *) menu, itemName);
  1591. for (j = 0; j < count; j++)
  1592. {
  1593. item = Menu_GetMatchingItemByNumber( (menuDef_t *) menu, j, itemName);
  1594. if (item != NULL)
  1595. {
  1596. // item->window.background = DC->registerShaderNoMip(background);
  1597. item->window.background = ui.R_RegisterShaderNoMip(background);
  1598. }
  1599. }
  1600. }
  1601. // Set all the items within a given menu, with the given itemName, to the given text
  1602. void Menu_SetItemText(const menuDef_t *menu,const char *itemName, const char *text)
  1603. {
  1604. itemDef_t *item;
  1605. int j, count;
  1606. if (!menu) // No menu???
  1607. {
  1608. return;
  1609. }
  1610. count = Menu_ItemsMatchingGroup( (menuDef_t *) menu, itemName);
  1611. for (j = 0; j < count; j++)
  1612. {
  1613. item = Menu_GetMatchingItemByNumber( (menuDef_t *) menu, j, itemName);
  1614. if (item != NULL)
  1615. {
  1616. if (text[0] == '*')
  1617. {
  1618. item->cvar = text+1;
  1619. // Just copying what was in ItemParse_cvar()
  1620. if ( item->typeData)
  1621. {
  1622. editFieldDef_t *editPtr;
  1623. editPtr = (editFieldDef_t*)item->typeData;
  1624. editPtr->minVal = -1;
  1625. editPtr->maxVal = -1;
  1626. editPtr->defVal = -1;
  1627. }
  1628. }
  1629. else
  1630. {
  1631. if (item->type == ITEM_TYPE_TEXTSCROLL )
  1632. {
  1633. char cvartext[1024];
  1634. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  1635. if ( scrollPtr )
  1636. {
  1637. scrollPtr->startPos = 0;
  1638. scrollPtr->endPos = 0;
  1639. }
  1640. if (item->cvar)
  1641. {
  1642. DC->getCVarString(item->cvar, cvartext, sizeof(cvartext));
  1643. item->text = cvartext;
  1644. }
  1645. else
  1646. {
  1647. item->text = (char *) text;
  1648. }
  1649. Item_TextScroll_BuildLines ( item );
  1650. }
  1651. else
  1652. {
  1653. item->text = (char *) text;
  1654. }
  1655. }
  1656. }
  1657. }
  1658. }
  1659. /*
  1660. =================
  1661. Menu_TransitionItemByName
  1662. =================
  1663. */
  1664. void Menu_TransitionItemByName(menuDef_t *menu, const char *p, const rectDef_t *rectFrom, const rectDef_t *rectTo, int time, float amt)
  1665. {
  1666. itemDef_t *item;
  1667. int i;
  1668. int count = Menu_ItemsMatchingGroup(menu, p);
  1669. for (i = 0; i < count; i++)
  1670. {
  1671. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1672. if (item != NULL)
  1673. {
  1674. if (!rectFrom)
  1675. {
  1676. rectFrom = &item->window.rect; //if there are more than one of these with the same name, they'll all use the FIRST one's FROM.
  1677. }
  1678. item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE);
  1679. item->window.offsetTime = time;
  1680. memcpy(&item->window.rectClient, rectFrom, sizeof(rectDef_t));
  1681. memcpy(&item->window.rectEffects, rectTo, sizeof(rectDef_t));
  1682. item->window.rectEffects2.x = abs(rectTo->x - rectFrom->x) / amt;
  1683. item->window.rectEffects2.y = abs(rectTo->y - rectFrom->y) / amt;
  1684. item->window.rectEffects2.w = abs(rectTo->w - rectFrom->w) / amt;
  1685. item->window.rectEffects2.h = abs(rectTo->h - rectFrom->h) / amt;
  1686. Item_UpdatePosition(item);
  1687. }
  1688. }
  1689. }
  1690. /*
  1691. =================
  1692. Menu_TransitionItemByName
  1693. =================
  1694. */
  1695. //JLF MOVED
  1696. #define _TRANS3
  1697. #ifdef _TRANS3
  1698. void Menu_Transition3ItemByName(menuDef_t *menu, const char *p, const float minx, const float miny, const float minz,
  1699. const float maxx, const float maxy, const float maxz, const float fovtx, const float fovty,
  1700. const int time, const float amt)
  1701. {
  1702. itemDef_t *item;
  1703. int i;
  1704. int count = Menu_ItemsMatchingGroup(menu, p);
  1705. modelDef_t * modelptr;
  1706. for (i = 0; i < count; i++)
  1707. {
  1708. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1709. if (item != NULL)
  1710. {
  1711. if ( item->type == ITEM_TYPE_MODEL)
  1712. {
  1713. modelptr = (modelDef_t*)item->typeData;
  1714. item->window.flags |= (WINDOW_INTRANSITIONMODEL | WINDOW_VISIBLE);
  1715. item->window.offsetTime = time;
  1716. modelptr->fov_x2 = fovtx;
  1717. modelptr->fov_y2 = fovty;
  1718. VectorSet(modelptr->g2maxs2, maxx, maxy, maxz);
  1719. VectorSet(modelptr->g2mins2, minx, miny, minz);
  1720. // //modelptr->g2maxs2.x= maxx;
  1721. // modelptr->g2maxs2.y= maxy;
  1722. // modelptr->g2maxs2.z= maxz;
  1723. // modelptr->g2mins2.x= minx;
  1724. // modelptr->g2mins2.y= miny;
  1725. // modelptr->g2mins2.z= minz;
  1726. // VectorSet(modelptr->g2maxs2, maxx, maxy, maxz);
  1727. modelptr->g2maxsEffect[0] = abs(modelptr->g2maxs2[0] - modelptr->g2maxs[0]) / amt;
  1728. modelptr->g2maxsEffect[1] = abs(modelptr->g2maxs2[1] - modelptr->g2maxs[1]) / amt;
  1729. modelptr->g2maxsEffect[2] = abs(modelptr->g2maxs2[2] - modelptr->g2maxs[2]) / amt;
  1730. modelptr->g2minsEffect[0] = abs(modelptr->g2mins2[0] - modelptr->g2mins[0]) / amt;
  1731. modelptr->g2minsEffect[1] = abs(modelptr->g2mins2[1] - modelptr->g2mins[1]) / amt;
  1732. modelptr->g2minsEffect[2] = abs(modelptr->g2mins2[2] - modelptr->g2mins[2]) / amt;
  1733. modelptr->fov_Effectx = abs(modelptr->fov_x2 - modelptr->fov_x) / amt;
  1734. modelptr->fov_Effecty = abs(modelptr->fov_y2 - modelptr->fov_y) / amt;
  1735. }
  1736. }
  1737. }
  1738. }
  1739. #endif
  1740. /*
  1741. =================
  1742. Menu_OrbitItemByName
  1743. =================
  1744. */
  1745. void Menu_OrbitItemByName(menuDef_t *menu, const char *p, float x, float y, float cx, float cy, int time)
  1746. {
  1747. itemDef_t *item;
  1748. int i;
  1749. int count = Menu_ItemsMatchingGroup(menu, p);
  1750. for (i = 0; i < count; i++)
  1751. {
  1752. item = Menu_GetMatchingItemByNumber(menu, i, p);
  1753. if (item != NULL)
  1754. {
  1755. item->window.flags |= (WINDOW_ORBITING | WINDOW_VISIBLE);
  1756. item->window.offsetTime = time;
  1757. item->window.rectEffects.x = cx;
  1758. item->window.rectEffects.y = cy;
  1759. item->window.rectClient.x = x;
  1760. item->window.rectClient.y = y;
  1761. Item_UpdatePosition(item);
  1762. }
  1763. }
  1764. }
  1765. /*
  1766. =================
  1767. Rect_Parse
  1768. =================
  1769. */
  1770. qboolean Rect_Parse(const char **p, rectDef_t *r)
  1771. {
  1772. if (!COM_ParseFloat(p, &r->x))
  1773. {
  1774. if (!COM_ParseFloat(p, &r->y))
  1775. {
  1776. if (!COM_ParseFloat(p, &r->w))
  1777. {
  1778. if (!COM_ParseFloat(p, &r->h))
  1779. {
  1780. return qtrue;
  1781. }
  1782. }
  1783. }
  1784. }
  1785. return qfalse;
  1786. }
  1787. qboolean Script_SetItemRect(itemDef_t *item, const char **args)
  1788. {
  1789. const char *itemname;
  1790. rectDef_t *out;
  1791. rectDef_t rect;
  1792. // expecting type of color to set and 4 args for the color
  1793. if (String_Parse(args, &itemname))
  1794. {
  1795. itemDef_t *item2;
  1796. int j;
  1797. int count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, itemname);
  1798. if (!Rect_Parse(args, &rect))
  1799. {
  1800. return qtrue;
  1801. }
  1802. for (j = 0; j < count; j++)
  1803. {
  1804. item2 = Menu_GetMatchingItemByNumber((menuDef_t *) item->parent, j, itemname);
  1805. if (item2 != NULL)
  1806. {
  1807. out = &item2->window.rect;
  1808. if (out)
  1809. {
  1810. item2->window.rect.x = rect.x;
  1811. item2->window.rect.y = rect.y;
  1812. item2->window.rect.w = rect.w;
  1813. item2->window.rect.h = rect.h;
  1814. }
  1815. }
  1816. }
  1817. }
  1818. return qtrue;
  1819. }
  1820. /*
  1821. =================
  1822. Script_SetItemBackground
  1823. =================
  1824. */
  1825. qboolean Script_SetItemBackground(itemDef_t *item, const char **args)
  1826. {
  1827. const char *itemName;
  1828. const char *name;
  1829. // expecting name of shader
  1830. if (String_Parse(args, &itemName) && String_Parse(args, &name))
  1831. {
  1832. Menu_SetItemBackground((menuDef_t *) item->parent, itemName, name);
  1833. }
  1834. return qtrue;
  1835. }
  1836. /*
  1837. =================
  1838. Script_SetItemText
  1839. =================
  1840. */
  1841. qboolean Script_SetItemText(itemDef_t *item, const char **args)
  1842. {
  1843. const char *itemName;
  1844. const char *text;
  1845. // expecting text
  1846. if (String_Parse(args, &itemName) && String_Parse(args, &text))
  1847. {
  1848. Menu_SetItemText((menuDef_t *) item->parent, itemName, text);
  1849. }
  1850. return qtrue;
  1851. }
  1852. /*
  1853. =================
  1854. Script_FadeIn
  1855. =================
  1856. */
  1857. qboolean Script_FadeIn(itemDef_t *item, const char **args)
  1858. {
  1859. const char *name;
  1860. if (String_Parse(args, &name))
  1861. {
  1862. Menu_FadeItemByName((menuDef_t *) item->parent, name, qfalse);
  1863. }
  1864. return qtrue;
  1865. }
  1866. /*
  1867. =================
  1868. Script_FadeOut
  1869. =================
  1870. */
  1871. qboolean Script_FadeOut(itemDef_t *item, const char **args)
  1872. {
  1873. const char *name;
  1874. if (String_Parse(args, &name))
  1875. {
  1876. Menu_FadeItemByName((menuDef_t *) item->parent, name, qtrue);
  1877. }
  1878. return qtrue;
  1879. }
  1880. /*
  1881. =================
  1882. Script_Show
  1883. =================
  1884. */
  1885. qboolean Script_Show(itemDef_t *item, const char **args)
  1886. {
  1887. const char *name;
  1888. if (String_Parse(args, &name))
  1889. {
  1890. Menu_ShowItemByName((menuDef_t *) item->parent, name, qtrue);
  1891. }
  1892. return qtrue;
  1893. }
  1894. /*
  1895. ==========
  1896. Script_SetDecoration
  1897. ==========
  1898. */
  1899. qboolean Script_SetDecoration(itemDef_t* item, const char **args)
  1900. {
  1901. const char *name;
  1902. int val;
  1903. if (String_Parse(args, &name))
  1904. {
  1905. if(!strcmp("vstr", name))
  1906. {
  1907. if(String_Parse(args, &name))
  1908. {
  1909. if(Int_Parse( args, &val))
  1910. {
  1911. Menu_SetItemDecorationByName((menuDef_t*) item->parent, Cvar_VariableString(name), val );
  1912. return qtrue;
  1913. }
  1914. }
  1915. }
  1916. else
  1917. {
  1918. if(Int_Parse( args, &val))
  1919. {
  1920. Menu_SetItemDecorationByName((menuDef_t*) item->parent, name, val );
  1921. return qtrue;
  1922. }
  1923. }
  1924. }
  1925. return qfalse;
  1926. }
  1927. /*
  1928. =================
  1929. Script_ShowMenu
  1930. =================
  1931. */
  1932. qboolean Script_ShowMenu(itemDef_t *item, const char **args)
  1933. {
  1934. const char *name;
  1935. if (String_Parse(args, &name))
  1936. {
  1937. Menus_ShowItems(name);
  1938. }
  1939. return qtrue;
  1940. }
  1941. /*
  1942. =================
  1943. Script_Hide
  1944. =================
  1945. */
  1946. qboolean Script_Hide(itemDef_t *item, const char **args)
  1947. {
  1948. const char *name;
  1949. if (String_Parse(args, &name))
  1950. {
  1951. Menu_ShowItemByName((menuDef_t *) item->parent, name, qfalse);
  1952. }
  1953. return qtrue;
  1954. }
  1955. /*
  1956. =================
  1957. Script_SetColor
  1958. =================
  1959. */
  1960. qboolean Script_SetColor(itemDef_t *item, const char **args)
  1961. {
  1962. const char *name;
  1963. int i;
  1964. float f;
  1965. vec4_t *out;
  1966. // expecting type of color to set and 4 args for the color
  1967. if (String_Parse(args, &name))
  1968. {
  1969. out = NULL;
  1970. if (Q_stricmp(name, "backcolor") == 0)
  1971. {
  1972. out = &item->window.backColor;
  1973. item->window.flags |= WINDOW_BACKCOLORSET;
  1974. }
  1975. else if (Q_stricmp(name, "forecolor") == 0)
  1976. {
  1977. out = &item->window.foreColor;
  1978. item->window.flags |= WINDOW_FORECOLORSET;
  1979. }
  1980. else if (Q_stricmp(name, "bordercolor") == 0)
  1981. {
  1982. out = &item->window.borderColor;
  1983. }
  1984. if (out)
  1985. {
  1986. for (i = 0; i < 4; i++)
  1987. {
  1988. // if (!Float_Parse(args, &f))
  1989. if (COM_ParseFloat( args, &f))
  1990. {
  1991. return qtrue;
  1992. }
  1993. (*out)[i] = f;
  1994. }
  1995. }
  1996. }
  1997. return qtrue;
  1998. }
  1999. /*
  2000. =================
  2001. Script_Open
  2002. =================
  2003. */
  2004. qboolean Script_Open(itemDef_t *item, const char **args)
  2005. {
  2006. const char *name;
  2007. if (String_Parse(args, &name))
  2008. {
  2009. if(!strcmp("vstr",name))
  2010. {
  2011. if(String_Parse(args,&name))
  2012. {
  2013. Menus_OpenByName(Cvar_VariableString(name));
  2014. }
  2015. }
  2016. else
  2017. {
  2018. Menus_OpenByName(name);
  2019. }
  2020. }
  2021. return qtrue;
  2022. }
  2023. qboolean Script_OpenGoToMenu(itemDef_t *item, const char **args)
  2024. {
  2025. Menus_OpenByName(GoToMenu); // Give warning
  2026. return qtrue;
  2027. }
  2028. /*
  2029. =================
  2030. Script_Close
  2031. =================
  2032. */
  2033. qboolean Script_Close(itemDef_t *item, const char **args)
  2034. {
  2035. const char *name;
  2036. if (String_Parse(args, &name))
  2037. {
  2038. if (Q_stricmp(name, "all") == 0)
  2039. {
  2040. Menus_CloseAll();
  2041. }
  2042. else
  2043. {
  2044. Menus_CloseByName(name);
  2045. }
  2046. }
  2047. return qtrue;
  2048. }
  2049. /*
  2050. =================
  2051. Script_Activate
  2052. =================
  2053. */
  2054. qboolean Script_Activate(itemDef_t *item, const char **args)
  2055. {
  2056. const char *name, *menu;
  2057. if (String_Parse(args, &menu))
  2058. {
  2059. if (String_Parse(args, &name))
  2060. {
  2061. Item_ActivateByName(menu,name);
  2062. }
  2063. }
  2064. return qtrue;
  2065. }
  2066. /*
  2067. =================
  2068. Script_SetBackground
  2069. =================
  2070. */
  2071. qboolean Script_SetBackground(itemDef_t *item, const char **args)
  2072. {
  2073. const char *name;
  2074. // expecting name to set asset to
  2075. if (String_Parse(args, &name))
  2076. {
  2077. item->window.background = DC->registerShaderNoMip(name);
  2078. }
  2079. return qtrue;
  2080. }
  2081. /*
  2082. =================
  2083. Script_SetAsset
  2084. =================
  2085. */
  2086. qboolean Script_SetAsset(itemDef_t *item, const char **args)
  2087. {
  2088. const char *name;
  2089. // expecting name to set asset to
  2090. if (String_Parse(args, &name))
  2091. {
  2092. // check for a model
  2093. if (item->type == ITEM_TYPE_MODEL)
  2094. {
  2095. }
  2096. }
  2097. return qtrue;
  2098. }
  2099. /*
  2100. =================
  2101. Script_SetFocus
  2102. =================
  2103. */
  2104. qboolean Script_SetFocus(itemDef_t *item, const char **args)
  2105. {
  2106. const char *name;
  2107. itemDef_t *focusItem;
  2108. if (String_Parse(args, &name))
  2109. {
  2110. if(!strcmp("vstr", name))
  2111. {
  2112. if(String_Parse(args, &name))
  2113. {
  2114. #ifdef _XBOX
  2115. focusItem = (itemDef_s *) Menu_FindVisibleItemByName((menuDef_t *) item->parent, Cvar_VariableString(name));
  2116. #else
  2117. focusItem = (itemDef_s *) Menu_FindItemByName((menuDef_t *) item->parent, Cvar_VariableString(name));
  2118. #endif
  2119. }
  2120. else
  2121. {
  2122. return qfalse;
  2123. }
  2124. }
  2125. else
  2126. {
  2127. #ifdef _XBOX
  2128. focusItem = (itemDef_s *) Menu_FindVisibleItemByName((menuDef_t *) item->parent, name);
  2129. #else
  2130. focusItem = (itemDef_s *) Menu_FindItemByName((menuDef_t *) item->parent, name);
  2131. #endif
  2132. }
  2133. if (focusItem && !(focusItem->window.flags & WINDOW_DECORATION) && !(focusItem->window.flags & WINDOW_HASFOCUS))
  2134. {
  2135. Menu_ClearFocus((menuDef_t *) item->parent);
  2136. //JLF
  2137. #ifdef _XBOX
  2138. Item_SetFocus(focusItem, 0,0);
  2139. #else
  2140. focusItem->window.flags |= WINDOW_HASFOCUS;
  2141. #endif
  2142. //END JLF
  2143. if (focusItem->onFocus)
  2144. {
  2145. Item_RunScript(focusItem, focusItem->onFocus);
  2146. }
  2147. if (DC->Assets.itemFocusSound)
  2148. {
  2149. DC->startLocalSound( DC->Assets.itemFocusSound, CHAN_LOCAL_SOUND );
  2150. }
  2151. #ifdef _IMMERSION
  2152. if (DC->Assets.itemFocusForce)
  2153. {
  2154. DC->startForce( DC->Assets.itemFocusForce );
  2155. }
  2156. #endif // _IMMERSION
  2157. }
  2158. }
  2159. return qtrue;
  2160. }
  2161. /*
  2162. =================
  2163. Script_SetItemFlag
  2164. =================
  2165. */
  2166. qboolean Script_SetItemFlag(itemDef_t *item, const char **args)
  2167. {
  2168. const char *itemName,*number;
  2169. if (String_Parse(args, &itemName))
  2170. {
  2171. item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) item->parent, itemName);
  2172. if (String_Parse(args, &number))
  2173. {
  2174. int amount = atoi(number);
  2175. item->window.flags |= amount;
  2176. }
  2177. }
  2178. return qtrue;
  2179. }
  2180. void UI_SetItemVisible(menuDef_t *menu,const char *itemname,qboolean visible)
  2181. {
  2182. itemDef_t *item;
  2183. int j;
  2184. int count = Menu_ItemsMatchingGroup(menu, itemname);
  2185. for (j = 0; j < count; j++)
  2186. {
  2187. item = Menu_GetMatchingItemByNumber(menu, j, itemname);
  2188. if (item != NULL)
  2189. {
  2190. if (visible==qtrue)
  2191. {
  2192. item->window.flags |= WINDOW_VISIBLE;
  2193. }
  2194. else
  2195. {
  2196. item->window.flags &= ~WINDOW_VISIBLE;
  2197. }
  2198. }
  2199. }
  2200. }
  2201. void UI_SetItemColor(itemDef_t *item,const char *itemname,const char *name,vec4_t color)
  2202. {
  2203. itemDef_t *item2;
  2204. int i,j;
  2205. vec4_t *out;
  2206. int count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, itemname);
  2207. for (j = 0; j < count; j++)
  2208. {
  2209. item2 = Menu_GetMatchingItemByNumber((menuDef_t *) item->parent, j, itemname);
  2210. if (item2 != NULL)
  2211. {
  2212. out = NULL;
  2213. if (Q_stricmp(name, "backcolor") == 0)
  2214. {
  2215. out = &item2->window.backColor;
  2216. }
  2217. else if (Q_stricmp(name, "forecolor") == 0)
  2218. {
  2219. out = &item2->window.foreColor;
  2220. item2->window.flags |= WINDOW_FORECOLORSET;
  2221. }
  2222. else if (Q_stricmp(name, "bordercolor") == 0)
  2223. {
  2224. out = &item2->window.borderColor;
  2225. }
  2226. if (out)
  2227. {
  2228. for (i = 0; i < 4; i++)
  2229. {
  2230. (*out)[i] = color[i];
  2231. }
  2232. }
  2233. }
  2234. }
  2235. }
  2236. /*
  2237. =================
  2238. Script_SetItemColor
  2239. =================
  2240. */
  2241. qboolean Script_SetItemColor(itemDef_t *item, const char **args)
  2242. {
  2243. const char *itemname;
  2244. const char *name;
  2245. vec4_t color;
  2246. // expecting type of color to set and 4 args for the color
  2247. if (String_Parse(args, &itemname) && String_Parse(args, &name))
  2248. {
  2249. if (COM_ParseVec4(args, &color))
  2250. {
  2251. return qtrue;
  2252. }
  2253. UI_SetItemColor(item,itemname,name,color);
  2254. }
  2255. return qtrue;
  2256. }
  2257. /*
  2258. =================
  2259. Script_SetFocusColor
  2260. =================
  2261. */
  2262. qboolean Script_SetFocusColor(itemDef_t *item, const char **args)
  2263. {
  2264. menuDef_t *menu = (menuDef_t *) item->parent;
  2265. // expecting type of color to set and 4 args for the color
  2266. if (COM_ParseVec4(args, &menu->focusColor))
  2267. {
  2268. return qtrue;
  2269. }
  2270. return qtrue;
  2271. }
  2272. /*
  2273. =================
  2274. Script_CvarIfEqual
  2275. Egads. OK. Script command should be:
  2276. cvarIfEqual <cvarname> <value> <cvarTrueScript> <cvarFalseScript>
  2277. If the contents of cvarname are equal to value, then the script in
  2278. cvarTrueScript will be executed, otherwise the script in cvarFalseScript
  2279. =================
  2280. */
  2281. qboolean Script_CvarIfEqual ( itemDef_t* item, const char **args )
  2282. {
  2283. const char *cvarName;
  2284. const char *testVal;
  2285. const char *cvarTrueScript;
  2286. const char *cvarFalseScript;
  2287. if (!String_Parse(args, &cvarName) || !String_Parse(args, &testVal) ||
  2288. !String_Parse(args, &cvarTrueScript) || !String_Parse(args, &cvarFalseScript))
  2289. {
  2290. Com_Printf("Error parsing cvarIfEqual\n");
  2291. return qfalse;
  2292. }
  2293. bool testResult = (Q_stricmp(Cvar_VariableString(cvarName), testVal) == 0);
  2294. if( testResult )
  2295. Item_RunScript( item, Cvar_VariableString( cvarTrueScript ) );
  2296. else
  2297. Item_RunScript( item, Cvar_VariableString( cvarFalseScript ) );
  2298. return qtrue;
  2299. }
  2300. /*
  2301. =================
  2302. Script_Defer
  2303. Defers the rest of the script based on the defer condition. The deferred
  2304. portion of the script can later be run with the "rundeferred"
  2305. =================
  2306. */
  2307. qboolean Script_Defer ( itemDef_t* item, const char **args )
  2308. {
  2309. // Should the script be deferred?
  2310. if ( DC->deferScript ( args ) )
  2311. {
  2312. // Need the item the script was being run on
  2313. uiInfo.deferredScriptItem = item;
  2314. // Save the rest of the script
  2315. Q_strncpyz ( uiInfo.deferredScript, *args, MAX_DEFERRED_SCRIPT, qfalse );
  2316. // No more running
  2317. return qfalse;
  2318. }
  2319. // Keep running the script, its ok
  2320. return qtrue;
  2321. }
  2322. /*
  2323. =================
  2324. Script_RunDeferred
  2325. Runs the last deferred script, there can only be one script deferred at a
  2326. time so be careful of recursion
  2327. =================
  2328. */
  2329. qboolean Script_RunDeferred ( itemDef_t* item, const char **args )
  2330. {
  2331. // Make sure there is something to run.
  2332. if ( !uiInfo.deferredScript[0] || !uiInfo.deferredScriptItem )
  2333. {
  2334. return qtrue;
  2335. }
  2336. // Run the deferred script now
  2337. Item_RunScript ( uiInfo.deferredScriptItem, uiInfo.deferredScript );
  2338. uiInfo.deferredScriptItem = NULL;
  2339. uiInfo.deferredScript[0] = 0;
  2340. return qtrue;
  2341. }
  2342. /*
  2343. =================
  2344. Script_Delay
  2345. Delays the rest of the script for the specified amount of time
  2346. =================
  2347. */
  2348. qboolean Script_Delay ( itemDef_t* item, const char **args )
  2349. {
  2350. int time;
  2351. if (Int_Parse(args, &time))
  2352. {
  2353. // item->window.flags |= WINDOW_SCRIPTWAITING;
  2354. // item->window.delayTime = DC->realTime + time; // Flag to set delay time on next paint
  2355. // item->window.delayedScript = (char *)*args; // Copy current location, we'll resume executing here later
  2356. ((menuDef_t*)(item->parent))->window.flags |= WINDOW_SCRIPTWAITING;
  2357. ((menuDef_t*)(item->parent))->window.delayTime = DC->realTime + time; // Flag to set delay time on next paint
  2358. ((menuDef_t*)(item->parent))->window.delayedScript = (char *)*args; // Copy current location, we'll resume executing here later
  2359. }
  2360. else
  2361. {
  2362. Com_Printf(S_COLOR_YELLOW"WARNING: Script_Delay: error parsing\n" );
  2363. }
  2364. // Stop running
  2365. return qfalse;
  2366. }
  2367. /*
  2368. =================
  2369. Script_Transition
  2370. transition rtvscr 321 0 202 264 415 0 202 264 20 25
  2371. =================
  2372. */
  2373. qboolean Script_Transition(itemDef_t *item, const char **args)
  2374. {
  2375. const char *name;
  2376. rectDef_t rectFrom, rectTo;
  2377. int time;
  2378. float amt;
  2379. if (String_Parse(args, &name))
  2380. {
  2381. if ( ParseRect(args, &rectFrom) && ParseRect(args, &rectTo) && Int_Parse(args, &time) && !COM_ParseFloat(args, &amt))
  2382. {
  2383. Menu_TransitionItemByName((menuDef_t *) item->parent, name, &rectFrom, &rectTo, time, amt);
  2384. }
  2385. else
  2386. {
  2387. Com_Printf(S_COLOR_YELLOW"WARNING: Script_Transition: error parsing '%s'\n", name );
  2388. }
  2389. }
  2390. return qtrue;
  2391. }
  2392. /*
  2393. =================
  2394. Script_Transition2
  2395. uses current origin instead of specifing a starting origin
  2396. transition2 lfvscr 25 0 202 264 20 25
  2397. =================
  2398. */
  2399. qboolean Script_Transition2(itemDef_t *item, const char **args)
  2400. {
  2401. const char *name;
  2402. rectDef_t rectTo;
  2403. int time;
  2404. float amt;
  2405. if (String_Parse(args, &name))
  2406. {
  2407. if ( ParseRect(args, &rectTo) && Int_Parse(args, &time) && !COM_ParseFloat(args, &amt))
  2408. {
  2409. Menu_TransitionItemByName((menuDef_t *) item->parent, name, 0, &rectTo, time, amt);
  2410. }
  2411. else
  2412. {
  2413. Com_Printf(S_COLOR_YELLOW"WARNING: Script_Transition2: error parsing '%s'\n", name );
  2414. }
  2415. }
  2416. return qtrue;
  2417. }
  2418. #ifdef _TRANS3
  2419. /*
  2420. JLF MPMOVED
  2421. =================
  2422. Script_Transition3
  2423. used exclusively with model views
  2424. uses current origin instead of specifing a starting origin
  2425. transition3 lfvscr (min extent) (max extent) (fovx,y) 20 25
  2426. =================
  2427. */
  2428. qboolean Script_Transition3(itemDef_t *item, const char **args)
  2429. {
  2430. const char *name;
  2431. const char *value;
  2432. float minx, miny, minz, maxx, maxy, maxz, fovtx, fovty;
  2433. int time;
  2434. float amt;
  2435. if (String_Parse(args, &name))
  2436. {
  2437. if (String_Parse( args, &value))
  2438. {
  2439. minx = atof(value);
  2440. if (String_Parse( args, &value))
  2441. {
  2442. miny = atof(value);
  2443. if (String_Parse( args, &value))
  2444. {
  2445. minz = atof(value);
  2446. if (String_Parse( args, &value))
  2447. {
  2448. maxx = atof(value);
  2449. if (String_Parse( args, &value))
  2450. {
  2451. maxy = atof(value);
  2452. if (String_Parse( args, &value))
  2453. {
  2454. maxz = atof(value);
  2455. if (String_Parse( args, &value))
  2456. {
  2457. fovtx = atof(value);
  2458. if (String_Parse( args, &value))
  2459. {
  2460. fovty = atof(value);
  2461. if (String_Parse( args, &value))
  2462. {
  2463. time = atoi(value);
  2464. if (String_Parse( args, &value))
  2465. {
  2466. amt = atof(value);
  2467. //set up the variables
  2468. Menu_Transition3ItemByName((menuDef_t *) item->parent,
  2469. name,
  2470. minx, miny, minz,
  2471. maxx, maxy, maxz,
  2472. fovtx, fovty,
  2473. time, amt);
  2474. return qtrue;
  2475. }
  2476. }
  2477. }
  2478. }
  2479. }
  2480. }
  2481. }
  2482. }
  2483. }
  2484. }
  2485. }
  2486. Com_Printf(S_COLOR_YELLOW"WARNING: Script_Transition2: error parsing '%s'\n", name );
  2487. return qtrue;
  2488. }
  2489. #endif
  2490. //only works on some feeders
  2491. int GetCurrentFeederIndex(itemDef_t * item)
  2492. {
  2493. float feederID = item->special;
  2494. char * name;
  2495. int i, max;
  2496. if (feederID == FEEDER_PLAYER_SPECIES)
  2497. {
  2498. return uiInfo.playerSpeciesIndex;
  2499. }
  2500. if (feederID == FEEDER_PLAYER_SKIN_HEAD)
  2501. {
  2502. name = Cvar_VariableString("ui_char_skin_head");
  2503. max = uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount;
  2504. for ( i = 0; i < max ; i++)
  2505. {
  2506. if (!Q_stricmp(name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[i]))
  2507. {
  2508. return i;
  2509. }
  2510. // Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
  2511. }
  2512. return -1;
  2513. }
  2514. else if (feederID == FEEDER_PLAYER_SKIN_TORSO)
  2515. {
  2516. name = Cvar_VariableString("ui_char_skin_torso");
  2517. max = uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount;
  2518. for ( i = 0; i < max ; i++)
  2519. {
  2520. if (!Q_stricmp(name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[i]))
  2521. {
  2522. return i;
  2523. }
  2524. // Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
  2525. }
  2526. return -1;
  2527. }
  2528. else if (feederID == FEEDER_PLAYER_SKIN_LEGS)
  2529. {
  2530. name = Cvar_VariableString("ui_char_skin_legs");
  2531. max = uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount;
  2532. for ( i = 0; i < max ; i++)
  2533. {
  2534. if (!Q_stricmp(name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[i]))
  2535. {
  2536. return i;
  2537. }
  2538. // Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
  2539. }
  2540. return -1;
  2541. // if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount)
  2542. // {
  2543. // Cvar_Set("ui_char_skin_legs", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]);
  2544. // }
  2545. }
  2546. else if (feederID == FEEDER_COLORCHOICES)
  2547. {
  2548. extern void Item_RunScript(itemDef_t *item, const char *s); //from ui_shared;
  2549. int currR, currG, currB, newR, newG, newB;
  2550. currR = Cvar_VariableIntegerValue( "ui_char_color_red");
  2551. currG = Cvar_VariableIntegerValue( "ui_char_color_green");
  2552. currB = Cvar_VariableIntegerValue( "ui_char_color_blue");
  2553. max = uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount;
  2554. for ( i = 0; i < max ; i++)
  2555. {
  2556. Item_RunScript(item, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorActionText[i]);
  2557. newR = Cvar_VariableIntegerValue( "ui_char_color_red");
  2558. newG = Cvar_VariableIntegerValue( "ui_char_color_green");
  2559. newB = Cvar_VariableIntegerValue( "ui_char_color_blue");
  2560. if ( currR == newR && currG == newG && currB == newB)
  2561. return i;
  2562. }
  2563. return -1;
  2564. //JLF junk copied code
  2565. /*
  2566. extern void Item_RunScript(itemDef_t *item, const char *s); //from ui_shared;
  2567. name = Cvar_VariableString("ui_char_skin_legs");
  2568. max = uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount;
  2569. for ( i = 0; i < max ; i++)
  2570. if (!qstrcmp(name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[i]))
  2571. {
  2572. return i;
  2573. // Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
  2574. }
  2575. return -1;
  2576. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount)
  2577. {
  2578. Item_RunScript(item, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorActionText[index]);
  2579. }
  2580. */
  2581. }
  2582. return -1;
  2583. }
  2584. qboolean Script_IncrementFeeder(itemDef_t * item, const char ** args)
  2585. {
  2586. int feedercount = uiInfo.uiDC.feederCount(item->special);
  2587. int value = GetCurrentFeederIndex(item);
  2588. value++;
  2589. if ( value >= feedercount)
  2590. value = 0;
  2591. DC->feederSelection(item->special, value, item);
  2592. return qtrue;
  2593. }
  2594. qboolean Script_DecrementFeeder(itemDef_t * item, const char ** args)
  2595. {
  2596. int feedercount = uiInfo.uiDC.feederCount(item->special);
  2597. int value = GetCurrentFeederIndex(item);
  2598. value--;
  2599. if ( value < 0)
  2600. value = feedercount-1;
  2601. DC->feederSelection(item->special, value, item);
  2602. return qtrue;
  2603. }
  2604. /*
  2605. =================
  2606. Script_SetCvar
  2607. =================
  2608. */
  2609. qboolean Script_SetCvar(itemDef_t *item, const char **args)
  2610. {
  2611. const char *cvar, *val;
  2612. if (String_Parse(args, &cvar) && String_Parse(args, &val))
  2613. {
  2614. DC->setCVar(cvar, val);
  2615. }
  2616. return qtrue;
  2617. }
  2618. /*
  2619. =================
  2620. Script_Exec
  2621. =================
  2622. */
  2623. qboolean Script_Exec ( itemDef_t *item, const char **args)
  2624. {
  2625. const char *val;
  2626. if (String_Parse(args, &val))
  2627. {
  2628. DC->executeText(EXEC_APPEND, va("%s ; ", val));
  2629. }
  2630. return qtrue;
  2631. }
  2632. /*
  2633. =================
  2634. Script_Play
  2635. =================
  2636. */
  2637. static qboolean Script_Play(itemDef_t *item, const char **args)
  2638. {
  2639. const char *val;
  2640. if (String_Parse(args, &val))
  2641. {
  2642. DC->startLocalSound(DC->registerSound(val, qfalse), CHAN_AUTO );
  2643. }
  2644. return qtrue;
  2645. }
  2646. /*
  2647. =================
  2648. Script_PlayVoice
  2649. =================
  2650. */
  2651. static qboolean Script_PlayVoice(itemDef_t *item, const char **args)
  2652. {
  2653. const char *val;
  2654. if (String_Parse(args, &val))
  2655. {
  2656. DC->startLocalSound(DC->registerSound(val, qfalse), CHAN_VOICE );
  2657. }
  2658. return qtrue;
  2659. }
  2660. /*
  2661. =================
  2662. Script_StopVoice
  2663. =================
  2664. */
  2665. static qboolean Script_StopVoice(itemDef_t *item, const char **args)
  2666. {
  2667. #ifdef _XBOX
  2668. extern void S_KillEntityChannel(int entnum, int chan);
  2669. S_KillEntityChannel( 0, CHAN_VOICE );
  2670. #else
  2671. DC->startLocalSound(uiInfo.uiDC.Assets.nullSound, CHAN_VOICE );
  2672. #endif
  2673. return qtrue;
  2674. }
  2675. /*
  2676. =================
  2677. Script_playLooped
  2678. =================
  2679. */
  2680. /*
  2681. qboolean Script_playLooped(itemDef_t *item, const char **args)
  2682. {
  2683. const char *val;
  2684. if (String_Parse(args, &val))
  2685. {
  2686. // FIXME BOB - is this needed?
  2687. DC->stopBackgroundTrack();
  2688. DC->startBackgroundTrack(val, val);
  2689. }
  2690. return qtrue;
  2691. }
  2692. */
  2693. #ifdef _IMMERSION
  2694. /*
  2695. =================
  2696. Script_FFPlay
  2697. =================
  2698. */
  2699. qboolean Script_FFPlay(itemDef_t *item, const char **args)
  2700. {
  2701. const char *val;
  2702. if (String_Parse(args, &val))
  2703. {
  2704. DC->startForce(DC->registerForce(val));
  2705. }
  2706. return qtrue;
  2707. }
  2708. #endif // _IMMERSION
  2709. /*
  2710. =================
  2711. Script_Orbit
  2712. =================
  2713. */
  2714. qboolean Script_Orbit(itemDef_t *item, const char **args)
  2715. {
  2716. const char *name;
  2717. float cx, cy, x, y;
  2718. int time;
  2719. if (String_Parse(args, &name))
  2720. {
  2721. // if ( Float_Parse(args, &x) && Float_Parse(args, &y) && Float_Parse(args, &cx) && Float_Parse(args, &cy) && Int_Parse(args, &time) )
  2722. if ( !COM_ParseFloat(args, &x) && !COM_ParseFloat(args, &y) && !COM_ParseFloat(args, &cx) && !COM_ParseFloat(args, &cy) && Int_Parse(args, &time) )
  2723. {
  2724. Menu_OrbitItemByName((menuDef_t *) item->parent, name, x, y, cx, cy, time);
  2725. }
  2726. }
  2727. return qtrue;
  2728. }
  2729. commandDef_t commandList[] =
  2730. {
  2731. {"activate", &Script_Activate}, // menu
  2732. {"close", &Script_Close}, // menu
  2733. {"exec", &Script_Exec}, // group/name
  2734. {"fadein", &Script_FadeIn}, // group/name
  2735. {"fadeout", &Script_FadeOut}, // group/name
  2736. {"hide", &Script_Hide}, // group/name
  2737. {"open", &Script_Open}, // menu
  2738. {"openGoToMenu", &Script_OpenGoToMenu}, //
  2739. {"orbit", &Script_Orbit}, // group/name
  2740. {"play", &Script_Play}, // group/name
  2741. {"playVoice", &Script_PlayVoice}, // group/name
  2742. {"stopVoice", &Script_StopVoice}, // group/name
  2743. // {"playlooped", &Script_playLooped}, // group/name
  2744. #ifdef _IMMERSION
  2745. {"ffplay", &Script_FFPlay},
  2746. #endif // _IMMERSION
  2747. {"setasset", &Script_SetAsset}, // works on this
  2748. {"setbackground", &Script_SetBackground}, // works on this
  2749. {"setcolor", &Script_SetColor}, // works on this
  2750. {"setcvar", &Script_SetCvar}, // group/name
  2751. {"setfocus", &Script_SetFocus}, // sets this background color to team color
  2752. {"setitemcolor", &Script_SetItemColor}, // group/name
  2753. {"setfocuscolor", &Script_SetFocusColor}, // affects whole menu
  2754. {"setitemflag", &Script_SetItemFlag}, // name
  2755. {"show", &Script_Show}, // group/name
  2756. {"showMenu", &Script_ShowMenu}, // menu
  2757. {"transition", &Script_Transition}, // group/name
  2758. {"transition2", &Script_Transition2}, // group/name
  2759. {"setitembackground", &Script_SetItemBackground}, // group/name
  2760. {"setitemtext", &Script_SetItemText}, // group/name
  2761. {"setitemrect", &Script_SetItemRect}, // group/name
  2762. {"defer", &Script_Defer}, //
  2763. {"rundeferred", &Script_RunDeferred}, //
  2764. {"delay", &Script_Delay}, // works on this (script)
  2765. {"transition3", &Script_Transition3}, // model exclusive transition
  2766. {"incrementfeeder", &Script_IncrementFeeder},
  2767. {"decrementfeeder", &Script_DecrementFeeder},
  2768. {"setdecoration", &Script_SetDecoration}, // changes the decoration flag of an object
  2769. {"cvarifequal", &Script_CvarIfEqual}
  2770. };
  2771. int scriptCommandCount = sizeof(commandList) / sizeof(commandDef_t);
  2772. /*
  2773. ===============
  2774. Item_Init
  2775. ===============
  2776. */
  2777. void Item_Init(itemDef_t *item)
  2778. {
  2779. memset(item, 0, sizeof(itemDef_t));
  2780. item->textscale = 0.55f;
  2781. Window_Init(&item->window);
  2782. }
  2783. /*
  2784. ===============
  2785. Item_Multi_Setting
  2786. ===============
  2787. */
  2788. const char *Item_Multi_Setting(itemDef_t *item)
  2789. {
  2790. char buff[1024];
  2791. float value = 0;
  2792. int i;
  2793. multiDef_t *multiPtr = (multiDef_t*)item->typeData;
  2794. if (multiPtr)
  2795. {
  2796. if (multiPtr->strDef)
  2797. {
  2798. if (item->cvar)
  2799. {
  2800. DC->getCVarString(item->cvar, buff, sizeof(buff));
  2801. }
  2802. else
  2803. {
  2804. }
  2805. }
  2806. else
  2807. {
  2808. if (item->cvar) // Was a cvar given?
  2809. {
  2810. value = DC->getCVarValue(item->cvar);
  2811. }
  2812. else
  2813. {
  2814. value = item->value;
  2815. }
  2816. }
  2817. for (i = 0; i < multiPtr->count; i++)
  2818. {
  2819. if (multiPtr->strDef)
  2820. {
  2821. if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0)
  2822. {
  2823. return multiPtr->cvarList[i];
  2824. }
  2825. }
  2826. else
  2827. {
  2828. if (multiPtr->cvarValue[i] == value)
  2829. {
  2830. return multiPtr->cvarList[i];
  2831. }
  2832. }
  2833. }
  2834. }
  2835. return "";
  2836. }
  2837. //---------------------------------------------------------------------------------------------------------
  2838. // Item Keyword Parse functions
  2839. //---------------------------------------------------------------------------------------------------------
  2840. /*
  2841. ===============
  2842. ItemParse_name
  2843. name <string>
  2844. ===============
  2845. */
  2846. qboolean ItemParse_name( itemDef_t *item)
  2847. {
  2848. if (!PC_ParseStringMem((const char **)&item->window.name))
  2849. {
  2850. return qfalse;
  2851. }
  2852. return qtrue;
  2853. }
  2854. qboolean ItemParse_font( itemDef_t *item )
  2855. {
  2856. if (PC_ParseInt(&item->font))
  2857. {
  2858. return qfalse;
  2859. }
  2860. return qtrue;
  2861. }
  2862. /*
  2863. ===============
  2864. ItemParse_focusSound
  2865. name <string>
  2866. ===============
  2867. */
  2868. qboolean ItemParse_focusSound( itemDef_t *item)
  2869. {
  2870. const char *temp;
  2871. if (PC_ParseString(&temp))
  2872. {
  2873. return qfalse;
  2874. }
  2875. item->focusSound = DC->registerSound(temp, qfalse);
  2876. return qtrue;
  2877. }
  2878. #ifdef _IMMERSION
  2879. /*
  2880. ===============
  2881. ItemParse_focusForce
  2882. name <string>
  2883. ===============
  2884. */
  2885. qboolean ItemParse_focusForce( itemDef_t *item)
  2886. {
  2887. const char *temp;
  2888. if (PC_ParseString(&temp))
  2889. {
  2890. //#ifdef _DEBUG
  2891. //extern void UI_Debug_EnterReference(LPCSTR ps4LetterType, LPCSTR psItemString);
  2892. //#endif
  2893. return qfalse;
  2894. }
  2895. item->focusForce = DC->registerForce(temp);
  2896. return qtrue;
  2897. }
  2898. #endif // _IMMERSION
  2899. /*
  2900. ===============
  2901. ItemParse_text
  2902. text <string>
  2903. ===============
  2904. */
  2905. qboolean ItemParse_text( itemDef_t *item)
  2906. {
  2907. if (!PC_ParseStringMem((const char **) &item->text))
  2908. {
  2909. return qfalse;
  2910. }
  2911. //#ifdef _DEBUG
  2912. // UI_Debug_EnterReference("TEXT", item->text);
  2913. //#endif
  2914. return qtrue;
  2915. }
  2916. /*
  2917. ===============
  2918. ItemParse_descText
  2919. text <string>
  2920. ===============
  2921. */
  2922. /*
  2923. qboolean ItemParse_descText( itemDef_t *item)
  2924. {
  2925. if (!PC_ParseStringMem((const char **) &item->descText))
  2926. {
  2927. return qfalse;
  2928. }
  2929. //#ifdef _DEBUG
  2930. // UI_Debug_EnterReference("DESC", item->descText);
  2931. //#endif
  2932. return qtrue;
  2933. }
  2934. */
  2935. /*
  2936. ===============
  2937. ItemParse_text
  2938. text <string>
  2939. ===============
  2940. */
  2941. /*
  2942. qboolean ItemParse_text2( itemDef_t *item)
  2943. {
  2944. if (!PC_ParseStringMem((const char **) &item->text2))
  2945. {
  2946. return qfalse;
  2947. }
  2948. //#ifdef _DEBUG
  2949. // UI_Debug_EnterReference("TXT2", item->text2);
  2950. //#endif
  2951. return qtrue;
  2952. }
  2953. */
  2954. /*
  2955. ===============
  2956. ItemParse_group
  2957. group <string>
  2958. ===============
  2959. */
  2960. qboolean ItemParse_group( itemDef_t *item)
  2961. {
  2962. if (!PC_ParseStringMem((const char **)&item->window.group))
  2963. {
  2964. return qfalse;
  2965. }
  2966. return qtrue;
  2967. }
  2968. /*
  2969. ===============
  2970. ItemParse_asset_model
  2971. asset_model <string>
  2972. ===============
  2973. */
  2974. qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name )
  2975. {
  2976. modelDef_t *modelPtr;
  2977. Item_ValidateTypeData(item);
  2978. modelPtr = (modelDef_t*)item->typeData;
  2979. if (!Q_stricmp(&name[strlen(name) - 4], ".glm"))
  2980. { //it's a ghoul2 model then
  2981. if ( item->ghoul2.size() && item->ghoul2[0].mModelindex >= 0)
  2982. {
  2983. DC->g2_RemoveGhoul2Model( item->ghoul2, 0 );
  2984. item->flags &= ~ITF_G2VALID;
  2985. }
  2986. int g2Model = DC->g2_InitGhoul2Model(item->ghoul2, name, 0, 0, 0, 0, 0);
  2987. if (g2Model >= 0)
  2988. {
  2989. item->flags |= ITF_G2VALID;
  2990. if (modelPtr->g2anim)
  2991. { //does the menu request this model be playing an animation?
  2992. DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qfalse);
  2993. }
  2994. if ( modelPtr->g2skin )
  2995. {
  2996. DC->g2_SetSkin( &item->ghoul2[0], 0, modelPtr->g2skin );//this is going to set the surfs on/off matching the skin file
  2997. }
  2998. }
  2999. }
  3000. else if(!(item->asset))
  3001. { //guess it's just an md3
  3002. item->asset = DC->registerModel(name);
  3003. item->flags &= ~ITF_G2VALID;
  3004. }
  3005. return qtrue;
  3006. }
  3007. qboolean ItemParse_asset_model( itemDef_t *item )
  3008. {
  3009. const char *temp;
  3010. modelDef_t *modelPtr;
  3011. Item_ValidateTypeData(item);
  3012. modelPtr = (modelDef_t*)item->typeData;
  3013. if (PC_ParseString(&temp))
  3014. {
  3015. return qfalse;
  3016. }
  3017. char modelPath[MAX_QPATH];
  3018. if (!stricmp(temp,"ui_char_model") )
  3019. {
  3020. Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", Cvar_VariableString ( "g_char_model" ) );
  3021. }
  3022. else
  3023. {
  3024. Com_sprintf( modelPath, sizeof( modelPath ), temp);
  3025. }
  3026. return (ItemParse_asset_model_go( item, modelPath ));
  3027. }
  3028. /*
  3029. ===============
  3030. ItemParse_asset_model
  3031. asset_shader <string>
  3032. ===============
  3033. */
  3034. qboolean ItemParse_asset_shader( itemDef_t *item)
  3035. {
  3036. const char *temp;
  3037. if (PC_ParseString(&temp))
  3038. {
  3039. return qfalse;
  3040. }
  3041. item->asset = DC->registerShaderNoMip(temp);
  3042. return qtrue;
  3043. }
  3044. /*
  3045. ===============
  3046. ItemParse_asset_model
  3047. model_origin <number> <number> <number>
  3048. ===============
  3049. */
  3050. qboolean ItemParse_model_origin( itemDef_t *item)
  3051. {
  3052. modelDef_t *modelPtr;
  3053. Item_ValidateTypeData(item);
  3054. modelPtr = (modelDef_t*)item->typeData;
  3055. if (!PC_ParseFloat(&modelPtr->origin[0]))
  3056. {
  3057. if (!PC_ParseFloat(&modelPtr->origin[1]))
  3058. {
  3059. if (!PC_ParseFloat(&modelPtr->origin[2]))
  3060. {
  3061. return qtrue;
  3062. }
  3063. }
  3064. }
  3065. return qfalse;
  3066. }
  3067. /*
  3068. ===============
  3069. ItemParse_model_fovx
  3070. model_fovx <number>
  3071. ===============
  3072. */
  3073. qboolean ItemParse_model_fovx( itemDef_t *item)
  3074. {
  3075. modelDef_t *modelPtr;
  3076. Item_ValidateTypeData(item);
  3077. modelPtr = (modelDef_t*)item->typeData;
  3078. if (PC_ParseFloat(&modelPtr->fov_x))
  3079. {
  3080. return qfalse;
  3081. }
  3082. return qtrue;
  3083. }
  3084. /*
  3085. ===============
  3086. ItemParse_model_fovy
  3087. model_fovy <number>
  3088. ===============
  3089. */
  3090. qboolean ItemParse_model_fovy( itemDef_t *item)
  3091. {
  3092. modelDef_t *modelPtr;
  3093. Item_ValidateTypeData(item);
  3094. modelPtr = (modelDef_t*)item->typeData;
  3095. if (PC_ParseFloat(&modelPtr->fov_y))
  3096. {
  3097. return qfalse;
  3098. }
  3099. return qtrue;
  3100. }
  3101. /*
  3102. ===============
  3103. ItemParse_model_rotation
  3104. model_rotation <integer>
  3105. ===============
  3106. */
  3107. qboolean ItemParse_model_rotation( itemDef_t *item)
  3108. {
  3109. modelDef_t *modelPtr;
  3110. Item_ValidateTypeData(item);
  3111. modelPtr = (modelDef_t*)item->typeData;
  3112. if (PC_ParseInt(&modelPtr->rotationSpeed))
  3113. {
  3114. return qfalse;
  3115. }
  3116. return qtrue;
  3117. }
  3118. /*
  3119. ===============
  3120. ItemParse_model_angle
  3121. model_angle <integer>
  3122. ===============
  3123. */
  3124. qboolean ItemParse_model_angle( itemDef_t *item)
  3125. {
  3126. modelDef_t *modelPtr;
  3127. Item_ValidateTypeData(item);
  3128. modelPtr = (modelDef_t*)item->typeData;
  3129. if (PC_ParseInt(&modelPtr->angle))
  3130. {
  3131. return qfalse;
  3132. }
  3133. return qtrue;
  3134. }
  3135. // model_g2mins <number> <number> <number>
  3136. qboolean ItemParse_model_g2mins( itemDef_t *item ) {
  3137. modelDef_t *modelPtr;
  3138. Item_ValidateTypeData(item);
  3139. modelPtr = (modelDef_t*)item->typeData;
  3140. if (!PC_ParseFloat(&modelPtr->g2mins[0])) {
  3141. if (!PC_ParseFloat(&modelPtr->g2mins[1])) {
  3142. if (!PC_ParseFloat(&modelPtr->g2mins[2])) {
  3143. return qtrue;
  3144. }
  3145. }
  3146. }
  3147. return qfalse;
  3148. }
  3149. // model_g2maxs <number> <number> <number>
  3150. qboolean ItemParse_model_g2maxs( itemDef_t *item ) {
  3151. modelDef_t *modelPtr;
  3152. Item_ValidateTypeData(item);
  3153. modelPtr = (modelDef_t*)item->typeData;
  3154. if (!PC_ParseFloat(&modelPtr->g2maxs[0])) {
  3155. if (!PC_ParseFloat(&modelPtr->g2maxs[1])) {
  3156. if (!PC_ParseFloat(&modelPtr->g2maxs[2])) {
  3157. return qtrue;
  3158. }
  3159. }
  3160. }
  3161. return qfalse;
  3162. }
  3163. // model_g2skin <string>
  3164. qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName )
  3165. {
  3166. modelDef_t *modelPtr;
  3167. Item_ValidateTypeData(item);
  3168. modelPtr = (modelDef_t*)item->typeData;
  3169. if (!skinName || !skinName[0])
  3170. { //it was parsed cor~rectly so still return true.
  3171. modelPtr->g2skin = 0;
  3172. DC->g2_SetSkin( &item->ghoul2[0], -1, 0 );//turn off custom skin
  3173. return qtrue;
  3174. }
  3175. modelPtr->g2skin = DC->registerSkin(skinName);
  3176. if ( item->ghoul2.IsValid() )
  3177. {
  3178. DC->g2_SetSkin( &item->ghoul2[0], 0, modelPtr->g2skin );//this is going to set the surfs on/off matching the skin file
  3179. }
  3180. return qtrue;
  3181. }
  3182. qboolean ItemParse_model_g2skin( itemDef_t *item )
  3183. {
  3184. const char *skinName;
  3185. if (PC_ParseString(&skinName)) {
  3186. return qfalse;
  3187. }
  3188. return (ItemParse_model_g2skin_go( item, skinName ));
  3189. }
  3190. // model_g2anim <number>
  3191. qboolean ItemParse_model_g2anim_go( itemDef_t *item, const char *animName )
  3192. {
  3193. modelDef_t *modelPtr;
  3194. int i = 0;
  3195. Item_ValidateTypeData(item);
  3196. modelPtr = (modelDef_t*)item->typeData;
  3197. if (!animName || !animName[0])
  3198. { //it was parsed correctly so still return true.
  3199. return qtrue;
  3200. }
  3201. while (i < MAX_ANIMATIONS)
  3202. {
  3203. if (!Q_stricmp(animName, animTable[i].name))
  3204. { //found it
  3205. modelPtr->g2anim = animTable[i].id;
  3206. return qtrue;
  3207. }
  3208. i++;
  3209. }
  3210. Com_Printf("Could not find '%s' in the anim table\n", animName);
  3211. return qtrue;
  3212. }
  3213. qboolean ItemParse_model_g2anim( itemDef_t *item ) {
  3214. const char *animName;
  3215. if (PC_ParseString(&animName)) {
  3216. return qfalse;
  3217. }
  3218. return ItemParse_model_g2anim_go( item, animName );
  3219. }
  3220. /*
  3221. ===============
  3222. ItemParse_rect
  3223. rect <rectangle>
  3224. ===============
  3225. */
  3226. qboolean ItemParse_rect( itemDef_t *item)
  3227. {
  3228. if (!PC_ParseRect(&item->window.rectClient))
  3229. {
  3230. return qfalse;
  3231. }
  3232. return qtrue;
  3233. }
  3234. /*
  3235. ===============
  3236. ItemParse_flag
  3237. flag <integer>
  3238. ===============
  3239. */
  3240. qboolean ItemParse_flag( itemDef_t *item)
  3241. {
  3242. int i;
  3243. const char *tempStr;
  3244. if (PC_ParseString(&tempStr))
  3245. {
  3246. return qfalse;
  3247. }
  3248. i=0;
  3249. while (itemFlags[i].string)
  3250. {
  3251. if (Q_stricmp(tempStr,itemFlags[i].string)==0)
  3252. {
  3253. item->window.flags |= itemFlags[i].value;
  3254. break;
  3255. }
  3256. i++;
  3257. }
  3258. if (itemFlags[i].string == NULL)
  3259. {
  3260. PC_ParseWarning(va("Unknown item flag value '%s'",tempStr));
  3261. }
  3262. return qtrue;
  3263. }
  3264. /*
  3265. ===============
  3266. ItemParse_style
  3267. style <integer>
  3268. ===============
  3269. */
  3270. qboolean ItemParse_style( itemDef_t *item)
  3271. {
  3272. int i;
  3273. const char *tempStr;
  3274. if (PC_ParseString(&tempStr))
  3275. {
  3276. return qfalse;
  3277. }
  3278. i=0;
  3279. while (styles[i])
  3280. {
  3281. if (Q_stricmp(tempStr,styles[i])==0)
  3282. {
  3283. item->window.style = i;
  3284. break;
  3285. }
  3286. i++;
  3287. }
  3288. if (styles[i] == NULL)
  3289. {
  3290. PC_ParseWarning(va("Unknown item style value '%s'",tempStr));
  3291. }
  3292. return qtrue;
  3293. }
  3294. /*
  3295. ===============
  3296. ItemParse_decoration
  3297. decoration
  3298. ===============
  3299. */
  3300. qboolean ItemParse_decoration( itemDef_t *item )
  3301. {
  3302. item->window.flags |= WINDOW_DECORATION;
  3303. return qtrue;
  3304. }
  3305. /*
  3306. ===============
  3307. ItemParse_notselectable
  3308. notselectable
  3309. ===============
  3310. */
  3311. qboolean ItemParse_notselectable( itemDef_t *item )
  3312. {
  3313. listBoxDef_t *listPtr;
  3314. Item_ValidateTypeData(item);
  3315. listPtr = (listBoxDef_t*)item->typeData;
  3316. if (item->type == ITEM_TYPE_LISTBOX && listPtr)
  3317. {
  3318. listPtr->notselectable = qtrue;
  3319. }
  3320. return qtrue;
  3321. }
  3322. //JLF
  3323. #ifdef _XBOX
  3324. /*
  3325. ===============
  3326. ItemParse_scrollhidden
  3327. scrollhidden
  3328. ===============
  3329. */
  3330. qboolean ItemParse_scrollhidden( itemDef_t *item )
  3331. {
  3332. listBoxDef_t *listPtr;
  3333. Item_ValidateTypeData(item);
  3334. listPtr = (listBoxDef_t*)item->typeData;
  3335. if (item->type == ITEM_TYPE_LISTBOX && listPtr)
  3336. {
  3337. listPtr->scrollhidden = qtrue;
  3338. }
  3339. return qtrue;
  3340. }
  3341. /*
  3342. ===============
  3343. ItemParse_selectionShader
  3344. selectionShader
  3345. ===============
  3346. */
  3347. qboolean ItemParse_selectionShader( itemDef_t *item )
  3348. {
  3349. const char *temp;
  3350. if (PC_ParseString(&temp))
  3351. {
  3352. return qfalse;
  3353. }
  3354. listBoxDef_t *listPtr;
  3355. Item_ValidateTypeData( item );
  3356. listPtr = (listBoxDef_t *)item->typeData;
  3357. if (item->type == ITEM_TYPE_LISTBOX && listPtr)
  3358. {
  3359. listPtr->selectionShader = ui.R_RegisterShaderNoMip(temp);
  3360. }
  3361. return qtrue;
  3362. }
  3363. #endif
  3364. /*
  3365. ===============
  3366. ItemParse_wrapped
  3367. manually wrapped
  3368. ===============
  3369. */
  3370. qboolean ItemParse_wrapped( itemDef_t *item )
  3371. {
  3372. item->window.flags |= WINDOW_WRAPPED;
  3373. return qtrue;
  3374. }
  3375. /*
  3376. ===============
  3377. ItemParse_autowrapped
  3378. auto wrapped
  3379. ===============
  3380. */
  3381. qboolean ItemParse_autowrapped( itemDef_t *item)
  3382. {
  3383. item->window.flags |= WINDOW_AUTOWRAPPED;
  3384. return qtrue;
  3385. }
  3386. /*
  3387. ===============
  3388. ItemParse_horizontalscroll
  3389. horizontalscroll
  3390. ===============
  3391. */
  3392. qboolean ItemParse_horizontalscroll( itemDef_t *item )
  3393. {
  3394. item->window.flags |= WINDOW_HORIZONTAL;
  3395. return qtrue;
  3396. }
  3397. /*
  3398. ===============
  3399. ItemParse_type
  3400. type <integer>
  3401. ===============
  3402. */
  3403. qboolean ItemParse_type( itemDef_t *item )
  3404. {
  3405. int i;
  3406. const char *tempStr;
  3407. if (PC_ParseString(&tempStr))
  3408. {
  3409. return qfalse;
  3410. }
  3411. i=0;
  3412. while (types[i])
  3413. {
  3414. if (Q_stricmp(tempStr,types[i])==0)
  3415. {
  3416. item->type = i;
  3417. break;
  3418. }
  3419. i++;
  3420. }
  3421. if (types[i] == NULL)
  3422. {
  3423. PC_ParseWarning(va("Unknown item type value '%s'",tempStr));
  3424. }
  3425. else
  3426. {
  3427. Item_ValidateTypeData(item);
  3428. }
  3429. return qtrue;
  3430. }
  3431. /*
  3432. ===============
  3433. ItemParse_elementwidth
  3434. elementwidth, used for listbox image elements
  3435. uses textalignx for storage
  3436. ===============
  3437. */
  3438. qboolean ItemParse_elementwidth( itemDef_t *item )
  3439. {
  3440. listBoxDef_t *listPtr;
  3441. Item_ValidateTypeData(item);
  3442. listPtr = (listBoxDef_t*)item->typeData;
  3443. if (PC_ParseFloat(&listPtr->elementWidth))
  3444. {
  3445. return qfalse;
  3446. }
  3447. return qtrue;
  3448. }
  3449. /*
  3450. ===============
  3451. ItemParse_elementheight
  3452. elementheight, used for listbox image elements
  3453. uses textaligny for storage
  3454. ===============
  3455. */
  3456. qboolean ItemParse_elementheight( itemDef_t *item )
  3457. {
  3458. listBoxDef_t *listPtr;
  3459. Item_ValidateTypeData(item);
  3460. listPtr = (listBoxDef_t*)item->typeData;
  3461. if (PC_ParseFloat(&listPtr->elementHeight))
  3462. {
  3463. return qfalse;
  3464. }
  3465. return qtrue;
  3466. }
  3467. /*
  3468. ===============
  3469. ItemParse_feeder
  3470. feeder <float>
  3471. ===============
  3472. */
  3473. qboolean ItemParse_feeder( itemDef_t *item )
  3474. {
  3475. if (PC_ParseFloat( &item->special))
  3476. {
  3477. return qfalse;
  3478. }
  3479. return qtrue;
  3480. }
  3481. /*
  3482. ===============
  3483. ItemParse_elementtype
  3484. elementtype, used to specify what type of elements a listbox contains
  3485. uses textstyle for storage
  3486. ===============
  3487. */
  3488. qboolean ItemParse_elementtype( itemDef_t *item )
  3489. {
  3490. listBoxDef_t *listPtr;
  3491. Item_ValidateTypeData(item);
  3492. if (!item->typeData)
  3493. {
  3494. return qfalse;
  3495. }
  3496. listPtr = (listBoxDef_t*)item->typeData;
  3497. if (PC_ParseInt(&listPtr->elementStyle))
  3498. {
  3499. return qfalse;
  3500. }
  3501. return qtrue;
  3502. }
  3503. /*
  3504. ===============
  3505. ItemParse_columns
  3506. columns sets a number of columns and an x pos and width per..
  3507. ===============
  3508. */
  3509. qboolean ItemParse_columns( itemDef_t *item)
  3510. {
  3511. int num, i;
  3512. listBoxDef_t *listPtr;
  3513. Item_ValidateTypeData(item);
  3514. if (!item->typeData)
  3515. {
  3516. return qfalse;
  3517. }
  3518. listPtr = (listBoxDef_t*)item->typeData;
  3519. if (!PC_ParseInt(&num))
  3520. {
  3521. if (num > MAX_LB_COLUMNS)
  3522. {
  3523. num = MAX_LB_COLUMNS;
  3524. }
  3525. listPtr->numColumns = num;
  3526. for (i = 0; i < num; i++)
  3527. {
  3528. int pos, width, maxChars;
  3529. if (!PC_ParseInt(&pos) && !PC_ParseInt(&width) && !PC_ParseInt(&maxChars))
  3530. {
  3531. listPtr->columnInfo[i].pos = pos;
  3532. listPtr->columnInfo[i].width = width;
  3533. listPtr->columnInfo[i].maxChars = maxChars;
  3534. }
  3535. else
  3536. {
  3537. return qfalse;
  3538. }
  3539. }
  3540. }
  3541. else
  3542. {
  3543. return qfalse;
  3544. }
  3545. return qtrue;
  3546. }
  3547. /*
  3548. ===============
  3549. ItemParse_border
  3550. ===============
  3551. */
  3552. qboolean ItemParse_border( itemDef_t *item)
  3553. {
  3554. if (PC_ParseInt(&item->window.border))
  3555. {
  3556. return qfalse;
  3557. }
  3558. return qtrue;
  3559. }
  3560. /*
  3561. ===============
  3562. ItemParse_bordersize
  3563. ===============
  3564. */
  3565. qboolean ItemParse_bordersize( itemDef_t *item )
  3566. {
  3567. if (PC_ParseFloat(&item->window.borderSize))
  3568. {
  3569. return qfalse;
  3570. }
  3571. return qtrue;
  3572. }
  3573. /*
  3574. ===============
  3575. ItemParse_visible
  3576. ===============
  3577. */
  3578. qboolean ItemParse_visible( itemDef_t *item)
  3579. {
  3580. int i;
  3581. if (PC_ParseInt(&i))
  3582. {
  3583. return qfalse;
  3584. }
  3585. if (i)
  3586. {
  3587. item->window.flags |= WINDOW_VISIBLE;
  3588. }
  3589. return qtrue;
  3590. }
  3591. /*
  3592. ===============
  3593. ItemParse_ownerdraw
  3594. ===============
  3595. */
  3596. qboolean ItemParse_ownerdraw( itemDef_t *item)
  3597. {
  3598. if (PC_ParseInt(&item->window.ownerDraw))
  3599. {
  3600. return qfalse;
  3601. }
  3602. item->type = ITEM_TYPE_OWNERDRAW;
  3603. return qtrue;
  3604. }
  3605. /*
  3606. ===============
  3607. ItemParse_align
  3608. ===============
  3609. */
  3610. qboolean ItemParse_align( itemDef_t *item)
  3611. {
  3612. if (PC_ParseInt(&item->alignment))
  3613. {
  3614. return qfalse;
  3615. }
  3616. return qtrue;
  3617. }
  3618. /*
  3619. ===============
  3620. ItemParse_align
  3621. ===============
  3622. */
  3623. /*
  3624. qboolean ItemParse_Appearance_slot( itemDef_t *item)
  3625. {
  3626. if (PC_ParseInt(&item->appearanceSlot))
  3627. {
  3628. return qfalse;
  3629. }
  3630. return qtrue;
  3631. }
  3632. */
  3633. /*
  3634. ===============
  3635. ItemParse_textalign
  3636. ===============
  3637. */
  3638. qboolean ItemParse_textalign( itemDef_t *item )
  3639. {
  3640. const char *tempStr;
  3641. int i;
  3642. if (PC_ParseString(&tempStr))
  3643. {
  3644. return qfalse;
  3645. }
  3646. i=0;
  3647. while (alignment[i])
  3648. {
  3649. if (Q_stricmp(tempStr,alignment[i])==0)
  3650. {
  3651. item->textalignment = i;
  3652. break;
  3653. }
  3654. i++;
  3655. }
  3656. if (alignment[i] == NULL)
  3657. {
  3658. PC_ParseWarning(va("Unknown text alignment value '%s'",tempStr));
  3659. }
  3660. return qtrue;
  3661. }
  3662. /*
  3663. ===============
  3664. ItemParse_text2alignx
  3665. ===============
  3666. */
  3667. /*
  3668. qboolean ItemParse_text2alignx( itemDef_t *item)
  3669. {
  3670. if (PC_ParseFloat(&item->text2alignx))
  3671. {
  3672. return qfalse;
  3673. }
  3674. return qtrue;
  3675. }
  3676. */
  3677. /*
  3678. ===============
  3679. ItemParse_text2aligny
  3680. ===============
  3681. */
  3682. /*
  3683. qboolean ItemParse_text2aligny( itemDef_t *item)
  3684. {
  3685. if (PC_ParseFloat(&item->text2aligny))
  3686. {
  3687. return qfalse;
  3688. }
  3689. return qtrue;
  3690. }
  3691. */
  3692. /*
  3693. ===============
  3694. ItemParse_textalignx
  3695. ===============
  3696. */
  3697. qboolean ItemParse_textalignx( itemDef_t *item)
  3698. {
  3699. if (PC_ParseFloat(&item->textalignx))
  3700. {
  3701. return qfalse;
  3702. }
  3703. return qtrue;
  3704. }
  3705. /*
  3706. ===============
  3707. ItemParse_textaligny
  3708. ===============
  3709. */
  3710. qboolean ItemParse_textaligny( itemDef_t *item)
  3711. {
  3712. if (PC_ParseFloat(&item->textaligny))
  3713. {
  3714. return qfalse;
  3715. }
  3716. return qtrue;
  3717. }
  3718. /*
  3719. ===============
  3720. ItemParse_textscale
  3721. ===============
  3722. */
  3723. qboolean ItemParse_textscale( itemDef_t *item )
  3724. {
  3725. if (PC_ParseFloat(&item->textscale))
  3726. {
  3727. return qfalse;
  3728. }
  3729. return qtrue;
  3730. }
  3731. /*
  3732. ===============
  3733. ItemParse_textstyle
  3734. ===============
  3735. */
  3736. qboolean ItemParse_textstyle( itemDef_t *item)
  3737. {
  3738. if (PC_ParseInt(&item->textStyle))
  3739. {
  3740. return qfalse;
  3741. }
  3742. return qtrue;
  3743. }
  3744. /*
  3745. ===============
  3746. ItemParse_invertyesno
  3747. ===============
  3748. */
  3749. /*
  3750. qboolean ItemParse_invertyesno( itemDef_t *item)
  3751. {
  3752. if (PC_ParseInt(&item->invertYesNo))
  3753. {
  3754. return qfalse;
  3755. }
  3756. return qtrue;
  3757. }
  3758. */
  3759. /*
  3760. ===============
  3761. ItemParse_xoffset (used for yes/no and multi)
  3762. ===============
  3763. */
  3764. qboolean ItemParse_xoffset( itemDef_t *item)
  3765. {
  3766. if (PC_ParseInt(&item->xoffset))
  3767. {
  3768. return qfalse;
  3769. }
  3770. return qtrue;
  3771. }
  3772. /*
  3773. ===============
  3774. ItemParse_backcolor
  3775. ===============
  3776. */
  3777. qboolean ItemParse_backcolor( itemDef_t *item)
  3778. {
  3779. int i;
  3780. float f;
  3781. for (i = 0; i < 4; i++)
  3782. {
  3783. if (PC_ParseFloat(&f))
  3784. {
  3785. return qfalse;
  3786. }
  3787. item->window.backColor[i] = f;
  3788. }
  3789. return qtrue;
  3790. }
  3791. /*
  3792. ===============
  3793. ItemParse_forecolor
  3794. ===============
  3795. */
  3796. qboolean ItemParse_forecolor( itemDef_t *item)
  3797. {
  3798. int i;
  3799. float f;
  3800. for (i = 0; i < 4; i++)
  3801. {
  3802. if (PC_ParseFloat(&f))
  3803. {
  3804. return qfalse;
  3805. }
  3806. if (f < 0)
  3807. { //special case for player color
  3808. item->window.flags |= WINDOW_PLAYERCOLOR;
  3809. return qtrue;
  3810. }
  3811. item->window.foreColor[i] = f;
  3812. item->window.flags |= WINDOW_FORECOLORSET;
  3813. }
  3814. return qtrue;
  3815. }
  3816. /*
  3817. ===============
  3818. ItemParse_bordercolor
  3819. ===============
  3820. */
  3821. qboolean ItemParse_bordercolor( itemDef_t *item)
  3822. {
  3823. int i;
  3824. float f;
  3825. for (i = 0; i < 4; i++)
  3826. {
  3827. if (PC_ParseFloat(&f))
  3828. {
  3829. return qfalse;
  3830. }
  3831. item->window.borderColor[i] = f;
  3832. }
  3833. return qtrue;
  3834. }
  3835. /*
  3836. ===============
  3837. ItemParse_outlinecolor
  3838. ===============
  3839. */
  3840. /*
  3841. qboolean ItemParse_outlinecolor( itemDef_t *item)
  3842. {
  3843. if (PC_ParseColor(&item->window.outlineColor))
  3844. {
  3845. return qfalse;
  3846. }
  3847. return qtrue;
  3848. }
  3849. */
  3850. /*
  3851. ===============
  3852. ItemParse_background
  3853. ===============
  3854. */
  3855. qboolean ItemParse_background( itemDef_t *item)
  3856. {
  3857. const char *temp;
  3858. if (PC_ParseString(&temp))
  3859. {
  3860. return qfalse;
  3861. }
  3862. item->window.background = ui.R_RegisterShaderNoMip(temp);
  3863. return qtrue;
  3864. }
  3865. /*
  3866. ===============
  3867. ItemParse_cinematic
  3868. ===============
  3869. */
  3870. /*
  3871. qboolean ItemParse_cinematic( itemDef_t *item)
  3872. {
  3873. if (!PC_ParseStringMem((const char **) &item->window.cinematicName))
  3874. {
  3875. return qfalse;
  3876. }
  3877. return qtrue;
  3878. }
  3879. */
  3880. /*
  3881. ===============
  3882. ItemParse_doubleClick
  3883. ===============
  3884. */
  3885. qboolean ItemParse_doubleClick( itemDef_t *item)
  3886. {
  3887. listBoxDef_t *listPtr;
  3888. Item_ValidateTypeData(item);
  3889. if (!item->typeData)
  3890. {
  3891. return qfalse;
  3892. }
  3893. listPtr = (listBoxDef_t*)item->typeData;
  3894. if (!PC_Script_Parse(&listPtr->doubleClick))
  3895. {
  3896. return qfalse;
  3897. }
  3898. return qtrue;
  3899. }
  3900. /*
  3901. ===============
  3902. ItemParse_onFocus
  3903. ===============
  3904. */
  3905. qboolean ItemParse_onFocus( itemDef_t *item)
  3906. {
  3907. if (!PC_Script_Parse(&item->onFocus))
  3908. {
  3909. return qfalse;
  3910. }
  3911. return qtrue;
  3912. }
  3913. /*
  3914. ===============
  3915. ItemParse_leaveFocus
  3916. ===============
  3917. */
  3918. qboolean ItemParse_leaveFocus( itemDef_t *item )
  3919. {
  3920. if (!PC_Script_Parse(&item->leaveFocus))
  3921. {
  3922. return qfalse;
  3923. }
  3924. return qtrue;
  3925. }
  3926. /*
  3927. ===============
  3928. ItemParse_mouseEnter
  3929. ===============
  3930. */
  3931. /*
  3932. qboolean ItemParse_mouseEnter( itemDef_t *item)
  3933. {
  3934. if (!PC_Script_Parse(&item->mouseEnter))
  3935. {
  3936. return qfalse;
  3937. }
  3938. return qtrue;
  3939. }
  3940. */
  3941. /*
  3942. ===============
  3943. ItemParse_mouseExit
  3944. ===============
  3945. */
  3946. /*
  3947. qboolean ItemParse_mouseExit( itemDef_t *item)
  3948. {
  3949. if (!PC_Script_Parse(&item->mouseExit))
  3950. {
  3951. return qfalse;
  3952. }
  3953. return qtrue;
  3954. }
  3955. */
  3956. /*
  3957. ===============
  3958. ItemParse_mouseEnterText
  3959. ===============
  3960. */
  3961. /*
  3962. qboolean ItemParse_mouseEnterText( itemDef_t *item)
  3963. {
  3964. if (!PC_Script_Parse(&item->mouseEnterText))
  3965. {
  3966. return qfalse;
  3967. }
  3968. return qtrue;
  3969. }
  3970. */
  3971. /*
  3972. ===============
  3973. ItemParse_mouseExitText
  3974. ===============
  3975. */
  3976. /*
  3977. qboolean ItemParse_mouseExitText( itemDef_t *item)
  3978. {
  3979. if (!PC_Script_Parse(&item->mouseExitText))
  3980. {
  3981. return qfalse;
  3982. }
  3983. return qtrue;
  3984. }
  3985. */
  3986. /*
  3987. ===============
  3988. ItemParse_accept
  3989. ===============
  3990. */
  3991. /*
  3992. qboolean ItemParse_accept( itemDef_t *item)
  3993. {
  3994. if (!PC_Script_Parse(&item->accept))
  3995. {
  3996. return qfalse;
  3997. }
  3998. return qtrue;
  3999. }
  4000. */
  4001. //JLFDPADSCRIPT
  4002. /*
  4003. ===============
  4004. ItemParse_selectionNext
  4005. ===============
  4006. */
  4007. qboolean ItemParse_selectionNext( itemDef_t *item)
  4008. {
  4009. if (!PC_Script_Parse(&item->selectionNext))
  4010. {
  4011. return qfalse;
  4012. }
  4013. return qtrue;
  4014. }
  4015. /*
  4016. ===============
  4017. ItemParse_selectionPrev
  4018. ===============
  4019. */
  4020. qboolean ItemParse_selectionPrev( itemDef_t *item)
  4021. {
  4022. if (!PC_Script_Parse(&item->selectionPrev))
  4023. {
  4024. return qfalse;
  4025. }
  4026. return qtrue;
  4027. }
  4028. // END JLFDPADSCRIPT
  4029. /*
  4030. ===============
  4031. ItemParse_action
  4032. ===============
  4033. */
  4034. qboolean ItemParse_action( itemDef_t *item)
  4035. {
  4036. if (!PC_Script_Parse(&item->action))
  4037. {
  4038. return qfalse;
  4039. }
  4040. return qtrue;
  4041. }
  4042. /*
  4043. ===============
  4044. ItemParse_special
  4045. ===============
  4046. */
  4047. qboolean ItemParse_special( itemDef_t *item)
  4048. {
  4049. if (PC_ParseFloat(&item->special))
  4050. {
  4051. return qfalse;
  4052. }
  4053. return qtrue;
  4054. }
  4055. /*
  4056. ===============
  4057. ItemParse_cvarTest
  4058. ===============
  4059. */
  4060. qboolean ItemParse_cvarTest( itemDef_t *item)
  4061. {
  4062. if (!PC_ParseStringMem((const char **) &item->cvarTest))
  4063. {
  4064. return qfalse;
  4065. }
  4066. return qtrue;
  4067. }
  4068. /*
  4069. ===============
  4070. ItemParse_cvar
  4071. ===============
  4072. */
  4073. qboolean ItemParse_cvar( itemDef_t *item)
  4074. {
  4075. editFieldDef_t *editPtr;
  4076. Item_ValidateTypeData(item);
  4077. if (!PC_ParseStringMem(&item->cvar))
  4078. {
  4079. return qfalse;
  4080. }
  4081. if ( item->typeData)
  4082. {
  4083. switch ( item->type )
  4084. {
  4085. case ITEM_TYPE_EDITFIELD:
  4086. case ITEM_TYPE_NUMERICFIELD:
  4087. case ITEM_TYPE_YESNO:
  4088. case ITEM_TYPE_BIND:
  4089. case ITEM_TYPE_SLIDER:
  4090. case ITEM_TYPE_TEXT:
  4091. case ITEM_TYPE_TEXTSCROLL:
  4092. editPtr = (editFieldDef_t*)item->typeData;
  4093. editPtr->minVal = -1;
  4094. editPtr->maxVal = -1;
  4095. editPtr->defVal = -1;
  4096. break;
  4097. }
  4098. }
  4099. return qtrue;
  4100. }
  4101. /*
  4102. ===============
  4103. ItemParse_maxChars
  4104. ===============
  4105. */
  4106. qboolean ItemParse_maxChars( itemDef_t *item)
  4107. {
  4108. editFieldDef_t *editPtr;
  4109. int maxChars;
  4110. Item_ValidateTypeData(item);
  4111. if (!item->typeData)
  4112. {
  4113. return qfalse;
  4114. }
  4115. if (PC_ParseInt(&maxChars))
  4116. {
  4117. return qfalse;
  4118. }
  4119. editPtr = (editFieldDef_t*)item->typeData;
  4120. editPtr->maxChars = maxChars;
  4121. return qtrue;
  4122. }
  4123. /*
  4124. ===============
  4125. ItemParse_maxPaintChars
  4126. ===============
  4127. */
  4128. qboolean ItemParse_maxPaintChars( itemDef_t *item)
  4129. {
  4130. editFieldDef_t *editPtr;
  4131. int maxChars;
  4132. Item_ValidateTypeData(item);
  4133. if (!item->typeData)
  4134. {
  4135. return qfalse;
  4136. }
  4137. if (PC_ParseInt(&maxChars))
  4138. {
  4139. return qfalse;
  4140. }
  4141. editPtr = (editFieldDef_t*)item->typeData;
  4142. editPtr->maxPaintChars = maxChars;
  4143. return qtrue;
  4144. }
  4145. qboolean ItemParse_lineHeight( itemDef_t *item)
  4146. {
  4147. textScrollDef_t *scrollPtr;
  4148. int height;
  4149. Item_ValidateTypeData(item);
  4150. if (!item->typeData)
  4151. {
  4152. return qfalse;
  4153. }
  4154. if (PC_ParseInt(&height))
  4155. {
  4156. return qfalse;
  4157. }
  4158. scrollPtr = (textScrollDef_t*)item->typeData;
  4159. scrollPtr->lineHeight = height;
  4160. return qtrue;
  4161. }
  4162. /*
  4163. ===============
  4164. ItemParse_cvarFloat
  4165. ===============
  4166. */
  4167. qboolean ItemParse_cvarFloat( itemDef_t *item)
  4168. {
  4169. editFieldDef_t *editPtr;
  4170. Item_ValidateTypeData(item);
  4171. if (!item->typeData)
  4172. {
  4173. return qfalse;
  4174. }
  4175. editPtr = (editFieldDef_t*)item->typeData;
  4176. if (PC_ParseStringMem((const char **) &item->cvar) &&
  4177. !PC_ParseFloat(&editPtr->defVal) &&
  4178. !PC_ParseFloat(&editPtr->minVal) &&
  4179. !PC_ParseFloat(&editPtr->maxVal))
  4180. {
  4181. if (!stricmp(item->cvar,"r_ext_texture_filter_anisotropic"))
  4182. {//hehe, hook up the correct max value here.
  4183. editPtr->maxVal=glConfig.maxTextureFilterAnisotropy;
  4184. }
  4185. return qtrue;
  4186. }
  4187. return qfalse;
  4188. }
  4189. /*
  4190. ===============
  4191. ItemParse_cvarStrList
  4192. ===============
  4193. */
  4194. qboolean ItemParse_cvarStrList( itemDef_t *item)
  4195. {
  4196. const char *token;
  4197. multiDef_t *multiPtr;
  4198. int pass;
  4199. Item_ValidateTypeData(item);
  4200. if (!item->typeData)
  4201. {
  4202. return qfalse;
  4203. }
  4204. multiPtr = (multiDef_t*)item->typeData;
  4205. multiPtr->count = 0;
  4206. multiPtr->strDef = qtrue;
  4207. if (PC_ParseString(&token))
  4208. {
  4209. return qfalse;
  4210. }
  4211. if (!stricmp(token,"feeder") && item->special == FEEDER_PLAYER_SPECIES)
  4212. {
  4213. for (; multiPtr->count < uiInfo.playerSpeciesCount; multiPtr->count++)
  4214. {
  4215. multiPtr->cvarList[multiPtr->count] = String_Alloc(strupr(va("@MENUS_%s",uiInfo.playerSpecies[multiPtr->count].Name ))); //look up translation
  4216. multiPtr->cvarStr[multiPtr->count] = uiInfo.playerSpecies[multiPtr->count].Name; //value
  4217. }
  4218. return qtrue;
  4219. }
  4220. // languages
  4221. if (!stricmp(token,"feeder") && item->special == FEEDER_LANGUAGES)
  4222. {
  4223. assert( 0 );
  4224. /*
  4225. for (; multiPtr->count < uiInfo.languageCount; multiPtr->count++)
  4226. {
  4227. // The displayed text
  4228. multiPtr->cvarList[multiPtr->count] = "@MENUS_MYLANGUAGE";
  4229. // The cvar value that goes into se_language
  4230. multiPtr->cvarStr[multiPtr->count] = SE_GetLanguageName( multiPtr->count );
  4231. }
  4232. */
  4233. return qtrue;
  4234. }
  4235. if (*token != '{')
  4236. {
  4237. return qfalse;
  4238. }
  4239. pass = 0;
  4240. while ( 1 )
  4241. {
  4242. if (!PC_ParseStringMem(&token))
  4243. {
  4244. PC_ParseWarning("end of file inside menu item\n");
  4245. return qfalse;
  4246. }
  4247. if (*token == '}')
  4248. {
  4249. return qtrue;
  4250. }
  4251. if (*token == ',' || *token == ';')
  4252. {
  4253. continue;
  4254. }
  4255. if (pass == 0)
  4256. {
  4257. multiPtr->cvarList[multiPtr->count] = token;
  4258. pass = 1;
  4259. }
  4260. else
  4261. {
  4262. multiPtr->cvarStr[multiPtr->count] = token;
  4263. pass = 0;
  4264. multiPtr->count++;
  4265. if (multiPtr->count >= MAX_MULTI_CVARS)
  4266. {
  4267. return qfalse;
  4268. }
  4269. }
  4270. }
  4271. return qfalse;
  4272. }
  4273. /*
  4274. ===============
  4275. ItemParse_cvarFloatList
  4276. ===============
  4277. */
  4278. qboolean ItemParse_cvarFloatList( itemDef_t *item)
  4279. {
  4280. const char *token;
  4281. multiDef_t *multiPtr;
  4282. Item_ValidateTypeData(item);
  4283. if (!item->typeData)
  4284. {
  4285. return qfalse;
  4286. }
  4287. multiPtr = (multiDef_t*)item->typeData;
  4288. multiPtr->count = 0;
  4289. multiPtr->strDef = qfalse;
  4290. if (PC_ParseString(&token))
  4291. {
  4292. return qfalse;
  4293. }
  4294. if (*token != '{')
  4295. {
  4296. return qfalse;
  4297. }
  4298. while ( 1 )
  4299. {
  4300. if (!PC_ParseStringMem(&token))
  4301. {
  4302. PC_ParseWarning("end of file inside menu item\n");
  4303. return qfalse;
  4304. }
  4305. if (*token == '}')
  4306. {
  4307. return qtrue;
  4308. }
  4309. if (*token == ',' || *token == ';')
  4310. {
  4311. continue;
  4312. }
  4313. multiPtr->cvarList[multiPtr->count] = token; //a StringAlloc ptr
  4314. if (PC_ParseFloat(&multiPtr->cvarValue[multiPtr->count]))
  4315. {
  4316. return qfalse;
  4317. }
  4318. multiPtr->count++;
  4319. if (multiPtr->count >= MAX_MULTI_CVARS)
  4320. {
  4321. return qfalse;
  4322. }
  4323. }
  4324. return qfalse;
  4325. }
  4326. /*
  4327. ===============
  4328. ItemParse_addColorRange
  4329. ===============
  4330. */
  4331. /*
  4332. qboolean ItemParse_addColorRange( itemDef_t *item)
  4333. {
  4334. colorRangeDef_t color;
  4335. if (PC_ParseFloat(&color.low) &&
  4336. PC_ParseFloat(&color.high) &&
  4337. PC_ParseColor(&color.color) )
  4338. {
  4339. if (item->numColors < MAX_COLOR_RANGES)
  4340. {
  4341. memcpy(&item->colorRanges[item->numColors], &color, sizeof(color));
  4342. item->numColors++;
  4343. }
  4344. return qtrue;
  4345. }
  4346. return qfalse;
  4347. }
  4348. */
  4349. /*
  4350. ===============
  4351. ItemParse_ownerdrawFlag
  4352. ===============
  4353. */
  4354. qboolean ItemParse_ownerdrawFlag( itemDef_t *item )
  4355. {
  4356. int i;
  4357. if (PC_ParseInt(&i))
  4358. {
  4359. return qfalse;
  4360. }
  4361. item->window.ownerDrawFlags |= i;
  4362. return qtrue;
  4363. }
  4364. /*
  4365. ===============
  4366. ItemParse_enableCvar
  4367. ===============
  4368. */
  4369. qboolean ItemParse_enableCvar( itemDef_t *item)
  4370. {
  4371. if (PC_Script_Parse(&item->enableCvar))
  4372. {
  4373. item->cvarFlags = CVAR_ENABLE;
  4374. return qtrue;
  4375. }
  4376. return qfalse;
  4377. }
  4378. /*
  4379. ===============
  4380. ItemParse_disableCvar
  4381. ===============
  4382. */
  4383. qboolean ItemParse_disableCvar( itemDef_t *item )
  4384. {
  4385. if (PC_Script_Parse(&item->enableCvar))
  4386. {
  4387. item->cvarFlags = CVAR_DISABLE;
  4388. return qtrue;
  4389. }
  4390. return qfalse;
  4391. }
  4392. /*
  4393. ===============
  4394. ItemParse_showCvar
  4395. ===============
  4396. */
  4397. qboolean ItemParse_showCvar( itemDef_t *item )
  4398. {
  4399. if (PC_Script_Parse(&item->enableCvar))
  4400. {
  4401. item->cvarFlags = CVAR_SHOW;
  4402. return qtrue;
  4403. }
  4404. return qfalse;
  4405. }
  4406. /*
  4407. ===============
  4408. ItemParse_hideCvar
  4409. ===============
  4410. */
  4411. qboolean ItemParse_hideCvar( itemDef_t *item)
  4412. {
  4413. if (PC_Script_Parse(&item->enableCvar))
  4414. {
  4415. item->cvarFlags = CVAR_HIDE;
  4416. return qtrue;
  4417. }
  4418. return qfalse;
  4419. }
  4420. /*
  4421. ===============
  4422. ItemParse_cvarsubstring
  4423. ===============
  4424. */
  4425. qboolean ItemParse_cvarsubstring( itemDef_t *item)
  4426. {
  4427. assert(item->cvarFlags); //need something set first, then we or in our flag.
  4428. item->cvarFlags |= CVAR_SUBSTRING;
  4429. return qtrue;
  4430. }
  4431. /*
  4432. ===============
  4433. Item_ValidateTypeData
  4434. ===============
  4435. */
  4436. void Item_ValidateTypeData(itemDef_t *item)
  4437. {
  4438. if (item->typeData)
  4439. {
  4440. return;
  4441. }
  4442. if (item->type == ITEM_TYPE_LISTBOX)
  4443. {
  4444. item->typeData = UI_Alloc(sizeof(listBoxDef_t));
  4445. memset(item->typeData, 0, sizeof(listBoxDef_t));
  4446. }
  4447. else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD || item->type == ITEM_TYPE_YESNO || item->type == ITEM_TYPE_BIND || item->type == ITEM_TYPE_SLIDER || item->type == ITEM_TYPE_TEXT)
  4448. {
  4449. item->typeData = UI_Alloc(sizeof(editFieldDef_t));
  4450. memset(item->typeData, 0, sizeof(editFieldDef_t));
  4451. if (item->type == ITEM_TYPE_EDITFIELD)
  4452. {
  4453. if (!((editFieldDef_t *) item->typeData)->maxPaintChars)
  4454. {
  4455. ((editFieldDef_t *) item->typeData)->maxPaintChars = MAX_EDITFIELD;
  4456. }
  4457. }
  4458. }
  4459. else if (item->type == ITEM_TYPE_MULTI)
  4460. {
  4461. item->typeData = UI_Alloc(sizeof(multiDef_t));
  4462. }
  4463. else if (item->type == ITEM_TYPE_MODEL)
  4464. {
  4465. item->typeData = UI_Alloc(sizeof(modelDef_t));
  4466. memset(item->typeData, 0, sizeof(modelDef_t));
  4467. }
  4468. else if (item->type == ITEM_TYPE_TEXTSCROLL )
  4469. {
  4470. item->typeData = UI_Alloc(sizeof(textScrollDef_t));
  4471. }
  4472. }
  4473. qboolean ItemParse_isCharacter( itemDef_t *item )
  4474. {
  4475. int i;
  4476. if ( !PC_ParseInt(&i) )
  4477. {
  4478. if ( i )
  4479. {
  4480. item->flags |= ITF_ISCHARACTER;
  4481. }
  4482. else
  4483. {
  4484. item->flags &= ~ITF_ISCHARACTER;
  4485. }
  4486. return qtrue;
  4487. }
  4488. return qfalse;
  4489. }
  4490. qboolean ItemParse_isSaber( itemDef_t *item )
  4491. {
  4492. extern void UI_SaberLoadParms( void );
  4493. extern qboolean ui_saber_parms_parsed;
  4494. extern void UI_CacheSaberGlowGraphics( void );
  4495. int i;
  4496. if ( !PC_ParseInt(&i) )
  4497. {
  4498. if ( i )
  4499. {
  4500. item->flags |= ITF_ISSABER;
  4501. UI_CacheSaberGlowGraphics();
  4502. if ( !ui_saber_parms_parsed )
  4503. {
  4504. UI_SaberLoadParms();
  4505. }
  4506. }
  4507. else
  4508. {
  4509. item->flags &= ~ITF_ISSABER;
  4510. }
  4511. return qtrue;
  4512. }
  4513. return qfalse;
  4514. }
  4515. qboolean ItemParse_isSaber2( itemDef_t *item )
  4516. {
  4517. extern void UI_SaberLoadParms( void );
  4518. extern qboolean ui_saber_parms_parsed;
  4519. extern void UI_CacheSaberGlowGraphics( void );
  4520. int i;
  4521. if ( !PC_ParseInt(&i) )
  4522. {
  4523. if ( i )
  4524. {
  4525. item->flags |= ITF_ISSABER2;
  4526. UI_CacheSaberGlowGraphics();
  4527. if ( !ui_saber_parms_parsed )
  4528. {
  4529. UI_SaberLoadParms();
  4530. }
  4531. }
  4532. else
  4533. {
  4534. item->flags &= ~ITF_ISSABER2;
  4535. }
  4536. return qtrue;
  4537. }
  4538. return qfalse;
  4539. }
  4540. keywordHash_t itemParseKeywords[] = {
  4541. // {"accept", ItemParse_accept, },
  4542. {"selectNext", ItemParse_selectionNext, },
  4543. {"selectPrev", ItemParse_selectionPrev, },
  4544. {"action", ItemParse_action, },
  4545. // {"addColorRange", ItemParse_addColorRange, },
  4546. {"align", ItemParse_align, },
  4547. // {"appearance_slot", ItemParse_Appearance_slot, },
  4548. {"asset_model", ItemParse_asset_model, },
  4549. {"asset_shader", ItemParse_asset_shader, },
  4550. {"isCharacter", ItemParse_isCharacter, },
  4551. {"isSaber", ItemParse_isSaber, },
  4552. {"isSaber2", ItemParse_isSaber2, },
  4553. {"autowrapped", ItemParse_autowrapped, },
  4554. {"backcolor", ItemParse_backcolor, },
  4555. {"background", ItemParse_background, },
  4556. {"border", ItemParse_border, },
  4557. {"bordercolor", ItemParse_bordercolor, },
  4558. {"bordersize", ItemParse_bordersize, },
  4559. // {"cinematic", ItemParse_cinematic, },
  4560. {"columns", ItemParse_columns, },
  4561. {"cvar", ItemParse_cvar, },
  4562. {"cvarFloat", ItemParse_cvarFloat, },
  4563. {"cvarFloatList", ItemParse_cvarFloatList, },
  4564. {"cvarSubString", ItemParse_cvarsubstring },
  4565. {"cvarStrList", ItemParse_cvarStrList, },
  4566. {"cvarTest", ItemParse_cvarTest, },
  4567. {"decoration", ItemParse_decoration, },
  4568. // {"desctext", ItemParse_descText },
  4569. {"disableCvar", ItemParse_disableCvar, },
  4570. {"doubleclick", ItemParse_doubleClick, },
  4571. {"elementheight", ItemParse_elementheight, },
  4572. {"elementtype", ItemParse_elementtype, },
  4573. {"elementwidth", ItemParse_elementwidth, },
  4574. {"enableCvar", ItemParse_enableCvar, },
  4575. {"feeder", ItemParse_feeder, },
  4576. {"flag", ItemParse_flag, },
  4577. {"focusSound", ItemParse_focusSound, },
  4578. #ifdef _IMMERSION
  4579. {"focusForce", ItemParse_focusForce, },
  4580. #endif // _IMMERSION
  4581. {"font", ItemParse_font, },
  4582. {"forecolor", ItemParse_forecolor, },
  4583. {"group", ItemParse_group, },
  4584. {"hideCvar", ItemParse_hideCvar, },
  4585. {"horizontalscroll",ItemParse_horizontalscroll, },
  4586. {"leaveFocus", ItemParse_leaveFocus, },
  4587. {"maxChars", ItemParse_maxChars, },
  4588. {"maxPaintChars", ItemParse_maxPaintChars, },
  4589. {"model_angle", ItemParse_model_angle, },
  4590. {"model_fovx", ItemParse_model_fovx, },
  4591. {"model_fovy", ItemParse_model_fovy, },
  4592. {"model_origin", ItemParse_model_origin, },
  4593. {"model_rotation", ItemParse_model_rotation, },
  4594. //rww - g2 begin
  4595. {"model_g2mins", ItemParse_model_g2mins, },
  4596. {"model_g2maxs", ItemParse_model_g2maxs, },
  4597. {"model_g2skin", ItemParse_model_g2skin, },
  4598. {"model_g2anim", ItemParse_model_g2anim, },
  4599. //rww - g2 end
  4600. // {"mouseEnter", ItemParse_mouseEnter, },
  4601. // {"mouseEnterText", ItemParse_mouseEnterText, },
  4602. // {"mouseExit", ItemParse_mouseExit, },
  4603. // {"mouseExitText", ItemParse_mouseExitText, },
  4604. {"name", ItemParse_name },
  4605. {"notselectable", ItemParse_notselectable, },
  4606. //JLF
  4607. #ifdef _XBOX
  4608. {"scrollhidden", ItemParse_scrollhidden, },
  4609. #endif
  4610. //JLF END
  4611. {"onFocus", ItemParse_onFocus, },
  4612. // {"outlinecolor", ItemParse_outlinecolor, },
  4613. {"ownerdraw", ItemParse_ownerdraw, },
  4614. {"ownerdrawFlag", ItemParse_ownerdrawFlag, },
  4615. {"rect", ItemParse_rect, },
  4616. {"showCvar", ItemParse_showCvar, },
  4617. {"special", ItemParse_special, },
  4618. {"style", ItemParse_style, },
  4619. {"text", ItemParse_text },
  4620. // {"text2", ItemParse_text2 },
  4621. // {"text2alignx", ItemParse_text2alignx, },
  4622. // {"text2aligny", ItemParse_text2aligny, },
  4623. {"textalign", ItemParse_textalign, },
  4624. {"textalignx", ItemParse_textalignx, },
  4625. {"textaligny", ItemParse_textaligny, },
  4626. {"textscale", ItemParse_textscale, },
  4627. {"textstyle", ItemParse_textstyle, },
  4628. {"type", ItemParse_type, },
  4629. {"visible", ItemParse_visible, },
  4630. {"wrapped", ItemParse_wrapped, },
  4631. // {"invertyesno", ItemParse_invertyesno },
  4632. {"xoffset", ItemParse_xoffset },//for yes/no and multi
  4633. {"selectionshader", ItemParse_selectionShader },
  4634. // Text scroll specific
  4635. {"lineHeight", ItemParse_lineHeight, NULL },
  4636. {NULL, NULL, }
  4637. };
  4638. keywordHash_t *itemParseKeywordHash[KEYWORDHASH_SIZE];
  4639. /*
  4640. ===============
  4641. Item_SetupKeywordHash
  4642. ===============
  4643. */
  4644. void Item_SetupKeywordHash(void)
  4645. {
  4646. int i;
  4647. memset(itemParseKeywordHash, 0, sizeof(itemParseKeywordHash));
  4648. for (i = 0; itemParseKeywords[i].keyword; i++)
  4649. {
  4650. KeywordHash_Add(itemParseKeywordHash, &itemParseKeywords[i]);
  4651. }
  4652. }
  4653. /*
  4654. ===============
  4655. Item_Parse
  4656. ===============
  4657. */
  4658. qboolean Item_Parse(itemDef_t *item)
  4659. {
  4660. keywordHash_t *key;
  4661. const char *token;
  4662. // Brace is handled by MenuParse_ItemDef now, to handle wedge hackery
  4663. /*
  4664. if (PC_ParseString(&token))
  4665. {
  4666. return qfalse;
  4667. }
  4668. if (*token != '{')
  4669. {
  4670. return qfalse;
  4671. }
  4672. */
  4673. while ( 1 )
  4674. {
  4675. if (PC_ParseString(&token))
  4676. {
  4677. PC_ParseWarning("End of file inside menu item");
  4678. return qfalse;
  4679. }
  4680. if (*token == '}')
  4681. {
  4682. /* if (!item->window.name)
  4683. {
  4684. item->window.name = defaultString;
  4685. Com_Printf(S_COLOR_YELLOW"WARNING: Menu item has no name\n");
  4686. }
  4687. if (!item->window.group)
  4688. {
  4689. item->window.group = defaultString;
  4690. Com_Printf(S_COLOR_YELLOW"WARNING: Menu item has no group\n");
  4691. }
  4692. */
  4693. return qtrue;
  4694. }
  4695. key = (keywordHash_s *) KeywordHash_Find(itemParseKeywordHash, token);
  4696. if (!key)
  4697. {
  4698. PC_ParseWarning(va("Unknown item keyword '%s'", token));
  4699. continue;
  4700. }
  4701. if ( !key->func(item) )
  4702. {
  4703. PC_ParseWarning(va("Couldn't parse item keyword '%s'", token));
  4704. return qfalse;
  4705. }
  4706. }
  4707. }
  4708. static void Item_TextScroll_BuildLines ( itemDef_t* item )
  4709. {
  4710. // new asian-aware line breaker... (pasted from elsewhere late @ night, hence aliasing-vars ;-)
  4711. //
  4712. textScrollDef_t* scrollPtr = (textScrollDef_t*) item->typeData;
  4713. const char *psText = item->text; // for copy/paste ease
  4714. int iBoxWidth = item->window.rect.w - SCROLLBAR_SIZE - 10;
  4715. // this could probably be simplified now, but it was converted from something else I didn't originally write,
  4716. // and it works anyway so wtf...
  4717. //
  4718. const char *psCurrentTextReadPos;
  4719. const char *psReadPosAtLineStart;
  4720. const char *psBestLineBreakSrcPos;
  4721. const char *psLastGood_s; // needed if we get a full screen of chars with no punctuation or space (see usage notes)
  4722. qboolean bIsTrailingPunctuation;
  4723. unsigned int uiLetter;
  4724. if (!psText)
  4725. {
  4726. return;
  4727. }
  4728. if (*psText == '@') // string reference
  4729. {
  4730. // trap_SP_GetStringTextString( &psText[1], text, sizeof(text));
  4731. psText = SE_GetString( &psText[1] );
  4732. }
  4733. psCurrentTextReadPos = psText;
  4734. psReadPosAtLineStart = psCurrentTextReadPos;
  4735. psBestLineBreakSrcPos = psCurrentTextReadPos;
  4736. scrollPtr->iLineCount = 0;
  4737. memset((char*)scrollPtr->pLines,0,sizeof(scrollPtr->pLines));
  4738. while (*psCurrentTextReadPos && (scrollPtr->iLineCount < MAX_TEXTSCROLL_LINES) )
  4739. {
  4740. char sLineForDisplay[2048]; // ott
  4741. // construct a line...
  4742. //
  4743. psCurrentTextReadPos = psReadPosAtLineStart;
  4744. sLineForDisplay[0] = '\0';
  4745. while ( *psCurrentTextReadPos )
  4746. {
  4747. int iAdvanceCount;
  4748. psLastGood_s = psCurrentTextReadPos;
  4749. // read letter...
  4750. //
  4751. uiLetter = ui.AnyLanguage_ReadCharFromString(psCurrentTextReadPos, &iAdvanceCount, &bIsTrailingPunctuation);
  4752. psCurrentTextReadPos += iAdvanceCount;
  4753. // concat onto string so far...
  4754. //
  4755. if (uiLetter == 32 && sLineForDisplay[0] == '\0')
  4756. {
  4757. psReadPosAtLineStart++;
  4758. continue; // unless it's a space at the start of a line, in which case ignore it.
  4759. }
  4760. if (uiLetter > 255)
  4761. {
  4762. Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c%c",uiLetter >> 8, uiLetter & 0xFF));
  4763. }
  4764. else
  4765. {
  4766. Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c",uiLetter & 0xFF));
  4767. }
  4768. if (uiLetter == '\n')
  4769. {
  4770. // explicit new line...
  4771. //
  4772. sLineForDisplay[ strlen(sLineForDisplay)-1 ] = '\0'; // kill the CR
  4773. psReadPosAtLineStart = psCurrentTextReadPos;
  4774. psBestLineBreakSrcPos = psCurrentTextReadPos;
  4775. // hack it to fit in with this code...
  4776. //
  4777. scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc ( sLineForDisplay );
  4778. break; // print this line
  4779. }
  4780. else
  4781. if ( DC->textWidth( sLineForDisplay, item->textscale, item->font ) >= iBoxWidth )
  4782. {
  4783. // reached screen edge, so cap off string at bytepos after last good position...
  4784. //
  4785. if (uiLetter > 255 && bIsTrailingPunctuation && !ui.Language_UsesSpaces())
  4786. {
  4787. // Special case, don't consider line breaking if you're on an asian punctuation char of
  4788. // a language that doesn't use spaces...
  4789. //
  4790. uiLetter = uiLetter; // breakpoint line only
  4791. }
  4792. else
  4793. {
  4794. if (psBestLineBreakSrcPos == psReadPosAtLineStart)
  4795. {
  4796. // aarrrggh!!!!! we'll only get here is someone has fed in a (probably) garbage string,
  4797. // since it doesn't have a single space or punctuation mark right the way across one line
  4798. // of the screen. So far, this has only happened in testing when I hardwired a taiwanese
  4799. // string into this function while the game was running in english (which should NEVER happen
  4800. // normally). On the other hand I suppose it's entirely possible that some taiwanese string
  4801. // might have no punctuation at all, so...
  4802. //
  4803. psBestLineBreakSrcPos = psLastGood_s; // force a break after last good letter
  4804. }
  4805. sLineForDisplay[ psBestLineBreakSrcPos - psReadPosAtLineStart ] = '\0';
  4806. psReadPosAtLineStart = psCurrentTextReadPos = psBestLineBreakSrcPos;
  4807. // hack it to fit in with this code...
  4808. //
  4809. scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc( sLineForDisplay );
  4810. break; // print this line
  4811. }
  4812. }
  4813. // record last-good linebreak pos... (ie if we've just concat'd a punctuation point (western or asian) or space)
  4814. //
  4815. if (bIsTrailingPunctuation || uiLetter == ' ' || (uiLetter > 255 && !ui.Language_UsesSpaces()))
  4816. {
  4817. psBestLineBreakSrcPos = psCurrentTextReadPos;
  4818. }
  4819. }
  4820. /// arrgghh, this is gettng horrible now...
  4821. //
  4822. if (scrollPtr->pLines[ scrollPtr->iLineCount ] == NULL && strlen(sLineForDisplay))
  4823. {
  4824. // then this is the last line and we've just run out of text, no CR, no overflow etc...
  4825. //
  4826. scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc( sLineForDisplay );
  4827. }
  4828. scrollPtr->iLineCount++;
  4829. }
  4830. }
  4831. /*
  4832. ===============
  4833. Item_InitControls
  4834. init's special control types
  4835. ===============
  4836. */
  4837. void Item_InitControls(itemDef_t *item)
  4838. {
  4839. if (item == NULL)
  4840. {
  4841. return;
  4842. }
  4843. if (item->type == ITEM_TYPE_LISTBOX)
  4844. {
  4845. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  4846. item->cursorPos = 0;
  4847. if (listPtr)
  4848. {
  4849. listPtr->cursorPos = 0;
  4850. listPtr->startPos = 0;
  4851. listPtr->endPos = 0;
  4852. listPtr->cursorPos = 0;
  4853. }
  4854. }
  4855. }
  4856. /*
  4857. =================
  4858. Int_Parse
  4859. =================
  4860. */
  4861. qboolean Int_Parse(const char **p, int *i)
  4862. {
  4863. char *token;
  4864. token = COM_ParseExt(p, qfalse);
  4865. if (token && token[0] != 0)
  4866. {
  4867. *i = atoi(token);
  4868. return qtrue;
  4869. }
  4870. else
  4871. {
  4872. return qfalse;
  4873. }
  4874. }
  4875. /*
  4876. =================
  4877. String_Parse
  4878. =================
  4879. */
  4880. qboolean String_Parse(const char **p, const char **out)
  4881. {
  4882. char *token;
  4883. token = COM_ParseExt(p, qfalse);
  4884. if (token && token[0] != 0)
  4885. {
  4886. *(out) = String_Alloc(token);
  4887. return *(out)!=NULL;
  4888. }
  4889. return qfalse;
  4890. }
  4891. /*
  4892. ===============
  4893. Item_RunScript
  4894. ===============
  4895. */
  4896. void Item_RunScript(itemDef_t *item, const char *s)
  4897. {
  4898. const char *p;
  4899. int i;
  4900. qboolean bRan;
  4901. uiInfo.runScriptItem = item;
  4902. if (item && s && s[0])
  4903. {
  4904. p = s;
  4905. while (1)
  4906. {
  4907. const char *command;
  4908. // expect command then arguments, ; ends command, NULL ends script
  4909. if (!String_Parse(&p, &command))
  4910. {
  4911. return;
  4912. }
  4913. if (command[0] == ';' && command[1] == '\0')
  4914. {
  4915. continue;
  4916. }
  4917. bRan = qfalse;
  4918. for (i = 0; i < scriptCommandCount; i++)
  4919. {
  4920. if (Q_stricmp(command, commandList[i].name) == 0)
  4921. {
  4922. if ( !(commandList[i].handler(item, &p)) )
  4923. {
  4924. return;
  4925. }
  4926. bRan = qtrue;
  4927. break;
  4928. }
  4929. }
  4930. // not in our auto list, pass to handler
  4931. if (!bRan)
  4932. {
  4933. // Allow any script command to fail
  4934. if ( !DC->runScript(&p) )
  4935. {
  4936. break;
  4937. }
  4938. }
  4939. }
  4940. }
  4941. }
  4942. /*
  4943. ===============
  4944. Menu_SetupKeywordHash
  4945. ===============
  4946. */
  4947. void Menu_SetupKeywordHash(void)
  4948. {
  4949. int i;
  4950. memset(menuParseKeywordHash, 0, sizeof(menuParseKeywordHash));
  4951. for (i = 0; menuParseKeywords[i].keyword; i++)
  4952. {
  4953. KeywordHash_Add(menuParseKeywordHash, &menuParseKeywords[i]);
  4954. }
  4955. }
  4956. /*
  4957. ===============
  4958. Menus_ActivateByName
  4959. ===============
  4960. */
  4961. void Menu_HandleMouseMove(menuDef_t *menu, float x, float y);
  4962. menuDef_t *Menus_ActivateByName(const char *p)
  4963. {
  4964. int i;
  4965. menuDef_t *m = NULL;
  4966. menuDef_t *focus = Menu_GetFocused();
  4967. for (i = 0; i < menuCount; i++)
  4968. {
  4969. // Look for the name in the current list of windows
  4970. if (Q_stricmp(Menus[i].window.name, p) == 0)
  4971. {
  4972. m = &Menus[i];
  4973. Menus_Activate(m);
  4974. if (openMenuCount < MAX_OPEN_MENUS && focus != NULL)
  4975. {
  4976. menuStack[openMenuCount++] = focus;
  4977. }
  4978. }
  4979. else
  4980. {
  4981. Menus[i].window.flags &= ~WINDOW_HASFOCUS;
  4982. }
  4983. }
  4984. if (!m)
  4985. { // A hack so we don't have to load all three mission menus before we know what tier we're on
  4986. if (!Q_stricmp( p, "ingameMissionSelect1" ) )
  4987. {
  4988. UI_LoadMenus("ui/tier1.txt",qfalse);
  4989. Menus_CloseAll();
  4990. Menus_OpenByName("ingameMissionSelect1");
  4991. }
  4992. else if (!Q_stricmp( p, "ingameMissionSelect2" ) )
  4993. {
  4994. UI_LoadMenus("ui/tier2.txt",qfalse);
  4995. Menus_CloseAll();
  4996. Menus_OpenByName("ingameMissionSelect2");
  4997. }
  4998. else if (!Q_stricmp( p, "ingameMissionSelect3" ) )
  4999. {
  5000. UI_LoadMenus("ui/tier3.txt",qfalse);
  5001. Menus_CloseAll();
  5002. Menus_OpenByName("ingameMissionSelect3");
  5003. }
  5004. else
  5005. {
  5006. Com_Printf(S_COLOR_YELLOW"WARNING: Menus_ActivateByName: Unable to find menu '%s'\n",p);
  5007. }
  5008. }
  5009. // First time, show force select instructions
  5010. if (!Q_stricmp( p, "ingameForceSelect" ) )
  5011. {
  5012. int tier_storyinfo = Cvar_VariableIntegerValue( "tier_storyinfo" );
  5013. if (tier_storyinfo==1)
  5014. {
  5015. #ifndef _XBOX
  5016. Menus_OpenByName("ingameForceHelp");
  5017. #endif
  5018. }
  5019. }
  5020. // First time, show weapons select instructions
  5021. if (!Q_stricmp( p, "ingameWpnSelect" ) )
  5022. {
  5023. int tier_storyinfo = Cvar_VariableIntegerValue( "tier_storyinfo" );
  5024. if (tier_storyinfo==1)
  5025. {
  5026. #ifndef _XBOX
  5027. Menus_OpenByName("ingameWpnSelectHelp");
  5028. #endif
  5029. }
  5030. }
  5031. // Want to handle a mouse move on the new menu in case your already over an item
  5032. Menu_HandleMouseMove ( m, DC->cursorx, DC->cursory );
  5033. return m;
  5034. }
  5035. /*
  5036. ===============
  5037. Menus_Activate
  5038. ===============
  5039. */
  5040. void Menus_Activate(menuDef_t *menu)
  5041. {
  5042. menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
  5043. //JLFCALLOUT MPMOVED
  5044. #ifdef _XBOX
  5045. if (!(menu->window.flags & WINDOW_POPUP)&& menu->fullScreen )
  5046. {
  5047. DC->setCVar("ui_showWmove", "0");
  5048. DC->setCVar("ui_showXrls", "0");
  5049. DC->setCVar("ui_showXctrl", "0");
  5050. DC->setCVar("ui_showXNew", "0");
  5051. DC->setCVar("ui_showXforce", "0");
  5052. DC->setCVar("ui_showXdfrc", "0");
  5053. DC->setCVar("ui_showXcstm", "0");
  5054. DC->setCVar("ui_showXhost", "0");
  5055. DC->setCVar("ui_showXchk", "0");
  5056. DC->setCVar("ui_showYref", "0");
  5057. DC->setCVar("ui_showYdel", "0");
  5058. DC->setCVar("ui_showYsaber", "0");
  5059. DC->setCVar("ui_showYwpn", "0");
  5060. DC->setCVar("ui_showAcallout", "0");
  5061. DC->setCVar("ui_showBcallout", "0");
  5062. DC->setCVar("ui_cancelYScript", "0");
  5063. }
  5064. #endif
  5065. //JLF END
  5066. if (menu->onOpen)
  5067. {
  5068. itemDef_t item;
  5069. item.parent = menu;
  5070. item.window.flags = 0; //err, item is fake here, but we want a valid flag before calling runscript
  5071. Item_RunScript(&item, menu->onOpen);
  5072. if (item.window.flags & WINDOW_SCRIPTWAITING) //in case runscript set waiting, copy it up to the menu
  5073. {
  5074. menu->window.flags |= WINDOW_SCRIPTWAITING;
  5075. menu->window.delayedScript = item.window.delayedScript;
  5076. menu->window.delayTime = item.window.delayTime;
  5077. }
  5078. }
  5079. // menu->appearanceTime = DC->realTime + 1000;
  5080. menu->appearanceTime = 0;
  5081. menu->appearanceCnt = 0;
  5082. }
  5083. typedef struct {
  5084. char *command;
  5085. int id;
  5086. int defaultbind1;
  5087. int defaultbind2;
  5088. int bind1;
  5089. int bind2;
  5090. } bind_t;
  5091. static bind_t g_bindings[] =
  5092. {
  5093. {"invuse", A_ENTER, -1, -1, -1},
  5094. {"force_throw", A_F1, -1, -1, -1},
  5095. {"force_pull", A_F2, -1, -1, -1},
  5096. {"force_speed", A_F3, -1, -1, -1},
  5097. {"force_distract", A_F4, -1, -1, -1},
  5098. {"force_heal", A_F5, -1, -1, -1},
  5099. {"+force_grip", A_F6, -1, -1, -1},
  5100. {"+force_lightning",A_F7, -1, -1, -1},
  5101. //new powers
  5102. {"+force_drain", -1, -1, -1, -1},
  5103. {"force_rage", -1, -1, -1, -1},
  5104. {"force_protect", -1, -1, -1, -1},
  5105. {"force_absorb", -1, -1, -1, -1},
  5106. {"force_sight", -1, -1, -1, -1},
  5107. {"taunt", -1, -1, -1, -1},
  5108. {"+useforce", 'f', -1, -1, -1},
  5109. {"forceprev", 'z', -1, -1, -1},
  5110. {"forcenext", 'x', -1, -1, -1},
  5111. {"use_bacta", -1, -1, -1, -1},
  5112. {"use_seeker", -1, -1, -1, -1},
  5113. {"use_sentry", -1, -1, -1, -1},
  5114. {"use_lightamp_goggles",-1, -1, -1, -1},
  5115. {"use_electrobinoculars",-1, -1, -1, -1},
  5116. {"invnext", -1, -1, -1, -1},
  5117. {"invprev", -1, -1, -1, -1},
  5118. {"invuse", -1, -1, -1, -1},
  5119. {"+speed", A_SHIFT, -1, -1, -1},
  5120. {"+forward", A_CURSOR_UP, -1, -1, -1},
  5121. {"+back", A_CURSOR_DOWN, -1, -1, -1},
  5122. {"+moveleft", ',', -1, -1, -1},
  5123. {"+moveright", '.', -1, -1, -1},
  5124. {"+moveup", 'v', -1, -1, -1},
  5125. {"+movedown", 'c', -1, -1, -1},
  5126. {"+left", A_CURSOR_LEFT, -1, -1, -1},
  5127. {"+right", A_CURSOR_RIGHT, -1, -1, -1},
  5128. {"+strafe", -1, -1, -1, -1},
  5129. {"+lookup", A_PAGE_DOWN, -1, -1, -1},
  5130. {"+lookdown", A_DELETE, -1, -1, -1},
  5131. {"+mlook", '/', -1, -1, -1},
  5132. {"centerview", A_END, -1, -1, -1},
  5133. {"zoom", -1, -1, -1, -1},
  5134. {"weapon 0", -1, -1, -1, -1},
  5135. {"weapon 1", '1', -1, -1, -1},
  5136. {"weapon 2", '2', -1, -1, -1},
  5137. {"weapon 3", '3', -1, -1, -1},
  5138. {"weapon 4", '4', -1, -1, -1},
  5139. {"weapon 5", '5', -1, -1, -1},
  5140. {"weapon 6", '6', -1, -1, -1},
  5141. {"weapon 7", '7', -1, -1, -1},
  5142. {"weapon 8", '8', -1, -1, -1},
  5143. {"weapon 9", '9', -1, -1, -1},
  5144. {"weapon 10", '0', -1, -1, -1},
  5145. {"weapon 11", -1, -1, -1, -1},
  5146. {"weapon 12", -1, -1, -1, -1},
  5147. {"weapon 13", -1, -1, -1, -1},
  5148. {"+attack", A_CTRL, -1, -1, -1},
  5149. {"+altattack", A_ALT, -1, -1, -1},
  5150. {"weapprev", '[', -1, -1, -1},
  5151. {"weapnext", ']', -1, -1, -1},
  5152. {"+use", A_SPACE, -1, -1, -1},
  5153. {"datapad", A_TAB, -1, -1, -1},
  5154. {"save quick", A_F9, -1, -1, -1},
  5155. {"load quick", -1, -1, -1, -1},
  5156. {"load auto", -1, -1, -1, -1},
  5157. {"cg_thirdperson !",'p', -1, -1, -1},
  5158. {"exitview", -1, -1, -1, -1},
  5159. {"uimenu ingameloadmenu", A_F10, -1, -1, -1},
  5160. {"uimenu ingamesavemenu", A_F11, -1, -1, -1},
  5161. {"saberAttackCycle",-1, -1, -1, -1},
  5162. };
  5163. static const int g_bindCount = sizeof(g_bindings) / sizeof(bind_t);
  5164. /*
  5165. =================
  5166. Controls_GetKeyAssignment
  5167. =================
  5168. */
  5169. static void Controls_GetKeyAssignment (char *command, int *twokeys)
  5170. {
  5171. int count;
  5172. int j;
  5173. char b[256];
  5174. twokeys[0] = twokeys[1] = -1;
  5175. count = 0;
  5176. for ( j = 0; j < MAX_KEYS; j++ )
  5177. {
  5178. DC->getBindingBuf( j, b, 256 );
  5179. if ( *b == 0 )
  5180. {
  5181. continue;
  5182. }
  5183. if ( !Q_stricmp( b, command ) )
  5184. {
  5185. twokeys[count] = j;
  5186. count++;
  5187. if (count == 2)
  5188. {
  5189. break;
  5190. }
  5191. }
  5192. }
  5193. }
  5194. /*
  5195. =================
  5196. Controls_GetConfig
  5197. =================
  5198. */
  5199. void Controls_GetConfig( void )
  5200. {
  5201. int i;
  5202. int twokeys[2];
  5203. // iterate each command, get its numeric binding
  5204. for (i=0; i < g_bindCount; i++)
  5205. {
  5206. Controls_GetKeyAssignment(g_bindings[i].command, twokeys);
  5207. g_bindings[i].bind1 = twokeys[0];
  5208. g_bindings[i].bind2 = twokeys[1];
  5209. }
  5210. }
  5211. /*
  5212. ===============
  5213. Item_SetScreenCoords
  5214. ===============
  5215. */
  5216. void Item_SetScreenCoords(itemDef_t *item, float x, float y)
  5217. {
  5218. if (item == NULL)
  5219. {
  5220. return;
  5221. }
  5222. if (item->window.border != 0)
  5223. {
  5224. x += item->window.borderSize;
  5225. y += item->window.borderSize;
  5226. }
  5227. item->window.rect.x = x + item->window.rectClient.x;
  5228. item->window.rect.y = y + item->window.rectClient.y;
  5229. item->window.rect.w = item->window.rectClient.w;
  5230. item->window.rect.h = item->window.rectClient.h;
  5231. // force the text rects to recompute
  5232. item->textRect.w = 0;
  5233. item->textRect.h = 0;
  5234. switch ( item->type)
  5235. {
  5236. case ITEM_TYPE_TEXTSCROLL:
  5237. {
  5238. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  5239. if ( scrollPtr )
  5240. {
  5241. scrollPtr->startPos = 0;
  5242. scrollPtr->endPos = 0;
  5243. }
  5244. Item_TextScroll_BuildLines ( item );
  5245. break;
  5246. }
  5247. }
  5248. }
  5249. static void Menu_FreeGhoulItems(menuDef_t *menu)
  5250. {
  5251. int i,j;
  5252. for (i = 0; i < menu->itemCount; i++)
  5253. {
  5254. for (j=0; j < menu->items[i]->ghoul2.size(); j++)
  5255. {
  5256. if ( menu->items[i]->ghoul2[j].mModelindex >= 0)
  5257. {
  5258. DC->g2_RemoveGhoul2Model( menu->items[i]->ghoul2, j );
  5259. }
  5260. }
  5261. (menu->items[i]->ghoul2).clear(); //clear is the public Free so i can actually remove this slot
  5262. }
  5263. }
  5264. /*
  5265. ===============
  5266. Menu_Reset
  5267. ===============
  5268. */
  5269. void Menu_Reset(void)
  5270. {
  5271. //FIXME iterate menus to destoy G2 assets.
  5272. int i;
  5273. for (i = 0; i < menuCount; i++)
  5274. {
  5275. Menu_FreeGhoulItems( &Menus[i] );
  5276. }
  5277. menuCount = 0;
  5278. }
  5279. /*
  5280. ===============
  5281. Menu_UpdatePosition
  5282. ===============
  5283. */
  5284. void Menu_UpdatePosition(menuDef_t *menu)
  5285. {
  5286. int i;
  5287. float x, y;
  5288. if (menu == NULL)
  5289. {
  5290. return;
  5291. }
  5292. x = menu->window.rect.x;
  5293. y = menu->window.rect.y;
  5294. if (menu->window.border != 0)
  5295. {
  5296. x += menu->window.borderSize;
  5297. y += menu->window.borderSize;
  5298. }
  5299. for (i = 0; i < menu->itemCount; i++)
  5300. {
  5301. Item_SetScreenCoords(menu->items[i], x, y);
  5302. }
  5303. }
  5304. /*
  5305. ===============
  5306. Menu_PostParse
  5307. ===============
  5308. */
  5309. void Menu_PostParse(menuDef_t *menu)
  5310. {
  5311. if (menu == NULL)
  5312. {
  5313. return;
  5314. }
  5315. if (menu->fullScreen)
  5316. {
  5317. menu->window.rect.x = 0;
  5318. menu->window.rect.y = 0;
  5319. menu->window.rect.w = 640;
  5320. menu->window.rect.h = 480;
  5321. }
  5322. Menu_UpdatePosition(menu);
  5323. }
  5324. /*
  5325. ===============
  5326. Menu_Init
  5327. ===============
  5328. */
  5329. void Menu_Init(menuDef_t *menu)
  5330. {
  5331. memset(menu, 0, sizeof(menuDef_t));
  5332. menu->cursorItem = -1;
  5333. UI_Cursor_Show(qtrue);
  5334. if (DC)
  5335. {
  5336. menu->fadeAmount = DC->Assets.fadeAmount;
  5337. menu->fadeClamp = DC->Assets.fadeClamp;
  5338. menu->fadeCycle = DC->Assets.fadeCycle;
  5339. }
  5340. Window_Init(&menu->window);
  5341. }
  5342. /*
  5343. ===============
  5344. Menu_Parse
  5345. ===============
  5346. */
  5347. qboolean Menu_Parse(char *inbuffer, menuDef_t *menu)
  5348. {
  5349. // pc_token_t token;
  5350. keywordHash_t *key;
  5351. char *token2;
  5352. char * buffer;
  5353. bool nest= false;
  5354. buffer = inbuffer;
  5355. #ifdef _XBOX
  5356. char * includeBuffer;
  5357. #endif
  5358. token2 = PC_ParseExt();
  5359. if (!token2)
  5360. {
  5361. return qfalse;
  5362. }
  5363. if (*token2 != '{')
  5364. {
  5365. PC_ParseWarning("Misplaced {");
  5366. return qfalse;
  5367. }
  5368. while ( 1 )
  5369. {
  5370. token2 = PC_ParseExt();
  5371. if (!token2)
  5372. {
  5373. PC_ParseWarning("End of file inside menu.");
  5374. return qfalse;
  5375. }
  5376. if (*token2 == '}')
  5377. {
  5378. return qtrue;
  5379. }
  5380. #ifdef _XBOX
  5381. //JLFCALLOUT
  5382. char * UI_ParseInclude(const char *menuFile, menuDef_t * menu);
  5383. if (!strcmp (token2, "#include"))
  5384. {
  5385. token2 = PC_ParseExt();
  5386. includeBuffer = UI_ParseInclude(token2, menu );
  5387. //bufferize thetoken2
  5388. nest = true;
  5389. buffer = includeBuffer;
  5390. continue;
  5391. }
  5392. #endif
  5393. if (nest && (*token2 == 0))
  5394. {
  5395. PC_EndParseSession(buffer);
  5396. nest = false;
  5397. continue;
  5398. }
  5399. key = KeywordHash_Find(menuParseKeywordHash, token2);
  5400. if (!key)
  5401. {
  5402. PC_ParseWarning(va("Unknown menu keyword %s",token2));
  5403. continue;
  5404. }
  5405. if ( !key->func((itemDef_t*)menu) )
  5406. {
  5407. PC_ParseWarning(va("Couldn't parse menu keyword %s as %s",token2, key->keyword));
  5408. return qfalse;
  5409. }
  5410. }
  5411. }
  5412. /*
  5413. ===============
  5414. Menu_New
  5415. ===============
  5416. */
  5417. void Menu_New(char *buffer)
  5418. {
  5419. menuDef_t *menu = &Menus[menuCount];
  5420. if (menuCount < MAX_MENUS)
  5421. {
  5422. Menu_Init(menu);
  5423. if (Menu_Parse(buffer, menu))
  5424. {
  5425. Menu_PostParse(menu);
  5426. menuCount++;
  5427. }
  5428. }
  5429. }
  5430. /*
  5431. ===============
  5432. Menus_CloseAll
  5433. ===============
  5434. */
  5435. void Menus_CloseAll(void)
  5436. {
  5437. int i;
  5438. for (i = 0; i < menuCount; i++)
  5439. {
  5440. Menu_RunCloseScript ( &Menus[i] );
  5441. Menus[i].window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
  5442. }
  5443. // Clear the menu stack
  5444. openMenuCount = 0;
  5445. }
  5446. /*
  5447. ===============
  5448. PC_StartParseSession
  5449. ===============
  5450. */
  5451. #ifdef _XBOX
  5452. int PC_StartParseSession(const char *fileName,char **buffer, bool nested)
  5453. #else
  5454. int PC_StartParseSession(const char *fileName,char **buffer)
  5455. #endif
  5456. {
  5457. int len;
  5458. // Try to open file and read it in.
  5459. len = ui.FS_ReadFile( fileName,(void **) buffer );
  5460. // Not there?
  5461. if ( len>0 )
  5462. {
  5463. #ifdef _XBOX
  5464. if (nested)
  5465. parseDataCount = 1;
  5466. else
  5467. #endif
  5468. parseDataCount = 0;
  5469. strncpy(parseData[parseDataCount].fileName, fileName, MAX_QPATH);
  5470. parseData[parseDataCount].bufferStart = *buffer;
  5471. parseData[parseDataCount].bufferCurrent = *buffer;
  5472. #ifdef _XBOX
  5473. COM_BeginParseSession(nested);
  5474. #else
  5475. COM_BeginParseSession();
  5476. #endif
  5477. }
  5478. return len;
  5479. }
  5480. /*
  5481. ===============
  5482. PC_EndParseSession
  5483. ===============
  5484. */
  5485. void PC_EndParseSession(char *buffer)
  5486. {
  5487. parseDataCount--;
  5488. ui.FS_FreeFile( buffer ); //let go of the buffer
  5489. }
  5490. /*
  5491. ===============
  5492. PC_ParseWarning
  5493. ===============
  5494. */
  5495. void PC_ParseWarning(const char *message)
  5496. {
  5497. ui.Printf(S_COLOR_YELLOW "WARNING: %s Line #%d of File '%s'\n", message,parseData[parseDataCount].com_lines,parseData[parseDataCount].fileName);
  5498. }
  5499. char *PC_ParseExt(void)
  5500. {
  5501. return (COM_ParseExt(&parseData[parseDataCount].bufferCurrent, qtrue));
  5502. }
  5503. qboolean PC_ParseString(const char **string)
  5504. {
  5505. int hold;
  5506. hold = COM_ParseString(&parseData[parseDataCount].bufferCurrent,string);
  5507. while (hold==0 && **string == 0)
  5508. {
  5509. hold = COM_ParseString(&parseData[parseDataCount].bufferCurrent,string);
  5510. }
  5511. return(hold);
  5512. }
  5513. qboolean PC_ParseInt(int *number)
  5514. {
  5515. return(COM_ParseInt(&parseData[parseDataCount].bufferCurrent,number));
  5516. }
  5517. qboolean PC_ParseFloat(float *number)
  5518. {
  5519. return(COM_ParseFloat(&parseData[parseDataCount].bufferCurrent,number));
  5520. }
  5521. qboolean PC_ParseColor(vec4_t *color)
  5522. {
  5523. return(COM_ParseVec4(&parseData[parseDataCount].bufferCurrent, color));
  5524. }
  5525. void PC_SkipBracedSection( void )
  5526. {
  5527. SkipBracedSection( &parseData[parseDataCount].bufferCurrent );
  5528. }
  5529. /*
  5530. =================
  5531. Menu_Count
  5532. =================
  5533. */
  5534. int Menu_Count(void)
  5535. {
  5536. return menuCount;
  5537. }
  5538. /*
  5539. =================
  5540. Menu_PaintAll
  5541. =================
  5542. */
  5543. void Menu_PaintAll(void)
  5544. {
  5545. int i;
  5546. if (captureFunc)
  5547. {
  5548. captureFunc(captureData);
  5549. }
  5550. for (i = 0; i < menuCount; i++)
  5551. {
  5552. if (!(Menus[i].window.flags & WINDOW_POPUP || !Menus[i].fullScreen))
  5553. Menu_Paint(&Menus[i], qfalse);
  5554. }
  5555. for (i = 0; i < menuCount; i++)
  5556. {
  5557. if ((Menus[i].window.flags & WINDOW_POPUP || !Menus[i].fullScreen))
  5558. Menu_Paint(&Menus[i], qfalse);
  5559. }
  5560. if (uis.debugMode)
  5561. {
  5562. vec4_t v = {1, 1, 1, 1};
  5563. DC->drawText(5, 25, .75, v, va("(%d,%d)",DC->cursorx,DC->cursory), 0, 0, DC->Assets.qhMediumFont);
  5564. DC->drawText(5, 10, .75, v, va("fps: %f", DC->FPS), 0, 0, DC->Assets.qhMediumFont);
  5565. }
  5566. }
  5567. /*
  5568. =================
  5569. Menu_Paint
  5570. =================
  5571. */
  5572. void Menu_Paint(menuDef_t *menu, qboolean forcePaint)
  5573. {
  5574. int i;
  5575. if (menu == NULL)
  5576. {
  5577. return;
  5578. }
  5579. if (menu->window.flags & WINDOW_SCRIPTWAITING)
  5580. {
  5581. if (DC->realTime > menu->window.delayTime)
  5582. { // Time has elapsed, resume running whatever script we saved
  5583. itemDef_t item;
  5584. item.parent = menu;
  5585. item.window.flags = 0; //clear before calling RunScript
  5586. menu->window.flags &= ~WINDOW_SCRIPTWAITING;
  5587. Item_RunScript(&item, menu->window.delayedScript);
  5588. // Could have hit another delay. Need to hoist from fake item
  5589. if (item.window.flags & WINDOW_SCRIPTWAITING)
  5590. {
  5591. menu->window.flags |= WINDOW_SCRIPTWAITING;
  5592. menu->window.delayedScript = item.window.delayedScript;
  5593. menu->window.delayTime = item.window.delayTime;
  5594. }
  5595. }
  5596. }
  5597. if (!(menu->window.flags & WINDOW_VISIBLE) && !forcePaint)
  5598. {
  5599. return;
  5600. }
  5601. // if (menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible(menu->window.ownerDrawFlags))
  5602. // {
  5603. // return;
  5604. // }
  5605. if (forcePaint)
  5606. {
  5607. menu->window.flags |= WINDOW_FORCED;
  5608. }
  5609. // draw the background if necessary
  5610. if (menu->fullScreen)
  5611. {
  5612. vec4_t color;
  5613. color[0] = menu->window.backColor[0];
  5614. color[1] = menu->window.backColor[1];
  5615. color[2] = menu->window.backColor[2];
  5616. color[3] = menu->window.backColor[3];
  5617. ui.R_SetColor( color);
  5618. if (menu->window.background==0) // No background shader given? Make it blank
  5619. {
  5620. menu->window.background = uis.whiteShader;
  5621. }
  5622. DC->drawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, menu->window.background );
  5623. }
  5624. else if (menu->window.background)
  5625. {
  5626. // this allows a background shader without being full screen
  5627. //UI_DrawHandlePic(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, menu->backgroundShader);
  5628. }
  5629. // paint the background and or border
  5630. Window_Paint(&menu->window, menu->fadeAmount, menu->fadeClamp, menu->fadeCycle );
  5631. // Loop through all items for the menu and paint them
  5632. int iSlotsVisible = 0;
  5633. for (i = 0; i < menu->itemCount; i++)
  5634. {
  5635. // if (!menu->items[i]->appearanceSlot)
  5636. // {
  5637. Item_Paint(menu->items[i], qtrue);
  5638. // }
  5639. // else // Timed order of appearance
  5640. // {
  5641. // if (Item_Paint(menu->items[i], qfalse) )
  5642. // {
  5643. // iSlotsVisible++; //It would paint
  5644. // }
  5645. // if (menu->items[i]->appearanceSlot<=menu->appearanceCnt)
  5646. // {
  5647. // Item_Paint(menu->items[i], qtrue);
  5648. // }
  5649. // }
  5650. #ifdef _XBOX
  5651. //JLFCALLOUT
  5652. // if ( menu->items[i]->window.flags & WINDOW_HASFOCUS)
  5653. // {
  5654. // if ( menu->items[i]->type == ITEM_TYPE_BUTTON || menu->onAccept)
  5655. // {
  5656. // }
  5657. // }
  5658. #endif
  5659. }
  5660. if (iSlotsVisible && menu->appearanceTime < DC->realTime && menu->appearanceCnt < menu->itemCount) // Time to show another item
  5661. {
  5662. menu->appearanceTime = DC->realTime + menu->appearanceIncrement;
  5663. menu->appearanceCnt++;
  5664. }
  5665. if (uis.debugMode)
  5666. {
  5667. vec4_t color;
  5668. color[0] = color[2] = color[3] = 1;
  5669. color[1] = 0;
  5670. DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, color);
  5671. }
  5672. }
  5673. /*
  5674. =================
  5675. Item_EnableShowViaCvar
  5676. =================
  5677. */
  5678. qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag)
  5679. {
  5680. if (item && item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest)
  5681. {
  5682. char script[1024];
  5683. const char *p;
  5684. char buff[1024];
  5685. if (item->cvarFlags & CVAR_SUBSTRING)
  5686. {
  5687. const char *val;
  5688. p = item->enableCvar;
  5689. if (!String_Parse(&p, &val))
  5690. {//strip the quotes off
  5691. return (item->cvarFlags & flag) ? qfalse : qtrue;
  5692. }
  5693. Q_strncpyz(buff, val, sizeof(buff), qtrue);
  5694. DC->getCVarString(item->cvarTest, script, sizeof(script));
  5695. p = script;
  5696. }
  5697. else
  5698. {
  5699. DC->getCVarString(item->cvarTest, buff, sizeof(buff));
  5700. Q_strncpyz(script, item->enableCvar, sizeof(script), qtrue);
  5701. p = script;
  5702. }
  5703. while (1)
  5704. {
  5705. const char *val;
  5706. // expect value then ; or NULL, NULL ends list
  5707. if (!String_Parse(&p, &val))
  5708. {
  5709. return (item->cvarFlags & flag) ? qfalse : qtrue;
  5710. }
  5711. if (val[0] == ';' && val[1] == '\0')
  5712. {
  5713. continue;
  5714. }
  5715. // enable it if any of the values are true
  5716. if (item->cvarFlags & flag)
  5717. {
  5718. if (Q_stricmp(buff, val) == 0)
  5719. {
  5720. return qtrue;
  5721. }
  5722. }
  5723. else
  5724. {
  5725. // disable it if any of the values are true
  5726. if (Q_stricmp(buff, val) == 0)
  5727. {
  5728. return qfalse;
  5729. }
  5730. }
  5731. }
  5732. return (item->cvarFlags & flag) ? qfalse : qtrue;
  5733. }
  5734. return qtrue;
  5735. }
  5736. /*
  5737. =================
  5738. Item_SetTextExtents
  5739. =================
  5740. */
  5741. void Item_SetTextExtents(itemDef_t *item, int *width, int *height, const char *text)
  5742. {
  5743. const char *textPtr = (text) ? text : item->text;
  5744. if (textPtr == NULL )
  5745. {
  5746. return;
  5747. }
  5748. *width = item->textRect.w;
  5749. *height = item->textRect.h;
  5750. // keeps us from computing the widths and heights more than once
  5751. if (*width == 0 || (item->type == ITEM_TYPE_OWNERDRAW && item->textalignment == ITEM_ALIGN_CENTER)
  5752. || (item->text && item->text[0]=='@' && item->asset != se_language->modificationCount ) //string package language changed
  5753. )
  5754. {
  5755. int originalWidth;
  5756. originalWidth = DC->textWidth(textPtr, item->textscale, item->font);
  5757. if (item->type == ITEM_TYPE_OWNERDRAW && (item->textalignment == ITEM_ALIGN_CENTER || item->textalignment == ITEM_ALIGN_RIGHT))
  5758. {
  5759. originalWidth += DC->ownerDrawWidth(item->window.ownerDraw, item->textscale);
  5760. }
  5761. else if (item->type == ITEM_TYPE_EDITFIELD && item->textalignment == ITEM_ALIGN_CENTER && item->cvar)
  5762. {
  5763. char buff[256];
  5764. DC->getCVarString(item->cvar, buff, 256);
  5765. originalWidth += DC->textWidth(buff, item->textscale, item->font);
  5766. }
  5767. *width = DC->textWidth(textPtr, item->textscale, item->font);
  5768. *height = DC->textHeight(textPtr, item->textscale, item->font);
  5769. item->textRect.w = *width;
  5770. item->textRect.h = *height;
  5771. item->textRect.x = item->textalignx;
  5772. item->textRect.y = item->textaligny;
  5773. if (item->textalignment == ITEM_ALIGN_RIGHT)
  5774. {
  5775. item->textRect.x = item->textalignx - originalWidth;
  5776. }
  5777. else if (item->textalignment == ITEM_ALIGN_CENTER)
  5778. {
  5779. item->textRect.x = item->textalignx - originalWidth / 2;
  5780. }
  5781. ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
  5782. if (item->text && item->text[0]=='@' )//string package
  5783. {//mark language
  5784. item->asset = se_language->modificationCount;
  5785. }
  5786. }
  5787. }
  5788. /*
  5789. =================
  5790. Item_TextColor
  5791. =================
  5792. */
  5793. void Item_TextColor(itemDef_t *item, vec4_t *newColor)
  5794. {
  5795. vec4_t lowLight;
  5796. const vec4_t greyColor = { .5, .5, .5, 1};
  5797. menuDef_t *parent = (menuDef_t*)item->parent;
  5798. Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
  5799. if ( !(item->type == ITEM_TYPE_TEXT && item->window.flags & WINDOW_AUTOWRAPPED) && item->window.flags & WINDOW_HASFOCUS)
  5800. {
  5801. memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
  5802. /*
  5803. lowLight[0] = 0.8 * parent->focusColor[0];
  5804. lowLight[1] = 0.8 * parent->focusColor[1];
  5805. lowLight[2] = 0.8 * parent->focusColor[2];
  5806. lowLight[3] = 0.8 * parent->focusColor[3];
  5807. LerpColor(parent->focusColor,lowLight,*newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  5808. */
  5809. }
  5810. #ifdef _XBOX
  5811. else if (item->textStyle == ITEM_TEXTSTYLE_BLINK )
  5812. {
  5813. lowLight[0] = 0.8 * item->window.foreColor[0];
  5814. lowLight[1] = 0.8 * item->window.foreColor[1];
  5815. lowLight[2] = 0.8 * item->window.foreColor[2];
  5816. lowLight[3] = 0.8 * item->window.foreColor[3];
  5817. LerpColor(parent->focusColor,lowLight,*newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  5818. }
  5819. #endif//_XBOX
  5820. else
  5821. {
  5822. memcpy(newColor, &item->window.foreColor, sizeof(vec4_t));
  5823. }
  5824. // items can be enabled and disabled based on cvars
  5825. if (item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest)
  5826. {
  5827. if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
  5828. {
  5829. memcpy(newColor, &parent->disableColor, sizeof(vec4_t));
  5830. }
  5831. }
  5832. if (item->window.flags & WINDOW_INACTIVE)
  5833. {
  5834. memcpy(newColor, &greyColor, sizeof(vec4_t));
  5835. }
  5836. }
  5837. /*
  5838. =================
  5839. Item_Text_Wrapped_Paint
  5840. =================
  5841. */
  5842. void Item_Text_Wrapped_Paint(itemDef_t *item)
  5843. {
  5844. char text[1024];
  5845. const char *p, *start, *textPtr;
  5846. char buff[1024];
  5847. int width, height;
  5848. float x, y;
  5849. vec4_t color;
  5850. // now paint the text and/or any optional images
  5851. // default to left
  5852. if (item->text == NULL)
  5853. {
  5854. if (item->cvar == NULL)
  5855. {
  5856. return;
  5857. }
  5858. else
  5859. {
  5860. DC->getCVarString(item->cvar, text, sizeof(text));
  5861. textPtr = text;
  5862. }
  5863. }
  5864. else
  5865. {
  5866. textPtr = item->text;
  5867. }
  5868. if (*textPtr == '@') // string reference
  5869. {
  5870. textPtr = SE_GetString( &textPtr[1] );
  5871. }
  5872. if (*textPtr == '\0')
  5873. {
  5874. return;
  5875. }
  5876. Item_TextColor(item, &color);
  5877. Item_SetTextExtents(item, &width, &height, textPtr);
  5878. x = item->textRect.x;
  5879. y = item->textRect.y;
  5880. start = textPtr;
  5881. p = strchr(textPtr, '\r');
  5882. while (p && *p)
  5883. {
  5884. strncpy(buff, start, p-start+1);
  5885. buff[p-start] = '\0';
  5886. DC->drawText(x, y, item->textscale, color, buff, 0, item->textStyle, item->font);
  5887. y += height + 5;
  5888. start += p - start + 1;
  5889. p = strchr(p+1, '\r');
  5890. }
  5891. DC->drawText(x, y, item->textscale, color, start, 0, item->textStyle, item->font);
  5892. }
  5893. /*
  5894. =================
  5895. Menu_Paint
  5896. =================
  5897. */
  5898. void Item_Text_Paint(itemDef_t *item)
  5899. {
  5900. char text[1024];
  5901. const char *textPtr;
  5902. int height, width;
  5903. vec4_t color;
  5904. if (item->window.flags & WINDOW_WRAPPED)
  5905. {
  5906. Item_Text_Wrapped_Paint(item);
  5907. return;
  5908. }
  5909. if (item->window.flags & WINDOW_AUTOWRAPPED)
  5910. {
  5911. Item_Text_AutoWrapped_Paint(item);
  5912. return;
  5913. }
  5914. if (item->text == NULL)
  5915. {
  5916. if (item->cvar == NULL)
  5917. {
  5918. return;
  5919. }
  5920. else
  5921. {
  5922. DC->getCVarString(item->cvar, text, sizeof(text));
  5923. textPtr = text;
  5924. }
  5925. }
  5926. else
  5927. {
  5928. textPtr = item->text;
  5929. }
  5930. if (*textPtr == '@') // string reference
  5931. {
  5932. textPtr = SE_GetString( &textPtr[1] );
  5933. }
  5934. // this needs to go here as it sets extents for cvar types as well
  5935. Item_SetTextExtents(item, &width, &height, textPtr);
  5936. if (*textPtr == '\0')
  5937. {
  5938. return;
  5939. }
  5940. Item_TextColor(item, &color);
  5941. DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, item->textStyle, item->font);
  5942. /*
  5943. if (item->text2) // Is there a second line of text?
  5944. {
  5945. textPtr = item->text2;
  5946. if (*textPtr == '@') // string reference
  5947. {
  5948. textPtr = SE_GetString( &textPtr[1] );
  5949. }
  5950. Item_TextColor(item, &color);
  5951. DC->drawText(item->textRect.x + item->text2alignx, item->textRect.y + item->text2aligny, item->textscale, color, textPtr, 0, item->textStyle, item->font);
  5952. }
  5953. */
  5954. }
  5955. /*
  5956. =================
  5957. Item_UpdatePosition
  5958. =================
  5959. */
  5960. // FIXME: consolidate this with nearby stuff
  5961. void Item_UpdatePosition(itemDef_t *item)
  5962. {
  5963. float x, y;
  5964. menuDef_t *menu;
  5965. if (item == NULL || item->parent == NULL)
  5966. {
  5967. return;
  5968. }
  5969. menu = (menuDef_t *) item->parent;
  5970. x = menu->window.rect.x;
  5971. y = menu->window.rect.y;
  5972. if (menu->window.border != 0)
  5973. {
  5974. x += menu->window.borderSize;
  5975. y += menu->window.borderSize;
  5976. }
  5977. Item_SetScreenCoords(item, x, y);
  5978. }
  5979. /*
  5980. =================
  5981. Item_TextField_Paint
  5982. =================
  5983. */
  5984. void Item_TextField_Paint(itemDef_t *item)
  5985. {
  5986. char buff[1024];
  5987. vec4_t newColor, lowLight;
  5988. int offset;
  5989. menuDef_t *parent = (menuDef_t*)item->parent;
  5990. editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
  5991. Item_Text_Paint(item);
  5992. buff[0] = '\0';
  5993. if (item->cvar)
  5994. {
  5995. DC->getCVarString(item->cvar, buff, sizeof(buff));
  5996. }
  5997. parent = (menuDef_t*)item->parent;
  5998. if (item->window.flags & WINDOW_HASFOCUS)
  5999. {
  6000. lowLight[0] = 0.8 * parent->focusColor[0];
  6001. lowLight[1] = 0.8 * parent->focusColor[1];
  6002. lowLight[2] = 0.8 * parent->focusColor[2];
  6003. lowLight[3] = 0.8 * parent->focusColor[3];
  6004. LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  6005. }
  6006. else
  6007. {
  6008. memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
  6009. }
  6010. offset = 8;//(item->text && *item->text) ? 8 : 0;
  6011. if (item->window.flags & WINDOW_HASFOCUS && g_editingField)
  6012. {
  6013. char cursor = DC->getOverstrikeMode() ? '_' : '|';
  6014. DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset , cursor, /*editPtr->maxPaintChars*/ item->window.rect.w, item->textStyle, item->font);
  6015. }
  6016. else
  6017. {
  6018. DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, /*editPtr->maxPaintChars*/ item->window.rect.w, item->textStyle, item->font);
  6019. }
  6020. }
  6021. void Item_TextScroll_Paint(itemDef_t *item)
  6022. {
  6023. char cvartext[1024];
  6024. float x, y, size, count;
  6025. int i;
  6026. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  6027. size = item->window.rect.h - 2;
  6028. // Re-arranged this function. Previous version had a plethora of bugs.
  6029. // Still a little iffy - BTO (VV)
  6030. if (item->cvar)
  6031. {
  6032. DC->getCVarString(item->cvar, cvartext, sizeof(cvartext));
  6033. item->text = cvartext;
  6034. }
  6035. Item_TextScroll_BuildLines ( item );
  6036. count = scrollPtr->iLineCount;
  6037. // Just fix position - no scrolbar
  6038. scrollPtr->endPos = scrollPtr->startPos;
  6039. // adjust size for item painting
  6040. size = item->window.rect.h - 2;
  6041. x = item->window.rect.x + item->textalignx + 1;
  6042. y = item->window.rect.y + item->textaligny + 1;
  6043. for (i = scrollPtr->startPos; i < count; i++)
  6044. {
  6045. const char *text;
  6046. text = scrollPtr->pLines[i];
  6047. if (!text)
  6048. {
  6049. continue;
  6050. }
  6051. DC->drawText(x + 4, y, item->textscale, item->window.foreColor, text, 0, item->textStyle, item->font);
  6052. size -= scrollPtr->lineHeight;
  6053. if (size < scrollPtr->lineHeight)
  6054. {
  6055. scrollPtr->drawPadding = scrollPtr->lineHeight - size;
  6056. break;
  6057. }
  6058. scrollPtr->endPos++;
  6059. y += scrollPtr->lineHeight;
  6060. }
  6061. }
  6062. /*
  6063. =================
  6064. Item_ListBox_Paint
  6065. =================
  6066. */
  6067. #define COLOR_MAX 255.0f
  6068. void Item_ListBox_Paint(itemDef_t *item)
  6069. {
  6070. float x, y, size;
  6071. int count, i, thumb;
  6072. qhandle_t image;
  6073. qhandle_t optionalImage;
  6074. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6075. //JLF MPMOVED
  6076. int numlines;
  6077. int startPos;
  6078. int i2;
  6079. float sizeWidth, sizeHeight;
  6080. // the listbox is horizontal or vertical and has a fixed size scroll bar going either direction
  6081. // elements are enumerated from the DC and either text or image handles are acquired from the DC as well
  6082. // textscale is used to size the text, textalignx and textaligny are used to size image elements
  6083. // there is no clipping available so only the last completely visible item is painted
  6084. count = DC->feederCount(item->special);
  6085. if (count ==0)
  6086. return;
  6087. //JLFLISTBOX MPMOVED
  6088. #ifdef _XBOX
  6089. if (listPtr->notselectable)
  6090. listPtr->startPos = listPtr->cursorPos;//item->cursorPos;
  6091. // item->cursorPos = listPtr->startPos;
  6092. #endif
  6093. //JLFLISTBOX
  6094. if (listPtr->startPos > (count?count-1:count))
  6095. {//probably changed feeders, so reset
  6096. listPtr->startPos = 0;
  6097. }
  6098. if (item->cursorPos > (count?count-1:count))
  6099. {//probably changed feeders, so reset
  6100. item->cursorPos = 0;
  6101. }
  6102. // default is vertical if horizontal flag is not here
  6103. if (item->window.flags & WINDOW_HORIZONTAL)
  6104. {
  6105. //JLF new variable (code just indented)
  6106. if (!listPtr->scrollhidden)
  6107. {
  6108. // draw scrollbar in bottom of the window
  6109. // bar
  6110. if (Item_ListBox_MaxScroll(item) > 0)
  6111. {
  6112. x = item->window.rect.x + 1;
  6113. y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1;
  6114. DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft);
  6115. x += SCROLLBAR_SIZE - 1;
  6116. size = item->window.rect.w - (SCROLLBAR_SIZE * 2);
  6117. DC->drawHandlePic(x, y, size+1, SCROLLBAR_SIZE, DC->Assets.scrollBar);
  6118. x += size - 1;
  6119. DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight);
  6120. // thumb
  6121. thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item);
  6122. if (thumb > x - SCROLLBAR_SIZE - 1)
  6123. {
  6124. thumb = x - SCROLLBAR_SIZE - 1;
  6125. }
  6126. DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
  6127. }
  6128. else if (listPtr->startPos > 0)
  6129. {
  6130. listPtr->startPos = 0;
  6131. }
  6132. }
  6133. //JLF end
  6134. //
  6135. listPtr->endPos = listPtr->startPos;
  6136. size = item->window.rect.w - 2;
  6137. // items
  6138. // size contains max available space
  6139. if (listPtr->elementStyle == LISTBOX_IMAGE)
  6140. {
  6141. // fit = 0;
  6142. x = item->window.rect.x + 1;
  6143. y = item->window.rect.y + 1;
  6144. for (i = listPtr->startPos; i < count; i++)
  6145. {
  6146. // always draw at least one
  6147. // which may overdraw the box if it is too small for the element
  6148. image = DC->feederItemImage(item->special, i);
  6149. if (image)
  6150. {
  6151. if (item->window.flags & WINDOW_PLAYERCOLOR)
  6152. {
  6153. vec4_t color;
  6154. color[0] = ui_char_color_red.integer/255.0f;
  6155. color[1] = ui_char_color_green.integer/255.0f;
  6156. color[2] = ui_char_color_blue.integer/255.0f;
  6157. color[3] = 1;
  6158. ui.R_SetColor(color);
  6159. }
  6160. DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
  6161. }
  6162. if (i == item->cursorPos)
  6163. {
  6164. DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor);
  6165. }
  6166. size -= listPtr->elementWidth;
  6167. if (size < listPtr->elementWidth)
  6168. {
  6169. listPtr->drawPadding = size; //listPtr->elementWidth - size;
  6170. break;
  6171. }
  6172. x += listPtr->elementWidth;
  6173. listPtr->endPos++;
  6174. // fit++;
  6175. }
  6176. }
  6177. else
  6178. {
  6179. //
  6180. }
  6181. }
  6182. else //VERTICAL
  6183. {
  6184. //JLF MPMOVED
  6185. numlines = item->window.rect.h / listPtr->elementHeight;
  6186. if (listPtr->endPos +1 >= count)
  6187. {
  6188. //Cvar_Set("ui_downArrow","0");
  6189. }
  6190. else
  6191. {
  6192. //Cvar_Set("ui_downArrow","1");
  6193. }
  6194. if (listPtr->startPos <= 0)
  6195. {
  6196. //Cvar_Set("ui_upArrow","0");
  6197. }
  6198. else
  6199. {
  6200. //Cvar_Set("ui_upArrow","1");
  6201. }
  6202. //JLFEND
  6203. //JLF new variable (code idented with if)
  6204. if (!listPtr->scrollhidden)
  6205. {
  6206. // draw scrollbar to right side of the window
  6207. x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1;
  6208. y = item->window.rect.y + 1;
  6209. DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp);
  6210. y += SCROLLBAR_SIZE - 1;
  6211. listPtr->endPos = listPtr->startPos;
  6212. size = item->window.rect.h - (SCROLLBAR_SIZE * 2);
  6213. DC->drawHandlePic(x, y, SCROLLBAR_SIZE, size+1, DC->Assets.scrollBar);
  6214. y += size - 1;
  6215. DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown);
  6216. // thumb
  6217. thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item);
  6218. if (thumb > y - SCROLLBAR_SIZE - 1)
  6219. {
  6220. thumb = y - SCROLLBAR_SIZE - 1;
  6221. }
  6222. DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
  6223. }
  6224. listPtr->endPos = listPtr->startPos;
  6225. //JLF end
  6226. // adjust size for item painting
  6227. size = item->window.rect.h - 2;
  6228. sizeWidth = item->window.rect.w - 2;
  6229. sizeHeight = item->window.rect.h - 2;
  6230. if (listPtr->elementStyle == LISTBOX_IMAGE)
  6231. {
  6232. // Multiple rows and columns (since it's more than twice as wide as an element)
  6233. if ( item->window.rect.w > (listPtr->elementWidth*2) )
  6234. {
  6235. startPos = listPtr->startPos;
  6236. x = item->window.rect.x + 1;
  6237. y = item->window.rect.y + 1;
  6238. // Next row
  6239. for (i2 = startPos; i2 < count; i2++)
  6240. {
  6241. x = item->window.rect.x + 1;
  6242. sizeWidth = item->window.rect.w - 2;
  6243. // print a row
  6244. for (i = startPos; i < count; i++)
  6245. {
  6246. // always draw at least one
  6247. // which may overdraw the box if it is too small for the element
  6248. image = DC->feederItemImage(item->special, i);
  6249. if (image)
  6250. {
  6251. #ifndef CGAME
  6252. if (item->window.flags & WINDOW_PLAYERCOLOR)
  6253. {
  6254. vec4_t color;
  6255. color[0] = ui_char_color_red.integer/COLOR_MAX;
  6256. color[1] = ui_char_color_green.integer/COLOR_MAX;
  6257. color[2] = ui_char_color_blue.integer/COLOR_MAX;
  6258. color[3] = 1.0f;
  6259. DC->setColor(color);
  6260. }
  6261. #endif
  6262. DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
  6263. }
  6264. if (i == item->cursorPos)
  6265. {
  6266. DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor);
  6267. }
  6268. sizeWidth -= listPtr->elementWidth;
  6269. if (sizeWidth < listPtr->elementWidth)
  6270. {
  6271. listPtr->drawPadding = sizeWidth; //listPtr->elementWidth - size;
  6272. break;
  6273. }
  6274. x += listPtr->elementWidth;
  6275. listPtr->endPos++;
  6276. }
  6277. sizeHeight -= listPtr->elementHeight;
  6278. if (sizeHeight < listPtr->elementHeight)
  6279. {
  6280. listPtr->drawPadding = sizeHeight; //listPtr->elementWidth - size;
  6281. break;
  6282. }
  6283. listPtr->endPos++;
  6284. startPos = listPtr->endPos;
  6285. y += listPtr->elementHeight;
  6286. }
  6287. }
  6288. // single column
  6289. else
  6290. {
  6291. // fit = 0;
  6292. x = item->window.rect.x + 1;
  6293. y = item->window.rect.y + 1;
  6294. for (i = listPtr->startPos; i < count; i++)
  6295. {
  6296. // always draw at least one
  6297. // which may overdraw the box if it is too small for the element
  6298. image = DC->feederItemImage(item->special, i);
  6299. if (image)
  6300. {
  6301. DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
  6302. }
  6303. if (i == item->cursorPos)
  6304. {
  6305. DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, item->window.borderSize, item->window.borderColor);
  6306. }
  6307. listPtr->endPos++;
  6308. size -= listPtr->elementHeight;
  6309. if (size < listPtr->elementHeight)
  6310. {
  6311. listPtr->drawPadding = listPtr->elementHeight - size;
  6312. break;
  6313. }
  6314. y += listPtr->elementHeight;
  6315. // fit++;
  6316. }
  6317. }
  6318. }
  6319. else
  6320. {
  6321. x = item->window.rect.x + 1;
  6322. y = item->window.rect.y + 1 - listPtr->elementHeight;
  6323. //JLF MPMOVED
  6324. #ifdef _XBOX
  6325. if ( listPtr->notselectable)
  6326. i = listPtr->startPos - (numlines/2);
  6327. else
  6328. i = listPtr->startPos;
  6329. #else
  6330. i = listPtr->startPos;
  6331. #endif
  6332. int enddisplaynum = i + numlines;
  6333. if (enddisplaynum > count)
  6334. enddisplaynum = count;
  6335. for (; i<enddisplaynum; i++)
  6336. // for (; i < count; i++)
  6337. {
  6338. #ifdef _XBOX // Draw selection bar using custom shader - do it first, so fancy gfx are under text:
  6339. if (i == item->cursorPos && listPtr->selectionShader)
  6340. {
  6341. int barWidth = item->window.rect.w - 4 - (listPtr->scrollhidden ? 0 : SCROLLBAR_SIZE);
  6342. // Crazy math to match the text offset below. Ugh.
  6343. int yOff = DC->textHeight("", item->textscale, item->font);
  6344. yOff = (-yOff) / 2 + (listPtr->elementHeight / 2);
  6345. DC->drawHandlePic(x + 2, y + listPtr->elementHeight + 2 + yOff, barWidth, listPtr->elementHeight, listPtr->selectionShader);
  6346. }
  6347. #endif
  6348. const char *text;
  6349. // always draw at least one
  6350. // which may overdraw the box if it is too small for the element
  6351. if ((!listPtr->notselectable) || i>=0)
  6352. {
  6353. if (listPtr->numColumns > 0)
  6354. {
  6355. int j;
  6356. for (j = 0; j < listPtr->numColumns; j++)
  6357. {
  6358. text = DC->feederItemText(item->special, i, j, &optionalImage);
  6359. if (text[0]=='@')
  6360. {
  6361. text = SE_GetString( &text[1] );
  6362. }
  6363. if (optionalImage >= 0)
  6364. {
  6365. DC->drawHandlePic(x + 4 + listPtr->columnInfo[j].pos, y - 1 + listPtr->elementHeight / 2, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage);
  6366. }
  6367. else if (text)
  6368. {
  6369. vec4_t *color;
  6370. vec4_t newColor;
  6371. menuDef_t *parent = (menuDef_t*)item->parent;
  6372. // Use focus color is it has focus.
  6373. if (i == item->cursorPos)
  6374. {
  6375. if (item->window.flags & WINDOW_HASFOCUS)
  6376. {
  6377. Item_TextColor(item,&newColor);
  6378. color = &newColor;
  6379. }
  6380. else
  6381. color = &parent->focusColor;
  6382. }
  6383. else
  6384. {
  6385. color = &item->window.foreColor;
  6386. }
  6387. int textyOffset = 0;
  6388. int textxOffset = 0;
  6389. //JLF MPMOVED
  6390. #ifdef _XBOX
  6391. float fScaleA = item->textscale;
  6392. textyOffset = DC->textHeight (text, fScaleA, item->font);
  6393. textyOffset *= -1;
  6394. textyOffset /=2;
  6395. textyOffset += listPtr->elementHeight/2;
  6396. // First column, always left justified:
  6397. if( j == 0 )
  6398. {
  6399. textxOffset = 0;
  6400. }
  6401. else if( (j > 0) && (j < listPtr->numColumns - 1) )
  6402. { // Middle columns in those with three or more - centered
  6403. // Half the column width minus half the text width -> centered
  6404. textxOffset = (listPtr->columnInfo[j].width / 2) -
  6405. (DC->textWidth (text, fScaleA, item->font) / 2);
  6406. textxOffset -= 4; // Cancel out the +4 from below
  6407. }
  6408. else if( j == listPtr->numColumns - 1 )
  6409. { // Right most column, right justified
  6410. // Colum width, minus text width -> right aligned
  6411. textxOffset = listPtr->columnInfo[j].width -
  6412. DC->textWidth (text, fScaleA, item->font);
  6413. textxOffset -= 8; // Go 4 pixels from the other border (see below)
  6414. }
  6415. #endif
  6416. DC->drawText(x + 4 + listPtr->columnInfo[j].pos + textxOffset, y + listPtr->elementHeight+ textyOffset, item->textscale, *color, text, listPtr->columnInfo[j].maxChars, item->textStyle, item->font);
  6417. }
  6418. }
  6419. }
  6420. else
  6421. {
  6422. //JLF MPMOVED
  6423. #ifdef _XBOX
  6424. if (i >= 0)
  6425. {
  6426. #endif
  6427. text = DC->feederItemText(item->special, i, 0, &optionalImage);
  6428. int textyOffset = 0;
  6429. float fScaleA = item->textscale;
  6430. textyOffset = DC->textHeight (text, fScaleA, item->font);
  6431. textyOffset *= -1;
  6432. textyOffset /=2;
  6433. textyOffset += listPtr->elementHeight/2;
  6434. if (optionalImage >= 0)
  6435. {
  6436. //DC->drawHandlePic(x + 4 + listPtr->elementHeight, y, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage);
  6437. }
  6438. else if (text)
  6439. {
  6440. DC->drawText(x + 4, y + listPtr->elementHeight + textyOffset, item->textscale, item->window.foreColor, text, 0, item->textStyle, item->font);
  6441. }
  6442. //JLF MPMOVED
  6443. #ifdef _XBOX
  6444. }
  6445. #endif
  6446. }
  6447. }
  6448. // The chosen text
  6449. #ifndef _XBOX
  6450. if (i == item->cursorPos)
  6451. {
  6452. DC->fillRect(x + 2, y + listPtr->elementHeight + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, listPtr->elementHeight+2, item->window.outlineColor);
  6453. }
  6454. #endif
  6455. size -= listPtr->elementHeight;
  6456. if (size < listPtr->elementHeight)
  6457. {
  6458. listPtr->drawPadding = listPtr->elementHeight - size;
  6459. break;
  6460. }
  6461. listPtr->endPos++;
  6462. y += listPtr->elementHeight;
  6463. // fit++;
  6464. }
  6465. }
  6466. }
  6467. }
  6468. char g_nameBind1[32];
  6469. char g_nameBind2[32];
  6470. typedef struct
  6471. {
  6472. char* name;
  6473. float defaultvalue;
  6474. float value;
  6475. } configcvar_t;
  6476. /*
  6477. =================
  6478. BindingFromName
  6479. =================
  6480. */
  6481. void BindingFromName(const char *cvar)
  6482. {
  6483. int i, b1, b2;
  6484. // iterate each command, set its default binding
  6485. for (i=0; i < g_bindCount; i++)
  6486. {
  6487. if (Q_stricmp(cvar, g_bindings[i].command) == 0) {
  6488. b1 = g_bindings[i].bind1;
  6489. if (b1 == -1)
  6490. {
  6491. break;
  6492. }
  6493. DC->keynumToStringBuf( b1, g_nameBind1, sizeof(g_nameBind1) );
  6494. // do NOT do this or it corrupts asian text!!! Q_strupr(g_nameBind1);
  6495. b2 = g_bindings[i].bind2;
  6496. if (b2 != -1)
  6497. {
  6498. DC->keynumToStringBuf( b2, g_nameBind2, sizeof(g_nameBind2) );
  6499. // do NOT do this or it corrupts asian text!!!// Q_strupr(g_nameBind2);
  6500. strcat( g_nameBind1, va(" %s ",SE_GetString("MENUS_KEYBIND_OR" )) );
  6501. strcat( g_nameBind1, g_nameBind2 );
  6502. }
  6503. return;
  6504. }
  6505. }
  6506. strcpy(g_nameBind1, "???");
  6507. }
  6508. /*
  6509. =================
  6510. Item_Bind_Paint
  6511. =================
  6512. */
  6513. void Item_Bind_Paint(itemDef_t *item)
  6514. {
  6515. vec4_t newColor, lowLight;
  6516. float value,textScale,textWidth;
  6517. int maxChars = 0, textHeight,yAdj,startingXPos;
  6518. menuDef_t *parent = (menuDef_t*)item->parent;
  6519. editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
  6520. if (editPtr)
  6521. {
  6522. maxChars = editPtr->maxPaintChars;
  6523. }
  6524. value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
  6525. if (item->window.flags & WINDOW_HASFOCUS)
  6526. {
  6527. if (g_bindItem == item)
  6528. {
  6529. lowLight[0] = 0.8f * 1.0f;
  6530. lowLight[1] = 0.8f * 0.0f;
  6531. lowLight[2] = 0.8f * 0.0f;
  6532. lowLight[3] = 0.8f * 1.0f;
  6533. }
  6534. else
  6535. {
  6536. lowLight[0] = 0.8f * parent->focusColor[0];
  6537. lowLight[1] = 0.8f * parent->focusColor[1];
  6538. lowLight[2] = 0.8f * parent->focusColor[2];
  6539. lowLight[3] = 0.8f * parent->focusColor[3];
  6540. }
  6541. LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  6542. }
  6543. else
  6544. {
  6545. Item_TextColor( item,&newColor);
  6546. }
  6547. if (item->text)
  6548. {
  6549. Item_Text_Paint(item);
  6550. BindingFromName(item->cvar);
  6551. // If the text runs past the limit bring the scale down until it fits.
  6552. textScale = item->textscale;
  6553. textWidth = DC->textWidth(g_nameBind1,(float) textScale, uiInfo.uiDC.Assets.qhMediumFont);
  6554. startingXPos = (item->textRect.x + item->textRect.w + 8);
  6555. while ((startingXPos + textWidth) >= SCREEN_WIDTH)
  6556. {
  6557. textScale -= .05f;
  6558. textWidth = DC->textWidth(g_nameBind1,(float) textScale, uiInfo.uiDC.Assets.qhMediumFont);
  6559. }
  6560. // Try to adjust it's y placement if the scale has changed.
  6561. yAdj = 0;
  6562. if (textScale != item->textscale)
  6563. {
  6564. textHeight = DC->textHeight(g_nameBind1, item->textscale, uiInfo.uiDC.Assets.qhMediumFont);
  6565. yAdj = textHeight - DC->textHeight(g_nameBind1, textScale, uiInfo.uiDC.Assets.qhMediumFont);
  6566. }
  6567. DC->drawText(startingXPos, item->textRect.y + yAdj, textScale, newColor, g_nameBind1, maxChars/*item->textRect.w*/, item->textStyle, item->font);
  6568. }
  6569. else
  6570. {
  6571. DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME 1" : "FIXME 0", maxChars/*item->textRect.w*/, item->textStyle, item->font);
  6572. }
  6573. }
  6574. void UI_ScaleModelAxis(refEntity_t *ent)
  6575. { // scale the model should we need to
  6576. if (ent->modelScale[0] && ent->modelScale[0] != 1.0f)
  6577. {
  6578. VectorScale( ent->axis[0], ent->modelScale[0] , ent->axis[0] );
  6579. ent->nonNormalizedAxes = qtrue;
  6580. }
  6581. if (ent->modelScale[1] && ent->modelScale[1] != 1.0f)
  6582. {
  6583. VectorScale( ent->axis[1], ent->modelScale[1] , ent->axis[1] );
  6584. ent->nonNormalizedAxes = qtrue;
  6585. }
  6586. if (ent->modelScale[2] && ent->modelScale[2] != 1.0f)
  6587. {
  6588. VectorScale( ent->axis[2], ent->modelScale[2] , ent->axis[2] );
  6589. ent->nonNormalizedAxes = qtrue;
  6590. }
  6591. }
  6592. /*
  6593. =================
  6594. Item_Model_Paint
  6595. =================
  6596. */
  6597. #ifdef _XBOX
  6598. extern int *s_entityWavVol;
  6599. #else
  6600. extern int s_entityWavVol[MAX_GENTITIES]; //from snd_dma.cpp
  6601. #endif
  6602. void UI_TalkingHead(itemDef_t *item)
  6603. {
  6604. // static int facial_blink = DC->realTime + Q_flrand(4000.0, 8000.0);
  6605. static int facial_timer = DC->realTime + Q_flrand(10000.0, 30000.0);
  6606. // static animNumber_t facial_anim = FACE_ALERT;
  6607. int anim = -1;
  6608. //are we blinking?
  6609. /* if (facial_blink < 0)
  6610. { // yes, check if we are we done blinking ?
  6611. if (-(facial_blink) < DC->realTime)
  6612. { // yes, so reset blink timer
  6613. facial_blink = DC->realTime + Q_flrand(4000.0, 8000.0);
  6614. CG_G2SetHeadBlink( cent, qfalse ); //stop the blink
  6615. }
  6616. }
  6617. else // no we aren't blinking
  6618. {
  6619. if (facial_blink < DC->realTime)// but should we start ?
  6620. {
  6621. CG_G2SetHeadBlink( cent, qtrue );
  6622. if (facial_blink == 1)
  6623. {//requested to stay shut by SET_FACEEYESCLOSED
  6624. facial_blink = -(DC->realTime + 99999999.0f);// set blink timer
  6625. }
  6626. else
  6627. {
  6628. facial_blink = -(DC->realTime + 300.0f);// set blink timer
  6629. }
  6630. }
  6631. }
  6632. */
  6633. if (s_entityWavVol[0] > 0) // if we aren't talking, then it will be 0, -1 for talking but paused
  6634. {
  6635. anim = FACE_TALK1 + s_entityWavVol[0]-1;
  6636. if( anim > FACE_TALK4 )
  6637. {
  6638. anim = FACE_TALK4;
  6639. }
  6640. // reset timers so we don't start right away after talking
  6641. facial_timer = DC->realTime + Q_flrand(2000.0, 7000.0);
  6642. }
  6643. else if (s_entityWavVol[0] == -1)
  6644. {// talking, but silent
  6645. anim = FACE_TALK0;
  6646. // reset timers so we don't start right away after talking
  6647. facial_timer = DC->realTime + Q_flrand(2000.0, 7000.0);
  6648. }
  6649. /* else if (s_entityWavVol[0] == 0) //don't anim if in a slient part of speech
  6650. {//not talking
  6651. if (facial_timer < 0) // are animating ?
  6652. { //yes
  6653. if (-(facial_timer) < DC->realTime)// are we done animating ?
  6654. { // yes, reset timer
  6655. facial_timer = DC->realTime + Q_flrand(10000.0, 30000.0);
  6656. }
  6657. else
  6658. { // not yet, so choose anim
  6659. anim = facial_anim;
  6660. }
  6661. }
  6662. else // no we aren't animating
  6663. { // but should we start ?
  6664. if (facial_timer < DC->realTime)
  6665. {//yes
  6666. facial_anim = FACE_ALERT + Q_irand(0,2); //alert, smile, frown
  6667. // set aux timer
  6668. facial_timer = -(DC->realTime + 2000.0);
  6669. anim = facial_anim;
  6670. }
  6671. }
  6672. }//talking
  6673. */
  6674. if (facial_timer < DC->realTime)
  6675. {//restart the base anim
  6676. // modelDef_t *modelPtr = (modelDef_t*)item->typeData;
  6677. //ItemParse_model_g2anim_go( item, "BOTH_STAND5IDLE1" );
  6678. // facial_timer = DC->realTime + Q_flrand(2000.0, 7000.0) + DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6679. }
  6680. if (anim != -1)
  6681. {
  6682. DC->g2hilev_SetAnim(&item->ghoul2[0], "face", anim, qfalse);
  6683. }
  6684. }
  6685. /*
  6686. =================
  6687. Item_Model_Paint
  6688. =================
  6689. */
  6690. extern void UI_SaberDrawBlades( itemDef_t *item, vec3_t origin, float curYaw );
  6691. void Item_Model_Paint(itemDef_t *item)
  6692. {
  6693. float x, y, w, h;
  6694. refdef_t refdef;
  6695. refEntity_t ent;
  6696. vec3_t mins, maxs, origin;
  6697. vec3_t angles;
  6698. const modelDef_t *modelPtr = (modelDef_t*)item->typeData;
  6699. if (modelPtr == NULL)
  6700. {
  6701. return;
  6702. }
  6703. // a moves datapad anim is playing
  6704. if (uiInfo.moveAnimTime && (uiInfo.moveAnimTime < uiInfo.uiDC.realTime))
  6705. {
  6706. modelDef_t *modelPtr;
  6707. modelPtr = (modelDef_t*)item->typeData;
  6708. if (modelPtr)
  6709. {
  6710. //HACKHACKHACK: check for any multi-part anim sequences, and play the next anim, if needbe
  6711. switch( modelPtr->g2anim )
  6712. {
  6713. case BOTH_FORCEWALLREBOUND_FORWARD:
  6714. case BOTH_FORCEJUMP1:
  6715. ItemParse_model_g2anim_go( item, animTable[BOTH_FORCEINAIR1].name );
  6716. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6717. if ( !uiInfo.moveAnimTime )
  6718. {
  6719. uiInfo.moveAnimTime = 500;
  6720. }
  6721. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6722. break;
  6723. case BOTH_FORCEINAIR1:
  6724. ItemParse_model_g2anim_go( item, animTable[BOTH_FORCELAND1].name );
  6725. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6726. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6727. break;
  6728. case BOTH_FORCEWALLRUNFLIP_START:
  6729. ItemParse_model_g2anim_go( item, animTable[BOTH_FORCEWALLRUNFLIP_END].name );
  6730. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6731. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6732. break;
  6733. case BOTH_FORCELONGLEAP_START:
  6734. ItemParse_model_g2anim_go( item, animTable[BOTH_FORCELONGLEAP_LAND].name );
  6735. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6736. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6737. break;
  6738. case BOTH_KNOCKDOWN3://on front - into force getup
  6739. DC->startLocalSound(uiInfo.uiDC.Assets.datapadmoveJumpSound, CHAN_LOCAL );
  6740. ItemParse_model_g2anim_go( item, animTable[BOTH_FORCE_GETUP_F1].name );
  6741. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6742. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6743. break;
  6744. case BOTH_KNOCKDOWN2://on back - kick forward getup
  6745. DC->startLocalSound(uiInfo.uiDC.Assets.datapadmoveJumpSound, CHAN_LOCAL );
  6746. ItemParse_model_g2anim_go( item, animTable[BOTH_GETUP_BROLL_F].name );
  6747. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6748. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6749. break;
  6750. case BOTH_KNOCKDOWN1://on back - roll-away
  6751. DC->startLocalSound(uiInfo.uiDC.Assets.datapadmoveRollSound, CHAN_LOCAL );
  6752. ItemParse_model_g2anim_go( item, animTable[BOTH_GETUP_BROLL_R].name );
  6753. uiInfo.moveAnimTime = DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6754. uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
  6755. break;
  6756. default:
  6757. ItemParse_model_g2anim_go( item, uiInfo.movesBaseAnim );
  6758. DC->g2hilev_SetAnim(&item->ghoul2[0], "model_root", modelPtr->g2anim, qtrue);
  6759. uiInfo.moveAnimTime = 0;
  6760. break;
  6761. }
  6762. }
  6763. }
  6764. // setup the refdef
  6765. memset( &refdef, 0, sizeof( refdef ) );
  6766. refdef.rdflags = RDF_NOWORLDMODEL;
  6767. AxisClear( refdef.viewaxis );
  6768. x = item->window.rect.x+1;
  6769. y = item->window.rect.y+1;
  6770. w = item->window.rect.w-2;
  6771. h = item->window.rect.h-2;
  6772. refdef.x = x * DC->xscale;
  6773. refdef.y = y * DC->yscale;
  6774. refdef.width = w * DC->xscale;
  6775. refdef.height = h * DC->yscale;
  6776. if (item->flags&ITF_G2VALID)
  6777. { //ghoul2 models don't have bounds, so we have to parse them.
  6778. VectorCopy(modelPtr->g2mins, mins);
  6779. VectorCopy(modelPtr->g2maxs, maxs);
  6780. if (!mins[0] && !mins[1] && !mins[2] &&
  6781. !maxs[0] && !maxs[1] && !maxs[2])
  6782. { //we'll use defaults then I suppose.
  6783. VectorSet(mins, -16, -16, -24);
  6784. VectorSet(maxs, 16, 16, 32);
  6785. }
  6786. }
  6787. else
  6788. {
  6789. DC->modelBounds( item->asset, mins, maxs );
  6790. }
  6791. origin[2] = -0.5 * ( mins[2] + maxs[2] );
  6792. origin[1] = 0.5 * ( mins[1] + maxs[1] );
  6793. refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : (int)((float)refdef.width / 640.0f * 90.0f);
  6794. refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : atan2( refdef.height, refdef.width / tan( refdef.fov_x / 360 * M_PI ) ) * ( 360 / M_PI );
  6795. // refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : refdef.width;
  6796. // refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : refdef.height;
  6797. // calculate distance so the model nearly fills the box
  6798. float len = 0.5 * ( maxs[2] - mins[2] );
  6799. origin[0] = len / 0.268;
  6800. DC->clearScene();
  6801. refdef.time = DC->realTime;
  6802. // add the model
  6803. memset( &ent, 0, sizeof(ent) );
  6804. // use item storage to track
  6805. float curYaw = modelPtr->angle;
  6806. if (modelPtr->rotationSpeed)
  6807. {
  6808. curYaw += (float)refdef.time/modelPtr->rotationSpeed;
  6809. }
  6810. // if ( item->flags&ITF_ISANYSABER && !(item->flags&ITF_ISCHARACTER) )
  6811. // {//hack to put saber on it's side
  6812. // VectorSet( angles, curYaw, 0, 90 );
  6813. // }
  6814. // else
  6815. if (item->flags&ITF_G2VALID)
  6816. {
  6817. VectorSet( angles, 0, curYaw, 0 );
  6818. }
  6819. else
  6820. {
  6821. // Hack to put the spinning saber logo thing on its side
  6822. VectorSet( angles, curYaw, 0, 90 );
  6823. }
  6824. AnglesToAxis( angles, ent.axis );
  6825. if (item->flags&ITF_G2VALID)
  6826. {
  6827. ent.ghoul2 = &item->ghoul2;
  6828. ent.radius = 1000;
  6829. ent.customSkin = modelPtr->g2skin;
  6830. if ( (item->flags&ITF_ISCHARACTER) )
  6831. {
  6832. ent.shaderRGBA[0] = ui_char_color_red.integer;
  6833. ent.shaderRGBA[1] = ui_char_color_green.integer;
  6834. ent.shaderRGBA[2] = ui_char_color_blue.integer;
  6835. ent.shaderRGBA[3] = 255;
  6836. UI_TalkingHead(item);
  6837. }
  6838. if ( item->flags&ITF_ISANYSABER )
  6839. {//UGH, draw the saber blade!
  6840. UI_SaberDrawBlades( item, origin, curYaw );
  6841. }
  6842. }
  6843. else
  6844. {
  6845. ent.hModel = item->asset;
  6846. }
  6847. VectorCopy( origin, ent.origin );
  6848. VectorCopy( ent.origin, ent.oldorigin );
  6849. // Set up lighting
  6850. //VectorCopy( refdef.vieworg, ent.lightingOrigin );
  6851. //ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
  6852. ent.renderfx = RF_NOSHADOW ;
  6853. #ifndef _XBOX
  6854. ui.R_AddLightToScene(refdef.vieworg, 500, 1, 1, 1); //fixme: specify in menu file!
  6855. #endif
  6856. float oldCull = tr.distanceCull;
  6857. tr.distanceCull = 12000;
  6858. DC->addRefEntityToScene( &ent );
  6859. DC->renderScene( &refdef );
  6860. tr.distanceCull = oldCull;
  6861. }
  6862. /*
  6863. =================
  6864. Item_OwnerDraw_Paint
  6865. =================
  6866. */
  6867. void Item_OwnerDraw_Paint(itemDef_t *item)
  6868. {
  6869. menuDef_t *parent;
  6870. if (item == NULL)
  6871. {
  6872. return;
  6873. }
  6874. parent = (menuDef_t*)item->parent;
  6875. if (DC->ownerDrawItem)
  6876. {
  6877. vec4_t color, lowLight;
  6878. menuDef_t *parent = (menuDef_t*)item->parent;
  6879. Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
  6880. memcpy(&color, &item->window.foreColor, sizeof(color));
  6881. /*
  6882. if (item->numColors > 0 && DC->getValue)
  6883. {
  6884. // if the value is within one of the ranges then set color to that, otherwise leave at default
  6885. int i;
  6886. float f = DC->getValue(item->window.ownerDraw);
  6887. for (i = 0; i < item->numColors; i++)
  6888. {
  6889. if (f >= item->colorRanges[i].low && f <= item->colorRanges[i].high)
  6890. {
  6891. memcpy(&color, &item->colorRanges[i].color, sizeof(color));
  6892. break;
  6893. }
  6894. }
  6895. }
  6896. */
  6897. if (item->window.flags & WINDOW_HASFOCUS)
  6898. {
  6899. memcpy(color, &parent->focusColor, sizeof(vec4_t));
  6900. /*
  6901. lowLight[0] = 0.8 * parent->focusColor[0];
  6902. lowLight[1] = 0.8 * parent->focusColor[1];
  6903. lowLight[2] = 0.8 * parent->focusColor[2];
  6904. lowLight[3] = 0.8 * parent->focusColor[3];
  6905. LerpColor(parent->focusColor,lowLight,color,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  6906. */
  6907. }
  6908. else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1))
  6909. {
  6910. lowLight[0] = 0.8 * item->window.foreColor[0];
  6911. lowLight[1] = 0.8 * item->window.foreColor[1];
  6912. lowLight[2] = 0.8 * item->window.foreColor[2];
  6913. lowLight[3] = 0.8 * item->window.foreColor[3];
  6914. LerpColor(item->window.foreColor,lowLight,color,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
  6915. }
  6916. if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
  6917. {
  6918. memcpy(color, parent->disableColor, sizeof(vec4_t));
  6919. }
  6920. if (item->text)
  6921. {
  6922. Item_Text_Paint(item);
  6923. // +8 is an offset kludge to properly align owner draw items that have text combined with them
  6924. DC->ownerDrawItem(item->textRect.x + item->textRect.w + 8, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle, item->font );
  6925. }
  6926. else
  6927. {
  6928. DC->ownerDrawItem(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, item->textalignx, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle, item->font );
  6929. }
  6930. }
  6931. }
  6932. void Item_YesNo_Paint(itemDef_t *item)
  6933. {
  6934. vec4_t newColor;
  6935. float value;
  6936. menuDef_t *parent = (menuDef_t*)item->parent;
  6937. value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
  6938. if (item->window.flags & WINDOW_HASFOCUS)
  6939. {
  6940. memcpy(&newColor, &parent->focusColor, sizeof(vec4_t));
  6941. }
  6942. else
  6943. {
  6944. memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
  6945. }
  6946. const char *psYes = SE_GetString( "MENUS_YES" );
  6947. const char *psNo = SE_GetString( "MENUS_NO" );
  6948. const char *yesnovalue;
  6949. // if (item->invertYesNo)
  6950. // yesnovalue = (value == 0) ? psYes : psNo;
  6951. // else
  6952. yesnovalue = (value != 0) ? psYes : psNo;
  6953. if (item->text)
  6954. {
  6955. Item_Text_Paint(item);
  6956. //JLF
  6957. #ifdef _XBOX
  6958. if (item->xoffset == 0)
  6959. DC->drawText(item->textRect.x + item->textRect.w + item->xoffset + 8, item->textRect.y, item->textscale, newColor, yesnovalue, 0, item->textStyle, item->font);
  6960. else
  6961. #endif
  6962. DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, yesnovalue, 0, item->textStyle, item->font);
  6963. }
  6964. else
  6965. {
  6966. //JLF
  6967. #ifdef _XBOX
  6968. DC->drawText(item->textRect.x + item->xoffset, item->textRect.y, item->textscale, newColor, yesnovalue , 0, item->textStyle, item->font);
  6969. #else
  6970. DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, yesnovalue , 0, item->textStyle, item->font);
  6971. #endif
  6972. }
  6973. }
  6974. /*
  6975. =================
  6976. Item_Multi_Paint
  6977. =================
  6978. */
  6979. void Item_Multi_Paint(itemDef_t *item)
  6980. {
  6981. vec4_t newColor;
  6982. const char *text = "";
  6983. menuDef_t *parent = (menuDef_t*)item->parent;
  6984. if (item->window.flags & WINDOW_HASFOCUS)
  6985. {
  6986. memcpy(&newColor, &parent->focusColor, sizeof(vec4_t));
  6987. }
  6988. else
  6989. {
  6990. memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
  6991. }
  6992. text = Item_Multi_Setting(item);
  6993. if (*text == '@') // string reference
  6994. {
  6995. text = SE_GetString( &text[1] );
  6996. }
  6997. // How big is the string:
  6998. int textWidth = DC->textWidth( text, item->textscale, item->font );
  6999. if (item->text)
  7000. {
  7001. // Draw the item's label:
  7002. Item_Text_Paint(item);
  7003. int x = item->textRect.x; // Start at left edge of rectangle
  7004. x += item->xoffset; // Add xoffset
  7005. x -= textWidth; // Minus width (to get right-justified)
  7006. x -= 20; // Leave 16 pixels (and slack) for arrow
  7007. // Draw the text:
  7008. DC->drawText( x, item->textRect.y, item->textscale, newColor, text, 0, item->textStyle, item->font );
  7009. // If this item has focus, draw the change arrows two pixels out on either end:
  7010. if (item->window.flags & WINDOW_HASFOCUS)
  7011. {
  7012. qhandle_t arrowShader = ui.R_RegisterShaderNoMip( "gfx/menus/newFront/left_arrow" );
  7013. ui.R_SetColor( NULL );
  7014. int textHeight = DC->textHeight( "", item->textscale, item->font );
  7015. ui.R_DrawStretchPic( x - 20, item->textRect.y + (textHeight/2) - 3, 16, 16, 0, 0, 1, 1, arrowShader );
  7016. ui.R_DrawStretchPic( x + textWidth + 4, item->textRect.y + (textHeight/2) - 3, 16, 16, 1, 1, 0, 0, arrowShader );
  7017. }
  7018. }
  7019. else
  7020. {
  7021. int x = item->window.rect.x; // Start at left edge of window
  7022. x += item->xoffset; // Add xoffset
  7023. if( item->textalignment == ITEM_ALIGN_RIGHT )
  7024. {
  7025. x -= 20; // Leave 16 pixels (and slack) for arrow
  7026. x -= textWidth; // Minus width (for right justified)
  7027. }
  7028. else if( item->textalignment == ITEM_ALIGN_CENTER )
  7029. {
  7030. x -= textWidth / 2; // Minus half-width (for centered)
  7031. }
  7032. // Draw the text:
  7033. DC->drawText( x, item->window.rect.y, item->textscale, newColor, text, 0, item->textStyle, item->font );
  7034. // If this item has focus, draw the change arrows two pixels out on either end:
  7035. if (item->window.flags & WINDOW_HASFOCUS)
  7036. {
  7037. qhandle_t arrowShader = ui.R_RegisterShaderNoMip( "gfx/menus/newFront/left_arrow" );
  7038. ui.R_SetColor( NULL );
  7039. int textHeight = DC->textHeight( "", item->textscale, item->font );
  7040. ui.R_DrawStretchPic( x - 20, item->window.rect.y + (textHeight/2) - 3, 16, 16, 0, 0, 1, 1, arrowShader );
  7041. ui.R_DrawStretchPic( x + textWidth + 4, item->window.rect.y + (textHeight/2) - 3, 16, 16, 1, 1, 0, 0, arrowShader );
  7042. }
  7043. }
  7044. }
  7045. int Item_TextScroll_MaxScroll ( itemDef_t *item )
  7046. {
  7047. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  7048. int count = scrollPtr->iLineCount;
  7049. int max = count - (int)(item->window.rect.h / scrollPtr->lineHeight) + 1;
  7050. if (max < 0)
  7051. {
  7052. return 0;
  7053. }
  7054. return max;
  7055. }
  7056. int Item_TextScroll_ThumbPosition ( itemDef_t *item )
  7057. {
  7058. float max, pos, size;
  7059. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  7060. max = Item_TextScroll_MaxScroll ( item );
  7061. size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2;
  7062. if (max > 0)
  7063. {
  7064. pos = (size-SCROLLBAR_SIZE) / (float) max;
  7065. }
  7066. else
  7067. {
  7068. pos = 0;
  7069. }
  7070. pos *= scrollPtr->startPos;
  7071. return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos;
  7072. }
  7073. int Item_TextScroll_ThumbDrawPosition ( itemDef_t *item )
  7074. {
  7075. int min, max;
  7076. if (itemCapture == item)
  7077. {
  7078. min = item->window.rect.y + SCROLLBAR_SIZE + 1;
  7079. max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1;
  7080. if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2)
  7081. {
  7082. return DC->cursory - SCROLLBAR_SIZE/2;
  7083. }
  7084. return Item_TextScroll_ThumbPosition(item);
  7085. }
  7086. return Item_TextScroll_ThumbPosition(item);
  7087. }
  7088. int Item_TextScroll_OverLB ( itemDef_t *item, float x, float y )
  7089. {
  7090. rectDef_t r;
  7091. textScrollDef_t *scrollPtr;
  7092. int thumbstart;
  7093. int count;
  7094. scrollPtr = (textScrollDef_t*)item->typeData;
  7095. count = scrollPtr->iLineCount;
  7096. // Scroll bar isn't drawing so ignore this input
  7097. if ((( scrollPtr->iLineCount * scrollPtr->lineHeight ) <= (item->window.rect.h - 2)) && (item->type == ITEM_TYPE_TEXTSCROLL))
  7098. {
  7099. return 0;
  7100. }
  7101. r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
  7102. r.y = item->window.rect.y;
  7103. r.h = r.w = SCROLLBAR_SIZE;
  7104. if (Rect_ContainsPoint(&r, x, y))
  7105. {
  7106. return WINDOW_LB_LEFTARROW;
  7107. }
  7108. r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
  7109. if (Rect_ContainsPoint(&r, x, y))
  7110. {
  7111. return WINDOW_LB_RIGHTARROW;
  7112. }
  7113. thumbstart = Item_TextScroll_ThumbPosition(item);
  7114. r.y = thumbstart;
  7115. if (Rect_ContainsPoint(&r, x, y))
  7116. {
  7117. return WINDOW_LB_THUMB;
  7118. }
  7119. r.y = item->window.rect.y + SCROLLBAR_SIZE;
  7120. r.h = thumbstart - r.y;
  7121. if (Rect_ContainsPoint(&r, x, y))
  7122. {
  7123. return WINDOW_LB_PGUP;
  7124. }
  7125. r.y = thumbstart + SCROLLBAR_SIZE;
  7126. r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
  7127. if (Rect_ContainsPoint(&r, x, y))
  7128. {
  7129. return WINDOW_LB_PGDN;
  7130. }
  7131. return 0;
  7132. }
  7133. void Item_TextScroll_MouseEnter (itemDef_t *item, float x, float y)
  7134. {
  7135. item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
  7136. item->window.flags |= Item_TextScroll_OverLB(item, x, y);
  7137. }
  7138. /*
  7139. =================
  7140. Item_Slider_ThumbPosition
  7141. =================
  7142. */
  7143. int Item_ListBox_ThumbDrawPosition(itemDef_t *item)
  7144. {
  7145. int min, max;
  7146. if (itemCapture == item)
  7147. {
  7148. if (item->window.flags & WINDOW_HORIZONTAL)
  7149. {
  7150. min = item->window.rect.x + SCROLLBAR_SIZE + 1;
  7151. max = item->window.rect.x + item->window.rect.w - 2*SCROLLBAR_SIZE - 1;
  7152. if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2)
  7153. {
  7154. return DC->cursorx - SCROLLBAR_SIZE/2;
  7155. }
  7156. else
  7157. {
  7158. return Item_ListBox_ThumbPosition(item);
  7159. }
  7160. }
  7161. else
  7162. {
  7163. min = item->window.rect.y + SCROLLBAR_SIZE + 1;
  7164. max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1;
  7165. if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2)
  7166. {
  7167. return DC->cursory - SCROLLBAR_SIZE/2;
  7168. }
  7169. else
  7170. {
  7171. return Item_ListBox_ThumbPosition(item);
  7172. }
  7173. }
  7174. }
  7175. else
  7176. {
  7177. return Item_ListBox_ThumbPosition(item);
  7178. }
  7179. }
  7180. /*
  7181. =================
  7182. Item_Slider_ThumbPosition
  7183. =================
  7184. */
  7185. float Item_Slider_ThumbPosition(itemDef_t *item)
  7186. {
  7187. float value, range;
  7188. editFieldDef_t *editDef = (editFieldDef_t *) item->typeData;
  7189. if (!editDef || !item->cvar)
  7190. return 0.0f;
  7191. value = DC->getCVarValue(item->cvar);
  7192. if (value < editDef->minVal) {
  7193. value = editDef->minVal;
  7194. } else if (value > editDef->maxVal) {
  7195. value = editDef->maxVal;
  7196. }
  7197. range = editDef->maxVal - editDef->minVal;
  7198. value -= editDef->minVal;
  7199. return value / range;
  7200. }
  7201. /*
  7202. =================
  7203. Item_Slider_Paint
  7204. =================
  7205. */
  7206. void Item_Slider_Paint(itemDef_t *item)
  7207. {
  7208. float x, y, value;
  7209. if (item->text) {
  7210. Item_Text_Paint(item);
  7211. }
  7212. // Offset is to right of the (full) slider:
  7213. x = (item->window.rect.x + item->xoffset) - (SLIDER_WIDTH);
  7214. // And if we drew text, we need to shift vertically to be centered as well:
  7215. y = item->window.rect.y;
  7216. if (item->text)
  7217. y += (DC->textHeight("", item->textscale, item->font) / 2) - 2;
  7218. value = Item_Slider_ThumbPosition(item);
  7219. ui.R_SetColor( NULL );
  7220. ui.R_DrawStretchPic( x, y, SLIDER_WIDTH * value, SLIDER_HEIGHT, 0.0f, 0.0f, value, 1.0f, DC->Assets.sliderBar );
  7221. }
  7222. /*
  7223. =================
  7224. Item_Paint
  7225. =================
  7226. */
  7227. static qboolean Item_Paint(itemDef_t *item, qboolean bDraw)
  7228. {
  7229. int xPos,textWidth;
  7230. vec4_t red;
  7231. menuDef_t *parent = (menuDef_t*)item->parent;
  7232. red[0] = red[3] = 1;
  7233. red[1] = red[2] = 0;
  7234. if (item == NULL)
  7235. {
  7236. return qfalse;
  7237. }
  7238. if (item->window.flags & WINDOW_SCRIPTWAITING)
  7239. {
  7240. if (DC->realTime > item->window.delayTime)
  7241. { // Time has elapsed, resume running whatever script we saved
  7242. item->window.flags &= ~WINDOW_SCRIPTWAITING;
  7243. Item_RunScript(item, item->window.delayedScript);
  7244. }
  7245. }
  7246. if (item->window.flags & WINDOW_ORBITING)
  7247. {
  7248. if (DC->realTime > item->window.nextTime)
  7249. {
  7250. float rx, ry, a, c, s, w, h;
  7251. item->window.nextTime = DC->realTime + item->window.offsetTime;
  7252. // translate
  7253. w = item->window.rectClient.w / 2;
  7254. h = item->window.rectClient.h / 2;
  7255. rx = item->window.rectClient.x + w - item->window.rectEffects.x;
  7256. ry = item->window.rectClient.y + h - item->window.rectEffects.y;
  7257. a = (float) (3 * M_PI / 180);
  7258. c = cos(a);
  7259. s = sin(a);
  7260. item->window.rectClient.x = (rx * c - ry * s) + item->window.rectEffects.x - w;
  7261. item->window.rectClient.y = (rx * s + ry * c) + item->window.rectEffects.y - h;
  7262. Item_UpdatePosition(item);
  7263. }
  7264. }
  7265. if (item->window.flags & WINDOW_INTRANSITION)
  7266. {
  7267. if (DC->realTime > item->window.nextTime)
  7268. {
  7269. int done = 0;
  7270. item->window.nextTime = DC->realTime + item->window.offsetTime;
  7271. // transition the x,y
  7272. if (item->window.rectClient.x == item->window.rectEffects.x)
  7273. {
  7274. done++;
  7275. }
  7276. else
  7277. {
  7278. if (item->window.rectClient.x < item->window.rectEffects.x)
  7279. {
  7280. item->window.rectClient.x += item->window.rectEffects2.x;
  7281. if (item->window.rectClient.x > item->window.rectEffects.x)
  7282. {
  7283. item->window.rectClient.x = item->window.rectEffects.x;
  7284. done++;
  7285. }
  7286. }
  7287. else
  7288. {
  7289. item->window.rectClient.x -= item->window.rectEffects2.x;
  7290. if (item->window.rectClient.x < item->window.rectEffects.x)
  7291. {
  7292. item->window.rectClient.x = item->window.rectEffects.x;
  7293. done++;
  7294. }
  7295. }
  7296. }
  7297. if (item->window.rectClient.y == item->window.rectEffects.y)
  7298. {
  7299. done++;
  7300. }
  7301. else
  7302. {
  7303. if (item->window.rectClient.y < item->window.rectEffects.y)
  7304. {
  7305. item->window.rectClient.y += item->window.rectEffects2.y;
  7306. if (item->window.rectClient.y > item->window.rectEffects.y)
  7307. {
  7308. item->window.rectClient.y = item->window.rectEffects.y;
  7309. done++;
  7310. }
  7311. }
  7312. else
  7313. {
  7314. item->window.rectClient.y -= item->window.rectEffects2.y;
  7315. if (item->window.rectClient.y < item->window.rectEffects.y)
  7316. {
  7317. item->window.rectClient.y = item->window.rectEffects.y;
  7318. done++;
  7319. }
  7320. }
  7321. }
  7322. if (item->window.rectClient.w == item->window.rectEffects.w)
  7323. {
  7324. done++;
  7325. }
  7326. else
  7327. {
  7328. if (item->window.rectClient.w < item->window.rectEffects.w)
  7329. {
  7330. item->window.rectClient.w += item->window.rectEffects2.w;
  7331. if (item->window.rectClient.w > item->window.rectEffects.w)
  7332. {
  7333. item->window.rectClient.w = item->window.rectEffects.w;
  7334. done++;
  7335. }
  7336. }
  7337. else
  7338. {
  7339. item->window.rectClient.w -= item->window.rectEffects2.w;
  7340. if (item->window.rectClient.w < item->window.rectEffects.w)
  7341. {
  7342. item->window.rectClient.w = item->window.rectEffects.w;
  7343. done++;
  7344. }
  7345. }
  7346. }
  7347. if (item->window.rectClient.h == item->window.rectEffects.h)
  7348. {
  7349. done++;
  7350. }
  7351. else
  7352. {
  7353. if (item->window.rectClient.h < item->window.rectEffects.h)
  7354. {
  7355. item->window.rectClient.h += item->window.rectEffects2.h;
  7356. if (item->window.rectClient.h > item->window.rectEffects.h)
  7357. {
  7358. item->window.rectClient.h = item->window.rectEffects.h;
  7359. done++;
  7360. }
  7361. }
  7362. else
  7363. {
  7364. item->window.rectClient.h -= item->window.rectEffects2.h;
  7365. if (item->window.rectClient.h < item->window.rectEffects.h)
  7366. {
  7367. item->window.rectClient.h = item->window.rectEffects.h;
  7368. done++;
  7369. }
  7370. }
  7371. }
  7372. Item_UpdatePosition(item);
  7373. if (done == 4)
  7374. {
  7375. item->window.flags &= ~WINDOW_INTRANSITION;
  7376. }
  7377. }
  7378. }
  7379. #ifdef _TRANS3
  7380. //JLF begin model transition stuff
  7381. if (item->window.flags & WINDOW_INTRANSITIONMODEL)
  7382. {
  7383. if ( item->type == ITEM_TYPE_MODEL)
  7384. {
  7385. //fields ing modelptr
  7386. // vec3_t g2mins2, g2maxs2, g2minsEffect, g2maxsEffect;
  7387. // float fov_x2, fov_y2, fov_Effectx, fov_Effecty;
  7388. modelDef_t * modelptr = (modelDef_t *)item->typeData;
  7389. if (DC->realTime > item->window.nextTime)
  7390. {
  7391. int done = 0;
  7392. item->window.nextTime = DC->realTime + item->window.offsetTime;
  7393. // transition the x,y,z max
  7394. if (modelptr->g2maxs[0] == modelptr->g2maxs2[0])
  7395. {
  7396. done++;
  7397. }
  7398. else
  7399. {
  7400. if (modelptr->g2maxs[0] < modelptr->g2maxs2[0])
  7401. {
  7402. modelptr->g2maxs[0] += modelptr->g2maxsEffect[0];
  7403. if (modelptr->g2maxs[0] > modelptr->g2maxs2[0])
  7404. {
  7405. modelptr->g2maxs[0] = modelptr->g2maxs2[0];
  7406. done++;
  7407. }
  7408. }
  7409. else
  7410. {
  7411. modelptr->g2maxs[0] -= modelptr->g2maxsEffect[0];
  7412. if (modelptr->g2maxs[0] < modelptr->g2maxs2[0])
  7413. {
  7414. modelptr->g2maxs[0] = modelptr->g2maxs2[0];
  7415. done++;
  7416. }
  7417. }
  7418. }
  7419. //y
  7420. if (modelptr->g2maxs[1] == modelptr->g2maxs2[1])
  7421. {
  7422. done++;
  7423. }
  7424. else
  7425. {
  7426. if (modelptr->g2maxs[1] < modelptr->g2maxs2[1])
  7427. {
  7428. modelptr->g2maxs[1] += modelptr->g2maxsEffect[1];
  7429. if (modelptr->g2maxs[1] > modelptr->g2maxs2[1])
  7430. {
  7431. modelptr->g2maxs[1] = modelptr->g2maxs2[1];
  7432. done++;
  7433. }
  7434. }
  7435. else
  7436. {
  7437. modelptr->g2maxs[1] -= modelptr->g2maxsEffect[1];
  7438. if (modelptr->g2maxs[1] < modelptr->g2maxs2[1])
  7439. {
  7440. modelptr->g2maxs[1] = modelptr->g2maxs2[1];
  7441. done++;
  7442. }
  7443. }
  7444. }
  7445. //z
  7446. if (modelptr->g2maxs[2] == modelptr->g2maxs2[2])
  7447. {
  7448. done++;
  7449. }
  7450. else
  7451. {
  7452. if (modelptr->g2maxs[2] < modelptr->g2maxs2[2])
  7453. {
  7454. modelptr->g2maxs[2] += modelptr->g2maxsEffect[2];
  7455. if (modelptr->g2maxs[2] > modelptr->g2maxs2[2])
  7456. {
  7457. modelptr->g2maxs[2] = modelptr->g2maxs2[2];
  7458. done++;
  7459. }
  7460. }
  7461. else
  7462. {
  7463. modelptr->g2maxs[2] -= modelptr->g2maxsEffect[2];
  7464. if (modelptr->g2maxs[2] < modelptr->g2maxs2[2])
  7465. {
  7466. modelptr->g2maxs[2] = modelptr->g2maxs2[2];
  7467. done++;
  7468. }
  7469. }
  7470. }
  7471. // transition the x,y,z min
  7472. if (modelptr->g2mins[0] == modelptr->g2mins2[0])
  7473. {
  7474. done++;
  7475. }
  7476. else
  7477. {
  7478. if (modelptr->g2mins[0] < modelptr->g2mins2[0])
  7479. {
  7480. modelptr->g2mins[0] += modelptr->g2minsEffect[0];
  7481. if (modelptr->g2mins[0] > modelptr->g2mins2[0])
  7482. {
  7483. modelptr->g2mins[0] = modelptr->g2mins2[0];
  7484. done++;
  7485. }
  7486. }
  7487. else
  7488. {
  7489. modelptr->g2mins[0] -= modelptr->g2minsEffect[0];
  7490. if (modelptr->g2mins[0] < modelptr->g2mins2[0])
  7491. {
  7492. modelptr->g2mins[0] = modelptr->g2mins2[0];
  7493. done++;
  7494. }
  7495. }
  7496. }
  7497. //y
  7498. if (modelptr->g2mins[1] == modelptr->g2mins2[1])
  7499. {
  7500. done++;
  7501. }
  7502. else
  7503. {
  7504. if (modelptr->g2mins[1] < modelptr->g2mins2[1])
  7505. {
  7506. modelptr->g2mins[1] += modelptr->g2minsEffect[1];
  7507. if (modelptr->g2mins[1] > modelptr->g2mins2[1])
  7508. {
  7509. modelptr->g2mins[1] = modelptr->g2mins2[1];
  7510. done++;
  7511. }
  7512. }
  7513. else
  7514. {
  7515. modelptr->g2mins[1] -= modelptr->g2minsEffect[1];
  7516. if (modelptr->g2mins[1] < modelptr->g2mins2[1])
  7517. {
  7518. modelptr->g2mins[1] = modelptr->g2mins2[1];
  7519. done++;
  7520. }
  7521. }
  7522. }
  7523. //z
  7524. if (modelptr->g2mins[2] == modelptr->g2mins2[2])
  7525. {
  7526. done++;
  7527. }
  7528. else
  7529. {
  7530. if (modelptr->g2mins[2] < modelptr->g2mins2[2])
  7531. {
  7532. modelptr->g2mins[2] += modelptr->g2minsEffect[2];
  7533. if (modelptr->g2mins[2] > modelptr->g2mins2[2])
  7534. {
  7535. modelptr->g2mins[2] = modelptr->g2mins2[2];
  7536. done++;
  7537. }
  7538. }
  7539. else
  7540. {
  7541. modelptr->g2mins[2] -= modelptr->g2minsEffect[2];
  7542. if (modelptr->g2mins[2] < modelptr->g2mins2[2])
  7543. {
  7544. modelptr->g2mins[2] = modelptr->g2mins2[2];
  7545. done++;
  7546. }
  7547. }
  7548. }
  7549. //fovx
  7550. if (modelptr->fov_x == modelptr->fov_x2)
  7551. {
  7552. done++;
  7553. }
  7554. else
  7555. {
  7556. if (modelptr->fov_x < modelptr->fov_x2)
  7557. {
  7558. modelptr->fov_x += modelptr->fov_Effectx;
  7559. if (modelptr->fov_x > modelptr->fov_x2)
  7560. {
  7561. modelptr->fov_x = modelptr->fov_x2;
  7562. done++;
  7563. }
  7564. }
  7565. else
  7566. {
  7567. modelptr->fov_x -= modelptr->fov_Effectx;
  7568. if (modelptr->fov_x < modelptr->fov_x2)
  7569. {
  7570. modelptr->fov_x = modelptr->fov_x2;
  7571. done++;
  7572. }
  7573. }
  7574. }
  7575. //fovy
  7576. if (modelptr->fov_y == modelptr->fov_y2)
  7577. {
  7578. done++;
  7579. }
  7580. else
  7581. {
  7582. if (modelptr->fov_y < modelptr->fov_y2)
  7583. {
  7584. modelptr->fov_y += modelptr->fov_Effecty;
  7585. if (modelptr->fov_y > modelptr->fov_y2)
  7586. {
  7587. modelptr->fov_y = modelptr->fov_y2;
  7588. done++;
  7589. }
  7590. }
  7591. else
  7592. {
  7593. modelptr->fov_y -= modelptr->fov_Effecty;
  7594. if (modelptr->fov_y < modelptr->fov_y2)
  7595. {
  7596. modelptr->fov_y = modelptr->fov_y2;
  7597. done++;
  7598. }
  7599. }
  7600. }
  7601. if (done == 5)
  7602. {
  7603. item->window.flags &= ~WINDOW_INTRANSITIONMODEL;
  7604. }
  7605. }
  7606. }
  7607. }
  7608. #endif
  7609. //JLF end transition stuff for models
  7610. if (item->window.ownerDrawFlags && DC->ownerDrawVisible)
  7611. {
  7612. if (!DC->ownerDrawVisible(item->window.ownerDrawFlags))
  7613. {
  7614. item->window.flags &= ~WINDOW_VISIBLE;
  7615. }
  7616. else
  7617. {
  7618. item->window.flags |= WINDOW_VISIBLE;
  7619. }
  7620. }
  7621. if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE))
  7622. {
  7623. if (!Item_EnableShowViaCvar(item, CVAR_SHOW))
  7624. {
  7625. return qfalse;
  7626. }
  7627. }
  7628. if (item->window.flags & WINDOW_TIMEDVISIBLE)
  7629. {
  7630. }
  7631. if (!(item->window.flags & WINDOW_VISIBLE))
  7632. {
  7633. return qfalse;
  7634. }
  7635. if (!bDraw)
  7636. {
  7637. return qtrue;
  7638. }
  7639. //okay to paint
  7640. /*
  7641. //JLFMOUSE
  7642. #ifndef _XBOX
  7643. if (item->window.flags & WINDOW_MOUSEOVER)
  7644. #else
  7645. if (item->window.flags & WINDOW_HASFOCUS)
  7646. #endif
  7647. {
  7648. if (item->descText && !Display_KeyBindPending())
  7649. {
  7650. // Make DOUBLY sure that this item should have desctext.
  7651. #ifndef _XBOX
  7652. // NOTE : we can't just check the mouse position on this, what if we TABBED
  7653. // to the current menu item -- in that case our mouse isn't over the item.
  7654. // Removing the WINDOW_MOUSEOVER flag just prevents the item's OnExit script from running
  7655. // if (!Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
  7656. // { // It isn't something that should, because it isn't live anymore.
  7657. // item->window.flags &= ~WINDOW_MOUSEOVER;
  7658. // }
  7659. // else
  7660. #endif
  7661. //END JLFMOUSE
  7662. // items can be enabled and disabled based on cvars
  7663. if( !(item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) )
  7664. { // Draw the desctext
  7665. const char *textPtr = item->descText;
  7666. if (*textPtr == '@') // string reference
  7667. {
  7668. textPtr = SE_GetString( &textPtr[1] );
  7669. }
  7670. vec4_t color = {1, 1, 1, 1};
  7671. Item_TextColor(item, &color);
  7672. float fDescScale = parent->descScale ? parent->descScale : 1;
  7673. float fDescScaleCopy = fDescScale;
  7674. while (1)
  7675. {
  7676. // FIXME - add some type of parameter in the menu file like descfont to specify the font for the descriptions for this menu.
  7677. textWidth = DC->textWidth(textPtr, fDescScale, 4); // item->font);
  7678. if (parent->descAlignment == ITEM_ALIGN_RIGHT)
  7679. {
  7680. xPos = parent->descX - textWidth; // Right justify
  7681. }
  7682. else if (parent->descAlignment == ITEM_ALIGN_CENTER)
  7683. {
  7684. xPos = parent->descX - (textWidth/2); // Center justify
  7685. }
  7686. else // Left justify
  7687. {
  7688. xPos = parent->descX;
  7689. }
  7690. if (parent->descAlignment == ITEM_ALIGN_CENTER)
  7691. {
  7692. // only this one will auto-shrink the scale until we eventually fit...
  7693. //
  7694. if (xPos + textWidth > (SCREEN_WIDTH-4)) {
  7695. fDescScale -= 0.001f;
  7696. continue;
  7697. }
  7698. }
  7699. // Try to adjust it's y placement if the scale has changed...
  7700. //
  7701. int iYadj = 0;
  7702. if (fDescScale != fDescScaleCopy)
  7703. {
  7704. int iOriginalTextHeight = DC->textHeight(textPtr, fDescScaleCopy, uiInfo.uiDC.Assets.qhMediumFont);
  7705. iYadj = iOriginalTextHeight - DC->textHeight(textPtr, fDescScale, uiInfo.uiDC.Assets.qhMediumFont);
  7706. }
  7707. // FIXME - add some type of parameter in the menu file like descfont to specify the font for the descriptions for this menu.
  7708. DC->drawText(xPos, parent->descY + iYadj, fDescScale, parent->descColor, textPtr, 0, parent->descTextStyle, 4); //item->font);
  7709. break;
  7710. }
  7711. }
  7712. }
  7713. }
  7714. */
  7715. // paint the rect first..
  7716. Window_Paint(&item->window, parent->fadeAmount , parent->fadeClamp, parent->fadeCycle);
  7717. // Print a box showing the extents of the rectangle, when in debug mode
  7718. if (uis.debugMode)
  7719. {
  7720. vec4_t color;
  7721. color[1] = color[3] = 1;
  7722. color[0] = color[2] = 0;
  7723. DC->drawRect(
  7724. item->window.rect.x,
  7725. item->window.rect.y,
  7726. item->window.rect.w,
  7727. item->window.rect.h,
  7728. 1,
  7729. color);
  7730. }
  7731. //DC->drawRect(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, 1, red);
  7732. switch (item->type)
  7733. {
  7734. case ITEM_TYPE_OWNERDRAW:
  7735. Item_OwnerDraw_Paint(item);
  7736. break;
  7737. case ITEM_TYPE_TEXT:
  7738. case ITEM_TYPE_BUTTON:
  7739. Item_Text_Paint(item);
  7740. break;
  7741. case ITEM_TYPE_RADIOBUTTON:
  7742. break;
  7743. case ITEM_TYPE_CHECKBOX:
  7744. break;
  7745. case ITEM_TYPE_EDITFIELD:
  7746. case ITEM_TYPE_NUMERICFIELD:
  7747. Item_TextField_Paint(item);
  7748. break;
  7749. case ITEM_TYPE_COMBO:
  7750. break;
  7751. case ITEM_TYPE_LISTBOX:
  7752. Item_ListBox_Paint(item);
  7753. break;
  7754. case ITEM_TYPE_TEXTSCROLL:
  7755. Item_TextScroll_Paint ( item );
  7756. break;
  7757. case ITEM_TYPE_MODEL:
  7758. Item_Model_Paint(item);
  7759. break;
  7760. case ITEM_TYPE_YESNO:
  7761. Item_YesNo_Paint(item);
  7762. break;
  7763. case ITEM_TYPE_MULTI:
  7764. Item_Multi_Paint(item);
  7765. break;
  7766. case ITEM_TYPE_BIND:
  7767. Item_Bind_Paint(item);
  7768. break;
  7769. case ITEM_TYPE_SLIDER:
  7770. Item_Slider_Paint(item);
  7771. break;
  7772. default:
  7773. break;
  7774. }
  7775. return qtrue;
  7776. }
  7777. /*
  7778. =================
  7779. LerpColor
  7780. =================
  7781. */
  7782. void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t)
  7783. {
  7784. int i;
  7785. // lerp and clamp each component
  7786. for (i=0; i<4; i++)
  7787. {
  7788. c[i] = a[i] + t*(b[i]-a[i]);
  7789. if (c[i] < 0)
  7790. {
  7791. c[i] = 0;
  7792. }
  7793. else if (c[i] > 1.0)
  7794. {
  7795. c[i] = 1.0;
  7796. }
  7797. }
  7798. }
  7799. /*
  7800. =================
  7801. Fade
  7802. =================
  7803. */
  7804. void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount)
  7805. {
  7806. if (*flags & (WINDOW_FADINGOUT | WINDOW_FADINGIN))
  7807. {
  7808. if (DC->realTime > *nextTime)
  7809. {
  7810. *nextTime = DC->realTime + offsetTime;
  7811. if (*flags & WINDOW_FADINGOUT)
  7812. {
  7813. *f -= fadeAmount;
  7814. if (bFlags && *f <= 0.0)
  7815. {
  7816. *flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE);
  7817. }
  7818. }
  7819. else
  7820. {
  7821. *f += fadeAmount;
  7822. if (*f >= clamp)
  7823. {
  7824. *f = clamp;
  7825. if (bFlags)
  7826. {
  7827. *flags &= ~WINDOW_FADINGIN;
  7828. }
  7829. }
  7830. }
  7831. }
  7832. }
  7833. }
  7834. /*
  7835. =================
  7836. GradientBar_Paint
  7837. =================
  7838. */
  7839. void GradientBar_Paint(rectDef_t *rect, vec4_t color)
  7840. {
  7841. // gradient bar takes two paints
  7842. DC->setColor( color );
  7843. DC->drawHandlePic(rect->x, rect->y, rect->w, rect->h, DC->Assets.gradientBar);
  7844. DC->setColor( NULL );
  7845. }
  7846. /*
  7847. =================
  7848. Window_Paint
  7849. =================
  7850. */
  7851. void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle)
  7852. {
  7853. //float bordersize = 0;
  7854. vec4_t color;
  7855. rectDef_t fillRect = w->rect;
  7856. if (uis.debugMode)
  7857. {
  7858. color[0] = color[1] = color[2] = color[3] = 1;
  7859. DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color);
  7860. }
  7861. if (w == NULL || (w->style == 0 && w->border == 0))
  7862. {
  7863. return;
  7864. }
  7865. if (w->border != 0)
  7866. {
  7867. fillRect.x += w->borderSize;
  7868. fillRect.y += w->borderSize;
  7869. fillRect.w -= w->borderSize + 1;
  7870. fillRect.h -= w->borderSize + 1;
  7871. }
  7872. if (w->style == WINDOW_STYLE_FILLED)
  7873. {
  7874. // box, but possible a shader that needs filled
  7875. if (w->background)
  7876. {
  7877. Fade(&w->flags, &w->backColor[3], fadeClamp, &w->nextTime, fadeCycle, qtrue, fadeAmount);
  7878. DC->setColor(w->backColor);
  7879. DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
  7880. DC->setColor(NULL);
  7881. }
  7882. else
  7883. {
  7884. DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->backColor);
  7885. }
  7886. }
  7887. else if (w->style == WINDOW_STYLE_GRADIENT)
  7888. {
  7889. GradientBar_Paint(&fillRect, w->backColor);
  7890. // gradient bar
  7891. }
  7892. else if (w->style == WINDOW_STYLE_SHADER)
  7893. {
  7894. if (w->flags & WINDOW_PLAYERCOLOR)
  7895. {
  7896. vec4_t color;
  7897. color[0] = ui_char_color_red.integer/255.0f;
  7898. color[1] = ui_char_color_green.integer/255.0f;
  7899. color[2] = ui_char_color_blue.integer/255.0f;
  7900. color[3] = 1;
  7901. ui.R_SetColor(color);
  7902. }
  7903. else if (w->flags & WINDOW_FORECOLORSET)
  7904. {
  7905. DC->setColor(w->foreColor);
  7906. }
  7907. int rectw = fillRect.w;
  7908. #ifdef _XBOX
  7909. if(glw_state->isWidescreen && cls.state == CA_ACTIVE && !(Menus_AnyFullScreenVisible()))
  7910. {
  7911. if(strcmp(w->name, "screenOverlay") == 0)
  7912. rectw = 720;
  7913. if(strcmp(w->name, "imageboxFill") == 0)
  7914. fillRect.x += 40;
  7915. if(strcmp(w->name, "lineLeft") == 0)
  7916. fillRect.x += 40;
  7917. if(strcmp(w->name, "lineRight") == 0)
  7918. fillRect.x += 40;
  7919. if(strcmp(w->name, "lineTop") == 0)
  7920. fillRect.x += 40;
  7921. if(strcmp(w->name, "lineTitle") == 0)
  7922. fillRect.x += 40;
  7923. if(strcmp(w->name, "lineBottom") == 0)
  7924. fillRect.x += 40;
  7925. if(strcmp(w->name, "acceptButton") == 0)
  7926. fillRect.x += 40;
  7927. }
  7928. #endif
  7929. DC->drawHandlePic(fillRect.x, fillRect.y, rectw, fillRect.h, w->background);
  7930. DC->setColor(NULL);
  7931. }
  7932. if (w->border == WINDOW_BORDER_FULL)
  7933. {
  7934. // full
  7935. // HACK HACK HACK
  7936. if (w->style == WINDOW_STYLE_TEAMCOLOR)
  7937. {
  7938. if (color[0] > 0)
  7939. {
  7940. // red
  7941. color[0] = 1;
  7942. color[1] = color[2] = .5;
  7943. }
  7944. else
  7945. {
  7946. color[2] = 1;
  7947. color[0] = color[1] = .5;
  7948. }
  7949. color[3] = 1;
  7950. DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color);
  7951. }
  7952. else
  7953. {
  7954. int rectw = w->rect.w;
  7955. #ifdef _XBOX
  7956. if(glw_state->isWidescreen)
  7957. {
  7958. if(strcmp(w->name, "missionfailed_menu") == 0)
  7959. rectw = 720;
  7960. }
  7961. #endif
  7962. DC->drawRect(w->rect.x, w->rect.y, rectw, w->rect.h, w->borderSize, w->borderColor);
  7963. }
  7964. }
  7965. else if (w->border == WINDOW_BORDER_HORZ)
  7966. {
  7967. // top/bottom
  7968. DC->setColor(w->borderColor);
  7969. DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
  7970. DC->setColor( NULL );
  7971. }
  7972. else if (w->border == WINDOW_BORDER_VERT)
  7973. {
  7974. // left right
  7975. DC->setColor(w->borderColor);
  7976. DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
  7977. DC->setColor( NULL );
  7978. }
  7979. else if (w->border == WINDOW_BORDER_KCGRADIENT)
  7980. {
  7981. // this is just two gradient bars along each horz edge
  7982. rectDef_t r = w->rect;
  7983. r.h = w->borderSize;
  7984. GradientBar_Paint(&r, w->borderColor);
  7985. r.y = w->rect.y + w->rect.h - 1;
  7986. GradientBar_Paint(&r, w->borderColor);
  7987. }
  7988. }
  7989. /*
  7990. =================
  7991. Display_KeyBindPending
  7992. =================
  7993. */
  7994. qboolean Display_KeyBindPending(void)
  7995. {
  7996. return g_waitingForKey;
  7997. }
  7998. /*
  7999. =================
  8000. ToWindowCoords
  8001. =================
  8002. */
  8003. void ToWindowCoords(float *x, float *y, windowDef_t *window)
  8004. {
  8005. if (window->border != 0)
  8006. {
  8007. *x += window->borderSize;
  8008. *y += window->borderSize;
  8009. }
  8010. *x += window->rect.x;
  8011. *y += window->rect.y;
  8012. }
  8013. /*
  8014. =================
  8015. Item_Text_AutoWrapped_Paint
  8016. =================
  8017. */
  8018. void Item_Text_AutoWrapped_Paint(itemDef_t *item)
  8019. {
  8020. char text[1024];
  8021. const char *p, *textPtr, *newLinePtr;
  8022. char buff[1024];
  8023. int height, len, textWidth, newLine, newLineWidth;
  8024. float y;
  8025. vec4_t color;
  8026. textWidth = 0;
  8027. newLinePtr = NULL;
  8028. if (item->text == NULL)
  8029. {
  8030. if (item->cvar == NULL)
  8031. {
  8032. return;
  8033. }
  8034. else
  8035. {
  8036. DC->getCVarString(item->cvar, text, sizeof(text));
  8037. textPtr = text;
  8038. }
  8039. }
  8040. else
  8041. {
  8042. textPtr = item->text;
  8043. }
  8044. if (*textPtr == '@') // string reference
  8045. {
  8046. textPtr = SE_GetString( &textPtr[1] );
  8047. }
  8048. if (*textPtr == '\0')
  8049. {
  8050. return;
  8051. }
  8052. Item_TextColor(item, &color);
  8053. //Item_SetTextExtents(item, &width, &height, textPtr);
  8054. if (item->value == 0)
  8055. {
  8056. item->value = (int)(0.5 + (float)DC->textWidth(textPtr, item->textscale, item->font) / item->window.rect.w);
  8057. }
  8058. height = DC->textHeight(textPtr, item->textscale, item->font);
  8059. item->special = 0;
  8060. y = item->textaligny;
  8061. len = 0;
  8062. buff[0] = '\0';
  8063. newLine = 0;
  8064. newLineWidth = 0;
  8065. p = textPtr;
  8066. int line = 1;
  8067. while (1) //findmeste (this will break widechar languages)!
  8068. {
  8069. if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0')
  8070. {
  8071. newLine = len;
  8072. newLinePtr = p+1;
  8073. newLineWidth = textWidth;
  8074. }
  8075. textWidth = DC->textWidth(buff, item->textscale, 0);
  8076. if ( (newLine && textWidth >= item->window.rect.w - item->textalignx) || *p == '\n' || *p == '\0')
  8077. {
  8078. if (line > item->cursorPos) //scroll
  8079. {
  8080. if (len)
  8081. {
  8082. if (item->textalignment == ITEM_ALIGN_LEFT)
  8083. {
  8084. item->textRect.x = item->textalignx;
  8085. }
  8086. else if (item->textalignment == ITEM_ALIGN_RIGHT)
  8087. {
  8088. item->textRect.x = item->textalignx - newLineWidth;
  8089. }
  8090. else if (item->textalignment == ITEM_ALIGN_CENTER)
  8091. {
  8092. item->textRect.x = item->textalignx - newLineWidth / 2;
  8093. }
  8094. item->textRect.y = y;
  8095. ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
  8096. //
  8097. buff[newLine] = '\0';
  8098. if ( *p && y + height + 4 > item->window.rect.h - height)
  8099. {
  8100. item->special = 1;
  8101. strcat(buff,"...");//uhh, let's render some ellipses
  8102. }
  8103. DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, item->textStyle, item->font);
  8104. }
  8105. y += height + 4;
  8106. if ( y > item->window.rect.h - height)
  8107. {//reached the bottom of the box, so stop
  8108. break;
  8109. }
  8110. len = 0;
  8111. }
  8112. else
  8113. {
  8114. strcpy(buff,"...");
  8115. len = 3;
  8116. }
  8117. if (*p == '\0')
  8118. { //end of string
  8119. break;
  8120. }
  8121. p = newLinePtr;
  8122. newLine = 0;
  8123. newLineWidth = 0;
  8124. line++;
  8125. }
  8126. buff[len++] = *p++;
  8127. buff[len] = '\0';
  8128. }
  8129. item->textRect = item->window.rect;
  8130. }
  8131. /*
  8132. =================
  8133. Rect_ContainsPoint
  8134. =================
  8135. */
  8136. static qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y)
  8137. {
  8138. //JLF ignore mouse pointer location
  8139. // return true;
  8140. // END JLF
  8141. if (rect)
  8142. {
  8143. // if ((x > rect->x) && (x < (rect->x + rect->w)) && (y > rect->y) && (y < (rect->y + rect->h)))
  8144. if ((x > rect->x) && (x < (rect->x + rect->w)))
  8145. {
  8146. if ((y > rect->y) && (y < (rect->y + rect->h)))
  8147. {
  8148. return qtrue;
  8149. }
  8150. }
  8151. }
  8152. return qfalse;
  8153. }
  8154. qboolean Item_TextScroll_HandleKey ( itemDef_t *item, int key, qboolean down, qboolean force)
  8155. {
  8156. textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
  8157. int max;
  8158. int viewmax;
  8159. if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
  8160. {
  8161. max = Item_TextScroll_MaxScroll(item);
  8162. viewmax = (item->window.rect.h / scrollPtr->lineHeight);
  8163. if ( key == A_CURSOR_UP || key == A_KP_8 )
  8164. {
  8165. scrollPtr->startPos--;
  8166. if (scrollPtr->startPos < 0)
  8167. {
  8168. scrollPtr->startPos = 0;
  8169. }
  8170. return qtrue;
  8171. }
  8172. if ( key == A_CURSOR_DOWN || key == A_KP_2 )
  8173. {
  8174. scrollPtr->startPos++;
  8175. if (scrollPtr->startPos > max)
  8176. {
  8177. scrollPtr->startPos = max;
  8178. }
  8179. return qtrue;
  8180. }
  8181. // mouse hit
  8182. if (key == A_MOUSE1 || key == A_MOUSE2)
  8183. {
  8184. if (item->window.flags & WINDOW_LB_LEFTARROW)
  8185. {
  8186. scrollPtr->startPos--;
  8187. if (scrollPtr->startPos < 0)
  8188. {
  8189. scrollPtr->startPos = 0;
  8190. }
  8191. }
  8192. else if (item->window.flags & WINDOW_LB_RIGHTARROW)
  8193. {
  8194. // one down
  8195. scrollPtr->startPos++;
  8196. if (scrollPtr->startPos > max)
  8197. {
  8198. scrollPtr->startPos = max;
  8199. }
  8200. }
  8201. else if (item->window.flags & WINDOW_LB_PGUP)
  8202. {
  8203. // page up
  8204. scrollPtr->startPos -= viewmax;
  8205. if (scrollPtr->startPos < 0)
  8206. {
  8207. scrollPtr->startPos = 0;
  8208. }
  8209. }
  8210. else if (item->window.flags & WINDOW_LB_PGDN)
  8211. {
  8212. // page down
  8213. scrollPtr->startPos += viewmax;
  8214. if (scrollPtr->startPos > max)
  8215. {
  8216. scrollPtr->startPos = max;
  8217. }
  8218. }
  8219. else if (item->window.flags & WINDOW_LB_THUMB)
  8220. {
  8221. // Display_SetCaptureItem(item);
  8222. }
  8223. return qtrue;
  8224. }
  8225. if ( key == A_HOME || key == A_KP_7)
  8226. {
  8227. // home
  8228. scrollPtr->startPos = 0;
  8229. return qtrue;
  8230. }
  8231. if ( key == A_END || key == A_KP_1)
  8232. {
  8233. // end
  8234. scrollPtr->startPos = max;
  8235. return qtrue;
  8236. }
  8237. if (key == A_PAGE_UP || key == A_KP_9 )
  8238. {
  8239. scrollPtr->startPos -= viewmax;
  8240. if (scrollPtr->startPos < 0)
  8241. {
  8242. scrollPtr->startPos = 0;
  8243. }
  8244. return qtrue;
  8245. }
  8246. if ( key == A_PAGE_DOWN || key == A_KP_3 )
  8247. {
  8248. scrollPtr->startPos += viewmax;
  8249. if (scrollPtr->startPos > max)
  8250. {
  8251. scrollPtr->startPos = max;
  8252. }
  8253. return qtrue;
  8254. }
  8255. }
  8256. return qfalse;
  8257. }
  8258. /*
  8259. =================
  8260. Item_ListBox_MaxScroll
  8261. =================
  8262. */
  8263. int Item_ListBox_MaxScroll(itemDef_t *item)
  8264. {
  8265. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  8266. int count = DC->feederCount(item->special);
  8267. int max;
  8268. if (item->window.flags & WINDOW_HORIZONTAL)
  8269. {
  8270. max = count - (item->window.rect.w / listPtr->elementWidth) + 1;
  8271. }
  8272. else
  8273. {
  8274. max = count - (item->window.rect.h / listPtr->elementHeight) + 1;
  8275. }
  8276. if (max < 0)
  8277. {
  8278. return 0;
  8279. }
  8280. return max;
  8281. }
  8282. /*
  8283. =================
  8284. Item_ListBox_ThumbPosition
  8285. =================
  8286. */
  8287. int Item_ListBox_ThumbPosition(itemDef_t *item)
  8288. {
  8289. float max, pos, size;
  8290. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  8291. max = Item_ListBox_MaxScroll(item);
  8292. if (item->window.flags & WINDOW_HORIZONTAL) {
  8293. size = item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2;
  8294. if (max > 0)
  8295. {
  8296. pos = (size-SCROLLBAR_SIZE) / (float) max;
  8297. }
  8298. else
  8299. {
  8300. pos = 0;
  8301. }
  8302. pos *= listPtr->startPos;
  8303. return item->window.rect.x + 1 + SCROLLBAR_SIZE + pos;
  8304. }
  8305. else
  8306. {
  8307. size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2;
  8308. if (max > 0)
  8309. {
  8310. pos = (size-SCROLLBAR_SIZE) / (float) max;
  8311. }
  8312. else
  8313. {
  8314. pos = 0;
  8315. }
  8316. pos *= listPtr->startPos;
  8317. return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos;
  8318. }
  8319. }
  8320. /*
  8321. =================
  8322. Item_ListBox_OverLB
  8323. =================
  8324. */
  8325. int Item_ListBox_OverLB(itemDef_t *item, float x, float y)
  8326. {
  8327. rectDef_t r;
  8328. listBoxDef_t *listPtr;
  8329. int thumbstart;
  8330. int count;
  8331. count = DC->feederCount(item->special);
  8332. listPtr = (listBoxDef_t*)item->typeData;
  8333. if (item->window.flags & WINDOW_HORIZONTAL)
  8334. {
  8335. // check if on left arrow
  8336. r.x = item->window.rect.x;
  8337. r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
  8338. r.h = r.w = SCROLLBAR_SIZE;
  8339. if (Rect_ContainsPoint(&r, x, y))
  8340. {
  8341. return WINDOW_LB_LEFTARROW;
  8342. }
  8343. // check if on right arrow
  8344. r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
  8345. if (Rect_ContainsPoint(&r, x, y))
  8346. {
  8347. return WINDOW_LB_RIGHTARROW;
  8348. }
  8349. // check if on thumb
  8350. thumbstart = Item_ListBox_ThumbPosition(item);
  8351. r.x = thumbstart;
  8352. if (Rect_ContainsPoint(&r, x, y))
  8353. {
  8354. return WINDOW_LB_THUMB;
  8355. }
  8356. r.x = item->window.rect.x + SCROLLBAR_SIZE;
  8357. r.w = thumbstart - r.x;
  8358. if (Rect_ContainsPoint(&r, x, y))
  8359. {
  8360. return WINDOW_LB_PGUP;
  8361. }
  8362. r.x = thumbstart + SCROLLBAR_SIZE;
  8363. r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
  8364. if (Rect_ContainsPoint(&r, x, y))
  8365. {
  8366. return WINDOW_LB_PGDN;
  8367. }
  8368. }
  8369. else
  8370. {
  8371. r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
  8372. r.y = item->window.rect.y;
  8373. r.h = r.w = SCROLLBAR_SIZE;
  8374. if (Rect_ContainsPoint(&r, x, y))
  8375. {
  8376. return WINDOW_LB_LEFTARROW;
  8377. }
  8378. r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
  8379. if (Rect_ContainsPoint(&r, x, y))
  8380. {
  8381. return WINDOW_LB_RIGHTARROW;
  8382. }
  8383. thumbstart = Item_ListBox_ThumbPosition(item);
  8384. r.y = thumbstart;
  8385. if (Rect_ContainsPoint(&r, x, y))
  8386. {
  8387. return WINDOW_LB_THUMB;
  8388. }
  8389. r.y = item->window.rect.y + SCROLLBAR_SIZE;
  8390. r.h = thumbstart - r.y;
  8391. if (Rect_ContainsPoint(&r, x, y))
  8392. {
  8393. return WINDOW_LB_PGUP;
  8394. }
  8395. r.y = thumbstart + SCROLLBAR_SIZE;
  8396. r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
  8397. if (Rect_ContainsPoint(&r, x, y))
  8398. {
  8399. return WINDOW_LB_PGDN;
  8400. }
  8401. }
  8402. return 0;
  8403. }
  8404. /*
  8405. =================
  8406. Item_ListBox_MouseEnter
  8407. =================
  8408. */
  8409. void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y)
  8410. {
  8411. rectDef_t r;
  8412. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  8413. item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
  8414. item->window.flags |= Item_ListBox_OverLB(item, x, y);
  8415. if (item->window.flags & WINDOW_HORIZONTAL)
  8416. {
  8417. if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN)))
  8418. {
  8419. // check for selection hit as we have exausted buttons and thumb
  8420. if (listPtr->elementStyle == LISTBOX_IMAGE)
  8421. {
  8422. r.x = item->window.rect.x;
  8423. r.y = item->window.rect.y;
  8424. r.h = item->window.rect.h - SCROLLBAR_SIZE;
  8425. r.w = item->window.rect.w - listPtr->drawPadding;
  8426. if (Rect_ContainsPoint(&r, x, y))
  8427. {
  8428. listPtr->cursorPos = (int)((x - r.x) / listPtr->elementWidth) + listPtr->startPos;
  8429. if (listPtr->cursorPos > listPtr->endPos)
  8430. {
  8431. listPtr->cursorPos = listPtr->endPos;
  8432. }
  8433. }
  8434. }
  8435. else
  8436. {
  8437. // text hit..
  8438. }
  8439. }
  8440. }
  8441. else if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN)))
  8442. {
  8443. r.x = item->window.rect.x;
  8444. r.y = item->window.rect.y;
  8445. r.w = item->window.rect.w - SCROLLBAR_SIZE;
  8446. r.h = item->window.rect.h - listPtr->drawPadding;
  8447. if (Rect_ContainsPoint(&r, x, y))
  8448. {
  8449. listPtr->cursorPos = (int)((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos;
  8450. if (listPtr->cursorPos > listPtr->endPos)
  8451. {
  8452. listPtr->cursorPos = listPtr->endPos;
  8453. }
  8454. }
  8455. }
  8456. }
  8457. /*
  8458. =================
  8459. Item_MouseEnter
  8460. =================
  8461. */
  8462. void Item_MouseEnter(itemDef_t *item, float x, float y)
  8463. {
  8464. rectDef_t r;
  8465. //JLFMOUSE
  8466. if (item)
  8467. {
  8468. r = item->textRect;
  8469. // r.y -= r.h; // NOt sure why this is here, but I commented it out.
  8470. // in the text rect?
  8471. // items can be enabled and disabled based on cvars
  8472. if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
  8473. {
  8474. return;
  8475. }
  8476. if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
  8477. {
  8478. return;
  8479. }
  8480. //JLFMOUSE
  8481. #ifndef _XBOX
  8482. if (Rect_ContainsPoint(&r, x, y))
  8483. #else
  8484. if (item->flags & WINDOW_HASFOCUS)
  8485. #endif
  8486. {
  8487. if (!(item->window.flags & WINDOW_MOUSEOVERTEXT))
  8488. {
  8489. // Item_RunScript(item, item->mouseEnterText);
  8490. item->window.flags |= WINDOW_MOUSEOVERTEXT;
  8491. }
  8492. if (!(item->window.flags & WINDOW_MOUSEOVER))
  8493. {
  8494. // Item_RunScript(item, item->mouseEnter);
  8495. item->window.flags |= WINDOW_MOUSEOVER;
  8496. }
  8497. }
  8498. else
  8499. {
  8500. // not in the text rect
  8501. if (item->window.flags & WINDOW_MOUSEOVERTEXT)
  8502. {
  8503. // if we were
  8504. // Item_RunScript(item, item->mouseExitText);
  8505. item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
  8506. }
  8507. if (!(item->window.flags & WINDOW_MOUSEOVER))
  8508. {
  8509. // Item_RunScript(item, item->mouseEnter);
  8510. item->window.flags |= WINDOW_MOUSEOVER;
  8511. }
  8512. if (item->type == ITEM_TYPE_LISTBOX)
  8513. {
  8514. Item_ListBox_MouseEnter(item, x, y);
  8515. }
  8516. else if ( item->type == ITEM_TYPE_TEXTSCROLL )
  8517. {
  8518. Item_TextScroll_MouseEnter ( item, x, y );
  8519. }
  8520. }
  8521. }
  8522. }
  8523. /*
  8524. =================
  8525. Item_SetFocus
  8526. =================
  8527. */
  8528. // will optionaly set focus to this item
  8529. qboolean Item_SetFocus(itemDef_t *item, float x, float y)
  8530. {
  8531. int i;
  8532. itemDef_t *oldFocus;
  8533. sfxHandle_t *sfx = &DC->Assets.itemFocusSound;
  8534. qboolean playSound = qfalse;
  8535. #ifdef _IMMERSION
  8536. ffHandle_t *ff = &DC->Assets.itemFocusForce;
  8537. qboolean playForce = qfalse;
  8538. #endif // _IMMERSION
  8539. // sanity check, non-null, not a decoration and does not already have the focus
  8540. if (item == NULL || item->window.flags & WINDOW_DECORATION || item->window.flags & WINDOW_HASFOCUS || !(item->window.flags & WINDOW_VISIBLE) || (item->window.flags & WINDOW_INACTIVE))
  8541. {
  8542. return qfalse;
  8543. }
  8544. menuDef_t *parent = (menuDef_t*)item->parent;
  8545. // items can be enabled and disabled based on cvars
  8546. if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
  8547. {
  8548. return qfalse;
  8549. }
  8550. if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
  8551. {
  8552. return qfalse;
  8553. }
  8554. oldFocus = Menu_ClearFocus((menuDef_t *) item->parent);
  8555. item->window.flags |= WINDOW_HASFOCUS;
  8556. if (item->onFocus)
  8557. {
  8558. Item_RunScript(item, item->onFocus);
  8559. }
  8560. if (item->focusSound)
  8561. {
  8562. sfx = &item->focusSound;
  8563. }
  8564. playSound = qtrue;
  8565. if (playSound && sfx)
  8566. {
  8567. DC->startLocalSound( *sfx, CHAN_LOCAL_SOUND );
  8568. }
  8569. for (i = 0; i < parent->itemCount; i++)
  8570. {
  8571. if (parent->items[i] == item)
  8572. {
  8573. parent->cursorItem = i;
  8574. break;
  8575. }
  8576. }
  8577. return qtrue;
  8578. }
  8579. /*
  8580. =================
  8581. IsVisible
  8582. =================
  8583. */
  8584. qboolean IsVisible(int flags)
  8585. {
  8586. return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT));
  8587. }
  8588. /*
  8589. =================
  8590. Item_MouseLeave
  8591. =================
  8592. */
  8593. void Item_MouseLeave(itemDef_t *item)
  8594. {
  8595. if (item)
  8596. {
  8597. if (item->window.flags & WINDOW_MOUSEOVERTEXT)
  8598. {
  8599. // Item_RunScript(item, item->mouseExitText);
  8600. item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
  8601. }
  8602. // Item_RunScript(item, item->mouseExit);
  8603. item->window.flags &= ~(WINDOW_LB_RIGHTARROW | WINDOW_LB_LEFTARROW);
  8604. }
  8605. }
  8606. /*
  8607. =================
  8608. Item_SetMouseOver
  8609. =================
  8610. */
  8611. void Item_SetMouseOver(itemDef_t *item, qboolean focus)
  8612. {
  8613. if (item)
  8614. {
  8615. if (focus)
  8616. {
  8617. item->window.flags |= WINDOW_MOUSEOVER;
  8618. }
  8619. else
  8620. {
  8621. item->window.flags &= ~WINDOW_MOUSEOVER;
  8622. }
  8623. }
  8624. }
  8625. extern int gScrollDelta;
  8626. /*
  8627. =================
  8628. Menu_HandleMouseMove
  8629. =================
  8630. */
  8631. void Menu_HandleMouseMove(menuDef_t *menu, float x, float y)
  8632. {
  8633. //JLF used exclusively for textscroll items
  8634. #ifdef _XBOX
  8635. if (!menu)
  8636. return;
  8637. itemDef_t * item;
  8638. int i, itemCount;
  8639. itemCount = menu->itemCount;
  8640. textScrollDef_t *scrollPtr;
  8641. if (menu->window.flags && WINDOW_HASFOCUS)
  8642. {
  8643. for( i = 0; i < itemCount ;i++)
  8644. {
  8645. item = menu->items[i];
  8646. if (item->type != ITEM_TYPE_TEXTSCROLL)
  8647. continue;
  8648. if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
  8649. continue;
  8650. if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
  8651. continue;
  8652. if ( !(item->window.flags & WINDOW_VISIBLE) )
  8653. continue;
  8654. scrollPtr = (textScrollDef_t*)item->typeData;
  8655. if (gScrollDelta >0)
  8656. {
  8657. if (scrollPtr->endPos < scrollPtr->iLineCount-1)
  8658. {
  8659. scrollPtr->startPos+= gScrollDelta;
  8660. }
  8661. }
  8662. else if (gScrollDelta <0)
  8663. {
  8664. if(scrollPtr->startPos > 0)
  8665. {
  8666. scrollPtr->startPos+=gScrollDelta;
  8667. }
  8668. }
  8669. if ((scrollPtr->endPos +1 >= scrollPtr->iLineCount) || (scrollPtr->endPos == 0))
  8670. {
  8671. Cvar_Set("ui_downArrow","0");
  8672. }
  8673. else
  8674. {
  8675. Cvar_Set("ui_downArrow","1");
  8676. }
  8677. if (scrollPtr->startPos <= 0)
  8678. {
  8679. Cvar_Set("ui_upArrow","0");
  8680. }
  8681. else
  8682. {
  8683. Cvar_Set("ui_upArrow","1");
  8684. }
  8685. }
  8686. }
  8687. #endif
  8688. return ;
  8689. }
  8690. /*
  8691. =================
  8692. Display_MouseMove
  8693. =================
  8694. */
  8695. qboolean Display_MouseMove(void *p, int x, int y)
  8696. {
  8697. //JLFMOUSE AGAIN I THINK THIS SHOULD BE MOOT
  8698. int i;
  8699. menuDef_t *menu = (menuDef_t *) p;
  8700. if (menu == NULL)
  8701. {
  8702. menu = Menu_GetFocused();
  8703. if (menu)
  8704. {
  8705. if (menu->window.flags & WINDOW_POPUP)
  8706. {
  8707. Menu_HandleMouseMove(menu, x, y);
  8708. return qtrue;
  8709. }
  8710. }
  8711. for (i = 0; i < menuCount; i++)
  8712. {
  8713. Menu_HandleMouseMove(&Menus[i], x, y);
  8714. }
  8715. }
  8716. else
  8717. {
  8718. menu->window.rect.x += x;
  8719. menu->window.rect.y += y;
  8720. Menu_UpdatePosition(menu);
  8721. }
  8722. return qtrue;
  8723. }
  8724. /*
  8725. =================
  8726. Menus_AnyFullScreenVisible
  8727. =================
  8728. */
  8729. qboolean Menus_AnyFullScreenVisible(void)
  8730. {
  8731. int i;
  8732. for (i = 0; i < menuCount; i++)
  8733. {
  8734. if (Menus[i].window.flags & WINDOW_VISIBLE && Menus[i].fullScreen)
  8735. {
  8736. return qtrue;
  8737. }
  8738. }
  8739. return qfalse;
  8740. }
  8741. /*
  8742. =================
  8743. BindingIDFromName
  8744. =================
  8745. */
  8746. int BindingIDFromName(const char *name)
  8747. {
  8748. int i;
  8749. for (i=0; i < g_bindCount; i++)
  8750. {
  8751. if (Q_stricmp(name, g_bindings[i].command) == 0)
  8752. {
  8753. return i;
  8754. }
  8755. }
  8756. return -1;
  8757. }
  8758. /*
  8759. =================
  8760. Controls_SetConfig
  8761. =================
  8762. */
  8763. void Controls_SetConfig(qboolean restart)
  8764. {
  8765. int i;
  8766. // iterate each command, get its numeric binding
  8767. for (i=0; i < g_bindCount; i++)
  8768. {
  8769. if (g_bindings[i].bind1 != -1)
  8770. {
  8771. DC->setBinding( g_bindings[i].bind1, g_bindings[i].command );
  8772. if (g_bindings[i].bind2 != -1)
  8773. DC->setBinding( g_bindings[i].bind2, g_bindings[i].command );
  8774. }
  8775. }
  8776. //if ( s_controls.invertmouse.curvalue )
  8777. // DC->setCVar("m_pitch", va("%f),-fabs( DC->getCVarValue( "m_pitch" ) ) );
  8778. //else
  8779. // trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
  8780. //trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue );
  8781. //trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue );
  8782. //trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue );
  8783. //trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue );
  8784. //trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue );
  8785. //trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue );
  8786. //trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue );
  8787. //
  8788. // DC->executeText(EXEC_APPEND, "in_restart\n");
  8789. // ^--this is bad, it shows the cursor during map load, if you need to, add it as an exec cmd to use_joy or something.
  8790. }
  8791. void Item_Bind_Ungrey(itemDef_t *item)
  8792. {
  8793. menuDef_t *menu;
  8794. int i;
  8795. menu = (menuDef_t *) item->parent;
  8796. for (i=0;i<menu->itemCount;++i)
  8797. {
  8798. if (menu->items[i] == item)
  8799. {
  8800. continue;
  8801. }
  8802. menu->items[i]->window.flags &= ~WINDOW_INACTIVE;
  8803. }
  8804. }
  8805. /*
  8806. =================
  8807. Item_Bind_HandleKey
  8808. =================
  8809. */
  8810. qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down)
  8811. {
  8812. int id;
  8813. int i;
  8814. menuDef_t *menu;
  8815. if (key == A_MOUSE1 && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey)
  8816. {
  8817. if (down)
  8818. {
  8819. g_waitingForKey = qtrue;
  8820. g_bindItem = item;
  8821. // Set all others in the menu to grey
  8822. menu = (menuDef_t *) item->parent;
  8823. for (i=0;i<menu->itemCount;++i)
  8824. {
  8825. if (menu->items[i] == item)
  8826. {
  8827. continue;
  8828. }
  8829. menu->items[i]->window.flags |= WINDOW_INACTIVE;
  8830. }
  8831. }
  8832. return qtrue;
  8833. }
  8834. else if (key == A_ENTER && !g_waitingForKey)
  8835. {
  8836. if (down)
  8837. {
  8838. g_waitingForKey = qtrue;
  8839. g_bindItem = item;
  8840. // Set all others in the menu to grey
  8841. menu = (menuDef_t *) item->parent;
  8842. for (i=0;i<menu->itemCount;++i)
  8843. {
  8844. if (menu->items[i] == item)
  8845. {
  8846. continue;
  8847. }
  8848. menu->items[i]->window.flags |= WINDOW_INACTIVE;
  8849. }
  8850. }
  8851. return qtrue;
  8852. }
  8853. else
  8854. {
  8855. if (!g_waitingForKey || g_bindItem == NULL)
  8856. {
  8857. return qfalse;
  8858. }
  8859. if (key & K_CHAR_FLAG)
  8860. {
  8861. return qtrue;
  8862. }
  8863. switch (key)
  8864. {
  8865. case A_ESCAPE:
  8866. g_waitingForKey = qfalse;
  8867. Item_Bind_Ungrey(item);
  8868. return qtrue;
  8869. case A_BACKSPACE:
  8870. id = BindingIDFromName(item->cvar);
  8871. if (id != -1)
  8872. {
  8873. DC->setBinding( g_bindings[id].bind1, "" );
  8874. DC->setBinding( g_bindings[id].bind2, "" );
  8875. g_bindings[id].bind1 = -1;
  8876. g_bindings[id].bind2 = -1;
  8877. }
  8878. Controls_SetConfig(qtrue);
  8879. g_waitingForKey = qfalse;
  8880. g_bindItem = NULL;
  8881. Item_Bind_Ungrey(item);
  8882. return qtrue;
  8883. break;
  8884. case '`':
  8885. return qtrue;
  8886. }
  8887. }
  8888. // Is the same key being bound to something else?
  8889. if (key != -1)
  8890. {
  8891. for (i=0; i < g_bindCount; i++)
  8892. {
  8893. // The second binding matches the key
  8894. if (g_bindings[i].bind2 == key)
  8895. {
  8896. g_bindings[i].bind2 = -1; // NULL it out
  8897. }
  8898. if (g_bindings[i].bind1 == key)
  8899. {
  8900. g_bindings[i].bind1 = g_bindings[i].bind2;
  8901. g_bindings[i].bind2 = -1;
  8902. }
  8903. }
  8904. }
  8905. id = BindingIDFromName(item->cvar);
  8906. if (id != -1)
  8907. {
  8908. if (key == -1)
  8909. {
  8910. if( g_bindings[id].bind1 != -1 )
  8911. {
  8912. DC->setBinding( g_bindings[id].bind1, "" );
  8913. g_bindings[id].bind1 = -1;
  8914. }
  8915. if( g_bindings[id].bind2 != -1 )
  8916. {
  8917. DC->setBinding( g_bindings[id].bind2, "" );
  8918. g_bindings[id].bind2 = -1;
  8919. }
  8920. }
  8921. else if (g_bindings[id].bind1 == -1)
  8922. {
  8923. g_bindings[id].bind1 = key;
  8924. }
  8925. else if (g_bindings[id].bind1 != key && g_bindings[id].bind2 == -1)
  8926. {
  8927. g_bindings[id].bind2 = key;
  8928. }
  8929. else
  8930. {
  8931. DC->setBinding( g_bindings[id].bind1, "" );
  8932. DC->setBinding( g_bindings[id].bind2, "" );
  8933. g_bindings[id].bind1 = key;
  8934. g_bindings[id].bind2 = -1;
  8935. }
  8936. }
  8937. Controls_SetConfig(qtrue);
  8938. g_waitingForKey = qfalse;
  8939. Item_Bind_Ungrey(item);
  8940. return qtrue;
  8941. }
  8942. /*
  8943. =================
  8944. Menu_SetNextCursorItem
  8945. =================
  8946. */
  8947. itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu)
  8948. {
  8949. qboolean wrapped = qfalse;
  8950. int oldCursor = menu->cursorItem;
  8951. if (menu->cursorItem == -1)
  8952. {
  8953. menu->cursorItem = 0;
  8954. wrapped = qtrue;
  8955. }
  8956. while (menu->cursorItem < menu->itemCount)
  8957. {
  8958. menu->cursorItem++;
  8959. if (menu->cursorItem >= menu->itemCount && !wrapped)
  8960. {
  8961. wrapped = qtrue;
  8962. menu->cursorItem = 0;
  8963. }
  8964. if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory))
  8965. {
  8966. Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
  8967. return menu->items[menu->cursorItem];
  8968. }
  8969. }
  8970. menu->cursorItem = oldCursor;
  8971. return NULL;
  8972. }
  8973. /*
  8974. =================
  8975. Menu_SetPrevCursorItem
  8976. =================
  8977. */
  8978. itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu)
  8979. {
  8980. qboolean wrapped = qfalse;
  8981. int oldCursor = menu->cursorItem;
  8982. if (menu->cursorItem < 0)
  8983. {
  8984. menu->cursorItem = menu->itemCount-1;
  8985. wrapped = qtrue;
  8986. }
  8987. while (menu->cursorItem > -1)
  8988. {
  8989. menu->cursorItem--;
  8990. if (menu->cursorItem < 0 )
  8991. {
  8992. if (wrapped)
  8993. {
  8994. break;
  8995. }
  8996. wrapped = qtrue;
  8997. menu->cursorItem = menu->itemCount -1;
  8998. }
  8999. if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory))
  9000. {
  9001. Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
  9002. return menu->items[menu->cursorItem];
  9003. }
  9004. }
  9005. menu->cursorItem = oldCursor;
  9006. return NULL;
  9007. }
  9008. /*
  9009. =================
  9010. Item_TextField_HandleKey
  9011. =================
  9012. */
  9013. qboolean Item_TextField_HandleKey(itemDef_t *item, int key)
  9014. {
  9015. char buff[1024];
  9016. int len;
  9017. itemDef_t *newItem = NULL;
  9018. editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
  9019. if (item->cvar)
  9020. {
  9021. memset(buff, 0, sizeof(buff));
  9022. DC->getCVarString(item->cvar, buff, sizeof(buff));
  9023. len = strlen(buff);
  9024. if (editPtr->maxChars && len > editPtr->maxChars)
  9025. {
  9026. len = editPtr->maxChars;
  9027. }
  9028. if ( key & K_CHAR_FLAG )
  9029. {
  9030. key &= ~K_CHAR_FLAG;
  9031. if (key == 'h' - 'a' + 1 )
  9032. { // ctrl-h is backspace
  9033. if ( item->cursorPos > 0 )
  9034. {
  9035. memmove( &buff[item->cursorPos - 1], &buff[item->cursorPos], len + 1 - item->cursorPos);
  9036. item->cursorPos--;
  9037. if (item->cursorPos < editPtr->paintOffset)
  9038. {
  9039. editPtr->paintOffset--;
  9040. }
  9041. }
  9042. DC->setCVar(item->cvar, buff);
  9043. return qtrue;
  9044. }
  9045. //
  9046. // ignore any non printable chars
  9047. //
  9048. if ( key < 32 || !item->cvar)
  9049. {
  9050. return qtrue;
  9051. }
  9052. if (item->type == ITEM_TYPE_NUMERICFIELD)
  9053. {
  9054. if (key < '0' || key > '9')
  9055. {
  9056. return qfalse;
  9057. }
  9058. }
  9059. if (!DC->getOverstrikeMode())
  9060. {
  9061. if (( len == MAX_EDITFIELD - 1 ) || (editPtr->maxChars && len >= editPtr->maxChars))
  9062. {
  9063. return qtrue;
  9064. }
  9065. memmove( &buff[item->cursorPos + 1], &buff[item->cursorPos], len + 1 - item->cursorPos );
  9066. }
  9067. else
  9068. {
  9069. if (editPtr->maxChars && item->cursorPos >= editPtr->maxChars)
  9070. {
  9071. return qtrue;
  9072. }
  9073. }
  9074. buff[item->cursorPos] = key;
  9075. DC->setCVar(item->cvar, buff);
  9076. if (item->cursorPos < len + 1)
  9077. {
  9078. item->cursorPos++;
  9079. if (editPtr->maxPaintChars && item->cursorPos > editPtr->maxPaintChars)
  9080. {
  9081. editPtr->paintOffset++;
  9082. }
  9083. }
  9084. }
  9085. else
  9086. {
  9087. if ( key == A_DELETE || key == A_KP_PERIOD )
  9088. {
  9089. if ( item->cursorPos < len )
  9090. {
  9091. memmove( buff + item->cursorPos, buff + item->cursorPos + 1, len - item->cursorPos);
  9092. DC->setCVar(item->cvar, buff);
  9093. }
  9094. return qtrue;
  9095. }
  9096. if ( key == A_CURSOR_RIGHT || key == A_KP_6 )
  9097. {
  9098. if (editPtr->maxPaintChars && item->cursorPos >= editPtr->maxPaintChars && item->cursorPos < len)
  9099. {
  9100. item->cursorPos++;
  9101. editPtr->paintOffset++;
  9102. return qtrue;
  9103. }
  9104. if (item->cursorPos < len)
  9105. {
  9106. item->cursorPos++;
  9107. }
  9108. return qtrue;
  9109. }
  9110. if ( key == A_CURSOR_LEFT|| key == A_KP_4 )
  9111. {
  9112. if ( item->cursorPos > 0 )
  9113. {
  9114. item->cursorPos--;
  9115. }
  9116. if (item->cursorPos < editPtr->paintOffset)
  9117. {
  9118. editPtr->paintOffset--;
  9119. }
  9120. return qtrue;
  9121. }
  9122. if ( key == A_HOME || key == A_KP_7)
  9123. {
  9124. item->cursorPos = 0;
  9125. editPtr->paintOffset = 0;
  9126. return qtrue;
  9127. }
  9128. if ( key == A_END || key == A_KP_1)
  9129. {
  9130. item->cursorPos = len;
  9131. if(item->cursorPos > editPtr->maxPaintChars)
  9132. {
  9133. editPtr->paintOffset = len - editPtr->maxPaintChars;
  9134. }
  9135. return qtrue;
  9136. }
  9137. if ( key == A_INSERT || key == A_KP_0 )
  9138. {
  9139. DC->setOverstrikeMode(!DC->getOverstrikeMode());
  9140. return qtrue;
  9141. }
  9142. }
  9143. if (key == A_TAB || key == A_CURSOR_DOWN || key == A_KP_2)
  9144. {
  9145. newItem = Menu_SetNextCursorItem((menuDef_t *) item->parent);
  9146. if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD))
  9147. {
  9148. g_editItem = newItem;
  9149. }
  9150. }
  9151. if (key == A_CURSOR_UP || key == A_KP_8)
  9152. {
  9153. newItem = Menu_SetPrevCursorItem((menuDef_t *) item->parent);
  9154. if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD))
  9155. {
  9156. g_editItem = newItem;
  9157. }
  9158. }
  9159. if ( key == A_ENTER || key == A_KP_ENTER || key == A_ESCAPE)
  9160. {
  9161. return qfalse;
  9162. }
  9163. return qtrue;
  9164. }
  9165. return qfalse;
  9166. }
  9167. static void Scroll_TextScroll_AutoFunc (void *p)
  9168. {
  9169. scrollInfo_t *si = (scrollInfo_t*)p;
  9170. if (DC->realTime > si->nextScrollTime)
  9171. {
  9172. // need to scroll which is done by simulating a click to the item
  9173. // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
  9174. // so it calls it directly
  9175. Item_TextScroll_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
  9176. si->nextScrollTime = DC->realTime + si->adjustValue;
  9177. }
  9178. if (DC->realTime > si->nextAdjustTime)
  9179. {
  9180. si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  9181. if (si->adjustValue > SCROLL_TIME_FLOOR)
  9182. {
  9183. si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
  9184. }
  9185. }
  9186. }
  9187. static void Scroll_TextScroll_ThumbFunc(void *p)
  9188. {
  9189. scrollInfo_t *si = (scrollInfo_t*)p;
  9190. rectDef_t r;
  9191. int pos;
  9192. int max;
  9193. textScrollDef_t *scrollPtr = (textScrollDef_t*)si->item->typeData;
  9194. if (DC->cursory != si->yStart)
  9195. {
  9196. r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1;
  9197. r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1;
  9198. r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2;
  9199. r.w = SCROLLBAR_SIZE;
  9200. max = Item_TextScroll_MaxScroll(si->item);
  9201. //
  9202. pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE);
  9203. if (pos < 0)
  9204. {
  9205. pos = 0;
  9206. }
  9207. else if (pos > max)
  9208. {
  9209. pos = max;
  9210. }
  9211. scrollPtr->startPos = pos;
  9212. si->yStart = DC->cursory;
  9213. }
  9214. if (DC->realTime > si->nextScrollTime)
  9215. {
  9216. // need to scroll which is done by simulating a click to the item
  9217. // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
  9218. // so it calls it directly
  9219. Item_TextScroll_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
  9220. si->nextScrollTime = DC->realTime + si->adjustValue;
  9221. }
  9222. if (DC->realTime > si->nextAdjustTime)
  9223. {
  9224. si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  9225. if (si->adjustValue > SCROLL_TIME_FLOOR)
  9226. {
  9227. si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
  9228. }
  9229. }
  9230. }
  9231. /*
  9232. =================
  9233. Menu_OverActiveItem
  9234. =================
  9235. */
  9236. static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y)
  9237. {
  9238. if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))
  9239. {
  9240. //JLFMOUSE
  9241. #ifdef _XBOX
  9242. return qtrue;
  9243. #endif
  9244. if (Rect_ContainsPoint(&menu->window.rect, x, y))
  9245. {
  9246. int i;
  9247. for (i = 0; i < menu->itemCount; i++)
  9248. {
  9249. // turn off focus each item
  9250. // menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
  9251. if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)))
  9252. {
  9253. continue;
  9254. }
  9255. if (menu->items[i]->window.flags & WINDOW_DECORATION)
  9256. {
  9257. continue;
  9258. }
  9259. if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y))
  9260. {
  9261. itemDef_t *overItem = menu->items[i];
  9262. if (overItem->type == ITEM_TYPE_TEXT && overItem->text)
  9263. {
  9264. if (Rect_ContainsPoint(&overItem->window.rect, x, y))
  9265. {
  9266. return qtrue;
  9267. }
  9268. else
  9269. {
  9270. continue;
  9271. }
  9272. }
  9273. else
  9274. {
  9275. return qtrue;
  9276. }
  9277. }
  9278. }
  9279. }
  9280. }
  9281. return qfalse;
  9282. }
  9283. /*
  9284. =================
  9285. Display_VisibleMenuCount
  9286. =================
  9287. */
  9288. int Display_VisibleMenuCount(void)
  9289. {
  9290. int i, count;
  9291. count = 0;
  9292. for (i = 0; i < menuCount; i++)
  9293. {
  9294. if (Menus[i].window.flags & (WINDOW_FORCED | WINDOW_VISIBLE))
  9295. {
  9296. count++;
  9297. }
  9298. }
  9299. return count;
  9300. }
  9301. /*
  9302. =================
  9303. Window_CloseCinematic
  9304. =================
  9305. */
  9306. static void Window_CloseCinematic(windowDef_t *window)
  9307. {
  9308. /*
  9309. if (window->style == WINDOW_STYLE_CINEMATIC && window->cinematic >= 0)
  9310. {
  9311. DC->stopCinematic(window->cinematic);
  9312. window->cinematic = -1;
  9313. }
  9314. */
  9315. }
  9316. /*
  9317. =================
  9318. Menu_CloseCinematics
  9319. =================
  9320. */
  9321. static void Menu_CloseCinematics(menuDef_t *menu)
  9322. {
  9323. if (menu)
  9324. {
  9325. int i;
  9326. Window_CloseCinematic(&menu->window);
  9327. for (i = 0; i < menu->itemCount; i++)
  9328. {
  9329. Window_CloseCinematic(&menu->items[i]->window);
  9330. if (menu->items[i]->type == ITEM_TYPE_OWNERDRAW)
  9331. {
  9332. DC->stopCinematic(0-menu->items[i]->window.ownerDraw);
  9333. }
  9334. }
  9335. }
  9336. }
  9337. /*
  9338. =================
  9339. Display_CloseCinematics
  9340. =================
  9341. */
  9342. static void Display_CloseCinematics()
  9343. {
  9344. int i;
  9345. for (i = 0; i < menuCount; i++)
  9346. {
  9347. Menu_CloseCinematics(&Menus[i]);
  9348. }
  9349. }
  9350. /*
  9351. =================
  9352. Item_StopCapture
  9353. =================
  9354. */
  9355. void Item_StopCapture(itemDef_t *item)
  9356. {
  9357. }
  9358. /*
  9359. =================
  9360. Item_ListBox_HandleKey
  9361. =================
  9362. */
  9363. qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force)
  9364. {
  9365. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  9366. int count = DC->feederCount(item->special);
  9367. int max, viewmaxw, viewmaxh,viewmax;
  9368. int gridcount;
  9369. viewmaxw = (item->window.rect.w / listPtr->elementWidth);
  9370. viewmaxh = (item->window.rect.h / listPtr->elementHeight);
  9371. gridcount = viewmaxw * viewmaxh;
  9372. if (count <=0)
  9373. return qfalse;
  9374. //JLFMOUSE
  9375. #ifndef _XBOX
  9376. if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
  9377. #else
  9378. if (force || item->window.flags & WINDOW_HASFOCUS)
  9379. #endif
  9380. {
  9381. max = Item_ListBox_MaxScroll(item);
  9382. if (item->window.flags & WINDOW_HORIZONTAL)
  9383. {
  9384. viewmax = viewmaxw;
  9385. if ( key == A_CURSOR_LEFT || key == A_KP_4 )
  9386. {
  9387. if (!listPtr->notselectable)
  9388. {
  9389. listPtr->cursorPos--;
  9390. if (listPtr->cursorPos < 0)
  9391. {
  9392. listPtr->cursorPos = 0;
  9393. #ifdef _XBOX
  9394. item->cursorPos = listPtr->cursorPos;
  9395. DC->feederSelection(item->special, item->cursorPos, item);
  9396. return qfalse;
  9397. #endif
  9398. }
  9399. if (listPtr->cursorPos < listPtr->startPos)
  9400. {
  9401. listPtr->startPos = listPtr->cursorPos;
  9402. }
  9403. if (listPtr->cursorPos >= listPtr->startPos + viewmaxw)
  9404. {
  9405. listPtr->startPos = listPtr->cursorPos - viewmaxw + 1;
  9406. }
  9407. item->cursorPos = listPtr->cursorPos;
  9408. DC->feederSelection(item->special, item->cursorPos, item);
  9409. }
  9410. else
  9411. {
  9412. listPtr->startPos--;
  9413. //JLF
  9414. #ifdef _XBOX // MPMOVED
  9415. listPtr->cursorPos--;
  9416. if (listPtr->cursorPos >= 0)
  9417. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9418. else
  9419. listPtr->cursorPos =0;
  9420. #endif
  9421. if (listPtr->startPos < 0)
  9422. {
  9423. listPtr->startPos = 0;
  9424. //JLFMOUSE
  9425. #ifdef _XBOX // MPMOVED
  9426. return false;
  9427. #endif
  9428. }
  9429. }
  9430. return qtrue;
  9431. }
  9432. if ( key == A_CURSOR_RIGHT || key == A_KP_6 )
  9433. {
  9434. if (!listPtr->notselectable)
  9435. {
  9436. listPtr->cursorPos++;
  9437. if (listPtr->cursorPos < listPtr->startPos)
  9438. {
  9439. listPtr->startPos = listPtr->cursorPos;
  9440. }
  9441. if (listPtr->cursorPos >= count)
  9442. {
  9443. listPtr->cursorPos = count-1;
  9444. #ifdef _XBOX
  9445. item->cursorPos = listPtr->cursorPos;
  9446. DC->feederSelection(item->special, item->cursorPos, item);
  9447. return qfalse;
  9448. #endif
  9449. }
  9450. if (listPtr->cursorPos >= listPtr->startPos + viewmaxw)
  9451. {
  9452. listPtr->startPos = listPtr->cursorPos - viewmaxw + 1;
  9453. }
  9454. item->cursorPos = listPtr->cursorPos;
  9455. DC->feederSelection(item->special, item->cursorPos, item);
  9456. }
  9457. else
  9458. {
  9459. listPtr->startPos++;
  9460. //JLF
  9461. #ifdef _XBOX // MPMOVED
  9462. listPtr->cursorPos++;
  9463. if (listPtr->cursorPos < count)
  9464. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9465. else
  9466. listPtr->cursorPos =count -1;
  9467. #endif
  9468. if (listPtr->startPos >= count)
  9469. {
  9470. listPtr->startPos = count-1;
  9471. //JLFMOUSE
  9472. #ifdef _XBOX // MPMOVED
  9473. return false;
  9474. #endif
  9475. }
  9476. }
  9477. return qtrue;
  9478. }
  9479. }
  9480. else //VERTICAL ALIGNMENT *************************
  9481. {
  9482. viewmax = viewmaxh;
  9483. if ( key == A_CURSOR_UP || key == A_KP_8 )
  9484. {
  9485. if (!listPtr->notselectable)
  9486. {
  9487. if (listPtr->elementStyle == LISTBOX_IMAGE)
  9488. { listPtr->cursorPos-= viewmaxw;
  9489. if (listPtr->cursorPos < 0)
  9490. {
  9491. listPtr->cursorPos+=viewmaxw;
  9492. return qfalse;
  9493. }
  9494. }
  9495. else
  9496. listPtr->cursorPos--;
  9497. if (listPtr->cursorPos < 0)
  9498. {
  9499. listPtr->cursorPos = 0;
  9500. #ifdef _XBOX
  9501. item->cursorPos = listPtr->cursorPos;
  9502. DC->feederSelection(item->special, item->cursorPos, item);
  9503. return qfalse;
  9504. #endif
  9505. }
  9506. if (listPtr->cursorPos < listPtr->startPos)
  9507. {
  9508. if (listPtr->elementStyle == LISTBOX_IMAGE)
  9509. listPtr->startPos -= viewmaxw;
  9510. else
  9511. listPtr->startPos = listPtr->cursorPos;
  9512. }
  9513. if (listPtr->elementStyle == LISTBOX_IMAGE)
  9514. {
  9515. if (listPtr->cursorPos >= listPtr->startPos + gridcount)
  9516. listPtr->startPos += gridcount;
  9517. }
  9518. else
  9519. {
  9520. if (listPtr->cursorPos >= listPtr->startPos + viewmaxh)
  9521. listPtr->startPos= listPtr->cursorPos-viewmaxh + 1;
  9522. }
  9523. // listPtr->startPos = listPtr->cursorPos - viewmaxh + 1;
  9524. item->cursorPos = listPtr->cursorPos;
  9525. DC->feederSelection(item->special, item->cursorPos, item);
  9526. }
  9527. else
  9528. {
  9529. listPtr->startPos--;
  9530. //JLF
  9531. #ifdef _XBOX // MPMOVED
  9532. listPtr->cursorPos--;
  9533. if (listPtr->cursorPos >= 0)
  9534. {
  9535. item->cursorPos = listPtr->cursorPos;
  9536. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9537. }
  9538. else
  9539. listPtr->cursorPos = 0;
  9540. #endif
  9541. if (listPtr->startPos < 0)
  9542. {
  9543. listPtr->startPos = 0;
  9544. //JLFMOUSE
  9545. #ifdef _XBOX // MPMOVED
  9546. return false;
  9547. #endif
  9548. }
  9549. }
  9550. return qtrue;
  9551. }
  9552. if ( key == A_CURSOR_DOWN || key == A_KP_2 )
  9553. {
  9554. if (!listPtr->notselectable)
  9555. {
  9556. if (listPtr->elementStyle == LISTBOX_IMAGE)
  9557. {
  9558. listPtr->cursorPos+= viewmaxw;
  9559. if (listPtr->cursorPos >=count)
  9560. {
  9561. listPtr->cursorPos-= viewmaxw;
  9562. if ( count-1 == listPtr->cursorPos)
  9563. listPtr->cursorPos++;
  9564. else
  9565. listPtr->cursorPos = count-1;
  9566. }
  9567. }
  9568. else
  9569. listPtr->cursorPos++;
  9570. if (listPtr->cursorPos < listPtr->startPos)
  9571. {
  9572. listPtr->startPos = listPtr->cursorPos;
  9573. }
  9574. if (listPtr->cursorPos >= count)
  9575. {
  9576. listPtr->cursorPos = count-1;
  9577. #ifdef _XBOX
  9578. item->cursorPos = listPtr->cursorPos;
  9579. DC->feederSelection(item->special, item->cursorPos, item);
  9580. return qfalse;
  9581. #endif
  9582. }
  9583. if (listPtr->elementStyle == LISTBOX_IMAGE)
  9584. {
  9585. if (listPtr->cursorPos >= listPtr->startPos + gridcount) {
  9586. #ifdef _XBOX
  9587. listPtr->startPos += viewmaxw;
  9588. #else
  9589. listPtr->startPos = listPtr->cursorPos - viewmax + 1;
  9590. #endif
  9591. }
  9592. }
  9593. else
  9594. {
  9595. if (listPtr->cursorPos >= listPtr->startPos + viewmaxh)
  9596. listPtr->startPos++;
  9597. }
  9598. item->cursorPos = listPtr->cursorPos;
  9599. DC->feederSelection(item->special, item->cursorPos, item);
  9600. }
  9601. else
  9602. {
  9603. listPtr->startPos++;
  9604. //JLF
  9605. #ifdef _XBOX // MPMOVED
  9606. listPtr->cursorPos++;
  9607. if (listPtr->cursorPos < count)
  9608. {
  9609. item->cursorPos = listPtr->cursorPos;
  9610. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9611. }
  9612. else
  9613. listPtr->cursorPos = count -1;
  9614. #endif
  9615. //JLFMOUSE
  9616. #ifdef _XBOX // MPMOVED
  9617. if (listPtr->startPos > count-1)
  9618. {
  9619. listPtr->startPos = count-1;
  9620. return false;
  9621. #else
  9622. if (listPtr->startPos > max)
  9623. {
  9624. listPtr->startPos = max;
  9625. #endif
  9626. }
  9627. }
  9628. return qtrue;
  9629. }
  9630. //JLF newstuff
  9631. if ( key == A_CURSOR_LEFT && listPtr->elementStyle == LISTBOX_IMAGE )
  9632. {
  9633. if (viewmaxw <=1)
  9634. return false;
  9635. if (!listPtr->notselectable)
  9636. {
  9637. listPtr->cursorPos--;
  9638. if (listPtr->cursorPos < 0)
  9639. {
  9640. listPtr->cursorPos = 0;
  9641. #ifdef _XBOX
  9642. item->cursorPos = listPtr->cursorPos;
  9643. DC->feederSelection(item->special, item->cursorPos, item);
  9644. return qfalse;
  9645. #endif
  9646. }
  9647. if (listPtr->cursorPos < listPtr->startPos)
  9648. {
  9649. //JLF newgrid
  9650. #ifdef _XBOX
  9651. listPtr->startPos -= viewmaxw;
  9652. #else
  9653. listPtr->startPos = listPtr->cursorPos;
  9654. #endif
  9655. }
  9656. // if (listPtr->cursorPos >= listPtr->startPos + viewmaxh)
  9657. // {
  9658. // listPtr->startPos = listPtr->cursorPos - viewmaxh + 1;
  9659. // }
  9660. item->cursorPos = listPtr->cursorPos;
  9661. DC->feederSelection(item->special, item->cursorPos, item);
  9662. }
  9663. else
  9664. {
  9665. listPtr->startPos--;
  9666. //JLF
  9667. #ifdef _XBOX // MPMOVED
  9668. listPtr->cursorPos--;
  9669. if (listPtr->cursorPos >= 0)
  9670. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9671. else
  9672. listPtr->cursorPos = 0;
  9673. #endif
  9674. if (listPtr->startPos < 0)
  9675. {
  9676. listPtr->startPos = 0;
  9677. //JLFMOUSE
  9678. #ifdef _XBOX // MPMOVED
  9679. return false;
  9680. #endif
  9681. }
  9682. }
  9683. return qtrue;
  9684. }
  9685. if ( key == A_CURSOR_RIGHT && listPtr->elementStyle == LISTBOX_IMAGE )
  9686. {
  9687. if (viewmaxw <=1)
  9688. return false;
  9689. if (!listPtr->notselectable)
  9690. {
  9691. listPtr->cursorPos++;
  9692. if (listPtr->cursorPos >= count)
  9693. {
  9694. listPtr->cursorPos = count-1;
  9695. #ifdef _XBOX
  9696. item->cursorPos = listPtr->cursorPos;
  9697. DC->feederSelection(item->special, item->cursorPos, item);
  9698. return qfalse;
  9699. #endif
  9700. }
  9701. if (listPtr->cursorPos < listPtr->startPos)
  9702. {
  9703. listPtr->startPos = listPtr->cursorPos;
  9704. }
  9705. if (listPtr->cursorPos >= listPtr->startPos + gridcount)
  9706. {
  9707. //listPtr->startPos = listPtr->cursorPos - viewmaxh + 1;
  9708. listPtr->startPos += viewmaxw;
  9709. }
  9710. item->cursorPos = listPtr->cursorPos;
  9711. DC->feederSelection(item->special, item->cursorPos, item);
  9712. }
  9713. else
  9714. {
  9715. listPtr->startPos++;
  9716. //JLF
  9717. #ifdef _XBOX // MPMOVED
  9718. listPtr->cursorPos++;
  9719. if (listPtr->cursorPos < count)
  9720. DC->feederSelection(item->special, listPtr->cursorPos, item);
  9721. else
  9722. listPtr->cursorPos = count-1;
  9723. #endif
  9724. if (listPtr->startPos <count)
  9725. {
  9726. listPtr->startPos = count-1;
  9727. //JLFMOUSE
  9728. #ifdef _XBOX // MPMOVED
  9729. return false;
  9730. #endif
  9731. }
  9732. }
  9733. return qtrue;
  9734. }
  9735. }
  9736. // mouse hit
  9737. if (key == A_MOUSE1 || key == A_MOUSE2)
  9738. {
  9739. #ifdef _XBOX
  9740. if (listPtr->doubleClick)
  9741. {
  9742. Item_RunScript(item, listPtr->doubleClick);
  9743. return qtrue;
  9744. }
  9745. else
  9746. {
  9747. return Item_HandleAction(item);
  9748. }
  9749. #else
  9750. if (item->window.flags & WINDOW_LB_LEFTARROW)
  9751. {
  9752. listPtr->startPos--;
  9753. if (listPtr->startPos < 0)
  9754. {
  9755. listPtr->startPos = 0;
  9756. //JLFMOUSE
  9757. #ifdef _XBOX // MPMOVED
  9758. return false;
  9759. #endif
  9760. }
  9761. }
  9762. else if (item->window.flags & WINDOW_LB_RIGHTARROW)
  9763. {
  9764. // one down
  9765. listPtr->startPos++;
  9766. if (listPtr->startPos > max)
  9767. {
  9768. listPtr->startPos = max;
  9769. //JLFMOUSE
  9770. #ifdef _XBOX // MPMOVED
  9771. return false;
  9772. #endif
  9773. }
  9774. }
  9775. else if (item->window.flags & WINDOW_LB_PGUP)
  9776. {
  9777. // page up
  9778. listPtr->startPos -= viewmax;
  9779. if (listPtr->startPos < 0)
  9780. {
  9781. listPtr->startPos = 0;
  9782. //JLFMOUSE
  9783. #ifdef _XBOX // MPMOVED
  9784. return false;
  9785. #endif
  9786. }
  9787. }
  9788. else if (item->window.flags & WINDOW_LB_PGDN)
  9789. {
  9790. // page down
  9791. listPtr->startPos += viewmax;
  9792. if (listPtr->startPos > max)
  9793. {
  9794. listPtr->startPos = max;
  9795. //JLFMOUSE
  9796. #ifdef _XBOX // MPMOVED
  9797. return false;
  9798. #endif
  9799. }
  9800. }
  9801. else if (item->window.flags & WINDOW_LB_THUMB)
  9802. {
  9803. // Display_SetCaptureItem(item);
  9804. }
  9805. else
  9806. {
  9807. // select an item
  9808. if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick)
  9809. {
  9810. Item_RunScript(item, listPtr->doubleClick);
  9811. }
  9812. lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
  9813. item->cursorPos = listPtr->cursorPos;
  9814. DC->feederSelection(item->special, item->cursorPos, item);
  9815. }
  9816. return qtrue;
  9817. #endif
  9818. }
  9819. }
  9820. return qfalse;
  9821. }
  9822. /*
  9823. =================
  9824. Scroll_ListBox_AutoFunc
  9825. =================
  9826. */
  9827. static void Scroll_ListBox_AutoFunc(void *p)
  9828. {
  9829. scrollInfo_t *si = (scrollInfo_t*)p;
  9830. if (DC->realTime > si->nextScrollTime)
  9831. {
  9832. // need to scroll which is done by simulating a click to the item
  9833. // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
  9834. // so it calls it directly
  9835. Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
  9836. si->nextScrollTime = DC->realTime + si->adjustValue;
  9837. }
  9838. if (DC->realTime > si->nextAdjustTime)
  9839. {
  9840. si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  9841. if (si->adjustValue > SCROLL_TIME_FLOOR)
  9842. {
  9843. si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
  9844. }
  9845. }
  9846. }
  9847. /*
  9848. =================
  9849. Scroll_ListBox_ThumbFunc
  9850. =================
  9851. */
  9852. static void Scroll_ListBox_ThumbFunc(void *p)
  9853. {
  9854. scrollInfo_t *si = (scrollInfo_t*)p;
  9855. rectDef_t r;
  9856. int pos, max;
  9857. listBoxDef_t *listPtr = (listBoxDef_t*)si->item->typeData;
  9858. if (si->item->window.flags & WINDOW_HORIZONTAL)
  9859. {
  9860. if (DC->cursorx == si->xStart)
  9861. {
  9862. return;
  9863. }
  9864. r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1;
  9865. r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1;
  9866. r.h = SCROLLBAR_SIZE;
  9867. r.w = si->item->window.rect.w - (SCROLLBAR_SIZE*2) - 2;
  9868. max = Item_ListBox_MaxScroll(si->item);
  9869. //
  9870. pos = (DC->cursorx - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE);
  9871. if (pos < 0)
  9872. {
  9873. pos = 0;
  9874. }
  9875. else if (pos > max)
  9876. {
  9877. pos = max;
  9878. }
  9879. listPtr->startPos = pos;
  9880. si->xStart = DC->cursorx;
  9881. }
  9882. else if (DC->cursory != si->yStart)
  9883. {
  9884. r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1;
  9885. r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1;
  9886. r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2;
  9887. r.w = SCROLLBAR_SIZE;
  9888. max = Item_ListBox_MaxScroll(si->item);
  9889. //
  9890. pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE);
  9891. if (pos < 0)
  9892. {
  9893. pos = 0;
  9894. }
  9895. else if (pos > max)
  9896. {
  9897. pos = max;
  9898. }
  9899. listPtr->startPos = pos;
  9900. si->yStart = DC->cursory;
  9901. }
  9902. if (DC->realTime > si->nextScrollTime)
  9903. {
  9904. // need to scroll which is done by simulating a click to the item
  9905. // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
  9906. // so it calls it directly
  9907. Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
  9908. si->nextScrollTime = DC->realTime + si->adjustValue;
  9909. }
  9910. if (DC->realTime > si->nextAdjustTime)
  9911. {
  9912. si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  9913. if (si->adjustValue > SCROLL_TIME_FLOOR)
  9914. {
  9915. si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
  9916. }
  9917. }
  9918. }
  9919. /*
  9920. =================
  9921. Item_Slider_OverSlider
  9922. =================
  9923. */
  9924. int Item_Slider_OverSlider(itemDef_t *item, float x, float y)
  9925. {
  9926. rectDef_t r;
  9927. r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2);
  9928. r.y = item->window.rect.y - 2;
  9929. r.w = SLIDER_THUMB_WIDTH;
  9930. r.h = SLIDER_THUMB_HEIGHT;
  9931. if (Rect_ContainsPoint(&r, x, y))
  9932. {
  9933. return WINDOW_LB_THUMB;
  9934. }
  9935. return 0;
  9936. }
  9937. /*
  9938. =================
  9939. Scroll_Slider_ThumbFunc
  9940. =================
  9941. */
  9942. static void Scroll_Slider_ThumbFunc(void *p)
  9943. {
  9944. float x, value, cursorx;
  9945. scrollInfo_t *si = (scrollInfo_t*)p;
  9946. editFieldDef_t *editDef = (struct editFieldDef_s *) si->item->typeData;
  9947. if (si->item->text)
  9948. {
  9949. x = si->item->textRect.x + si->item->textRect.w + 8;
  9950. }
  9951. else
  9952. {
  9953. x = si->item->window.rect.x;
  9954. }
  9955. cursorx = DC->cursorx;
  9956. if (cursorx < x)
  9957. {
  9958. cursorx = x;
  9959. }
  9960. else if (cursorx > x + SLIDER_WIDTH)
  9961. {
  9962. cursorx = x + SLIDER_WIDTH;
  9963. }
  9964. value = cursorx - x;
  9965. value /= SLIDER_WIDTH;
  9966. value *= (editDef->maxVal - editDef->minVal);
  9967. value += editDef->minVal;
  9968. DC->setCVar(si->item->cvar, va("%f", value));
  9969. }
  9970. /*
  9971. =================
  9972. Item_StartCapture
  9973. =================
  9974. */
  9975. void Item_StartCapture(itemDef_t *item, int key)
  9976. {
  9977. int flags;
  9978. switch (item->type)
  9979. {
  9980. case ITEM_TYPE_EDITFIELD:
  9981. case ITEM_TYPE_NUMERICFIELD:
  9982. case ITEM_TYPE_LISTBOX:
  9983. {
  9984. flags = Item_ListBox_OverLB(item, DC->cursorx, DC->cursory);
  9985. if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW))
  9986. {
  9987. scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
  9988. scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  9989. scrollInfo.adjustValue = SCROLL_TIME_START;
  9990. scrollInfo.scrollKey = key;
  9991. scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse;
  9992. scrollInfo.item = item;
  9993. captureData = &scrollInfo;
  9994. captureFunc = &Scroll_ListBox_AutoFunc;
  9995. itemCapture = item;
  9996. }
  9997. else if (flags & WINDOW_LB_THUMB)
  9998. {
  9999. scrollInfo.scrollKey = key;
  10000. scrollInfo.item = item;
  10001. scrollInfo.xStart = DC->cursorx;
  10002. scrollInfo.yStart = DC->cursory;
  10003. captureData = &scrollInfo;
  10004. captureFunc = &Scroll_ListBox_ThumbFunc;
  10005. itemCapture = item;
  10006. }
  10007. break;
  10008. }
  10009. case ITEM_TYPE_TEXTSCROLL:
  10010. flags = Item_TextScroll_OverLB (item, DC->cursorx, DC->cursory);
  10011. if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW))
  10012. {
  10013. scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
  10014. scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
  10015. scrollInfo.adjustValue = SCROLL_TIME_START;
  10016. scrollInfo.scrollKey = key;
  10017. scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse;
  10018. scrollInfo.item = item;
  10019. captureData = &scrollInfo;
  10020. captureFunc = &Scroll_TextScroll_AutoFunc;
  10021. itemCapture = item;
  10022. }
  10023. else if (flags & WINDOW_LB_THUMB)
  10024. {
  10025. scrollInfo.scrollKey = key;
  10026. scrollInfo.item = item;
  10027. scrollInfo.xStart = DC->cursorx;
  10028. scrollInfo.yStart = DC->cursory;
  10029. captureData = &scrollInfo;
  10030. captureFunc = &Scroll_TextScroll_ThumbFunc;
  10031. itemCapture = item;
  10032. }
  10033. break;
  10034. case ITEM_TYPE_SLIDER:
  10035. {
  10036. flags = Item_Slider_OverSlider(item, DC->cursorx, DC->cursory);
  10037. if (flags & WINDOW_LB_THUMB)
  10038. {
  10039. scrollInfo.scrollKey = key;
  10040. scrollInfo.item = item;
  10041. scrollInfo.xStart = DC->cursorx;
  10042. scrollInfo.yStart = DC->cursory;
  10043. captureData = &scrollInfo;
  10044. captureFunc = &Scroll_Slider_ThumbFunc;
  10045. itemCapture = item;
  10046. }
  10047. break;
  10048. }
  10049. }
  10050. }
  10051. /*
  10052. =================
  10053. Item_YesNo_HandleKey
  10054. =================
  10055. */
  10056. qboolean Item_YesNo_HandleKey(itemDef_t *item, int key)
  10057. {
  10058. //JLFMOUSE MPMOVED
  10059. #ifndef _XBOX
  10060. if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar)
  10061. #else
  10062. if (item->window.flags & WINDOW_HASFOCUS && item->cvar)
  10063. #endif
  10064. {
  10065. //JLFDPAD MPMOVED
  10066. #ifndef _XBOX
  10067. if (key == A_MOUSE1 || key == A_ENTER || key == A_MOUSE2 || key == A_MOUSE3)
  10068. #else
  10069. if ( key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)
  10070. #endif
  10071. //end JLFDPAD
  10072. {
  10073. DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
  10074. return qtrue;
  10075. }
  10076. }
  10077. return qfalse;
  10078. }
  10079. /*
  10080. =================
  10081. Item_Multi_FindCvarByValue
  10082. =================
  10083. */
  10084. int Item_Multi_FindCvarByValue(itemDef_t *item)
  10085. {
  10086. char buff[1024];
  10087. float value = 0;
  10088. int i;
  10089. multiDef_t *multiPtr = (multiDef_t*)item->typeData;
  10090. if (multiPtr)
  10091. {
  10092. if (multiPtr->strDef)
  10093. {
  10094. DC->getCVarString(item->cvar, buff, sizeof(buff));
  10095. }
  10096. else
  10097. {
  10098. value = DC->getCVarValue(item->cvar);
  10099. }
  10100. for (i = 0; i < multiPtr->count; i++)
  10101. {
  10102. if (multiPtr->strDef)
  10103. {
  10104. if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0)
  10105. {
  10106. return i;
  10107. }
  10108. }
  10109. else
  10110. {
  10111. if (multiPtr->cvarValue[i] == value)
  10112. {
  10113. return i;
  10114. }
  10115. }
  10116. }
  10117. }
  10118. return 0;
  10119. }
  10120. /*
  10121. =================
  10122. Item_Multi_CountSettings
  10123. =================
  10124. */
  10125. int Item_Multi_CountSettings(itemDef_t *item)
  10126. {
  10127. multiDef_t *multiPtr = (multiDef_t*)item->typeData;
  10128. if (multiPtr == NULL)
  10129. {
  10130. return 0;
  10131. }
  10132. return multiPtr->count;
  10133. }
  10134. /*
  10135. =================
  10136. Item_OwnerDraw_HandleKey
  10137. =================
  10138. */
  10139. qboolean Item_OwnerDraw_HandleKey(itemDef_t *item, int key)
  10140. {
  10141. if (item && DC->ownerDrawHandleKey)
  10142. {
  10143. return DC->ownerDrawHandleKey(item->window.ownerDraw, item->window.ownerDrawFlags, &item->special, key);
  10144. }
  10145. return qfalse;
  10146. }
  10147. //JLF new selection LEFT/RIGHT
  10148. qboolean Item_Button_HandleKey(itemDef_t *item, int key)
  10149. {
  10150. #ifdef _XBOX
  10151. if (key == A_MOUSE1)
  10152. {
  10153. if (Item_HandleAction(item))
  10154. {
  10155. return qtrue;
  10156. }
  10157. }
  10158. if ( key == A_CURSOR_RIGHT)
  10159. {
  10160. if (Item_HandleSelectionNext(item))
  10161. {
  10162. //Item processed it
  10163. return qtrue;
  10164. }
  10165. }
  10166. else if ( key == A_CURSOR_LEFT)
  10167. {
  10168. if (Item_HandleSelectionPrev(item))
  10169. {
  10170. //Item processed it
  10171. return qtrue;
  10172. }
  10173. }
  10174. #endif
  10175. return false;
  10176. }
  10177. /*
  10178. =================
  10179. Item_Text_HandleKey
  10180. =================
  10181. */
  10182. qboolean Item_Text_HandleKey(itemDef_t *item, int key)
  10183. {
  10184. if (key == A_MOUSE1)
  10185. {
  10186. if (Item_HandleAction(item))
  10187. {
  10188. return qtrue;
  10189. }
  10190. }
  10191. else if (key == A_CURSOR_RIGHT)
  10192. {
  10193. if (Item_HandleSelectionNext(item))
  10194. {
  10195. //Item processed it
  10196. return qtrue;
  10197. }
  10198. }
  10199. else if (key == A_CURSOR_LEFT)
  10200. {
  10201. if (Item_HandleSelectionPrev(item))
  10202. {
  10203. //Item processed it
  10204. return qtrue;
  10205. }
  10206. }
  10207. return qfalse;
  10208. }
  10209. /*
  10210. =================
  10211. Item_Multi_HandleKey
  10212. =================
  10213. */
  10214. qboolean Item_Multi_HandleKey(itemDef_t *item, int key)
  10215. {
  10216. multiDef_t *multiPtr = (multiDef_t*)item->typeData;
  10217. if (multiPtr)
  10218. {
  10219. //JLF MPMOVED
  10220. #ifndef _XBOX
  10221. if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)
  10222. #else
  10223. if (item->window.flags & WINDOW_HASFOCUS)// JLF* && item->cvar)
  10224. #endif
  10225. {
  10226. #ifndef _XBOX
  10227. if (key == A_MOUSE1 || key == A_ENTER || key == A_MOUSE2 || key == A_MOUSE3)
  10228. #else
  10229. //JLFDPAD MPMOVED
  10230. if ( key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)
  10231. //end JLFDPAD
  10232. #endif
  10233. {
  10234. if (item->cvar)
  10235. {
  10236. int current = Item_Multi_FindCvarByValue(item);
  10237. int max = Item_Multi_CountSettings(item);
  10238. #ifndef _XBOX
  10239. if (key == A_MOUSE2)
  10240. #else
  10241. if (key == A_CURSOR_LEFT)
  10242. #endif
  10243. {
  10244. current--;
  10245. if ( current < 0 )
  10246. {
  10247. current = max-1;
  10248. }
  10249. }
  10250. else
  10251. {
  10252. current++;
  10253. if ( current >= max )
  10254. {
  10255. current = 0;
  10256. }
  10257. }
  10258. if (multiPtr->strDef)
  10259. {
  10260. DC->setCVar(item->cvar, multiPtr->cvarStr[current]);
  10261. }
  10262. else
  10263. {
  10264. float value = multiPtr->cvarValue[current];
  10265. if (((float)((int) value)) == value)
  10266. {
  10267. DC->setCVar(item->cvar, va("%i", (int) value ));
  10268. }
  10269. else
  10270. {
  10271. DC->setCVar(item->cvar, va("%f", value ));
  10272. }
  10273. }
  10274. if (item->special)
  10275. {//its a feeder?
  10276. DC->feederSelection(item->special, current, item);
  10277. }
  10278. }
  10279. else
  10280. {
  10281. int max = Item_Multi_CountSettings(item);
  10282. #ifndef _XBOX
  10283. if (key == A_MOUSE2)
  10284. #else
  10285. if (key == A_CURSOR_LEFT)
  10286. #endif
  10287. {
  10288. item->value--;
  10289. if ( item->value < 0 )
  10290. {
  10291. item->value = max;
  10292. }
  10293. }
  10294. else
  10295. {
  10296. item->value++;
  10297. if ( item->value >= max )
  10298. {
  10299. item->value = 0;
  10300. }
  10301. }
  10302. if (item->special)
  10303. {//its a feeder?
  10304. DC->feederSelection(item->special, item->value, item);
  10305. }
  10306. }
  10307. //JLF
  10308. #ifdef _XBOX
  10309. if ( key == A_CURSOR_RIGHT)
  10310. {
  10311. if (Item_HandleSelectionNext(item))
  10312. {
  10313. //Item processed it
  10314. }
  10315. }
  10316. else if ( key == A_CURSOR_LEFT)
  10317. {
  10318. if (Item_HandleSelectionPrev(item))
  10319. {
  10320. //Item processed it
  10321. }
  10322. }
  10323. #endif
  10324. return qtrue;
  10325. }
  10326. }
  10327. }
  10328. return qfalse;
  10329. }
  10330. /*
  10331. =================
  10332. Item_Slider_HandleKey
  10333. =================
  10334. */
  10335. qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down)
  10336. {
  10337. float value;
  10338. if (item->window.flags & WINDOW_HASFOCUS && item->cvar)
  10339. {
  10340. if (key == A_CURSOR_LEFT)
  10341. {
  10342. editFieldDef_t *editDef = (editFieldDef_s *) item->typeData;
  10343. if (editDef)
  10344. {
  10345. value = DC->getCVarValue(item->cvar);
  10346. value -= (editDef->maxVal-editDef->minVal)/TICK_COUNT;
  10347. if ( value < editDef->minVal)
  10348. value = editDef->minVal;
  10349. DC->setCVar(item->cvar, va("%f", value));
  10350. return qtrue;
  10351. }
  10352. }
  10353. if (key == A_CURSOR_RIGHT)
  10354. {
  10355. editFieldDef_t *editDef = (editFieldDef_s *) item->typeData;
  10356. if (editDef)
  10357. {
  10358. value = DC->getCVarValue(item->cvar);
  10359. value += (editDef->maxVal-editDef->minVal)/TICK_COUNT;
  10360. if ( value > editDef->maxVal)
  10361. value = editDef->maxVal;
  10362. DC->setCVar(item->cvar, va("%f", value));
  10363. return qtrue;
  10364. }
  10365. }
  10366. }
  10367. return qfalse;
  10368. }
  10369. /*
  10370. =================
  10371. Item_HandleKey
  10372. =================
  10373. */
  10374. qboolean Item_HandleKey(itemDef_t *item, int key, qboolean down)
  10375. {
  10376. if (itemCapture)
  10377. {
  10378. Item_StopCapture(itemCapture);
  10379. itemCapture = NULL;
  10380. captureFunc = NULL;
  10381. captureData = NULL;
  10382. }
  10383. else
  10384. {
  10385. if (down && key == A_MOUSE1 || key == A_MOUSE2 || key == A_MOUSE3)
  10386. {
  10387. Item_StartCapture(item, key);
  10388. }
  10389. }
  10390. if (!down)
  10391. {
  10392. return qfalse;
  10393. }
  10394. switch (item->type)
  10395. {
  10396. case ITEM_TYPE_BUTTON:
  10397. #ifdef _XBOX
  10398. return Item_Button_HandleKey(item, key);
  10399. #else
  10400. return qfalse;
  10401. #endif
  10402. break;
  10403. case ITEM_TYPE_RADIOBUTTON:
  10404. return qfalse;
  10405. break;
  10406. case ITEM_TYPE_CHECKBOX:
  10407. return qfalse;
  10408. break;
  10409. case ITEM_TYPE_EDITFIELD:
  10410. case ITEM_TYPE_NUMERICFIELD:
  10411. //return Item_TextField_HandleKey(item, key);
  10412. return qfalse;
  10413. break;
  10414. case ITEM_TYPE_COMBO:
  10415. return qfalse;
  10416. break;
  10417. case ITEM_TYPE_LISTBOX:
  10418. return Item_ListBox_HandleKey(item, key, down, qfalse);
  10419. break;
  10420. case ITEM_TYPE_TEXTSCROLL:
  10421. return Item_TextScroll_HandleKey(item, key, down, qfalse);
  10422. break;
  10423. case ITEM_TYPE_YESNO:
  10424. return Item_YesNo_HandleKey(item, key);
  10425. break;
  10426. case ITEM_TYPE_MULTI:
  10427. return Item_Multi_HandleKey(item, key);
  10428. break;
  10429. case ITEM_TYPE_OWNERDRAW:
  10430. return Item_OwnerDraw_HandleKey(item, key);
  10431. break;
  10432. case ITEM_TYPE_BIND:
  10433. return Item_Bind_HandleKey(item, key, down);
  10434. break;
  10435. case ITEM_TYPE_SLIDER:
  10436. return Item_Slider_HandleKey(item, key, down);
  10437. break;
  10438. //JLF MPMOVED
  10439. case ITEM_TYPE_TEXT:
  10440. return Item_Text_HandleKey(item, key);
  10441. break;
  10442. default:
  10443. return qfalse;
  10444. break;
  10445. }
  10446. //return qfalse;
  10447. }
  10448. //JLFACCEPT MPMOVED
  10449. /*
  10450. -----------------------------------------
  10451. Item_HandleAction
  10452. If Item has an action script, run it.
  10453. -------------------------------------------
  10454. */
  10455. qboolean Item_HandleAction(itemDef_t * item)
  10456. {
  10457. if (!item)
  10458. return qfalse;
  10459. if (item->action)
  10460. //if (item->accept)
  10461. {
  10462. //Item_RunScript(item, item->accept);
  10463. Item_RunScript(item, item->action);
  10464. return true;
  10465. }
  10466. return false;
  10467. }
  10468. //JLFDPADSCRIPT MPMOVED
  10469. /*
  10470. -----------------------------------------
  10471. Item_HandleSelectionNext
  10472. If Item has an selectionNext script, run it.
  10473. -------------------------------------------
  10474. */
  10475. qboolean Item_HandleSelectionNext(itemDef_t * item)
  10476. {
  10477. if (item->selectionNext)
  10478. {
  10479. Item_RunScript(item, item->selectionNext);
  10480. return true;
  10481. }
  10482. return false;
  10483. }
  10484. //JLFDPADSCRIPT MPMOVED
  10485. /*
  10486. -----------------------------------------
  10487. Item_HandleSelectionPrev
  10488. If Item has an selectionPrev script, run it.
  10489. -------------------------------------------
  10490. */
  10491. qboolean Item_HandleSelectionPrev(itemDef_t * item)
  10492. {
  10493. if (item->selectionPrev)
  10494. {
  10495. Item_RunScript(item, item->selectionPrev);
  10496. return true;
  10497. }
  10498. return false;
  10499. }
  10500. /*
  10501. =================
  10502. Item_Action
  10503. =================
  10504. */
  10505. /*
  10506. void Item_Action(itemDef_t *item)
  10507. {
  10508. if (item)
  10509. {
  10510. Item_RunScript(item, item->action);
  10511. }
  10512. }
  10513. */
  10514. /*
  10515. =================
  10516. Menu_HandleKey
  10517. =================
  10518. */
  10519. void Menu_HandleKey(menuDef_t *menu, int key, qboolean down)
  10520. {
  10521. int i;
  10522. itemDef_t *item = NULL;
  10523. qboolean inHandler = qfalse;
  10524. if (inHandler)
  10525. {
  10526. return;
  10527. }
  10528. inHandler = qtrue;
  10529. if (g_waitingForKey && down)
  10530. {
  10531. Item_Bind_HandleKey(g_bindItem, key, down);
  10532. inHandler = qfalse;
  10533. return;
  10534. }
  10535. if (g_editingField && down)
  10536. {
  10537. if (!Item_TextField_HandleKey(g_editItem, key))
  10538. {
  10539. g_editingField = qfalse;
  10540. g_editItem = NULL;
  10541. inHandler = qfalse;
  10542. return;
  10543. }
  10544. else if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_MOUSE3)
  10545. {
  10546. g_editingField = qfalse;
  10547. g_editItem = NULL;
  10548. Display_MouseMove(NULL, DC->cursorx, DC->cursory);
  10549. }
  10550. else if (key == A_TAB || key == A_CURSOR_UP || key == A_CURSOR_DOWN)
  10551. {
  10552. return;
  10553. }
  10554. }
  10555. if (menu == NULL)
  10556. {
  10557. inHandler = qfalse;
  10558. return;
  10559. }
  10560. #ifdef _XBOX
  10561. Menu_MapHack(key);
  10562. #endif
  10563. // get the item with focus
  10564. for (i = 0; i < menu->itemCount; i++)
  10565. {
  10566. if (menu->items[i]->window.flags & WINDOW_HASFOCUS)
  10567. {
  10568. item = menu->items[i];
  10569. break;
  10570. }
  10571. }
  10572. if (!down)
  10573. {
  10574. inHandler = qfalse;
  10575. return;
  10576. }
  10577. if ( item !=NULL)
  10578. {
  10579. //Handlekey implies that this control was able to interpret and use this input
  10580. if (Item_HandleKey(item, key, down))
  10581. {
  10582. if (((item->type == ITEM_TYPE_MULTI) || (item->type == ITEM_TYPE_SLIDER) || (item->type == ITEM_TYPE_YESNO)) &&
  10583. ((key == A_CURSOR_RIGHT) || (key == A_CURSOR_LEFT)))
  10584. {
  10585. Item_HandleAction(item);
  10586. }
  10587. // if ((item->type != ITEM_TYPE_LISTBOX) && ((key != A_CURSOR_RIGHT && key != A_CURSOR_LEFT) || (item->type == ITEM_TYPE_MULTI)))
  10588. // Item_HandleAction(item);
  10589. inHandler = qfalse;
  10590. return;
  10591. }
  10592. }
  10593. // Special Data Pad key handling (gotta love the datapad)
  10594. if (!(key & K_CHAR_FLAG) )
  10595. { //only check keys not chars
  10596. char b[256];
  10597. DC->getBindingBuf( key, b, 256 );
  10598. if (Q_stricmp(b,"datapad") == 0) // They hit the datapad key again.
  10599. {
  10600. if (( Q_stricmp(menu->window.name,"datapadMissionMenu") == 0) ||
  10601. (Q_stricmp(menu->window.name,"datapadWeaponsMenu") == 0) ||
  10602. (Q_stricmp(menu->window.name,"datapadForcePowersMenu") == 0) ||
  10603. (Q_stricmp(menu->window.name,"datapadInventoryMenu") == 0))
  10604. {
  10605. key = A_ESCAPE; //pop on outta here
  10606. }
  10607. }
  10608. }
  10609. // default handling
  10610. switch ( key )
  10611. {
  10612. case A_CURSOR_UP:
  10613. Menu_SetPrevCursorItem(menu);
  10614. break;
  10615. case A_ESCAPE:
  10616. if (menu->onESC)
  10617. {
  10618. itemDef_t it;
  10619. it.parent = menu;
  10620. Item_RunScript(&it, menu->onESC);
  10621. }
  10622. break;
  10623. case A_DELETE:
  10624. if (menu->xScript)
  10625. {
  10626. itemDef_t it;
  10627. it.parent = menu;
  10628. Item_RunScript(&it, menu->xScript);
  10629. }
  10630. break;
  10631. case A_BACKSPACE:
  10632. if (menu->yScript)
  10633. {
  10634. itemDef_t it;
  10635. it.parent = menu;
  10636. if (Cvar_VariableIntegerValue("ui_cancelYScript")==0)
  10637. Item_RunScript(&it, menu->yScript);
  10638. }
  10639. break;
  10640. case A_HOME:
  10641. if (menu->whiteScript)
  10642. {
  10643. itemDef_t it;
  10644. it.parent = menu;
  10645. Item_RunScript(&it, menu->whiteScript);
  10646. }
  10647. break;
  10648. case A_CURSOR_DOWN:
  10649. Menu_SetNextCursorItem(menu);
  10650. break;
  10651. case A_MOUSE1:
  10652. if (menu->onAccept)
  10653. {
  10654. itemDef_t it;
  10655. it.parent = menu;
  10656. Item_RunScript(&it, menu->onAccept);
  10657. }
  10658. break;
  10659. case A_JOY0:
  10660. case A_JOY1:
  10661. case A_JOY2:
  10662. case A_JOY3:
  10663. case A_JOY4:
  10664. case A_AUX0:
  10665. case A_AUX1:
  10666. case A_AUX2:
  10667. case A_AUX3:
  10668. case A_AUX4:
  10669. case A_AUX5:
  10670. case A_AUX6:
  10671. case A_AUX7:
  10672. case A_AUX8:
  10673. case A_AUX9:
  10674. case A_AUX10:
  10675. case A_AUX11:
  10676. case A_AUX12:
  10677. case A_AUX13:
  10678. case A_AUX14:
  10679. case A_AUX15:
  10680. case A_AUX16:
  10681. break;
  10682. case A_KP_ENTER:
  10683. case A_ENTER:
  10684. if (item)
  10685. {
  10686. Item_HandleAction(item);
  10687. }
  10688. break;
  10689. }
  10690. inHandler = qfalse;
  10691. }
  10692. /*
  10693. =================
  10694. ParseRect
  10695. =================
  10696. */
  10697. qboolean ParseRect(const char **p, rectDef_t *r)
  10698. {
  10699. if (!COM_ParseFloat(p, &r->x))
  10700. {
  10701. if (!COM_ParseFloat(p, &r->y))
  10702. {
  10703. if (!COM_ParseFloat(p, &r->w))
  10704. {
  10705. if (!COM_ParseFloat(p, &r->h))
  10706. {
  10707. return qtrue;
  10708. }
  10709. }
  10710. }
  10711. }
  10712. return qfalse;
  10713. }
  10714. /*
  10715. =================
  10716. Menus_HideItems
  10717. =================
  10718. */
  10719. void Menus_HideItems(const char *menuName)
  10720. {
  10721. menuDef_t *menu;
  10722. int i;
  10723. menu =Menus_FindByName(menuName); // Get menu
  10724. if (!menu)
  10725. {
  10726. Com_Printf(S_COLOR_YELLOW"WARNING: No menu was found. Could not hide items.\n");
  10727. return;
  10728. }
  10729. menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
  10730. for (i = 0; i < menu->itemCount; i++)
  10731. {
  10732. menu->items[i]->cvarFlags = CVAR_HIDE;
  10733. }
  10734. }
  10735. /*
  10736. =================
  10737. Menus_ShowItems
  10738. =================
  10739. */
  10740. void Menus_ShowItems(const char *menuName)
  10741. {
  10742. menuDef_t *menu;
  10743. int i;
  10744. menu =Menus_FindByName(menuName); // Get menu
  10745. if (!menu)
  10746. {
  10747. Com_Printf(S_COLOR_YELLOW"WARNING: No menu was found. Could not show items.\n");
  10748. return;
  10749. }
  10750. menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
  10751. for (i = 0; i < menu->itemCount; i++)
  10752. {
  10753. menu->items[i]->cvarFlags = CVAR_SHOW;
  10754. }
  10755. }
  10756. /*
  10757. =================
  10758. UI_Cursor_Show
  10759. =================
  10760. */
  10761. void UI_Cursor_Show(qboolean flag)
  10762. {
  10763. DC->cursorShow = flag;
  10764. if ((DC->cursorShow != qtrue) && (DC->cursorShow != qfalse))
  10765. {
  10766. DC->cursorShow = qtrue;
  10767. }
  10768. }
  10769. #ifdef _XBOX
  10770. /*
  10771. =================
  10772. Menu_MapHack
  10773. =================
  10774. */
  10775. void Menu_MapHack(int key)
  10776. {
  10777. if (key == A_F1 || key == A_F2)
  10778. {
  10779. const char *maps[] =
  10780. {
  10781. "academy1",
  10782. "academy2",
  10783. "academy3",
  10784. "academy4",
  10785. "academy5",
  10786. "academy6",
  10787. "hoth2",
  10788. "hoth3",
  10789. "kor1",
  10790. "kor2",
  10791. "t1_danger",
  10792. "t1_fatal",
  10793. "t1_inter",
  10794. "t1_rail",
  10795. "t1_sour",
  10796. "t1_surprise",
  10797. "t2_dpred",
  10798. "t2_rancor",
  10799. "t2_rogue",
  10800. "t2_trip",
  10801. "t2_wedge",
  10802. "t3_bounty",
  10803. "t3_byss",
  10804. "t3_hevil",
  10805. "t3_rift",
  10806. "t3_stamp",
  10807. "taspir1",
  10808. "taspir2",
  10809. "vjun1",
  10810. "vjun2",
  10811. "vjun3",
  10812. "yavin1",
  10813. "yavin1b",
  10814. "yavin2",
  10815. };
  10816. const int num_maps = sizeof(maps) / sizeof(char*);
  10817. int current = 0;
  10818. while (current < num_maps)
  10819. {
  10820. if (!strcmp(cl_mapname->string, maps[current])) break;
  10821. ++current;
  10822. }
  10823. if (key == A_F1) --current;
  10824. if (key == A_F2) ++current;
  10825. if (current < 0) current = num_maps - 1;
  10826. if (current >= num_maps) current = 0;
  10827. DC->setCVar( "cl_mapname", maps[current] );
  10828. }
  10829. else if (key == A_F3)
  10830. {
  10831. char localMapname[32];
  10832. DC->getCVarString("cl_mapname", localMapname, sizeof(localMapname));
  10833. DC->executeText( EXEC_APPEND, va("devmapall %s\n", localMapname ) );
  10834. }
  10835. }
  10836. //JLF DEMOCODE
  10837. // IS ALREADY IN #ifdef _XBOX
  10838. void G_DemoStart()
  10839. {
  10840. // demoDelay = 0;
  10841. // lastChange = 0;
  10842. g_runningDemo = true;
  10843. // g_demoLastChange = 0;
  10844. extern void Menus_CloseAll();
  10845. Menus_CloseAll();
  10846. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  10847. trap_Key_ClearStates();
  10848. Cvar_Set( "cl_paused", "0" );
  10849. //We're moving back out to the attract movie - re-enable all controllers to interrupt it!
  10850. Cvar_SetValue( "inSplashMenu", 1 );
  10851. // g_demoStartFade = 0;
  10852. // g_demoStartTransition = 0;
  10853. }
  10854. void G_DemoKeypress()
  10855. {
  10856. g_demoLastKeypress = Sys_Milliseconds();
  10857. //JLF moved
  10858. // g_demoLastKeypress = Sys_Milliseconds();
  10859. }
  10860. extern void UI_SetActiveMenu( const char* menuname,const char *menuID );
  10861. void G_DemoEnd()
  10862. {
  10863. if (!g_runningDemo)
  10864. return;
  10865. //CIN_StopCinematic(1);
  10866. CIN_CloseAllVideos();
  10867. // Key_SetCatcher( KEYCATCH_UI );
  10868. Menus_CloseAll();
  10869. g_ReturnToSplash = true;
  10870. g_runningDemo = qfalse;
  10871. G_DemoKeypress();
  10872. trap_Key_SetCatcher( trap_Key_GetCatcher() & KEYCATCH_UI );
  10873. trap_Key_ClearStates();
  10874. Cvar_Set( "cl_paused", "0" );
  10875. UI_SetActiveMenu("splashMenu", NULL);
  10876. // g_demoStartFade = 0;
  10877. // g_demoStartTransition = 0;
  10878. // g_demoLastKeypress = 0;
  10879. }
  10880. void PlayDemo()
  10881. {
  10882. // bool keypressed = false;
  10883. G_DemoStart();
  10884. CIN_PlayAllFrames( "attract", 0, 0, 640, 480, 0, true );
  10885. // while (!keypressed)
  10886. // keypressed = CIN_PlayAllFrames( "atvi.bik", 0, 0, 640, 480, 0, true );
  10887. G_DemoEnd();
  10888. }
  10889. void UpdateDemoTimer()
  10890. {
  10891. g_demoLastKeypress = Sys_Milliseconds();
  10892. }
  10893. bool TestDemoTimer()
  10894. {
  10895. //JLF TEMP DEBUG
  10896. // return false;
  10897. menuDef_t* curMenu = Menu_GetFocused();
  10898. if (curMenu && curMenu->window.name &&
  10899. (!Q_stricmp(curMenu->window.name , "mainMenu") ||
  10900. !Q_stricmp(curMenu->window.name, "splashMenu")))
  10901. {
  10902. if (!g_demoLastKeypress)
  10903. g_demoLastKeypress = Sys_Milliseconds();
  10904. else if (g_demoLastKeypress + DEMO_TIME_MAX < Sys_Milliseconds())
  10905. return true;
  10906. }
  10907. return false;
  10908. }
  10909. //END DEMOCODE
  10910. #endif // _XBOX