Cinematic.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #define JPEG_INTERNALS
  23. extern "C" {
  24. #include "jpeg-6/jpeglib.h"
  25. }
  26. #include "tr_local.h"
  27. #define CIN_system 1
  28. #define CIN_loop 2
  29. #define CIN_hold 4
  30. #define CIN_silent 8
  31. #define CIN_shader 16
  32. class idCinematicLocal : public idCinematic {
  33. public:
  34. idCinematicLocal();
  35. virtual ~idCinematicLocal();
  36. virtual bool InitFromFile( const char *qpath, bool looping );
  37. virtual cinData_t ImageForTime( int milliseconds );
  38. virtual int AnimationLength();
  39. virtual void Close();
  40. virtual void ResetTime(int time);
  41. private:
  42. unsigned int mcomp[256];
  43. byte ** qStatus[2];
  44. idStr fileName;
  45. int CIN_WIDTH, CIN_HEIGHT;
  46. idFile * iFile;
  47. cinStatus_t status;
  48. long tfps;
  49. long RoQPlayed;
  50. long ROQSize;
  51. unsigned int RoQFrameSize;
  52. long onQuad;
  53. long numQuads;
  54. long samplesPerLine;
  55. unsigned int roq_id;
  56. long screenDelta;
  57. byte * buf;
  58. long samplesPerPixel; // defaults to 2
  59. unsigned int xsize, ysize, maxsize, minsize;
  60. long normalBuffer0;
  61. long roq_flags;
  62. long roqF0;
  63. long roqF1;
  64. long t[2];
  65. long roqFPS;
  66. long drawX, drawY;
  67. int animationLength;
  68. int startTime;
  69. float frameRate;
  70. byte * image;
  71. bool looping;
  72. bool dirty;
  73. bool half;
  74. bool smootheddouble;
  75. bool inMemory;
  76. void RoQ_init( void );
  77. void blitVQQuad32fs( byte **status, unsigned char *data );
  78. void RoQShutdown( void );
  79. void RoQInterrupt(void);
  80. void move8_32( byte *src, byte *dst, int spl );
  81. void move4_32( byte *src, byte *dst, int spl );
  82. void blit8_32( byte *src, byte *dst, int spl );
  83. void blit4_32( byte *src, byte *dst, int spl );
  84. void blit2_32( byte *src, byte *dst, int spl );
  85. unsigned short yuv_to_rgb( long y, long u, long v );
  86. unsigned int yuv_to_rgb24( long y, long u, long v );
  87. void decodeCodeBook( byte *input, unsigned short roq_flags );
  88. void recurseQuad( long startX, long startY, long quadSize, long xOff, long yOff );
  89. void setupQuad( long xOff, long yOff );
  90. void readQuadInfo( byte *qData );
  91. void RoQPrepMcomp( long xoff, long yoff );
  92. void RoQReset();
  93. };
  94. const int DEFAULT_CIN_WIDTH = 512;
  95. const int DEFAULT_CIN_HEIGHT = 512;
  96. const int MAXSIZE = 8;
  97. const int MINSIZE = 4;
  98. const int ROQ_FILE = 0x1084;
  99. const int ROQ_QUAD = 0x1000;
  100. const int ROQ_QUAD_INFO = 0x1001;
  101. const int ROQ_CODEBOOK = 0x1002;
  102. const int ROQ_QUAD_VQ = 0x1011;
  103. const int ROQ_QUAD_JPEG = 0x1012;
  104. const int ROQ_QUAD_HANG = 0x1013;
  105. const int ROQ_PACKET = 0x1030;
  106. const int ZA_SOUND_MONO = 0x1020;
  107. const int ZA_SOUND_STEREO = 0x1021;
  108. // temporary buffers used by all cinematics
  109. static long ROQ_YY_tab[256];
  110. static long ROQ_UB_tab[256];
  111. static long ROQ_UG_tab[256];
  112. static long ROQ_VG_tab[256];
  113. static long ROQ_VR_tab[256];
  114. static byte * file = NULL;
  115. static unsigned short * vq2 = NULL;
  116. static unsigned short * vq4 = NULL;
  117. static unsigned short * vq8 = NULL;
  118. //===========================================
  119. /*
  120. ==============
  121. idCinematicLocal::InitCinematic
  122. ==============
  123. */
  124. void idCinematic::InitCinematic( void ) {
  125. float t_ub,t_vr,t_ug,t_vg;
  126. long i;
  127. // generate YUV tables
  128. t_ub = (1.77200f/2.0f) * (float)(1<<6) + 0.5f;
  129. t_vr = (1.40200f/2.0f) * (float)(1<<6) + 0.5f;
  130. t_ug = (0.34414f/2.0f) * (float)(1<<6) + 0.5f;
  131. t_vg = (0.71414f/2.0f) * (float)(1<<6) + 0.5f;
  132. for( i = 0; i < 256; i++ ) {
  133. float x = (float)(2 * i - 255);
  134. ROQ_UB_tab[i] = (long)( ( t_ub * x) + (1<<5));
  135. ROQ_VR_tab[i] = (long)( ( t_vr * x) + (1<<5));
  136. ROQ_UG_tab[i] = (long)( (-t_ug * x) );
  137. ROQ_VG_tab[i] = (long)( (-t_vg * x) + (1<<5));
  138. ROQ_YY_tab[i] = (long)( (i << 6) | (i >> 2) );
  139. }
  140. file = (byte *)Mem_Alloc( 65536 );
  141. vq2 = (word *)Mem_Alloc( 256*16*4 * sizeof( word ) );
  142. vq4 = (word *)Mem_Alloc( 256*64*4 * sizeof( word ) );
  143. vq8 = (word *)Mem_Alloc( 256*256*4 * sizeof( word ) );
  144. }
  145. /*
  146. ==============
  147. idCinematicLocal::ShutdownCinematic
  148. ==============
  149. */
  150. void idCinematic::ShutdownCinematic( void ) {
  151. Mem_Free( file );
  152. file = NULL;
  153. Mem_Free( vq2 );
  154. vq2 = NULL;
  155. Mem_Free( vq4 );
  156. vq4 = NULL;
  157. Mem_Free( vq8 );
  158. vq8 = NULL;
  159. }
  160. /*
  161. ==============
  162. idCinematicLocal::Alloc
  163. ==============
  164. */
  165. idCinematic *idCinematic::Alloc() {
  166. return new idCinematicLocal;
  167. }
  168. /*
  169. ==============
  170. idCinematicLocal::~idCinematic
  171. ==============
  172. */
  173. idCinematic::~idCinematic( ) {
  174. Close();
  175. }
  176. /*
  177. ==============
  178. idCinematicLocal::InitFromFile
  179. ==============
  180. */
  181. bool idCinematic::InitFromFile( const char *qpath, bool looping ) {
  182. return false;
  183. }
  184. /*
  185. ==============
  186. idCinematicLocal::AnimationLength
  187. ==============
  188. */
  189. int idCinematic::AnimationLength() {
  190. return 0;
  191. }
  192. /*
  193. ==============
  194. idCinematicLocal::ResetTime
  195. ==============
  196. */
  197. void idCinematic::ResetTime(int milliseconds) {
  198. }
  199. /*
  200. ==============
  201. idCinematicLocal::ImageForTime
  202. ==============
  203. */
  204. cinData_t idCinematic::ImageForTime( int milliseconds ) {
  205. cinData_t c;
  206. memset( &c, 0, sizeof( c ) );
  207. return c;
  208. }
  209. /*
  210. ==============
  211. idCinematicLocal::Close
  212. ==============
  213. */
  214. void idCinematic::Close() {
  215. }
  216. //===========================================
  217. /*
  218. ==============
  219. idCinematicLocal::idCinematicLocal
  220. ==============
  221. */
  222. idCinematicLocal::idCinematicLocal() {
  223. image = NULL;
  224. status = FMV_EOF;
  225. buf = NULL;
  226. iFile = NULL;
  227. qStatus[0] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) );
  228. qStatus[1] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) );
  229. }
  230. /*
  231. ==============
  232. idCinematicLocal::~idCinematicLocal
  233. ==============
  234. */
  235. idCinematicLocal::~idCinematicLocal() {
  236. Close();
  237. Mem_Free( qStatus[0] );
  238. qStatus[0] = NULL;
  239. Mem_Free( qStatus[1] );
  240. qStatus[1] = NULL;
  241. }
  242. /*
  243. ==============
  244. idCinematicLocal::InitFromFile
  245. ==============
  246. */
  247. bool idCinematicLocal::InitFromFile( const char *qpath, bool amilooping ) {
  248. unsigned short RoQID;
  249. Close();
  250. inMemory = 0;
  251. animationLength = 100000;
  252. if ( strstr( qpath, "/" ) == NULL && strstr( qpath, "\\" ) == NULL ) {
  253. sprintf( fileName, "video/%s", qpath );
  254. } else {
  255. sprintf( fileName, "%s", qpath );
  256. }
  257. iFile = fileSystem->OpenFileRead( fileName );
  258. if ( !iFile ) {
  259. return false;
  260. }
  261. ROQSize = iFile->Length();
  262. looping = amilooping;
  263. CIN_HEIGHT = DEFAULT_CIN_HEIGHT;
  264. CIN_WIDTH = DEFAULT_CIN_WIDTH;
  265. samplesPerPixel = 4;
  266. startTime = 0; //Sys_Milliseconds();
  267. buf = NULL;
  268. iFile->Read( file, 16 );
  269. RoQID = (unsigned short)(file[0]) + (unsigned short)(file[1])*256;
  270. frameRate = file[6];
  271. if ( frameRate == 32.0f ) {
  272. frameRate = 1000.0f / 32.0f;
  273. }
  274. if ( RoQID == ROQ_FILE ) {
  275. RoQ_init();
  276. status = FMV_PLAY;
  277. ImageForTime( 0 );
  278. status = ( looping ) ? FMV_PLAY : FMV_IDLE;
  279. return true;
  280. }
  281. RoQShutdown();
  282. return false;
  283. }
  284. /*
  285. ==============
  286. idCinematicLocal::Close
  287. ==============
  288. */
  289. void idCinematicLocal::Close() {
  290. if ( image ) {
  291. Mem_Free( (void *)image );
  292. image = NULL;
  293. buf = NULL;
  294. status = FMV_EOF;
  295. }
  296. RoQShutdown();
  297. }
  298. /*
  299. ==============
  300. idCinematicLocal::AnimationLength
  301. ==============
  302. */
  303. int idCinematicLocal::AnimationLength() {
  304. return animationLength;
  305. }
  306. /*
  307. ==============
  308. idCinematicLocal::ResetTime
  309. ==============
  310. */
  311. void idCinematicLocal::ResetTime(int time) {
  312. startTime = ( backEnd.viewDef ) ? 1000 * backEnd.viewDef->floatTime : -1;
  313. status = FMV_PLAY;
  314. }
  315. /*
  316. ==============
  317. idCinematicLocal::ImageForTime
  318. ==============
  319. */
  320. cinData_t idCinematicLocal::ImageForTime( int thisTime ) {
  321. cinData_t cinData;
  322. if ( thisTime < 0 ) {
  323. thisTime = 0;
  324. }
  325. memset( &cinData, 0, sizeof(cinData) );
  326. if ( r_skipROQ.GetBool() ) {
  327. return cinData;
  328. }
  329. if ( status == FMV_EOF || status == FMV_IDLE ) {
  330. return cinData;
  331. }
  332. if ( buf == NULL || startTime == -1 ) {
  333. if ( startTime == -1 ) {
  334. RoQReset();
  335. }
  336. startTime = thisTime;
  337. }
  338. tfps = ( ( thisTime - startTime ) * frameRate ) / 1000;
  339. if ( tfps < 0 ) {
  340. tfps = 0;
  341. }
  342. if ( tfps < numQuads ) {
  343. RoQReset();
  344. buf = NULL;
  345. status = FMV_PLAY;
  346. }
  347. if ( buf == NULL ) {
  348. while( buf == NULL ) {
  349. RoQInterrupt();
  350. }
  351. } else {
  352. while( (tfps != numQuads && status == FMV_PLAY) ) {
  353. RoQInterrupt();
  354. }
  355. }
  356. if ( status == FMV_LOOPED ) {
  357. status = FMV_PLAY;
  358. while( buf == NULL && status == FMV_PLAY ) {
  359. RoQInterrupt();
  360. }
  361. startTime = thisTime;
  362. }
  363. if ( status == FMV_EOF ) {
  364. if ( looping ) {
  365. RoQReset();
  366. buf = NULL;
  367. if ( status == FMV_LOOPED ) {
  368. status = FMV_PLAY;
  369. }
  370. while ( buf == NULL && status == FMV_PLAY ) {
  371. RoQInterrupt();
  372. }
  373. startTime = thisTime;
  374. } else {
  375. status = FMV_IDLE;
  376. RoQShutdown();
  377. }
  378. }
  379. cinData.imageWidth = CIN_WIDTH;
  380. cinData.imageHeight = CIN_HEIGHT;
  381. cinData.status = status;
  382. cinData.image = buf;
  383. return cinData;
  384. }
  385. /*
  386. ==============
  387. idCinematicLocal::move8_32
  388. ==============
  389. */
  390. void idCinematicLocal::move8_32( byte *src, byte *dst, int spl ) {
  391. #if 1
  392. int *dsrc, *ddst;
  393. int dspl;
  394. dsrc = (int *)src;
  395. ddst = (int *)dst;
  396. dspl = spl>>2;
  397. ddst[0*dspl+0] = dsrc[0*dspl+0];
  398. ddst[0*dspl+1] = dsrc[0*dspl+1];
  399. ddst[0*dspl+2] = dsrc[0*dspl+2];
  400. ddst[0*dspl+3] = dsrc[0*dspl+3];
  401. ddst[0*dspl+4] = dsrc[0*dspl+4];
  402. ddst[0*dspl+5] = dsrc[0*dspl+5];
  403. ddst[0*dspl+6] = dsrc[0*dspl+6];
  404. ddst[0*dspl+7] = dsrc[0*dspl+7];
  405. ddst[1*dspl+0] = dsrc[1*dspl+0];
  406. ddst[1*dspl+1] = dsrc[1*dspl+1];
  407. ddst[1*dspl+2] = dsrc[1*dspl+2];
  408. ddst[1*dspl+3] = dsrc[1*dspl+3];
  409. ddst[1*dspl+4] = dsrc[1*dspl+4];
  410. ddst[1*dspl+5] = dsrc[1*dspl+5];
  411. ddst[1*dspl+6] = dsrc[1*dspl+6];
  412. ddst[1*dspl+7] = dsrc[1*dspl+7];
  413. ddst[2*dspl+0] = dsrc[2*dspl+0];
  414. ddst[2*dspl+1] = dsrc[2*dspl+1];
  415. ddst[2*dspl+2] = dsrc[2*dspl+2];
  416. ddst[2*dspl+3] = dsrc[2*dspl+3];
  417. ddst[2*dspl+4] = dsrc[2*dspl+4];
  418. ddst[2*dspl+5] = dsrc[2*dspl+5];
  419. ddst[2*dspl+6] = dsrc[2*dspl+6];
  420. ddst[2*dspl+7] = dsrc[2*dspl+7];
  421. ddst[3*dspl+0] = dsrc[3*dspl+0];
  422. ddst[3*dspl+1] = dsrc[3*dspl+1];
  423. ddst[3*dspl+2] = dsrc[3*dspl+2];
  424. ddst[3*dspl+3] = dsrc[3*dspl+3];
  425. ddst[3*dspl+4] = dsrc[3*dspl+4];
  426. ddst[3*dspl+5] = dsrc[3*dspl+5];
  427. ddst[3*dspl+6] = dsrc[3*dspl+6];
  428. ddst[3*dspl+7] = dsrc[3*dspl+7];
  429. ddst[4*dspl+0] = dsrc[4*dspl+0];
  430. ddst[4*dspl+1] = dsrc[4*dspl+1];
  431. ddst[4*dspl+2] = dsrc[4*dspl+2];
  432. ddst[4*dspl+3] = dsrc[4*dspl+3];
  433. ddst[4*dspl+4] = dsrc[4*dspl+4];
  434. ddst[4*dspl+5] = dsrc[4*dspl+5];
  435. ddst[4*dspl+6] = dsrc[4*dspl+6];
  436. ddst[4*dspl+7] = dsrc[4*dspl+7];
  437. ddst[5*dspl+0] = dsrc[5*dspl+0];
  438. ddst[5*dspl+1] = dsrc[5*dspl+1];
  439. ddst[5*dspl+2] = dsrc[5*dspl+2];
  440. ddst[5*dspl+3] = dsrc[5*dspl+3];
  441. ddst[5*dspl+4] = dsrc[5*dspl+4];
  442. ddst[5*dspl+5] = dsrc[5*dspl+5];
  443. ddst[5*dspl+6] = dsrc[5*dspl+6];
  444. ddst[5*dspl+7] = dsrc[5*dspl+7];
  445. ddst[6*dspl+0] = dsrc[6*dspl+0];
  446. ddst[6*dspl+1] = dsrc[6*dspl+1];
  447. ddst[6*dspl+2] = dsrc[6*dspl+2];
  448. ddst[6*dspl+3] = dsrc[6*dspl+3];
  449. ddst[6*dspl+4] = dsrc[6*dspl+4];
  450. ddst[6*dspl+5] = dsrc[6*dspl+5];
  451. ddst[6*dspl+6] = dsrc[6*dspl+6];
  452. ddst[6*dspl+7] = dsrc[6*dspl+7];
  453. ddst[7*dspl+0] = dsrc[7*dspl+0];
  454. ddst[7*dspl+1] = dsrc[7*dspl+1];
  455. ddst[7*dspl+2] = dsrc[7*dspl+2];
  456. ddst[7*dspl+3] = dsrc[7*dspl+3];
  457. ddst[7*dspl+4] = dsrc[7*dspl+4];
  458. ddst[7*dspl+5] = dsrc[7*dspl+5];
  459. ddst[7*dspl+6] = dsrc[7*dspl+6];
  460. ddst[7*dspl+7] = dsrc[7*dspl+7];
  461. #else
  462. double *dsrc, *ddst;
  463. int dspl;
  464. dsrc = (double *)src;
  465. ddst = (double *)dst;
  466. dspl = spl>>3;
  467. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  468. dsrc += dspl; ddst += dspl;
  469. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  470. dsrc += dspl; ddst += dspl;
  471. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  472. dsrc += dspl; ddst += dspl;
  473. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  474. dsrc += dspl; ddst += dspl;
  475. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  476. dsrc += dspl; ddst += dspl;
  477. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  478. dsrc += dspl; ddst += dspl;
  479. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  480. dsrc += dspl; ddst += dspl;
  481. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  482. #endif
  483. }
  484. /*
  485. ==============
  486. idCinematicLocal::move4_32
  487. ==============
  488. */
  489. void idCinematicLocal::move4_32( byte *src, byte *dst, int spl ) {
  490. #if 1
  491. int *dsrc, *ddst;
  492. int dspl;
  493. dsrc = (int *)src;
  494. ddst = (int *)dst;
  495. dspl = spl>>2;
  496. ddst[0*dspl+0] = dsrc[0*dspl+0];
  497. ddst[0*dspl+1] = dsrc[0*dspl+1];
  498. ddst[0*dspl+2] = dsrc[0*dspl+2];
  499. ddst[0*dspl+3] = dsrc[0*dspl+3];
  500. ddst[1*dspl+0] = dsrc[1*dspl+0];
  501. ddst[1*dspl+1] = dsrc[1*dspl+1];
  502. ddst[1*dspl+2] = dsrc[1*dspl+2];
  503. ddst[1*dspl+3] = dsrc[1*dspl+3];
  504. ddst[2*dspl+0] = dsrc[2*dspl+0];
  505. ddst[2*dspl+1] = dsrc[2*dspl+1];
  506. ddst[2*dspl+2] = dsrc[2*dspl+2];
  507. ddst[2*dspl+3] = dsrc[2*dspl+3];
  508. ddst[3*dspl+0] = dsrc[3*dspl+0];
  509. ddst[3*dspl+1] = dsrc[3*dspl+1];
  510. ddst[3*dspl+2] = dsrc[3*dspl+2];
  511. ddst[3*dspl+3] = dsrc[3*dspl+3];
  512. #else
  513. double *dsrc, *ddst;
  514. int dspl;
  515. dsrc = (double *)src;
  516. ddst = (double *)dst;
  517. dspl = spl>>3;
  518. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  519. dsrc += dspl; ddst += dspl;
  520. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  521. dsrc += dspl; ddst += dspl;
  522. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  523. dsrc += dspl; ddst += dspl;
  524. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  525. #endif
  526. }
  527. /*
  528. ==============
  529. idCinematicLocal::blit8_32
  530. ==============
  531. */
  532. void idCinematicLocal::blit8_32( byte *src, byte *dst, int spl ) {
  533. #if 1
  534. int *dsrc, *ddst;
  535. int dspl;
  536. dsrc = (int *)src;
  537. ddst = (int *)dst;
  538. dspl = spl>>2;
  539. ddst[0*dspl+0] = dsrc[ 0];
  540. ddst[0*dspl+1] = dsrc[ 1];
  541. ddst[0*dspl+2] = dsrc[ 2];
  542. ddst[0*dspl+3] = dsrc[ 3];
  543. ddst[0*dspl+4] = dsrc[ 4];
  544. ddst[0*dspl+5] = dsrc[ 5];
  545. ddst[0*dspl+6] = dsrc[ 6];
  546. ddst[0*dspl+7] = dsrc[ 7];
  547. ddst[1*dspl+0] = dsrc[ 8];
  548. ddst[1*dspl+1] = dsrc[ 9];
  549. ddst[1*dspl+2] = dsrc[10];
  550. ddst[1*dspl+3] = dsrc[11];
  551. ddst[1*dspl+4] = dsrc[12];
  552. ddst[1*dspl+5] = dsrc[13];
  553. ddst[1*dspl+6] = dsrc[14];
  554. ddst[1*dspl+7] = dsrc[15];
  555. ddst[2*dspl+0] = dsrc[16];
  556. ddst[2*dspl+1] = dsrc[17];
  557. ddst[2*dspl+2] = dsrc[18];
  558. ddst[2*dspl+3] = dsrc[19];
  559. ddst[2*dspl+4] = dsrc[20];
  560. ddst[2*dspl+5] = dsrc[21];
  561. ddst[2*dspl+6] = dsrc[22];
  562. ddst[2*dspl+7] = dsrc[23];
  563. ddst[3*dspl+0] = dsrc[24];
  564. ddst[3*dspl+1] = dsrc[25];
  565. ddst[3*dspl+2] = dsrc[26];
  566. ddst[3*dspl+3] = dsrc[27];
  567. ddst[3*dspl+4] = dsrc[28];
  568. ddst[3*dspl+5] = dsrc[29];
  569. ddst[3*dspl+6] = dsrc[30];
  570. ddst[3*dspl+7] = dsrc[31];
  571. ddst[4*dspl+0] = dsrc[32];
  572. ddst[4*dspl+1] = dsrc[33];
  573. ddst[4*dspl+2] = dsrc[34];
  574. ddst[4*dspl+3] = dsrc[35];
  575. ddst[4*dspl+4] = dsrc[36];
  576. ddst[4*dspl+5] = dsrc[37];
  577. ddst[4*dspl+6] = dsrc[38];
  578. ddst[4*dspl+7] = dsrc[39];
  579. ddst[5*dspl+0] = dsrc[40];
  580. ddst[5*dspl+1] = dsrc[41];
  581. ddst[5*dspl+2] = dsrc[42];
  582. ddst[5*dspl+3] = dsrc[43];
  583. ddst[5*dspl+4] = dsrc[44];
  584. ddst[5*dspl+5] = dsrc[45];
  585. ddst[5*dspl+6] = dsrc[46];
  586. ddst[5*dspl+7] = dsrc[47];
  587. ddst[6*dspl+0] = dsrc[48];
  588. ddst[6*dspl+1] = dsrc[49];
  589. ddst[6*dspl+2] = dsrc[50];
  590. ddst[6*dspl+3] = dsrc[51];
  591. ddst[6*dspl+4] = dsrc[52];
  592. ddst[6*dspl+5] = dsrc[53];
  593. ddst[6*dspl+6] = dsrc[54];
  594. ddst[6*dspl+7] = dsrc[55];
  595. ddst[7*dspl+0] = dsrc[56];
  596. ddst[7*dspl+1] = dsrc[57];
  597. ddst[7*dspl+2] = dsrc[58];
  598. ddst[7*dspl+3] = dsrc[59];
  599. ddst[7*dspl+4] = dsrc[60];
  600. ddst[7*dspl+5] = dsrc[61];
  601. ddst[7*dspl+6] = dsrc[62];
  602. ddst[7*dspl+7] = dsrc[63];
  603. #else
  604. double *dsrc, *ddst;
  605. int dspl;
  606. dsrc = (double *)src;
  607. ddst = (double *)dst;
  608. dspl = spl>>3;
  609. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  610. dsrc += 4; ddst += dspl;
  611. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  612. dsrc += 4; ddst += dspl;
  613. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  614. dsrc += 4; ddst += dspl;
  615. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  616. dsrc += 4; ddst += dspl;
  617. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  618. dsrc += 4; ddst += dspl;
  619. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  620. dsrc += 4; ddst += dspl;
  621. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  622. dsrc += 4; ddst += dspl;
  623. ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
  624. #endif
  625. }
  626. /*
  627. ==============
  628. idCinematicLocal::blit4_32
  629. ==============
  630. */
  631. void idCinematicLocal::blit4_32( byte *src, byte *dst, int spl ) {
  632. #if 1
  633. int *dsrc, *ddst;
  634. int dspl;
  635. dsrc = (int *)src;
  636. ddst = (int *)dst;
  637. dspl = spl>>2;
  638. ddst[0*dspl+0] = dsrc[ 0];
  639. ddst[0*dspl+1] = dsrc[ 1];
  640. ddst[0*dspl+2] = dsrc[ 2];
  641. ddst[0*dspl+3] = dsrc[ 3];
  642. ddst[1*dspl+0] = dsrc[ 4];
  643. ddst[1*dspl+1] = dsrc[ 5];
  644. ddst[1*dspl+2] = dsrc[ 6];
  645. ddst[1*dspl+3] = dsrc[ 7];
  646. ddst[2*dspl+0] = dsrc[ 8];
  647. ddst[2*dspl+1] = dsrc[ 9];
  648. ddst[2*dspl+2] = dsrc[10];
  649. ddst[2*dspl+3] = dsrc[11];
  650. ddst[3*dspl+0] = dsrc[12];
  651. ddst[3*dspl+1] = dsrc[13];
  652. ddst[3*dspl+2] = dsrc[14];
  653. ddst[3*dspl+3] = dsrc[15];
  654. #else
  655. double *dsrc, *ddst;
  656. int dspl;
  657. dsrc = (double *)src;
  658. ddst = (double *)dst;
  659. dspl = spl>>3;
  660. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  661. dsrc += 2; ddst += dspl;
  662. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  663. dsrc += 2; ddst += dspl;
  664. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  665. dsrc += 2; ddst += dspl;
  666. ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
  667. #endif
  668. }
  669. /*
  670. ==============
  671. idCinematicLocal::blit2_32
  672. ==============
  673. */
  674. void idCinematicLocal::blit2_32( byte *src, byte *dst, int spl ) {
  675. #if 1
  676. int *dsrc, *ddst;
  677. int dspl;
  678. dsrc = (int *)src;
  679. ddst = (int *)dst;
  680. dspl = spl>>2;
  681. ddst[0*dspl+0] = dsrc[0];
  682. ddst[0*dspl+1] = dsrc[1];
  683. ddst[1*dspl+0] = dsrc[2];
  684. ddst[1*dspl+1] = dsrc[3];
  685. #else
  686. double *dsrc, *ddst;
  687. int dspl;
  688. dsrc = (double *)src;
  689. ddst = (double *)dst;
  690. dspl = spl>>3;
  691. ddst[0] = dsrc[0];
  692. ddst[dspl] = dsrc[1];
  693. #endif
  694. }
  695. /*
  696. ==============
  697. idCinematicLocal::blitVQQuad32fs
  698. ==============
  699. */
  700. void idCinematicLocal::blitVQQuad32fs( byte **status, unsigned char *data ) {
  701. unsigned short newd, celdata, code;
  702. unsigned int index, i;
  703. newd = 0;
  704. celdata = 0;
  705. index = 0;
  706. do {
  707. if (!newd) {
  708. newd = 7;
  709. celdata = data[0] + data[1]*256;
  710. data += 2;
  711. } else {
  712. newd--;
  713. }
  714. code = (unsigned short)(celdata&0xc000);
  715. celdata <<= 2;
  716. switch (code) {
  717. case 0x8000: // vq code
  718. blit8_32( (byte *)&vq8[(*data)*128], status[index], samplesPerLine );
  719. data++;
  720. index += 5;
  721. break;
  722. case 0xc000: // drop
  723. index++; // skip 8x8
  724. for(i=0;i<4;i++) {
  725. if (!newd) {
  726. newd = 7;
  727. celdata = data[0] + data[1]*256;
  728. data += 2;
  729. } else {
  730. newd--;
  731. }
  732. code = (unsigned short)(celdata&0xc000); celdata <<= 2;
  733. switch (code) { // code in top two bits of code
  734. case 0x8000: // 4x4 vq code
  735. blit4_32( (byte *)&vq4[(*data)*32], status[index], samplesPerLine );
  736. data++;
  737. break;
  738. case 0xc000: // 2x2 vq code
  739. blit2_32( (byte *)&vq2[(*data)*8], status[index], samplesPerLine );
  740. data++;
  741. blit2_32( (byte *)&vq2[(*data)*8], status[index]+8, samplesPerLine );
  742. data++;
  743. blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2, samplesPerLine );
  744. data++;
  745. blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2+8, samplesPerLine );
  746. data++;
  747. break;
  748. case 0x4000: // motion compensation
  749. move4_32( status[index] + mcomp[(*data)], status[index], samplesPerLine );
  750. data++;
  751. break;
  752. }
  753. index++;
  754. }
  755. break;
  756. case 0x4000: // motion compensation
  757. move8_32( status[index] + mcomp[(*data)], status[index], samplesPerLine );
  758. data++;
  759. index += 5;
  760. break;
  761. case 0x0000:
  762. index += 5;
  763. break;
  764. }
  765. } while ( status[index] != NULL );
  766. }
  767. #define VQ2TO4(a,b,c,d) { \
  768. *c++ = a[0]; \
  769. *d++ = a[0]; \
  770. *d++ = a[0]; \
  771. *c++ = a[1]; \
  772. *d++ = a[1]; \
  773. *d++ = a[1]; \
  774. *c++ = b[0]; \
  775. *d++ = b[0]; \
  776. *d++ = b[0]; \
  777. *c++ = b[1]; \
  778. *d++ = b[1]; \
  779. *d++ = b[1]; \
  780. *d++ = a[0]; \
  781. *d++ = a[0]; \
  782. *d++ = a[1]; \
  783. *d++ = a[1]; \
  784. *d++ = b[0]; \
  785. *d++ = b[0]; \
  786. *d++ = b[1]; \
  787. *d++ = b[1]; \
  788. a += 2; b += 2; }
  789. #define VQ2TO2(a,b,c,d) { \
  790. *c++ = *a; \
  791. *d++ = *a; \
  792. *d++ = *a; \
  793. *c++ = *b; \
  794. *d++ = *b; \
  795. *d++ = *b; \
  796. *d++ = *a; \
  797. *d++ = *a; \
  798. *d++ = *b; \
  799. *d++ = *b; \
  800. a++; b++; }
  801. /*
  802. ==============
  803. idCinematicLocal::yuv_to_rgb
  804. ==============
  805. */
  806. unsigned short idCinematicLocal::yuv_to_rgb( long y, long u, long v ) {
  807. long r,g,b,YY = (long)(ROQ_YY_tab[(y)]);
  808. r = (YY + ROQ_VR_tab[v]) >> 9;
  809. g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 8;
  810. b = (YY + ROQ_UB_tab[u]) >> 9;
  811. if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
  812. if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31;
  813. return (unsigned short)((r<<11)+(g<<5)+(b));
  814. }
  815. /*
  816. ==============
  817. idCinematicLocal::yuv_to_rgb24
  818. ==============
  819. */
  820. unsigned int idCinematicLocal::yuv_to_rgb24( long y, long u, long v ) {
  821. long r,g,b,YY = (long)(ROQ_YY_tab[(y)]);
  822. r = (YY + ROQ_VR_tab[v]) >> 6;
  823. g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 6;
  824. b = (YY + ROQ_UB_tab[u]) >> 6;
  825. if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
  826. if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255;
  827. return LittleLong((r)+(g<<8)+(b<<16));
  828. }
  829. /*
  830. ==============
  831. idCinematicLocal::decodeCodeBook
  832. ==============
  833. */
  834. void idCinematicLocal::decodeCodeBook( byte *input, unsigned short roq_flags ) {
  835. long i, j, two, four;
  836. unsigned short *aptr, *bptr, *cptr, *dptr;
  837. long y0,y1,y2,y3,cr,cb;
  838. unsigned int *iaptr, *ibptr, *icptr, *idptr;
  839. if (!roq_flags) {
  840. two = four = 256;
  841. } else {
  842. two = roq_flags>>8;
  843. if (!two) two = 256;
  844. four = roq_flags&0xff;
  845. }
  846. four *= 2;
  847. bptr = (unsigned short *)vq2;
  848. if (!half) {
  849. if (!smootheddouble) {
  850. //
  851. // normal height
  852. //
  853. if (samplesPerPixel==2) {
  854. for(i=0;i<two;i++) {
  855. y0 = (long)*input++;
  856. y1 = (long)*input++;
  857. y2 = (long)*input++;
  858. y3 = (long)*input++;
  859. cr = (long)*input++;
  860. cb = (long)*input++;
  861. *bptr++ = yuv_to_rgb( y0, cr, cb );
  862. *bptr++ = yuv_to_rgb( y1, cr, cb );
  863. *bptr++ = yuv_to_rgb( y2, cr, cb );
  864. *bptr++ = yuv_to_rgb( y3, cr, cb );
  865. }
  866. cptr = (unsigned short *)vq4;
  867. dptr = (unsigned short *)vq8;
  868. for(i=0;i<four;i++) {
  869. aptr = (unsigned short *)vq2 + (*input++)*4;
  870. bptr = (unsigned short *)vq2 + (*input++)*4;
  871. for(j=0;j<2;j++)
  872. VQ2TO4(aptr,bptr,cptr,dptr);
  873. }
  874. } else if (samplesPerPixel==4) {
  875. ibptr = (unsigned int *)bptr;
  876. for(i=0;i<two;i++) {
  877. y0 = (long)*input++;
  878. y1 = (long)*input++;
  879. y2 = (long)*input++;
  880. y3 = (long)*input++;
  881. cr = (long)*input++;
  882. cb = (long)*input++;
  883. *ibptr++ = yuv_to_rgb24( y0, cr, cb );
  884. *ibptr++ = yuv_to_rgb24( y1, cr, cb );
  885. *ibptr++ = yuv_to_rgb24( y2, cr, cb );
  886. *ibptr++ = yuv_to_rgb24( y3, cr, cb );
  887. }
  888. icptr = (unsigned int *)vq4;
  889. idptr = (unsigned int *)vq8;
  890. for(i=0;i<four;i++) {
  891. iaptr = (unsigned int *)vq2 + (*input++)*4;
  892. ibptr = (unsigned int *)vq2 + (*input++)*4;
  893. for(j=0;j<2;j++)
  894. VQ2TO4(iaptr, ibptr, icptr, idptr);
  895. }
  896. }
  897. } else {
  898. //
  899. // double height, smoothed
  900. //
  901. if (samplesPerPixel==2) {
  902. for(i=0;i<two;i++) {
  903. y0 = (long)*input++;
  904. y1 = (long)*input++;
  905. y2 = (long)*input++;
  906. y3 = (long)*input++;
  907. cr = (long)*input++;
  908. cb = (long)*input++;
  909. *bptr++ = yuv_to_rgb( y0, cr, cb );
  910. *bptr++ = yuv_to_rgb( y1, cr, cb );
  911. *bptr++ = yuv_to_rgb( ((y0*3)+y2)/4, cr, cb );
  912. *bptr++ = yuv_to_rgb( ((y1*3)+y3)/4, cr, cb );
  913. *bptr++ = yuv_to_rgb( (y0+(y2*3))/4, cr, cb );
  914. *bptr++ = yuv_to_rgb( (y1+(y3*3))/4, cr, cb );
  915. *bptr++ = yuv_to_rgb( y2, cr, cb );
  916. *bptr++ = yuv_to_rgb( y3, cr, cb );
  917. }
  918. cptr = (unsigned short *)vq4;
  919. dptr = (unsigned short *)vq8;
  920. for(i=0;i<four;i++) {
  921. aptr = (unsigned short *)vq2 + (*input++)*8;
  922. bptr = (unsigned short *)vq2 + (*input++)*8;
  923. for(j=0;j<2;j++) {
  924. VQ2TO4(aptr,bptr,cptr,dptr);
  925. VQ2TO4(aptr,bptr,cptr,dptr);
  926. }
  927. }
  928. } else if (samplesPerPixel==4) {
  929. ibptr = (unsigned int *)bptr;
  930. for(i=0;i<two;i++) {
  931. y0 = (long)*input++;
  932. y1 = (long)*input++;
  933. y2 = (long)*input++;
  934. y3 = (long)*input++;
  935. cr = (long)*input++;
  936. cb = (long)*input++;
  937. *ibptr++ = yuv_to_rgb24( y0, cr, cb );
  938. *ibptr++ = yuv_to_rgb24( y1, cr, cb );
  939. *ibptr++ = yuv_to_rgb24( ((y0*3)+y2)/4, cr, cb );
  940. *ibptr++ = yuv_to_rgb24( ((y1*3)+y3)/4, cr, cb );
  941. *ibptr++ = yuv_to_rgb24( (y0+(y2*3))/4, cr, cb );
  942. *ibptr++ = yuv_to_rgb24( (y1+(y3*3))/4, cr, cb );
  943. *ibptr++ = yuv_to_rgb24( y2, cr, cb );
  944. *ibptr++ = yuv_to_rgb24( y3, cr, cb );
  945. }
  946. icptr = (unsigned int *)vq4;
  947. idptr = (unsigned int *)vq8;
  948. for(i=0;i<four;i++) {
  949. iaptr = (unsigned int *)vq2 + (*input++)*8;
  950. ibptr = (unsigned int *)vq2 + (*input++)*8;
  951. for(j=0;j<2;j++) {
  952. VQ2TO4(iaptr, ibptr, icptr, idptr);
  953. VQ2TO4(iaptr, ibptr, icptr, idptr);
  954. }
  955. }
  956. }
  957. }
  958. } else {
  959. //
  960. // 1/4 screen
  961. //
  962. if (samplesPerPixel==2) {
  963. for(i=0;i<two;i++) {
  964. y0 = (long)*input; input+=2;
  965. y2 = (long)*input; input+=2;
  966. cr = (long)*input++;
  967. cb = (long)*input++;
  968. *bptr++ = yuv_to_rgb( y0, cr, cb );
  969. *bptr++ = yuv_to_rgb( y2, cr, cb );
  970. }
  971. cptr = (unsigned short *)vq4;
  972. dptr = (unsigned short *)vq8;
  973. for(i=0;i<four;i++) {
  974. aptr = (unsigned short *)vq2 + (*input++)*2;
  975. bptr = (unsigned short *)vq2 + (*input++)*2;
  976. for(j=0;j<2;j++) {
  977. VQ2TO2(aptr,bptr,cptr,dptr);
  978. }
  979. }
  980. } else if (samplesPerPixel == 4) {
  981. ibptr = (unsigned int *) bptr;
  982. for(i=0;i<two;i++) {
  983. y0 = (long)*input; input+=2;
  984. y2 = (long)*input; input+=2;
  985. cr = (long)*input++;
  986. cb = (long)*input++;
  987. *ibptr++ = yuv_to_rgb24( y0, cr, cb );
  988. *ibptr++ = yuv_to_rgb24( y2, cr, cb );
  989. }
  990. icptr = (unsigned int *)vq4;
  991. idptr = (unsigned int *)vq8;
  992. for(i=0;i<four;i++) {
  993. iaptr = (unsigned int *)vq2 + (*input++)*2;
  994. ibptr = (unsigned int *)vq2 + (*input++)*2;
  995. for(j=0;j<2;j++) {
  996. VQ2TO2(iaptr,ibptr,icptr,idptr);
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. /*
  1003. ==============
  1004. idCinematicLocal::recurseQuad
  1005. ==============
  1006. */
  1007. void idCinematicLocal::recurseQuad( long startX, long startY, long quadSize, long xOff, long yOff ) {
  1008. byte *scroff;
  1009. long bigx, bigy, lowx, lowy, useY;
  1010. long offset;
  1011. offset = screenDelta;
  1012. lowx = lowy = 0;
  1013. bigx = xsize;
  1014. bigy = ysize;
  1015. if (bigx > CIN_WIDTH) bigx = CIN_WIDTH;
  1016. if (bigy > CIN_HEIGHT) bigy = CIN_HEIGHT;
  1017. if ( (startX >= lowx) && (startX+quadSize) <= (bigx) && (startY+quadSize) <= (bigy) && (startY >= lowy) && quadSize <= MAXSIZE) {
  1018. useY = startY;
  1019. scroff = image + (useY+((CIN_HEIGHT-bigy)>>1)+yOff)*(samplesPerLine) + (((startX+xOff))*samplesPerPixel);
  1020. qStatus[0][onQuad ] = scroff;
  1021. qStatus[1][onQuad++] = scroff+offset;
  1022. }
  1023. if ( quadSize != MINSIZE ) {
  1024. quadSize >>= 1;
  1025. recurseQuad( startX, startY , quadSize, xOff, yOff );
  1026. recurseQuad( startX+quadSize, startY , quadSize, xOff, yOff );
  1027. recurseQuad( startX, startY+quadSize , quadSize, xOff, yOff );
  1028. recurseQuad( startX+quadSize, startY+quadSize , quadSize, xOff, yOff );
  1029. }
  1030. }
  1031. /*
  1032. ==============
  1033. idCinematicLocal::setupQuad
  1034. ==============
  1035. */
  1036. void idCinematicLocal::setupQuad( long xOff, long yOff ) {
  1037. long numQuadCels, i,x,y;
  1038. byte *temp;
  1039. numQuadCels = (CIN_WIDTH*CIN_HEIGHT) / (16);
  1040. numQuadCels += numQuadCels/4 + numQuadCels/16;
  1041. numQuadCels += 64; // for overflow
  1042. numQuadCels = (xsize*ysize) / (16);
  1043. numQuadCels += numQuadCels/4;
  1044. numQuadCels += 64; // for overflow
  1045. onQuad = 0;
  1046. for(y=0;y<(long)ysize;y+=16)
  1047. for(x=0;x<(long)xsize;x+=16)
  1048. recurseQuad( x, y, 16, xOff, yOff );
  1049. temp = NULL;
  1050. for(i=(numQuadCels-64);i<numQuadCels;i++) {
  1051. qStatus[0][i] = temp; // eoq
  1052. qStatus[1][i] = temp; // eoq
  1053. }
  1054. }
  1055. /*
  1056. ==============
  1057. idCinematicLocal::readQuadInfo
  1058. ==============
  1059. */
  1060. void idCinematicLocal::readQuadInfo( byte *qData ) {
  1061. xsize = qData[0]+qData[1]*256;
  1062. ysize = qData[2]+qData[3]*256;
  1063. maxsize = qData[4]+qData[5]*256;
  1064. minsize = qData[6]+qData[7]*256;
  1065. CIN_HEIGHT = ysize;
  1066. CIN_WIDTH = xsize;
  1067. samplesPerLine = CIN_WIDTH*samplesPerPixel;
  1068. screenDelta = CIN_HEIGHT*samplesPerLine;
  1069. if (!image ) {
  1070. image = (byte *)Mem_Alloc( CIN_WIDTH*CIN_HEIGHT*samplesPerPixel*2 );
  1071. }
  1072. half = false;
  1073. smootheddouble = false;
  1074. t[0] = (0 - (unsigned int)image)+(unsigned int)image+screenDelta;
  1075. t[1] = (0 - ((unsigned int)image + screenDelta))+(unsigned int)image;
  1076. drawX = CIN_WIDTH;
  1077. drawY = CIN_HEIGHT;
  1078. }
  1079. /*
  1080. ==============
  1081. idCinematicLocal::RoQPrepMcomp
  1082. ==============
  1083. */
  1084. void idCinematicLocal::RoQPrepMcomp( long xoff, long yoff ) {
  1085. long i, j, x, y, temp, temp2;
  1086. i=samplesPerLine; j=samplesPerPixel;
  1087. if ( xsize == (ysize*4) && !half ) { j = j+j; i = i+i; }
  1088. for(y=0;y<16;y++) {
  1089. temp2 = (y+yoff-8)*i;
  1090. for(x=0;x<16;x++) {
  1091. temp = (x+xoff-8)*j;
  1092. mcomp[(x*16)+y] = normalBuffer0-(temp2+temp);
  1093. }
  1094. }
  1095. }
  1096. /*
  1097. ==============
  1098. idCinematicLocal::RoQReset
  1099. ==============
  1100. */
  1101. void idCinematicLocal::RoQReset() {
  1102. iFile->Seek( 0, FS_SEEK_SET );
  1103. iFile->Read( file, 16 );
  1104. RoQ_init();
  1105. status = FMV_LOOPED;
  1106. }
  1107. typedef struct {
  1108. struct jpeg_source_mgr pub; /* public fields */
  1109. byte *infile; /* source stream */
  1110. JOCTET * buffer; /* start of buffer */
  1111. boolean start_of_file; /* have we gotten any data yet? */
  1112. int memsize;
  1113. } my_source_mgr;
  1114. typedef my_source_mgr * my_src_ptr;
  1115. #define INPUT_BUF_SIZE 32768 /* choose an efficiently fread'able size */
  1116. /* jpeg error handling */
  1117. struct jpeg_error_mgr jerr;
  1118. /*
  1119. * Fill the input buffer --- called whenever buffer is emptied.
  1120. *
  1121. * In typical applications, this should read fresh data into the buffer
  1122. * (ignoring the current state of next_input_byte & bytes_in_buffer),
  1123. * reset the pointer & count to the start of the buffer, and return TRUE
  1124. * indicating that the buffer has been reloaded. It is not necessary to
  1125. * fill the buffer entirely, only to obtain at least one more byte.
  1126. *
  1127. * There is no such thing as an EOF return. If the end of the file has been
  1128. * reached, the routine has a choice of ERREXIT() or inserting fake data into
  1129. * the buffer. In most cases, generating a warning message and inserting a
  1130. * fake EOI marker is the best course of action --- this will allow the
  1131. * decompressor to output however much of the image is there. However,
  1132. * the resulting error message is misleading if the real problem is an empty
  1133. * input file, so we handle that case specially.
  1134. *
  1135. * In applications that need to be able to suspend compression due to input
  1136. * not being available yet, a FALSE return indicates that no more data can be
  1137. * obtained right now, but more may be forthcoming later. In this situation,
  1138. * the decompressor will return to its caller (with an indication of the
  1139. * number of scanlines it has read, if any). The application should resume
  1140. * decompression after it has loaded more data into the input buffer. Note
  1141. * that there are substantial restrictions on the use of suspension --- see
  1142. * the documentation.
  1143. *
  1144. * When suspending, the decompressor will back up to a convenient restart point
  1145. * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
  1146. * indicate where the restart point will be if the current call returns FALSE.
  1147. * Data beyond this point must be rescanned after resumption, so move it to
  1148. * the front of the buffer rather than discarding it.
  1149. */
  1150. METHODDEF boolean fill_input_buffer( j_decompress_ptr cinfo )
  1151. {
  1152. my_src_ptr src = (my_src_ptr) cinfo->src;
  1153. int nbytes;
  1154. nbytes = INPUT_BUF_SIZE;
  1155. if (nbytes > src->memsize) nbytes = src->memsize;
  1156. if (nbytes == 0) {
  1157. /* Insert a fake EOI marker */
  1158. src->buffer[0] = (JOCTET) 0xFF;
  1159. src->buffer[1] = (JOCTET) JPEG_EOI;
  1160. nbytes = 2;
  1161. } else {
  1162. memcpy( src->buffer, src->infile, INPUT_BUF_SIZE );
  1163. src->infile = src->infile + nbytes;
  1164. src->memsize = src->memsize - INPUT_BUF_SIZE;
  1165. }
  1166. src->pub.next_input_byte = src->buffer;
  1167. src->pub.bytes_in_buffer = nbytes;
  1168. src->start_of_file = FALSE;
  1169. return TRUE;
  1170. }
  1171. /*
  1172. * Initialize source --- called by jpeg_read_header
  1173. * before any data is actually read.
  1174. */
  1175. METHODDEF void init_source (j_decompress_ptr cinfo)
  1176. {
  1177. my_src_ptr src = (my_src_ptr) cinfo->src;
  1178. /* We reset the empty-input-file flag for each image,
  1179. * but we don't clear the input buffer.
  1180. * This is correct behavior for reading a series of images from one source.
  1181. */
  1182. src->start_of_file = TRUE;
  1183. }
  1184. /*
  1185. * Skip data --- used to skip over a potentially large amount of
  1186. * uninteresting data (such as an APPn marker).
  1187. *
  1188. * Writers of suspendable-input applications must note that skip_input_data
  1189. * is not granted the right to give a suspension return. If the skip extends
  1190. * beyond the data currently in the buffer, the buffer can be marked empty so
  1191. * that the next read will cause a fill_input_buffer call that can suspend.
  1192. * Arranging for additional bytes to be discarded before reloading the input
  1193. * buffer is the application writer's problem.
  1194. */
  1195. METHODDEF void
  1196. skip_input_data (j_decompress_ptr cinfo, long num_bytes)
  1197. {
  1198. my_src_ptr src = (my_src_ptr) cinfo->src;
  1199. /* Just a dumb implementation for now. Could use fseek() except
  1200. * it doesn't work on pipes. Not clear that being smart is worth
  1201. * any trouble anyway --- large skips are infrequent.
  1202. */
  1203. if (num_bytes > 0) {
  1204. src->infile = src->infile + num_bytes;
  1205. src->pub.next_input_byte += (size_t) num_bytes;
  1206. src->pub.bytes_in_buffer -= (size_t) num_bytes;
  1207. }
  1208. }
  1209. /*
  1210. * An additional method that can be provided by data source modules is the
  1211. * resync_to_restart method for error recovery in the presence of RST markers.
  1212. * For the moment, this source module just uses the default resync method
  1213. * provided by the JPEG library. That method assumes that no backtracking
  1214. * is possible.
  1215. */
  1216. /*
  1217. * Terminate source --- called by jpeg_finish_decompress
  1218. * after all data has been read. Often a no-op.
  1219. *
  1220. * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
  1221. * application must deal with any cleanup that should happen even
  1222. * for error exit.
  1223. */
  1224. METHODDEF void
  1225. term_source (j_decompress_ptr cinfo)
  1226. {
  1227. cinfo = cinfo;
  1228. /* no work necessary here */
  1229. }
  1230. GLOBAL void
  1231. jpeg_memory_src (j_decompress_ptr cinfo, byte *infile, int size)
  1232. {
  1233. my_src_ptr src;
  1234. /* The source object and input buffer are made permanent so that a series
  1235. * of JPEG images can be read from the same file by calling jpeg_stdio_src
  1236. * only before the first one. (If we discarded the buffer at the end of
  1237. * one image, we'd likely lose the start of the next one.)
  1238. * This makes it unsafe to use this manager and a different source
  1239. * manager serially with the same JPEG object. Caveat programmer.
  1240. */
  1241. if (cinfo->src == NULL) { /* first time for this JPEG object? */
  1242. cinfo->src = (struct jpeg_source_mgr *)
  1243. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
  1244. sizeof(my_source_mgr));
  1245. src = (my_src_ptr) cinfo->src;
  1246. src->buffer = (JOCTET *)
  1247. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
  1248. INPUT_BUF_SIZE * sizeof(JOCTET));
  1249. }
  1250. src = (my_src_ptr) cinfo->src;
  1251. src->pub.init_source = init_source;
  1252. src->pub.fill_input_buffer = fill_input_buffer;
  1253. src->pub.skip_input_data = skip_input_data;
  1254. src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
  1255. src->pub.term_source = term_source;
  1256. src->infile = infile;
  1257. src->memsize = size;
  1258. src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
  1259. src->pub.next_input_byte = NULL; /* until buffer loaded */
  1260. }
  1261. int JPEGBlit( byte *wStatus, byte *data, int datasize )
  1262. {
  1263. /* This struct contains the JPEG decompression parameters and pointers to
  1264. * working space (which is allocated as needed by the JPEG library).
  1265. */
  1266. struct jpeg_decompress_struct cinfo;
  1267. /* We use our private extension JPEG error handler.
  1268. * Note that this struct must live as long as the main JPEG parameter
  1269. * struct, to avoid dangling-pointer problems.
  1270. */
  1271. /* More stuff */
  1272. JSAMPARRAY buffer; /* Output row buffer */
  1273. int row_stride; /* physical row width in output buffer */
  1274. /* Step 1: allocate and initialize JPEG decompression object */
  1275. /* We set up the normal JPEG error routines, then override error_exit. */
  1276. cinfo.err = jpeg_std_error(&jerr);
  1277. /* Now we can initialize the JPEG decompression object. */
  1278. jpeg_create_decompress(&cinfo);
  1279. /* Step 2: specify data source (eg, a file) */
  1280. jpeg_memory_src(&cinfo, data, datasize);
  1281. /* Step 3: read file parameters with jpeg_read_header() */
  1282. (void) jpeg_read_header(&cinfo, TRUE);
  1283. /* We can ignore the return value from jpeg_read_header since
  1284. * (a) suspension is not possible with the stdio data source, and
  1285. * (b) we passed TRUE to reject a tables-only JPEG file as an error.
  1286. * See libjpeg.doc for more info.
  1287. */
  1288. /* Step 4: set parameters for decompression */
  1289. /* In this example, we don't need to change any of the defaults set by
  1290. * jpeg_read_header(), so we do nothing here.
  1291. */
  1292. /* Step 5: Start decompressor */
  1293. cinfo.dct_method = JDCT_IFAST;
  1294. cinfo.dct_method = JDCT_FASTEST;
  1295. cinfo.dither_mode = JDITHER_NONE;
  1296. cinfo.do_fancy_upsampling = FALSE;
  1297. // cinfo.out_color_space = JCS_GRAYSCALE;
  1298. (void) jpeg_start_decompress(&cinfo);
  1299. /* We can ignore the return value since suspension is not possible
  1300. * with the stdio data source.
  1301. */
  1302. /* We may need to do some setup of our own at this point before reading
  1303. * the data. After jpeg_start_decompress() we have the correct scaled
  1304. * output image dimensions available, as well as the output colormap
  1305. * if we asked for color quantization.
  1306. * In this example, we need to make an output work buffer of the right size.
  1307. */
  1308. /* JSAMPLEs per row in output buffer */
  1309. row_stride = cinfo.output_width * cinfo.output_components;
  1310. /* Make a one-row-high sample array that will go away when done with image */
  1311. buffer = (*cinfo.mem->alloc_sarray)
  1312. ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  1313. /* Step 6: while (scan lines remain to be read) */
  1314. /* jpeg_read_scanlines(...); */
  1315. /* Here we use the library's state variable cinfo.output_scanline as the
  1316. * loop counter, so that we don't have to keep track ourselves.
  1317. */
  1318. wStatus += (cinfo.output_height-1)*row_stride;
  1319. while (cinfo.output_scanline < cinfo.output_height) {
  1320. /* jpeg_read_scanlines expects an array of pointers to scanlines.
  1321. * Here the array is only one element long, but you could ask for
  1322. * more than one scanline at a time if that's more convenient.
  1323. */
  1324. (void) jpeg_read_scanlines(&cinfo, &buffer[0], 1);
  1325. /* Assume put_scanline_someplace wants a pointer and sample count. */
  1326. memcpy( wStatus, &buffer[0][0], row_stride );
  1327. /*
  1328. int x;
  1329. unsigned int *buf = (unsigned int *)&buffer[0][0];
  1330. unsigned int *out = (unsigned int *)wStatus;
  1331. for(x=0;x<cinfo.output_width;x++) {
  1332. unsigned int pixel = buf[x];
  1333. byte *roof = (byte *)&pixel;
  1334. byte temp = roof[0];
  1335. roof[0] = roof[2];
  1336. roof[2] = temp;
  1337. out[x] = pixel;
  1338. }
  1339. */
  1340. wStatus -= row_stride;
  1341. }
  1342. /* Step 7: Finish decompression */
  1343. (void) jpeg_finish_decompress(&cinfo);
  1344. /* We can ignore the return value since suspension is not possible
  1345. * with the stdio data source.
  1346. */
  1347. /* Step 8: Release JPEG decompression object */
  1348. /* This is an important step since it will release a good deal of memory. */
  1349. jpeg_destroy_decompress(&cinfo);
  1350. /* At this point you may want to check to see whether any corrupt-data
  1351. * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  1352. */
  1353. /* And we're done! */
  1354. return 1;
  1355. }
  1356. /*
  1357. ==============
  1358. idCinematicLocal::RoQInterrupt
  1359. ==============
  1360. */
  1361. void idCinematicLocal::RoQInterrupt(void) {
  1362. byte *framedata;
  1363. iFile->Read( file, RoQFrameSize+8 );
  1364. if ( RoQPlayed >= ROQSize ) {
  1365. if (looping) {
  1366. RoQReset();
  1367. } else {
  1368. status = FMV_EOF;
  1369. }
  1370. return;
  1371. }
  1372. framedata = file;
  1373. //
  1374. // new frame is ready
  1375. //
  1376. redump:
  1377. switch(roq_id)
  1378. {
  1379. case ROQ_QUAD_VQ:
  1380. if ((numQuads&1)) {
  1381. normalBuffer0 = t[1];
  1382. RoQPrepMcomp( roqF0, roqF1 );
  1383. blitVQQuad32fs( qStatus[1], framedata);
  1384. buf = image + screenDelta;
  1385. } else {
  1386. normalBuffer0 = t[0];
  1387. RoQPrepMcomp( roqF0, roqF1 );
  1388. blitVQQuad32fs( qStatus[0], framedata );
  1389. buf = image;
  1390. }
  1391. if (numQuads == 0) { // first frame
  1392. memcpy(image+screenDelta, image, samplesPerLine*ysize);
  1393. }
  1394. numQuads++;
  1395. dirty = true;
  1396. break;
  1397. case ROQ_CODEBOOK:
  1398. decodeCodeBook( framedata, (unsigned short)roq_flags );
  1399. break;
  1400. case ZA_SOUND_MONO:
  1401. break;
  1402. case ZA_SOUND_STEREO:
  1403. break;
  1404. case ROQ_QUAD_INFO:
  1405. if (numQuads == -1) {
  1406. readQuadInfo( framedata );
  1407. setupQuad( 0, 0 );
  1408. }
  1409. if (numQuads != 1) numQuads = 0;
  1410. break;
  1411. case ROQ_PACKET:
  1412. inMemory = ( roq_flags != 0 );
  1413. RoQFrameSize = 0; // for header
  1414. break;
  1415. case ROQ_QUAD_HANG:
  1416. RoQFrameSize = 0;
  1417. break;
  1418. case ROQ_QUAD_JPEG:
  1419. if (!numQuads) {
  1420. normalBuffer0 = t[0];
  1421. JPEGBlit( image, framedata, RoQFrameSize );
  1422. memcpy(image+screenDelta, image, samplesPerLine*ysize);
  1423. numQuads++;
  1424. }
  1425. break;
  1426. default:
  1427. status = FMV_EOF;
  1428. break;
  1429. }
  1430. //
  1431. // read in next frame data
  1432. //
  1433. if ( RoQPlayed >= ROQSize ) {
  1434. if (looping) {
  1435. RoQReset();
  1436. } else {
  1437. status = FMV_EOF;
  1438. }
  1439. return;
  1440. }
  1441. framedata += RoQFrameSize;
  1442. roq_id = framedata[0] + framedata[1]*256;
  1443. RoQFrameSize = framedata[2] + framedata[3]*256 + framedata[4]*65536;
  1444. roq_flags = framedata[6] + framedata[7]*256;
  1445. roqF0 = (char)framedata[7];
  1446. roqF1 = (char)framedata[6];
  1447. if (RoQFrameSize>65536||roq_id==0x1084) {
  1448. common->DPrintf("roq_size>65536||roq_id==0x1084\n");
  1449. status = FMV_EOF;
  1450. if (looping) {
  1451. RoQReset();
  1452. }
  1453. return;
  1454. }
  1455. if (inMemory && (status != FMV_EOF)) {
  1456. inMemory = false; framedata += 8; goto redump;
  1457. }
  1458. //
  1459. // one more frame hits the dust
  1460. //
  1461. // assert(RoQFrameSize <= 65536);
  1462. // r = Sys_StreamedRead( file, RoQFrameSize+8, 1, iFile );
  1463. RoQPlayed += RoQFrameSize+8;
  1464. }
  1465. /*
  1466. ==============
  1467. idCinematicLocal::RoQ_init
  1468. ==============
  1469. */
  1470. void idCinematicLocal::RoQ_init( void ) {
  1471. RoQPlayed = 24;
  1472. /* get frame rate */
  1473. roqFPS = file[ 6] + file[ 7]*256;
  1474. if (!roqFPS) roqFPS = 30;
  1475. numQuads = -1;
  1476. roq_id = file[ 8] + file[ 9]*256;
  1477. RoQFrameSize= file[10] + file[11]*256 + file[12]*65536;
  1478. roq_flags = file[14] + file[15]*256;
  1479. }
  1480. /*
  1481. ==============
  1482. idCinematicLocal::RoQShutdown
  1483. ==============
  1484. */
  1485. void idCinematicLocal::RoQShutdown( void ) {
  1486. if ( status == FMV_IDLE ) {
  1487. return;
  1488. }
  1489. status = FMV_IDLE;
  1490. if ( iFile ) {
  1491. fileSystem->CloseFile( iFile );
  1492. iFile = NULL;
  1493. }
  1494. fileName = "";
  1495. }
  1496. //===========================================
  1497. /*
  1498. ==============
  1499. idSndWindow::InitFromFile
  1500. ==============
  1501. */
  1502. bool idSndWindow::InitFromFile( const char *qpath, bool looping ) {
  1503. idStr fname = qpath;
  1504. fname.ToLower();
  1505. if ( !fname.Icmp( "waveform" ) ) {
  1506. showWaveform = true;
  1507. } else {
  1508. showWaveform = false;
  1509. }
  1510. return true;
  1511. }
  1512. /*
  1513. ==============
  1514. idSndWindow::ImageForTime
  1515. ==============
  1516. */
  1517. cinData_t idSndWindow::ImageForTime( int milliseconds ) {
  1518. return soundSystem->ImageForTime( milliseconds, showWaveform );
  1519. }
  1520. /*
  1521. ==============
  1522. idSndWindow::AnimationLength
  1523. ==============
  1524. */
  1525. int idSndWindow::AnimationLength() {
  1526. return -1;
  1527. }