Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

TombRaider.cpp 192KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : OpenRaider
  5. * Author : Mongoose
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : OpenRaider
  9. * License : No use w/o permission (C) 2001 Mongoose
  10. * Comments: Loads TR 1, 2, 3, and 4 maps, meshes, and textures
  11. *
  12. * This file was generated using Mongoose's C++
  13. * template generator script. <stu7440@westga.edu>
  14. *
  15. *-- History ------------------------------------------------
  16. *
  17. * 2003.05.13:
  18. * Mongoose - New API, maintance cost was becoming so high
  19. * it was needed to sort out methods in groups
  20. * like my newer source code -- of course some
  21. * methods were altered or removed ( clean up )
  22. *
  23. * 2001.06.19:
  24. * Mongoose - New texture API for the new TR4/TR5 bump map
  25. * support, also purged textile exposure
  26. *
  27. * 2001.05.21:
  28. * Mongoose - Added to project OpenRaider, more documentation
  29. * than Freyja version I wrote ( 3d modeler )
  30. *
  31. *
  32. * 2000-05-13:
  33. * Mongoose - Added gcc and VC++ pragmas for packing
  34. *
  35. * id style typedefs for structs
  36. *
  37. * Heavy clean up and ported to C++
  38. *
  39. * I saved yuri's notes as best I could and
  40. * reformatted and corected as needed
  41. *
  42. * Mongoose - Created, based on:
  43. * tr_view's tr2io.c by Yuri Zhivago, PhD,
  44. * TR Rosetta Stone ( TombRaider pak format specs )
  45. ================================================================*/
  46. #include <stdlib.h>
  47. #include <stdio.h>
  48. #include <math.h>
  49. #include <string.h>
  50. #include <stdarg.h>
  51. #include <zlib.h>
  52. #include "TombRaider.h"
  53. #ifdef __TEST_TR5_DUMP_TGA
  54. #include "TGA.h"
  55. #endif
  56. TombRaider::TombRaider()
  57. {
  58. _textile8 = NULL;
  59. _textile16 = NULL;
  60. _textile32 = NULL;
  61. _tex_special = NULL;
  62. _rooms = NULL;
  63. _floor_data = NULL;
  64. _animations = NULL;
  65. _state_changes = NULL;
  66. _anim_dispatches = NULL;
  67. _anim_commands = NULL;
  68. _mesh_trees = NULL;
  69. _frames = NULL;
  70. _moveables = NULL;
  71. _static_meshes = NULL;
  72. _object_textures = NULL;
  73. _sprite_textures = NULL;
  74. _sprite_sequences = NULL;
  75. _cameras = NULL;
  76. _sound_sources = NULL;
  77. _boxes = NULL;
  78. _overlaps = NULL;
  79. _zones = NULL;
  80. _animated_textures = NULL;
  81. _items = NULL;
  82. _light_map = NULL;
  83. _cinematic_frames = NULL;
  84. _demo_data = NULL;
  85. mRoomsTR5 = 0x0;
  86. mMeshes = 0x0;
  87. mSoundMap = 0x0;
  88. mSoundDetails = 0x0;
  89. mSampleIndices = 0x0;
  90. mSampleIndicesTR5 = 0x0;
  91. mRiffData = 0x0;
  92. mTR4Samples = 0x0;
  93. mTR4SamplesSz = 0x0;
  94. mRiffAlternateOffsets = 0x0;
  95. mCompressedLevelData = 0x0;
  96. moveablesTR5 = 0x0;
  97. animationsTR5 = 0x0;
  98. objectTexturesTR5 = 0x0;
  99. cinematicFramesTR5 = 0x0;
  100. flyByCamerasTR5 = 0x0;
  101. mNumTR4Samples = 0;
  102. mReset = false;
  103. mDebug = false;
  104. mRiffAlternateLoaded = false;
  105. mRoomVertexLightingFactor = 50.0f;
  106. mTexelScale = 256.0f;
  107. mRiffDataSz = 0;
  108. reset();
  109. }
  110. TombRaider::~TombRaider()
  111. {
  112. reset();
  113. }
  114. int TombRaider::NumMoveables()
  115. {
  116. return _num_moveables;
  117. }
  118. int TombRaider::NumRooms()
  119. {
  120. return _num_rooms;
  121. }
  122. int TombRaider::NumAnimations()
  123. {
  124. return _num_animations;
  125. }
  126. unsigned int TombRaider::NumFrames()
  127. {
  128. return _num_frames;
  129. }
  130. int TombRaider::NumStaticMeshes()
  131. {
  132. return _num_static_meshes;
  133. }
  134. int TombRaider::NumSprites()
  135. {
  136. return _num_sprite_textures;
  137. }
  138. int TombRaider::NumSpriteSequences()
  139. {
  140. return _num_sprite_sequences;
  141. }
  142. int TombRaider::NumItems()
  143. {
  144. return _num_items;
  145. }
  146. int TombRaider::NumTextures()
  147. {
  148. //return _num_room_textures + _num_misc_textures + _num_bump_map_textures / 2;
  149. return _num_textiles - _num_bump_map_textures / 2;
  150. }
  151. tr2_room_t *TombRaider::Room()
  152. {
  153. return _rooms;
  154. }
  155. tr2_item_t *TombRaider::Item()
  156. {
  157. return _items;
  158. }
  159. tr2_object_texture_t *TombRaider::ObjectTextures()
  160. {
  161. return _object_textures;
  162. }
  163. unsigned int TombRaider::getNumBoxes()
  164. {
  165. return _num_boxes;
  166. }
  167. tr2_box_t *TombRaider::Box()
  168. {
  169. return _boxes;
  170. }
  171. tr2_mesh_t *TombRaider::Mesh()
  172. {
  173. /*
  174. if (n > 0 || n > mMeshCount)
  175. return NULL;
  176. return _meshes+n;
  177. */
  178. return mMeshes;
  179. }
  180. int TombRaider::getNumAnimsForMoveable(int moveable_index)
  181. {
  182. /***************************************************************************
  183. * It seems the number of animations isn't available in the moveable,
  184. * so we have to calculate it:
  185. * - Get the "# starting anim" for the next moveable (->N)
  186. * - Substract the "# starting anim" for moveable to N
  187. *
  188. * Doing this, we assume that the next moveable has its animations following
  189. * the animations of the current moveable (seems right for all tested
  190. * levels, but...)
  191. *
  192. * We also have to deal with the fact that the next moveable
  193. * could have "# starting anim" == -1
  194. * (ie. anim handled by the engine, like the ponytail anim).
  195. * If it's the case, we skip the moveable
  196. * and use the next moveable for our computation
  197. *
  198. * - Mongoose, Notes I edited from TRViewer
  199. **************************************************************************/
  200. int start_anim;
  201. int next_start_anim = 0xFFFF;
  202. tr2_moveable_t *last_moveable = 0x0;
  203. tr2_moveable_t *moveable = 0x0;
  204. tr2_moveable_t *next_moveable = 0x0;
  205. if ((moveable_index >= 0 &&
  206. moveable_index <= (int)_num_moveables) || _num_moveables < 1)
  207. {
  208. moveable = &_moveables[moveable_index];
  209. }
  210. if (!moveable)
  211. {
  212. return -1; // Was 0
  213. }
  214. last_moveable = &_moveables[moveable_index-1];
  215. start_anim = moveable->animation;
  216. while (moveable != last_moveable)
  217. {
  218. next_moveable = moveable + 1;
  219. next_start_anim = next_moveable->animation;
  220. if (next_start_anim != 0xFFFF)
  221. break;
  222. moveable = next_moveable++;
  223. }
  224. if (moveable == last_moveable)
  225. {
  226. next_start_anim = _num_animations;
  227. }
  228. return ((start_anim != 0xFFFF) ? next_start_anim - start_anim : 0);
  229. }
  230. tr2_staticmesh_t *TombRaider::StaticMesh()
  231. {
  232. return _static_meshes;
  233. }
  234. tr2_version_type TombRaider::Engine()
  235. {
  236. return mEngineVersion;
  237. }
  238. tr2_animation_t *TombRaider::Animation()
  239. {
  240. return _animations;
  241. }
  242. unsigned short *TombRaider::Frame()
  243. {
  244. return _frames;
  245. }
  246. tr2_moveable_t *TombRaider::Moveable()
  247. {
  248. /*
  249. if (n > 0 || n > (int)_num_moveables)
  250. return NULL;
  251. */
  252. return _moveables;
  253. }
  254. tr2_meshtree_t *TombRaider::MeshTree()
  255. {
  256. /*
  257. if (n > 0 || n > (int)_num_mesh_trees)
  258. return NULL;
  259. */
  260. return _mesh_trees;
  261. }
  262. tr2_sprite_texture_t *TombRaider::Sprite()
  263. {
  264. return _sprite_textures;
  265. }
  266. tr2_sprite_sequence_t *TombRaider::SpriteSequence()
  267. {
  268. return _sprite_sequences;
  269. }
  270. unsigned char *TombRaider::SpecialTexTile(int texture)
  271. {
  272. unsigned char *image;
  273. unsigned char *ptr;
  274. image = NULL;
  275. if (texture >=0 && texture < NumSpecialTextures())
  276. {
  277. // Get base and offset into 32bit special textures/bump maps
  278. ptr = _tex_special;
  279. ptr += 256*256*4*texture;
  280. // Clone it as a single 256x256 @ 32bpp image
  281. image = new unsigned char[256*256*4];
  282. memcpy(image, ptr, 256*256*4);
  283. }
  284. return image;
  285. }
  286. int TombRaider::NumSpecialTextures()
  287. {
  288. return _num_tex_special;
  289. }
  290. void TombRaider::Texture(int texture, unsigned char **image,
  291. unsigned char **bumpmap)
  292. {
  293. int bumpmap_base = _num_room_textures + _num_misc_textures;
  294. *image = getTexTile(texture);
  295. *bumpmap = NULL;
  296. if (_num_bump_map_textures && texture >= bumpmap_base)
  297. {
  298. *bumpmap = getTexTile(texture + _num_bump_map_textures/2);
  299. }
  300. }
  301. unsigned int *TombRaider::Palette16()
  302. {
  303. return _palette16;
  304. }
  305. unsigned char *TombRaider::Palette8()
  306. {
  307. return (unsigned char *)_palette8;
  308. }
  309. int TombRaider::checkMime(char *filename)
  310. {
  311. FILE *f;
  312. unsigned int version;
  313. if (!filename || !filename[0])
  314. {
  315. print("checkFile", "Given filename was empty string or NULL");
  316. return -1;
  317. }
  318. f = fopen(filename, "rb");
  319. if (!f)
  320. {
  321. perror(filename);
  322. return -1;
  323. }
  324. //! \fixme Endianess
  325. fread(&version, sizeof(version), 1, f);
  326. fclose(f);
  327. switch (version)
  328. {
  329. case 0x00000020:
  330. case 0x0000002d:
  331. case 0xff080038:
  332. case 0xff180038:
  333. case 0xfffffff0: // bogus
  334. case 0x00345254: // "TR4\0"
  335. return 0;
  336. default:
  337. ;
  338. }
  339. return 1;
  340. }
  341. int TombRaider::Load(char *filename, void (*percent)(int))
  342. {
  343. FILE *f;
  344. int i, j, l;
  345. unsigned int num_mesh_data_words, num_mesh_pointers, data_size, data_offset;
  346. unsigned int *mesh_pointer_list;
  347. unsigned char *raw_mesh_data;
  348. bool tr5;
  349. long debugf;
  350. f = fopen(filename, "rb");
  351. if (!f)
  352. {
  353. perror(filename);
  354. return -1;
  355. }
  356. if (percent)
  357. (*percent)(1);
  358. mReset = false;
  359. Fread(&mPakVersion, sizeof(mPakVersion), 1, f);
  360. //! \fixme endian
  361. printDebug("Load", "mPakVersion = %u", mPakVersion);
  362. tr5 = false;
  363. switch (mPakVersion)
  364. {
  365. case 0x00000020:
  366. mEngineVersion = TR_VERSION_1;
  367. break;
  368. case 0x0000002d:
  369. mEngineVersion = TR_VERSION_2;
  370. break;
  371. case 0xff080038:
  372. case 0xff180038:
  373. mEngineVersion = TR_VERSION_3;
  374. break;
  375. case 0xfffffff0: // bogus
  376. case 0x00345254: // "TR4\0"
  377. mEngineVersion = TR_VERSION_4;
  378. // Check to see if this is really a TR5 demo
  379. l = strlen(filename);
  380. // Looking for pattern "filename.trc"
  381. if ((filename[l-1] == 'c' || filename[l-1] == 'C') &&
  382. (filename[l-2] == 'r' || filename[l-2] == 'R') &&
  383. (filename[l-3] == 't' || filename[l-3] == 'T'))
  384. {
  385. printDebug("Load", "This is really a TR5 pak");
  386. mEngineVersion = TR_VERSION_5;
  387. return loadTR5(f, percent);
  388. }
  389. break;
  390. default:
  391. mEngineVersion = TR_VERSION_UNKNOWN;
  392. }
  393. if (percent)
  394. (*percent)(5);
  395. printDebug("Load", "mEngineVersion = 0x%x", mPakVersion);
  396. if (mEngineVersion == TR_VERSION_UNKNOWN)
  397. return -1;
  398. if (mEngineVersion == TR_VERSION_4)
  399. {
  400. unsigned int sz, usz; // compressed and uncompressed size
  401. unsigned char *compressed_data = NULL;
  402. int zerr;
  403. uLongf foo;
  404. // Read texture type offsets
  405. Fread(&_num_room_textures, 2, 1, f);
  406. printDebug("LoadTR4", "_num_room_textures = %u", _num_room_textures);
  407. Fread(&_num_misc_textures, 2, 1, f);
  408. printDebug("LoadTR4", "_num_misc_textures = %u", _num_misc_textures);
  409. Fread(&_num_bump_map_textures, 2, 1, f);
  410. printDebug("LoadTR4", "_num_bump_map_textures = %u", _num_bump_map_textures);
  411. // Read the sizes of the 32-bit textures
  412. Fread(&usz, sizeof(usz), 1, f);
  413. Fread(&sz, sizeof(sz), 1, f);
  414. printDebug("Load", "TR4 32-bit textures compressed size = %u bytes", sz);
  415. printDebug("Load", "TR4 32-bit textures uncompressed size = %u bytes", usz);
  416. _num_textiles = usz / sizeof(tr2_textile32_t);
  417. printDebug("LoadTR4", "_num_textiles = %i/%lu = %i",
  418. usz, sizeof(tr2_textile32_t), _num_textiles);
  419. _textile32 = new tr2_textile32_t[_num_textiles];
  420. // Allocate a temporary buffer for decompression
  421. compressed_data = new unsigned char[sz];
  422. Fread(compressed_data, sz, 1, f);
  423. // Decompress the textures
  424. foo = usz;
  425. zerr = uncompress((unsigned char *)_textile32,
  426. &foo,
  427. compressed_data,
  428. sz);
  429. usz = foo;
  430. if (percent)
  431. (*percent)(6);
  432. printDebug("LoadTR4", "textile decompress [%s]",
  433. (zerr == Z_OK) ? "OK" : "ERROR");
  434. switch (zerr)
  435. {
  436. case Z_MEM_ERROR:
  437. printDebug("LoadTR4", "There was not enough memory");
  438. break;
  439. case Z_BUF_ERROR:
  440. printDebug("LoadTR4", "There was not enough room in the output buffer");
  441. break;
  442. case Z_DATA_ERROR:
  443. printDebug("LoadTR4", "The input data was corrupted");
  444. break;
  445. default:
  446. printDebug("LoadTR4", "textile decompress %i", zerr);
  447. }
  448. // Free the temporary buffer
  449. delete [] compressed_data;
  450. // Read in the 16-bit textures, set NumTextiles
  451. Fread(&usz, sizeof(usz), 1, f);
  452. Fread(&sz, sizeof(sz), 1, f);
  453. printDebug("Load", "TR4 16-bit textures compressed size = %u bytes", sz);
  454. printDebug("Load", "TR4 16-bit textures uncompressed size = %u bytes", usz);
  455. _num_textiles = usz / sizeof(tr2_textile16_t);
  456. printDebug("Load", "TR4 _num_textiles = %i/%lu = %i",
  457. usz, sizeof(tr2_textile16_t), _num_textiles);
  458. _textile16 = new tr2_textile16_t[_num_textiles];
  459. // Allocate a temporary buffer for decompression
  460. compressed_data = new unsigned char[sz];
  461. Fread(compressed_data, sz, 1, f);
  462. // Decompress the textures
  463. foo = usz;
  464. zerr = uncompress((unsigned char *)_textile16,
  465. &foo,
  466. compressed_data,
  467. sz);
  468. usz = foo;
  469. if (percent)
  470. (*percent)(7);
  471. // printDebug("Load", "TR4 textile decompress [%s]",
  472. // (zerr == Z_OK) ? "OK" : "ERROR");
  473. switch (zerr)
  474. {
  475. case Z_MEM_ERROR:
  476. printDebug("Load", "TR4 textile decompress [ERROR]");
  477. printDebug("Load", "TR4 There was not enough memory");
  478. break;
  479. case Z_BUF_ERROR:
  480. printDebug("Load", "TR4 textile decompress [ERROR]");
  481. printDebug("Load", "TR4 There was not enough room in the output buffer");
  482. break;
  483. case Z_DATA_ERROR:
  484. printDebug("Load", "TR4 textile decompress [ERROR]");
  485. printDebug("Load", "TR4 The input data was corrupted");
  486. break;
  487. case Z_OK:
  488. printDebug("Load", "TR4 textile decompress [OK]");
  489. break;
  490. default:
  491. printDebug("Load", "TR4 textile decompress %i", zerr);
  492. }
  493. // Free the temporary buffer
  494. delete [] compressed_data;
  495. // Read the sizes of the sprite textures
  496. Fread(&usz, sizeof(usz), 1, f);
  497. Fread(&sz, sizeof(sz), 1, f);
  498. printDebug("Load", "TR4 sprite textures compressed size = %u bytes", sz);
  499. printDebug("Load", "TR4 sprite textures uncompressed size = %u bytes", usz);
  500. // Load sprite/bump map/gui/etc textures also
  501. _num_tex_special = usz/(256*256*4);
  502. printDebug("LoadTR5", "_num_tex_special = %i/%i = %i",
  503. usz, 256*256*4, _num_tex_special);
  504. printDebug("LoadTR5", "Reading %ibytes of sprite textures", usz);
  505. if (usz)
  506. {
  507. _tex_special = new unsigned char[usz];
  508. // Allocate a temporary buffer for decompression
  509. compressed_data = new unsigned char[sz];
  510. Fread(compressed_data, sz, 1, f);
  511. // Decompress the textures
  512. foo = usz;
  513. zerr = uncompress(_tex_special,
  514. &foo,
  515. compressed_data,
  516. sz);
  517. usz = foo;
  518. printDebug("LoadTR5", "special texture decompress [%s]",
  519. (zerr == Z_OK) ? "OK" : "ERROR");
  520. switch (zerr)
  521. {
  522. case Z_MEM_ERROR:
  523. printDebug("LoadTR5", "There was not enough memory");
  524. break;
  525. case Z_BUF_ERROR:
  526. printDebug("LoadTR5", "There was not enough room in the output buffer");
  527. break;
  528. case Z_DATA_ERROR:
  529. printDebug("LoadTR5", "The input data was corrupted");
  530. break;
  531. default:
  532. printDebug("LoadTR5", "textile decompress %i", zerr);
  533. }
  534. // Free the temporary buffer
  535. delete [] compressed_data;
  536. }
  537. if (percent)
  538. (*percent)(9);
  539. // Read the sizes of the level data
  540. Fread(&usz, sizeof(usz), 1, f);
  541. Fread(&sz, sizeof(sz), 1, f);
  542. printDebug("Load", "TR4 level data compressed size = %u bytes", sz);
  543. printDebug("Load", "TR4 level data uncompressed size = %u bytes", usz);
  544. // Allocate a temporary buffer for decompression
  545. compressed_data = new unsigned char[sz];
  546. Fread(compressed_data, sz, 1, f);
  547. mCompressedLevelData = new unsigned char[usz];
  548. // Decompress the level data
  549. foo = usz;
  550. zerr = uncompress(mCompressedLevelData, &foo, compressed_data, sz);
  551. usz = foo;
  552. printDebug("Load", "TR4 level data decompress [%s]",
  553. (zerr == Z_OK) ? "OK" : "ERROR");
  554. switch (zerr)
  555. {
  556. case Z_MEM_ERROR:
  557. printDebug("Load", "TR4 There was not enough memory");
  558. break;
  559. case Z_BUF_ERROR:
  560. printDebug("Load", "TR4 There was not enough room in the output buffer");
  561. break;
  562. case Z_DATA_ERROR:
  563. printDebug("Load", "TR4 The input data was corrupted");
  564. break;
  565. }
  566. delete [] compressed_data;
  567. mCompressedLevelDataOffset = 0;
  568. mCompressedLevelSize = usz;
  569. // Toggle Fread mode to read from decompressed data in memory, not diskfile
  570. mFreadMode = TR_FREAD_COMPRESSED;
  571. }
  572. if (mEngineVersion == TR_VERSION_2 || mEngineVersion == TR_VERSION_3)
  573. {
  574. /* Read the 8-bit palette */
  575. Fread(_palette8, sizeof(tr2_colour_t), 256, f);
  576. /* Read 16-bit palette */
  577. Fread(_palette16, sizeof(_palette16), 1, f);
  578. printDebug("Load", "Read TR 2|3 8bit and 16bit palettes");
  579. }
  580. if (mEngineVersion != TR_VERSION_4)
  581. {
  582. /* Read the textiles */
  583. Fread(&_num_textiles, sizeof(_num_textiles), 1, f);
  584. printDebug("Load", "_num_textiles = %i", _num_textiles);
  585. /* 8-bit textiles come first */
  586. _textile8 = new tr2_textile8_t[_num_textiles];
  587. Fread(_textile8, sizeof(tr2_textile8_t), _num_textiles, f);
  588. /* 16-bit textiles come second */
  589. _textile16 = new tr2_textile16_t[_num_textiles];
  590. if (mEngineVersion != TR_VERSION_1)
  591. {
  592. //! \fixme need endian checking here
  593. Fread(_textile16, sizeof(tr2_textile16_t), _num_textiles, f);
  594. printDebug("Load", "Read in 16bit texture tiles");
  595. }
  596. }
  597. if (percent)
  598. (*percent)(10);
  599. /* 32-bit unknown - seems to always be 0 */
  600. Fread(&_unknown_t, sizeof(_unknown_t), 1, f);
  601. printDebug("Load", "_unknown_t = 0x%x", _unknown_t);
  602. /* Read raw room data */
  603. //! \fixme needs endian checking
  604. Fread(&_num_rooms, sizeof(_num_rooms), 1, f);
  605. printDebug("Load", "_num_rooms = %i", _num_rooms);
  606. data_size = _num_rooms * sizeof(tr2_room_t);
  607. _rooms = new tr2_room_t[_num_rooms];
  608. /* Extract room details */
  609. for (i = 0; i < _num_rooms; ++i)
  610. {
  611. if (percent)
  612. {
  613. (*percent)(11 + (int)(((float)i/(float)_num_rooms)*70.0));
  614. }
  615. /* Read RoomInfo */
  616. //! \fixme endian check needed
  617. Fread(&_rooms[i].info, sizeof(tr2_room_info_t), 1, f);
  618. printDebug("Load", "_rooms[%i].info =\n { x=%i, z=%i, yt=%i, yb=%i}",
  619. i,
  620. _rooms[i].info.x, _rooms[i].info.z,
  621. _rooms[i].info.y_top, _rooms[i].info.y_bottom);
  622. /* Read raw data for rest of room */
  623. Fread(&_rooms[i].num_data_words, sizeof(_rooms[i].num_data_words), 1, f);
  624. printDebug("Load", "_rooms[%i].num_data_words = %u",
  625. i, _rooms[i].num_data_words);
  626. _rooms[i].data = new unsigned char[_rooms[i].num_data_words*2];
  627. Fread(_rooms[i].data, 2, _rooms[i].num_data_words, f);
  628. /* Identify vertices */
  629. data_offset = 0;
  630. //! \fixme endian
  631. _rooms[i].room_data.num_vertices = *(short *)(void *)(_rooms[i].data);
  632. data_offset += sizeof(_rooms[0].room_data.num_vertices);
  633. data_size = _rooms[i].room_data.num_vertices * sizeof(tr2_vertex_room_t);
  634. printDebug("Load", "_rooms[%i].room_data.num_vertices = %u",
  635. i, _rooms[i].room_data.num_vertices);
  636. _rooms[i].room_data.vertices = 0x0;
  637. if (_rooms[i].room_data.num_vertices > 0)
  638. {
  639. _rooms[i].room_data.vertices =
  640. new tr2_vertex_room_t[_rooms[i].room_data.num_vertices];
  641. if (mEngineVersion == TR_VERSION_1)
  642. {
  643. data_size = _rooms[i].room_data.num_vertices *
  644. (sizeof(tr2_vertex_room_t) - 4);
  645. for (j = 0; j < _rooms[i].room_data.num_vertices; ++j)
  646. {
  647. memcpy(&_rooms[i].room_data.vertices[j],
  648. _rooms[i].data + data_offset +
  649. (j * (sizeof(tr2_vertex_room_t) - 4)),
  650. sizeof(tr2_vertex_room_t) - 4);
  651. // ??? Adjust for what's missing?
  652. _rooms[i].room_data.vertices[j].lighting2 =
  653. _rooms[i].room_data.vertices[j].lighting1;
  654. _rooms[i].room_data.vertices[j].attributes = 0;
  655. }
  656. }
  657. else
  658. {
  659. memcpy(_rooms[i].room_data.vertices,
  660. _rooms[i].data + data_offset, data_size);
  661. }
  662. //! \fixme endian conversions for verts needed
  663. }
  664. data_offset += data_size;
  665. /* identify rectangles */
  666. //! \fixme endian conversion
  667. _rooms[i].room_data.num_rectangles =
  668. *(short *)(void *)(_rooms[i].data + data_offset);
  669. data_offset += sizeof(_rooms[0].room_data.num_rectangles);
  670. data_size = _rooms[i].room_data.num_rectangles * sizeof(tr2_quad_t);
  671. printDebug("Load", "_rooms[%i].room_data.num_rectangles = %i",
  672. i, _rooms[i].room_data.num_rectangles);
  673. _rooms[i].room_data.rectangles = 0x0;
  674. if (_rooms[i].room_data.num_rectangles > 0)
  675. {
  676. _rooms[i].room_data.rectangles =
  677. new tr2_quad_t[_rooms[i].room_data.num_rectangles];
  678. memcpy(_rooms[i].room_data.rectangles,
  679. _rooms[i].data + data_offset, data_size);
  680. if (mEngineVersion >= TR_VERSION_3)
  681. {
  682. for (j = 0; j < _rooms[i].room_data.num_rectangles; ++j)
  683. {
  684. _rooms[i].room_data.rectangles[j].texture &= 0x7fff;
  685. }
  686. }
  687. //! \fixme endian conversion
  688. }
  689. data_offset += data_size;
  690. /* Identify triangles */
  691. _rooms[i].room_data.num_triangles =
  692. *(short *)(void *)(_rooms[i].data + data_offset);
  693. //! \fixme endian
  694. data_offset += sizeof(_rooms[0].room_data.num_triangles);
  695. data_size = _rooms[i].room_data.num_triangles * sizeof(tr2_tri_t);
  696. printDebug("Load", "_rooms[%i].room_data.num_triangles = %i",
  697. i, _rooms[i].room_data.num_triangles);
  698. _rooms[i].room_data.triangles = 0x0;
  699. if (_rooms[i].room_data.num_triangles > 0)
  700. {
  701. _rooms[i].room_data.triangles =
  702. new tr2_tri_t[_rooms[i].room_data.num_triangles];
  703. memcpy(_rooms[i].room_data.triangles,
  704. _rooms[i].data + data_offset, data_size);
  705. if (mEngineVersion >= TR_VERSION_3)
  706. {
  707. for (j = 0; j < _rooms[i].room_data.num_triangles; ++j)
  708. {
  709. _rooms[i].room_data.triangles[j].texture &= 0x7fff;
  710. }
  711. //! \fixme endian
  712. }
  713. }
  714. data_offset += data_size;
  715. /* Identify sprites */
  716. _rooms[i].room_data.num_sprites =
  717. *(short *)(void *)(_rooms[i].data + data_offset);
  718. //! \fixme endian
  719. data_offset += sizeof(_rooms[0].room_data.num_sprites);
  720. data_size = _rooms[i].room_data.num_sprites * sizeof(tr2_room_sprite_t);
  721. printDebug("Load", "_rooms[%i].room_data.num_sprites = %i",
  722. i, _rooms[i].room_data.num_sprites);
  723. _rooms[i].room_data.sprites = 0x0;
  724. if (_rooms[i].room_data.num_sprites > 0)
  725. {
  726. _rooms[i].room_data.sprites =
  727. new tr2_room_sprite_t[_rooms[i].room_data.num_sprites];
  728. memcpy(_rooms[i].room_data.sprites,
  729. _rooms[i].data + data_offset, data_size);
  730. if (mEngineVersion >= TR_VERSION_3)
  731. {
  732. for (j = 0; j < _rooms[i].room_data.num_sprites; j++)
  733. {
  734. _rooms[i].room_data.sprites[j].texture &= 0x7fff;
  735. }
  736. }
  737. //! \fixme endian
  738. }
  739. /* Free the raw room data */
  740. delete [] _rooms[i].data;
  741. _rooms[i].data = NULL;
  742. /* Read door info */
  743. //! \fixme endian
  744. Fread(&_rooms[i].num_portals, sizeof(_rooms[0].num_portals), 1, f);
  745. printDebug("Load", "_rooms[%i].num_portals = %i",
  746. i, _rooms[i].num_portals);
  747. if (_rooms[i].num_portals > 0)
  748. _rooms[i].portals = new tr2_room_portal_t[_rooms[i].num_portals];
  749. else
  750. _rooms[i].portals = 0;
  751. Fread(_rooms[i].portals, sizeof(tr2_room_portal_t),
  752. _rooms[i].num_portals, f);
  753. //! \fixme endian
  754. /* Read sector info */
  755. //! \fixme endian
  756. Fread(&_rooms[i].num_zsectors, sizeof(_rooms[0].num_zsectors), 1, f);
  757. Fread(&_rooms[i].num_xsectors, sizeof(_rooms[0].num_xsectors), 1, f);
  758. printDebug("Load", "_rooms[%i].num_zsectors = %i",
  759. i, _rooms[i].num_zsectors);
  760. printDebug("Load", "_rooms[%i].num_xsectors = %i",
  761. i, _rooms[i].num_xsectors);
  762. if (_rooms[i].num_zsectors > 0 && _rooms[i].num_xsectors > 0)
  763. {
  764. _rooms[i].sector_list =
  765. new tr2_room_sector_t[_rooms[i].num_zsectors * _rooms[i].num_xsectors];
  766. }
  767. else
  768. {
  769. _rooms[i].sector_list = 0x0;
  770. }
  771. Fread(_rooms[i].sector_list, sizeof(tr2_room_sector_t),
  772. _rooms[i].num_zsectors * _rooms[i].num_xsectors, f);
  773. //! \fixme endian
  774. printDebug("Load", "Read %u room sectors",
  775. _rooms[i].num_zsectors * _rooms[i].num_xsectors);
  776. /* Read room lighting & mode */
  777. if (mEngineVersion >= TR_VERSION_3)
  778. {
  779. Fread(&_rooms[i].intensity1, 4, 1, f);
  780. // Fake TR2 record:
  781. _rooms[i].light_mode = 0;
  782. }
  783. else if (mEngineVersion == TR_VERSION_1)
  784. {
  785. Fread(&_rooms[i].intensity1, 2, 1, f);
  786. // Is this intensity or LightMode?
  787. printDebug("Load", "_rooms[%i].intensity1 = %u",
  788. i, _rooms[i].intensity1);
  789. _rooms[i].intensity2 = _rooms[i].intensity1;
  790. _rooms[i].light_mode = 0;
  791. }
  792. else
  793. { // TR2
  794. Fread(&_rooms[i].intensity1, 6, 1, f);
  795. printDebug("Load", "TR2 _rooms[%i].intensity1 = %u",
  796. i, _rooms[i].intensity1);
  797. }
  798. /* Read room lighting info */
  799. //! \fixme endian
  800. Fread(&_rooms[i].num_lights, sizeof(_rooms[i].num_lights), 1, f);
  801. printDebug("Load", "_rooms[%i].num_lights = %u",
  802. i, _rooms[i].num_lights);
  803. _rooms[i].lights = 0x0;
  804. _rooms[i].tr4Lights = 0x0;
  805. // Mongoose 2002.04.03, New TR4 light struct, removed old
  806. // double size for others
  807. if (_rooms[i].num_lights > 0)
  808. {
  809. if (mEngineVersion == TR_VERSION_1)
  810. {
  811. _rooms[i].lights = new tr2_room_light_t[_rooms[i].num_lights];
  812. for (j = 0; j < _rooms[i].num_lights; ++j)
  813. {
  814. Fread(&_rooms[i].lights[j].x, sizeof(_rooms[0].lights[0].x), 3,f);
  815. // x, y, z
  816. printDebug("Load", "_rooms[%i].lights[%i] = <%i %i %i>",
  817. i, j,
  818. _rooms[i].lights[j].x,
  819. _rooms[i].lights[j].y,
  820. _rooms[i].lights[j].z);
  821. Fread(&_rooms[i].lights[j].intensity1, sizeof(short), 1, f);
  822. // Intensity1
  823. printDebug("Load", "_rooms[%i].lights[%i].intensity1 = %u",
  824. i, j,
  825. _rooms[i].lights[j].intensity1);
  826. _rooms[i].lights[j].intensity2 = _rooms[i].lights[j].intensity1;
  827. Fread(&_rooms[i].lights[j].fade1, sizeof(unsigned int), 1, f);
  828. // Fade1
  829. printDebug("Load", "_rooms[%i].lights[%i].fade1 = %u",
  830. i, j,
  831. _rooms[i].lights[j].fade1);
  832. _rooms[i].lights[j].fade2 = _rooms[i].lights[j].fade1;
  833. }
  834. }
  835. else if (mEngineVersion == TR_VERSION_4)
  836. {
  837. _rooms[i].tr4Lights = new tr4_room_light_t[_rooms[i].num_lights];
  838. Fread(_rooms[i].tr4Lights, sizeof(tr4_room_light_t),
  839. _rooms[i].num_lights, f);
  840. }
  841. else
  842. {
  843. _rooms[i].lights = new tr2_room_light_t[_rooms[i].num_lights];
  844. Fread(_rooms[i].lights, sizeof(tr2_room_light_t),
  845. _rooms[i].num_lights, f);
  846. }
  847. }
  848. //! \fixme endian
  849. /* Read Static Mesh Data */
  850. Fread(&_rooms[i].num_static_meshes, sizeof(unsigned short), 1, f);
  851. //! \fixme endian
  852. printDebug("Load", "_rooms[%i].num_static_meshes = %u",
  853. i, _rooms[i].num_static_meshes);
  854. _rooms[i].static_meshes = 0x0;
  855. if (_rooms[i].num_static_meshes > 0)
  856. {
  857. _rooms[i].static_meshes =
  858. new tr2_room_staticmesh_t[_rooms[i].num_static_meshes];
  859. if (mEngineVersion == TR_VERSION_1)
  860. {
  861. for (j = 0; j < _rooms[i].num_static_meshes; j++)
  862. {
  863. Fread(&_rooms[i].static_meshes[j], 18, 1, f);
  864. // Account for the missing .intensity2
  865. _rooms[i].static_meshes[j].object_id =
  866. _rooms[i].static_meshes[j].intensity2;
  867. _rooms[i].static_meshes[j].intensity2 =
  868. _rooms[i].static_meshes[j].intensity1;
  869. }
  870. }
  871. else
  872. {
  873. Fread(_rooms[i].static_meshes, sizeof(tr2_room_staticmesh_t),
  874. _rooms[i].num_static_meshes, f);
  875. }
  876. }
  877. //! \fixme endian
  878. Fread(&_rooms[i].alternate_room, sizeof(short), 1, f);
  879. //! \fixme endian
  880. printDebug("Load", "_rooms[%i].alternate_room = %i",
  881. i, _rooms[i].alternate_room);
  882. Fread(&_rooms[i].flags, sizeof(short), 1, f);
  883. //! \fixme endian
  884. printDebug("Load", "_rooms[%i].flags = 0x%x",
  885. i, _rooms[i].flags);
  886. /* Read TR3 room light colour */
  887. if (mEngineVersion >= TR_VERSION_3)
  888. {
  889. /* we force this to be 3 bytes
  890. (instead of just sizeof(room_light_colour))
  891. for Macs and others that can't handle odd-length structures...
  892. */
  893. Fread(&_rooms[i].room_light_colour, 3, 1, f);
  894. printDebug("Load", "TR3 _rooms[%i].room_light_colour {%i %i %i}",
  895. i,
  896. _rooms[i].room_light_colour.r,
  897. _rooms[i].room_light_colour.g,
  898. _rooms[i].room_light_colour.b);
  899. }
  900. }
  901. /* Read floor data */
  902. /*
  903. * Really, FloorData should be a per-sector dynamic allocation; however,
  904. * that requires a parser that can accurately determine where one sector's
  905. * FloorData ends and another's begins. Until we have that, we'll stick to
  906. * this crude (but effective) method...
  907. */
  908. Fread(&_num_floor_data, sizeof(_num_floor_data), 1, f);
  909. printDebug("Load", "_num_floor_data = %u", _num_floor_data);
  910. _floor_data = 0x0;
  911. if (_num_floor_data > 0)
  912. {
  913. _floor_data = new unsigned short[_num_floor_data];
  914. Fread(_floor_data, sizeof(short), _num_floor_data, f);
  915. //! \fixme endian
  916. }
  917. /* Read mesh data */
  918. Fread(&num_mesh_data_words, sizeof(num_mesh_data_words), 1, f);
  919. //! \fixme endian
  920. printDebug("Load", "num_mesh_data_words = %u", num_mesh_data_words);
  921. raw_mesh_data = new unsigned char[num_mesh_data_words*2];
  922. Fread(raw_mesh_data, 2, num_mesh_data_words, f);
  923. // Endian-conversion of this data occurs in ExtractMeshes()
  924. printDebug("Load", "Read raw_mesh_data");
  925. /* Read mesh pointers */
  926. Fread(&num_mesh_pointers, sizeof(num_mesh_pointers), 1, f);
  927. //! \fixme endian
  928. printDebug("Load", "num_mesh_pointers = %u", num_mesh_pointers);
  929. mesh_pointer_list = new unsigned int[num_mesh_pointers];
  930. Fread(mesh_pointer_list, sizeof(unsigned int), num_mesh_pointers, f);
  931. //! \fixme endian
  932. printDebug("Load", "Read mesh_pointer_list");
  933. /* Extract meshes */
  934. extractMeshes(raw_mesh_data, num_mesh_pointers, mesh_pointer_list);
  935. delete [] raw_mesh_data;
  936. delete [] mesh_pointer_list;
  937. /* Read animations */
  938. Fread(&_num_animations, sizeof(_num_animations), 1, f);
  939. //! \fixme endian
  940. printDebug("Load", "_num_animations = %u", _num_animations);
  941. _animations = 0x0;
  942. if (_num_animations > 0)
  943. {
  944. _animations = new tr2_animation_t[_num_animations];
  945. if (mEngineVersion == TR_VERSION_4)
  946. {
  947. tr4_animation_t tr4_anim;
  948. for (i = 0; i < (int)_num_animations; ++i)
  949. {
  950. Fread(&tr4_anim, 40, 1, f);
  951. _animations[i].frame_offset = tr4_anim.frame_offset;
  952. _animations[i].frame_rate = tr4_anim.frame_rate;
  953. _animations[i].frame_size = tr4_anim.frame_size;
  954. _animations[i].state_id = tr4_anim.state_id;
  955. _animations[i].unknown1 = tr4_anim.unknown;
  956. _animations[i].unknown2 = tr4_anim.speed;
  957. _animations[i].unknown3 = tr4_anim.accel_lo;
  958. _animations[i].unknown4 = tr4_anim.accel_hi;
  959. _animations[i].frame_start = tr4_anim.frame_start;
  960. _animations[i].frame_end = tr4_anim.frame_end;
  961. _animations[i].next_animation = tr4_anim.next_animation;
  962. _animations[i].next_frame = tr4_anim.next_frame;
  963. _animations[i].num_state_changes = tr4_anim.num_state_changes;
  964. _animations[i].state_change_offset = tr4_anim.state_change_offset;
  965. _animations[i].num_anim_commands = (tr4_anim.num_anim_commands > 256)
  966. ? 0 : tr4_anim.num_anim_commands;
  967. _animations[i].anim_command = tr4_anim.anim_command;
  968. }
  969. }
  970. else
  971. {
  972. Fread(_animations, sizeof(tr2_animation_t), _num_animations, f);
  973. }
  974. }
  975. //! \fixme endian
  976. /* Read state changes */
  977. Fread(&_num_state_changes, sizeof(_num_state_changes), 1, f);
  978. //! \fixme endian
  979. if (percent)
  980. (*percent)(80);
  981. printDebug("Load", "_num_state_changes = %u", _num_state_changes);
  982. if (_num_state_changes > 0)
  983. {
  984. _state_changes = new tr2_state_change_t[_num_state_changes];
  985. Fread(_state_changes, sizeof(tr2_state_change_t), _num_state_changes, f);
  986. }
  987. //! \fixme endian
  988. /* Read AnimDispatches */
  989. Fread(&_num_anim_dispatches, sizeof(_num_anim_dispatches), 1, f);
  990. //! \fixme endian
  991. printDebug("Load", "_num_anim_dispatches = %u", _num_anim_dispatches);
  992. _anim_dispatches = 0x0;
  993. if (_num_anim_dispatches > 0)
  994. {
  995. _anim_dispatches = new tr2_anim_dispatch_t[_num_anim_dispatches];
  996. Fread(_anim_dispatches, sizeof(tr2_anim_dispatch_t),
  997. _num_anim_dispatches, f);
  998. }
  999. //! \fixme endian
  1000. /* Read anim commands */
  1001. Fread(&_num_anim_commands, sizeof(_num_anim_commands), 1, f);
  1002. //! \fixme endian
  1003. printDebug("Load", "_num_anim_commands = %u", _num_anim_commands);
  1004. _anim_commands = 0x0;
  1005. if (_num_anim_commands > 0)
  1006. {
  1007. _anim_commands = new tr2_anim_command_t[_num_anim_commands];
  1008. Fread(_anim_commands, sizeof(tr2_anim_command_t), _num_anim_commands, f);
  1009. }
  1010. //! \fixme endian
  1011. /* Read MeshTrees */
  1012. Fread(&_num_mesh_trees, sizeof(_num_mesh_trees), 1, f);
  1013. //! \fixme endian
  1014. printDebug("Load", "_num_mesh_trees = %u", _num_mesh_trees);
  1015. _mesh_trees = 0x0;
  1016. if (_num_mesh_trees > 0)
  1017. {
  1018. _mesh_trees = new tr2_meshtree_t[_num_mesh_trees];
  1019. Fread(_mesh_trees, sizeof(int), _num_mesh_trees, f);
  1020. }
  1021. //! \fixme endian
  1022. /* Read frames */
  1023. Fread(&_num_frames, sizeof(_num_frames), 1, f);
  1024. //! \fixme endian
  1025. printDebug("Load", "_num_frames = %u", _num_frames);
  1026. _frames = 0x0;
  1027. if (_num_frames > 0)
  1028. {
  1029. _frames = new unsigned short[_num_frames];
  1030. Fread(_frames, 2, _num_frames, f);
  1031. //! \fixme endian
  1032. if (mEngineVersion == TR_VERSION_1)
  1033. {
  1034. // re-format the frames[] to look like TR2 frames
  1035. int num_frames;
  1036. for (j = 0; j < (int)_num_animations; ++j)
  1037. {
  1038. int fo = _animations[j].frame_offset / 2;
  1039. _animations[j].frame_size = (unsigned char)(_frames[fo + 9] * 2) + 10;
  1040. }
  1041. for (i = 0; i < (int)_num_frames; )
  1042. {
  1043. i += 9; // point to num_frames;
  1044. j = i; // get rid of (overwrite) num_frames
  1045. num_frames = _frames[i++];
  1046. while (num_frames--)
  1047. {
  1048. _frames[j++] = _frames[i + 1]; // reverse the words as we go
  1049. _frames[j++] = _frames[i];
  1050. i += 2;
  1051. }
  1052. }
  1053. }
  1054. }
  1055. /* Read moveables */
  1056. Fread(&_num_moveables, sizeof(_num_moveables), 1, f);
  1057. //! \fixme endian
  1058. printDebug("Load", "_num_moveables = %u", _num_moveables);
  1059. _moveables = 0x0;
  1060. if (_num_moveables > 0)
  1061. {
  1062. debugf = ftell(f);
  1063. _moveables = new tr2_moveable_t[_num_moveables];
  1064. Fread(_moveables, 18, _num_moveables, f);
  1065. }
  1066. //! \fixme endian
  1067. Fread(&_num_static_meshes, sizeof(int), 1, f);
  1068. //! \fixme endian
  1069. printDebug("Load", "_num_static_meshes = %u", _num_static_meshes);
  1070. // SAFE EXIT //////////////////////////
  1071. _static_meshes = 0x0;
  1072. if (_num_static_meshes > 0)
  1073. {
  1074. _static_meshes = new tr2_staticmesh_t[_num_static_meshes];
  1075. Fread(_static_meshes, sizeof(tr2_staticmesh_t),
  1076. _num_static_meshes, f);
  1077. //! \fixme endian
  1078. }
  1079. _object_textures = 0x0;
  1080. if (mEngineVersion < TR_VERSION_3)
  1081. {
  1082. /* Read object textures */
  1083. Fread(&_num_object_textures, sizeof(int), 1, f);
  1084. printDebug("Load", "_num_object_textures = %u", _num_object_textures);
  1085. //! \fixme endian
  1086. if (_num_object_textures > 0)
  1087. {
  1088. _object_textures = new tr2_object_texture_t[_num_object_textures];
  1089. Fread(_object_textures, sizeof(tr2_object_texture_t),
  1090. _num_object_textures, f);
  1091. }
  1092. //! \fixme endian
  1093. }
  1094. if (percent)
  1095. (*percent)(90);
  1096. if (mEngineVersion == TR_VERSION_4)
  1097. {
  1098. unsigned char zzbuf[4];
  1099. Fread(zzbuf, 1, 3, f); // skip "SPR"
  1100. zzbuf[3] = 0;
  1101. printDebug("Load", "TR4 checking if %s == SPR", zzbuf);
  1102. }
  1103. /* Read sprite textures */
  1104. Fread(&_num_sprite_textures, sizeof(int), 1, f);
  1105. //! \fixme endian
  1106. printDebug("Load", "_num_sprite_textures = %u", _num_sprite_textures);
  1107. _sprite_textures = 0x0;
  1108. if (_num_sprite_textures > 0)
  1109. {
  1110. _sprite_textures = new tr2_sprite_texture_t[_num_sprite_textures];
  1111. Fread(_sprite_textures, sizeof(tr2_sprite_texture_t),
  1112. _num_sprite_textures, f);
  1113. }
  1114. //! \fixme endian
  1115. /* Read sprite texture data (?) */
  1116. Fread(&_num_sprite_sequences, sizeof(int), 1, f);
  1117. //! \fixme endian
  1118. printDebug("Load", "_num_sprite_sequences = %u", _num_sprite_sequences);
  1119. _sprite_sequences = 0x0;
  1120. if (_num_sprite_sequences > 0)
  1121. {
  1122. _sprite_sequences = new tr2_sprite_sequence_t[_num_sprite_sequences];
  1123. Fread(_sprite_sequences, sizeof(tr2_sprite_sequence_t),
  1124. _num_sprite_sequences, f);
  1125. }
  1126. //! \fixme endian
  1127. /* Read cameras */
  1128. Fread(&_num_cameras, sizeof(_num_cameras), 1, f);
  1129. //! \fixme endian
  1130. printDebug("Load", "_num_cameras = %i", _num_cameras);
  1131. _cameras = 0x0;
  1132. if (_num_cameras > 0)
  1133. {
  1134. _cameras = new tr2_camera_t[_num_cameras];
  1135. Fread(_cameras, sizeof(tr2_camera_t), _num_cameras, f);
  1136. //! \fixme endian
  1137. }
  1138. if (mEngineVersion == TR_VERSION_4)
  1139. {
  1140. int num_ex_cam;
  1141. tr4_extra_camera_t *ex_cam;
  1142. Fread(&num_ex_cam, 4, 1, f);
  1143. printDebug("Load", "num_extra_cam = %i", num_ex_cam);
  1144. if (num_ex_cam > 0)
  1145. {
  1146. ex_cam = new tr4_extra_camera_t[num_ex_cam];
  1147. Fread(ex_cam, sizeof(tr4_extra_camera_t), num_ex_cam, f);
  1148. delete [] ex_cam;
  1149. }
  1150. }
  1151. /* Read sound effects (?) */
  1152. Fread(&_num_sound_sources, sizeof(_num_sound_sources), 1, f);
  1153. //! \fixme endian
  1154. printDebug("Load", "_num_sound_sources = %i", _num_sound_sources);
  1155. _sound_sources = 0x0;
  1156. if (_num_sound_sources > 0)
  1157. {
  1158. _sound_sources =
  1159. (tr2_sound_source_t*) new unsigned char[_num_sound_sources*40];
  1160. Fread(_sound_sources, sizeof(tr2_sound_source_t),
  1161. _num_sound_sources, f);
  1162. //! \fixme endian
  1163. }
  1164. #ifdef OBSOLETE
  1165. if (mEngineVersion == TR_VERSION_4)
  1166. {
  1167. unsigned int num_ZZ;
  1168. unsigned char zzbuf[17];
  1169. Fread(&num_ZZ, 1, sizeof(num_ZZ), f);
  1170. while (num_ZZ--)
  1171. {
  1172. Fread(zzbuf, 1, 16, f);
  1173. zzbuf[16] = 0;
  1174. printDebug("Load", "TR4 zz dump '%s'", zzbuf);
  1175. }
  1176. }
  1177. #endif
  1178. /* Read boxes */
  1179. Fread(&_num_boxes, sizeof(_num_boxes), 1, f);
  1180. //! \fixme endian
  1181. printDebug("Load", "_num_boxes = %i", _num_boxes);
  1182. _boxes = 0x0;
  1183. if (_num_boxes > 0)
  1184. {
  1185. _boxes = new tr2_box_t[_num_boxes];
  1186. if (mEngineVersion == TR_VERSION_1)
  1187. {
  1188. struct tr1_box
  1189. {
  1190. int zmin, zmax, xmin, xmax;
  1191. short true_floor, overlap_index;
  1192. } __attribute__ ((packed)) *tr1box;
  1193. tr1box = new tr1_box[_num_boxes];
  1194. Fread(tr1box, sizeof(struct tr1_box), _num_boxes, f);
  1195. //! \fixme endian
  1196. for (j = 0; j < _num_boxes; ++j)
  1197. {
  1198. _boxes[j].zmin = (unsigned char)(tr1box[j].zmin / 1024);
  1199. _boxes[j].zmax = (unsigned char)(tr1box[j].zmax / 1024);
  1200. _boxes[j].xmin = (unsigned char)(tr1box[j].xmin / 1024);
  1201. _boxes[j].xmax = (unsigned char)(tr1box[j].xmax / 1024);
  1202. _boxes[j].true_floor = tr1box[j].true_floor;
  1203. _boxes[j].overlap_index = tr1box[j].overlap_index;
  1204. }
  1205. delete [] tr1box;
  1206. }
  1207. else
  1208. {
  1209. Fread(_boxes, sizeof(tr2_box_t), _num_boxes, f);
  1210. }
  1211. //! \fixme endian
  1212. }
  1213. /* Read overlaps (?) */
  1214. Fread(&_num_overlaps, sizeof(_num_overlaps), 1, f);
  1215. //! \fixme endian
  1216. printDebug("Load", "_num_overlaps = %i", _num_overlaps);
  1217. _overlaps = 0x0;
  1218. if (_num_overlaps > 0)
  1219. {
  1220. _overlaps = new short[_num_overlaps];
  1221. Fread(_overlaps, 2, _num_overlaps, f);
  1222. //! \fixme endian
  1223. }
  1224. _zones = 0x0;
  1225. /* Read Zones */
  1226. if (_num_boxes > 0)
  1227. {
  1228. _zones = new short[_num_boxes*10];
  1229. if (mEngineVersion == TR_VERSION_1)
  1230. {
  1231. Fread(_zones, 12, _num_boxes, f);
  1232. }
  1233. else
  1234. {
  1235. Fread(_zones, 20, _num_boxes, f);
  1236. }
  1237. //! \fixme endian
  1238. }
  1239. /* Read animation textures (?) */
  1240. Fread(&_num_animated_textures, sizeof(_num_animated_textures), 1, f);
  1241. //! \fixme endian
  1242. printDebug("Load", "_num_animated_textures = %i", _num_animated_textures);
  1243. _animated_textures = 0x0;
  1244. if (_num_animated_textures > 0)
  1245. {
  1246. _animated_textures = new short[_num_animated_textures];
  1247. Fread(_animated_textures, 2, _num_animated_textures, f);
  1248. //! \fixme endian
  1249. }
  1250. if (mEngineVersion >= TR_VERSION_3)
  1251. {
  1252. /* Read object textures */
  1253. if (mEngineVersion == TR_VERSION_4)
  1254. {
  1255. unsigned char zzbuf[5];
  1256. Fread(zzbuf, 1, 4, f); // skip "TEX"
  1257. //!! this should be 3, but we have a bug...
  1258. zzbuf[4] = 0;
  1259. printDebug("Load", "TR4 checking %s == TEX", zzbuf);
  1260. }
  1261. Fread(&_num_object_textures, sizeof(_num_object_textures), 1, f);
  1262. //! \fixme endian
  1263. printDebug("Load", "_num_object_textures = %i", _num_object_textures);
  1264. _object_textures = 0x0;
  1265. if (_num_object_textures > 0)
  1266. {
  1267. // Used to be 2 * num, and I forgot why...
  1268. _object_textures = new tr2_object_texture_t[_num_object_textures];
  1269. //! \fixme This is fu fu fu fu fu fu
  1270. if (mEngineVersion == TR_VERSION_4)
  1271. {
  1272. int jjj, kkk;
  1273. tr4_object_texture_t *tr4_tex;
  1274. tr4_tex = new tr4_object_texture_t[_num_object_textures];
  1275. Fread(tr4_tex, 38, _num_object_textures, f);
  1276. for (jjj = 0; jjj < (int)_num_object_textures; ++jjj)
  1277. {
  1278. _object_textures[jjj].transparency_flags =
  1279. tr4_tex[jjj].attribute;
  1280. _object_textures[jjj].tile =
  1281. (unsigned short)tr4_tex[jjj].tile & 0x7fff;
  1282. for (kkk = 0; kkk < 4; ++kkk)
  1283. {
  1284. _object_textures[jjj].vertices[kkk].xcoordinate =
  1285. tr4_tex[jjj].vertices[kkk].xcoordinate;
  1286. _object_textures[jjj].vertices[kkk].xpixel =
  1287. tr4_tex[jjj].vertices[kkk].xpixel;
  1288. _object_textures[jjj].vertices[kkk].ycoordinate =
  1289. tr4_tex[jjj].vertices[kkk].ycoordinate;
  1290. _object_textures[jjj].vertices[kkk].ypixel =
  1291. tr4_tex[jjj].vertices[kkk].ypixel;
  1292. }
  1293. }
  1294. delete [] tr4_tex;
  1295. }
  1296. else
  1297. {
  1298. Fread(_object_textures, sizeof(tr2_object_texture_t),
  1299. _num_object_textures, f);
  1300. }
  1301. }
  1302. //! \fixme endian
  1303. }
  1304. /* Read items */
  1305. Fread(&_num_items, sizeof(_num_items), 1, f);
  1306. //! \fixme endian
  1307. printDebug("Load", "_num_items = %i", _num_items);
  1308. _items = 0x0;
  1309. if (_num_items > 0)
  1310. {
  1311. _items = new tr2_item_t[_num_items];
  1312. if (mEngineVersion == TR_VERSION_1)
  1313. {
  1314. for (i = 0; i < _num_items; ++i)
  1315. {
  1316. Fread(&_items[i], sizeof(tr2_item_t) - 2, 1, f);
  1317. _items[i].flags = _items[i].intensity2;
  1318. _items[i].intensity2 = _items[i].intensity1;
  1319. }
  1320. }
  1321. else
  1322. {
  1323. Fread(_items, sizeof(tr2_item_t), _num_items, f);
  1324. }
  1325. }
  1326. //! \fixme endian
  1327. /* Read LightMaps */
  1328. _light_map = new unsigned char[32 * 256];
  1329. if (mEngineVersion != TR_VERSION_4)
  1330. {
  1331. Fread(_light_map, 32, 256, f);
  1332. }
  1333. if (mEngineVersion == TR_VERSION_1)
  1334. {
  1335. /* read the 8-bit palette */
  1336. Fread(_palette8, sizeof(tr2_colour_t), 256, f);
  1337. printDebug("Load", "Read TR 1 palette");
  1338. // build 16-bit textiles from 8-bit
  1339. // (no extra colours, but creates consistent .TR2 file)
  1340. for (i = 0; i < (int)_num_textiles; ++i)
  1341. {
  1342. unsigned short argb;
  1343. double colour_tmp;
  1344. for (j = 0; j < (256 * 256); ++j)
  1345. {
  1346. colour_tmp = _palette8[_textile8[i].tile[j]].r & 0x3f;
  1347. colour_tmp = colour_tmp * 31.0 / 63.0;
  1348. argb = (unsigned short)(((int)colour_tmp) << 10);
  1349. colour_tmp = _palette8[_textile8[i].tile[j]].g & 0x3f;
  1350. colour_tmp = colour_tmp * 31.0 / 63.0;
  1351. argb |= (unsigned short)(((int)colour_tmp) << 5);
  1352. colour_tmp = _palette8[_textile8[i].tile[j]].b & 0x3f;
  1353. colour_tmp = colour_tmp * 31.0 / 63.0;
  1354. argb |= (unsigned short)((int)colour_tmp);
  1355. argb &= 0x7fff; // ???
  1356. if (_textile8[i].tile[j] != 0)
  1357. argb |= 0x8000;
  1358. _textile16[i].tile[j] = argb;
  1359. }
  1360. }
  1361. }
  1362. /* Read cinematic frames */
  1363. if (mEngineVersion == TR_VERSION_4)
  1364. {
  1365. unsigned int num_ai_data;
  1366. Fread(&num_ai_data, 4, 1, f);
  1367. printDebug("Load", "num_ai_data = %i", num_ai_data);
  1368. tr4_ai_object_t *ai_obj = 0x0;
  1369. if (num_ai_data > 0)
  1370. {
  1371. ai_obj = new tr4_ai_object_t[num_ai_data];
  1372. Fread(ai_obj, sizeof(tr4_ai_object_t), num_ai_data, f);
  1373. delete [] ai_obj;
  1374. }
  1375. }
  1376. else
  1377. {
  1378. unsigned short num_cinematic_frames;
  1379. Fread(&num_cinematic_frames, sizeof(num_cinematic_frames), 1, f);
  1380. //! \fixme endian
  1381. _num_cinematic_frames = num_cinematic_frames;
  1382. printDebug("Load", "_num_cinematic_frames = %i", _num_cinematic_frames);
  1383. _cinematic_frames = 0x0;
  1384. if (_num_cinematic_frames > 0)
  1385. {
  1386. _cinematic_frames = new tr2_cinematic_frame_t[_num_cinematic_frames];
  1387. Fread(_cinematic_frames, sizeof(tr2_cinematic_frame_t),
  1388. _num_cinematic_frames, f);
  1389. // There may or may not be endian conversion required here - I have
  1390. // no idea what this data is.
  1391. }
  1392. }
  1393. /* Read demodata (?) */
  1394. Fread(&_num_demo_data, sizeof(_num_demo_data), 1, f);
  1395. //! \fixme endian
  1396. printDebug("Load", "_num_demo_data = %i", _num_demo_data);
  1397. _demo_data = 0x0;
  1398. if (_num_demo_data > 0)
  1399. {
  1400. _demo_data = new unsigned char[_num_demo_data];
  1401. Fread(_demo_data, 1, _num_demo_data, f);
  1402. // There may or may not be endian conversion required here - I have
  1403. // no idea what this data is.
  1404. }
  1405. /* Read SoundMap */
  1406. mSoundMap = new short[370];
  1407. if (mEngineVersion == TR_VERSION_1)
  1408. {
  1409. Fread(mSoundMap, sizeof(short), 256, f);
  1410. //memset(_sound_map, 0, 370 * sizeof(short)); //! \fixme KLUDGE!!!
  1411. }
  1412. else
  1413. {
  1414. Fread(mSoundMap, sizeof(short), 370, f);
  1415. }
  1416. //! \fixme endian
  1417. /* Read SoundDetails */
  1418. Fread(&mNumSoundDetails, sizeof(mNumSoundDetails), 1, f);
  1419. printDebug("Load", "mNumSoundDetails = %i", mNumSoundDetails);
  1420. //! \fixme endian
  1421. mSoundDetails = 0x0;
  1422. if (mNumSoundDetails > 0)
  1423. {
  1424. mSoundDetails = new tr2_sound_details_t[mNumSoundDetails];
  1425. Fread(mSoundDetails, sizeof(tr2_sound_details_t), mNumSoundDetails, f);
  1426. }
  1427. //! \fixme endian
  1428. // Read sound sample indices
  1429. mSampleIndices = 0x0;
  1430. mNumSampleIndices = 0;
  1431. mRiffDataSz = 0;
  1432. mRiffData = 0x0;
  1433. mNumTR4Samples = 0;
  1434. mTR4Samples = 0x0;
  1435. switch (mEngineVersion)
  1436. {
  1437. case TR_VERSION_1:
  1438. Fread(&mRiffDataSz, 4, 1, f);
  1439. printDebug("Load", "mRiffDataSz = %ibytes", mRiffDataSz);
  1440. if (mRiffDataSz > 0)
  1441. {
  1442. mRiffData = new unsigned char[mRiffDataSz];
  1443. Fread(mRiffData, 1, mRiffDataSz, f);
  1444. }
  1445. Fread(&mNumSampleIndices, 4, 1, f);
  1446. printDebug("Load", "mNumSampleIndices = %i", mNumSampleIndices);
  1447. if (mNumSampleIndices > 0)
  1448. {
  1449. mSampleIndices = new int[mNumSampleIndices];
  1450. //! \fixme (Endian)
  1451. Fread(mSampleIndices, 4, mNumSampleIndices, f);
  1452. }
  1453. break;
  1454. case TR_VERSION_4:
  1455. mFreadMode = TR_FREAD_NORMAL;
  1456. // 0x46464952
  1457. //! \fixme (Endian) Read bitu32 / u_int32_t
  1458. Fread(&mNumTR4Samples, 4, 1, f);
  1459. printDebug("Load", "mNumTR4Samples = %i", mNumTR4Samples);
  1460. mRiffDataSz = 0;
  1461. mTR4Samples = new unsigned char *[mNumTR4Samples];
  1462. mTR4SamplesSz = new unsigned int[mNumTR4Samples];
  1463. memset(mTR4SamplesSz, 0, mNumTR4Samples*4);
  1464. for (i = 0; i < (int)mNumTR4Samples; ++i)
  1465. {
  1466. unsigned int sizeCompressed;
  1467. unsigned int sizeUncompressed;
  1468. unsigned char *compressedSoundSample;
  1469. unsigned char *unCompressedSoundSample;
  1470. int zErr;
  1471. uLongf libzUncompressedSize;
  1472. Fread(&sizeUncompressed, 4, 1, f);
  1473. printDebug("Load", " sizeUncompressed = %i", sizeUncompressed);
  1474. Fread(&sizeCompressed, 4, 1, f);
  1475. printDebug("Load", " sizeCompressed = %i", sizeCompressed);
  1476. compressedSoundSample = new unsigned char[sizeCompressed];
  1477. unCompressedSoundSample = new unsigned char[sizeUncompressed];
  1478. //printDebug("Load", " %lubytes read from file", ftell(f));
  1479. Fread(compressedSoundSample, sizeCompressed, 1, f);
  1480. printDebug("Load", " %c%c%c%c should be RIFF",
  1481. compressedSoundSample[0],
  1482. compressedSoundSample[1],
  1483. compressedSoundSample[2],
  1484. compressedSoundSample[3]);
  1485. //#define NEVER_DECOMPRESS
  1486. #ifdef NEVER_DECOMPRESS
  1487. mTR4Samples[i] = compressedSoundSample;
  1488. mTR4SamplesSz[i] = sizeCompressed;
  1489. delete [] unCompressedSoundSample;
  1490. #else
  1491. // Decompress the sample
  1492. libzUncompressedSize = sizeUncompressed;
  1493. zErr = uncompress(unCompressedSoundSample,
  1494. &libzUncompressedSize,
  1495. compressedSoundSample,
  1496. sizeCompressed);
  1497. sizeUncompressed = libzUncompressedSize;
  1498. switch (zErr)
  1499. {
  1500. case Z_MEM_ERROR:
  1501. printDebug("Load", " Decompress Error: not enough memory");
  1502. break;
  1503. case Z_BUF_ERROR:
  1504. printDebug("Load", " Decompress Error: output buffer too small");
  1505. break;
  1506. case Z_DATA_ERROR:
  1507. printDebug("Load", " Decompress Error: input data was corrupted");
  1508. break;
  1509. case Z_OK:
  1510. printDebug("Load", " Decompress OK");
  1511. break;
  1512. default:
  1513. printDebug("Load", " Decompress Error: decompress error #%i", zErr);
  1514. }
  1515. // Hhhmm... handle uncompressed RIFFs too?
  1516. if (zErr == Z_OK)
  1517. {
  1518. mTR4Samples[i] = unCompressedSoundSample;
  1519. mTR4SamplesSz[i] = sizeUncompressed;
  1520. delete [] compressedSoundSample;
  1521. }
  1522. else
  1523. {
  1524. printDebug("Load", " %lubytes read from file", ftell(f));
  1525. mTR4Samples[i] = compressedSoundSample;
  1526. mTR4SamplesSz[i] = sizeCompressed;
  1527. delete [] unCompressedSoundSample;
  1528. }
  1529. #endif
  1530. }
  1531. break;
  1532. case TR_VERSION_2:
  1533. case TR_VERSION_3:
  1534. case TR_VERSION_5:
  1535. case TR_VERSION_UNKNOWN:
  1536. //! \fixme (Endian) Read bit32 / int32_t
  1537. Fread(&mNumSampleIndices, 4, 1, f);
  1538. printDebug("Load", "mNumSampleIndices = %i", mNumSampleIndices);
  1539. if (mNumSampleIndices > 0)
  1540. {
  1541. mSampleIndices = new int[mNumSampleIndices];
  1542. //! \fixme (Endian)
  1543. Fread(mSampleIndices, 4, mNumSampleIndices, f);
  1544. }
  1545. break;
  1546. }
  1547. if (mCompressedLevelData)
  1548. {
  1549. printDebug("Load", "Freeing uncompressed TR4 data");
  1550. delete [] mCompressedLevelData;
  1551. }
  1552. //! \fixme memory damage?
  1553. mCompressedLevelData = NULL;
  1554. fclose(f);
  1555. if (percent)
  1556. (*percent)(100);
  1557. return 0;
  1558. }
  1559. ////////////////////////////////////////////////////////////
  1560. // Public Accessors
  1561. ////////////////////////////////////////////////////////////
  1562. float TombRaider::adjustTexel(unsigned char texel, char offset)
  1563. {
  1564. if (offset >= 0)
  1565. texel++;
  1566. else
  1567. texel--;
  1568. return ((float)texel / 255.0f);
  1569. }
  1570. void TombRaider::computeRotationAngles(unsigned short **frame,
  1571. unsigned int *frame_offset,
  1572. unsigned int *angle_offset,
  1573. float *x, float *y, float *z)
  1574. {
  1575. unsigned short itmp, itmp2;
  1576. float angle;
  1577. itmp = (*frame)[(*frame_offset) + (*angle_offset)++];
  1578. if (Engine() == TR_VERSION_1)
  1579. {
  1580. // All angles are three-axis
  1581. angle = (itmp >> 4) & 0x03ff;
  1582. angle *= 360.0 / 1024.0;
  1583. *x = angle;
  1584. itmp2 = (itmp << 6) & 0x03c0;
  1585. // Get Z rotation
  1586. itmp = (*frame)[(*frame_offset) + (*angle_offset)];
  1587. ++(*angle_offset);
  1588. itmp2 |= (itmp >> 10) & 0x003f;
  1589. angle = itmp2;
  1590. angle *= 360.0 / 1024.0;
  1591. *y = angle;
  1592. angle = itmp & 0x3ff;
  1593. angle *= 360.0 / 1024.0;
  1594. *z = angle;
  1595. }
  1596. else if (itmp & 0xc000)
  1597. {
  1598. // TR2, TR3, TR4 - single axis of rotation
  1599. if (Engine() == TR_VERSION_4)
  1600. {
  1601. angle = itmp & 0x0fff;
  1602. angle /= 4096.0;
  1603. angle *= 360.0;
  1604. }
  1605. else
  1606. {
  1607. angle = itmp & 0x3ff;
  1608. angle /= 1024.0;
  1609. angle *= 360.0;
  1610. }
  1611. switch (itmp & 0xc000)
  1612. {
  1613. case 0x4000:
  1614. *x = angle;
  1615. break;
  1616. case 0x8000:
  1617. *y = angle;
  1618. break;
  1619. case 0xc000:
  1620. *z = angle;
  1621. break;
  1622. }
  1623. }
  1624. else // TR2, TR3, TR4 - three axes
  1625. {
  1626. angle = (itmp >> 4) & 0x03ff;
  1627. angle *= 360.0 / 1024.0;
  1628. *x = angle;
  1629. itmp2 = (itmp << 6) & 0x03c0;
  1630. itmp = (*frame)[(*frame_offset) + (*angle_offset)++]; // get Z rotation
  1631. itmp2 |= (itmp >> 10) & 0x003f;
  1632. angle = itmp2;
  1633. angle *= 360.0 / 1024.0;
  1634. *y = angle;
  1635. angle = itmp & 0x3ff;
  1636. angle *= 360.0 / 1024.0;
  1637. *z = angle;
  1638. }
  1639. }
  1640. void TombRaider::computeUV(tr2_object_texture_vert_t *st, float *u, float *v)
  1641. {
  1642. unsigned char x, y;
  1643. if (!st || !u || !v)
  1644. return;
  1645. x = st->xpixel;
  1646. y = st->ypixel;
  1647. x += (char)st->xcoordinate;
  1648. y += (char)st->ycoordinate;
  1649. //x += ((char)st->xcoordinate >= 0) ? 1 : -1;
  1650. //y += ((char)st->ycoordinate >= 0) ? 1 : -1;
  1651. *u = (float)x / 255.0f;
  1652. *v = (float)y / 255.0f;
  1653. }
  1654. int TombRaider::getBumpMapCount()
  1655. {
  1656. return _num_bump_map_textures / 2;
  1657. }
  1658. void TombRaider::getColor(int index, float color[4])
  1659. {
  1660. switch (getEngine())
  1661. {
  1662. case TR_VERSION_1:
  1663. color[0] = _palette8[index].r / 64.0f;
  1664. color[1] = _palette8[index].g / 64.0f;
  1665. color[2] = _palette8[index].b / 64.0f;
  1666. //color[0] = (_palette8[index].r & 0xfd) / 64.0f;
  1667. //color[1] = (_palette8[index].g & 0xfd) / 64.0f;
  1668. //color[2] = (_palette8[index].b & 0xfd) / 64.0f;
  1669. color[3] = 1.0;
  1670. break;
  1671. case TR_VERSION_2:
  1672. case TR_VERSION_3:
  1673. case TR_VERSION_4:
  1674. case TR_VERSION_5:
  1675. case TR_VERSION_UNKNOWN:
  1676. color[0] = (float)(_palette16[index] & 0xff) / 256.0f;
  1677. color[1] = (float)((_palette16[index] >> 8) & 0xff) / 256.0f;
  1678. color[2] = (float)((_palette16[index] >> 16) & 0xff) / 256.0f;
  1679. color[3] = 1.0;
  1680. break;
  1681. }
  1682. }
  1683. tr2_version_type TombRaider::getEngine()
  1684. {
  1685. return mEngineVersion;
  1686. }
  1687. void TombRaider::getMeshCollisionInfo(unsigned int meshIndex,
  1688. float center[3], float *radius)
  1689. {
  1690. if ((int)meshIndex > mMeshCount)
  1691. {
  1692. print("getMeshCollisionInfo", "Assertion error: invalid mesh index\n");
  1693. return;
  1694. }
  1695. center[0] = mMeshes[meshIndex].centre.x;
  1696. center[1] = mMeshes[meshIndex].centre.y;
  1697. center[2] = mMeshes[meshIndex].centre.z;
  1698. *radius = mMeshes[meshIndex].collision_size;
  1699. }
  1700. int TombRaider::getMeshCount()
  1701. {
  1702. return mMeshCount;
  1703. }
  1704. //! \fixme Needs refinement once the ideal format it's feeding is refined
  1705. // I should stick a HACK postfix on the method name - it's temporary
  1706. // until an array format can be crafted from a pinned down design and
  1707. // RE notes review session ( eg what about TR5? )
  1708. void TombRaider::getMeshColoredRectangle(unsigned int meshIndex,
  1709. unsigned int faceIndex,
  1710. int *index, float *color)
  1711. {
  1712. unsigned int t1_1, t1_2, t1_3, t2_1, t2_2, t2_3;
  1713. if ((int)meshIndex > mMeshCount)
  1714. {
  1715. print("getMeshColoredRectangle", "Assertion error: invalid mesh index\n");
  1716. return;
  1717. }
  1718. // Make 2 triangles from one quad!
  1719. t1_1 = 0;
  1720. t1_2 = 1;
  1721. t1_3 = 2;
  1722. t2_1 = 3;
  1723. t2_2 = 0;
  1724. t2_3 = 2;
  1725. index[0] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t1_1];
  1726. index[1] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t1_2];
  1727. index[2] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t1_3];
  1728. index[3] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t2_1];
  1729. index[4] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t2_2];
  1730. index[5] = mMeshes[meshIndex].coloured_rectangles[faceIndex].vertices[t2_3];
  1731. switch (Engine())
  1732. {
  1733. case TR_VERSION_1:
  1734. getColor(mMeshes[meshIndex].coloured_rectangles[faceIndex].texture & 0xff, color);
  1735. break;
  1736. case TR_VERSION_2:
  1737. case TR_VERSION_3:
  1738. case TR_VERSION_4:
  1739. case TR_VERSION_5:
  1740. case TR_VERSION_UNKNOWN:
  1741. getColor((mMeshes[meshIndex].coloured_rectangles[faceIndex].texture>>8) & 0xff, color);
  1742. break;
  1743. }
  1744. }
  1745. void TombRaider::getMeshColoredTriangle(unsigned int meshIndex,
  1746. unsigned int faceIndex,
  1747. int *index, float *color)
  1748. {
  1749. if ((int)meshIndex > mMeshCount)
  1750. {
  1751. print("getMeshColoredTriangle", "Assertion error: invalid mesh index\n");
  1752. return;
  1753. }
  1754. index[0] = mMeshes[meshIndex].coloured_triangles[faceIndex].vertices[0];
  1755. index[1] = mMeshes[meshIndex].coloured_triangles[faceIndex].vertices[1];
  1756. index[2] = mMeshes[meshIndex].coloured_triangles[faceIndex].vertices[2];
  1757. switch (Engine())
  1758. {
  1759. case TR_VERSION_1:
  1760. getColor(mMeshes[meshIndex].coloured_triangles[faceIndex].texture & 0xff,
  1761. color);
  1762. break;
  1763. case TR_VERSION_2:
  1764. case TR_VERSION_3:
  1765. case TR_VERSION_4:
  1766. case TR_VERSION_5:
  1767. case TR_VERSION_UNKNOWN:
  1768. getColor((mMeshes[meshIndex].coloured_triangles[faceIndex].texture>>8) & 0xff,
  1769. color);
  1770. break;
  1771. }
  1772. }
  1773. void TombRaider::getMeshTexturedRectangle(unsigned int meshIndex,
  1774. unsigned int faceIndex,
  1775. int *index, float *st, int *texture,
  1776. unsigned short *transparency)
  1777. {
  1778. unsigned int t1_1, t1_2, t1_3, t2_1, t2_2, t2_3;
  1779. static bool givenWarning = false; // hahaha... okay less spewing
  1780. tr2_mesh_t *meshes;
  1781. tr2_object_texture_t *object_texture;
  1782. int t_index;
  1783. unsigned int i, m;
  1784. if ((int)meshIndex > mMeshCount)
  1785. {
  1786. print("getMeshTexturedRectangle", "Assertion error: invalid mesh index\n");
  1787. return;
  1788. }
  1789. m = meshIndex; // lazy
  1790. meshes = mMeshes; // lazy
  1791. object_texture = _object_textures; // lazy
  1792. i = faceIndex; // lazy
  1793. // Make 2 triangles from one quad!
  1794. t1_1 = 0;
  1795. t1_2 = 1;
  1796. t1_3 = 2;
  1797. t2_1 = 3;
  1798. t2_2 = 0;
  1799. t2_3 = 2;
  1800. t_index = meshes[m].textured_rectangles[i].texture;
  1801. index[0] = meshes[m].textured_rectangles[i].vertices[t1_1];
  1802. index[1] = meshes[m].textured_rectangles[i].vertices[t1_2];
  1803. index[2] = meshes[m].textured_rectangles[i].vertices[t1_3];
  1804. index[3] = meshes[m].textured_rectangles[i].vertices[t2_1];
  1805. index[4] = meshes[m].textured_rectangles[i].vertices[t2_2];
  1806. index[5] = meshes[m].textured_rectangles[i].vertices[t2_3];
  1807. computeUV(object_texture[t_index].vertices+t1_1, (st), (st)+1);
  1808. computeUV(object_texture[t_index].vertices+t1_2, (st)+2, (st)+3);
  1809. computeUV(object_texture[t_index].vertices+t1_3, (st)+4, (st)+5);
  1810. computeUV(object_texture[t_index].vertices+t2_1, (st)+6, (st)+7);
  1811. computeUV(object_texture[t_index].vertices+t2_2, (st)+8, (st)+9);
  1812. computeUV(object_texture[t_index].vertices+t2_3, (st)+10, (st)+11);
  1813. *texture = object_texture[t_index].tile;
  1814. *transparency = object_texture[t_index].transparency_flags;
  1815. // TR3+ alpha Textured polygons
  1816. if (!givenWarning && *transparency == 2)
  1817. {
  1818. givenWarning = true;
  1819. //! \fixme Use Material class to handle greyscale alpha intensity
  1820. // (partial alpha)
  1821. print("getMeshTexturedRectangle",
  1822. "TR3+ greyscale alpha intensity not implmented, %s:%i",
  1823. __FILE__, __LINE__);
  1824. }
  1825. }
  1826. void TombRaider::getMeshTexturedTriangle(unsigned int meshIndex,
  1827. unsigned int faceIndex,
  1828. int *index, float *st, int *texture,
  1829. unsigned short *transparency)
  1830. {
  1831. static bool givenWarning = false; // hahaha... okay less spewing
  1832. tr2_mesh_t *meshes;
  1833. tr2_object_texture_t *object_texture;
  1834. int t_index;
  1835. unsigned int i;
  1836. if ((int)meshIndex > mMeshCount)
  1837. {
  1838. print("getMeshTexturedTriangle", "Assertion error: invalid mesh index\n");
  1839. return;
  1840. }
  1841. meshes = mMeshes; // lazy
  1842. object_texture = _object_textures; // lazy
  1843. i = faceIndex; // lazy
  1844. t_index = meshes[meshIndex].textured_triangles[i].texture;
  1845. index[0] = meshes[meshIndex].textured_triangles[i].vertices[0];
  1846. index[1] = meshes[meshIndex].textured_triangles[i].vertices[1];
  1847. index[2] = meshes[meshIndex].textured_triangles[i].vertices[2];
  1848. computeUV(object_texture[t_index].vertices, (st), (st)+1);
  1849. computeUV(object_texture[t_index].vertices+1, (st)+2, (st)+3);
  1850. computeUV(object_texture[t_index].vertices+2, (st)+4, (st)+5);
  1851. *texture = object_texture[t_index].tile;
  1852. *transparency = object_texture[t_index].transparency_flags;
  1853. // TR3+ alpha Textured polygons
  1854. if (!givenWarning && *transparency == 2)
  1855. {
  1856. givenWarning = true;
  1857. //! \fixme Use Material class to handle greyscale alpha intensity
  1858. // (partial alpha)
  1859. print("getMeshTexturedTriangle",
  1860. "TR3+ greyscale alpha intensity not implmented, %s:%i",
  1861. __FILE__, __LINE__);
  1862. }
  1863. }
  1864. int TombRaider::getMeshTexturedTriangleCount(unsigned int meshIndex)
  1865. {
  1866. if ((int)meshIndex > mMeshCount)
  1867. {
  1868. print("getMeshTexturedTriangleCount", "Assertion error: invalid mesh index\n");
  1869. return 0;
  1870. }
  1871. return ((mMeshes[meshIndex].num_textured_triangles <= 0) ? 0 :
  1872. mMeshes[meshIndex].num_textured_triangles);
  1873. }
  1874. int TombRaider::getMeshColoredTriangleCount(unsigned int meshIndex)
  1875. {
  1876. if ((int)meshIndex > mMeshCount)
  1877. {
  1878. print("getMeshColoredTriangleCount", "Assertion error: invalid mesh index\n");
  1879. return 0;
  1880. }
  1881. return ((mMeshes[meshIndex].num_coloured_triangles <= 0) ? 0 :
  1882. mMeshes[meshIndex].num_coloured_triangles);
  1883. }
  1884. int TombRaider::getMeshTexturedRectangleCount(unsigned int meshIndex)
  1885. {
  1886. if ((int)meshIndex > mMeshCount)
  1887. {
  1888. print("getMeshTexturedRectangleCount", "Assertion error: invalid mesh index\n");
  1889. return 0;
  1890. }
  1891. return ((mMeshes[meshIndex].num_textured_rectangles <= 0) ? 0 :
  1892. mMeshes[meshIndex].num_textured_rectangles);
  1893. }
  1894. int TombRaider::getMeshColoredRectangleCount(unsigned int meshIndex)
  1895. {
  1896. if ((int)meshIndex > mMeshCount)
  1897. {
  1898. print("getMeshColoredRectangleCount", "Assertion error: invalid mesh index\n");
  1899. return 0;
  1900. }
  1901. return ((mMeshes[meshIndex].num_coloured_rectangles <= 0) ? 0:
  1902. mMeshes[meshIndex].num_coloured_rectangles);
  1903. }
  1904. //! \fixme Perhaps making color an 8bit intensity would be a better idea
  1905. void TombRaider::getMeshVertexArrays(unsigned int meshIndex,
  1906. unsigned int *vertexCount, float **verts,
  1907. unsigned int *normalCount, float **norms,
  1908. unsigned int *colorCount, float **colors)
  1909. {
  1910. unsigned int i;
  1911. float colorValue;
  1912. *vertexCount = 0;
  1913. *verts = 0x0;
  1914. *normalCount = 0;
  1915. *norms = 0x0;
  1916. *colorCount = 0;
  1917. *colors = 0x0;
  1918. if ((int)meshIndex > mMeshCount || mMeshes[meshIndex].num_vertices < 0)
  1919. return;
  1920. // Vertices
  1921. *vertexCount = mMeshes[meshIndex].num_vertices;
  1922. *verts = new float[*vertexCount * 3];
  1923. for (i = 0; i < *vertexCount; ++i)
  1924. {
  1925. (*verts)[i*3] = mMeshes[meshIndex].vertices[i].x;
  1926. (*verts)[i*3+1] = mMeshes[meshIndex].vertices[i].y;
  1927. (*verts)[i*3+2] = mMeshes[meshIndex].vertices[i].z;
  1928. }
  1929. // Normals, if any
  1930. if (mMeshes[meshIndex].num_normals > 0 &&
  1931. mMeshes[meshIndex].normals &&
  1932. mMeshes[meshIndex].num_normals == mMeshes[meshIndex].num_vertices)
  1933. {
  1934. *normalCount = mMeshes[meshIndex].num_vertices;
  1935. *norms = new float[*normalCount * 3];
  1936. for (i = 0; i < *normalCount; ++i)
  1937. {
  1938. (*norms)[i*3] = mMeshes[meshIndex].normals[i].x;
  1939. (*norms)[i*3+1] = mMeshes[meshIndex].normals[i].y;
  1940. (*norms)[i*3+2] = mMeshes[meshIndex].normals[i].z;
  1941. }
  1942. }
  1943. // Vertex lighting/colors, if any
  1944. else if (mMeshes[meshIndex].num_vertices > 0 &&
  1945. mMeshes[meshIndex].mesh_lights)
  1946. {
  1947. *colorCount = mMeshes[meshIndex].num_vertices;
  1948. #ifdef MESH_COLORS_SHOULD_BR_RGBA
  1949. *colors = new float[*colorCount * 4];
  1950. #else
  1951. *colors = new float[*colorCount];
  1952. #endif
  1953. for (i = 0; i < *colorCount; ++i)
  1954. {
  1955. colorValue = mMeshes[meshIndex].mesh_lights[i];
  1956. switch (Engine())
  1957. {
  1958. case TR_VERSION_4:
  1959. case TR_VERSION_3:
  1960. colorValue /= 16384.0;
  1961. //! \fixme Should we really fall through here?!?
  1962. break; // just testing -- xythobuz, 20140119
  1963. case TR_VERSION_1:
  1964. case TR_VERSION_2:
  1965. case TR_VERSION_5:
  1966. case TR_VERSION_UNKNOWN:
  1967. colorValue = (1.0f - (colorValue / 8192.0f));
  1968. break;
  1969. }
  1970. #ifdef MESH_COLORS_SHOULD_BR_RGBA
  1971. (*colors)[i*4+0] = colorValue;
  1972. (*colors)[i*4+1] = colorValue;
  1973. (*colors)[i*4+2] = colorValue;
  1974. (*colors)[i*4+3] = 1.0;
  1975. #else
  1976. (*colors)[i] = colorValue;
  1977. #endif
  1978. }
  1979. }
  1980. }
  1981. int TombRaider::getRoomBox(unsigned int roomIndex, unsigned int index,
  1982. float *xyzA, float *xyzB,
  1983. float *xyzC, float *xyzD)
  1984. {
  1985. if (!getRoomBoxCount(roomIndex) || index > getRoomBoxCount(roomIndex))
  1986. return -1;
  1987. switch (getEngine())
  1988. {
  1989. case TR_VERSION_UNKNOWN:
  1990. break;
  1991. case TR_VERSION_1:
  1992. case TR_VERSION_2:
  1993. case TR_VERSION_3:
  1994. case TR_VERSION_4:
  1995. case TR_VERSION_5:
  1996. xyzA[0] = (unsigned short)_boxes[index].xmin * 1024.0f;
  1997. xyzA[1] = (short)_boxes[index].true_floor;
  1998. xyzA[2] = (unsigned short)_boxes[index].zmin * 1024.0f;
  1999. xyzB[0] = (unsigned short)_boxes[index].xmax * 1024.0f;
  2000. xyzB[1] = (short)_boxes[index].true_floor;
  2001. xyzB[2] = (unsigned short)_boxes[index].zmin * 1024.0f;
  2002. xyzC[0] = (unsigned short)_boxes[index].xmax * 1024.0f;
  2003. xyzC[1] = (short)_boxes[index].true_floor;
  2004. xyzC[2] = (unsigned short)_boxes[index].zmax * 1024.0f;
  2005. xyzD[0] = (unsigned short)_boxes[index].xmin * 1024.0f;
  2006. xyzD[1] = (short)_boxes[index].true_floor;
  2007. xyzD[2] = (unsigned short)_boxes[index].zmax * 1024.0f;
  2008. }
  2009. return 0;
  2010. }
  2011. unsigned int TombRaider::getRoomBoxCount(unsigned int roomIndex)
  2012. {
  2013. if (!isRoomValid(roomIndex))
  2014. return 0;
  2015. switch (getEngine())
  2016. {
  2017. case TR_VERSION_UNKNOWN:
  2018. break;
  2019. case TR_VERSION_1:
  2020. case TR_VERSION_2:
  2021. case TR_VERSION_3:
  2022. case TR_VERSION_4:
  2023. case TR_VERSION_5:
  2024. return _num_boxes;
  2025. }
  2026. return 0;
  2027. }
  2028. void TombRaider::getRoomInfo(unsigned int index,
  2029. unsigned int *flags, float pos[3],
  2030. float bboxMin[3], float bboxMax[3])
  2031. {
  2032. unsigned int i, n;
  2033. float f;
  2034. if (!isRoomValid(index))
  2035. return;
  2036. switch (getEngine())
  2037. {
  2038. case TR_VERSION_UNKNOWN:
  2039. break;
  2040. case TR_VERSION_5:
  2041. // Flags
  2042. *flags = mRoomsTR5[index].roomFlag; // Needs to be generic flags in class
  2043. // Positioning
  2044. pos[0] = mRoomsTR5[index].roomX;
  2045. pos[1] = 0.0f;
  2046. pos[2] = mRoomsTR5[index].roomZ;
  2047. // Bounding box setup
  2048. bboxMin[0] = 0.0;
  2049. bboxMin[1] = 0.0;
  2050. bboxMin[2] = 0.0;
  2051. bboxMax[0] = 0.0;
  2052. bboxMax[1] = 0.0;
  2053. bboxMax[2] = 0.0;
  2054. // Bounding Box setup
  2055. for (i = 0; i < mRoomsTR5[index].numLayers; ++i)
  2056. {
  2057. //! \fixme check the boxes are in min, max order in TRC
  2058. if (i == 0)
  2059. {
  2060. bboxMin[0] = mRoomsTR5[index].layers[i].layerBoundingBoxX1;
  2061. bboxMin[1] = mRoomsTR5[index].layers[i].layerBoundingBoxY1;
  2062. bboxMin[2] = mRoomsTR5[index].layers[i].layerBoundingBoxZ1;
  2063. bboxMax[0] = mRoomsTR5[index].layers[i].layerBoundingBoxX1;
  2064. bboxMax[1] = mRoomsTR5[index].layers[i].layerBoundingBoxY2;
  2065. bboxMax[2] = mRoomsTR5[index].layers[i].layerBoundingBoxZ2;
  2066. continue;
  2067. }
  2068. if (mRoomsTR5[index].layers[i].layerBoundingBoxX1 < bboxMin[0])
  2069. bboxMin[0] = mRoomsTR5[index].layers[i].layerBoundingBoxX1;
  2070. if (mRoomsTR5[index].layers[i].layerBoundingBoxY1 < bboxMin[1])
  2071. bboxMin[1] = mRoomsTR5[index].layers[i].layerBoundingBoxY1;
  2072. if (mRoomsTR5[index].layers[i].layerBoundingBoxZ1 < bboxMin[2])
  2073. bboxMin[2] = mRoomsTR5[index].layers[i].layerBoundingBoxZ1;
  2074. if (mRoomsTR5[index].layers[i].layerBoundingBoxX2 < bboxMax[0])
  2075. bboxMax[0] = mRoomsTR5[index].layers[i].layerBoundingBoxX2;
  2076. if (mRoomsTR5[index].layers[i].layerBoundingBoxY2 < bboxMax[1])
  2077. bboxMax[1] = mRoomsTR5[index].layers[i].layerBoundingBoxY2;
  2078. if (mRoomsTR5[index].layers[i].layerBoundingBoxZ2 < bboxMax[2])
  2079. bboxMax[2] = mRoomsTR5[index].layers[i].layerBoundingBoxZ2;
  2080. }
  2081. break;
  2082. case TR_VERSION_1:
  2083. case TR_VERSION_2:
  2084. case TR_VERSION_3:
  2085. case TR_VERSION_4:
  2086. // Flags
  2087. *flags = _rooms[index].flags; // Needs to be generic flags in class
  2088. // Positioning
  2089. pos[0] = _rooms[index].info.x;
  2090. pos[1] = 0.0f;
  2091. pos[2] = _rooms[index].info.z;
  2092. bboxMin[0] = 0.0;
  2093. bboxMin[1] = 0.0;
  2094. bboxMin[2] = 0.0;
  2095. bboxMax[0] = 0.0;
  2096. bboxMax[1] = 0.0;
  2097. bboxMax[2] = 0.0;
  2098. // Bounding Box setup
  2099. n = ((_rooms[index].room_data.num_vertices < 0) ? 0 :
  2100. _rooms[index].room_data.num_vertices);
  2101. for (i = 0; i < n; ++i)
  2102. {
  2103. if (i == 0)
  2104. {
  2105. bboxMin[0] = _rooms[index].room_data.vertices[i].vertex.x;
  2106. bboxMin[1] = _rooms[index].room_data.vertices[i].vertex.y;
  2107. bboxMin[2] = _rooms[index].room_data.vertices[i].vertex.z;
  2108. bboxMax[0] = _rooms[index].room_data.vertices[i].vertex.x;
  2109. bboxMax[1] = _rooms[index].room_data.vertices[i].vertex.y;
  2110. bboxMax[2] = _rooms[index].room_data.vertices[i].vertex.z;
  2111. continue;
  2112. }
  2113. f = _rooms[index].room_data.vertices[i].vertex.x;
  2114. if (f < bboxMin[0])
  2115. bboxMin[0] = f;
  2116. if (f > bboxMax[0])
  2117. bboxMax[0] = f;
  2118. f = _rooms[index].room_data.vertices[i].vertex.y;
  2119. if (f < bboxMin[1])
  2120. bboxMin[1] = f;
  2121. if (f > bboxMax[1])
  2122. bboxMax[1] = f;
  2123. f = _rooms[index].room_data.vertices[i].vertex.z;
  2124. if (f < bboxMin[2])
  2125. bboxMin[2] = f;
  2126. if (f > bboxMax[2])
  2127. bboxMax[2] = f;
  2128. }
  2129. break;
  2130. }
  2131. }
  2132. int TombRaider::getRoomLight(unsigned int roomIndex, unsigned int index,
  2133. float pos[4], float color[4], float dir[3],
  2134. float *attenuation, float *cutoffAngle,
  2135. unsigned int *type, unsigned int *flags)
  2136. {
  2137. const float dd = 10000.0; // 4095.0;
  2138. float f;
  2139. *flags = 0; // reset
  2140. switch (getEngine())
  2141. {
  2142. case TR_VERSION_UNKNOWN:
  2143. return -1;
  2144. case TR_VERSION_1:
  2145. case TR_VERSION_2:
  2146. case TR_VERSION_3:
  2147. if (_rooms[roomIndex].num_lights <= 0 ||
  2148. (int)index > _rooms[roomIndex].num_lights)
  2149. {
  2150. return -1;
  2151. }
  2152. if (_rooms[roomIndex].lights[index].fade1 == 100730731)
  2153. {
  2154. f = 1.0;
  2155. }
  2156. else
  2157. {
  2158. f = _rooms[roomIndex].lights[index].fade1;
  2159. f /= dd;
  2160. }
  2161. *attenuation = f;
  2162. *flags |= tombraiderLight_useAttenuation;
  2163. pos[0] = _rooms[roomIndex].lights[index].x;
  2164. pos[1] = _rooms[roomIndex].lights[index].y;
  2165. pos[2] = _rooms[roomIndex].lights[index].z;
  2166. pos[3] = 1.0f;
  2167. color[0] = _rooms[roomIndex].lights[index].intensity1 / 409.60f;
  2168. color[1] = color[0];
  2169. color[2] = color[0];
  2170. color[3] = 1.0f;
  2171. if (Engine() == TR_VERSION_3)
  2172. {
  2173. color[0] = _rooms[roomIndex].room_light_colour.r;
  2174. color[1] = _rooms[roomIndex].room_light_colour.g;
  2175. color[2] = _rooms[roomIndex].room_light_colour.b;
  2176. }
  2177. *type = tombraiderLight_typeDirectional;
  2178. break;
  2179. case TR_VERSION_4:
  2180. if (_rooms[roomIndex].num_lights <= 0 ||
  2181. (int)index > _rooms[roomIndex].num_lights)
  2182. {
  2183. return -1;
  2184. }
  2185. pos[0] = _rooms[roomIndex].tr4Lights[index].xPosition;
  2186. pos[1] = _rooms[roomIndex].tr4Lights[index].yPosition;
  2187. pos[2] = _rooms[roomIndex].tr4Lights[index].zPosition;
  2188. pos[3] = 0.0f;
  2189. color[0] = _rooms[roomIndex].tr4Lights[index].color.r;
  2190. color[1] = _rooms[roomIndex].tr4Lights[index].color.g;
  2191. color[2] = _rooms[roomIndex].tr4Lights[index].color.b;
  2192. dir[0] = _rooms[roomIndex].tr4Lights[index].xDir;
  2193. dir[1] = _rooms[roomIndex].tr4Lights[index].yDir;
  2194. dir[2] = _rooms[roomIndex].tr4Lights[index].zDir;
  2195. *cutoffAngle = _rooms[roomIndex].tr4Lights[index].cutoff;
  2196. *flags |= tombraiderLight_useCutoff;
  2197. switch (_rooms[roomIndex].tr4Lights[index].lightType)
  2198. {
  2199. case 1:
  2200. *type = tombraiderLight_typeDirectional;
  2201. break;
  2202. case 2:
  2203. *type = tombraiderLight_typeSpot;
  2204. break;
  2205. default:
  2206. *type = tombraiderLight_typePoint;
  2207. }
  2208. break;
  2209. case TR_VERSION_5:
  2210. if (mRoomsTR5[roomIndex].numRoomLights <= 0 ||
  2211. (int)index > mRoomsTR5[roomIndex].numRoomLights)
  2212. {
  2213. return -1;
  2214. }
  2215. pos[0] = mRoomsTR5[roomIndex].lights[index].x;
  2216. pos[1] = mRoomsTR5[roomIndex].lights[index].y;
  2217. pos[2] = mRoomsTR5[roomIndex].lights[index].z;
  2218. pos[3] = 0.0f;
  2219. color[0] = mRoomsTR5[roomIndex].lights[index].red;
  2220. color[1] = mRoomsTR5[roomIndex].lights[index].green;
  2221. color[2] = mRoomsTR5[roomIndex].lights[index].blue;
  2222. dir[0] = mRoomsTR5[roomIndex].lights[index].directionVectorX;
  2223. dir[1] = mRoomsTR5[roomIndex].lights[index].directionVectorY;
  2224. dir[2] = mRoomsTR5[roomIndex].lights[index].directionVectorZ;
  2225. switch (mRoomsTR5[roomIndex].lights[index].lightType)
  2226. {
  2227. case 2:
  2228. *type = tombraiderLight_typeSpot;
  2229. break;
  2230. case 3:
  2231. *type = tombraiderLight_typeDirectional;
  2232. break;
  2233. default:
  2234. *type = tombraiderLight_typePoint;
  2235. }
  2236. break;
  2237. }
  2238. return 0;
  2239. }
  2240. unsigned int TombRaider::getRoomLightCount(unsigned int roomIndex)
  2241. {
  2242. if (!isRoomValid(roomIndex))
  2243. return 0;
  2244. switch (getEngine())
  2245. {
  2246. case TR_VERSION_UNKNOWN:
  2247. break;
  2248. case TR_VERSION_5:
  2249. return mRoomsTR5[roomIndex].numRoomLights;
  2250. case TR_VERSION_1:
  2251. case TR_VERSION_2:
  2252. case TR_VERSION_3:
  2253. case TR_VERSION_4:
  2254. return _rooms[roomIndex].num_lights;
  2255. }
  2256. return 0;
  2257. }
  2258. int TombRaider::getRoomModel(unsigned int roomIndex, unsigned int index,
  2259. int *modelIndex, float pos[3], float *yaw)
  2260. {
  2261. unsigned int i, count;
  2262. if (!getRoomModelCount(roomIndex) || index > getRoomModelCount(roomIndex))
  2263. return -1;
  2264. switch (getEngine())
  2265. {
  2266. case TR_VERSION_UNKNOWN:
  2267. return -1;
  2268. case TR_VERSION_5:
  2269. count = NumStaticMeshes();
  2270. for (i = 0; i < count; ++i)
  2271. {
  2272. if (mRoomsTR5[roomIndex].meshes[index].object_id ==
  2273. _static_meshes[i].object_id)
  2274. {
  2275. *modelIndex = _static_meshes[i].starting_mesh;
  2276. pos[0] = mRoomsTR5[roomIndex].meshes[index].x;
  2277. pos[1] = mRoomsTR5[roomIndex].meshes[index].y;
  2278. pos[2] = mRoomsTR5[roomIndex].meshes[index].z;
  2279. *yaw = ((mRoomsTR5[roomIndex].meshes[index].rotation >> 14)
  2280. & 0x03) * 90;
  2281. }
  2282. }
  2283. break;
  2284. case TR_VERSION_1:
  2285. case TR_VERSION_2:
  2286. case TR_VERSION_3:
  2287. case TR_VERSION_4:
  2288. count = NumStaticMeshes();
  2289. for (i = 0; i < count; ++i)
  2290. {
  2291. if (_rooms[roomIndex].static_meshes[index].object_id ==
  2292. _static_meshes[i].object_id)
  2293. {
  2294. *modelIndex = _static_meshes[i].starting_mesh;
  2295. pos[0] = _rooms[roomIndex].static_meshes[index].x;
  2296. pos[1] = _rooms[roomIndex].static_meshes[index].y;
  2297. pos[2] = _rooms[roomIndex].static_meshes[index].z;
  2298. *yaw = ((_rooms[roomIndex].static_meshes[index].rotation >> 14)
  2299. & 0x03) * 90;
  2300. }
  2301. }
  2302. }
  2303. return 0;
  2304. }
  2305. unsigned int TombRaider::getRoomModelCount(unsigned int roomIndex)
  2306. {
  2307. if (!isRoomValid(roomIndex))
  2308. return 0;
  2309. switch (getEngine())
  2310. {
  2311. case TR_VERSION_UNKNOWN:
  2312. break;
  2313. case TR_VERSION_5:
  2314. return mRoomsTR5[roomIndex].numStaticMeshes;
  2315. case TR_VERSION_1:
  2316. case TR_VERSION_2:
  2317. case TR_VERSION_3:
  2318. case TR_VERSION_4:
  2319. return _rooms[roomIndex].num_static_meshes;
  2320. }
  2321. return 0;
  2322. }
  2323. int TombRaider::getRoomPortal(unsigned int roomIndex, unsigned int index,
  2324. int *adjoiningRoom,
  2325. float normal[3], float vertices[12])
  2326. {
  2327. if (!getRoomPortalCount(roomIndex) || index > getRoomPortalCount(roomIndex))
  2328. return 0;
  2329. switch (getEngine())
  2330. {
  2331. case TR_VERSION_UNKNOWN:
  2332. break;
  2333. case TR_VERSION_5:
  2334. *adjoiningRoom = mRoomsTR5[roomIndex].doors[index].adjoining_room;
  2335. normal[0] = mRoomsTR5[roomIndex].doors[index].normal.x;// / NORMAL_SCALE;
  2336. normal[1] = mRoomsTR5[roomIndex].doors[index].normal.y;// / NORMAL_SCALE;
  2337. normal[2] = mRoomsTR5[roomIndex].doors[index].normal.z;// / NORMAL_SCALE;
  2338. vertices[0] = mRoomsTR5[roomIndex].doors[index].vertices[0].x;
  2339. vertices[1] = mRoomsTR5[roomIndex].doors[index].vertices[0].y;
  2340. vertices[2] = mRoomsTR5[roomIndex].doors[index].vertices[0].z;
  2341. vertices[3] = mRoomsTR5[roomIndex].doors[index].vertices[1].x;
  2342. vertices[4] = mRoomsTR5[roomIndex].doors[index].vertices[1].y;
  2343. vertices[5] = mRoomsTR5[roomIndex].doors[index].vertices[1].z;
  2344. vertices[6] = mRoomsTR5[roomIndex].doors[index].vertices[2].x;
  2345. vertices[7] = mRoomsTR5[roomIndex].doors[index].vertices[2].y;
  2346. vertices[8] = mRoomsTR5[roomIndex].doors[index].vertices[2].z;
  2347. vertices[9] = mRoomsTR5[roomIndex].doors[index].vertices[3].x;
  2348. vertices[10] = mRoomsTR5[roomIndex].doors[index].vertices[3].y;
  2349. vertices[11] = mRoomsTR5[roomIndex].doors[index].vertices[3].z;
  2350. break;
  2351. case TR_VERSION_1:
  2352. case TR_VERSION_2:
  2353. case TR_VERSION_3:
  2354. case TR_VERSION_4:
  2355. *adjoiningRoom = _rooms[roomIndex].portals[index].adjoining_room;
  2356. normal[0] = _rooms[roomIndex].portals[index].normal.x;// / NORMAL_SCALE;
  2357. normal[1] = _rooms[roomIndex].portals[index].normal.y;// / NORMAL_SCALE;
  2358. normal[2] = _rooms[roomIndex].portals[index].normal.z;// / NORMAL_SCALE;
  2359. vertices[0] = _rooms[roomIndex].portals[index].vertices[0].x;
  2360. vertices[1] = _rooms[roomIndex].portals[index].vertices[0].y;
  2361. vertices[2] = _rooms[roomIndex].portals[index].vertices[0].z;
  2362. vertices[3] = _rooms[roomIndex].portals[index].vertices[1].x;
  2363. vertices[4] = _rooms[roomIndex].portals[index].vertices[1].y;
  2364. vertices[5] = _rooms[roomIndex].portals[index].vertices[1].z;
  2365. vertices[6] = _rooms[roomIndex].portals[index].vertices[2].x;
  2366. vertices[7] = _rooms[roomIndex].portals[index].vertices[2].y;
  2367. vertices[8] = _rooms[roomIndex].portals[index].vertices[2].z;
  2368. vertices[9] = _rooms[roomIndex].portals[index].vertices[3].x;
  2369. vertices[10] = _rooms[roomIndex].portals[index].vertices[3].y;
  2370. vertices[11] = _rooms[roomIndex].portals[index].vertices[3].z;
  2371. }
  2372. return 0;
  2373. }
  2374. unsigned int TombRaider::getRoomPortalCount(unsigned int roomIndex)
  2375. {
  2376. if (!isRoomValid(roomIndex))
  2377. return 0;
  2378. switch (getEngine())
  2379. {
  2380. case TR_VERSION_UNKNOWN:
  2381. break;
  2382. case TR_VERSION_5:
  2383. return mRoomsTR5[roomIndex].numDoors;
  2384. case TR_VERSION_1:
  2385. case TR_VERSION_2:
  2386. case TR_VERSION_3:
  2387. case TR_VERSION_4:
  2388. return _rooms[roomIndex].num_portals;
  2389. }
  2390. return 0;
  2391. }
  2392. //! \fixme No TRC support
  2393. void TombRaider::getRoomRectangle(unsigned int roomIndex,
  2394. unsigned int rectangleIndex,
  2395. unsigned int *indices, float *texCoords,
  2396. int *texture, unsigned int *flags)
  2397. {
  2398. int tIndex;
  2399. unsigned int count, i, j, k;
  2400. switch (getEngine())
  2401. {
  2402. case TR_VERSION_UNKNOWN:
  2403. break;
  2404. case TR_VERSION_5:
  2405. for (i = 0, count = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  2406. {
  2407. if (count + mRoomsTR5[roomIndex].layers[i].numLayerRectangles >
  2408. rectangleIndex)
  2409. {
  2410. k = rectangleIndex - count;
  2411. *texture = *flags = 0; // FIXME
  2412. // Setup per vertex
  2413. for (j = 0; j < 3; ++j)
  2414. {
  2415. // Get vertex index { (0, a), (1, b), (2, c), (3, d) }
  2416. indices[j] = mRoomsTR5[roomIndex].faces[i].quads[k].vertices[j];
  2417. // FIXME
  2418. //tIndex = mRoomsTR5[roomIndex].faces[i].vertices[j].texture & 0xff;
  2419. //computeUV(objectTexturesTR5[tIndex].vertices + i,
  2420. // texCoords+i*2, texCoords+i*2+1);
  2421. }
  2422. break;
  2423. }
  2424. count += mRoomsTR5[roomIndex].layers[i].numLayerRectangles;
  2425. }
  2426. break;
  2427. case TR_VERSION_1:
  2428. case TR_VERSION_2:
  2429. case TR_VERSION_3:
  2430. case TR_VERSION_4:
  2431. tIndex = _rooms[roomIndex].room_data.rectangles[rectangleIndex].texture;
  2432. *texture = _object_textures[tIndex].tile;
  2433. *flags = 0;
  2434. switch (_object_textures[tIndex].transparency_flags)
  2435. {
  2436. case 0:
  2437. break;
  2438. case 2:
  2439. *flags |= tombraiderFace_PartialAlpha;
  2440. break;
  2441. default:
  2442. *flags |= tombraiderFace_Alpha;
  2443. break;
  2444. }
  2445. // Setup per vertex
  2446. for (i = 0; i < 4; ++i)
  2447. {
  2448. // Get vertex index {(0, a), (1, b), (2, c), (3, d)}
  2449. indices[i] = _rooms[roomIndex].room_data.rectangles[rectangleIndex].vertices[i];
  2450. computeUV(_object_textures[tIndex].vertices + i,
  2451. texCoords+i*2, texCoords+i*2+1);
  2452. }
  2453. }
  2454. }
  2455. unsigned int TombRaider::getRoomRectangleCount(unsigned int roomIndex)
  2456. {
  2457. unsigned int i, count;
  2458. if (!isRoomValid(roomIndex))
  2459. return 0;
  2460. switch (getEngine())
  2461. {
  2462. case TR_VERSION_UNKNOWN:
  2463. break;
  2464. case TR_VERSION_5:
  2465. for (i = 0, count = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  2466. {
  2467. count += mRoomsTR5[roomIndex].layers[i].numLayerRectangles;
  2468. }
  2469. return count;
  2470. case TR_VERSION_1:
  2471. case TR_VERSION_2:
  2472. case TR_VERSION_3:
  2473. case TR_VERSION_4:
  2474. return ((_rooms[roomIndex].room_data.num_rectangles < 0) ? 0 :
  2475. _rooms[roomIndex].room_data.num_rectangles);
  2476. }
  2477. return 0;
  2478. }
  2479. int TombRaider::getRoomSector(unsigned int roomIndex, unsigned int index,
  2480. unsigned int *flags,
  2481. float *ceiling, float *floor,
  2482. int *floorDataIndex, int *boxIndex,
  2483. int *roomBelow, int *roomAbove)
  2484. {
  2485. unsigned int count;
  2486. unsigned int zSectorsCount;
  2487. unsigned int xSectorsCount;
  2488. count = getRoomSectorCount(roomIndex, &zSectorsCount, &xSectorsCount);
  2489. if (!count || index > count)
  2490. return -1;
  2491. *flags = 0;
  2492. switch (getEngine())
  2493. {
  2494. case TR_VERSION_UNKNOWN:
  2495. break;
  2496. case TR_VERSION_5:
  2497. *floorDataIndex = mRoomsTR5[roomIndex].sectors[index].fd_index;
  2498. *boxIndex = mRoomsTR5[roomIndex].sectors[index].box_index;
  2499. *roomBelow = mRoomsTR5[roomIndex].sectors[index].room_below;
  2500. *roomAbove = mRoomsTR5[roomIndex].sectors[index].room_above;
  2501. if ((unsigned char)mRoomsTR5[roomIndex].sectors[index].floor == 0x81 ||
  2502. (unsigned char)mRoomsTR5[roomIndex].sectors[index].ceiling == 0x81)
  2503. {
  2504. *flags |= tombraiderSector_wall;
  2505. }
  2506. *floor = mRoomsTR5[roomIndex].sectors[index].floor * 256.0f;
  2507. *ceiling = mRoomsTR5[roomIndex].sectors[index].ceiling * 256.0f;
  2508. break;
  2509. case TR_VERSION_1:
  2510. case TR_VERSION_2:
  2511. case TR_VERSION_3:
  2512. case TR_VERSION_4:
  2513. *floorDataIndex = _rooms[roomIndex].sector_list[index].fd_index;
  2514. *boxIndex = _rooms[roomIndex].sector_list[index].box_index;
  2515. *roomBelow = _rooms[roomIndex].sector_list[index].room_below;
  2516. *roomAbove = _rooms[roomIndex].sector_list[index].room_above;
  2517. if ((unsigned char)_rooms[roomIndex].sector_list[index].floor == 0x81 ||
  2518. (unsigned char)_rooms[roomIndex].sector_list[index].ceiling == 0x81)
  2519. {
  2520. *flags |= tombraiderSector_wall;
  2521. }
  2522. *floor = _rooms[roomIndex].sector_list[index].floor * 256.0f;
  2523. *ceiling = _rooms[roomIndex].sector_list[index].ceiling * 256.0f;
  2524. }
  2525. if (*boxIndex == 65536)
  2526. {
  2527. *boxIndex = -1;
  2528. }
  2529. if (*roomBelow == 255)
  2530. {
  2531. *roomBelow = -1;
  2532. }
  2533. if (*roomAbove == 255)
  2534. {
  2535. *roomAbove = -1;
  2536. }
  2537. return 0;
  2538. }
  2539. unsigned int TombRaider::getRoomSectorCount(unsigned int roomIndex,
  2540. unsigned int *zSectorsCount,
  2541. unsigned int *xSectorsCount)
  2542. {
  2543. unsigned int count;
  2544. if (!isRoomValid(roomIndex))
  2545. return 0;
  2546. switch (getEngine())
  2547. {
  2548. case TR_VERSION_UNKNOWN:
  2549. break;
  2550. case TR_VERSION_5:
  2551. // width of sector list
  2552. *zSectorsCount = mRoomsTR5[roomIndex].numZSectors;
  2553. // height of sector list
  2554. *xSectorsCount = mRoomsTR5[roomIndex].numXSectors;
  2555. return (mRoomsTR5[roomIndex].numZSectors *
  2556. mRoomsTR5[roomIndex].numXSectors);
  2557. case TR_VERSION_1:
  2558. case TR_VERSION_2:
  2559. case TR_VERSION_3:
  2560. case TR_VERSION_4:
  2561. // width of sector list
  2562. *zSectorsCount = _rooms[roomIndex].num_zsectors;
  2563. // height of sector list
  2564. *xSectorsCount = _rooms[roomIndex].num_xsectors;
  2565. count = _rooms[roomIndex].num_zsectors * _rooms[roomIndex].num_xsectors;
  2566. return count;
  2567. }
  2568. return 0;
  2569. }
  2570. void TombRaider::getRoomSprite(unsigned int roomIndex, unsigned int index,
  2571. float scale, int *texture,
  2572. float *pos, float *vertices, float *texcoords)
  2573. {
  2574. tr2_sprite_texture_t *sprite;
  2575. tr2_vertex_t *vertex;
  2576. int t_index, width, height, x, y;
  2577. float width2, height2;
  2578. unsigned int spriteCount;
  2579. spriteCount = getRoomSpriteCount(roomIndex);
  2580. if (spriteCount == 0 || index > spriteCount)
  2581. return;
  2582. if (scale == 0.0)
  2583. scale = 10.0;
  2584. t_index = _rooms[roomIndex].room_data.sprites[index].texture;
  2585. vertex =
  2586. &_rooms[roomIndex].room_data.vertices[_rooms[roomIndex].room_data.sprites[index].vertex].vertex;
  2587. sprite = &_sprite_textures[t_index];
  2588. // Info, offset in room added to position
  2589. pos[0] = _rooms[roomIndex].info.x + vertex->x;
  2590. pos[1] = vertex->y;
  2591. pos[2] = _rooms[roomIndex].info.z + vertex->z;
  2592. *texture = sprite->tile;
  2593. width = sprite->width >> 8;
  2594. height = sprite->height >> 8;
  2595. x = sprite->x;
  2596. y = sprite->y;
  2597. width2 = width * scale; // scale it up a bit (sprites are rather tiny)
  2598. height2 = height * scale;
  2599. // Quad
  2600. vertices[0] = -width2 / 2.0f;
  2601. vertices[1] = 0;
  2602. vertices[2] = 0;
  2603. vertices[3] = -width2 / 2.0f;
  2604. vertices[4] = -height2;
  2605. vertices[5] = 0;
  2606. vertices[6] = width2 / 2.0f;
  2607. vertices[7] = -height2;
  2608. vertices[8] = 0;
  2609. vertices[9] = width2 / 2.0f;
  2610. vertices[10] = 0;
  2611. vertices[11] = 0;
  2612. texcoords[0] = ((float)y + height) / mTexelScale;
  2613. texcoords[1] = (float)(x) / mTexelScale;
  2614. texcoords[2] = (float)(y) / mTexelScale;
  2615. texcoords[3] = (float)(x) / mTexelScale;
  2616. texcoords[4] = (float)(y) / mTexelScale;
  2617. texcoords[5] = ((float)x + width) / mTexelScale;
  2618. texcoords[6] = ((float)y + height) / mTexelScale;
  2619. texcoords[7] = ((float)x + width) / mTexelScale;
  2620. }
  2621. #ifdef OPTIONAL_ARRAY_INTERFACE
  2622. void TombRaider::getRoomSpriteArray(unsigned int index, float scale,
  2623. unsigned int *spriteCount, int *textures,
  2624. float *pos, float *vertices, float *texcoords)
  2625. {
  2626. int i, t_index;
  2627. tr2_vertex_t *vertex;
  2628. int width, height, x, y;
  2629. float width2, height2;
  2630. *spriteCount = ((room[index].room_data.num_sprites < 0) ?
  2631. 0 : room[index].room_data.num_sprites);
  2632. if (*spriteCount == 0)
  2633. return;
  2634. textures = new int[*spriteCount];
  2635. pos = new float[*spriteCount * 3];
  2636. vertices = new float[*spriteCount * 12];
  2637. texcoords = new float[*spriteCount * 8];
  2638. if (scale == 0.0)
  2639. scale = 10.0;
  2640. for (i = 0; i < *spriteCount; ++i)
  2641. {
  2642. t_index = room[index].room_data.sprites[i].texture;
  2643. vertex =
  2644. &room[index].room_data.vertices[room[index].room_data.sprites[i].vertex].vertex;
  2645. sprite = &sprite_textures[t_index];
  2646. // Info, offset in room added to position
  2647. pos[0+i*3] = room[index].info.x + vertex->x;
  2648. pos[1+i*3] = vertex->y;
  2649. pos[2+i*3] = room[index].info.z + vertex->z;
  2650. textures[i] = sprite->tile;
  2651. width = sprite->width >> 8;
  2652. height = sprite->height >> 8;
  2653. x = sprite->x;
  2654. y = sprite->y;
  2655. width2 = width * scale; // scale it up a bit (sprites are rather tiny)
  2656. height2 = height * scale;
  2657. // Quad
  2658. vertices[0+i*12] = -width2 / 2.0;
  2659. vertices[1+i*12] = 0;
  2660. vertices[2+i*12] = 0;
  2661. vertices[3+i*12] = -width2 / 2.0;
  2662. vertices[4+i*12] = -height2;
  2663. vertices[5+i*12] = 0;
  2664. vertices[6+i*12] = width2 / 2.0;
  2665. vertices[7+i*12] = -height2;
  2666. vertices[8+i*12] = 0;
  2667. vertices[9+i*12] = width2 / 2.0;
  2668. vertices[10+i*12] = 0;
  2669. vertices[11+i*12] = 0;
  2670. texcoords[0+i*8] = ((float)y + height) / mTexelScale;
  2671. texcoords[1+i*8] = (float)(x) / mTexelScale;
  2672. texcoords[2+i*8] = (float)(y) / mTexelScale;
  2673. texcoords[3+i*8] = (float)(x) / mTexelScale;
  2674. texcoords[4+i*8] = (float)(y) / mTexelScale;
  2675. texcoords[5+i*8] = ((float)x + width) / mTexelScale;
  2676. texcoords[6+i*8] = ((float)y + height) / mTexelScale;
  2677. texcoords[7+i*8] = ((float)x + width) / mTexelScale;
  2678. }
  2679. }
  2680. #endif
  2681. unsigned int TombRaider::getRoomSpriteCount(unsigned int roomIndex)
  2682. {
  2683. if (!isRoomValid(roomIndex))
  2684. return 0;
  2685. switch (getEngine())
  2686. {
  2687. case TR_VERSION_UNKNOWN:
  2688. break;
  2689. case TR_VERSION_5:
  2690. return 0; // No room sprites in TRC
  2691. case TR_VERSION_1:
  2692. case TR_VERSION_2:
  2693. case TR_VERSION_3:
  2694. case TR_VERSION_4:
  2695. return ((_rooms[roomIndex].room_data.num_sprites < 0) ?
  2696. 0 : _rooms[roomIndex].room_data.num_sprites);
  2697. }
  2698. return 0;
  2699. }
  2700. void TombRaider::getRoomTriangle(unsigned int roomIndex,
  2701. unsigned int triangleIndex,
  2702. unsigned int *indices, float *texCoords,
  2703. int *texture, unsigned int *flags)
  2704. {
  2705. int tIndex;
  2706. unsigned int count, i, j, k;
  2707. switch (getEngine())
  2708. {
  2709. case TR_VERSION_UNKNOWN:
  2710. break;
  2711. case TR_VERSION_5:
  2712. for (i = 0, count = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  2713. {
  2714. if (count + mRoomsTR5[roomIndex].layers[i].numLayerTriangles >
  2715. triangleIndex)
  2716. {
  2717. k = triangleIndex - count;
  2718. *texture = *flags = 0; // FIXME
  2719. // Setup per vertex
  2720. for (j = 0; j < 3; ++j)
  2721. {
  2722. // Get vertex index {(0, a), (1, b), (2, c) }
  2723. indices[j] = mRoomsTR5[roomIndex].faces[i].tris[k].vertices[j];
  2724. // FIXME
  2725. //tIndex = mRoomsTR5[roomIndex].faces[i].vertices[j].texture & 0xff;
  2726. //computeUV(objectTexturesTR5[tIndex].vertices + i,
  2727. // texCoords+i*2, texCoords+i*2+1);
  2728. }
  2729. break;
  2730. }
  2731. count += mRoomsTR5[roomIndex].layers[i].numLayerTriangles;
  2732. }
  2733. break;
  2734. case TR_VERSION_1:
  2735. case TR_VERSION_2:
  2736. case TR_VERSION_3:
  2737. case TR_VERSION_4:
  2738. tIndex = _rooms[roomIndex].room_data.triangles[triangleIndex].texture;
  2739. *texture = _object_textures[tIndex].tile;
  2740. *flags = 0;
  2741. switch (_object_textures[tIndex].transparency_flags)
  2742. {
  2743. case 0:
  2744. break;
  2745. case 2:
  2746. *flags |= tombraiderFace_PartialAlpha;
  2747. break;
  2748. default:
  2749. *flags |= tombraiderFace_Alpha;
  2750. break;
  2751. }
  2752. // Setup per vertex
  2753. for (i = 0; i < 3; ++i)
  2754. {
  2755. // Get vertex index {(0, a), (1, b), (2, c) }
  2756. indices[i] = _rooms[roomIndex].room_data.triangles[triangleIndex].vertices[i];
  2757. computeUV(_object_textures[tIndex].vertices + i,
  2758. texCoords+i*2, texCoords+i*2+1);
  2759. }
  2760. }
  2761. }
  2762. void TombRaider::getRoomTriangles(unsigned int index, int textureOffset,
  2763. unsigned int *triangleCount,
  2764. unsigned int **indices,
  2765. float **texCoords, int **textures,
  2766. unsigned int **flags)
  2767. {
  2768. unsigned int count, i, j;
  2769. int texture;
  2770. if (!isRoomValid(index))
  2771. return;
  2772. switch (getEngine())
  2773. {
  2774. case TR_VERSION_UNKNOWN:
  2775. break;
  2776. case TR_VERSION_5:
  2777. for (i = 0, count = 0; i < mRoomsTR5[index].numLayers; ++i)
  2778. {
  2779. count += mRoomsTR5[index].layers[i].numLayerTriangles;
  2780. }
  2781. //! \fixme !!!
  2782. break;
  2783. case TR_VERSION_1:
  2784. case TR_VERSION_2:
  2785. case TR_VERSION_3:
  2786. case TR_VERSION_4:
  2787. // Generate textured triangles
  2788. count = ((_rooms[index].room_data.num_triangles < 0) ? 0 :
  2789. _rooms[index].room_data.num_triangles);
  2790. *triangleCount = count;
  2791. *indices = new unsigned int[count * 3];
  2792. *texCoords = new float[count * 6];
  2793. *textures = new int[count];
  2794. *flags = new unsigned int[count];
  2795. for (i = 0; i < count; ++i)
  2796. {
  2797. texture = _rooms[index].room_data.triangles[i].texture;
  2798. // Adjust texture id using m_texOffset to map into
  2799. // correct textures
  2800. (*textures)[i] = _object_textures[texture].tile + textureOffset;
  2801. (*flags)[i] = 0;
  2802. switch (_object_textures[texture].transparency_flags)
  2803. {
  2804. case 0:
  2805. break;
  2806. case 2:
  2807. (*flags)[i] |= tombraiderFace_PartialAlpha;
  2808. break;
  2809. default:
  2810. (*flags)[i] |= tombraiderFace_Alpha;
  2811. break;
  2812. }
  2813. // Setup per vertex
  2814. for (j = 0; j < 3; ++j)
  2815. {
  2816. // Get vertex index {(0, a), (1, b), (2, c)}
  2817. (*indices)[i*3+j] = _rooms[index].room_data.triangles[i].vertices[j];
  2818. computeUV(_object_textures[texture].vertices+j,
  2819. (*texCoords)+i*3+j*2, (*texCoords)+i*3+j*2+1);
  2820. }
  2821. }
  2822. }
  2823. }
  2824. unsigned int TombRaider::getRoomTriangleCount(unsigned int roomIndex)
  2825. {
  2826. unsigned int i, count;
  2827. if (!isRoomValid(roomIndex))
  2828. return 0;
  2829. switch (getEngine())
  2830. {
  2831. case TR_VERSION_UNKNOWN:
  2832. break;
  2833. case TR_VERSION_5:
  2834. for (i = 0, count = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  2835. {
  2836. count += mRoomsTR5[roomIndex].layers[i].numLayerTriangles;
  2837. }
  2838. return count;
  2839. case TR_VERSION_1:
  2840. case TR_VERSION_2:
  2841. case TR_VERSION_3:
  2842. case TR_VERSION_4:
  2843. return ((_rooms[roomIndex].room_data.num_triangles < 0) ? 0 :
  2844. _rooms[roomIndex].room_data.num_triangles);
  2845. }
  2846. return 0;
  2847. }
  2848. //! \fixme No TR5 support
  2849. void TombRaider::getRoomVertex(unsigned int roomIndex,unsigned int vertexIndex,
  2850. float *xyz, float *rgba)
  2851. {
  2852. float color_value;
  2853. unsigned int index = roomIndex, i = vertexIndex;
  2854. tr2_vertex_t *vertex = 0x0;
  2855. switch (getEngine())
  2856. {
  2857. case TR_VERSION_5:
  2858. //! \fixme !!!
  2859. print("getRoomVertex", "Error: No TRC implementation is the answer");
  2860. break;
  2861. case TR_VERSION_1:
  2862. case TR_VERSION_2:
  2863. case TR_VERSION_3:
  2864. case TR_VERSION_4:
  2865. case TR_VERSION_UNKNOWN:
  2866. vertex = &_rooms[index].room_data.vertices[i].vertex;
  2867. xyz[0] = vertex->x;
  2868. xyz[1] = vertex->y;
  2869. xyz[2] = vertex->z;
  2870. switch (getEngine())
  2871. {
  2872. case TR_VERSION_1:
  2873. color_value = _rooms[index].room_data.vertices[i].attributes;
  2874. color_value = (1.1f - (color_value / 8192.0f));
  2875. rgba[0] = color_value;
  2876. rgba[1] = color_value;
  2877. rgba[2] = color_value;
  2878. break;
  2879. case TR_VERSION_3:
  2880. case TR_VERSION_4:
  2881. color_value = _rooms[index].room_data.vertices[i].lighting1;
  2882. color_value /= 16384.0;
  2883. rgba[0] = color_value + ((float)_rooms[index].room_light_colour.r /
  2884. mRoomVertexLightingFactor);
  2885. rgba[1] = color_value + ((float)_rooms[index].room_light_colour.g /
  2886. mRoomVertexLightingFactor);
  2887. rgba[2] = color_value + ((float)_rooms[index].room_light_colour.b /
  2888. mRoomVertexLightingFactor);
  2889. break;
  2890. case TR_VERSION_2:
  2891. case TR_VERSION_5: // Not really...
  2892. case TR_VERSION_UNKNOWN:
  2893. color_value = _rooms[index].room_data.vertices[i].lighting1;
  2894. color_value = (1.1f - (color_value / 8192.0f));
  2895. rgba[0] = color_value;
  2896. rgba[1] = color_value;
  2897. rgba[2] = color_value;
  2898. }
  2899. // Underwater rooms have an ambient color with a shade of blue
  2900. if (_rooms[index].flags & 0x0001)
  2901. {
  2902. rgba[0] *= 0.6;
  2903. rgba[2] *= 1.2;
  2904. }
  2905. // Alpha color
  2906. rgba[3] = 1.0;
  2907. }
  2908. }
  2909. void TombRaider::getRoomVertexArrays(unsigned int roomIndex,
  2910. unsigned int *vertexCount, float **vertices,
  2911. unsigned int *normalCount, float **normals,
  2912. unsigned int *colorCount, float **colors)
  2913. {
  2914. float color_value;
  2915. float rgba[4];
  2916. unsigned int i, j, k, count;
  2917. unsigned char c;
  2918. tr2_vertex_t *vertex = 0x0;
  2919. count = getRoomVertexCount(roomIndex);
  2920. *vertexCount = 0;
  2921. *vertices = 0x0;
  2922. *normalCount = 0;
  2923. *normals = 0x0;
  2924. *colorCount = 0;
  2925. *colors = 0x0;
  2926. if (count == 0)
  2927. return;
  2928. switch (getEngine())
  2929. {
  2930. case TR_VERSION_UNKNOWN:
  2931. break;
  2932. case TR_VERSION_5:
  2933. *vertexCount = count;
  2934. *vertices = new float[count*3];
  2935. *normalCount = count;
  2936. *normals = new float[count*3];
  2937. *colorCount = count;
  2938. *colors = new float[count*4];
  2939. for (i = 0, k = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  2940. {
  2941. for (j = 0; j < mRoomsTR5[roomIndex].layers[i].numLayerVertices; ++j)
  2942. {
  2943. (*vertices)[k*3] = mRoomsTR5[roomIndex].faces[i].verts[j].x;
  2944. (*vertices)[k*3+1] = mRoomsTR5[roomIndex].faces[i].verts[j].y;
  2945. (*vertices)[k*3+2] = mRoomsTR5[roomIndex].faces[i].verts[j].z;
  2946. (*normals)[k*3] = mRoomsTR5[roomIndex].faces[i].verts[j].nx;
  2947. (*normals)[k*3+1] = mRoomsTR5[roomIndex].faces[i].verts[j].ny;
  2948. (*normals)[k*3+2] = mRoomsTR5[roomIndex].faces[i].verts[j].nz;
  2949. //! \fixme Ah, yeah this may be wrong
  2950. c = ((unsigned char *)&mRoomsTR5[roomIndex].faces[i].verts[j].vColor)[1];
  2951. (*colors)[k*4] = (float)c / 255.0f;
  2952. c = ((unsigned char *)&mRoomsTR5[roomIndex].faces[i].verts[j].vColor)[2];
  2953. (*colors)[k*4+1] = (float)c / 255.0f;
  2954. c = ((unsigned char *)&mRoomsTR5[roomIndex].faces[i].verts[j].vColor)[3];
  2955. (*colors)[k*4+2] = (float)c / 255.0f;
  2956. c = ((unsigned char *)&mRoomsTR5[roomIndex].faces[i].verts[j].vColor)[0];
  2957. (*colors)[k*4+3] = (float)c / 255.0f;
  2958. }
  2959. }
  2960. break;
  2961. case TR_VERSION_1:
  2962. case TR_VERSION_2:
  2963. case TR_VERSION_3:
  2964. case TR_VERSION_4:
  2965. *vertexCount = count;
  2966. *vertices = new float[count*3];
  2967. *normalCount = 0; //! \fixme Do some TR1-TR4 levels support normals here?
  2968. *normals = 0x0;
  2969. *colorCount = count;
  2970. *colors = new float[count*4];
  2971. // Setup vertex coloring and vertices
  2972. for (i = 0; i < count; ++i)
  2973. {
  2974. vertex = &_rooms[roomIndex].room_data.vertices[i].vertex;
  2975. (*vertices)[i*3] = vertex->x;
  2976. (*vertices)[i*3+1] = vertex->y;
  2977. (*vertices)[i*3+2] = vertex->z;
  2978. switch (getEngine())
  2979. {
  2980. case TR_VERSION_1:
  2981. color_value = _rooms[roomIndex].room_data.vertices[i].attributes;
  2982. color_value = (1.1f - (color_value / 8192.0f));
  2983. break;
  2984. case TR_VERSION_4:
  2985. case TR_VERSION_3:
  2986. color_value = _rooms[roomIndex].room_data.vertices[i].lighting1;
  2987. color_value /= 16384.0;
  2988. break;
  2989. case TR_VERSION_2:
  2990. case TR_VERSION_5:
  2991. case TR_VERSION_UNKNOWN:
  2992. color_value = _rooms[roomIndex].room_data.vertices[i].lighting1;
  2993. color_value = (1.1f - (color_value / 8192.0f));
  2994. }
  2995. switch (getEngine())
  2996. {
  2997. case TR_VERSION_4:
  2998. case TR_VERSION_3:
  2999. rgba[0] = (color_value +
  3000. ((float)_rooms[roomIndex].room_light_colour.r /
  3001. mRoomVertexLightingFactor));
  3002. rgba[1] = (color_value +
  3003. ((float)_rooms[roomIndex].room_light_colour.g /
  3004. mRoomVertexLightingFactor));
  3005. rgba[2] = (color_value +
  3006. ((float)_rooms[roomIndex].room_light_colour.b /
  3007. mRoomVertexLightingFactor));
  3008. break;
  3009. case TR_VERSION_1:
  3010. case TR_VERSION_2:
  3011. case TR_VERSION_5:
  3012. case TR_VERSION_UNKNOWN:
  3013. rgba[0] = color_value;
  3014. rgba[1] = color_value;
  3015. rgba[2] = color_value;
  3016. }
  3017. // Underwater rooms have an ambient color with a shade of blue
  3018. if (_rooms[roomIndex].flags & 0x0001)
  3019. {
  3020. rgba[0] *= 0.6;
  3021. rgba[2] *= 1.2;
  3022. }
  3023. // Alpha color
  3024. rgba[3] = 1.0;
  3025. (*colors)[i*4] = rgba[0];
  3026. (*colors)[i*4+1] = rgba[1];
  3027. (*colors)[i*4+2] = rgba[2];
  3028. (*colors)[i*4+3] = rgba[3];
  3029. }
  3030. }
  3031. }
  3032. unsigned int TombRaider::getRoomVertexCount(unsigned int roomIndex)
  3033. {
  3034. unsigned int i, count;
  3035. if (!isRoomValid(roomIndex))
  3036. return 0;
  3037. switch (getEngine())
  3038. {
  3039. case TR_VERSION_UNKNOWN:
  3040. break;
  3041. case TR_VERSION_5:
  3042. for (i = 0, count = 0; i < mRoomsTR5[roomIndex].numLayers; ++i)
  3043. {
  3044. count += mRoomsTR5[roomIndex].layers[i].numLayerVertices;
  3045. }
  3046. return count;
  3047. case TR_VERSION_1:
  3048. case TR_VERSION_2:
  3049. case TR_VERSION_3:
  3050. case TR_VERSION_4:
  3051. return ((_rooms[roomIndex].room_data.num_vertices < 0) ? 0 :
  3052. _rooms[roomIndex].room_data.num_vertices);
  3053. }
  3054. return 0;
  3055. }
  3056. int TombRaider::getSkyModelId()
  3057. {
  3058. int skyMesh = -1;
  3059. //bool rot = false;
  3060. tr2_moveable_t *moveable;
  3061. unsigned int i, id;
  3062. moveable = Moveable();
  3063. switch (Engine())
  3064. {
  3065. case TR_VERSION_2:
  3066. //rot = true;
  3067. id = 254;
  3068. break;
  3069. case TR_VERSION_3:
  3070. id = 355;
  3071. break;
  3072. case TR_VERSION_4:
  3073. id = 459;
  3074. break;
  3075. case TR_VERSION_1:
  3076. case TR_VERSION_5:
  3077. case TR_VERSION_UNKNOWN:
  3078. return -1;
  3079. }
  3080. if (id > 0)
  3081. {
  3082. for (i = 0; (int)i < NumMoveables(); ++i)
  3083. {
  3084. if (moveable[i].object_id == id)
  3085. {
  3086. //sky_mesh = moveable[i].starting_mesh;
  3087. skyMesh = i;
  3088. break;
  3089. }
  3090. }
  3091. }
  3092. return skyMesh;
  3093. }
  3094. void TombRaider::getSprites()
  3095. {
  3096. #ifdef FIXME
  3097. int i, j, k, l, x, y, s_index, width, height;
  3098. float scale, width2, height2;
  3099. tr2_sprite_texture_t *sprite;
  3100. tr2_sprite_texture_t *sprite_textures;
  3101. tr2_sprite_sequence_t *sprite_sequence;
  3102. sprite_seq_t *r_mesh;
  3103. tr2_item_t *item;
  3104. r_mesh = Mesh();
  3105. item = Item();
  3106. sprite_textures = Sprite();
  3107. sprite_sequence = SpriteSequence();
  3108. scale = 4.0;
  3109. printf("Processing sprites: ");
  3110. for (i = 0; i < NumItems() - 1; ++i)
  3111. {
  3112. print(false, "Processing sprites in Items: %i/%i",
  3113. i, NumItems());
  3114. // It's a mesh, skip it
  3115. if (Engine() == TR_VERSION_1 && item[i].intensity1 == -1)
  3116. continue;
  3117. k = item[i].object_id;
  3118. // Search the SpriteSequence list
  3119. // (if we didn't already decide that it's a mesh)
  3120. for (j = 0; j < (int)NumSpriteSequences(); ++j)
  3121. {
  3122. if (sprite_sequence[j].object_id == k)
  3123. {
  3124. k = item[i].object_id;
  3125. s_index = sprite_sequence[j].offset;
  3126. spriteSequence = new sprite_seq_t;
  3127. spriteSequence->spriteCount = -sprite_sequence[j].negative_length;
  3128. spriteSequence->sprites = new sprite_t[r_mesh->num_sprites];
  3129. sprite = spriteSequence->sprites;
  3130. callbackAddSpriteSequence(spriteSequence);
  3131. for (l = 0; l < r_mesh->num_sprites; ++l)
  3132. {
  3133. sprite = &sprite_textures[s_index];
  3134. width = sprite->width >> 8;
  3135. height = sprite->height >> 8;
  3136. x = sprite->x;
  3137. y = sprite->y;
  3138. width2 = width * scale;
  3139. height2 = height * scale;
  3140. // For external use
  3141. sprite[l].pos[0] = item[i].x;
  3142. sprite[l].pos[1] = item[i].y;
  3143. sprite[l].pos[2] = item[i].z;
  3144. sprite[l].textureIndex = sprite->tile;
  3145. sprite[l].radius = width2 / 2.0;
  3146. sprite[l].vertex[0].pos[0] = -width2 / 2.0;
  3147. sprite[l].vertex[1].pos[0] = -width2 / 2.0;
  3148. sprite[l].vertex[2].pos[0] = width2 / 2.0;
  3149. sprite[l].vertex[3].pos[0] = width2 / 2.0;
  3150. sprite[l].vertex[0].pos[1] = 0;
  3151. sprite[l].vertex[1].pos[1] = -height2;
  3152. sprite[l].vertex[2].pos[1] = -height2;
  3153. sprite[l].vertex[3].pos[1] = 0;
  3154. sprite[l].vertex[0].pos[2] = 0;
  3155. sprite[l].vertex[1].pos[2] = 0;
  3156. sprite[l].vertex[2].pos[2] = 0;
  3157. sprite[l].vertex[3].pos[2] = 0;
  3158. sprite[l].texel[3].st[0] = (double)(x+width) / mTexelScale;
  3159. sprite[l].texel[3].st[1] = (double)(y+height) / mTexelScale;
  3160. sprite[l].texel[2].st[0] = (double)(x+width) / mTexelScale;
  3161. sprite[l].texel[2].st[1] = (double)(y) / mTexelScale;
  3162. sprite[l].texel[1].st[0] = (double)(x) / mTexelScale;
  3163. sprite[l].texel[1].st[1] = (double)(y) / mTexelScale;
  3164. sprite[l].texel[0].st[0] = (double)(x) / mTexelScale;
  3165. sprite[l].texel[0].st[1] = (double)(y+height) / mTexelScale;
  3166. printf(".");
  3167. fflush(stdout);
  3168. }
  3169. }
  3170. }
  3171. }
  3172. printf("\n");
  3173. #endif
  3174. }
  3175. void TombRaider::getSoundSample(unsigned int index,
  3176. unsigned int *bytes, unsigned char **data)
  3177. {
  3178. unsigned char *riff;
  3179. unsigned int offset, altIndex;
  3180. *bytes = 0;
  3181. *data = 0x0;
  3182. switch (Engine())
  3183. {
  3184. case TR_VERSION_1:
  3185. //! \fixme This implies higher tmp memory cost ( copy safety )
  3186. getRiffData(bytes, &riff);
  3187. if (riff && (int)index < mNumSampleIndices)
  3188. {
  3189. offset = mSampleIndices[index];
  3190. if ((int)index < mNumSampleIndices - 1)
  3191. {
  3192. *bytes = mSampleIndices[index+1] - mSampleIndices[index];
  3193. }
  3194. else
  3195. {
  3196. *bytes = *bytes - mSampleIndices[index];
  3197. }
  3198. *data = new unsigned char[*bytes];
  3199. memcpy(*data, riff+offset, *bytes);
  3200. }
  3201. if (riff)
  3202. {
  3203. delete [] riff;
  3204. }
  3205. break;
  3206. case TR_VERSION_2:
  3207. case TR_VERSION_3:
  3208. if (mRiffAlternateLoaded &&
  3209. mRiffData && mRiffAlternateOffsets && (int)index < mNumSampleIndices)
  3210. {
  3211. altIndex = mSampleIndices[index];
  3212. offset = mRiffAlternateOffsets[altIndex];
  3213. if ((int)offset > mRiffDataSz)
  3214. {
  3215. print("getSoundSample", "WARNING: offset too large, may be mismatched SFX and game pak, handling...\n");
  3216. return;
  3217. }
  3218. if (altIndex < mNumTR4Samples - 1)
  3219. {
  3220. *bytes = mRiffAlternateOffsets[altIndex+1] - offset;
  3221. }
  3222. else
  3223. {
  3224. *bytes = mRiffDataSz - offset;
  3225. }
  3226. *data = new unsigned char[*bytes];
  3227. memcpy(*data, mRiffData+offset, *bytes);
  3228. }
  3229. break;
  3230. case TR_VERSION_4:
  3231. case TR_VERSION_5:
  3232. getRiffDataTR4(index, bytes, data);
  3233. break;
  3234. case TR_VERSION_UNKNOWN:
  3235. break;
  3236. }
  3237. }
  3238. unsigned int TombRaider::getSoundSamplesCount()
  3239. {
  3240. unsigned int count = 0;
  3241. switch (Engine())
  3242. {
  3243. case TR_VERSION_1:
  3244. count = mNumSampleIndices;
  3245. break;
  3246. case TR_VERSION_2:
  3247. case TR_VERSION_3:
  3248. if (mRiffAlternateLoaded)
  3249. {
  3250. count = mNumSampleIndices;
  3251. }
  3252. break;
  3253. case TR_VERSION_4:
  3254. case TR_VERSION_5:
  3255. count = mNumTR4Samples;
  3256. break;
  3257. case TR_VERSION_UNKNOWN:
  3258. count = 0;
  3259. break;
  3260. }
  3261. return count;
  3262. }
  3263. bool TombRaider::isMeshValid(int index)
  3264. {
  3265. return !(index < 0 ||
  3266. index > mMeshCount ||
  3267. ((mMeshes[index].num_vertices < 0 ||
  3268. mMeshes[index].vertices == NULL)));
  3269. }
  3270. bool TombRaider::isRoomValid(int index)
  3271. {
  3272. // Yes, you MUST support signed indices due to legacy engines
  3273. if (index < 0)
  3274. return false;
  3275. switch (getEngine())
  3276. {
  3277. case TR_VERSION_UNKNOWN:
  3278. break;
  3279. case TR_VERSION_5:
  3280. if (index < _num_rooms &&
  3281. //mRoomsTR5[index].roomX != 0xcdcdcd &&
  3282. //mRoomsTR5[index].roomZ != 0xcdcdcd)
  3283. *((int *)&mRoomsTR5[index].roomX) != 0xcdcdcd &&
  3284. *((int *)&mRoomsTR5[index].roomZ) != 0xcdcdcd)
  3285. // Cast to int * as it was comparing with float 0xcdcdcd before
  3286. // -- xythobuz
  3287. {
  3288. return true;
  3289. }
  3290. break;
  3291. case TR_VERSION_1:
  3292. case TR_VERSION_2:
  3293. case TR_VERSION_3:
  3294. case TR_VERSION_4:
  3295. if (index < _num_rooms &&
  3296. _rooms[index].room_data.num_vertices > 0)
  3297. {
  3298. return true;
  3299. }
  3300. }
  3301. return false;
  3302. }
  3303. ////////////////////////////////////////////////////////////
  3304. // Public Mutators
  3305. ////////////////////////////////////////////////////////////
  3306. int TombRaider::loadSFX(char *filename)
  3307. {
  3308. FILE *f = fopen(filename, "rb");
  3309. long bytes = 0;
  3310. unsigned char *data;
  3311. if (!f)
  3312. {
  3313. perror("Couldn't load SFX file");
  3314. return -1;
  3315. }
  3316. fseek(f, 0L, SEEK_END);
  3317. bytes = ftell(f);
  3318. fseek(f, 0L, SEEK_SET);
  3319. if (bytes > 8)
  3320. {
  3321. data = new unsigned char[bytes];
  3322. fread(data, bytes, 1, f);
  3323. mNumTR4Samples = getRiffOffsets(data, bytes,
  3324. &mRiffAlternateOffsets,
  3325. mNumSampleIndices);
  3326. // This SFX must not come close to matching this game pak
  3327. if ((int)mNumTR4Samples < mNumSampleIndices)
  3328. {
  3329. delete [] data;
  3330. fclose(f);
  3331. print("loadSFX", "WARNING: SFX RIFF has less than pak's RIFF count\n");
  3332. return -2;
  3333. }
  3334. // If you ran out of room, then reallocate and parse agian =(
  3335. if (mNumSampleIndices < (int)mNumTR4Samples)
  3336. {
  3337. delete [] mRiffAlternateOffsets;
  3338. mNumTR4Samples = getRiffOffsets(data, bytes,
  3339. &mRiffAlternateOffsets,
  3340. mNumTR4Samples);
  3341. }
  3342. mRiffDataSz = bytes;
  3343. mRiffData = data;
  3344. mRiffAlternateLoaded = true;
  3345. }
  3346. fclose(f);
  3347. return 0;
  3348. }
  3349. void TombRaider::reset()
  3350. {
  3351. unsigned int i;
  3352. // Mongoose 2003.05.13, Don't let some jackass reset over and over
  3353. if (mReset)
  3354. {
  3355. return;
  3356. }
  3357. //! \fixme Palettes aren't the same size anymore
  3358. //memset(_palette8, 0, 256);
  3359. //memset(_palette16, 0, 256);
  3360. if (_anim_dispatches)
  3361. delete [] _anim_dispatches;
  3362. if (_anim_commands)
  3363. delete [] _anim_commands;
  3364. if (_mesh_trees)
  3365. delete [] _mesh_trees;
  3366. if (_frames)
  3367. delete [] _frames;
  3368. if (_moveables)
  3369. delete [] _moveables;
  3370. if (_static_meshes)
  3371. delete [] _static_meshes;
  3372. if (_object_textures)
  3373. delete [] _object_textures;
  3374. if (_sprite_textures)
  3375. delete [] _sprite_textures;
  3376. if (_sprite_sequences)
  3377. delete [] _sprite_sequences;
  3378. if (_cameras)
  3379. delete [] _cameras;
  3380. if (_sound_sources)
  3381. delete [] _sound_sources;
  3382. if (_boxes)
  3383. delete [] _boxes;
  3384. if (_overlaps)
  3385. delete [] _overlaps;
  3386. if (_zones)
  3387. delete [] _zones;
  3388. if (_animated_textures)
  3389. delete [] _animated_textures;
  3390. if (_items)
  3391. delete [] _items;
  3392. if (_light_map)
  3393. delete [] _light_map;
  3394. if (_cinematic_frames)
  3395. delete [] _cinematic_frames;
  3396. if (_demo_data)
  3397. delete [] _demo_data;
  3398. if (mRiffAlternateOffsets)
  3399. delete [] mRiffAlternateOffsets;
  3400. if (mSoundMap)
  3401. delete [] mSoundMap;
  3402. if (mSoundDetails)
  3403. delete [] mSoundDetails;
  3404. if (mSampleIndices)
  3405. delete [] mSampleIndices;
  3406. if (mRiffData)
  3407. delete [] mRiffData;
  3408. if (mTR4Samples)
  3409. {
  3410. for (i = 0; i < mNumTR4Samples; ++i)
  3411. {
  3412. if (mTR4SamplesSz[i])
  3413. delete [] mTR4Samples[i];
  3414. }
  3415. delete [] mTR4Samples;
  3416. }
  3417. if (mTR4SamplesSz)
  3418. delete [] mTR4SamplesSz;
  3419. if (_rooms)
  3420. {
  3421. for (i = 0; i < _num_rooms; ++i)
  3422. {
  3423. if (_rooms[i].room_data.num_vertices > 0)
  3424. delete [] _rooms[i].room_data.vertices;
  3425. if (_rooms[i].room_data.num_rectangles > 0)
  3426. delete [] _rooms[i].room_data.rectangles;
  3427. if (_rooms[i].room_data.num_triangles > 0)
  3428. delete [] _rooms[i].room_data.triangles;
  3429. if (_rooms[i].room_data.num_sprites > 0)
  3430. delete [] _rooms[i].room_data.sprites;
  3431. if (_rooms[i].num_portals > 0)
  3432. delete []_rooms[i].portals;
  3433. if (_rooms[i].sector_list)
  3434. delete [] _rooms[i].sector_list;
  3435. if (_rooms[i].lights)
  3436. delete [] _rooms[i].lights;
  3437. if (_rooms[i].tr4Lights)
  3438. delete [] _rooms[i].tr4Lights;
  3439. if (_rooms[i].static_meshes)
  3440. delete [] _rooms[i].static_meshes;
  3441. }
  3442. delete [] _rooms;
  3443. }
  3444. if (_floor_data)
  3445. {
  3446. delete [] _floor_data;
  3447. }
  3448. if (mMeshes)
  3449. {
  3450. for (i = 0; (int)i < mMeshCount; ++i)
  3451. {
  3452. if (mMeshes[i].vertices)
  3453. delete [] mMeshes[i].vertices;
  3454. if (mMeshes[i].mesh_lights)
  3455. delete [] mMeshes[i].mesh_lights;
  3456. if (mMeshes[i].normals)
  3457. delete [] mMeshes[i].normals;
  3458. if (mMeshes[i].textured_rectangles)
  3459. delete [] mMeshes[i].textured_rectangles;
  3460. if (mMeshes[i].textured_triangles)
  3461. delete [] mMeshes[i].textured_triangles;
  3462. if (mMeshes[i].coloured_rectangles)
  3463. delete [] mMeshes[i].coloured_rectangles;
  3464. if (mMeshes[i].coloured_triangles)
  3465. delete [] mMeshes[i].coloured_triangles;
  3466. }
  3467. delete [] mMeshes;
  3468. }
  3469. if (_animations)
  3470. delete [] _animations;
  3471. if (_state_changes)
  3472. delete _state_changes;
  3473. //delete [] _state_changes;
  3474. numMoveablesTR5 = 0;
  3475. if (moveablesTR5)
  3476. delete [] moveablesTR5;
  3477. numAnimationsTR5 = 0;
  3478. if (animationsTR5)
  3479. delete [] animationsTR5;
  3480. numObjectTexturesTR5 = 0;
  3481. if (objectTexturesTR5)
  3482. delete [] objectTexturesTR5;
  3483. numCinematicFramesTR5 = 0;
  3484. if (cinematicFramesTR5)
  3485. delete [] cinematicFramesTR5;
  3486. numFlyByCamerasTR5 = 0;
  3487. if (flyByCamerasTR5)
  3488. delete [] flyByCamerasTR5;
  3489. // Texture use
  3490. if (_tex_special)
  3491. delete [] _tex_special;
  3492. if (_textile8)
  3493. delete [] _textile8;
  3494. if (_textile16)
  3495. delete [] _textile16;
  3496. if (_textile32)
  3497. delete [] _textile32;
  3498. //! \fixme Damaged memory causes delete to not set pointer to NULL?
  3499. _tex_special = NULL;
  3500. _textile8 = NULL;
  3501. _textile16 = NULL;
  3502. _textile32 = NULL;
  3503. // Compressed level use
  3504. if (mCompressedLevelData)
  3505. delete [] mCompressedLevelData;
  3506. mCompressedLevelDataOffset = 0;
  3507. mCompressedLevelSize = 0;
  3508. mFreadMode = TR_FREAD_NORMAL;
  3509. // Clear out vars
  3510. mNumTR4Samples = 0;
  3511. mPakVersion = 0;
  3512. mEngineVersion = TR_VERSION_UNKNOWN;
  3513. mNumSampleIndices = 0;
  3514. mNumSoundDetails = 0;
  3515. mRiffAlternateLoaded = false;
  3516. _num_floor_data = 0;
  3517. _num_textiles = 0;
  3518. _num_tex_special = 0;
  3519. _num_room_textures = 0;
  3520. _num_misc_textures = 0;
  3521. _num_bump_map_textures = 0;
  3522. _unknown_t = 0;
  3523. _num_rooms = 0;
  3524. _num_anim_dispatches = 0;
  3525. mMeshCount = 0;
  3526. _num_state_changes = 0;
  3527. _num_animations = 0;
  3528. _num_anim_commands = 0;
  3529. _num_mesh_trees = 0;
  3530. _num_frames = 0;
  3531. _num_moveables = 0;
  3532. _num_demo_data = 0;
  3533. _num_cinematic_frames = 0;
  3534. _num_items = 0;
  3535. _num_animated_textures = 0;
  3536. _num_cameras = 0;
  3537. _num_sound_sources = 0;
  3538. _num_boxes = 0;
  3539. _num_static_meshes = 0;
  3540. _num_object_textures = 0;
  3541. _num_sprite_textures = 0;
  3542. _num_sprite_sequences = 0;
  3543. _num_overlaps = 0;
  3544. mReset = true;
  3545. }
  3546. void TombRaider::setDebug(bool toggle)
  3547. {
  3548. mDebug = toggle;
  3549. }
  3550. void TombRaider::setRoomVertexLightingFactor(float f)
  3551. {
  3552. mRoomVertexLightingFactor = f;
  3553. }
  3554. void TombRaider::setTexelScalingFactor(float f)
  3555. {
  3556. mTexelScale = f;
  3557. }
  3558. ////////////////////////////////////////////////////////////
  3559. // Private Accessors
  3560. ////////////////////////////////////////////////////////////
  3561. void TombRaider::extractMeshes(unsigned char *mesh_data,
  3562. unsigned int num_mesh_pointers,
  3563. unsigned int *mesh_pointers)
  3564. {
  3565. unsigned int size, i;
  3566. unsigned char *mesh_pointer;
  3567. int negative_size;
  3568. /* Alloc space for mesh */
  3569. mMeshCount = num_mesh_pointers;
  3570. printDebug("ExtractMeshes", "mMeshCount = %u", mMeshCount);
  3571. mMeshes = new tr2_mesh_t[mMeshCount];
  3572. printDebug("ExtractMeshes", "num_mesh_pointers = %u", num_mesh_pointers);
  3573. for (i = 0; i < num_mesh_pointers; ++i)
  3574. {
  3575. /* Get mesh start */
  3576. mesh_pointer = &mesh_data[mesh_pointers[i]];
  3577. /* Get Centre + Unknowns */
  3578. memcpy(&mMeshes[i].centre.x, mesh_pointer, 10);
  3579. //! \fixme endian
  3580. // depending on the interpretation of the unknowns that follow the Centre
  3581. // element, more endian conversion may be necessary
  3582. mesh_pointer += 10;
  3583. /* Get number of vertices */
  3584. memcpy(&mMeshes[i].num_vertices, mesh_pointer, 2);
  3585. //! \fixme endian
  3586. printDebug("ExtractMeshes", "mMeshes[%i].num_vertices = %u",
  3587. i, mMeshes[i].num_vertices);
  3588. mesh_pointer += sizeof(unsigned short);
  3589. mMeshes[i].num_vertices = (short)abs(mMeshes[i].num_vertices);
  3590. /* Get vertex list */
  3591. size = sizeof(tr2_vertex_t) * mMeshes[i].num_vertices;
  3592. mMeshes[i].vertices = 0x0;
  3593. if (mMeshes[i].num_vertices > 0)
  3594. mMeshes[i].vertices = new tr2_vertex_t[mMeshes[i].num_vertices];
  3595. memcpy(mMeshes[i].vertices, mesh_pointer, size);
  3596. //! \fixme endian
  3597. mesh_pointer += size;
  3598. /* Get number of normals */
  3599. memcpy(&mMeshes[i].num_normals, mesh_pointer, sizeof(unsigned short));
  3600. //! \fixme endian
  3601. mesh_pointer += sizeof(unsigned short);
  3602. negative_size = (mMeshes[i].num_normals < 0);
  3603. mMeshes[i].num_normals = (short)abs(mMeshes[i].num_normals);
  3604. printDebug("ExtractMeshes", "negative_size = %u", negative_size);
  3605. mMeshes[i].mesh_lights = 0x0;
  3606. mMeshes[i].normals = 0x0;
  3607. /* Get normal list */
  3608. if (negative_size)
  3609. {
  3610. negative_size = 0;
  3611. size = mMeshes[i].num_normals * sizeof(unsigned short);
  3612. mMeshes[i].mesh_lights = 0x0;
  3613. if (mMeshes[i].num_normals > 0)
  3614. mMeshes[i].mesh_lights = new short[mMeshes[i].num_normals];
  3615. memcpy(mMeshes[i].mesh_lights, mesh_pointer, size);
  3616. }
  3617. else
  3618. {
  3619. size = sizeof(tr2_vertex_t) * mMeshes[i].num_normals;
  3620. mMeshes[i].normals = 0x0;
  3621. if (mMeshes[i].num_normals > 0)
  3622. mMeshes[i].normals = new tr2_vertex_t[mMeshes[i].num_normals];
  3623. memcpy(mMeshes[i].normals, mesh_pointer, size);
  3624. }
  3625. //! \fixme endian
  3626. mesh_pointer += size;
  3627. /* Get number of textured rectangles */
  3628. memcpy(&mMeshes[i].num_textured_rectangles,
  3629. mesh_pointer, sizeof(unsigned short));
  3630. //! \fixme endian
  3631. mesh_pointer += sizeof(unsigned short);
  3632. mMeshes[i].num_textured_rectangles =
  3633. (short)abs(mMeshes[i].num_textured_rectangles);
  3634. size = sizeof(tr2_quad_t) * mMeshes[i].num_textured_rectangles;
  3635. mMeshes[i].textured_rectangles = 0x0;
  3636. if (mMeshes[i].num_textured_rectangles > 0)
  3637. mMeshes[i].textured_rectangles =
  3638. new tr2_quad_t[mMeshes[i].num_textured_rectangles];
  3639. printDebug("ExtractMeshes", "mMeshes[%i].num_textured_rectangles = %u",
  3640. i, mMeshes[i].num_textured_rectangles);
  3641. /* Get list of textured rectangles */
  3642. if (mMeshes[i].num_textured_rectangles > 0)
  3643. {
  3644. if (mEngineVersion == TR_VERSION_4)
  3645. {
  3646. int j;
  3647. for (j = 0; j < mMeshes[i].num_textured_rectangles; ++j)
  3648. {
  3649. memcpy(&mMeshes[i].textured_rectangles[j],
  3650. mesh_pointer, sizeof(tr2_quad_t));
  3651. mesh_pointer += sizeof(tr2_quad_t) + sizeof(unsigned short);
  3652. }
  3653. }
  3654. else
  3655. {
  3656. memcpy(mMeshes[i].textured_rectangles, mesh_pointer, size);
  3657. }
  3658. //! \fixme endian
  3659. if (mEngineVersion != TR_VERSION_4)
  3660. mesh_pointer += size;
  3661. }
  3662. /* Get number of textured triangles */
  3663. memcpy(&mMeshes[i].num_textured_triangles,
  3664. mesh_pointer, sizeof(unsigned short));
  3665. //! \fixme endian
  3666. mesh_pointer += sizeof(unsigned short);
  3667. mMeshes[i].num_textured_triangles =
  3668. (short)abs(mMeshes[i].num_textured_triangles);
  3669. size = sizeof(tr2_tri_t) * mMeshes[i].num_textured_triangles;
  3670. //if (mEngineVersion == TR_VERSION_4)
  3671. // size += 2 * mMeshes[i].num_textured_triangles;
  3672. mMeshes[i].textured_triangles = 0x0;
  3673. if (mMeshes[i].num_textured_triangles > 0)
  3674. {
  3675. mMeshes[i].textured_triangles =
  3676. new tr2_tri_t[mMeshes[i].num_textured_triangles];
  3677. }
  3678. printDebug("ExtractMeshes", " mMeshes[%i].num_textured_triangles = %u",
  3679. i, mMeshes[i].num_textured_triangles);
  3680. /* Get list of textured triangles */
  3681. if (mMeshes[i].num_textured_triangles > 0)
  3682. {
  3683. if (mEngineVersion == TR_VERSION_4)
  3684. {
  3685. int j;
  3686. for (j = 0; j < mMeshes[i].num_textured_triangles; ++j)
  3687. {
  3688. memcpy(&mMeshes[i].textured_triangles[j],
  3689. mesh_pointer, sizeof(tr2_tri_t));
  3690. mesh_pointer += sizeof(tr2_tri_t) + sizeof(unsigned short);
  3691. }
  3692. }
  3693. else
  3694. {
  3695. memcpy(mMeshes[i].textured_triangles, mesh_pointer, size);
  3696. }
  3697. //! \fixme endian
  3698. if (mEngineVersion != TR_VERSION_4)
  3699. mesh_pointer += size;
  3700. }
  3701. if (mEngineVersion == TR_VERSION_4)
  3702. {
  3703. mMeshes[i].num_coloured_rectangles = 0;
  3704. mMeshes[i].num_coloured_triangles = 0;
  3705. mMeshes[i].coloured_rectangles = 0x0;
  3706. mMeshes[i].coloured_triangles = 0x0;
  3707. // Mongoose 2002.04.04, FIXME is this right?
  3708. mesh_pointer += 2;
  3709. continue;
  3710. }
  3711. /* Get number of coloured rectangles */
  3712. memcpy(&mMeshes[i].num_coloured_rectangles, mesh_pointer,
  3713. sizeof(unsigned short));
  3714. //! \fixme endian
  3715. mesh_pointer += sizeof(unsigned short);
  3716. mMeshes[i].num_coloured_rectangles =
  3717. (short)abs(mMeshes[i].num_coloured_rectangles);
  3718. mMeshes[i].coloured_rectangles = 0x0;
  3719. size = sizeof(tr2_quad_t) * mMeshes[i].num_coloured_rectangles;
  3720. if (mMeshes[i].num_coloured_rectangles > 0)
  3721. mMeshes[i].coloured_rectangles =
  3722. new tr2_quad_t[mMeshes[i].num_coloured_rectangles];
  3723. printDebug("ExtractMeshes", "mMeshes[%i].num_coloured_rectangles = %u",
  3724. i, mMeshes[i].num_coloured_rectangles);
  3725. /* Get list of coloured rectangles */
  3726. if (mMeshes[i].num_coloured_rectangles > 0)
  3727. {
  3728. memcpy(mMeshes[i].coloured_rectangles, mesh_pointer, size);
  3729. //! \fixme endian
  3730. mesh_pointer += size;
  3731. }
  3732. /* Get number of coloured triangles */
  3733. memcpy(&mMeshes[i].num_coloured_triangles, mesh_pointer,
  3734. sizeof(unsigned short));
  3735. //! \fixme endian
  3736. mesh_pointer += sizeof(unsigned short);
  3737. mMeshes[i].num_coloured_triangles =
  3738. (short)abs(mMeshes[i].num_coloured_triangles);
  3739. size = sizeof(tr2_tri_t) * mMeshes[i].num_coloured_triangles;
  3740. mMeshes[i].coloured_triangles = 0x0;
  3741. if (mMeshes[i].num_coloured_triangles > 0)
  3742. mMeshes[i].coloured_triangles =
  3743. new tr2_tri_t[mMeshes[i].num_coloured_triangles];
  3744. printDebug("ExtractMeshes", "mMeshes[%i].num_coloured_triangles = %u",
  3745. i, mMeshes[i].num_coloured_triangles);
  3746. /* Get list of coloured triangles */
  3747. if (mMeshes[i].num_coloured_triangles > 0)
  3748. {
  3749. memcpy(mMeshes[i].coloured_triangles, mesh_pointer, size);
  3750. //! \fixme endian
  3751. mesh_pointer += size;
  3752. }
  3753. }
  3754. }
  3755. int TombRaider::Fread(void *buffer, size_t size, size_t count, FILE *f)
  3756. {
  3757. int num_read;
  3758. if (mFreadMode == TR_FREAD_COMPRESSED)
  3759. {
  3760. num_read = count;
  3761. num_read *= size;
  3762. if ((mCompressedLevelDataOffset + num_read) <= mCompressedLevelSize)
  3763. {
  3764. memcpy(buffer, &mCompressedLevelData[mCompressedLevelDataOffset],
  3765. num_read);
  3766. mCompressedLevelDataOffset += num_read;
  3767. return count;
  3768. }
  3769. else
  3770. {
  3771. print("Fread", "(%p, %lu, %lu, %p) ERROR: Returned %d bytes too far",
  3772. buffer, size, count, f, num_read);
  3773. reset();
  3774. exit(2);
  3775. }
  3776. }
  3777. unsigned int offset = ftell(f);
  3778. if (fread(buffer, size, count, f) != count)
  3779. {
  3780. print("Fread", "ERROR: Failed fread. Should Abort. @ 0x%x", offset);
  3781. reset();
  3782. exit(2);
  3783. // return -1; // Unreachable anyways
  3784. }
  3785. return count;
  3786. }
  3787. void TombRaider::getRiffData(unsigned int *bytes, unsigned char **data)
  3788. {
  3789. *bytes = 0;
  3790. *data = 0x0;
  3791. if (mRiffDataSz)
  3792. {
  3793. *bytes = mRiffDataSz;
  3794. *data = new unsigned char[mRiffDataSz];
  3795. memcpy(*data, mRiffData, mRiffDataSz);
  3796. }
  3797. }
  3798. void TombRaider::getRiffDataTR4(unsigned int index,
  3799. unsigned int *bytes, unsigned char **data)
  3800. {
  3801. *bytes = 0;
  3802. *data = 0x0;
  3803. if (index < mNumTR4Samples)
  3804. {
  3805. *bytes = mTR4SamplesSz[index];
  3806. *data = new unsigned char[*bytes];
  3807. memcpy(*data, mTR4Samples[index], *bytes);
  3808. }
  3809. }
  3810. int TombRaider::getRiffOffsets(unsigned char *riffData,
  3811. unsigned int riffDataBytes,
  3812. unsigned int **offsets,
  3813. unsigned int numOffsets)
  3814. {
  3815. unsigned int i, j = 0, riffCount, state;
  3816. *offsets = new unsigned int[numOffsets];
  3817. for (i = 0, riffCount = 0, state = 4; i < riffDataBytes; ++i)
  3818. {
  3819. switch (riffData[i])
  3820. {
  3821. case 'R':
  3822. if (state == 4)
  3823. {
  3824. j = i; // tmp offset guess
  3825. state = 0;
  3826. continue;
  3827. }
  3828. break;
  3829. case 'I':
  3830. if (state == 0)
  3831. {
  3832. state = 1;
  3833. continue;
  3834. }
  3835. break;
  3836. case 'F':
  3837. if (state == 1)
  3838. {
  3839. state = 2;
  3840. continue;
  3841. }
  3842. else if (state == 2)
  3843. {
  3844. state = 3;
  3845. // Found RIFF header, but we can only report
  3846. // riffCount offsets ( buffer size limits )
  3847. if (riffCount < numOffsets)
  3848. {
  3849. (*offsets)[riffCount] = j;
  3850. }
  3851. ++riffCount;
  3852. continue;
  3853. }
  3854. break;
  3855. }
  3856. state = 4;
  3857. }
  3858. return riffCount;
  3859. }
  3860. unsigned char *TombRaider::getTexTile(int texture)
  3861. {
  3862. unsigned char *image;
  3863. unsigned int color;
  3864. int j, k, index, offset;
  3865. int xmin, xmax, ymin, ymax, x, y;
  3866. image = NULL;
  3867. if (texture >=0 && texture < (int)_num_textiles)
  3868. {
  3869. image = new unsigned char[256*256*4];
  3870. memset(image, 0, 256*256*4);
  3871. if (_textile32)
  3872. {
  3873. // Convert 32bit BGRA image format to 32bit RGBA
  3874. for (j = 0; j < 256; j++)
  3875. {
  3876. for (k = 0; k < 256; k++)
  3877. {
  3878. index = (j * 256) + k;
  3879. color = _textile32[texture].tile[index];
  3880. index = (j * 1024) + (k * 4);
  3881. image[index + 2] = *((unsigned char *)(&color));
  3882. image[index + 1] = *((unsigned char *)(&color)+1);
  3883. image[index + 0] = *((unsigned char *)(&color)+2);
  3884. image[index + 3] = *((unsigned char *)(&color)+3);
  3885. }
  3886. }
  3887. }
  3888. else
  3889. {
  3890. // Convert 16bit ARGB image format to 32bit RGBA
  3891. for (j = 0; j < 256; j++)
  3892. {
  3893. for (k = 0; k < 256; k++)
  3894. {
  3895. index = (j * 256) + k;
  3896. offset = _textile16[texture].tile[index];
  3897. index = (j * 1024) + (k * 4);
  3898. image[index + 0] = ((offset >> 10) & 0x1f) * 8;
  3899. image[index + 1] = ((offset >> 5) & 0x1f) * 8;
  3900. image[index + 2] = (offset & 0x1f) * 8;
  3901. image[index + 3] = (offset & 0x8000) ? 0xFF : 0;
  3902. }
  3903. }
  3904. }
  3905. switch (Engine())
  3906. {
  3907. case TR_VERSION_4:
  3908. case TR_VERSION_3: // Account for alpha flags
  3909. for (j = 0; j < (int)_num_object_textures; j++)
  3910. {
  3911. //! \fixme This kind of works for lighting - but messes up lara
  3912. #ifdef FIXME
  3913. if (_object_textures[j].tile == texture &&
  3914. _object_textures[j].transparency_flags == 1)
  3915. {
  3916. xmin = 999;
  3917. xmax = 0;
  3918. ymin = 999;
  3919. ymax = 0;
  3920. y = 4;
  3921. // Account for triangles
  3922. if (_object_textures[j].vertices[3].xpixel == 0 &&
  3923. _object_textures[j].vertices[3].ypixel == 0)
  3924. y = 3;
  3925. for (k = 0; k < y; k++)
  3926. {
  3927. if (_object_textures[j].vertices[k].xpixel > xmax)
  3928. xmax = _object_textures[j].vertices[k].xpixel;
  3929. if (_object_textures[j].vertices[k].xpixel < xmin)
  3930. xmin = _object_textures[j].vertices[k].xpixel;
  3931. if (_object_textures[j].vertices[k].ypixel > ymax)
  3932. ymax = _object_textures[j].vertices[k].ypixel;
  3933. if (_object_textures[j].vertices[k].ypixel < ymin)
  3934. ymin = _object_textures[j].vertices[k].ypixel;
  3935. }
  3936. for (x = xmin; x <= xmax; x++)
  3937. {
  3938. for (y = ymin; y <= ymax; y++)
  3939. {
  3940. index = (y * 256) + x;
  3941. offset = _textile16[texture].tile[index];
  3942. index = (y * 1024) + (x * 4);
  3943. image[index + 0] = ((offset >> 10) & 0x1f) * 8;
  3944. image[index + 1] = ((offset >> 5) & 0x1f) * 8;
  3945. image[index + 2] = (offset & 0x1f) * 8;
  3946. // Set transparency to full
  3947. if (offset & 0x8000)
  3948. {
  3949. image[index + 3] = 0x00;
  3950. }
  3951. }
  3952. }
  3953. }
  3954. else
  3955. #endif
  3956. if (_object_textures[j].tile == texture &&
  3957. _object_textures[j].transparency_flags == 2)
  3958. {
  3959. xmin = 999;
  3960. xmax = 0;
  3961. ymin = 999;
  3962. ymax = 0;
  3963. y = 4;
  3964. // Account for triangles
  3965. if (_object_textures[j].vertices[3].xpixel == 0 &&
  3966. _object_textures[j].vertices[3].ypixel == 0)
  3967. y = 3;
  3968. for (k = 0; k < y; k++)
  3969. {
  3970. if (_object_textures[j].vertices[k].xpixel > xmax)
  3971. xmax = _object_textures[j].vertices[k].xpixel;
  3972. if (_object_textures[j].vertices[k].xpixel < xmin)
  3973. xmin = _object_textures[j].vertices[k].xpixel;
  3974. if (_object_textures[j].vertices[k].ypixel > ymax)
  3975. ymax = _object_textures[j].vertices[k].ypixel;
  3976. if (_object_textures[j].vertices[k].ypixel < ymin)
  3977. ymin = _object_textures[j].vertices[k].ypixel;
  3978. }
  3979. for (x = xmin; x <= xmax; x++)
  3980. {
  3981. for (y = ymin; y <= ymax; y++)
  3982. {
  3983. if (_textile32)
  3984. {
  3985. index = (y * 256) + x;
  3986. color = _textile32[texture].tile[index];
  3987. index = (y * 1024) + (x * 4);
  3988. image[index + 2] = *((unsigned char *)(&color));
  3989. image[index + 1] = *((unsigned char *)(&color)+1);
  3990. image[index + 0] = *((unsigned char *)(&color)+2);
  3991. image[index + 3] = *((unsigned char *)(&color)+3);
  3992. k = image[index] + image[index + 1] + image[index + 2];
  3993. // Set transparency based upon intensity
  3994. image[index + 3] = (unsigned char)(k / 3);
  3995. }
  3996. else
  3997. {
  3998. index = (y * 256) + x;
  3999. offset = _textile16[texture].tile[index];
  4000. index = (y * 1024) + (x * 4);
  4001. image[index + 0] = ((offset >> 10) & 0x1f) * 8;
  4002. image[index + 1] = ((offset >> 5) & 0x1f) * 8;
  4003. image[index + 2] = (offset & 0x1f) * 8;
  4004. image[index + 3] = (offset & 0x8000) ? 0xFF : 0;
  4005. k = image[index] + image[index + 1] + image[index + 2];
  4006. // Set transparency based upon intensity
  4007. if (offset & 0x8000)
  4008. image[index + 3] = (unsigned char)(k / 3);
  4009. else
  4010. image[index + 3] = 0;
  4011. }
  4012. }
  4013. }
  4014. }
  4015. }
  4016. break;
  4017. case TR_VERSION_1:
  4018. case TR_VERSION_2:
  4019. case TR_VERSION_5:
  4020. case TR_VERSION_UNKNOWN:
  4021. break;
  4022. }
  4023. }
  4024. return image;
  4025. }
  4026. //! \fixme Move these data about to make full use in the class ;)
  4027. int TombRaider::loadTR5(FILE *f, void (*percent)(int))
  4028. {
  4029. unsigned int level_data_sz, riffOffset, seperator0;
  4030. unsigned int portalOffset, nextRoomOffset, thisRoomOffset;
  4031. int i, j, k;
  4032. u_int16_t us;
  4033. u_int32_t numMeshData, numMeshPointers, u;
  4034. u_int32_t *meshPointers;
  4035. u_int8_t *meshData;
  4036. char check[32];
  4037. if (percent)
  4038. (*percent)(5);
  4039. printDebug("Load", "mEngineVersion = 0x%x", mPakVersion);
  4040. if (mEngineVersion != TR_VERSION_5)
  4041. return -1;
  4042. unsigned int sz, usz; // compressed and uncompressed size
  4043. unsigned char *compressed_data = NULL;
  4044. int zerr;
  4045. uLongf foo;
  4046. // Read texture type offsets
  4047. Fread(&_num_room_textures, 2, 1, f);
  4048. printDebug("LoadTR5", "_num_room_textures = %u", _num_room_textures);
  4049. Fread(&_num_misc_textures, 2, 1, f);
  4050. printDebug("LoadTR5", "_num_misc_textures = %u", _num_misc_textures);
  4051. Fread(&_num_bump_map_textures, 2, 1, f);
  4052. printDebug("LoadTR5", "_num_bump_map_textures = %u", _num_bump_map_textures);
  4053. // Read the sizes of the 32-bit textures
  4054. Fread(&usz, sizeof(usz), 1, f);
  4055. Fread(&sz, sizeof(sz), 1, f);
  4056. printDebug("LoadTR5", "32-bit textures compressed size = %u bytes", sz);
  4057. printDebug("LoadTR5", "32-bit textures uncompressed size = %u bytes", usz);
  4058. _num_textiles = usz / sizeof(tr2_textile32_t);
  4059. printDebug("LoadTR5", "_num_textiles = %i/%lu = %i",
  4060. usz, sizeof(tr2_textile32_t), _num_textiles);
  4061. _textile32 = new tr2_textile32_t[_num_textiles];
  4062. // Allocate a temporary buffer for decompression
  4063. compressed_data = new unsigned char[sz];
  4064. Fread(compressed_data, sz, 1, f);
  4065. // Decompress the textures
  4066. foo = usz;
  4067. zerr = uncompress((unsigned char *)_textile32,
  4068. &foo,
  4069. compressed_data,
  4070. sz);
  4071. usz = foo;
  4072. printDebug("LoadTR5", "textile decompress [%s]",
  4073. (zerr == Z_OK) ? "OK" : "ERROR");
  4074. switch (zerr)
  4075. {
  4076. case Z_MEM_ERROR:
  4077. printDebug("LoadTR5", "There was not enough memory");
  4078. break;
  4079. case Z_BUF_ERROR:
  4080. printDebug("LoadTR5", "There was not enough room in the output buffer");
  4081. break;
  4082. case Z_DATA_ERROR:
  4083. printDebug("LoadTR5", "The input data was corrupted");
  4084. break;
  4085. default:
  4086. printDebug("LoadTR5", "textile decompress %i", zerr);
  4087. }
  4088. // Free the temporary buffer
  4089. delete [] compressed_data;
  4090. // Read in the 16-bit textures, set NumTextiles
  4091. Fread(&usz, sizeof(usz), 1, f);
  4092. Fread(&sz, sizeof(sz), 1, f);
  4093. printDebug("LoadTR5", "16-bit textures compressed size = %u bytes", sz);
  4094. printDebug("LoadTR5", "16-bit textures uncompressed size = %u bytes", usz);
  4095. _num_textiles = usz / sizeof(tr2_textile16_t);
  4096. printDebug("LoadTR5", "_num_textiles = %i/%lu = %i",
  4097. usz, sizeof(tr2_textile16_t), _num_textiles);
  4098. _textile16 = new tr2_textile16_t[_num_textiles];
  4099. // Allocate a temporary buffer for decompression
  4100. compressed_data = new unsigned char[sz];
  4101. Fread(compressed_data, sz, 1, f);
  4102. // Decompress the textures
  4103. foo = usz;
  4104. zerr = uncompress((unsigned char *)_textile16,
  4105. &foo,
  4106. compressed_data,
  4107. sz);
  4108. usz = foo;
  4109. if (percent)
  4110. (*percent)(7);
  4111. printDebug("LoadTR5", "textile decompress [%s]",
  4112. (zerr == Z_OK) ? "OK" : "ERROR");
  4113. switch (zerr)
  4114. {
  4115. case Z_MEM_ERROR:
  4116. printDebug("LoadTR5", "There was not enough memory");
  4117. break;
  4118. case Z_BUF_ERROR:
  4119. printDebug("LoadTR5", "There was not enough room in the output buffer");
  4120. break;
  4121. case Z_DATA_ERROR:
  4122. printDebug("LoadTR5", "The input data was corrupted");
  4123. break;
  4124. default:
  4125. printDebug("LoadTR5", "textile decompress %i", zerr);
  4126. }
  4127. // Free the temporary buffer
  4128. delete [] compressed_data;
  4129. // Read the sizes of the sprite textures
  4130. Fread(&usz, sizeof(usz), 1, f);
  4131. Fread(&sz, sizeof(sz), 1, f);
  4132. printDebug("LoadTR5", "sprite textures compressed size = %u bytes", sz);
  4133. printDebug("LoadTR5", "sprite textures uncompressed size = %u bytes", usz);
  4134. // Load sprite/bump map/gui/etc textures also
  4135. _num_tex_special = usz/(256*256*4);
  4136. printDebug("LoadTR5", "_num_tex_special = %i/%i = %i",
  4137. usz, 256*256*4, _num_tex_special);
  4138. printDebug("LoadTR5", "Reading %ibytes of sprite textures", usz);
  4139. if (usz)
  4140. {
  4141. _tex_special = new unsigned char[usz];
  4142. // Allocate a temporary buffer for decompression
  4143. compressed_data = new unsigned char[sz];
  4144. Fread(compressed_data, sz, 1, f);
  4145. // Decompress the textures
  4146. foo = usz;
  4147. zerr = uncompress(_tex_special,
  4148. &foo,
  4149. compressed_data,
  4150. sz);
  4151. usz = foo;
  4152. printDebug("LoadTR5", "special texture decompress [%s]",
  4153. (zerr == Z_OK) ? "OK" : "ERROR");
  4154. switch (zerr)
  4155. {
  4156. case Z_MEM_ERROR:
  4157. printDebug("LoadTR5", "There was not enough memory");
  4158. break;
  4159. case Z_BUF_ERROR:
  4160. printDebug("LoadTR5", "There was not enough room in the output buffer");
  4161. break;
  4162. case Z_DATA_ERROR:
  4163. printDebug("LoadTR5", "The input data was corrupted");
  4164. break;
  4165. default:
  4166. printDebug("LoadTR5", "textile decompress %i", zerr);
  4167. }
  4168. // Free the temporary buffer
  4169. delete [] compressed_data;
  4170. }
  4171. if (percent)
  4172. (*percent)(10);
  4173. // Mongoose 2002.01.08, Michiel has discovered the
  4174. // first 4 bytes here are 2 bitu16 flags for Lara type and weather
  4175. u_int16_t laraType, weather;
  4176. Fread(&laraType, 2, 1, f);
  4177. printDebug("LoadTR5", "laraType = 0x%x", laraType);
  4178. Fread(&weather, 2, 1, f);
  4179. printDebug("LoadTR5", "weather = 0x%x", weather);
  4180. printDebug("LoadTR5", "skipping 28bytes of unknowns");
  4181. Fread(&seperator0, 4, 1, f);
  4182. printDebug("LoadTR5", "0x%x", seperator0);
  4183. Fread(&seperator0, 4, 1, f);
  4184. printDebug("LoadTR5", "0x%x", seperator0);
  4185. Fread(&seperator0, 4, 1, f);
  4186. printDebug("LoadTR5", "0x%x", seperator0);
  4187. Fread(&seperator0, 4, 1, f);
  4188. printDebug("LoadTR5", "0x%x", seperator0);
  4189. Fread(&seperator0, 4, 1, f);
  4190. printDebug("LoadTR5", "0x%x", seperator0);
  4191. Fread(&seperator0, 4, 1, f);
  4192. printDebug("LoadTR5", "0x%x", seperator0);
  4193. Fread(&seperator0, 4, 1, f);
  4194. printDebug("LoadTR5", "0x%x", seperator0);
  4195. Fread(&level_data_sz, 4, 1, f);
  4196. printDebug("LoadTR5", "Level data size = %u", level_data_sz);
  4197. Fread(&riffOffset, 4, 1, f);
  4198. printDebug("LoadTR5", "Same as last, also offset to RIFFs = %u",
  4199. riffOffset);
  4200. Fread(&seperator0, 4, 1, f);
  4201. printDebug("LoadTR5", "Seperator, always 0x00? = %u", seperator0);
  4202. Fread(&_num_rooms, 4, 1, f);
  4203. printDebug("LoadTR5", "_num_rooms = %u", _num_rooms);
  4204. mRoomsTR5 = new tr5_room_t[_num_rooms];
  4205. for (i = 0; i < _num_rooms; ++i)
  4206. {
  4207. if (percent)
  4208. (*percent)(11 + (int)(((float)i/(float)_num_rooms)*90.0));
  4209. thisRoomOffset = ftell(f);
  4210. Fread(&mRoomsTR5[i].checkXELA, 4, 1, f);
  4211. printDebug("LoadTR5", "room[%i].checkXELA (0x414c4558)? = 0x%x",
  4212. i, mRoomsTR5[i].checkXELA);
  4213. if (mRoomsTR5[i].checkXELA != 0x414c4558)
  4214. {
  4215. print("LoadTR5", "Error #1 room[%i].checkXELA (0x414c4558) != 0x%x",
  4216. i, mRoomsTR5[i].checkXELA);
  4217. return -3;
  4218. }
  4219. Fread(&mRoomsTR5[i].roomDataSize, 4, 1, f);
  4220. printDebug("LoadTR5", "offset to next room = %u",
  4221. mRoomsTR5[i].roomDataSize);
  4222. nextRoomOffset = ftell(f) + mRoomsTR5[i].roomDataSize;
  4223. Fread(&mRoomsTR5[i].seperator, 4, 1, f);
  4224. printDebug("LoadTR5", "room[%i].seperator, CDCDCDCD = %X?",
  4225. i, mRoomsTR5[i].seperator);
  4226. if (mRoomsTR5[i].seperator != 0xcdcdcdcd)
  4227. {
  4228. print("LoadTR5", "Error #2 room[%i].seperator, CDCDCDCD != 0x%X",
  4229. i, mRoomsTR5[i].seperator);
  4230. return -3;
  4231. }
  4232. // Start 60byte struct /////////////
  4233. printDebug("LoadTR5", "60byte struct {");
  4234. // Often start of "XELA" +216 + ublock1 = FD end,
  4235. // but have seen 0xffffffff (-1). Better using next data
  4236. // and compute FD size the old way of X*Z*8
  4237. Fread(&mRoomsTR5[i].endSDOffset, 4, 1, f);
  4238. printDebug("LoadTR5", "%u + 216 + XELA start = FD end",
  4239. mRoomsTR5[i].endSDOffset);
  4240. // Start of "XELA" + 216 + ublock2 = FD start
  4241. Fread(&mRoomsTR5[i].startSDOffset, 4, 1, f);
  4242. printDebug("LoadTR5", "%u + 216 + XELA start = FD start",
  4243. mRoomsTR5[i].startSDOffset);
  4244. Fread(&mRoomsTR5[i].seperator2, 4, 1, f);
  4245. printDebug("LoadTR5", "seperator2 = %u", mRoomsTR5[i].seperator2);
  4246. if (mRoomsTR5[i].seperator2 != 0xcdcdcdcd &&
  4247. mRoomsTR5[i].seperator2 != 0x00000000)
  4248. {
  4249. print("LoadTR5", "Error #3 CDCDCDCD | 0x0 != 0x%x",
  4250. mRoomsTR5[i].seperator2);
  4251. return -3;
  4252. }
  4253. // Possibly start of "XELA" + 216 + ublock4 = end portals
  4254. Fread(&mRoomsTR5[i].endPortalOffset, 4, 1, f);
  4255. printDebug("LoadTR5", "%u + 216 + XELA start = end portals",
  4256. mRoomsTR5[i].endPortalOffset);
  4257. Fread(&mRoomsTR5[i].x, 4, 1, f);
  4258. printDebug("LoadTR5", "room.x = %u", mRoomsTR5[i].x);
  4259. Fread(&mRoomsTR5[i].seperator3, 4, 1, f);
  4260. printDebug("LoadTR5", "0x00000000 = %u ?", mRoomsTR5[i].seperator3);
  4261. Fread(&mRoomsTR5[i].z, 4, 1, f);
  4262. printDebug("LoadTR5", "room.z = %u", mRoomsTR5[i].z);
  4263. Fread(&mRoomsTR5[i].yBottom, 4, 1, f);
  4264. printDebug("LoadTR5", "room.y_bottom = %u", mRoomsTR5[i].yBottom);
  4265. Fread(&mRoomsTR5[i].yTop, 4, 1, f);
  4266. printDebug("LoadTR5", "room.y_top = %u", mRoomsTR5[i].yTop);
  4267. Fread(&mRoomsTR5[i].numZSectors, 2, 1, f);
  4268. printDebug("LoadTR5", "num_z_sectors = %i", mRoomsTR5[i].numZSectors);
  4269. Fread(&mRoomsTR5[i].numXSectors, 2, 1, f);
  4270. printDebug("LoadTR5", "num_x_sectors = %i", mRoomsTR5[i].numXSectors);
  4271. Fread(&mRoomsTR5[i].roomAmbientColor, 4, 1, f);
  4272. printDebug("LoadTR5", "room_ambient_color = 0x%x",
  4273. mRoomsTR5[i].roomAmbientColor);
  4274. Fread(&mRoomsTR5[i].numRoomLights, 2, 1, f);
  4275. printDebug("LoadTR5", "num_lights = %i", mRoomsTR5[i].numRoomLights);
  4276. Fread(&mRoomsTR5[i].numStaticMeshes, 2, 1, f);
  4277. printDebug("LoadTR5", "num_static_meshes = %i",
  4278. mRoomsTR5[i].numStaticMeshes);
  4279. Fread(&mRoomsTR5[i].unknownR1, 2, 1, f);
  4280. printDebug("LoadTR5", "unknown 0x0001? = 0x%x", mRoomsTR5[i].unknownR1);
  4281. Fread(&mRoomsTR5[i].unknownR2, 2, 1, f);
  4282. printDebug("LoadTR5", "unknown 0x0000? = 0x%x", mRoomsTR5[i].unknownR2);
  4283. Fread(&mRoomsTR5[i].filler, 4, 1, f);
  4284. printDebug("LoadTR5", "Always 0x7fff? = 0x%x", mRoomsTR5[i].filler);
  4285. Fread(&mRoomsTR5[i].filler2, 4, 1, f);
  4286. printDebug("LoadTR5", "Always 0x7fff? = 0x%x", mRoomsTR5[i].filler2);
  4287. printDebug("LoadTR5", "}");
  4288. // End 60byte structure /////////////////
  4289. Fread(&mRoomsTR5[i].seperator4, 4, 1, f);
  4290. printDebug("LoadTR5", "seperator4 CDCDCDCD = 0x%x",
  4291. mRoomsTR5[i].seperator4);
  4292. if (mRoomsTR5[i].seperator4 != 0xcdcdcdcd)
  4293. {
  4294. print("LoadTR5", "Error #5 CDCDCDCD != 0x%x",
  4295. mRoomsTR5[i].seperator4);
  4296. return -3;
  4297. }
  4298. Fread(&mRoomsTR5[i].seperator5, 4, 1, f);
  4299. printDebug("LoadTR5", "seperator5 CDCDCDCD = 0x%x",
  4300. mRoomsTR5[i].seperator5);
  4301. if (mRoomsTR5[i].seperator5 != 0xcdcdcdcd)
  4302. {
  4303. print("LoadTR5", "Error #6 CDCDCDCD != 0x%x",
  4304. mRoomsTR5[i].seperator5);
  4305. return -3;
  4306. }
  4307. // Start 20byte structure ///////////////
  4308. printDebug("LoadTR5", "20byte struct {");
  4309. Fread(mRoomsTR5[i].seperator6, 6, 1, f);
  4310. printDebug("LoadTR5", "6 bytes 0xFF = 0x%x%x%x%x%x%x",
  4311. mRoomsTR5[i].seperator6[0], mRoomsTR5[i].seperator6[1],
  4312. mRoomsTR5[i].seperator6[2], mRoomsTR5[i].seperator6[3],
  4313. mRoomsTR5[i].seperator6[4], mRoomsTR5[i].seperator6[5]);
  4314. Fread(&mRoomsTR5[i].roomFlag, 2, 1, f);
  4315. printDebug("LoadTR5", "room_flag = %i", mRoomsTR5[i].roomFlag);
  4316. Fread(&mRoomsTR5[i].unknownR5, 2, 1, f);
  4317. printDebug("LoadTR5", "unknown = %i", mRoomsTR5[i].unknownR5);
  4318. Fread(mRoomsTR5[i].seperator7, 10, 1, f);
  4319. printDebug("LoadTR5", "10 bytes 0x00 = 0x%x%x%x%x%x%x%x%x%x%x",
  4320. mRoomsTR5[i].seperator7[0], mRoomsTR5[i].seperator7[1],
  4321. mRoomsTR5[i].seperator7[2], mRoomsTR5[i].seperator7[3],
  4322. mRoomsTR5[i].seperator7[4], mRoomsTR5[i].seperator7[5],
  4323. mRoomsTR5[i].seperator7[6], mRoomsTR5[i].seperator7[7],
  4324. mRoomsTR5[i].seperator7[8], mRoomsTR5[i].seperator7[9]);
  4325. printDebug("LoadTR5", "}");
  4326. // End 20byte structure /////////////////
  4327. Fread(&mRoomsTR5[i].seperator8, 4, 1, f);
  4328. printDebug("LoadTR5", "seperator8 CDCDCDCD = 0x%x",
  4329. mRoomsTR5[i].seperator8);
  4330. if (mRoomsTR5[i].seperator8 != 0xcdcdcdcd)
  4331. {
  4332. print("LoadTR5", "Error #9 CDCDCDCD != 0x%x",
  4333. mRoomsTR5[i].seperator8);
  4334. return -3;
  4335. }
  4336. printDebug("LoadTR5", "16byte struct {");
  4337. Fread(&mRoomsTR5[i].unknownR6, 4, 1, f);
  4338. printDebug("LoadTR5", "unknownR6 = %i", mRoomsTR5[i].unknownR6);
  4339. Fread(&mRoomsTR5[i].roomX, 4, 1, f);
  4340. printDebug("LoadTR5", "roomX = %f", mRoomsTR5[i].roomX);
  4341. Fread(&mRoomsTR5[i].seperator9, 4, 1, f);
  4342. printDebug("LoadTR5", "seperator9 CDCDCDCD | 0x0 = 0x%x",
  4343. mRoomsTR5[i].seperator9);
  4344. if (mRoomsTR5[i].seperator9 != 0xcdcdcdcd &&
  4345. mRoomsTR5[i].seperator9 != 0x0)
  4346. {
  4347. print("LoadTR5", "Error #10 CDCDCDCD | 0x0 != 0x%x",
  4348. mRoomsTR5[i].seperator9);
  4349. return -3;
  4350. }
  4351. Fread(&mRoomsTR5[i].roomZ, 4, 1, f);
  4352. printDebug("LoadTR5", "roomZ = %f", mRoomsTR5[i].roomZ);
  4353. printDebug("LoadTR5", "}");
  4354. Fread(&mRoomsTR5[i].seperator10, 4, 1, f);
  4355. printDebug("LoadTR5", "seperator10 CDCDCDCD = 0x%x",
  4356. mRoomsTR5[i].seperator10);
  4357. if (mRoomsTR5[i].seperator10 != 0xcdcdcdcd)
  4358. {
  4359. print("LoadTR5", "Error #11 CDCDCDCD != 0x%x",
  4360. mRoomsTR5[i].seperator10);
  4361. return -3;
  4362. }
  4363. Fread(&mRoomsTR5[i].seperator11, 4, 1, f);
  4364. printDebug("LoadTR5", "seperator11 CDCDCDCD = 0x%x",
  4365. mRoomsTR5[i].seperator11);
  4366. if (mRoomsTR5[i].seperator11 != 0xcdcdcdcd)
  4367. {
  4368. print("LoadTR5", "Error #12 CDCDCDCD != 0x%x",
  4369. mRoomsTR5[i].seperator11);
  4370. return -3;
  4371. }
  4372. Fread(&mRoomsTR5[i].seperator12, 4, 1, f);
  4373. printDebug("LoadTR5", "seperator12 CDCDCDCD = 0x%x",
  4374. mRoomsTR5[i].seperator12);
  4375. if (mRoomsTR5[i].seperator12 != 0xcdcdcdcd)
  4376. {
  4377. print("LoadTR5", "Error #13 CDCDCDCD != 0x%x",
  4378. mRoomsTR5[i].seperator12);
  4379. return -3;
  4380. }
  4381. Fread(&mRoomsTR5[i].seperator13, 4, 1, f);
  4382. printDebug("LoadTR5", "seperator13 CDCDCDCD = 0x%x",
  4383. mRoomsTR5[i].seperator13);
  4384. if (mRoomsTR5[i].seperator13 != 0xcdcdcdcd)
  4385. {
  4386. print("LoadTR5", "Error #14 CDCDCDCD | 0x0 != 0x%x",
  4387. mRoomsTR5[i].seperator13);
  4388. return -3;
  4389. }
  4390. Fread(&mRoomsTR5[i].seperator14, 4, 1, f);
  4391. printDebug("LoadTR5", "seperator14 CDCDCDCD = 0x%x",
  4392. mRoomsTR5[i].seperator14);
  4393. if (mRoomsTR5[i].seperator14 != 0xcdcdcdcd &&
  4394. mRoomsTR5[i].seperator14 != 0x00000000)
  4395. {
  4396. print("LoadTR5", "Error #15 CDCDCDCD | 0x0 != 0x%x",
  4397. mRoomsTR5[i].seperator14);
  4398. return -3;
  4399. }
  4400. Fread(&mRoomsTR5[i].seperator15, 4, 1, f);
  4401. printDebug("LoadTR5", "seperator15 CDCDCDCD = 0x%x",
  4402. mRoomsTR5[i].seperator15);
  4403. if (mRoomsTR5[i].seperator15 != 0xcdcdcdcd)
  4404. {
  4405. print("LoadTR5", "Error #16 CDCDCDCD != 0x%x",
  4406. mRoomsTR5[i].seperator15);
  4407. return -3;
  4408. }
  4409. // 56byte struct /////////////
  4410. printDebug("LoadTR5", "56byte struct {");
  4411. Fread(&mRoomsTR5[i].numRoomTriangles, 4, 1, f);
  4412. printDebug("LoadTR5", "num_triangles = %u",
  4413. mRoomsTR5[i].numRoomTriangles);
  4414. Fread(&mRoomsTR5[i].numRoomRectangles, 4, 1, f);
  4415. printDebug("LoadTR5", "num_rectangles = %u",
  4416. mRoomsTR5[i].numRoomRectangles);
  4417. Fread(&mRoomsTR5[i].seperator16, 4, 1, f);
  4418. printDebug("LoadTR5", "seperator16, 0x00? = 0x%x",
  4419. mRoomsTR5[i].seperator16);
  4420. // Num lights * 88bytes
  4421. Fread(&mRoomsTR5[i].lightSize, 4, 1, f);
  4422. printDebug("LoadTR5", "light_size = %u", mRoomsTR5[i].lightSize);
  4423. Fread(&mRoomsTR5[i].numTotalRoomLights, 4, 1, f);
  4424. printDebug("LoadTR5", "num_lights = %u",
  4425. mRoomsTR5[i].numTotalRoomLights);
  4426. Fread(&mRoomsTR5[i].unknownR7, 4, 1, f); // was num_unknown_36byte structs to read
  4427. printDebug("LoadTR5", "unknownR7 structs = %u", mRoomsTR5[i].unknownR7);
  4428. Fread(&mRoomsTR5[i].unknownR8, 4, 1, f);
  4429. printDebug("LoadTR5", "unknownR8 = 0x%x", mRoomsTR5[i].unknownR8);
  4430. Fread(&mRoomsTR5[i].yBottom, 4, 1, f);
  4431. printDebug("LoadTR5", "lyBottom = 0x%x", mRoomsTR5[i].lyBottom);
  4432. Fread(&mRoomsTR5[i].numLayers, 4, 1, f);
  4433. printDebug("LoadTR5", "num_layers = %u", mRoomsTR5[i].numLayers);
  4434. Fread(&mRoomsTR5[i].layerOffset, 4, 1, f);
  4435. printDebug("LoadTR5", "layerOffset = 0x%x", mRoomsTR5[i].layerOffset);
  4436. Fread(&mRoomsTR5[i].verticesOffset, 4, 1, f);
  4437. printDebug("LoadTR5", "verticesOffset = 0x%x", mRoomsTR5[i].verticesOffset);
  4438. Fread(&mRoomsTR5[i].polyOffset, 4, 1, f);
  4439. printDebug("LoadTR5", "polyOffset = 0x%x", mRoomsTR5[i].polyOffset);
  4440. Fread(&mRoomsTR5[i].polyOffset2, 4, 1, f);
  4441. printDebug("LoadTR5", "polyOffset2 = 0x%x", mRoomsTR5[i].polyOffset2);
  4442. Fread(&mRoomsTR5[i].verticesSize, 4, 1, f);
  4443. printDebug("LoadTR5", "verticesSize = 0x%x", mRoomsTR5[i].verticesSize);
  4444. printDebug("LoadTR5", "}");
  4445. //////////////////////////////
  4446. Fread(&mRoomsTR5[i].seperator17, 4, 1, f);
  4447. printDebug("LoadTR5", "seperator17 CDCDCDCD = 0x%x",
  4448. mRoomsTR5[i].seperator17);
  4449. if (mRoomsTR5[i].seperator17 != 0xcdcdcdcd)
  4450. {
  4451. print("LoadTR5", "Error #18 CDCDCDCD != 0x%x",
  4452. mRoomsTR5[i].seperator17);
  4453. return -3;
  4454. }
  4455. Fread(&mRoomsTR5[i].seperator18, 4, 1, f);
  4456. printDebug("LoadTR5", "seperator18 CDCDCDCD = 0x%x",
  4457. mRoomsTR5[i].seperator18);
  4458. if (mRoomsTR5[i].seperator18 != 0xcdcdcdcd)
  4459. {
  4460. print("LoadTR5", "Error #19 CDCDCDCD != 0x%x",
  4461. mRoomsTR5[i].seperator18);
  4462. return -3;
  4463. }
  4464. Fread(&mRoomsTR5[i].seperator19, 4, 1, f);
  4465. printDebug("LoadTR5", "seperator19 CDCDCDCD = 0x%x",
  4466. mRoomsTR5[i].seperator19);
  4467. if (mRoomsTR5[i].seperator19 != 0xcdcdcdcd)
  4468. {
  4469. print("LoadTR5", "Error #20 CDCDCDCD != 0x%x",
  4470. mRoomsTR5[i].seperator19);
  4471. return -3;
  4472. }
  4473. Fread(&mRoomsTR5[i].seperator20, 4, 1, f);
  4474. printDebug("LoadTR5", "seperator20 CDCDCDCD = 0x%x",
  4475. mRoomsTR5[i].seperator20);
  4476. if (mRoomsTR5[i].seperator20 != 0xcdcdcdcd)
  4477. {
  4478. print("LoadTR5", "Error #21 CDCDCDCD != 0x%x",
  4479. mRoomsTR5[i].seperator20);
  4480. return -3;
  4481. }
  4482. // Lights
  4483. printDebug("LoadTR5", "Reading %u lights @ 88bytes each",
  4484. mRoomsTR5[i].numRoomLights);
  4485. if (mRoomsTR5[i].numRoomLights)
  4486. {
  4487. mRoomsTR5[i].lights = new tr5_light_t[mRoomsTR5[i].numRoomLights];
  4488. }
  4489. for (j = 0; j < (int)mRoomsTR5[i].numRoomLights; ++j)
  4490. {
  4491. Fread(&mRoomsTR5[i].lights[j], 88, 1, f);
  4492. //Fread(&mRoomsTR5[i].lights[j].x, 4, 1, f);
  4493. printDebug("LoadTR5", "light[%i].x? = %f", j,
  4494. mRoomsTR5[i].lights[j].x);
  4495. //Fread(&mRoomsTR5[i].lights[j].y, 4, 1, f);
  4496. printDebug("LoadTR5", "light[%i].y? = %f", j,
  4497. mRoomsTR5[i].lights[j].y);
  4498. //Fread(&mRoomsTR5[i].lights[j].z, 4, 1, f);
  4499. printDebug("LoadTR5", "light[%i].z? = %f", j,
  4500. mRoomsTR5[i].lights[j].z);
  4501. //Fread(&mRoomsTR5[i].lights[j].red, 4, 1, f);
  4502. printDebug("LoadTR5", "light[%i].r? = %f",
  4503. j, mRoomsTR5[i].lights[j].red);
  4504. //Fread(&mRoomsTR5[i].lights[j].green, 4, 1, f);
  4505. printDebug("LoadTR5", "light[%i].g? = %f",
  4506. j, mRoomsTR5[i].lights[j].green);
  4507. //Fread(&mRoomsTR5[i].lights[j].blue, 4, 1, f);
  4508. printDebug("LoadTR5", "light[%i].b? = %f",
  4509. j, mRoomsTR5[i].lights[j].blue);
  4510. // 24bytes from start of light
  4511. //Fread(&mRoomsTR5[i].lights[j].seperator, 4, 1, f);
  4512. printDebug("LoadTR5", "CDCDCDCD for some maps? = 0x%8x\t\t[%s]",
  4513. mRoomsTR5[i].lights[j].seperator,
  4514. (mRoomsTR5[i].lights[j].seperator == 0xcdcdcdcd)
  4515. ? "OK" : "ERROR");
  4516. //Fread(&mRoomsTR5[i].lights[j].input, 4, 1, f);
  4517. printDebug("LoadTR5", "light[%i].input = %f",
  4518. j, mRoomsTR5[i].lights[j].input);
  4519. //Fread(&mRoomsTR5[i].lights[j].output, 4, 1, f);
  4520. printDebug("LoadTR5", "light[%i].output = %f",
  4521. j, mRoomsTR5[i].lights[j].output);
  4522. //Fread(&mRoomsTR5[i].lights[j].range, 4, 1, f);
  4523. printDebug("LoadTR5", "light[%i].range = %f",
  4524. j, mRoomsTR5[i].lights[j].range);
  4525. //Fread(&mRoomsTR5[i].lights[j].directionVectorX, 4, 1, f);
  4526. printDebug("LoadTR5", "light[%i].directionVectorX = %f",
  4527. j, mRoomsTR5[i].lights[j].directionVectorX);
  4528. //Fread(&mRoomsTR5[i].lights[j].directionVectorY, 4, 1, f);
  4529. printDebug("LoadTR5", "light[%i].directionVectorY = %f",
  4530. j, mRoomsTR5[i].lights[j].directionVectorY);
  4531. //Fread(&mRoomsTR5[i].lights[j].directionVectorZ, 4, 1, f);
  4532. printDebug("LoadTR5", "light[%i].directionVectorZ = %f",
  4533. j, mRoomsTR5[i].lights[j].directionVectorZ);
  4534. //Fread(&mRoomsTR5[i].lights[j].x2, 4, 1, f);
  4535. printDebug("LoadTR5", "light[%i].x2 = %u",
  4536. j, mRoomsTR5[i].lights[j].x2);
  4537. //Fread(&mRoomsTR5[i].lights[j].y2, 4, 1, f);
  4538. printDebug("LoadTR5", "light[%i].y2 = %u",
  4539. j, mRoomsTR5[i].lights[j].y2);
  4540. //Fread(&mRoomsTR5[i].lights[j].z2, 4, 1, f);
  4541. printDebug("LoadTR5", "light[%i].z2 = %u",
  4542. j, mRoomsTR5[i].lights[j].z2);
  4543. //Fread(&mRoomsTR5[i].lights[j].directionVectorX2, 4, 1, f);
  4544. printDebug("LoadTR5", "light[%i].directionVectorX2 = %u",
  4545. j, mRoomsTR5[i].lights[j].directionVectorX2);
  4546. //Fread(&mRoomsTR5[i].lights[j].directionVectorY2, 4, 1, f);
  4547. printDebug("LoadTR5", "light[%i].directionVectorY2 = %u",
  4548. j, mRoomsTR5[i].lights[j].directionVectorY2);
  4549. //Fread(&mRoomsTR5[i].lights[j].directionVectorZ2, 4, 1, f);
  4550. printDebug("LoadTR5", "light[%i].directionVectorZ2 = %u",
  4551. j, mRoomsTR5[i].lights[j].directionVectorZ2);
  4552. //Fread(&mRoomsTR5[i].lights[j].lightType, 1, 1, f);
  4553. printDebug("LoadTR5", "light[%i].d3d_flag = 0x%x (%s)",
  4554. j, mRoomsTR5[i].lights[j].lightType,
  4555. (mRoomsTR5[i].lights[j].lightType == 1) ? "Point" :
  4556. (mRoomsTR5[i].lights[j].lightType == 2) ? "Spot" :
  4557. (mRoomsTR5[i].lights[j].lightType == 3) ? "Directional" : "Unknown");
  4558. //Fread(&mRoomsTR5[i].lights[j].seperator2, 3, 1, f);
  4559. printDebug("LoadTR5", "CDCDCD = %c%c%c",
  4560. mRoomsTR5[i].lights[j].seperator2[0],
  4561. mRoomsTR5[i].lights[j].seperator2[1],
  4562. mRoomsTR5[i].lights[j].seperator2[2]);
  4563. }
  4564. int numSectors = mRoomsTR5[i].numXSectors * mRoomsTR5[i].numZSectors;
  4565. if (numSectors)
  4566. {
  4567. mRoomsTR5[i].sectors = new tr2_room_sector_t[numSectors];
  4568. }
  4569. // Sectors
  4570. printDebug("LoadTR5", "Reading %u sectors @ 8bytes each",
  4571. numSectors);
  4572. for (j = 0; j < numSectors; ++j)
  4573. {
  4574. Fread(&mRoomsTR5[i].sectors[j].fd_index, 2, 1, f);
  4575. printDebug("LoadTR5", "sector[%i].fd_index = %u", j,
  4576. mRoomsTR5[i].sectors[j].fd_index);
  4577. Fread(&mRoomsTR5[i].sectors[j].box_index, 2, 1, f);
  4578. printDebug("LoadTR5", "sector[%i].box_index = %u", j,
  4579. mRoomsTR5[i].sectors[j].box_index);
  4580. Fread(&mRoomsTR5[i].sectors[j].room_below, 1, 1, f);
  4581. printDebug("LoadTR5", "sector[%i].room_below = %u", j,
  4582. mRoomsTR5[i].sectors[j].room_below);
  4583. Fread(&mRoomsTR5[i].sectors[j].floor, 1, 1, f);
  4584. printDebug("LoadTR5", "sector[%i].floor = %i", j,
  4585. (*(char*)(&mRoomsTR5[i].sectors[j].floor)));
  4586. Fread(&mRoomsTR5[i].sectors[j].room_above, 1, 1, f);
  4587. printDebug("LoadTR5", "sector[%i].room_above = %u", j,
  4588. mRoomsTR5[i].sectors[j].room_above);
  4589. Fread(&mRoomsTR5[i].sectors[j].ceiling, 1, 1, f);
  4590. printDebug("LoadTR5", "sector[%i].ceiling = %i", j,
  4591. (*(char*)(&mRoomsTR5[i].sectors[j].ceiling)));
  4592. }
  4593. portalOffset = (thisRoomOffset + mRoomsTR5[i].startSDOffset + 216 +
  4594. numSectors * 8);
  4595. u = ftell(f);
  4596. if (u != portalOffset)
  4597. {
  4598. printDebug("LoadTR5", "*** Skipping %i bytes to start of portals ***",
  4599. portalOffset - u);
  4600. fseek(f, portalOffset, SEEK_SET);
  4601. }
  4602. // Portals //////////////////////
  4603. Fread(&mRoomsTR5[i].numDoors, 2, 1, f);
  4604. printDebug("LoadTR5", "room[%i].tr5_num_portals = %u",
  4605. i, mRoomsTR5[i].numDoors);
  4606. printDebug("LoadTR5", "Reading %u portals @ 32bytes each",
  4607. mRoomsTR5[i].numDoors);
  4608. if (mRoomsTR5[i].numDoors)
  4609. {
  4610. mRoomsTR5[i].doors = new tr2_room_portal_t[mRoomsTR5[i].numDoors];
  4611. }
  4612. for (j = 0; j < (int)mRoomsTR5[i].numDoors; ++j)
  4613. {
  4614. Fread(&mRoomsTR5[i].doors[j].adjoining_room, 2, 1, f);
  4615. printDebug("LoadTR5", "room[%i].portal[%i].adjoining_room = %u",
  4616. i, j, mRoomsTR5[i].doors[j].adjoining_room);
  4617. Fread(&mRoomsTR5[i].doors[j].normal.x, 2, 1, f);
  4618. Fread(&mRoomsTR5[i].doors[j].normal.y, 2, 1, f);
  4619. Fread(&mRoomsTR5[i].doors[j].normal.z, 2, 1, f);
  4620. printDebug("LoadTR5", "portal[%i].normal = ( %i, %i, %i )", j,
  4621. mRoomsTR5[i].doors[j].normal.x,
  4622. mRoomsTR5[i].doors[j].normal.y,
  4623. mRoomsTR5[i].doors[j].normal.z);
  4624. for (k = 0; k < 4; ++k)
  4625. {
  4626. Fread(&mRoomsTR5[i].doors[j].vertices[k].x, 2, 1, f);
  4627. Fread(&mRoomsTR5[i].doors[j].vertices[k].y, 2, 1, f);
  4628. Fread(&mRoomsTR5[i].doors[j].vertices[k].z, 2, 1, f);
  4629. printDebug("LoadTR5", "portal[%i].vertices[%i] = ( %i, %i, %i )",
  4630. j, k,
  4631. mRoomsTR5[i].doors[j].vertices[k].x,
  4632. mRoomsTR5[i].doors[j].vertices[k].y,
  4633. mRoomsTR5[i].doors[j].vertices[k].z);
  4634. }
  4635. }
  4636. Fread(&mRoomsTR5[i].seperator21, 2, 1, f);
  4637. printDebug("LoadTR5", "seperator21, CDCD = 0x%x",
  4638. mRoomsTR5[i].seperator21);
  4639. if (mRoomsTR5[i].seperator21 != 0xcdcd)
  4640. {
  4641. print("LoadTR5", "Error #22 CDCD != 0x%x",
  4642. mRoomsTR5[i].seperator21);
  4643. return -3;
  4644. }
  4645. portalOffset = (thisRoomOffset + mRoomsTR5[i].endPortalOffset + 216);
  4646. u = ftell(f);
  4647. if (u != portalOffset)
  4648. {
  4649. printDebug("LoadTR5", "*** Skipping %i bytes to end of portals ***",
  4650. portalOffset - u);
  4651. fseek(f, portalOffset, SEEK_SET);
  4652. }
  4653. if (mRoomsTR5[i].numStaticMeshes)
  4654. {
  4655. mRoomsTR5[i].meshes = new tr2_room_staticmesh_t[mRoomsTR5[i].numStaticMeshes];
  4656. }
  4657. // Static meshes
  4658. for (j = 0; j < (int)mRoomsTR5[i].numStaticMeshes; ++j)
  4659. {
  4660. Fread(&mRoomsTR5[i].meshes[j].x, 4, 1, f);
  4661. printDebug("LoadTR5", "static_mesh[%i].x = %i", j,
  4662. mRoomsTR5[i].meshes[j].x);
  4663. Fread(&mRoomsTR5[i].meshes[j].y, 4, 1, f);
  4664. printDebug("LoadTR5", "static_mesh[%i].y = %i", j,
  4665. mRoomsTR5[i].meshes[j].y);
  4666. Fread(&mRoomsTR5[i].meshes[j].z, 4, 1, f);
  4667. printDebug("LoadTR5", "static_mesh[%i].z = %i", j,
  4668. mRoomsTR5[i].meshes[j].z);
  4669. Fread(&mRoomsTR5[i].meshes[j].rotation, 2, 1, f);
  4670. printDebug("LoadTR5", "static_mesh[%i].rotation = %i", j,
  4671. mRoomsTR5[i].meshes[j].rotation);
  4672. Fread(&mRoomsTR5[i].meshes[j].intensity1, 2, 1, f);
  4673. printDebug("LoadTR5", "static_mesh[%i].intensity1 = %i", j,
  4674. mRoomsTR5[i].meshes[j].intensity1);
  4675. Fread(&mRoomsTR5[i].meshes[j].intensity2, 2, 1, f);
  4676. printDebug("LoadTR5", "static_mesh[%i].intensity2 = %i", j,
  4677. mRoomsTR5[i].meshes[j].intensity2);
  4678. Fread(&mRoomsTR5[i].meshes[j].object_id, 2, 1, f);
  4679. printDebug("LoadTR5", "static_mesh[%i].object_id = %i", j,
  4680. mRoomsTR5[i].meshes[j].object_id);
  4681. }
  4682. // Layers /////////////////
  4683. if (mRoomsTR5[i].numLayers)
  4684. {
  4685. mRoomsTR5[i].layers = new tr5_room_layer_t[mRoomsTR5[i].numLayers];
  4686. }
  4687. printDebug("LoadTR5", "Reading %i layers",
  4688. mRoomsTR5[i].numLayers);
  4689. for (j = 0; j < (int)mRoomsTR5[i].numLayers; ++j)
  4690. {
  4691. Fread(&mRoomsTR5[i].layers[j], 56, 1, f);
  4692. printDebug("LoadTR5", "layer[%i].num_vertices = %i", j,
  4693. mRoomsTR5[i].layers[j].numLayerVertices);
  4694. printDebug("LoadTR5", "layer[%i].unknown1 = %i", j,
  4695. mRoomsTR5[i].layers[j].unknownL1);
  4696. printDebug("LoadTR5", "layer[%i].num_rectangles = %i", j,
  4697. mRoomsTR5[i].layers[j].numLayerRectangles);
  4698. printDebug("LoadTR5", "layer[%i].num_triangles = %i", j,
  4699. mRoomsTR5[i].layers[j].numLayerTriangles);
  4700. printDebug("LoadTR5", "layer[%i].num_2side_textures? = %i", j,
  4701. mRoomsTR5[i].layers[j].unknownL2);
  4702. printDebug("LoadTR5", "layer[%i].filler, 0? = %i", j,
  4703. mRoomsTR5[i].layers[j].filler);
  4704. printDebug("LoadTR5", "layer[%i].filler2, 0? = %i", j,
  4705. mRoomsTR5[i].layers[j].filler2);
  4706. printDebug("LoadTR5", "layer[%i].bbox[0] = {%.2f %.2f %.2f}", j,
  4707. mRoomsTR5[i].layers[j].layerBoundingBoxX1,
  4708. mRoomsTR5[i].layers[j].layerBoundingBoxX1,
  4709. mRoomsTR5[i].layers[j].layerBoundingBoxX1);
  4710. printDebug("LoadTR5", "layer[%i].bbox[1] = {%.2f %.2f %.2f}", j,
  4711. mRoomsTR5[i].layers[j].layerBoundingBoxX2,
  4712. mRoomsTR5[i].layers[j].layerBoundingBoxX2,
  4713. mRoomsTR5[i].layers[j].layerBoundingBoxX2);
  4714. printDebug("LoadTR5", "layer[%i].filler3, 0? = %i", j,
  4715. mRoomsTR5[i].layers[j].filler3);
  4716. printDebug("LoadTR5", "layer[%i].unknown6 = %i", j,
  4717. mRoomsTR5[i].layers[j].unknownL6);
  4718. printDebug("LoadTR5", "layer[%i].unknown7 = %i", j,
  4719. mRoomsTR5[i].layers[j].unknownL7);
  4720. printDebug("LoadTR5", "layer[%i].unknown8 = %i", j,
  4721. mRoomsTR5[i].layers[j].unknownL8);
  4722. }
  4723. if (mRoomsTR5[i].numLayers)
  4724. {
  4725. mRoomsTR5[i].faces = new tr5_room_geometry_t[mRoomsTR5[i].numLayers];
  4726. }
  4727. for (j = 0; j < (int)mRoomsTR5[i].numLayers; ++j)
  4728. {
  4729. mRoomsTR5[i].faces[j].quads = 0x0;
  4730. mRoomsTR5[i].faces[j].tris = 0x0;
  4731. k = mRoomsTR5[i].layers[j].numLayerRectangles;
  4732. if (k)
  4733. {
  4734. printDebug("LoadTR5", "Reading %i layer quads", k);
  4735. mRoomsTR5[i].faces[j].quads = new tr5_face4_t[k];
  4736. Fread(mRoomsTR5[i].faces[j].quads, 12, k, f);
  4737. }
  4738. k = mRoomsTR5[i].layers[j].numLayerTriangles;
  4739. if (k)
  4740. {
  4741. printDebug("LoadTR5", "Reading %i layer tris", k);
  4742. mRoomsTR5[i].faces[j].tris = new tr5_face3_t[k];
  4743. Fread(mRoomsTR5[i].faces[j].tris, 10, k, f);
  4744. }
  4745. }
  4746. for (j = 0; j < (int)mRoomsTR5[i].numLayers; ++j)
  4747. {
  4748. mRoomsTR5[i].faces[j].verts = 0x0;
  4749. k = mRoomsTR5[i].layers[j].numLayerVertices;
  4750. if (k)
  4751. {
  4752. printDebug("LoadTR5", "Reading %i layer vertices", k);
  4753. mRoomsTR5[i].faces[j].verts = new tr5_vertex_t[k];
  4754. Fread(mRoomsTR5[i].faces[j].verts, 28, k, f);
  4755. }
  4756. }
  4757. #define TR5_SKIP_TO_ROOMS
  4758. #ifdef TR5_SKIP_TO_ROOMS
  4759. unsigned int hack = ftell(f);
  4760. if (hack < nextRoomOffset)
  4761. {
  4762. printDebug("LoadTR5", "Skipping %i bytes at end of room[%i]",
  4763. nextRoomOffset - hack, i);
  4764. fseek(f, nextRoomOffset, SEEK_SET);
  4765. }
  4766. #else
  4767. long hack = 0;
  4768. // This peels padding off the end of TRCs like ANDREA1.TRC
  4769. while (hack != 0xcdcd)
  4770. {
  4771. Fread(&hack, 2, 1, f);
  4772. printDebug("LoadTR5", "hack[%i] = 0x%x", i, hack);
  4773. }
  4774. #endif
  4775. }
  4776. Fread(&_num_floor_data, 4, 1, f);
  4777. printDebug("LoadTR5", "_num_floor_data = %u", _num_floor_data);
  4778. printDebug("LoadTR5", "Reading %u floorData elements", _num_floor_data);
  4779. _floor_data = new unsigned short[_num_floor_data];
  4780. Fread(_floor_data, 2, _num_floor_data, f);
  4781. // Number of 16bits of mesh data to follow
  4782. Fread(&numMeshData, 4, 1, f);
  4783. printDebug("LoadTR5", "numMeshData = %u", numMeshData);
  4784. meshData = new unsigned char[2*numMeshData];
  4785. Fread(meshData, 2, numMeshData, f);
  4786. // Use pointers array to index in meshData array for tr5_mesh_t's
  4787. Fread(&numMeshPointers, 4, 1, f);
  4788. printDebug("LoadTR5", "numMeshPointers = %u", numMeshPointers);
  4789. meshPointers = new u_int32_t[numMeshPointers];
  4790. Fread(meshPointers, 4, numMeshPointers, f);
  4791. Fread(&numAnimationsTR5, 4, 1, f);
  4792. printDebug("LoadTR5", "numAnimationsTR5 = %u", numAnimationsTR5);
  4793. animationsTR5 = new tr5_animation_t[numAnimationsTR5];
  4794. Fread(animationsTR5, 40, numAnimationsTR5, f);
  4795. Fread(&u, 4, 1, f);
  4796. _num_state_changes = u;
  4797. printDebug("LoadTR5", "_num_state_changes = %u", _num_state_changes);
  4798. _state_changes = new tr2_state_change_t[_num_state_changes];
  4799. Fread(_state_changes, 6, _num_state_changes, f);
  4800. Fread(&u, 4, 1, f);
  4801. _num_anim_dispatches = u;
  4802. printDebug("LoadTR5", "_num_anim_dispatches = %u", _num_anim_dispatches);
  4803. _anim_dispatches = new tr2_anim_dispatch_t[_num_anim_dispatches];
  4804. Fread(_anim_dispatches, 8, _num_anim_dispatches, f);
  4805. Fread(&u, 4, 1, f);
  4806. _num_anim_commands = u;
  4807. printDebug("LoadTR5", "_num_anim_commands = %u", _num_anim_commands);
  4808. _anim_commands = new tr2_anim_command_t[_num_anim_commands];
  4809. Fread(_anim_commands, 2, _num_anim_commands, f);
  4810. Fread(&u, 4, 1, f);
  4811. _num_mesh_trees = u;
  4812. printDebug("LoadTR5", "_num_mesh_trees = %u", _num_mesh_trees);
  4813. _mesh_trees = new tr2_meshtree_t[_num_mesh_trees];
  4814. Fread(_mesh_trees, 4, _num_mesh_trees, f);
  4815. Fread(&u, 4, 1, f);
  4816. _num_frames = u;
  4817. printDebug("LoadTR5", "_num_frames = %u", _num_frames);
  4818. _frames = new u_int16_t[_num_frames];
  4819. Fread(_frames, 2, _num_frames, f);
  4820. Fread(&numMoveablesTR5, 4, 1, f);
  4821. printDebug("LoadTR5", "numMoveablesTR5 = %u", numMoveablesTR5);
  4822. moveablesTR5 = new tr5_moveable_t[numMoveablesTR5];
  4823. Fread(moveablesTR5, 20, numMoveablesTR5, f);
  4824. Fread(&u, 4, 1, f);
  4825. _num_static_meshes = u;
  4826. printDebug("LoadTR5", "_num_static_meshes = %u", _num_static_meshes);
  4827. _static_meshes = new tr2_staticmesh_t[_num_static_meshes];
  4828. Fread(_static_meshes, 32, _num_static_meshes, f);
  4829. Fread(check, 4, 1, f);
  4830. printDebug("LoadTR5", "Check: SPR = '%c%c%c'?",
  4831. check[0], check[1], check[2]);
  4832. if (check[0] != 'S' || check[1] != 'P' || check[2] != 'R')
  4833. {
  4834. print("LoadTR5", "Error: SPR != '%c%c%c'", check[0], check[1], check[2]);
  4835. return -4;
  4836. }
  4837. Fread(&u, 4, 1, f);
  4838. _num_sprite_textures = u;
  4839. printDebug("LoadTR5", "_num_sprite_textures = %u", _num_sprite_textures);
  4840. _sprite_textures = new tr2_sprite_texture_t[_num_sprite_textures];
  4841. Fread(_sprite_textures, 16, _num_sprite_textures, f);
  4842. Fread(&u, 4, 1, f);
  4843. _num_sprite_sequences = u;
  4844. printDebug("LoadTR5", "_num_sprite_sequences = %u", _num_sprite_sequences);
  4845. _sprite_sequences = new tr2_sprite_sequence_t[_num_sprite_sequences];
  4846. Fread(_sprite_sequences, 8, _num_sprite_sequences, f);
  4847. Fread(&u, 4, 1, f);
  4848. _num_cameras = u;
  4849. printDebug("LoadTR5", "_num_cameras = %u", _num_cameras);
  4850. if (_num_cameras > 0)
  4851. {
  4852. _cameras = new tr2_camera_t[_num_cameras];
  4853. Fread(_cameras, 16, _num_cameras, f);
  4854. }
  4855. else
  4856. {
  4857. _cameras = 0x0;
  4858. }
  4859. Fread(&numFlyByCamerasTR5, 4, 1, f);
  4860. printDebug("LoadTR5", "numFlyByCameras = %u", numFlyByCamerasTR5);
  4861. if (numFlyByCamerasTR5 > 0)
  4862. {
  4863. flyByCamerasTR5 = new tr5_flyby_camera_t[numFlyByCamerasTR5];
  4864. Fread(flyByCamerasTR5, 40, numFlyByCamerasTR5, f);
  4865. }
  4866. else
  4867. {
  4868. flyByCamerasTR5 = 0x0;
  4869. }
  4870. Fread(&u, 4, 1, f);
  4871. _num_sound_sources = u;
  4872. printDebug("LoadTR5", "_num_sound_sources = %u", _num_sound_sources);
  4873. if (_num_sound_sources > 0)
  4874. {
  4875. _sound_sources = new tr2_sound_source_t[_num_sound_sources];
  4876. Fread(_sound_sources, 16, _num_sound_sources, f);
  4877. }
  4878. else
  4879. {
  4880. _sound_sources = 0x0;
  4881. }
  4882. Fread(&u, 4, 1, f);
  4883. _num_boxes = u;
  4884. printDebug("LoadTR5", "_num_boxes = %u", _num_boxes);
  4885. _boxes = new tr2_box_t[_num_boxes];
  4886. Fread(_boxes, 8, _num_boxes, f);
  4887. Fread(&u, 4, 1, f);
  4888. _num_overlaps = u;
  4889. printDebug("LoadTR5", "_num_overlaps = %u", _num_overlaps);
  4890. _overlaps = new short[_num_overlaps];
  4891. Fread(_overlaps, 2, _num_overlaps, f);
  4892. _zones = new short[_num_boxes*10];
  4893. Fread(_zones, 20, _num_boxes, f);
  4894. Fread(&u, 4, 1, f);
  4895. _num_animated_textures = u;
  4896. printDebug("LoadTR5", "_num_animated_textures = %u", _num_animated_textures);
  4897. _animated_textures = new short[_num_animated_textures];
  4898. Fread(_animated_textures, 2, _num_animated_textures, f);
  4899. Fread(check, 1, 5, f);
  4900. printDebug("LoadTR5", "Check: TEX = '%c%c%c'?",
  4901. check[1], check[2], check[3]);
  4902. // check[0] is '^D'
  4903. if (check[1] != 'T' || check[2] != 'E' || check[3] != 'X')
  4904. {
  4905. print("LoadTR5", "Error: TEX != '%c%c%c' @ %lu",
  4906. check[1], check[2], check[3], ftell(f));
  4907. return -4;
  4908. }
  4909. Fread(&numObjectTexturesTR5, 4, 1, f);
  4910. printDebug("LoadTR5", "numObjectTextures = %u", numObjectTexturesTR5);
  4911. objectTexturesTR5 = new tr5_object_texture_t[numObjectTexturesTR5];
  4912. Fread(objectTexturesTR5, 40, numObjectTexturesTR5, f);
  4913. Fread(&u, 4, 1, f);
  4914. _num_items = u;
  4915. printDebug("LoadTR5", "_num_items = %u", _num_items);
  4916. _items = new tr2_item_t[_num_items];
  4917. Fread(_items, 24, _num_items, f);
  4918. Fread(&numCinematicFramesTR5, 4, 1, f);
  4919. printDebug("LoadTR5", "numCinematicFrames = %u", numCinematicFramesTR5);
  4920. if (numCinematicFramesTR5 > 0)
  4921. {
  4922. cinematicFramesTR5 = new tr5_cinematic_frame_t[numCinematicFramesTR5];
  4923. Fread(cinematicFramesTR5, 24, numCinematicFramesTR5, f);
  4924. }
  4925. else
  4926. {
  4927. cinematicFramesTR5 = 0x0;
  4928. }
  4929. Fread(&us, 2, 1, f);
  4930. _num_demo_data = us; // Could overflow? not sure
  4931. printDebug("LoadTR5", "_num_demo_data = %u", _num_demo_data);
  4932. if (_num_demo_data > 0)
  4933. {
  4934. _demo_data = new unsigned char[_num_demo_data];
  4935. Fread(_demo_data, 1, _num_demo_data, f);
  4936. }
  4937. else
  4938. {
  4939. _demo_data = 0x0;
  4940. }
  4941. printDebug("LoadTR5", "Reading soundMap");
  4942. mSoundMap = new short[450];
  4943. Fread(mSoundMap, 900, 1, f);
  4944. Fread(&u, 4, 1, f);
  4945. mNumSoundDetails = u;
  4946. printDebug("LoadTR5", "numSoundDetails = %u", mNumSoundDetails);
  4947. mSoundDetails = new tr2_sound_details_t[mNumSoundDetails];
  4948. Fread(mSoundDetails, 8, mNumSoundDetails, f);
  4949. Fread(&u, 4, 1, f);
  4950. mNumSampleIndices = u;
  4951. printDebug("LoadTR5", "numSampleIndices = %u", mNumSampleIndices);
  4952. mSampleIndicesTR5 = new unsigned int[mNumSampleIndices];
  4953. Fread(mSampleIndicesTR5, 4, mNumSampleIndices, f);
  4954. Fread(&u, 4, 1, f);
  4955. printDebug("LoadTR5", "Check 0xCDCDCDCD = 0x%X?", u);
  4956. if (u != 0xcdcdcdcd)
  4957. {
  4958. print("LoadTR5", "Check 0xCDCDCDCD != 0x%X @ %ld", u, ftell(f));
  4959. return -5;
  4960. }
  4961. // Skip over the extra short in the demo.trc, but if it's not there
  4962. // seek back
  4963. u = ftell(f);
  4964. Fread(&us, 2, 1, f);
  4965. if (us != 0xcdcd)
  4966. {
  4967. fseek(f, u, SEEK_SET);
  4968. }
  4969. //! \fixme (Endian) Read bitu32 / u_int32_t
  4970. Fread(&mNumTR4Samples, 4, 1, f);
  4971. printDebug("Load", "mNumTR4Samples = %i", mNumTR4Samples);
  4972. mRiffDataSz = 0;
  4973. mTR4Samples = new unsigned char *[mNumTR4Samples];
  4974. mTR4SamplesSz = new unsigned int[mNumTR4Samples];
  4975. memset(mTR4SamplesSz, 0, mNumTR4Samples*4);
  4976. for (i = 0; i < (int)mNumTR4Samples; ++i)
  4977. {
  4978. unsigned int sizeCompressed;
  4979. unsigned int sizeUncompressed;
  4980. unsigned char *compressedSoundSample;
  4981. unsigned char *unCompressedSoundSample;
  4982. int zErr;
  4983. uLongf libzUncompressedSize;
  4984. Fread(&sizeUncompressed, 4, 1, f);
  4985. printDebug("Load", " sizeUncompressed = %i", sizeUncompressed);
  4986. Fread(&sizeCompressed, 4, 1, f);
  4987. printDebug("Load", " sizeCompressed = %i", sizeCompressed);
  4988. compressedSoundSample = new unsigned char[sizeCompressed];
  4989. unCompressedSoundSample = new unsigned char[sizeUncompressed];
  4990. //printDebug("Load", " %lubytes read from file", ftell(f));
  4991. Fread(compressedSoundSample, sizeCompressed, 1, f);
  4992. printDebug("Load", " %c%c%c%c should be RIFF",
  4993. compressedSoundSample[0],
  4994. compressedSoundSample[1],
  4995. compressedSoundSample[2],
  4996. compressedSoundSample[3]);
  4997. // Decompress the sample
  4998. libzUncompressedSize = sizeUncompressed;
  4999. zErr = uncompress(unCompressedSoundSample,
  5000. &libzUncompressedSize,
  5001. compressedSoundSample,
  5002. sizeCompressed);
  5003. sizeUncompressed = libzUncompressedSize;
  5004. switch (zErr)
  5005. {
  5006. case Z_MEM_ERROR:
  5007. printDebug("Load", " Decompress Error: not enough memory");
  5008. break;
  5009. case Z_BUF_ERROR:
  5010. printDebug("Load", " Decompress Error: output buffer too small");
  5011. break;
  5012. case Z_DATA_ERROR:
  5013. printDebug("Load", " Decompress Error: input data was corrupted");
  5014. break;
  5015. case Z_OK:
  5016. printDebug("Load", " Decompress OK");
  5017. break;
  5018. default:
  5019. printDebug("Load", " Decompress Error: decompress error #%i", zErr);
  5020. }
  5021. // Hhhmm... handle uncompressed RIFFs too?
  5022. if (zErr == Z_OK)
  5023. {
  5024. mTR4Samples[i] = unCompressedSoundSample;
  5025. mTR4SamplesSz[i] = sizeUncompressed;
  5026. delete [] compressedSoundSample;
  5027. }
  5028. else
  5029. {
  5030. printDebug("Load", " %lubytes read from file", ftell(f));
  5031. mTR4Samples[i] = compressedSoundSample;
  5032. mTR4SamplesSz[i] = sizeCompressed;
  5033. delete [] unCompressedSoundSample;
  5034. }
  5035. }
  5036. fclose(f);
  5037. return 0;
  5038. }
  5039. void TombRaider::print(const char *methodName, const char *s, ...)
  5040. {
  5041. va_list args;
  5042. va_start(args, s);
  5043. fprintf(stderr, "TombRaider::%s> ", methodName);
  5044. vfprintf(stderr, s, args);
  5045. fprintf(stderr, "\n");
  5046. va_end(args);
  5047. }
  5048. void TombRaider::printDebug(const char *methodName, const char *s, ...)
  5049. {
  5050. va_list args;
  5051. if (!mDebug)
  5052. return;
  5053. va_start(args, s);
  5054. fprintf(stdout, "TombRaider::%s> ", methodName);
  5055. vfprintf(stdout, s, args);
  5056. fprintf(stdout, "\n");
  5057. va_end(args);
  5058. }
  5059. ////////////////////////////////////////////////////////////
  5060. // Private Mutators
  5061. ////////////////////////////////////////////////////////////