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.

OpenRaider.cpp 76KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596
  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: This is the main class for OpenRaider
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2001.05.21:
  19. * Mongoose - Created
  20. =================================================================*/
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdio.h>
  24. #include <stdarg.h>
  25. #include <unistd.h>
  26. #include <math.h>
  27. #include <sys/types.h>
  28. #ifdef DEBUG_MEMEORY
  29. # include "memeory_test.h"
  30. #endif
  31. #ifdef USING_MD3
  32. # include "Md3AnimModel.h"
  33. Md3AnimModel gMd3;
  34. #endif
  35. #include "World.h"
  36. #include "SkeletalModel.h"
  37. #include "TombRaider1.h" // tmp stop-gap
  38. #include "OpenRaider.h"
  39. enum OpenRaiderText { textConsole = 2, textMenu = 3, textOutput = 4 };
  40. const unsigned int TextureLimit = 24;
  41. const float TexelScale = 256.0f;
  42. World gWorld;
  43. Map<int, int> gMapTex2Bump;
  44. Vector <unsigned int> gColorTextureHACK;
  45. int gTextureOffset;
  46. entity_t *LARA = 0x0;
  47. entity_t *gClientPlayer[32];
  48. unsigned int gNetTicks = 0;
  49. unsigned int gNetLastTicks = 0;
  50. bool gStartServer = false;
  51. skeletal_model_t *gLaraModel = 0x0;
  52. char *gFontFilename = 0x0;
  53. unsigned int getTicks()
  54. {
  55. OpenRaider *game = OpenRaider::Instance();
  56. return game->getTicks();
  57. }
  58. ////////////////////////////////////////////////////////////
  59. // Constructors
  60. ////////////////////////////////////////////////////////////
  61. OpenRaider *OpenRaider::mInstance = 0x0;
  62. OpenRaider *OpenRaider::Instance()
  63. {
  64. if (mInstance == 0x0)
  65. {
  66. mInstance = new OpenRaider();
  67. }
  68. return mInstance;
  69. }
  70. void killOpenRaiderSingleton()
  71. {
  72. killNetworkSingleton();
  73. printf("Shutting down Game...\n");
  74. // Requires public deconstructor
  75. // Causes pointer-being-freed-not-allocated error!
  76. //delete OpenRaider::Instance();
  77. #warning "Can't delete OpenRaider::Instance() without a not-allocated-free error. Something is fishy here..."
  78. #ifdef DEBUG_MEMEORY
  79. printf("\n[Mongoose MEMEORY_DEBUG]\nMemory leak table:\n");
  80. dump_memory_report();
  81. #endif
  82. printf("\nThanks for testing %s\n", VERSION);
  83. printf("Please file bug reports\n\n");
  84. printf("Build date: %s @ %s\n", __DATE__, __TIME__);
  85. printf("Build host: %s\n", BUILD_HOST);
  86. printf("Web site : http://github.com/xythobuz/OpenRaider\n");
  87. }
  88. OpenRaider::OpenRaider() : SDLSystem()
  89. {
  90. Network::Instance();
  91. for (unsigned int i = 0; i < 32; ++i)
  92. {
  93. gClientPlayer[i] = 0x0;
  94. }
  95. m_pakDir = 0x0;
  96. m_audioDir = 0x0;
  97. m_homeDir = 0x0;
  98. m_mouseX = 2.5;
  99. m_mouseY = 0.5;
  100. m_texOffset = 0;
  101. mLevelTextureOffset = 0;
  102. m_testSFX = -1;
  103. mNoClipping = 0;
  104. // TODO, Replace numbers with enum modes
  105. // Only do this when you know the amount of commands + 1 ( 0 reserved )
  106. mMode[addCommandMode("[OpenRaider.Engine]")] = 2;
  107. mMode[addCommandMode("[Network.Server]")] = 5;
  108. mMode[addCommandMode("[Video.OpenGL]")] = 0;
  109. mMode[addCommandMode("[Audio.OpenAL]")] = 1;
  110. mMode[addCommandMode("[OpenRaider.Console]")] = 4;
  111. mMode[addCommandMode("[Input.Mouse]")] = 3;
  112. }
  113. OpenRaider::~OpenRaider()
  114. {
  115. // Mongoose 2002.01.02, FIXME GL call to critical section,
  116. // needs mutex really
  117. m_render.setMode(Render::modeDisabled);
  118. //sleep(1); // Why should we sleep here? -- xythobuz
  119. printf("Removing World...\n");
  120. gWorld.destroy();
  121. printf("Cleaning up...\n");
  122. for (mMapList.start(); mMapList.forward(); mMapList.next())
  123. {
  124. if (mMapList.current())
  125. {
  126. delete [] mMapList.current();
  127. }
  128. }
  129. for (mMusicList.start(); mMusicList.forward(); mMusicList.next())
  130. {
  131. if (mMusicList.current())
  132. {
  133. delete [] mMusicList.current();
  134. }
  135. }
  136. if (m_pakDir)
  137. delete [] m_pakDir;
  138. if (m_audioDir)
  139. delete [] m_audioDir;
  140. if (m_homeDir)
  141. delete [] m_homeDir;
  142. if (gFontFilename)
  143. delete [] gFontFilename;
  144. }
  145. ////////////////////////////////////////////////////////////
  146. // Public Accessors
  147. ////////////////////////////////////////////////////////////
  148. ////////////////////////////////////////////////////////////
  149. // Public Mutators
  150. ////////////////////////////////////////////////////////////
  151. void eventAnimTest(int anim)
  152. {
  153. #ifdef USING_MD3
  154. switch (anim)
  155. {
  156. case TR_ANIAMTION_TURN_R:
  157. case TR_ANIAMTION_TURN_L:
  158. //gMd3.setAnimLower(LEGS_TURN);
  159. break;
  160. case TR_ANIAMTION_RUN:
  161. gMd3.setAnimLower(LEGS_RUN);
  162. break;
  163. default:
  164. gMd3.setAnimLower(LEGS_IDLE);
  165. }
  166. #endif
  167. if (LARA)
  168. {
  169. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  170. if (mdl)
  171. {
  172. mdl->setAnimation(anim);
  173. }
  174. }
  175. }
  176. void percent_callback(int p)
  177. {
  178. OpenRaider &game = *OpenRaider::Instance();
  179. switch (p)
  180. {
  181. case 10:
  182. game.print(true, "Level textures loaded");
  183. break;
  184. default:
  185. // %% has problems with OpenRaider::print it seems
  186. game.print(false, "Level pak %i/100 loaded", p);
  187. }
  188. }
  189. void openraider_warning(const char *func_name, const char *warning,
  190. const char *filename, int line)
  191. {
  192. printf("%s> WARNING %s %s:%i\n", func_name, warning, filename, line);
  193. }
  194. void openraider_error(const char *func_name, const char *error,
  195. const char *filename, int line)
  196. {
  197. printf("%s> ERROR %s %s:%i\n", func_name, error, filename, line);
  198. }
  199. void from_network_layer(network_packet_t *p, unsigned int *last_id)
  200. {
  201. static unsigned int i = 0;
  202. *last_id = i++;
  203. if (gNetTicks > gNetLastTicks + 200) // 200ms
  204. {
  205. gNetLastTicks = gNetTicks;
  206. p->send = 1;
  207. }
  208. if (LARA)
  209. {
  210. p->pos[0] = LARA->pos[0];
  211. p->pos[1] = LARA->pos[1];
  212. p->pos[2] = LARA->pos[2];
  213. p->yaw = LARA->angles[1];
  214. p->pitch = LARA->angles[1];
  215. p->view_model = LARA->modelId;
  216. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  217. if (mdl)
  218. {
  219. p->aframe = mdl->getAnimation();
  220. p->bframe = mdl->getFrame();
  221. }
  222. }
  223. #ifdef DEBUG_NETWORK
  224. printf("<> Sending data\n");
  225. #endif
  226. }
  227. void to_network_layer(network_packet_t p)
  228. {
  229. OpenRaider &game = *OpenRaider::Instance();
  230. #ifdef DEBUG_NETWORK
  231. printf("<> Recieved data\n");
  232. #endif
  233. if (gClientPlayer[p.cid])
  234. {
  235. gClientPlayer[p.cid]->pos[0] = p.pos[0];
  236. gClientPlayer[p.cid]->pos[1] = p.pos[1];
  237. gClientPlayer[p.cid]->pos[2] = p.pos[2];
  238. gClientPlayer[p.cid]->angles[1] = p.yaw;
  239. gClientPlayer[p.cid]->angles[2] = p.pitch;
  240. }
  241. else if (LARA)
  242. {
  243. gClientPlayer[p.cid] = new entity_t;
  244. gClientPlayer[p.cid]->pos[0] = p.pos[0];
  245. gClientPlayer[p.cid]->pos[1] = p.pos[1];
  246. gClientPlayer[p.cid]->pos[2] = p.pos[2];
  247. gClientPlayer[p.cid]->angles[1] = p.yaw;
  248. gClientPlayer[p.cid]->angles[2] = p.pitch;
  249. gClientPlayer[p.cid]->moving = true;
  250. gClientPlayer[p.cid]->objectId = 0;
  251. gClientPlayer[p.cid]->id = LARA->id+1000+p.cid;
  252. gClientPlayer[p.cid]->type = 0x02;
  253. SkeletalModel *mdl = new SkeletalModel();
  254. gClientPlayer[p.cid]->tmpHook = mdl;
  255. mdl->setAnimation(p.aframe);
  256. mdl->setFrame(p.bframe);
  257. mdl->setIdleAnimation(TR_ANIAMTION_STAND);
  258. gClientPlayer[p.cid]->modelId = LARA->modelId; //p.view_model;
  259. gClientPlayer[p.cid]->animate = true;
  260. gWorld.addEntity(gClientPlayer[p.cid]);
  261. game.print(true, "A new player (%u) connected", p.cid);
  262. }
  263. if (LARA)
  264. {
  265. Network &network = *Network::Instance();
  266. network_frame_t &gPiggyBack = network.getPiggyBack();
  267. if (gNetTicks > gNetLastTicks + 200)
  268. {
  269. gNetLastTicks = gNetTicks;
  270. gPiggyBack.data.send = 1;
  271. }
  272. gPiggyBack.data.pos[0] = LARA->pos[0];
  273. gPiggyBack.data.pos[1] = LARA->pos[1];
  274. gPiggyBack.data.pos[2] = LARA->pos[2];
  275. gPiggyBack.data.yaw = LARA->angles[1];
  276. gPiggyBack.data.pitch = LARA->angles[2];
  277. gPiggyBack.data.view_model = LARA->modelId;
  278. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  279. if (mdl)
  280. {
  281. gPiggyBack.data.aframe = mdl->getAnimation();
  282. gPiggyBack.data.bframe = mdl->getFrame();
  283. }
  284. }
  285. }
  286. void OpenRaider::handleMouseMotionEvent(float x, float y)
  287. {
  288. if (x > 0)
  289. {
  290. m_camera.command(CAMERA_ROTATE_RIGHT);
  291. if (LARA)
  292. {
  293. switch (LARA->moveType)
  294. {
  295. case worldMoveType_swim:
  296. case worldMoveType_fly:
  297. case worldMoveType_noClipping:
  298. eventAnimTest(TR_ANIAMTION_SWIM_R);
  299. break;
  300. default:
  301. eventAnimTest(TR_ANIAMTION_TURN_L); // TURN left always for now
  302. }
  303. LARA->moving = true;
  304. }
  305. }
  306. else if (x < 0)
  307. {
  308. m_camera.command(CAMERA_ROTATE_LEFT);
  309. if (LARA)
  310. {
  311. switch (LARA->moveType)
  312. {
  313. case worldMoveType_swim:
  314. case worldMoveType_fly:
  315. case worldMoveType_noClipping:
  316. eventAnimTest(TR_ANIAMTION_SWIM_L);
  317. break;
  318. default:
  319. eventAnimTest(TR_ANIAMTION_TURN_L);
  320. }
  321. LARA->moving = true;
  322. }
  323. }
  324. if (y > 0)
  325. m_camera.command(CAMERA_ROTATE_UP);
  326. else if (y < 0)
  327. m_camera.command(CAMERA_ROTATE_DOWN);
  328. if (LARA)
  329. {
  330. LARA->angles[1] = m_camera.getRadianYaw();
  331. LARA->angles[2] = m_camera.getRadianPitch();
  332. }
  333. }
  334. void OpenRaider::handleKeyReleaseEvent(unsigned int key, unsigned int mod)
  335. {
  336. }
  337. void OpenRaider::handleBoundKeyPressEvent(unsigned int key)
  338. {
  339. switch (key)
  340. {
  341. case OpenRaiderKey_jump:
  342. m_camera.command(CAMERA_MOVE_UP);
  343. if (LARA)
  344. {
  345. LARA->moving = true;
  346. }
  347. break;
  348. case OpenRaiderKey_crouch:
  349. m_camera.command(CAMERA_MOVE_DOWN);
  350. if (LARA)
  351. {
  352. LARA->moving = true;
  353. }
  354. break;
  355. case OpenRaiderKey_forward:
  356. gWorld.moveEntity(LARA, 'f');
  357. if (LARA && LARA->moving)
  358. {
  359. switch (LARA->moveType)
  360. {
  361. case worldMoveType_swim:
  362. case worldMoveType_fly:
  363. case worldMoveType_noClipping:
  364. eventAnimTest(TR_ANIAMTION_SWIM);
  365. break;
  366. default:
  367. eventAnimTest(TR_ANIAMTION_RUN);
  368. }
  369. }
  370. else if (LARA)
  371. {
  372. switch (LARA->moveType)
  373. {
  374. case worldMoveType_swim:
  375. case worldMoveType_fly:
  376. case worldMoveType_noClipping:
  377. eventAnimTest(TR_ANIAMTION_SWIM_IDLE);
  378. break;
  379. default:
  380. eventAnimTest(TR_ANIAMTION_HIT_WALL_FRONT);
  381. }
  382. }
  383. else
  384. {
  385. m_camera.command(CAMERA_MOVE_FORWARD);
  386. }
  387. break;
  388. case OpenRaiderKey_backward:
  389. gWorld.moveEntity(LARA, 'b');
  390. if (LARA && LARA->moving)
  391. {
  392. switch (LARA->moveType)
  393. {
  394. case worldMoveType_swim:
  395. case worldMoveType_fly:
  396. case worldMoveType_noClipping:
  397. eventAnimTest(TR_ANIAMTION_SWIM);
  398. break;
  399. default:
  400. eventAnimTest(TR_ANIAMTION_RUN);
  401. }
  402. }
  403. break;
  404. case OpenRaiderKey_left:
  405. gWorld.moveEntity(LARA, 'l');
  406. if (LARA && LARA->moving)
  407. {
  408. switch (LARA->moveType)
  409. {
  410. case worldMoveType_swim:
  411. case worldMoveType_fly:
  412. case worldMoveType_noClipping:
  413. eventAnimTest(TR_ANIAMTION_SWIM);
  414. break;
  415. default:
  416. eventAnimTest(TR_ANIAMTION_RUN);
  417. }
  418. }
  419. else if (!LARA)
  420. {
  421. m_camera.command(CAMERA_MOVE_LEFT);
  422. }
  423. break;
  424. case OpenRaiderKey_right:
  425. gWorld.moveEntity(LARA, 'r');
  426. if (LARA && LARA->moving)
  427. {
  428. switch (LARA->moveType)
  429. {
  430. case worldMoveType_swim:
  431. case worldMoveType_fly:
  432. case worldMoveType_noClipping:
  433. eventAnimTest(TR_ANIAMTION_SWIM);
  434. break;
  435. default:
  436. eventAnimTest(TR_ANIAMTION_RUN);
  437. }
  438. }
  439. else if (!LARA)
  440. {
  441. m_camera.command(CAMERA_MOVE_RIGHT);
  442. }
  443. break;
  444. case OpenRaiderKey_panRight:
  445. m_camera.command(CAMERA_ROTATE_RIGHT);
  446. break;
  447. case OpenRaiderKey_panLeft:
  448. m_camera.command(CAMERA_ROTATE_LEFT);
  449. break;
  450. case OpenRaiderKey_tiltDown:
  451. m_camera.command(CAMERA_ROTATE_DOWN);
  452. break;
  453. case OpenRaiderKey_tiltUp:
  454. m_camera.command(CAMERA_ROTATE_UP);
  455. break;
  456. }
  457. }
  458. void OpenRaider::handleBoundKeyReleaseEvent(unsigned int key)
  459. {
  460. switch (key)
  461. {
  462. case '`': // Temp hack also until console is rolled back
  463. //i = 2;
  464. if (mConsoleMode)
  465. {
  466. //buffer[0] = '>';
  467. //buffer[1] = ' ';
  468. //buffer[2] = 0;
  469. mText->setActive(textConsole, true);
  470. }
  471. else
  472. {
  473. mText->setActive(textConsole, false);
  474. //buffer[0] = 0;
  475. }
  476. break;
  477. case OpenRaiderKey_forward:
  478. case OpenRaiderKey_backward:
  479. case OpenRaiderKey_right:
  480. case OpenRaiderKey_left:
  481. if (LARA)
  482. {
  483. LARA->moving = false;
  484. }
  485. }
  486. }
  487. void OpenRaider::handleConsoleKeyPressEvent(unsigned int key,unsigned int mod)
  488. {
  489. static char lastCmd[64] = "2 ";
  490. static unsigned int i = 0;
  491. char *buffer;
  492. unsigned int len;
  493. // Cheap console test
  494. len = mText->GetStringLen(textConsole);
  495. buffer = mText->GetBuffer(textConsole);
  496. //printf("- 0x%x\n", key);
  497. if (key == mConsoleKey)
  498. {
  499. i = 2;
  500. if (mConsoleMode)
  501. {
  502. buffer[0] = '>';
  503. buffer[1] = ' ';
  504. buffer[2] = 0;
  505. mText->setActive(textConsole, true);
  506. }
  507. else
  508. {
  509. mText->setActive(textConsole, false);
  510. buffer[0] = 0;
  511. }
  512. }
  513. else if (mConsoleMode && len > i+1)
  514. {
  515. switch (key)
  516. {
  517. case SYS_KEY_UP:
  518. i = lastCmd[0];
  519. lastCmd[0] = '>';
  520. mText->SetString(textConsole, lastCmd);
  521. break;
  522. case 0:
  523. break;
  524. case '\b':
  525. if (i > 2)
  526. {
  527. buffer[--i] = 0;
  528. }
  529. break;
  530. case '\r':
  531. case '\n':
  532. strncpy(lastCmd, buffer, 63);
  533. lastCmd[0] = i;
  534. command("[OpenRaider.Console]");
  535. command(buffer);
  536. i = 2;
  537. buffer[0] = '>';
  538. buffer[1] = ' ';
  539. buffer[2] = 0;
  540. break;
  541. default:
  542. if (mod & (SYS_MOD_KEY_RSHIFT | SYS_MOD_KEY_LSHIFT) &&
  543. key > 96 && key < 122)
  544. {
  545. buffer[i++] = (key - 32);
  546. }
  547. else
  548. {
  549. if (mod & (SYS_MOD_KEY_RSHIFT | SYS_MOD_KEY_LSHIFT))
  550. {
  551. if (key == '-')
  552. key = '_';
  553. }
  554. buffer[i++] = key;
  555. }
  556. buffer[i] = 0;
  557. }
  558. }
  559. }
  560. void OpenRaider::handleKeyPressEvent(unsigned int key, unsigned int mod)
  561. {
  562. static bool menu = false;
  563. // Cheap menu test
  564. if (menu)
  565. {
  566. switch (key)
  567. {
  568. case SYS_KEY_ESC:
  569. menu = false;
  570. mText->SetString(textMenu, " ");
  571. mText->setActive(textMenu, false);
  572. break;
  573. case SYS_KEY_ENTER:
  574. loadLevel(mMapList.current());
  575. mText->SetString(textMenu, " ");
  576. mText->setActive(textMenu, false);
  577. menu = false;
  578. break;
  579. case SYS_KEY_DOWN:
  580. mMapList.prev();
  581. if (!mMapList.backward())
  582. {
  583. mMapList.finish();
  584. }
  585. if (mMapList.current())
  586. {
  587. mText->SetString(textMenu, "Load %s?", mMapList.current());
  588. }
  589. else
  590. {
  591. mText->SetString(textMenu, "See README for map install");
  592. }
  593. break;
  594. case SYS_KEY_UP:
  595. mMapList.next();
  596. if (!mMapList.forward())
  597. {
  598. mMapList.start();
  599. }
  600. if (mMapList.current())
  601. {
  602. mText->SetString(textMenu, "Load %s?", mMapList.current());
  603. }
  604. else
  605. {
  606. mText->SetString(textMenu, "See README for map install");
  607. }
  608. }
  609. return;
  610. }
  611. switch (key)
  612. {
  613. case SYS_KEY_ESC:
  614. menu = true;
  615. mText->SetString(textMenu, "Select a map UP/DOWN");
  616. mText->setActive(textMenu, true);
  617. break;
  618. case SYS_KEY_ENTER:
  619. if (mod & SYS_MOD_KEY_LALT)
  620. {
  621. toggleFullscreen();
  622. }
  623. break;
  624. }
  625. ////////////////////////////////////////////////////////////
  626. switch (key)
  627. {
  628. case SYS_MOUSE_LEFT:
  629. mSound.play(m_testSFX);
  630. if (LARA)
  631. {
  632. eventAnimTest(15);
  633. }
  634. break;
  635. case '/':
  636. if (LARA)
  637. {
  638. entity_t *e = new entity_t;
  639. e->pos[0] = LARA->pos[0];
  640. e->pos[1] = LARA->pos[1] - 256.0f; // crawling H
  641. e->pos[2] = LARA->pos[2];
  642. e->type = 61;
  643. e->master = LARA->master;
  644. LARA->master = e;
  645. }
  646. break;
  647. case '[':
  648. if (LARA)
  649. {
  650. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  651. if (mdl)
  652. {
  653. mdl->setIdleAnimation(mdl->getIdleAnimation() - 1);
  654. mdl->setAnimation(mdl->getIdleAnimation());
  655. print(false, "AFRAME %i\n", mdl->getIdleAnimation());
  656. }
  657. }
  658. break;
  659. case ']':
  660. if (LARA)
  661. {
  662. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  663. if (mdl)
  664. {
  665. mdl->setIdleAnimation(mdl->getIdleAnimation() + 1);
  666. mdl->setAnimation(mdl->getIdleAnimation());
  667. print(false, "AFRAME %i\n", mdl->getIdleAnimation());
  668. }
  669. }
  670. break;
  671. case 'r':
  672. mSound.play(m_testSFX);
  673. break;
  674. }
  675. }
  676. void OpenRaider::print(bool dump_stdout, const char *format, ...)
  677. {
  678. static char buffer[128];
  679. va_list args;
  680. unsigned int l;
  681. va_start(args, format);
  682. vsnprintf(buffer, 128, format, args);
  683. l = strlen(buffer);
  684. if (!l || !buffer[0])
  685. {
  686. return;
  687. }
  688. // Strip message of an trailing carrage return
  689. if (buffer[l-1] == '\n')
  690. {
  691. buffer[l-1] = 0;
  692. }
  693. // Print to game 'console'
  694. if (mText)
  695. {
  696. mText->SetString(textOutput, buffer);
  697. }
  698. // Print to stdout
  699. if (dump_stdout)
  700. {
  701. fprintf(stdout, "> %s\n", buffer);
  702. }
  703. va_end(args);
  704. // Mongoose 2002.08.14, Currently, you must request
  705. // frame redraws in this mode
  706. if (m_flags & OpenRaider_Loading)
  707. {
  708. gameFrame();
  709. }
  710. }
  711. void OpenRaider::initGL()
  712. {
  713. // Mongoose 2002.08.13, Handled in start() actually
  714. }
  715. void OpenRaider::start()
  716. {
  717. vec3_t up;
  718. char *filename;
  719. printf("\n[Starting %s]\n\n", VERSION);
  720. filename = fullPath("~/.OpenRaider/OpenRaider.init", 0);
  721. if (loadResourceFile(filename) < 0)
  722. {
  723. printf("Could not find ~/.OpenRaider/OpenRaider.init\n");
  724. if (loadResourceFile("OpenRaider.init") < 0)
  725. {
  726. shutdown(-1);
  727. }
  728. printf("Loaded defaults...\n");
  729. }
  730. delete [] filename;
  731. m_camera.reset();
  732. m_camera.setSensitivityX(m_mouseX);
  733. m_camera.setSensitivityY(m_mouseY);
  734. m_camera.setSpeed(512);
  735. up[0] = 0.0;
  736. up[1] = -1.0;
  737. up[2] = 0.0;
  738. m_camera.setUp(up);
  739. if (mMapList.empty())
  740. {
  741. printf("No maps in map list, please edit your OpenRaider.init\n");
  742. shutdown(0);
  743. }
  744. // Mongoose 2002.08.13, System protected members abuse
  745. m_fovY = 40.0f;
  746. m_clipFar = 600000.0f;
  747. m_clipNear = 10.0f;
  748. // Mongoose 2002.08.13, This starts GL context
  749. printf("\n[Starting video subsystem...]\n");
  750. setFastCardPerformance(true);
  751. initVideo(m_width, m_height, false);
  752. // Mongoose 2002.01.02, Disable rendering to avoid GL call conflicts
  753. m_render.setMode(Render::modeDisabled);
  754. m_render.Init(m_width, m_height, m_fastCard);
  755. m_render.initTextures(m_homeDir, &m_texOffset, &mLevelTextureOffset);
  756. m_render.RegisterCamera(&m_camera);
  757. mText = m_render.GetString();
  758. // Mongoose 2002.01.03, Good idea?
  759. m_render.setMode(Render::modeLoadScreen);
  760. // Mongoose 2002.01.02, Load external audio tracks and fx
  761. // General audio init
  762. initSound();
  763. // Old room movement
  764. //gWorld.setFlag(World::fEnableHopping);
  765. resetTicks();
  766. runGame();
  767. }
  768. void OpenRaider::initSound()
  769. {
  770. //char filename[128];
  771. //unsigned int len;
  772. //int id;
  773. if (!(m_flags & OpenRaider_EnableSound) || mSound.init() < 0)
  774. {
  775. print(true, "Disabling sound...\n");
  776. m_flags |= OpenRaider_EnableSound;
  777. m_flags ^= OpenRaider_EnableSound;
  778. return;
  779. }
  780. printf("Processing external sound files: ");
  781. #ifdef OBSOLETE
  782. // Mongoose 2001.12.31, Use music list from init script
  783. if (mMusicList.Empty())
  784. {
  785. print(true, "No music in map list, please edit your OpenRaider.init\n");
  786. }
  787. else
  788. {
  789. snprintf(filename, 126, "%s%s", m_audioDir, mMusicList[0]);
  790. filename[127] = 0;
  791. if (!mSound.add(filename, &id, SoundFlagsLoop))
  792. {
  793. mSound.play(id);
  794. printf("m");
  795. fflush(stdout);
  796. }
  797. }
  798. //snprintf(filename, 126, "%s%s", m_homeDir, "sample.wav");
  799. //filename[127] = 0;
  800. //mSound.add(filename, &m_testSFX, SoundFlagsNone);
  801. printf(".");
  802. fflush(stdout);
  803. #endif
  804. printf("\n");
  805. }
  806. void OpenRaider::processPakSounds()
  807. {
  808. unsigned char *riff;
  809. unsigned int riffSz;
  810. //tr2_sound_source_t *sound;
  811. //tr2_sound_details_t *detail;
  812. //float pos[3];
  813. unsigned int i;
  814. int id;
  815. /* detail
  816. short sample;
  817. short volume;
  818. short sound_range;
  819. short flags; // bits 8-15: priority?, 2-7: number of sound samples
  820. // in this group, bits 0-1: channel number
  821. */
  822. if (m_flags & OpenRaider_EnableSound)
  823. {
  824. printf("Processing pak sound files: ");
  825. }
  826. else
  827. {
  828. return;
  829. }
  830. for (i = 0; i < m_tombraider.getSoundSamplesCount(); ++i)
  831. {
  832. print(false, "Processing pak sounds: %i / %i",
  833. i, m_tombraider.getSoundSamplesCount());
  834. m_tombraider.getSoundSample(i, &riffSz, &riff);
  835. mSound.add(riff, &id, SoundFlagsNone);
  836. if (id == TR_SOUND_F_PISTOL && id > 0)
  837. {
  838. m_testSFX = id;
  839. }
  840. delete [] riff;
  841. // sound[i].sound_id; // internal sound index
  842. // sound[i].flags; // 0x40, 0x80, or 0xc0
  843. //pos[0] = sound[i].x;
  844. //pos[1] = sound[i].y;
  845. //pos[2] = sound[i].z;
  846. //mSound.SourceAt(id, pos);
  847. printf(".");
  848. fflush(stdout);
  849. }
  850. printf("\n");
  851. }
  852. void OpenRaider::loadLevel(char *mapname)
  853. {
  854. int i, j, len;
  855. char filename[256];
  856. // Mongoose 2002.03.23, Clear last loaded 'world'
  857. m_render.setMode(Render::modeDisabled);
  858. m_render.ClearWorld();
  859. gWorld.destroy();
  860. // Mongoose 2002.01.02, Now draw load screen, since external
  861. // GL textures are loaded and renderer is initialized
  862. m_render.setMode(Render::modeLoadScreen);
  863. gameFrame();
  864. /* 2003.07.05, Mongoose - No longer seeding, and looking for
  865. map to load -- load this map or fail and return */
  866. snprintf(filename, 254, "%s%s", m_pakDir, mapname);
  867. filename[255] = 0;
  868. len = strlen(filename);
  869. for (i = len, j = 0; i > 0; --i, ++j)
  870. {
  871. if (filename[i] == '/' || filename[i] == '\\')
  872. break;
  873. }
  874. j--;
  875. memset(m_mapName, 0, 32);
  876. for (i = 0; i < len - j && i < 30; ++i)
  877. {
  878. m_mapName[i] = filename[i + len - j];
  879. }
  880. m_tombraider.setDebug(m_flags & OpenRaider_DebugMap);
  881. m_flags |= OpenRaider_Loading;
  882. print(true, "Level %s loading", m_mapName);
  883. if (m_tombraider.Load(filename, percent_callback))
  884. {
  885. print(true, "ERROR: Failed to load level %s\n", m_mapName);
  886. return;
  887. }
  888. else
  889. {
  890. char altSfx[256];
  891. switch (m_tombraider.getEngine())
  892. {
  893. case TR_VERSION_2:
  894. case TR_VERSION_3:
  895. snprintf(altSfx, 255, "%s.sfx", filename);
  896. print(true, "Loading alternate SFX for TR2 or TR3 pak...\n");
  897. m_tombraider.loadSFX(altSfx);
  898. break;
  899. default:
  900. ;
  901. }
  902. }
  903. print(true, "Optimizing and translating pak data...");
  904. m_flags ^= OpenRaider_Loading;
  905. // Mongoose 2002.08.16, Used to cache TR4 textures at 10% of file load
  906. // in a callback - then with other engines process them here
  907. m_render.setMode(Render::modeDisabled);
  908. //sleep(1); // Why should we sleep here? -- xythobuz
  909. processTextures();
  910. m_render.setMode(Render::modeLoadScreen);
  911. print(true, "Level textures cached\n");
  912. // Cache/process rooms
  913. printf("Processing rooms: ");
  914. for (i = 0; i < m_tombraider.NumRooms(); ++i)
  915. {
  916. processRoom(i);
  917. print(false, "Processing rooms: %i/%i", i, m_tombraider.NumRooms());
  918. }
  919. printf("\n");
  920. // Cache/process meshes
  921. printf("Processing meshes: ");
  922. for (i = 0; i < m_tombraider.getMeshCount(); ++i)
  923. {
  924. m_render.setMode(Render::modeDisabled);
  925. processModel(i);
  926. m_render.setMode(Render::modeLoadScreen);
  927. print(false, "Processing meshes: %i/%i", i, m_tombraider.getMeshCount());
  928. }
  929. printf("\n");
  930. // Cache/process sprites
  931. processSprites();
  932. // Cache/process skeletal models
  933. processMoveables();
  934. // Cache/process sound fx
  935. processPakSounds();
  936. #ifdef DEBUG_MEMEORY
  937. // Right before pak is cleared will be highest use or memory
  938. display_memory_usage();
  939. #endif
  940. // Mongoose 2002.01.02, Go ahead and free the TR pak
  941. m_tombraider.reset();
  942. print(true, "Level pak freed from memory, Starting game...");
  943. #ifdef DEBUG_MEMEORY
  944. display_memory_usage();
  945. #endif
  946. // Mongoose 2002.01.02, FIXME GL call to critical section,
  947. // needs mutex really
  948. m_render.setMode(Render::modeDisabled);
  949. //sleep(2);
  950. // Draw game, level is loaded
  951. m_render.setMode(Render::modeVertexLight);
  952. m_flags ^= OpenRaider_Loading;
  953. }
  954. void OpenRaider::gameFrame()
  955. {
  956. SkeletalModel *mdl = 0x0;
  957. unsigned int ticks;
  958. float time;
  959. // Remember: ticks in milliseconds, time in hundredths
  960. gNetTicks = ticks = getTicks();
  961. time = gNetTicks * 0.1f;
  962. switch (m_render.getMode())
  963. {
  964. case Render::modeDisabled:
  965. break;
  966. case Render::modeLoadScreen:
  967. if ((ticks % 10000) > 1)
  968. {
  969. m_render.drawLoadScreen();
  970. swapBuffersGL();
  971. }
  972. break;
  973. default:
  974. if (LARA)
  975. {
  976. SkeletalModel *mdl = (SkeletalModel *)LARA->tmpHook;
  977. if (mdl)
  978. {
  979. float elapsed = time - mdl->lastTime;
  980. if (elapsed > mdl->rate)
  981. {
  982. if (mdl->getAnimation() == 0 &&
  983. (mdl->getFrame() == 2 || mdl->getFrame() == 10))
  984. {
  985. if (m_flags & OpenRaider_EnableSound)
  986. {
  987. mSound.play(TR_SOUND_FOOTSTEP0);
  988. }
  989. }
  990. else if (mdl->getAnimation() == 15)
  991. {
  992. eventAnimTest(TR_ANIAMTION_RUN);
  993. }
  994. mdl->setFrame(mdl->getFrame()+1);
  995. mdl->lastTime = elapsed / mdl->rate;
  996. }
  997. else
  998. {
  999. mdl->lastTime = time;
  1000. }
  1001. }
  1002. }
  1003. m_render.Display();
  1004. swapBuffersGL();
  1005. if (mdl && mdl->getAnimation() == 12)
  1006. {
  1007. switch (LARA->moveType)
  1008. {
  1009. case worldMoveType_swim:
  1010. case worldMoveType_fly:
  1011. case worldMoveType_noClipping:
  1012. eventAnimTest(TR_ANIAMTION_SWIM_IDLE);
  1013. break;
  1014. default:
  1015. eventAnimTest(TR_ANIAMTION_STAND);
  1016. }
  1017. LARA->moving = false;
  1018. }
  1019. }
  1020. if (m_flags & OpenRaider_ShowFPS)
  1021. {
  1022. static unsigned int frames = 0;
  1023. static float lastTime = 0.0f;
  1024. ++frames;
  1025. // Only update every second, so it can't be affected
  1026. // by fast/slow cards it only counts frames instead
  1027. // of estimating
  1028. if (time - lastTime > 100.0f)
  1029. {
  1030. if (mText)
  1031. mText->SetString(1, "FPS %d", frames);
  1032. lastTime = time;
  1033. frames = 0;
  1034. }
  1035. }
  1036. }
  1037. void OpenRaider::processTextures()
  1038. {
  1039. unsigned char *image;
  1040. unsigned char *bumpmap;
  1041. int i;
  1042. printf("Processing TR textures: ");
  1043. //if ( m_tombraider.getNumBumpMaps())
  1044. // gBumpMapStart = m_tombraider.NumTextures();
  1045. for (i = 0; i < m_tombraider.NumTextures(); ++i)
  1046. {
  1047. print(false, "Processing textures: %i/%i", i, m_tombraider.NumTextures());
  1048. m_tombraider.Texture(i, &image, &bumpmap);
  1049. // Overwrite any previous level textures on load
  1050. m_render.loadTexture(image, 256, 256, mLevelTextureOffset + i);
  1051. gMapTex2Bump.Add(mLevelTextureOffset + i, -1);
  1052. if (bumpmap)
  1053. {
  1054. gMapTex2Bump.Add(mLevelTextureOffset + i, mLevelTextureOffset + i +
  1055. m_tombraider.NumTextures());
  1056. m_render.loadTexture(bumpmap, 256, 256, mLevelTextureOffset + i +
  1057. m_tombraider.NumTextures());
  1058. }
  1059. if (image)
  1060. delete [] image;
  1061. if (bumpmap)
  1062. delete [] bumpmap;
  1063. printf(".");
  1064. fflush(stdout);
  1065. }
  1066. gTextureOffset = mLevelTextureOffset + m_tombraider.NumTextures();
  1067. printf("\n");
  1068. }
  1069. ////////////////////////////////////////////////////////////
  1070. // Private Accessors
  1071. ////////////////////////////////////////////////////////////
  1072. ////////////////////////////////////////////////////////////
  1073. // Private Mutators
  1074. ////////////////////////////////////////////////////////////
  1075. void OpenRaider::soundEvent(int type, int id, vec3_t pos, vec3_t angles)
  1076. {
  1077. switch (type)
  1078. {
  1079. case 0: // Reset listener position
  1080. mSound.listenAt(pos, angles);
  1081. break;
  1082. default:
  1083. mSound.sourceAt(id, pos);
  1084. mSound.play(id);
  1085. }
  1086. }
  1087. void OpenRaider::processSprites()
  1088. {
  1089. int i, j, k, l, x, y, s_index, width, height;
  1090. float scale, width2, height2;
  1091. tr2_sprite_texture_t *sprite;
  1092. tr2_sprite_texture_t *sprite_textures;
  1093. tr2_sprite_sequence_t *sprite_sequence;
  1094. sprite_seq_t *r_mesh;
  1095. tr2_item_t *item;
  1096. item = m_tombraider.Item();
  1097. sprite_textures = m_tombraider.Sprite();
  1098. sprite_sequence = m_tombraider.SpriteSequence();
  1099. scale = 4.0;
  1100. printf("Processing sprites: ");
  1101. for (i = 0; i < m_tombraider.NumItems() - 1; ++i)
  1102. {
  1103. print(false, "Processing sprites in Items: %i/%i",
  1104. i, m_tombraider.NumItems());
  1105. // It's a mesh, skip it
  1106. if (m_tombraider.Engine() == TR_VERSION_1 && item[i].intensity1 == -1)
  1107. continue;
  1108. k = item[i].object_id;
  1109. // Search the SpriteSequence list
  1110. // (if we didn't already decide that it's a mesh)
  1111. for (j = 0; j < (int)m_tombraider.NumSpriteSequences(); ++j)
  1112. {
  1113. if (sprite_sequence[j].object_id == k)
  1114. {
  1115. k = item[i].object_id;
  1116. s_index = sprite_sequence[j].offset;
  1117. r_mesh = new sprite_seq_t;
  1118. gWorld.addSprite(r_mesh);
  1119. r_mesh->num_sprites = -sprite_sequence[j].negative_length;
  1120. r_mesh->sprite = new sprite_t[r_mesh->num_sprites];
  1121. for (l = 0; l < r_mesh->num_sprites; ++l)
  1122. {
  1123. sprite = &sprite_textures[s_index];
  1124. width = sprite->width >> 8;
  1125. height = sprite->height >> 8;
  1126. x = sprite->x;
  1127. y = sprite->y;
  1128. width2 = width * scale;
  1129. height2 = height * scale;
  1130. // For vising use
  1131. r_mesh->sprite[l].pos[0] = item[i].x;
  1132. r_mesh->sprite[l].pos[1] = item[i].y;
  1133. r_mesh->sprite[l].pos[2] = item[i].z;
  1134. r_mesh->sprite[l].texture = sprite->tile + m_texOffset;
  1135. r_mesh->sprite[l].radius = width2 / 2.0;
  1136. r_mesh->sprite[l].vertex[0].pos[0] = -width2 / 2.0;
  1137. r_mesh->sprite[l].vertex[1].pos[0] = -width2 / 2.0;
  1138. r_mesh->sprite[l].vertex[2].pos[0] = width2 / 2.0;
  1139. r_mesh->sprite[l].vertex[3].pos[0] = width2 / 2.0;
  1140. r_mesh->sprite[l].vertex[0].pos[1] = 0;
  1141. r_mesh->sprite[l].vertex[1].pos[1] = -height2;
  1142. r_mesh->sprite[l].vertex[2].pos[1] = -height2;
  1143. r_mesh->sprite[l].vertex[3].pos[1] = 0;
  1144. r_mesh->sprite[l].vertex[0].pos[2] = 0;
  1145. r_mesh->sprite[l].vertex[1].pos[2] = 0;
  1146. r_mesh->sprite[l].vertex[2].pos[2] = 0;
  1147. r_mesh->sprite[l].vertex[3].pos[2] = 0;
  1148. r_mesh->sprite[l].texel[3].st[0] = (double)(x+width)/TexelScale;
  1149. r_mesh->sprite[l].texel[3].st[1] = (double)(y+height)/TexelScale;
  1150. r_mesh->sprite[l].texel[2].st[0] = (double)(x+width)/TexelScale;
  1151. r_mesh->sprite[l].texel[2].st[1] = (double)(y)/TexelScale;
  1152. r_mesh->sprite[l].texel[1].st[0] = (double)(x) /TexelScale;
  1153. r_mesh->sprite[l].texel[1].st[1] = (double)(y) /TexelScale;
  1154. r_mesh->sprite[l].texel[0].st[0] = (double)(x) / TexelScale;
  1155. r_mesh->sprite[l].texel[0].st[1] = (double)(y+height)/TexelScale;
  1156. printf(".");
  1157. fflush(stdout);
  1158. }
  1159. }
  1160. }
  1161. }
  1162. printf("\n");
  1163. }
  1164. void OpenRaider::processMoveables()
  1165. {
  1166. List <unsigned int> cache;
  1167. List <skeletal_model_t *> cache2;
  1168. tr2_mesh_t *mesh = NULL;
  1169. tr2_moveable_t *moveable = NULL;
  1170. tr2_meshtree_t *meshtree = NULL;
  1171. tr2_item_t *item = NULL;
  1172. tr2_animation_t *animation = NULL;
  1173. unsigned short *frame = NULL;
  1174. tr2_sprite_sequence_t *sprite_sequence = NULL;
  1175. tr2_object_texture_t *object_texture = NULL;
  1176. int i, j, object_id;
  1177. int ent = 0;
  1178. frame = m_tombraider.Frame();
  1179. moveable = m_tombraider.Moveable();
  1180. meshtree = m_tombraider.MeshTree();
  1181. mesh = m_tombraider.Mesh();
  1182. object_texture = m_tombraider.ObjectTextures();
  1183. item = m_tombraider.Item();
  1184. animation = m_tombraider.Animation();
  1185. sprite_sequence = m_tombraider.SpriteSequence();
  1186. printf("Processing skeletal models: ");
  1187. for (i = 0; i < m_tombraider.NumItems(); ++i)
  1188. {
  1189. object_id = item[i].object_id;
  1190. // It may not be a moveable, test for sprite
  1191. if (!(m_tombraider.Engine() == TR_VERSION_1 && item[i].intensity1 == -1))
  1192. {
  1193. for (j = 0; j < (int)m_tombraider.NumSpriteSequences(); ++j)
  1194. {
  1195. if (sprite_sequence[j].object_id == object_id)
  1196. break;
  1197. }
  1198. // It's not a moveable, skip sprite
  1199. if (j != (int)m_tombraider.NumSpriteSequences())
  1200. {
  1201. printf("s");
  1202. fflush(stdout);
  1203. continue;
  1204. }
  1205. }
  1206. for (j = 0; j < (int)m_tombraider.NumMoveables(); ++j)
  1207. {
  1208. if ((int)moveable[j].object_id == object_id)
  1209. break;
  1210. }
  1211. // It's not a moveable or even a sprite?, skip unknown
  1212. if (j == (int)m_tombraider.NumMoveables())
  1213. {
  1214. printf("?"); // what the wolf?
  1215. fflush(stdout);
  1216. continue;
  1217. }
  1218. processMoveable(j, i, &ent, cache2, cache, object_id);
  1219. }
  1220. // Get models that aren't items
  1221. for (i = 0; i < m_tombraider.NumMoveables(); ++i)
  1222. {
  1223. print(false, "Processing skeletal models: %i/%i",
  1224. i, m_tombraider.NumMoveables());
  1225. switch ((int)moveable[i].object_id)
  1226. {
  1227. case 30:
  1228. case 2: // Which tr needs this as model agian?
  1229. processMoveable(i, i, &ent, cache2, cache,
  1230. (int)moveable[i].object_id);
  1231. break;
  1232. default:
  1233. switch (m_tombraider.Engine())
  1234. {
  1235. case TR_VERSION_1:
  1236. switch ((int)moveable[i].object_id)
  1237. {
  1238. case TombRaider1::LaraMutant:
  1239. processMoveable(i, i, &ent, cache2, cache,
  1240. (int)moveable[i].object_id);
  1241. break;
  1242. }
  1243. break;
  1244. case TR_VERSION_4:
  1245. switch ((int)moveable[i].object_id)
  1246. {
  1247. case TR4_PISTOLS_ANIM:
  1248. case TR4_UZI_ANIM:
  1249. case TR4_SHOTGUN_ANIM:
  1250. case TR4_CROSSBOW_ANIM:
  1251. case TR4_GRENADE_GUN_ANIM:
  1252. case TR4_SIXSHOOTER_ANIM:
  1253. processMoveable(i, i, &ent, cache2, cache,
  1254. (int)moveable[i].object_id);
  1255. break;
  1256. }
  1257. break;
  1258. default:
  1259. ;
  1260. }
  1261. }
  1262. }
  1263. printf("\n");
  1264. }
  1265. void OpenRaider::processMoveable(int index, int i, int *ent,
  1266. List <skeletal_model_t *> &cache2,
  1267. List <unsigned int> &cache, int object_id)
  1268. {
  1269. skeletal_model_t *r_model = NULL;
  1270. skeletal_model_t *c_model = NULL;
  1271. animation_frame_t *animation_frame = NULL;
  1272. tr2_mesh_t *mesh = NULL;
  1273. tr2_moveable_t *moveable = NULL;
  1274. tr2_meshtree_t *meshtree = NULL;
  1275. tr2_item_t *item = NULL;
  1276. tr2_animation_t *animation = NULL;
  1277. tr2_meshtree_t *mesh_tree = NULL;
  1278. bone_frame_t *bone = NULL;
  1279. bone_tag_t *tag = NULL;
  1280. entity_t *thing = NULL;
  1281. SkeletalModel *sModel = 0x0;
  1282. unsigned short *frame;
  1283. int j, k, a, frame_step;
  1284. unsigned int l, frame_offset, frame_count, f;
  1285. float pos[3];
  1286. float yaw;
  1287. bool lara = false;
  1288. int skyMesh;
  1289. skyMesh = m_tombraider.getSkyModelId();
  1290. frame = m_tombraider.Frame();
  1291. moveable = m_tombraider.Moveable();
  1292. meshtree = m_tombraider.MeshTree();
  1293. mesh = m_tombraider.Mesh();
  1294. item = m_tombraider.Item();
  1295. animation = m_tombraider.Animation();
  1296. pos[0] = item[i].x;
  1297. pos[1] = item[i].y;
  1298. pos[2] = item[i].z;
  1299. yaw = ((item[i].angle >> 14) & 0x03);
  1300. yaw *= 90;
  1301. thing = new entity_t;
  1302. thing->id = (*ent)++;
  1303. thing->type = 0x00;
  1304. thing->pos[0] = item[i].x;
  1305. thing->pos[1] = item[i].y;
  1306. thing->pos[2] = item[i].z;
  1307. thing->angles[1] = yaw;
  1308. thing->objectId = moveable[index].object_id;
  1309. thing->moving = false;
  1310. thing->animate = false;
  1311. sModel = new SkeletalModel();
  1312. m_render.addSkeletalModel(sModel);
  1313. thing->tmpHook = sModel; // temp hack to keep a running version during refactoring
  1314. if (m_tombraider.Engine() == TR_VERSION_1)
  1315. {
  1316. switch (thing->objectId)
  1317. {
  1318. case TombRaider1::Wolf:
  1319. thing->state = TombRaider1::WolfState_Lying;
  1320. //thing->animate = true;
  1321. sModel->setAnimation(3);
  1322. sModel->setFrame(0);
  1323. break;
  1324. }
  1325. }
  1326. // FIXME: Check here and see if we already have one for object_id later
  1327. // if (gWorld.isCachedSkeletalModel(moveable[index].object_id))
  1328. // {
  1329. // thing->modelId = m_render.add(sModel);
  1330. // return;
  1331. // }
  1332. r_model = new skeletal_model_t;
  1333. r_model->id = moveable[index].object_id;
  1334. // Gather more info if this is lara
  1335. if (moveable[index].object_id == 0)
  1336. {
  1337. gLaraModel = r_model; // hack to avoid broken system until new event sys
  1338. lara = true;
  1339. m_camera.translate(pos[0], pos[1] - 470, pos[2]);
  1340. thing->type = 0x02;
  1341. LARA = thing; // Mongoose 2002.03.22, Cheap hack for now
  1342. LARA->master = 0x0;
  1343. switch (m_tombraider.Engine())
  1344. {
  1345. case TR_VERSION_3:
  1346. LARA->modelId = i;
  1347. sModel->setAnimation(TR_ANIAMTION_RUN);
  1348. sModel->setIdleAnimation(TR_ANIAMTION_STAND);
  1349. r_model->tr4Overlay = false;
  1350. break;
  1351. case TR_VERSION_4:
  1352. LARA->modelId = i;
  1353. sModel->setAnimation(TR_ANIAMTION_RUN);
  1354. sModel->setIdleAnimation(TR_ANIAMTION_STAND);
  1355. // Only TR4 lara has 2 layer bone tags/meshes per bone frame
  1356. r_model->tr4Overlay = true;
  1357. break;
  1358. default:
  1359. LARA->modelId = index;
  1360. sModel->setAnimation(TR_ANIAMTION_RUN);
  1361. sModel->setIdleAnimation(TR_ANIAMTION_STAND);
  1362. r_model->tr4Overlay = false;
  1363. }
  1364. r_model->ponytailId = 0;
  1365. }
  1366. else
  1367. {
  1368. lara = false;
  1369. r_model->ponytailId = -1;
  1370. }
  1371. // Animation
  1372. a = moveable[index].animation;
  1373. frame_offset = animation[a].frame_offset / 2;
  1374. frame_step = animation[a].frame_size;
  1375. int frame_cycle = 0;
  1376. if (a >= (int)m_tombraider.NumAnimations())
  1377. {
  1378. a = m_tombraider.NumFrames() - frame_offset;
  1379. }
  1380. else
  1381. {
  1382. a = (animation[a].frame_offset / 2) - frame_offset;
  1383. }
  1384. if (frame_step != 0) // prevent divide-by-zero errors
  1385. a /= frame_step;
  1386. if (a != 0) // prevent divide-by-zero errors
  1387. frame_offset += frame_step * (frame_cycle % a);
  1388. if (a < 0)
  1389. {
  1390. // continue;
  1391. return;
  1392. }
  1393. // FIXME: Might be better UID for each model, but this seems
  1394. // to work well
  1395. j = object_id;
  1396. // We only want one copy of the skeletal model in memory
  1397. if (cache.Empty() || cache.SearchKey(j) == UINT_MAX)
  1398. {
  1399. sModel->model = r_model;
  1400. gWorld.addEntity(thing);
  1401. k = gWorld.addModel(r_model);
  1402. cache.Add(j);
  1403. cache2.Add(r_model);
  1404. switch (m_tombraider.Engine())
  1405. {
  1406. case TR_VERSION_4:
  1407. if (LARA && moveable[index].object_id == 30)
  1408. {
  1409. r_model->ponytailId = k;
  1410. r_model->ponytailMeshId = moveable[index].starting_mesh;
  1411. r_model->ponytailNumMeshes = ((moveable[index].num_meshes > 0) ?
  1412. moveable[index].num_meshes : 0);
  1413. r_model->ponytailAngle = -90.0f;
  1414. r_model->ponytail[0] = -3;
  1415. r_model->ponytail[1] = -22;
  1416. r_model->ponytail[2] = -20;
  1417. r_model->ponyOff = 40;
  1418. r_model->ponyOff2 = 32;
  1419. r_model->pigtails = false;
  1420. // Try to guess pigtails by looking for certian num verts in head
  1421. if (mesh[moveable[0].starting_mesh].num_vertices > 80)
  1422. {
  1423. r_model->pigtails = true;
  1424. r_model->ponyOff -= 20;
  1425. r_model->ponytail[1] -= 32;
  1426. }
  1427. m_render.setFlags(Render::fRenderPonytail);
  1428. print(true, "Found known ponytail\n");
  1429. }
  1430. default:
  1431. if (LARA && moveable[index].object_id == 2)
  1432. {
  1433. r_model->ponytailId = k;
  1434. r_model->ponytailMeshId = moveable[index].starting_mesh;
  1435. r_model->ponytailNumMeshes = ((moveable[index].num_meshes > 0) ?
  1436. moveable[index].num_meshes : 0);
  1437. r_model->ponytailAngle = -90.0f;
  1438. r_model->ponytail[0] = 0;
  1439. r_model->ponytail[1] = -20;
  1440. r_model->ponytail[2] = -20;
  1441. r_model->ponyOff = 40;
  1442. r_model->ponyOff2 = 0;
  1443. m_render.setFlags(Render::fRenderPonytail);
  1444. print(true, "Found ponytail?\n");
  1445. }
  1446. }
  1447. }
  1448. else
  1449. {
  1450. delete r_model;
  1451. c_model = cache2[cache.SearchKey(j)];
  1452. sModel->model = c_model;
  1453. gWorld.addEntity(thing);
  1454. gWorld.addModel(c_model);
  1455. printf("c"); // it's already cached
  1456. fflush(stdout);
  1457. // continue;
  1458. return;
  1459. }
  1460. int aloop = m_tombraider.getNumAnimsForMoveable(index);
  1461. #ifdef DEBUG
  1462. if (m_flags & OpenRaider_DebugModel)
  1463. {
  1464. printf("\nanimation = %i, num_animations = %i\n",
  1465. moveable[index].animation, aloop);
  1466. printf("\nitem[%i].flags = %i\nentity[%i]\n",
  1467. i, item[i].flags, thing->id);
  1468. }
  1469. #endif
  1470. //a = moveable[index].animation;
  1471. //frame_offset = animation[a].frame_offset / 2;
  1472. //frame_step = animation[a].frame_size;
  1473. for (; a < aloop; ++a,
  1474. frame_offset = animation[a].frame_offset / 2,
  1475. frame_step = animation[a].frame_size)
  1476. {
  1477. animation_frame = new animation_frame_t;
  1478. r_model->animation.pushBack(animation_frame);
  1479. frame_count = (animation[a].frame_end - animation[a].frame_start) + 1;
  1480. animation_frame->rate = animation[a].frame_rate;
  1481. #ifdef DEBUG
  1482. if (m_flags & OpenRaider_DebugModel)
  1483. {
  1484. printf("animation[%i] state and unknowns = %i, %i, %i, %i, %i\n",
  1485. a, animation[a].state_id, animation[a].unknown1,
  1486. animation[a].unknown2, animation[a].unknown3,
  1487. animation[a].unknown4);
  1488. printf("animation[%i].frame_rate = %i\n",
  1489. a, animation[a].frame_rate);
  1490. printf("animation[%i].next_animation = %i\n",
  1491. a, animation[a].next_animation);
  1492. printf("animation[%i].frame_offset = %i\n",
  1493. a, animation[a].frame_offset);
  1494. printf("animation[%i].anim_command = %i\n",
  1495. a, animation[a].anim_command);
  1496. printf("animation[%i].num_anim_commands = %i\n",
  1497. a, animation[a].num_anim_commands);
  1498. printf("animation[%i].state_change_offset = %i\n",
  1499. a, animation[a].state_change_offset);
  1500. printf(" frame_offset = %i\n",
  1501. frame_offset);
  1502. }
  1503. #endif
  1504. // Get all the frames for aniamtion
  1505. for (f = 0; f < frame_count; ++f, frame_offset += frame_step)
  1506. {
  1507. // HACK: Lara's ObjectID is 315, but her meshes start at 0, so make a
  1508. // quick substitution (so she doesn't appear as a bunch of thighs)
  1509. if (index == 0 && m_tombraider.Engine() == TR_VERSION_3)
  1510. {
  1511. for (j = 0; j < (int)m_tombraider.NumMoveables() && !index; ++j)
  1512. {
  1513. if (moveable[j].object_id == 315)
  1514. index = j;
  1515. }
  1516. }
  1517. // Fix Lara in TR4
  1518. if (index == 0 && m_tombraider.Engine() == TR_VERSION_4)
  1519. {
  1520. for (j = 0; j < (int)m_tombraider.NumMoveables() && !index; ++j)
  1521. {
  1522. // Body is ItemID 8, joints are ItemID 9
  1523. // (TR4 demo: body is ItemID 10, joints are ItemID 11)
  1524. if (moveable[j].object_id == 8)
  1525. index = j;
  1526. }
  1527. }
  1528. else if (moveable[index].object_id == 8 &&
  1529. m_tombraider.Engine() == TR_VERSION_4)
  1530. {
  1531. // KLUDGE to do "skinning"
  1532. index = 0;
  1533. for (j = 0; j < (int)m_tombraider.NumMoveables() && !index; ++j)
  1534. {
  1535. // Body is ItemID 8, joints are ItemID 9
  1536. // (TR4 demo: body is ItemID 10, joints are ItemID 11)
  1537. if (moveable[j].object_id == 9)
  1538. index = j;
  1539. }
  1540. }
  1541. #ifdef DEBUG
  1542. if (m_flags & OpenRaider_DebugModel)
  1543. {
  1544. printf("animation[%i].boneframe[%i] = offset %i, step %i\n",
  1545. a, f, frame_offset, frame_step);
  1546. }
  1547. #endif
  1548. // Mongoose 2002.08.15, Was
  1549. // if (frame_offset + 8 > _tombraider.NumFrames())
  1550. if (frame_offset > m_tombraider.NumFrames())
  1551. {
  1552. print(true, "WARNING: Bad animation frame %i > %i\n",
  1553. frame_offset, m_tombraider.NumFrames());
  1554. // Mongoose 2002.08.15, Atempt to skip more likely bad animation data
  1555. print(true, "WARNING: Handling bad animation data...");
  1556. return; //continue;
  1557. }
  1558. // Generate bone frames and tags per frame ////////////
  1559. bone = new bone_frame_t;
  1560. animation_frame->frame.pushBack(bone);
  1561. // Init translate for bone frame
  1562. bone->pos[0] = (short)frame[frame_offset + 6];
  1563. bone->pos[1] = (short)frame[frame_offset + 7];
  1564. bone->pos[2] = (short)frame[frame_offset + 8];
  1565. bone->yaw = yaw;
  1566. //printf("%f %f %f\n", bone->pos[0], bone->pos[1], bone->pos[2]);
  1567. l = 9; // First angle offset in this Frame
  1568. // Run through the tag and calculate the rotation and offset
  1569. for (j = 0; j < (int)moveable[index].num_meshes; ++j)
  1570. {
  1571. tag = new bone_tag_t;
  1572. bone->tag.pushBack(tag);
  1573. tag->off[0] = 0.0;
  1574. tag->off[1] = 0.0;
  1575. tag->off[2] = 0.0;
  1576. tag->flag = 0x00;
  1577. tag->rot[0] = 0.0;
  1578. tag->rot[1] = 0.0;
  1579. tag->rot[2] = 0.0;
  1580. tag->mesh = moveable[index].starting_mesh + j;
  1581. // Setup offsets to produce skeletion
  1582. if (j == 0)
  1583. {
  1584. // Since we use bone's offset, these aren't used
  1585. tag->off[0] = 0.0;
  1586. tag->off[1] = 0.0;
  1587. tag->off[2] = 0.0;
  1588. // Always push tag[0], this isn't really used either
  1589. tag->flag = 0x02;
  1590. }
  1591. else // Nonprimary tag - position relative to first tag
  1592. {
  1593. int *tree;
  1594. // Hack: moveable[index].mesh_tree is a byte offset
  1595. // into mesh_tree[], so we have to convert to index
  1596. tree = (int *)meshtree;
  1597. mesh_tree = (tr2_meshtree_t *)&tree[moveable[index].mesh_tree
  1598. + ((j - 1) * 4)];
  1599. tag->off[0] = mesh_tree->x;
  1600. tag->off[1] = mesh_tree->y;
  1601. tag->off[2] = mesh_tree->z;
  1602. tag->flag = mesh_tree->flags;
  1603. }
  1604. // Setup tag rotations
  1605. m_tombraider.computeRotationAngles(&frame, &frame_offset, &l,
  1606. tag->rot, tag->rot+1, tag->rot+2);
  1607. }
  1608. }
  1609. }
  1610. if (i == skyMesh)
  1611. {
  1612. m_render.setSkyMesh(i, //moveable[i].starting_mesh,
  1613. (m_tombraider.Engine() == TR_VERSION_2));
  1614. }
  1615. printf(".");
  1616. fflush(stdout);
  1617. }
  1618. int compareFaceTextureId(const void *voidA, const void *voidB)
  1619. {
  1620. texture_tri_t *a = (texture_tri_t *)voidA, *b = (texture_tri_t *)voidB;
  1621. if (!a || !b)
  1622. return -1; // error really
  1623. // less than
  1624. if (a->texture < b->texture)
  1625. return -1;
  1626. // greater than ( no need for equal )
  1627. return 1;
  1628. }
  1629. void setupTextureColor(texture_tri_t *r_tri, Render *render, float *colorf)
  1630. {
  1631. unsigned char color[4];
  1632. unsigned int colorI;
  1633. color[0] = (unsigned char)(colorf[0]*255.0f);
  1634. color[1] = (unsigned char)(colorf[1]*255.0f);
  1635. color[2] = (unsigned char)(colorf[2]*255.0f);
  1636. color[3] = (unsigned char)(colorf[3]*255.0f);
  1637. ((unsigned char *)(&colorI))[3] = color[0];
  1638. ((unsigned char *)(&colorI))[2] = color[1];
  1639. ((unsigned char *)(&colorI))[1] = color[2];
  1640. ((unsigned char *)(&colorI))[0] = color[3];
  1641. if (!gColorTextureHACK.find(colorI))
  1642. {
  1643. gColorTextureHACK.pushBack(colorI);
  1644. r_tri->texture = gTextureOffset + gColorTextureHACK.size();
  1645. render->loadTexture(Texture::generateColorTexture(color, 32, 32),
  1646. 32, 32,
  1647. r_tri->texture);
  1648. #ifdef DEBUG_COLOR_TEXTURE_GEN
  1649. printf("Color 0x%02x%02x%02x%02x | 0x%08xto texture[%i]?\n",
  1650. color[0], color[1], color[2], color[3], colorI,
  1651. gColorTextureHACK.size());
  1652. #endif
  1653. }
  1654. else
  1655. {
  1656. //printf("Color already loaded %i -> 0x%08x\n",
  1657. // gColorTextureHACK.getCurrentIndex(),
  1658. // gColorTextureHACK.current());
  1659. r_tri->texture = gTextureOffset + gColorTextureHACK.getCurrentIndex();
  1660. }
  1661. //r_tri->texture = white; // White texture
  1662. }
  1663. void OpenRaider::processModel(int index)
  1664. {
  1665. int i, j, count, texture, white;
  1666. int vertexIndices[6];
  1667. float st[12];
  1668. float color[4];
  1669. unsigned short transparency;
  1670. texture_tri_t *r_tri;
  1671. // Assert common sense
  1672. if (index < 0 || !m_tombraider.isMeshValid(index))
  1673. {
  1674. // FIXME: allow sparse lists with matching ids instead?
  1675. gWorld.addMesh(NULL); // Filler, to make meshes array ids align
  1676. printf("x");
  1677. fflush(stdout);
  1678. return;
  1679. }
  1680. // WHITE texture id
  1681. white = 0;
  1682. model_mesh_t *mesh = new model_mesh_t;
  1683. // Mongoose 2002.08.30, Testing support for 'shootable' models ( traceable )
  1684. m_tombraider.getMeshCollisionInfo(index, mesh->center, &mesh->radius);
  1685. // FIXME: Arrays don't work either =)
  1686. // Mesh geometery, colors, etc
  1687. m_tombraider.getMeshVertexArrays(index,
  1688. &mesh->vertexCount, &mesh->vertices,
  1689. &mesh->normalCount, &mesh->normals,
  1690. &mesh->colorCount, &mesh->colors);
  1691. // Textured Triangles
  1692. count = m_tombraider.getMeshTexturedTriangleCount(index);
  1693. mesh->texturedTriangles.reserve(count); // little faster
  1694. for (i = 0; i < count; ++i)
  1695. {
  1696. r_tri = new texture_tri_t;
  1697. m_tombraider.getMeshTexturedTriangle(index, i,
  1698. r_tri->index,
  1699. r_tri->st,
  1700. &r_tri->texture,
  1701. &r_tri->transparency);
  1702. r_tri->texture += m_texOffset;
  1703. // Add to face vector
  1704. mesh->texturedTriangles.pushBack(r_tri);
  1705. }
  1706. // Coloured Triangles
  1707. count = m_tombraider.getMeshColoredTriangleCount(index);
  1708. mesh->coloredTriangles.reserve(count); // little faster
  1709. for (i = 0; i < count; i++)
  1710. {
  1711. r_tri = new texture_tri_t;
  1712. m_tombraider.getMeshColoredTriangle(index, i,
  1713. r_tri->index,
  1714. color);
  1715. r_tri->st[0] = color[0];
  1716. r_tri->st[1] = color[1];
  1717. r_tri->st[2] = color[2];
  1718. r_tri->st[3] = color[3];
  1719. r_tri->st[4] = 1.0;
  1720. r_tri->st[5] = 1.0;
  1721. #ifdef EXPERIMENTAL
  1722. setupTextureColor(r_tri, &m_render, color);
  1723. #else
  1724. r_tri->texture = white; // White texture
  1725. #endif
  1726. r_tri->transparency = 0;
  1727. // Add to face vector
  1728. mesh->coloredTriangles.pushBack(r_tri);
  1729. }
  1730. // Textured Rectangles
  1731. count = m_tombraider.getMeshTexturedRectangleCount(index);
  1732. mesh->texturedRectangles.reserve(count*2); // little faster
  1733. for (i = 0; i < count; ++i)
  1734. {
  1735. m_tombraider.getMeshTexturedRectangle(index, i,
  1736. vertexIndices,
  1737. st,
  1738. &texture,
  1739. &transparency);
  1740. r_tri = new texture_tri_t;
  1741. for (j = 0; j < 3; ++j)
  1742. r_tri->index[j] = vertexIndices[j];
  1743. for (j = 0; j < 6; ++j)
  1744. r_tri->st[j] = st[j];
  1745. r_tri->texture = texture + m_texOffset;
  1746. r_tri->transparency = transparency;
  1747. // Add to face vector
  1748. mesh->texturedRectangles.pushBack(r_tri);
  1749. r_tri = new texture_tri_t;
  1750. for (j = 3; j < 6; ++j)
  1751. r_tri->index[j-3] = vertexIndices[j];
  1752. for (j = 6; j < 12; ++j)
  1753. r_tri->st[j-6] = st[j];
  1754. r_tri->texture = texture + m_texOffset;
  1755. r_tri->transparency = transparency;
  1756. // Add to face vector
  1757. mesh->texturedRectangles.pushBack(r_tri);
  1758. }
  1759. // Coloured Rectangles
  1760. count = m_tombraider.getMeshColoredRectangleCount(index);
  1761. mesh->coloredRectangles.reserve(count*2); // little faster
  1762. for (i = 0; i < count; ++i)
  1763. {
  1764. m_tombraider.getMeshColoredRectangle(index, i,
  1765. vertexIndices,
  1766. color);
  1767. r_tri = new texture_tri_t;
  1768. for (j = 0; j < 3; ++j)
  1769. r_tri->index[j] = vertexIndices[j];
  1770. //for (j = 0; j < 6; ++j)
  1771. // r_tri->st[j] = st[j];
  1772. r_tri->st[0] = color[0];
  1773. r_tri->st[1] = color[1];
  1774. r_tri->st[2] = color[2];
  1775. r_tri->st[3] = color[3];
  1776. r_tri->st[4] = 1.0;
  1777. r_tri->st[5] = 1.0;
  1778. #ifdef EXPERIMENTAL
  1779. //for (j = 6; j < 12; ++j)
  1780. // r_tri->st[j-6] = st[j];
  1781. setupTextureColor(r_tri, &m_render, color);
  1782. #else
  1783. r_tri->texture = white; // White texture
  1784. #endif
  1785. r_tri->transparency = 0;
  1786. // Add to face vector
  1787. mesh->coloredRectangles.pushBack(r_tri);
  1788. r_tri = new texture_tri_t;
  1789. for (j = 3; j < 6; ++j)
  1790. r_tri->index[j-3] = vertexIndices[j];
  1791. //for (j = 6; j < 12; ++j)
  1792. // r_tri->st[j-6] = st[j];
  1793. r_tri->st[0] = color[0];
  1794. r_tri->st[1] = color[1];
  1795. r_tri->st[2] = color[2];
  1796. r_tri->st[3] = color[3];
  1797. r_tri->st[4] = 1.0;
  1798. r_tri->st[5] = 1.0;
  1799. #ifdef EXPERIMENTAL
  1800. setupTextureColor(r_tri, &m_render, color);
  1801. #else
  1802. r_tri->texture = white; // White texture
  1803. #endif
  1804. r_tri->transparency = 0;
  1805. // Add to face vector
  1806. mesh->coloredRectangles.pushBack(r_tri);
  1807. }
  1808. // Sort faces by texture
  1809. mesh->texturedTriangles.qSort(compareFaceTextureId);
  1810. mesh->coloredTriangles.qSort(compareFaceTextureId);
  1811. mesh->texturedRectangles.qSort(compareFaceTextureId);
  1812. mesh->coloredRectangles.qSort(compareFaceTextureId);
  1813. gWorld.addMesh(mesh);
  1814. printf(".");
  1815. fflush(stdout);
  1816. }
  1817. #define MATRIX_TRANSFORMS
  1818. void OpenRaider::processRoom(int index)
  1819. {
  1820. unsigned int i, j, count;
  1821. room_mesh_t *r_mesh = NULL;
  1822. RenderRoom *rRoom = NULL;
  1823. #ifdef MATRIX_TRANSFORMS
  1824. //matrix_t transform;
  1825. Matrix transform;
  1826. #endif
  1827. if (!m_tombraider.isRoomValid(index))
  1828. {
  1829. openraider_error("OpenRaider::RoomSetup", "Invalid room index",
  1830. __FILE__, __LINE__);
  1831. print(false, "WARNING: Handling invalid vertex array in room");
  1832. gWorld.addRoom(0x0);
  1833. m_render.addRoom(0x0);
  1834. printf("x");
  1835. fflush(stdout);
  1836. return;
  1837. }
  1838. rRoom = new RenderRoom();
  1839. r_mesh = new room_mesh_t;
  1840. r_mesh->id = index;
  1841. m_tombraider.getRoomInfo(index, &r_mesh->flags, r_mesh->pos,
  1842. r_mesh->bbox_min, r_mesh->bbox_max);
  1843. // Adjust positioning for OR world coord translation
  1844. r_mesh->bbox_min[0] += r_mesh->pos[0];
  1845. r_mesh->bbox_max[0] += r_mesh->pos[0];
  1846. r_mesh->bbox_min[2] += r_mesh->pos[2];
  1847. r_mesh->bbox_max[2] += r_mesh->pos[2];
  1848. // Mongoose 2002.04.03, Setup 3d transform
  1849. #ifdef MATRIX_TRANSFORMS
  1850. //mtkMatrixIdentity(transform);
  1851. //mtkMatrixTranslate(transform,
  1852. // r_mesh->pos[0], r_mesh->pos[1], r_mesh->pos[2]);
  1853. transform.setIdentity();
  1854. transform.translate(r_mesh->pos);
  1855. #else
  1856. #endif
  1857. // Setup portals
  1858. float portalVertices[12];
  1859. count = m_tombraider.getRoomPortalCount(index);
  1860. // FIXME: OR wrongly uses a cached adj room list for rendering vis
  1861. r_mesh->adjacentRooms.reserve(count + 1);
  1862. r_mesh->adjacentRooms.setError(-1);
  1863. // Current room is always first
  1864. r_mesh->adjacentRooms.pushBack(index);
  1865. for (i = 0; i < count; ++i)
  1866. {
  1867. portal_t *portal = new portal_t;
  1868. m_tombraider.getRoomPortal(index, i,
  1869. &portal->adjoining_room, portal->normal,
  1870. portalVertices);
  1871. for (j = 0; j < 4; ++j)
  1872. {
  1873. portal->vertices[j][0] = portalVertices[j*3];
  1874. portal->vertices[j][1] = portalVertices[j*3+1];
  1875. portal->vertices[j][2] = portalVertices[j*3+2];
  1876. // Relative coors in vis portals
  1877. #ifdef MATRIX_TRANSFORMS
  1878. //mtkMatrixTransform(transform, portal->vertices[j]);
  1879. transform.multiply3v(portal->vertices[j], portal->vertices[j]);
  1880. #else
  1881. portal->vertices[j][0] += r_mesh->pos[0];
  1882. portal->vertices[j][1] += r_mesh->pos[1];
  1883. portal->vertices[j][2] += r_mesh->pos[2];
  1884. #endif
  1885. }
  1886. r_mesh->adjacentRooms.pushBack(portal->adjoining_room);
  1887. r_mesh->portals.pushBack(portal);
  1888. }
  1889. // Physics/gameplay use /////////////////////////////
  1890. // FIXME: Use more of sector structure, boxes, and floordata
  1891. // List of sectors in this room
  1892. unsigned int sectorFlags;
  1893. int floorDataIndex, boxIndex, roomBelow, roomAbove;
  1894. count = m_tombraider.getRoomSectorCount(index, &r_mesh->numZSectors,
  1895. &r_mesh->numXSectors);
  1896. r_mesh->sectors.reserve(count);
  1897. r_mesh->sectors.setError(0x0);
  1898. for (i = 0; i < count; ++i)
  1899. {
  1900. sector_t *sector = new sector_t;
  1901. m_tombraider.getRoomSector(index, i, &sectorFlags,
  1902. &sector->ceiling, &sector->floor,
  1903. &floorDataIndex, &boxIndex, &roomBelow,
  1904. &roomAbove);
  1905. if (sectorFlags & tombraiderSector_wall)
  1906. {
  1907. sector->wall = true;
  1908. }
  1909. else
  1910. {
  1911. sector->wall = false;
  1912. }
  1913. r_mesh->sectors.pushBack(sector);
  1914. }
  1915. // Setup collision boxes ( Should use sectors, but this is a test )
  1916. count = m_tombraider.getRoomBoxCount(index);
  1917. r_mesh->boxes.reserve(count);
  1918. r_mesh->boxes.setError(0x0);
  1919. // FIXME: Only to be done only on room[0]? I don't think so...
  1920. for (i = 0; !index && i < count; ++i)
  1921. {
  1922. box_t *box = new box_t;
  1923. m_tombraider.getRoomBox(index, i,
  1924. box->a.pos, box->b.pos, box->c.pos, box->d.pos);
  1925. r_mesh->boxes.pushBack(box);
  1926. }
  1927. // Setup room lights /////////////////////////////////////
  1928. unsigned int lightFlags, lightType;
  1929. count = m_tombraider.getRoomLightCount(index);
  1930. rRoom->lights.reserve(count);
  1931. rRoom->lights.setError(0x0);
  1932. for (i = 0; i < count; ++i)
  1933. {
  1934. Light *light = new Light();
  1935. m_tombraider.getRoomLight(index, i,
  1936. light->mPos, light->mColor, light->mDir,
  1937. &light->mAtt, &light->mCutoff,
  1938. &lightType, &lightFlags);
  1939. switch (lightType)
  1940. {
  1941. case tombraiderLight_typeDirectional:
  1942. light->mType = Light::typeDirectional;
  1943. break;
  1944. case tombraiderLight_typeSpot:
  1945. light->mType = Light::typeSpot;
  1946. break;
  1947. case tombraiderLight_typePoint:
  1948. default:
  1949. light->mType = Light::typePoint;
  1950. }
  1951. rRoom->lights.pushBack(light);
  1952. }
  1953. // Room geometery //////////////////////////////////
  1954. //#define EXPERIMENTAL_UNFIFIED_ROOM_GEOMETERY
  1955. #ifdef EXPERIMENTAL_UNFIFIED_ROOM_GEOMETERY
  1956. unsigned int vertexCount, normalCount, colorCount, triCount;
  1957. vec_t *vertexArray;
  1958. vec_t *normalArray;
  1959. vec_t *colorArray;
  1960. unsigned int *indices, *flags;
  1961. float *texCoords;
  1962. int *textures;
  1963. m_tombraider.getRoomVertexArrays(index,
  1964. &vertexCount, &vertexArray,
  1965. &normalCount, &normalArray,
  1966. &colorCount, &colorArray);
  1967. rRoom->mesh.bufferVertexArray(vertexCount, (vec_t *)vertexArray);
  1968. rRoom->mesh.bufferNormalArray(normalCount, (vec_t *)normalArray);
  1969. rRoom->mesh.bufferColorArray(vertexCount, (vec_t *)colorArray, 4);
  1970. m_tombraider.getRoomTriangles(index, m_texOffset,
  1971. &triCount, &indices, &texCoords, &textures,
  1972. &flags);
  1973. rRoom->mesh.bufferTriangles(triCount, indices, texCoords, textures, flags);
  1974. #else
  1975. float rgba[4];
  1976. float xyz[3];
  1977. count = m_tombraider.getRoomVertexCount(index);
  1978. rRoom->mesh.allocateVertices(count);
  1979. rRoom->mesh.allocateNormals(0); // count
  1980. rRoom->mesh.allocateColors(count);
  1981. for (i = 0; i < count; ++i)
  1982. {
  1983. m_tombraider.getRoomVertex(index, i, xyz, rgba);
  1984. rRoom->mesh.setVertex(i, xyz[0], xyz[1], xyz[2]);
  1985. rRoom->mesh.setColor(i, rgba);
  1986. }
  1987. // Mongoose 2002.06.09, Setup allocation of meshes and polygons
  1988. // Counters ( Textured polygon lists are allocated per texture)
  1989. // ( Textures are mapped to these meshes )
  1990. int triangle_counter[TextureLimit];
  1991. int triangle_counter_alpha[TextureLimit];
  1992. int rectangle_counter[TextureLimit];
  1993. int rectangle_counter_alpha[TextureLimit];
  1994. int tris_mesh_map[TextureLimit];
  1995. int rect_mesh_map[TextureLimit];
  1996. for (i = 0; i < TextureLimit; ++i)
  1997. {
  1998. triangle_counter[i] = 0;
  1999. triangle_counter_alpha[i] = 0;
  2000. rectangle_counter[i] = 0;
  2001. rectangle_counter_alpha[i] = 0;
  2002. tris_mesh_map[i] = -1;
  2003. rect_mesh_map[i] = -1;
  2004. }
  2005. unsigned int numTris = 0;
  2006. unsigned int numQuads = 0;
  2007. int texture;
  2008. unsigned int r, t, q, v, flags;
  2009. unsigned int indices[4];
  2010. float texCoords[8];
  2011. count = m_tombraider.getRoomTriangleCount(index);
  2012. // Mongoose 2002.08.15, Presort by alpha and texture and setup mapping
  2013. for (t = 0; t < count; ++t)
  2014. {
  2015. m_tombraider.getRoomTriangle(index, t,
  2016. indices, texCoords, &texture, &flags);
  2017. texture += m_texOffset;
  2018. if (texture > (int)TextureLimit)
  2019. {
  2020. print(true, "Handling bad room[%i].tris[%i].texture = %i",
  2021. index, t, texture);
  2022. texture = TextureLimit - 1;
  2023. }
  2024. // Counters set up polygon allocation
  2025. if (flags & tombraiderFace_Alpha ||
  2026. flags & tombraiderFace_PartialAlpha)
  2027. {
  2028. triangle_counter_alpha[texture] += 1;
  2029. }
  2030. else
  2031. {
  2032. triangle_counter[texture] += 1;
  2033. }
  2034. // Counter sets up texture id to mesh id mapping
  2035. if (tris_mesh_map[texture] == -1)
  2036. {
  2037. tris_mesh_map[texture] = ++numTris;
  2038. }
  2039. }
  2040. count = m_tombraider.getRoomRectangleCount(index);
  2041. for (r = 0; r < count; ++r)
  2042. {
  2043. m_tombraider.getRoomRectangle(index, r,
  2044. indices, texCoords, &texture, &flags);
  2045. texture += m_texOffset;
  2046. if (texture > (int)TextureLimit)
  2047. {
  2048. print(true, "Handling bad room[%i].quad[%i].texture = %i",
  2049. index, r, texture);
  2050. texture = TextureLimit - 1;
  2051. }
  2052. if (flags & tombraiderFace_Alpha ||
  2053. flags & tombraiderFace_PartialAlpha)
  2054. {
  2055. rectangle_counter_alpha[texture] += 1;
  2056. }
  2057. else
  2058. {
  2059. rectangle_counter[texture] += 1;
  2060. }
  2061. if (rect_mesh_map[texture] == -1)
  2062. {
  2063. rect_mesh_map[texture] = ++numQuads;
  2064. }
  2065. }
  2066. // Allocate indexed polygon meshes
  2067. rRoom->mesh.allocateTriangles(numTris);
  2068. rRoom->mesh.allocateRectangles(numQuads);
  2069. for (i = 0, j = 0; i < TextureLimit; ++i)
  2070. {
  2071. if (tris_mesh_map[i] > 0)
  2072. {
  2073. j = tris_mesh_map[i] - 1;
  2074. t = triangle_counter[i];
  2075. rRoom->mesh.mTris[j].texture = i;
  2076. #ifdef MULTITEXTURE
  2077. rRoom->mesh.mTris[j].bumpmap = gMapTex2Bump[i];
  2078. #endif
  2079. rRoom->mesh.mTris[j].cnum_triangles = 0;
  2080. rRoom->mesh.mTris[j].num_triangles = 0;
  2081. rRoom->mesh.mTris[j].cnum_alpha_triangles = 0;
  2082. rRoom->mesh.mTris[j].num_alpha_triangles = 0;
  2083. rRoom->mesh.mTris[j].triangles = 0x0;
  2084. rRoom->mesh.mTris[j].alpha_triangles = 0x0;
  2085. rRoom->mesh.mTris[j].texcoors = 0x0;
  2086. rRoom->mesh.mTris[j].texcoors2 = 0x0;
  2087. if (t > 0)
  2088. {
  2089. rRoom->mesh.mTris[j].num_triangles = t;
  2090. rRoom->mesh.mTris[j].triangles = new unsigned int[t*3];
  2091. rRoom->mesh.mTris[j].num_texcoors = t * 3;
  2092. rRoom->mesh.mTris[j].texcoors = new vec2_t[t * 3];
  2093. }
  2094. t = triangle_counter_alpha[i];
  2095. if (t > 0)
  2096. {
  2097. rRoom->mesh.mTris[j].num_alpha_triangles = t;
  2098. rRoom->mesh.mTris[j].alpha_triangles = new unsigned int[t*3];
  2099. rRoom->mesh.mTris[j].num_texcoors2 = t * 3;
  2100. rRoom->mesh.mTris[j].texcoors2 = new vec2_t[t * 3];
  2101. }
  2102. }
  2103. ///////////////////////////////////////////
  2104. if (rect_mesh_map[i] > 0)
  2105. {
  2106. j = rect_mesh_map[i] - 1;
  2107. r = rectangle_counter[i];
  2108. rRoom->mesh.mQuads[j].texture = i;
  2109. #ifdef MULTITEXTURE
  2110. rRoom->mesh.mQuads[j].bumpmap = gMapTex2Bump[i];
  2111. #endif
  2112. rRoom->mesh.mQuads[j].cnum_quads = 0;
  2113. rRoom->mesh.mQuads[j].num_quads = 0;
  2114. rRoom->mesh.mQuads[j].cnum_alpha_quads = 0;
  2115. rRoom->mesh.mQuads[j].num_alpha_quads = 0;
  2116. rRoom->mesh.mQuads[j].quads = 0x0;
  2117. rRoom->mesh.mQuads[j].alpha_quads = 0x0;
  2118. rRoom->mesh.mQuads[j].texcoors = 0x0;
  2119. rRoom->mesh.mQuads[j].texcoors2 = 0x0;
  2120. if (r > 0)
  2121. {
  2122. rRoom->mesh.mQuads[j].num_quads = r;
  2123. rRoom->mesh.mQuads[j].quads = new unsigned int[r*4];
  2124. rRoom->mesh.mQuads[j].num_texcoors = r * 4;
  2125. rRoom->mesh.mQuads[j].texcoors = new vec2_t[r * 4];
  2126. }
  2127. r = rectangle_counter_alpha[i];
  2128. if (r > 0)
  2129. {
  2130. rRoom->mesh.mQuads[j].num_alpha_quads = r;
  2131. rRoom->mesh.mQuads[j].alpha_quads = new unsigned int[r*4];
  2132. rRoom->mesh.mQuads[j].num_texcoors2 = r * 4;
  2133. rRoom->mesh.mQuads[j].texcoors2 = new vec2_t[r * 4];
  2134. }
  2135. }
  2136. }
  2137. // Generate textured triangles
  2138. count = m_tombraider.getRoomTriangleCount(index);
  2139. for (t = 0; t < count; ++t)
  2140. {
  2141. m_tombraider.getRoomTriangle(index, t,
  2142. indices, texCoords, &texture, &flags);
  2143. // Adjust texture id using m_texOffset to map into
  2144. // correct textures
  2145. texture += m_texOffset;
  2146. j = tris_mesh_map[texture] - 1;
  2147. // Setup per vertex
  2148. for (i = 0; i < 3; ++i)
  2149. {
  2150. // Get vertex index {(0, a), (1, b), (2, c)}
  2151. v = indices[i];
  2152. if ((flags & tombraiderFace_Alpha ||
  2153. flags & tombraiderFace_PartialAlpha) &&
  2154. rRoom->mesh.mTris[j].num_alpha_triangles > 0)
  2155. {
  2156. q = rRoom->mesh.mTris[j].cnum_alpha_triangles*3+i;
  2157. rRoom->mesh.mTris[j].alpha_triangles[q] = v;
  2158. rRoom->mesh.mTris[j].texcoors2[q][0] = texCoords[i*2];
  2159. rRoom->mesh.mTris[j].texcoors2[q][1] = texCoords[i*2+1];
  2160. }
  2161. else if (rRoom->mesh.mTris[j].num_triangles > 0)
  2162. {
  2163. q = rRoom->mesh.mTris[j].cnum_triangles*3+i;
  2164. rRoom->mesh.mTris[j].triangles[q] = v;
  2165. rRoom->mesh.mTris[j].texcoors[q][0] = texCoords[i*2];
  2166. rRoom->mesh.mTris[j].texcoors[q][1] = texCoords[i*2+1];
  2167. }
  2168. // Partial alpha hack
  2169. if (flags & tombraiderFace_PartialAlpha)
  2170. {
  2171. //rRoom->mesh.colors[v].rgba[3] = 0.45;
  2172. }
  2173. }
  2174. if (flags & tombraiderFace_Alpha ||
  2175. flags & tombraiderFace_PartialAlpha)
  2176. {
  2177. rRoom->mesh.mTris[j].cnum_alpha_triangles++;
  2178. }
  2179. else
  2180. {
  2181. rRoom->mesh.mTris[j].cnum_triangles++;
  2182. }
  2183. }
  2184. // Generate textured quads
  2185. count = m_tombraider.getRoomRectangleCount(index);
  2186. for (r = 0; r < count; ++r)
  2187. {
  2188. m_tombraider.getRoomRectangle(index, r,
  2189. indices, texCoords, &texture, &flags);
  2190. // Adjust texture id using m_texOffset to map into
  2191. // correct textures
  2192. texture += m_texOffset;
  2193. if (texture > (int)TextureLimit)
  2194. {
  2195. texture = TextureLimit - 1;
  2196. }
  2197. j = rect_mesh_map[texture] - 1;
  2198. if (rRoom->mesh.mQuads[j].num_quads <= 0 &&
  2199. rRoom->mesh.mQuads[j].num_alpha_quads <= 0)
  2200. continue;
  2201. // Setup per vertex
  2202. for (i = 0; i < 4; ++i)
  2203. {
  2204. // Get vertex index {(0, a), (1, b), (2, c), (3, d)}
  2205. v = indices[i];
  2206. if ((flags & tombraiderFace_Alpha ||
  2207. flags & tombraiderFace_PartialAlpha) &&
  2208. rRoom->mesh.mQuads[j].num_alpha_quads > 0)
  2209. {
  2210. q = rRoom->mesh.mQuads[j].cnum_alpha_quads*4+i;
  2211. rRoom->mesh.mQuads[j].alpha_quads[q] = v;
  2212. rRoom->mesh.mQuads[j].texcoors2[q][0] = texCoords[i*2];
  2213. rRoom->mesh.mQuads[j].texcoors2[q][1] = texCoords[i*2+1];
  2214. }
  2215. else if (rRoom->mesh.mQuads[j].num_quads > 0)
  2216. {
  2217. q = rRoom->mesh.mQuads[j].cnum_quads*4+i;
  2218. rRoom->mesh.mQuads[j].quads[q] = v;
  2219. rRoom->mesh.mQuads[j].texcoors[q][0] = texCoords[i*2];
  2220. rRoom->mesh.mQuads[j].texcoors[q][1] = texCoords[i*2+1];
  2221. }
  2222. // Partial alpha hack
  2223. if (flags & tombraiderFace_PartialAlpha)
  2224. {
  2225. //rRoom->mesh.colors[v].rgba[3] = 0.45;
  2226. }
  2227. }
  2228. if (flags & tombraiderFace_Alpha ||
  2229. flags & tombraiderFace_PartialAlpha)
  2230. {
  2231. rRoom->mesh.mQuads[j].cnum_alpha_quads++;
  2232. }
  2233. else
  2234. {
  2235. rRoom->mesh.mQuads[j].cnum_quads++;
  2236. }
  2237. }
  2238. #endif
  2239. // Room models
  2240. count = m_tombraider.getRoomModelCount(index);
  2241. r_mesh->models.reserve(count);
  2242. r_mesh->models.setError(0x0);
  2243. for (i = 0; i < count; ++i)
  2244. {
  2245. static_model_t *model = new static_model_t;
  2246. m_tombraider.getRoomModel(index, i,
  2247. &model->index, model->pos, &model->yaw);
  2248. r_mesh->models.pushBack(model);
  2249. }
  2250. // Room sprites
  2251. float spriteVertices[12];
  2252. float spriteTexCoords[8];
  2253. count = m_tombraider.getRoomSpriteCount(index);
  2254. r_mesh->sprites.reserve(count);
  2255. r_mesh->sprites.setError(0x0);
  2256. for (i = 0; i < count; ++i)
  2257. {
  2258. sprite_t *sprite = new sprite_t;
  2259. m_tombraider.getRoomSprite(index, i,
  2260. 10.0f, &sprite->texture, sprite->pos,
  2261. spriteVertices, spriteTexCoords);
  2262. sprite->texture += m_texOffset; // OpenRaider preloads some textures
  2263. sprite->vertex[0].pos[0] = spriteVertices[0];
  2264. sprite->vertex[0].pos[1] = spriteVertices[1];
  2265. sprite->vertex[0].pos[2] = spriteVertices[2];
  2266. sprite->vertex[1].pos[0] = spriteVertices[3];
  2267. sprite->vertex[1].pos[1] = spriteVertices[4];
  2268. sprite->vertex[1].pos[2] = spriteVertices[5];
  2269. sprite->vertex[2].pos[0] = spriteVertices[6];
  2270. sprite->vertex[2].pos[1] = spriteVertices[7];
  2271. sprite->vertex[2].pos[2] = spriteVertices[8];
  2272. sprite->vertex[3].pos[0] = spriteVertices[9];
  2273. sprite->vertex[3].pos[1] = spriteVertices[10];
  2274. sprite->vertex[3].pos[2] = spriteVertices[11];
  2275. sprite->texel[0].st[0] = spriteTexCoords[0];
  2276. sprite->texel[0].st[1] = spriteTexCoords[1];
  2277. sprite->texel[1].st[0] = spriteTexCoords[2];
  2278. sprite->texel[1].st[1] = spriteTexCoords[3];
  2279. sprite->texel[2].st[0] = spriteTexCoords[4];
  2280. sprite->texel[2].st[1] = spriteTexCoords[5];
  2281. sprite->texel[3].st[0] = spriteTexCoords[6];
  2282. sprite->texel[3].st[1] = spriteTexCoords[7];
  2283. r_mesh->sprites.pushBack(sprite);
  2284. }
  2285. gWorld.addRoom(r_mesh);
  2286. rRoom->room = r_mesh;
  2287. m_render.addRoom(rRoom);
  2288. printf(".");
  2289. fflush(stdout);
  2290. }
  2291. void OpenRaider::consoleCommand(char *cmd)
  2292. {
  2293. if (!cmd || !cmd[0])
  2294. return;
  2295. // Mongoose 2003.05.31, Strip off decp console prefix
  2296. if (cmd[0] == '>')
  2297. {
  2298. rc_command(">", cmd);
  2299. }
  2300. if (rc_command("quit", cmd))
  2301. {
  2302. shutdown(0);
  2303. }
  2304. else if (rc_command("md3", cmd))
  2305. {
  2306. #ifdef USING_MD3
  2307. m_render.loadMd3(cmd, "default");
  2308. print(true, "\nYou've found an Easter Egg!\n");
  2309. #else
  2310. print(true, "\nThis build isn't MD3 Easter Egg enabled\n");
  2311. #endif
  2312. }
  2313. else if (rc_command("port", cmd))
  2314. {
  2315. Network &net = *Network::Instance();
  2316. net.setPort(atoi(cmd));
  2317. }
  2318. else if (rc_command("killserver", cmd))
  2319. {
  2320. Network &net = *Network::Instance();
  2321. print(true, "Stopping network server...");
  2322. net.killServerThread();
  2323. }
  2324. else if (rc_command("server", cmd))
  2325. {
  2326. Network &net = *Network::Instance();
  2327. print(true, "Starting network server...");
  2328. net.spawnServerThread();
  2329. }
  2330. else if (rc_command("disconnect", cmd))
  2331. {
  2332. Network &net = *Network::Instance();
  2333. print(true, "Diconnecting...");
  2334. net.killClientThread();
  2335. }
  2336. else if (rc_command("connect", cmd))
  2337. {
  2338. Network &net = *Network::Instance();
  2339. print(true, "Connecting to %s...", cmd);
  2340. net.setRemoteHost(cmd);
  2341. net.spawnClientThread();
  2342. }
  2343. else if (rc_command("fly", cmd))
  2344. {
  2345. mNoClipping = worldMoveType_fly;
  2346. if (LARA)
  2347. {
  2348. LARA->moveType = worldMoveType_fly;
  2349. }
  2350. print(false, "World clipping is [SPACEY]");
  2351. }
  2352. else if (rc_command("walk", cmd))
  2353. {
  2354. mNoClipping = worldMoveType_walk;
  2355. if (LARA)
  2356. {
  2357. LARA->moveType = worldMoveType_walk;
  2358. }
  2359. print(false, "World clipping is [ON]");
  2360. }
  2361. else if (rc_command("ghost", cmd))
  2362. {
  2363. mNoClipping = worldMoveType_noClipping;
  2364. if (LARA)
  2365. {
  2366. LARA->moveType = worldMoveType_noClipping;
  2367. }
  2368. print(false, "World clipping is [OFF]");
  2369. }
  2370. else if (rc_command("mem", cmd))
  2371. {
  2372. #ifdef DEBUG_MEMEORY
  2373. if (rc_command("usage", cmd))
  2374. {
  2375. display_memory_usage();
  2376. }
  2377. else if (rc_command("report", cmd))
  2378. {
  2379. dump_memory_report();
  2380. }
  2381. #else
  2382. printf("This build isn't DEBUG_MEMEORY enabled\n");
  2383. #endif
  2384. }
  2385. else if (rc_command("loadlevel", cmd))
  2386. {
  2387. loadLevel(cmd);
  2388. }
  2389. else if (rc_command("play", cmd))
  2390. {
  2391. if (m_flags & OpenRaider_EnableSound)
  2392. {
  2393. mSound.play(atoi(cmd));
  2394. }
  2395. }
  2396. else if (rc_command("sensitivity.x", cmd))
  2397. {
  2398. m_mouseX = atof(cmd);
  2399. }
  2400. else if (rc_command("sensitivity.y", cmd))
  2401. {
  2402. m_mouseY = atof(cmd);
  2403. }
  2404. else if (rc_command("r_pigtails", cmd))
  2405. {
  2406. if (gLaraModel)
  2407. {
  2408. gLaraModel->pigtails = atoi(cmd);
  2409. if (gLaraModel->pigtails)
  2410. {
  2411. gLaraModel->ponyOff -= 20;
  2412. gLaraModel->ponytail[1] -= 32;
  2413. }
  2414. else
  2415. {
  2416. gLaraModel->ponyOff += 20;
  2417. gLaraModel->ponytail[1] += 32;
  2418. }
  2419. }
  2420. }
  2421. else if (rc_command("r_ponyangle", cmd))
  2422. {
  2423. if (gLaraModel)
  2424. {
  2425. gLaraModel->ponytailAngle = atoi(cmd);
  2426. }
  2427. }
  2428. else if (rc_command("r_ponyx", cmd))
  2429. {
  2430. if (gLaraModel)
  2431. {
  2432. gLaraModel->ponytail[0] = atoi(cmd);
  2433. }
  2434. }
  2435. else if (rc_command("r_ponyy", cmd))
  2436. {
  2437. if (gLaraModel)
  2438. {
  2439. gLaraModel->ponytail[1] = atoi(cmd);
  2440. }
  2441. }
  2442. else if (rc_command("r_ponyz", cmd))
  2443. {
  2444. if (gLaraModel)
  2445. {
  2446. gLaraModel->ponytail[2] = atoi(cmd);
  2447. }
  2448. }
  2449. else if (rc_command("r_animate", cmd))
  2450. {
  2451. if (atoi(cmd))
  2452. {
  2453. m_render.setFlags(Render::fAnimateAllModels);
  2454. print(false, "Animating all models");
  2455. }
  2456. else
  2457. {
  2458. m_render.clearFlags(Render::fAnimateAllModels);
  2459. print(false, "No longer animating all models");
  2460. }
  2461. }
  2462. else if (rc_command("r_ponytail", cmd))
  2463. {
  2464. if (atoi(cmd))
  2465. {
  2466. m_render.setFlags(Render::fRenderPonytail);
  2467. print(false, "Rendering ponytail");
  2468. }
  2469. else
  2470. {
  2471. m_render.clearFlags(Render::fRenderPonytail);
  2472. print(false, "No longer rendering ponytail");
  2473. }
  2474. }
  2475. else if (rc_command("r_light", cmd))
  2476. {
  2477. if (atoi(cmd))
  2478. {
  2479. m_render.setFlags(Render::fGL_Lights);
  2480. }
  2481. else
  2482. {
  2483. m_render.clearFlags(Render::fGL_Lights);
  2484. }
  2485. }
  2486. else if (rc_command("hop", cmd))
  2487. {
  2488. if (atoi(cmd))
  2489. {
  2490. gWorld.setFlag(World::fEnableHopping);
  2491. print(true, "Room hopping is on");
  2492. }
  2493. else
  2494. {
  2495. gWorld.clearFlag(World::fEnableHopping);
  2496. print(true, "Room hopping is off");
  2497. }
  2498. }
  2499. else if (rc_command("r_fog", cmd))
  2500. {
  2501. if (atoi(cmd))
  2502. {
  2503. m_render.setFlags(Render::fFog);
  2504. }
  2505. else
  2506. {
  2507. m_render.clearFlags(Render::fFog);
  2508. }
  2509. }
  2510. else if (rc_command("wireframe", cmd))
  2511. {
  2512. m_render.setMode(Render::modeWireframe);
  2513. print(false, "wireframe mode");
  2514. }
  2515. else if (rc_command("solid", cmd))
  2516. {
  2517. m_render.setMode(Render::modeSolid);
  2518. print(false, "solid mode");
  2519. }
  2520. else if (rc_command("texture", cmd))
  2521. {
  2522. m_render.setMode(Render::modeTexture);
  2523. print(false, "texture mode");
  2524. }
  2525. else if (rc_command("vertexlight", cmd))
  2526. {
  2527. m_render.setMode(Render::modeVertexLight);
  2528. print(false, "vertexlight mode");
  2529. }
  2530. else if (rc_command("titlescreen", cmd))
  2531. {
  2532. m_render.setMode(Render::modeLoadScreen);
  2533. print(false, "titlescreen mode");
  2534. }
  2535. else if (rc_command("r_viewmodel", cmd))
  2536. {
  2537. if (LARA)
  2538. {
  2539. SkeletalModel *smdl = (SkeletalModel *)LARA->tmpHook;
  2540. skeletal_model_t *mdl = gWorld.getModel(atoi(cmd));
  2541. if (smdl)
  2542. {
  2543. smdl->setModel(mdl);
  2544. }
  2545. }
  2546. //m_render.ViewModel(LARA, atoi(cmd));
  2547. }
  2548. else if (rc_command("r_oneroom", cmd))
  2549. {
  2550. if (atoi(cmd))
  2551. {
  2552. m_render.setFlags(Render::fOneRoom);
  2553. }
  2554. else
  2555. {
  2556. m_render.clearFlags(Render::fOneRoom);
  2557. }
  2558. }
  2559. else if (rc_command("r_allrooms", cmd))
  2560. {
  2561. if (atoi(cmd))
  2562. {
  2563. m_render.setFlags(Render::fAllRooms);
  2564. }
  2565. else
  2566. {
  2567. m_render.clearFlags(Render::fAllRooms);
  2568. }
  2569. print(true, "Rendering all rooms [%s]", (atoi(cmd) == 0) ? "off" : "on");
  2570. }
  2571. else if (rc_command("r_sprite", cmd))
  2572. {
  2573. if (atoi(cmd))
  2574. {
  2575. m_render.setFlags(Render::fSprites);
  2576. }
  2577. else
  2578. {
  2579. m_render.clearFlags(Render::fSprites);
  2580. }
  2581. }
  2582. else if (rc_command("r_roommodel", cmd))
  2583. {
  2584. if (atoi(cmd))
  2585. {
  2586. m_render.setFlags(Render::fRoomModels);
  2587. }
  2588. else
  2589. {
  2590. m_render.clearFlags(Render::fRoomModels);
  2591. }
  2592. }
  2593. else if (rc_command("r_entmodel", cmd))
  2594. {
  2595. if (atoi(cmd))
  2596. {
  2597. m_render.setFlags(Render::fEntityModels);
  2598. }
  2599. else
  2600. {
  2601. m_render.clearFlags(Render::fEntityModels);
  2602. }
  2603. }
  2604. else if (rc_command("r_particle", cmd))
  2605. {
  2606. if (atoi(cmd))
  2607. {
  2608. m_render.setFlags(Render::fParticles);
  2609. }
  2610. else
  2611. {
  2612. m_render.clearFlags(Render::fParticles);
  2613. }
  2614. }
  2615. else if (rc_command("r_vis", cmd))
  2616. {
  2617. if (atoi(cmd))
  2618. {
  2619. m_render.clearFlags(Render::fUsePortals);
  2620. }
  2621. else
  2622. {
  2623. m_render.clearFlags(Render::fUsePortals);
  2624. }
  2625. }
  2626. else if (rc_command("r_upf", cmd))
  2627. {
  2628. if (atoi(cmd))
  2629. {
  2630. m_render.setFlags(Render::fUpdateRoomListPerFrame);
  2631. }
  2632. else
  2633. {
  2634. m_render.clearFlags(Render::fUpdateRoomListPerFrame);
  2635. }
  2636. }
  2637. else if (rc_command("r_portal", cmd))
  2638. {
  2639. if (atoi(cmd))
  2640. {
  2641. m_render.setFlags(Render::fPortals);
  2642. }
  2643. else
  2644. {
  2645. m_render.clearFlags(Render::fPortals);
  2646. }
  2647. }
  2648. else if (rc_command("r_vmodel", cmd))
  2649. {
  2650. if (atoi(cmd))
  2651. {
  2652. m_render.setFlags(Render::fViewModel);
  2653. }
  2654. else
  2655. {
  2656. m_render.clearFlags(Render::fViewModel);
  2657. }
  2658. }
  2659. else if (rc_command("r_ralpha", cmd))
  2660. {
  2661. if (atoi(cmd))
  2662. {
  2663. m_render.setFlags(Render::fRoomAlpha);
  2664. }
  2665. else
  2666. {
  2667. m_render.clearFlags(Render::fRoomAlpha);
  2668. }
  2669. }
  2670. else if (rc_command("resize", cmd))
  2671. {
  2672. if (rc_command("xga", cmd))
  2673. {
  2674. resize(1024, 768);
  2675. m_render.Update(1024, 768);
  2676. }
  2677. else if (rc_command("svga", cmd))
  2678. {
  2679. resize(800, 600);
  2680. m_render.Update(800, 600);
  2681. }
  2682. else if (rc_command("vga", cmd))
  2683. {
  2684. resize(640, 460);
  2685. m_render.Update(640, 460);
  2686. }
  2687. }
  2688. else if (rc_command("sshot", cmd))
  2689. {
  2690. char sfilename[1024];
  2691. char *tmp = fullPath("~/.OpenRaider/sshots/", '/');
  2692. /* Not very pretty, but gets it done */
  2693. snprintf(sfilename, 1024, "%s%s", tmp, VERSION);
  2694. delete [] tmp;
  2695. m_render.screenShot(sfilename);
  2696. print(false, "Took screenshot");
  2697. }
  2698. else if (rc_command("fullscreen", cmd))
  2699. {
  2700. toggleFullscreen();
  2701. }
  2702. else if (rc_command("showfps", cmd))
  2703. {
  2704. m_flags |= OpenRaider_ShowFPS;
  2705. if (!atoi(cmd))
  2706. {
  2707. m_flags ^= OpenRaider_ShowFPS;
  2708. }
  2709. }
  2710. else if (rc_command("bind", cmd))
  2711. {
  2712. if (rc_command("+forward", cmd))
  2713. {
  2714. bindKeyCommand("+forward", atoi(cmd), OpenRaiderKey_forward);
  2715. }
  2716. else if (rc_command("+console", cmd))
  2717. {
  2718. bindKeyCommand("+console", atoi(cmd), OpenRaiderKey_console);
  2719. }
  2720. else if (rc_command("+backward", cmd))
  2721. {
  2722. bindKeyCommand("+backward", atoi(cmd), OpenRaiderKey_backward);
  2723. }
  2724. else if (rc_command("+jump", cmd))
  2725. {
  2726. bindKeyCommand("+jump", atoi(cmd), OpenRaiderKey_jump);
  2727. }
  2728. else if (rc_command("+crouch", cmd))
  2729. {
  2730. bindKeyCommand("+crouch", atoi(cmd), OpenRaiderKey_crouch);
  2731. }
  2732. else if (rc_command("+right", cmd))
  2733. {
  2734. bindKeyCommand("+right", atoi(cmd), OpenRaiderKey_right);
  2735. }
  2736. else if (rc_command("+left", cmd))
  2737. {
  2738. bindKeyCommand("+left", atoi(cmd), OpenRaiderKey_left);
  2739. }
  2740. else if (rc_command("+attack", cmd))
  2741. {
  2742. bindKeyCommand("+attack", atoi(cmd), OpenRaiderKey_attack);
  2743. }
  2744. }
  2745. else if (rc_command("set", cmd))
  2746. {
  2747. if (rc_command("mousegrab", cmd))
  2748. {
  2749. setGrabMouse(atoi(cmd));
  2750. print(true, "Mouse grabbing [%s]", atoi(cmd) ? "on" : "off");
  2751. }
  2752. }
  2753. else if (rc_command("stat", cmd))
  2754. {
  2755. if (rc_command("fps", cmd))
  2756. {
  2757. m_flags ^= OpenRaider_ShowFPS;
  2758. }
  2759. else if (rc_command("pos", cmd))
  2760. {
  2761. if (LARA)
  2762. {
  2763. print(true, "Room %2i Pos %.0f %.0f %.0f Yaw %.0f Pitch %.0f",
  2764. LARA->room,
  2765. LARA->pos[0], LARA->pos[1], LARA->pos[2],
  2766. helRadToDeg(LARA->angles[1]),
  2767. helRadToDeg(LARA->angles[2]));
  2768. }
  2769. }
  2770. else if (rc_command("room", cmd))
  2771. {
  2772. if (rc_command("flags", cmd))
  2773. {
  2774. if (LARA)
  2775. {
  2776. print(true, "Room[%i] flags: 0x%x",
  2777. LARA->room,
  2778. gWorld.getRoomInfo(LARA->room));
  2779. }
  2780. }
  2781. }
  2782. }
  2783. }
  2784. void OpenRaider::handleCommand(char *cmd, unsigned int mode)
  2785. {
  2786. bool b;
  2787. int i;
  2788. // So we can use switch stmt, translate the Ids
  2789. mode = mMode[mode];
  2790. switch (mode)
  2791. {
  2792. case 0: // [Video.OpenGL]
  2793. if (rc_command("Width", cmd))
  2794. {
  2795. m_width = atoi(cmd);
  2796. }
  2797. else if (rc_command("Height", cmd))
  2798. {
  2799. m_height = atoi(cmd);
  2800. }
  2801. else if (rc_command("FastCard", cmd))
  2802. {
  2803. rc_get_bool(cmd, &m_fastCard);
  2804. }
  2805. else if (rc_command("FullScreen", cmd))
  2806. {
  2807. rc_get_bool(cmd, &b);
  2808. m_flags |= OpenRaider_FullScreen;
  2809. if (!b)
  2810. {
  2811. m_flags ^= OpenRaider_FullScreen;
  2812. }
  2813. }
  2814. else if (rc_command("Font", cmd))
  2815. {
  2816. gFontFilename = fullPath(cmd, '/');
  2817. }
  2818. else if (rc_command("Driver", cmd))
  2819. {
  2820. if (cmd[0])
  2821. {
  2822. setDriverGL(cmd);
  2823. }
  2824. }
  2825. else
  2826. {
  2827. printf("Command> [Video.OpenGL] Unknown command '%s'\n", cmd);
  2828. }
  2829. break;
  2830. case 1: // [Audio.OpenAL]
  2831. if (rc_command("Enable", cmd))
  2832. {
  2833. rc_get_bool(cmd, &b);
  2834. m_flags |= OpenRaider_EnableSound;
  2835. if (!b)
  2836. {
  2837. m_flags ^= OpenRaider_EnableSound;
  2838. }
  2839. }
  2840. else
  2841. {
  2842. printf("Command> [Audio.OpenAL] Unknown command '%s'\n", cmd);
  2843. }
  2844. break;
  2845. case 2: // [OpenRaider.Engine]
  2846. if (rc_command("PakDir", cmd))
  2847. {
  2848. if (m_pakDir)
  2849. {
  2850. delete [] m_pakDir;
  2851. }
  2852. m_pakDir = fullPath(cmd, '/');
  2853. }
  2854. else if (rc_command("HomeDir", cmd))
  2855. {
  2856. if (m_homeDir)
  2857. {
  2858. delete [] m_homeDir;
  2859. }
  2860. i = strlen(cmd);
  2861. m_homeDir = fullPath(cmd, '/');
  2862. }
  2863. else if (rc_command("AudioDir", cmd))
  2864. {
  2865. if (m_audioDir)
  2866. {
  2867. delete [] m_audioDir;
  2868. }
  2869. m_audioDir = fullPath(cmd, '/');
  2870. }
  2871. else if (rc_command("MapDebug", cmd))
  2872. {
  2873. rc_get_bool(cmd, &b);
  2874. m_flags |= OpenRaider_DebugMap;
  2875. if (!b)
  2876. {
  2877. m_flags ^= OpenRaider_DebugMap;
  2878. }
  2879. }
  2880. else if (rc_command("Map", cmd))
  2881. {
  2882. if (cmd[0])
  2883. {
  2884. char *fullPathMap;
  2885. fullPathMap = bufferString("%s%s", m_pakDir, cmd);
  2886. if (m_tombraider.checkMime(fullPathMap) == 0)
  2887. {
  2888. printf("Validated pak: '%s'\n",
  2889. fullPathMap);
  2890. delete [] fullPathMap;
  2891. /* Just load relative filename */
  2892. mMapList.pushBack(bufferString("%s", cmd));
  2893. }
  2894. else
  2895. {
  2896. printf("ERROR: pak file '%s' not found or invalid\n",
  2897. fullPathMap);
  2898. delete [] fullPathMap;
  2899. }
  2900. }
  2901. }
  2902. // Mongoose 2001.12.31, Added music list back
  2903. else if (rc_command("Music", cmd))
  2904. {
  2905. if (cmd[0])
  2906. {
  2907. char *music;
  2908. i = strlen(cmd);
  2909. music = new char[i+1];
  2910. strncpy(music, cmd, i);
  2911. music[i] = 0;
  2912. mMusicList.pushBack(music);
  2913. }
  2914. }
  2915. else if (rc_command("DisplayFPS", cmd))
  2916. {
  2917. rc_get_bool(cmd, &b);
  2918. m_flags |= OpenRaider_ShowFPS;
  2919. if (!b)
  2920. {
  2921. m_flags ^= OpenRaider_ShowFPS;
  2922. }
  2923. }
  2924. else if (rc_command("ModelDebug", cmd))
  2925. {
  2926. rc_get_bool(cmd, &b);
  2927. m_flags |= OpenRaider_DebugModel;
  2928. if (!b)
  2929. {
  2930. m_flags ^= OpenRaider_DebugModel;
  2931. }
  2932. }
  2933. else if (rc_command("DumpTexture", cmd))
  2934. {
  2935. rc_get_bool(cmd, &b);
  2936. m_flags |= OpenRaider_DumpTexture;
  2937. if (!b)
  2938. {
  2939. m_flags ^= OpenRaider_DumpTexture;
  2940. }
  2941. }
  2942. else
  2943. {
  2944. printf("Command> [OpenRaider.Engine] Unknown command '%s'\n", cmd);
  2945. }
  2946. break;
  2947. case 3: // [Input.Mouse]
  2948. if (rc_command("SensitivityX", cmd))
  2949. {
  2950. m_mouseX = atof(cmd);
  2951. }
  2952. else if (rc_command("SensitivityY", cmd))
  2953. {
  2954. m_mouseY = atof(cmd);
  2955. }
  2956. else
  2957. {
  2958. printf("Command> [Input.Mouse] Unknown command '%s'\n", cmd);
  2959. }
  2960. break;
  2961. case 4:
  2962. if (cmd[1] == '.')
  2963. {
  2964. cmd[0] = '>';
  2965. cmd[1] = ' ';
  2966. for (i = strlen(cmd) - 1; i >= 0; --i)
  2967. {
  2968. if (cmd[i] == '.' || cmd[i] == '=')
  2969. {
  2970. cmd[i] = ' ';
  2971. }
  2972. }
  2973. }
  2974. consoleCommand(cmd);
  2975. break;
  2976. case 5:
  2977. if (rc_command("Enable", cmd))
  2978. {
  2979. rc_get_bool(cmd, &gStartServer);
  2980. }
  2981. else if (rc_command("Port", cmd))
  2982. {
  2983. if (gStartServer)
  2984. {
  2985. Network &net = *Network::Instance();
  2986. int port = atoi(cmd);
  2987. net.setPort(port);
  2988. print(true, "Starting network server on port %i...", port);
  2989. net.spawnServerThread();
  2990. }
  2991. }
  2992. else
  2993. {
  2994. printf("Command> [Network.Server] '%s' not implemented\n", cmd);
  2995. }
  2996. break;
  2997. }
  2998. }
  2999. int main(int argc, char *argv[])
  3000. {
  3001. OpenRaider *game = OpenRaider::Instance();
  3002. atexit(killOpenRaiderSingleton);
  3003. game->start();
  3004. return 0;
  3005. }