2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 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.
24 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.
26 ===========================================================================
29 #include "../idlib/precompiled.h"
32 #define JPEG_INTERNALS
34 #include "jpeg-6/jpeglib.h"
45 class idCinematicLocal : public idCinematic {
48 virtual ~idCinematicLocal();
50 virtual bool InitFromFile( const char *qpath, bool looping );
51 virtual cinData_t ImageForTime( int milliseconds );
52 virtual int AnimationLength();
54 virtual void ResetTime(int time);
57 unsigned int mcomp[256];
60 int CIN_WIDTH, CIN_HEIGHT;
66 unsigned int RoQFrameSize;
73 long samplesPerPixel; // defaults to 2
74 unsigned int xsize, ysize, maxsize, minsize;
95 void RoQ_init( void );
96 void blitVQQuad32fs( byte **status, unsigned char *data );
97 void RoQShutdown( void );
98 void RoQInterrupt(void);
100 void move8_32( byte *src, byte *dst, int spl );
101 void move4_32( byte *src, byte *dst, int spl );
102 void blit8_32( byte *src, byte *dst, int spl );
103 void blit4_32( byte *src, byte *dst, int spl );
104 void blit2_32( byte *src, byte *dst, int spl );
106 unsigned short yuv_to_rgb( long y, long u, long v );
107 unsigned int yuv_to_rgb24( long y, long u, long v );
109 void decodeCodeBook( byte *input, unsigned short roq_flags );
110 void recurseQuad( long startX, long startY, long quadSize, long xOff, long yOff );
111 void setupQuad( long xOff, long yOff );
112 void readQuadInfo( byte *qData );
113 void RoQPrepMcomp( long xoff, long yoff );
117 const int DEFAULT_CIN_WIDTH = 512;
118 const int DEFAULT_CIN_HEIGHT = 512;
119 const int MAXSIZE = 8;
120 const int MINSIZE = 4;
122 const int ROQ_FILE = 0x1084;
123 const int ROQ_QUAD = 0x1000;
124 const int ROQ_QUAD_INFO = 0x1001;
125 const int ROQ_CODEBOOK = 0x1002;
126 const int ROQ_QUAD_VQ = 0x1011;
127 const int ROQ_QUAD_JPEG = 0x1012;
128 const int ROQ_QUAD_HANG = 0x1013;
129 const int ROQ_PACKET = 0x1030;
130 const int ZA_SOUND_MONO = 0x1020;
131 const int ZA_SOUND_STEREO = 0x1021;
133 // temporary buffers used by all cinematics
134 static long ROQ_YY_tab[256];
135 static long ROQ_UB_tab[256];
136 static long ROQ_UG_tab[256];
137 static long ROQ_VG_tab[256];
138 static long ROQ_VR_tab[256];
139 static byte * file = NULL;
140 static unsigned short * vq2 = NULL;
141 static unsigned short * vq4 = NULL;
142 static unsigned short * vq8 = NULL;
146 //===========================================
150 idCinematicLocal::InitCinematic
153 void idCinematic::InitCinematic( void ) {
154 float t_ub,t_vr,t_ug,t_vg;
157 // generate YUV tables
158 t_ub = (1.77200f/2.0f) * (float)(1<<6) + 0.5f;
159 t_vr = (1.40200f/2.0f) * (float)(1<<6) + 0.5f;
160 t_ug = (0.34414f/2.0f) * (float)(1<<6) + 0.5f;
161 t_vg = (0.71414f/2.0f) * (float)(1<<6) + 0.5f;
162 for( i = 0; i < 256; i++ ) {
163 float x = (float)(2 * i - 255);
165 ROQ_UB_tab[i] = (long)( ( t_ub * x) + (1<<5));
166 ROQ_VR_tab[i] = (long)( ( t_vr * x) + (1<<5));
167 ROQ_UG_tab[i] = (long)( (-t_ug * x) );
168 ROQ_VG_tab[i] = (long)( (-t_vg * x) + (1<<5));
169 ROQ_YY_tab[i] = (long)( (i << 6) | (i >> 2) );
172 file = (byte *)Mem_Alloc( 65536 );
173 vq2 = (word *)Mem_Alloc( 256*16*4 * sizeof( word ) );
174 vq4 = (word *)Mem_Alloc( 256*64*4 * sizeof( word ) );
175 vq8 = (word *)Mem_Alloc( 256*256*4 * sizeof( word ) );
180 idCinematicLocal::ShutdownCinematic
183 void idCinematic::ShutdownCinematic( void ) {
196 idCinematicLocal::Alloc
199 idCinematic *idCinematic::Alloc() {
200 return new idCinematicLocal;
205 idCinematicLocal::~idCinematic
208 idCinematic::~idCinematic( ) {
214 idCinematicLocal::InitFromFile
217 bool idCinematic::InitFromFile( const char *qpath, bool looping ) {
223 idCinematicLocal::AnimationLength
226 int idCinematic::AnimationLength() {
232 idCinematicLocal::ResetTime
235 void idCinematic::ResetTime(int milliseconds) {
240 idCinematicLocal::ImageForTime
243 cinData_t idCinematic::ImageForTime( int milliseconds ) {
245 memset( &c, 0, sizeof( c ) );
251 idCinematicLocal::Close
254 void idCinematic::Close() {
257 //===========================================
261 idCinematicLocal::idCinematicLocal
264 idCinematicLocal::idCinematicLocal() {
270 qStatus[0] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) );
271 qStatus[1] = (byte **)Mem_Alloc( 32768 * sizeof( byte *) );
276 idCinematicLocal::~idCinematicLocal
279 idCinematicLocal::~idCinematicLocal() {
282 Mem_Free( qStatus[0] );
284 Mem_Free( qStatus[1] );
290 idCinematicLocal::InitFromFile
293 bool idCinematicLocal::InitFromFile( const char *qpath, bool amilooping ) {
294 unsigned short RoQID;
299 animationLength = 100000;
301 if ( strstr( qpath, "/" ) == NULL && strstr( qpath, "\\" ) == NULL ) {
302 sprintf( fileName, "video/%s", qpath );
304 sprintf( fileName, "%s", qpath );
307 iFile = fileSystem->OpenFileRead( fileName );
313 ROQSize = iFile->Length();
315 looping = amilooping;
317 CIN_HEIGHT = DEFAULT_CIN_HEIGHT;
318 CIN_WIDTH = DEFAULT_CIN_WIDTH;
320 startTime = 0; //Sys_Milliseconds();
323 iFile->Read( file, 16 );
325 RoQID = (unsigned short)(file[0]) + (unsigned short)(file[1])*256;
328 if ( frameRate == 32.0f ) {
329 frameRate = 1000.0f / 32.0f;
332 if ( RoQID == ROQ_FILE ) {
336 status = ( looping ) ? FMV_PLAY : FMV_IDLE;
346 idCinematicLocal::Close
349 void idCinematicLocal::Close() {
351 Mem_Free( (void *)image );
361 idCinematicLocal::AnimationLength
364 int idCinematicLocal::AnimationLength() {
365 return animationLength;
370 idCinematicLocal::ResetTime
373 void idCinematicLocal::ResetTime(int time) {
374 startTime = ( backEnd.viewDef ) ? 1000 * backEnd.viewDef->floatTime : -1;
380 idCinematicLocal::ImageForTime
383 cinData_t idCinematicLocal::ImageForTime( int thisTime ) {
386 if ( thisTime < 0 ) {
390 memset( &cinData, 0, sizeof(cinData) );
392 if ( r_skipROQ.GetBool() ) {
396 if ( status == FMV_EOF || status == FMV_IDLE ) {
400 if ( buf == NULL || startTime == -1 ) {
401 if ( startTime == -1 ) {
404 startTime = thisTime;
407 tfps = ( ( thisTime - startTime ) * frameRate ) / 1000;
413 if ( tfps < numQuads ) {
420 while( buf == NULL ) {
424 while( (tfps != numQuads && status == FMV_PLAY) ) {
429 if ( status == FMV_LOOPED ) {
431 while( buf == NULL && status == FMV_PLAY ) {
434 startTime = thisTime;
437 if ( status == FMV_EOF ) {
441 if ( status == FMV_LOOPED ) {
444 while ( buf == NULL && status == FMV_PLAY ) {
447 startTime = thisTime;
454 cinData.imageWidth = CIN_WIDTH;
455 cinData.imageHeight = CIN_HEIGHT;
456 cinData.status = status;
464 idCinematicLocal::move8_32
467 void idCinematicLocal::move8_32( byte *src, byte *dst, int spl ) {
476 ddst[0*dspl+0] = dsrc[0*dspl+0];
477 ddst[0*dspl+1] = dsrc[0*dspl+1];
478 ddst[0*dspl+2] = dsrc[0*dspl+2];
479 ddst[0*dspl+3] = dsrc[0*dspl+3];
480 ddst[0*dspl+4] = dsrc[0*dspl+4];
481 ddst[0*dspl+5] = dsrc[0*dspl+5];
482 ddst[0*dspl+6] = dsrc[0*dspl+6];
483 ddst[0*dspl+7] = dsrc[0*dspl+7];
485 ddst[1*dspl+0] = dsrc[1*dspl+0];
486 ddst[1*dspl+1] = dsrc[1*dspl+1];
487 ddst[1*dspl+2] = dsrc[1*dspl+2];
488 ddst[1*dspl+3] = dsrc[1*dspl+3];
489 ddst[1*dspl+4] = dsrc[1*dspl+4];
490 ddst[1*dspl+5] = dsrc[1*dspl+5];
491 ddst[1*dspl+6] = dsrc[1*dspl+6];
492 ddst[1*dspl+7] = dsrc[1*dspl+7];
494 ddst[2*dspl+0] = dsrc[2*dspl+0];
495 ddst[2*dspl+1] = dsrc[2*dspl+1];
496 ddst[2*dspl+2] = dsrc[2*dspl+2];
497 ddst[2*dspl+3] = dsrc[2*dspl+3];
498 ddst[2*dspl+4] = dsrc[2*dspl+4];
499 ddst[2*dspl+5] = dsrc[2*dspl+5];
500 ddst[2*dspl+6] = dsrc[2*dspl+6];
501 ddst[2*dspl+7] = dsrc[2*dspl+7];
503 ddst[3*dspl+0] = dsrc[3*dspl+0];
504 ddst[3*dspl+1] = dsrc[3*dspl+1];
505 ddst[3*dspl+2] = dsrc[3*dspl+2];
506 ddst[3*dspl+3] = dsrc[3*dspl+3];
507 ddst[3*dspl+4] = dsrc[3*dspl+4];
508 ddst[3*dspl+5] = dsrc[3*dspl+5];
509 ddst[3*dspl+6] = dsrc[3*dspl+6];
510 ddst[3*dspl+7] = dsrc[3*dspl+7];
512 ddst[4*dspl+0] = dsrc[4*dspl+0];
513 ddst[4*dspl+1] = dsrc[4*dspl+1];
514 ddst[4*dspl+2] = dsrc[4*dspl+2];
515 ddst[4*dspl+3] = dsrc[4*dspl+3];
516 ddst[4*dspl+4] = dsrc[4*dspl+4];
517 ddst[4*dspl+5] = dsrc[4*dspl+5];
518 ddst[4*dspl+6] = dsrc[4*dspl+6];
519 ddst[4*dspl+7] = dsrc[4*dspl+7];
521 ddst[5*dspl+0] = dsrc[5*dspl+0];
522 ddst[5*dspl+1] = dsrc[5*dspl+1];
523 ddst[5*dspl+2] = dsrc[5*dspl+2];
524 ddst[5*dspl+3] = dsrc[5*dspl+3];
525 ddst[5*dspl+4] = dsrc[5*dspl+4];
526 ddst[5*dspl+5] = dsrc[5*dspl+5];
527 ddst[5*dspl+6] = dsrc[5*dspl+6];
528 ddst[5*dspl+7] = dsrc[5*dspl+7];
530 ddst[6*dspl+0] = dsrc[6*dspl+0];
531 ddst[6*dspl+1] = dsrc[6*dspl+1];
532 ddst[6*dspl+2] = dsrc[6*dspl+2];
533 ddst[6*dspl+3] = dsrc[6*dspl+3];
534 ddst[6*dspl+4] = dsrc[6*dspl+4];
535 ddst[6*dspl+5] = dsrc[6*dspl+5];
536 ddst[6*dspl+6] = dsrc[6*dspl+6];
537 ddst[6*dspl+7] = dsrc[6*dspl+7];
539 ddst[7*dspl+0] = dsrc[7*dspl+0];
540 ddst[7*dspl+1] = dsrc[7*dspl+1];
541 ddst[7*dspl+2] = dsrc[7*dspl+2];
542 ddst[7*dspl+3] = dsrc[7*dspl+3];
543 ddst[7*dspl+4] = dsrc[7*dspl+4];
544 ddst[7*dspl+5] = dsrc[7*dspl+5];
545 ddst[7*dspl+6] = dsrc[7*dspl+6];
546 ddst[7*dspl+7] = dsrc[7*dspl+7];
551 dsrc = (double *)src;
552 ddst = (double *)dst;
555 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
556 dsrc += dspl; ddst += dspl;
557 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
558 dsrc += dspl; ddst += dspl;
559 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
560 dsrc += dspl; ddst += dspl;
561 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
562 dsrc += dspl; ddst += dspl;
563 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
564 dsrc += dspl; ddst += dspl;
565 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
566 dsrc += dspl; ddst += dspl;
567 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
568 dsrc += dspl; ddst += dspl;
569 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
575 idCinematicLocal::move4_32
578 void idCinematicLocal::move4_32( byte *src, byte *dst, int spl ) {
587 ddst[0*dspl+0] = dsrc[0*dspl+0];
588 ddst[0*dspl+1] = dsrc[0*dspl+1];
589 ddst[0*dspl+2] = dsrc[0*dspl+2];
590 ddst[0*dspl+3] = dsrc[0*dspl+3];
592 ddst[1*dspl+0] = dsrc[1*dspl+0];
593 ddst[1*dspl+1] = dsrc[1*dspl+1];
594 ddst[1*dspl+2] = dsrc[1*dspl+2];
595 ddst[1*dspl+3] = dsrc[1*dspl+3];
597 ddst[2*dspl+0] = dsrc[2*dspl+0];
598 ddst[2*dspl+1] = dsrc[2*dspl+1];
599 ddst[2*dspl+2] = dsrc[2*dspl+2];
600 ddst[2*dspl+3] = dsrc[2*dspl+3];
602 ddst[3*dspl+0] = dsrc[3*dspl+0];
603 ddst[3*dspl+1] = dsrc[3*dspl+1];
604 ddst[3*dspl+2] = dsrc[3*dspl+2];
605 ddst[3*dspl+3] = dsrc[3*dspl+3];
610 dsrc = (double *)src;
611 ddst = (double *)dst;
614 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
615 dsrc += dspl; ddst += dspl;
616 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
617 dsrc += dspl; ddst += dspl;
618 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
619 dsrc += dspl; ddst += dspl;
620 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
626 idCinematicLocal::blit8_32
629 void idCinematicLocal::blit8_32( byte *src, byte *dst, int spl ) {
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[0*dspl+4] = dsrc[ 4];
643 ddst[0*dspl+5] = dsrc[ 5];
644 ddst[0*dspl+6] = dsrc[ 6];
645 ddst[0*dspl+7] = dsrc[ 7];
647 ddst[1*dspl+0] = dsrc[ 8];
648 ddst[1*dspl+1] = dsrc[ 9];
649 ddst[1*dspl+2] = dsrc[10];
650 ddst[1*dspl+3] = dsrc[11];
651 ddst[1*dspl+4] = dsrc[12];
652 ddst[1*dspl+5] = dsrc[13];
653 ddst[1*dspl+6] = dsrc[14];
654 ddst[1*dspl+7] = dsrc[15];
656 ddst[2*dspl+0] = dsrc[16];
657 ddst[2*dspl+1] = dsrc[17];
658 ddst[2*dspl+2] = dsrc[18];
659 ddst[2*dspl+3] = dsrc[19];
660 ddst[2*dspl+4] = dsrc[20];
661 ddst[2*dspl+5] = dsrc[21];
662 ddst[2*dspl+6] = dsrc[22];
663 ddst[2*dspl+7] = dsrc[23];
665 ddst[3*dspl+0] = dsrc[24];
666 ddst[3*dspl+1] = dsrc[25];
667 ddst[3*dspl+2] = dsrc[26];
668 ddst[3*dspl+3] = dsrc[27];
669 ddst[3*dspl+4] = dsrc[28];
670 ddst[3*dspl+5] = dsrc[29];
671 ddst[3*dspl+6] = dsrc[30];
672 ddst[3*dspl+7] = dsrc[31];
674 ddst[4*dspl+0] = dsrc[32];
675 ddst[4*dspl+1] = dsrc[33];
676 ddst[4*dspl+2] = dsrc[34];
677 ddst[4*dspl+3] = dsrc[35];
678 ddst[4*dspl+4] = dsrc[36];
679 ddst[4*dspl+5] = dsrc[37];
680 ddst[4*dspl+6] = dsrc[38];
681 ddst[4*dspl+7] = dsrc[39];
683 ddst[5*dspl+0] = dsrc[40];
684 ddst[5*dspl+1] = dsrc[41];
685 ddst[5*dspl+2] = dsrc[42];
686 ddst[5*dspl+3] = dsrc[43];
687 ddst[5*dspl+4] = dsrc[44];
688 ddst[5*dspl+5] = dsrc[45];
689 ddst[5*dspl+6] = dsrc[46];
690 ddst[5*dspl+7] = dsrc[47];
692 ddst[6*dspl+0] = dsrc[48];
693 ddst[6*dspl+1] = dsrc[49];
694 ddst[6*dspl+2] = dsrc[50];
695 ddst[6*dspl+3] = dsrc[51];
696 ddst[6*dspl+4] = dsrc[52];
697 ddst[6*dspl+5] = dsrc[53];
698 ddst[6*dspl+6] = dsrc[54];
699 ddst[6*dspl+7] = dsrc[55];
701 ddst[7*dspl+0] = dsrc[56];
702 ddst[7*dspl+1] = dsrc[57];
703 ddst[7*dspl+2] = dsrc[58];
704 ddst[7*dspl+3] = dsrc[59];
705 ddst[7*dspl+4] = dsrc[60];
706 ddst[7*dspl+5] = dsrc[61];
707 ddst[7*dspl+6] = dsrc[62];
708 ddst[7*dspl+7] = dsrc[63];
713 dsrc = (double *)src;
714 ddst = (double *)dst;
717 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
718 dsrc += 4; ddst += dspl;
719 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
720 dsrc += 4; ddst += dspl;
721 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
722 dsrc += 4; ddst += dspl;
723 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
724 dsrc += 4; ddst += dspl;
725 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
726 dsrc += 4; ddst += dspl;
727 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
728 dsrc += 4; ddst += dspl;
729 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
730 dsrc += 4; ddst += dspl;
731 ddst[0] = dsrc[0]; ddst[1] = dsrc[1]; ddst[2] = dsrc[2]; ddst[3] = dsrc[3];
737 idCinematicLocal::blit4_32
740 void idCinematicLocal::blit4_32( byte *src, byte *dst, int spl ) {
749 ddst[0*dspl+0] = dsrc[ 0];
750 ddst[0*dspl+1] = dsrc[ 1];
751 ddst[0*dspl+2] = dsrc[ 2];
752 ddst[0*dspl+3] = dsrc[ 3];
753 ddst[1*dspl+0] = dsrc[ 4];
754 ddst[1*dspl+1] = dsrc[ 5];
755 ddst[1*dspl+2] = dsrc[ 6];
756 ddst[1*dspl+3] = dsrc[ 7];
757 ddst[2*dspl+0] = dsrc[ 8];
758 ddst[2*dspl+1] = dsrc[ 9];
759 ddst[2*dspl+2] = dsrc[10];
760 ddst[2*dspl+3] = dsrc[11];
761 ddst[3*dspl+0] = dsrc[12];
762 ddst[3*dspl+1] = dsrc[13];
763 ddst[3*dspl+2] = dsrc[14];
764 ddst[3*dspl+3] = dsrc[15];
769 dsrc = (double *)src;
770 ddst = (double *)dst;
773 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
774 dsrc += 2; ddst += dspl;
775 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
776 dsrc += 2; ddst += dspl;
777 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
778 dsrc += 2; ddst += dspl;
779 ddst[0] = dsrc[0]; ddst[1] = dsrc[1];
785 idCinematicLocal::blit2_32
788 void idCinematicLocal::blit2_32( byte *src, byte *dst, int spl ) {
797 ddst[0*dspl+0] = dsrc[0];
798 ddst[0*dspl+1] = dsrc[1];
799 ddst[1*dspl+0] = dsrc[2];
800 ddst[1*dspl+1] = dsrc[3];
805 dsrc = (double *)src;
806 ddst = (double *)dst;
810 ddst[dspl] = dsrc[1];
816 idCinematicLocal::blitVQQuad32fs
819 void idCinematicLocal::blitVQQuad32fs( byte **status, unsigned char *data ) {
820 unsigned short newd, celdata, code;
821 unsigned int index, i;
830 celdata = data[0] + data[1]*256;
836 code = (unsigned short)(celdata&0xc000);
840 case 0x8000: // vq code
841 blit8_32( (byte *)&vq8[(*data)*128], status[index], samplesPerLine );
850 celdata = data[0] + data[1]*256;
856 code = (unsigned short)(celdata&0xc000); celdata <<= 2;
858 switch (code) { // code in top two bits of code
859 case 0x8000: // 4x4 vq code
860 blit4_32( (byte *)&vq4[(*data)*32], status[index], samplesPerLine );
863 case 0xc000: // 2x2 vq code
864 blit2_32( (byte *)&vq2[(*data)*8], status[index], samplesPerLine );
866 blit2_32( (byte *)&vq2[(*data)*8], status[index]+8, samplesPerLine );
868 blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2, samplesPerLine );
870 blit2_32( (byte *)&vq2[(*data)*8], status[index]+samplesPerLine*2+8, samplesPerLine );
873 case 0x4000: // motion compensation
874 move4_32( status[index] + mcomp[(*data)], status[index], samplesPerLine );
881 case 0x4000: // motion compensation
882 move8_32( status[index] + mcomp[(*data)], status[index], samplesPerLine );
890 } while ( status[index] != NULL );
893 #define VQ2TO4(a,b,c,d) { \
916 #define VQ2TO2(a,b,c,d) { \
931 idCinematicLocal::yuv_to_rgb
934 unsigned short idCinematicLocal::yuv_to_rgb( long y, long u, long v ) {
935 long r,g,b,YY = (long)(ROQ_YY_tab[(y)]);
937 r = (YY + ROQ_VR_tab[v]) >> 9;
938 g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 8;
939 b = (YY + ROQ_UB_tab[u]) >> 9;
941 if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
942 if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31;
944 return (unsigned short)((r<<11)+(g<<5)+(b));
949 idCinematicLocal::yuv_to_rgb24
952 unsigned int idCinematicLocal::yuv_to_rgb24( long y, long u, long v ) {
953 long r,g,b,YY = (long)(ROQ_YY_tab[(y)]);
955 r = (YY + ROQ_VR_tab[v]) >> 6;
956 g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 6;
957 b = (YY + ROQ_UB_tab[u]) >> 6;
959 if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
960 if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255;
962 return LittleLong((r)+(g<<8)+(b<<16));
967 idCinematicLocal::decodeCodeBook
970 void idCinematicLocal::decodeCodeBook( byte *input, unsigned short roq_flags ) {
971 long i, j, two, four;
972 unsigned short *aptr, *bptr, *cptr, *dptr;
973 long y0,y1,y2,y3,cr,cb;
974 unsigned int *iaptr, *ibptr, *icptr, *idptr;
981 four = roq_flags&0xff;
986 bptr = (unsigned short *)vq2;
989 if (!smootheddouble) {
993 if (samplesPerPixel==2) {
1000 cb = (long)*input++;
1001 *bptr++ = yuv_to_rgb( y0, cr, cb );
1002 *bptr++ = yuv_to_rgb( y1, cr, cb );
1003 *bptr++ = yuv_to_rgb( y2, cr, cb );
1004 *bptr++ = yuv_to_rgb( y3, cr, cb );
1007 cptr = (unsigned short *)vq4;
1008 dptr = (unsigned short *)vq8;
1010 for(i=0;i<four;i++) {
1011 aptr = (unsigned short *)vq2 + (*input++)*4;
1012 bptr = (unsigned short *)vq2 + (*input++)*4;
1014 VQ2TO4(aptr,bptr,cptr,dptr);
1016 } else if (samplesPerPixel==4) {
1017 ibptr = (unsigned int *)bptr;
1018 for(i=0;i<two;i++) {
1019 y0 = (long)*input++;
1020 y1 = (long)*input++;
1021 y2 = (long)*input++;
1022 y3 = (long)*input++;
1023 cr = (long)*input++;
1024 cb = (long)*input++;
1025 *ibptr++ = yuv_to_rgb24( y0, cr, cb );
1026 *ibptr++ = yuv_to_rgb24( y1, cr, cb );
1027 *ibptr++ = yuv_to_rgb24( y2, cr, cb );
1028 *ibptr++ = yuv_to_rgb24( y3, cr, cb );
1031 icptr = (unsigned int *)vq4;
1032 idptr = (unsigned int *)vq8;
1034 for(i=0;i<four;i++) {
1035 iaptr = (unsigned int *)vq2 + (*input++)*4;
1036 ibptr = (unsigned int *)vq2 + (*input++)*4;
1038 VQ2TO4(iaptr, ibptr, icptr, idptr);
1043 // double height, smoothed
1045 if (samplesPerPixel==2) {
1046 for(i=0;i<two;i++) {
1047 y0 = (long)*input++;
1048 y1 = (long)*input++;
1049 y2 = (long)*input++;
1050 y3 = (long)*input++;
1051 cr = (long)*input++;
1052 cb = (long)*input++;
1053 *bptr++ = yuv_to_rgb( y0, cr, cb );
1054 *bptr++ = yuv_to_rgb( y1, cr, cb );
1055 *bptr++ = yuv_to_rgb( ((y0*3)+y2)/4, cr, cb );
1056 *bptr++ = yuv_to_rgb( ((y1*3)+y3)/4, cr, cb );
1057 *bptr++ = yuv_to_rgb( (y0+(y2*3))/4, cr, cb );
1058 *bptr++ = yuv_to_rgb( (y1+(y3*3))/4, cr, cb );
1059 *bptr++ = yuv_to_rgb( y2, cr, cb );
1060 *bptr++ = yuv_to_rgb( y3, cr, cb );
1063 cptr = (unsigned short *)vq4;
1064 dptr = (unsigned short *)vq8;
1066 for(i=0;i<four;i++) {
1067 aptr = (unsigned short *)vq2 + (*input++)*8;
1068 bptr = (unsigned short *)vq2 + (*input++)*8;
1070 VQ2TO4(aptr,bptr,cptr,dptr);
1071 VQ2TO4(aptr,bptr,cptr,dptr);
1074 } else if (samplesPerPixel==4) {
1075 ibptr = (unsigned int *)bptr;
1076 for(i=0;i<two;i++) {
1077 y0 = (long)*input++;
1078 y1 = (long)*input++;
1079 y2 = (long)*input++;
1080 y3 = (long)*input++;
1081 cr = (long)*input++;
1082 cb = (long)*input++;
1083 *ibptr++ = yuv_to_rgb24( y0, cr, cb );
1084 *ibptr++ = yuv_to_rgb24( y1, cr, cb );
1085 *ibptr++ = yuv_to_rgb24( ((y0*3)+y2)/4, cr, cb );
1086 *ibptr++ = yuv_to_rgb24( ((y1*3)+y3)/4, cr, cb );
1087 *ibptr++ = yuv_to_rgb24( (y0+(y2*3))/4, cr, cb );
1088 *ibptr++ = yuv_to_rgb24( (y1+(y3*3))/4, cr, cb );
1089 *ibptr++ = yuv_to_rgb24( y2, cr, cb );
1090 *ibptr++ = yuv_to_rgb24( y3, cr, cb );
1093 icptr = (unsigned int *)vq4;
1094 idptr = (unsigned int *)vq8;
1096 for(i=0;i<four;i++) {
1097 iaptr = (unsigned int *)vq2 + (*input++)*8;
1098 ibptr = (unsigned int *)vq2 + (*input++)*8;
1100 VQ2TO4(iaptr, ibptr, icptr, idptr);
1101 VQ2TO4(iaptr, ibptr, icptr, idptr);
1110 if (samplesPerPixel==2) {
1111 for(i=0;i<two;i++) {
1112 y0 = (long)*input; input+=2;
1113 y2 = (long)*input; input+=2;
1114 cr = (long)*input++;
1115 cb = (long)*input++;
1116 *bptr++ = yuv_to_rgb( y0, cr, cb );
1117 *bptr++ = yuv_to_rgb( y2, cr, cb );
1120 cptr = (unsigned short *)vq4;
1121 dptr = (unsigned short *)vq8;
1123 for(i=0;i<four;i++) {
1124 aptr = (unsigned short *)vq2 + (*input++)*2;
1125 bptr = (unsigned short *)vq2 + (*input++)*2;
1127 VQ2TO2(aptr,bptr,cptr,dptr);
1130 } else if (samplesPerPixel == 4) {
1131 ibptr = (unsigned int *) bptr;
1132 for(i=0;i<two;i++) {
1133 y0 = (long)*input; input+=2;
1134 y2 = (long)*input; input+=2;
1135 cr = (long)*input++;
1136 cb = (long)*input++;
1137 *ibptr++ = yuv_to_rgb24( y0, cr, cb );
1138 *ibptr++ = yuv_to_rgb24( y2, cr, cb );
1141 icptr = (unsigned int *)vq4;
1142 idptr = (unsigned int *)vq8;
1144 for(i=0;i<four;i++) {
1145 iaptr = (unsigned int *)vq2 + (*input++)*2;
1146 ibptr = (unsigned int *)vq2 + (*input++)*2;
1148 VQ2TO2(iaptr,ibptr,icptr,idptr);
1157 idCinematicLocal::recurseQuad
1160 void idCinematicLocal::recurseQuad( long startX, long startY, long quadSize, long xOff, long yOff ) {
1162 long bigx, bigy, lowx, lowy, useY;
1165 offset = screenDelta;
1171 if (bigx > CIN_WIDTH) bigx = CIN_WIDTH;
1172 if (bigy > CIN_HEIGHT) bigy = CIN_HEIGHT;
1174 if ( (startX >= lowx) && (startX+quadSize) <= (bigx) && (startY+quadSize) <= (bigy) && (startY >= lowy) && quadSize <= MAXSIZE) {
1176 scroff = image + (useY+((CIN_HEIGHT-bigy)>>1)+yOff)*(samplesPerLine) + (((startX+xOff))*samplesPerPixel);
1178 qStatus[0][onQuad ] = scroff;
1179 qStatus[1][onQuad++] = scroff+offset;
1182 if ( quadSize != MINSIZE ) {
1184 recurseQuad( startX, startY , quadSize, xOff, yOff );
1185 recurseQuad( startX+quadSize, startY , quadSize, xOff, yOff );
1186 recurseQuad( startX, startY+quadSize , quadSize, xOff, yOff );
1187 recurseQuad( startX+quadSize, startY+quadSize , quadSize, xOff, yOff );
1193 idCinematicLocal::setupQuad
1196 void idCinematicLocal::setupQuad( long xOff, long yOff ) {
1197 long numQuadCels, i,x,y;
1200 numQuadCels = (CIN_WIDTH*CIN_HEIGHT) / (16);
1201 numQuadCels += numQuadCels/4 + numQuadCels/16;
1202 numQuadCels += 64; // for overflow
1204 numQuadCels = (xsize*ysize) / (16);
1205 numQuadCels += numQuadCels/4;
1206 numQuadCels += 64; // for overflow
1210 for(y=0;y<(long)ysize;y+=16)
1211 for(x=0;x<(long)xsize;x+=16)
1212 recurseQuad( x, y, 16, xOff, yOff );
1216 for(i=(numQuadCels-64);i<numQuadCels;i++) {
1217 qStatus[0][i] = temp; // eoq
1218 qStatus[1][i] = temp; // eoq
1224 idCinematicLocal::readQuadInfo
1227 void idCinematicLocal::readQuadInfo( byte *qData ) {
1228 xsize = qData[0]+qData[1]*256;
1229 ysize = qData[2]+qData[3]*256;
1230 maxsize = qData[4]+qData[5]*256;
1231 minsize = qData[6]+qData[7]*256;
1236 samplesPerLine = CIN_WIDTH*samplesPerPixel;
1237 screenDelta = CIN_HEIGHT*samplesPerLine;
1240 image = (byte *)Mem_Alloc( CIN_WIDTH*CIN_HEIGHT*samplesPerPixel*2 );
1244 smootheddouble = false;
1246 t[0] = (0 - (unsigned int)image)+(unsigned int)image+screenDelta;
1247 t[1] = (0 - ((unsigned int)image + screenDelta))+(unsigned int)image;
1255 idCinematicLocal::RoQPrepMcomp
1258 void idCinematicLocal::RoQPrepMcomp( long xoff, long yoff ) {
1259 long i, j, x, y, temp, temp2;
1261 i=samplesPerLine; j=samplesPerPixel;
1262 if ( xsize == (ysize*4) && !half ) { j = j+j; i = i+i; }
1265 temp2 = (y+yoff-8)*i;
1267 temp = (x+xoff-8)*j;
1268 mcomp[(x*16)+y] = normalBuffer0-(temp2+temp);
1275 idCinematicLocal::RoQReset
1278 void idCinematicLocal::RoQReset() {
1280 iFile->Seek( 0, FS_SEEK_SET );
1281 iFile->Read( file, 16 );
1283 status = FMV_LOOPED;
1288 struct jpeg_source_mgr pub; /* public fields */
1290 byte *infile; /* source stream */
1291 JOCTET * buffer; /* start of buffer */
1292 boolean start_of_file; /* have we gotten any data yet? */
1296 typedef my_source_mgr * my_src_ptr;
1298 #define INPUT_BUF_SIZE 32768 /* choose an efficiently fread'able size */
1300 /* jpeg error handling */
1301 struct jpeg_error_mgr jerr;
1304 * Fill the input buffer --- called whenever buffer is emptied.
1306 * In typical applications, this should read fresh data into the buffer
1307 * (ignoring the current state of next_input_byte & bytes_in_buffer),
1308 * reset the pointer & count to the start of the buffer, and return TRUE
1309 * indicating that the buffer has been reloaded. It is not necessary to
1310 * fill the buffer entirely, only to obtain at least one more byte.
1312 * There is no such thing as an EOF return. If the end of the file has been
1313 * reached, the routine has a choice of ERREXIT() or inserting fake data into
1314 * the buffer. In most cases, generating a warning message and inserting a
1315 * fake EOI marker is the best course of action --- this will allow the
1316 * decompressor to output however much of the image is there. However,
1317 * the resulting error message is misleading if the real problem is an empty
1318 * input file, so we handle that case specially.
1320 * In applications that need to be able to suspend compression due to input
1321 * not being available yet, a FALSE return indicates that no more data can be
1322 * obtained right now, but more may be forthcoming later. In this situation,
1323 * the decompressor will return to its caller (with an indication of the
1324 * number of scanlines it has read, if any). The application should resume
1325 * decompression after it has loaded more data into the input buffer. Note
1326 * that there are substantial restrictions on the use of suspension --- see
1327 * the documentation.
1329 * When suspending, the decompressor will back up to a convenient restart point
1330 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
1331 * indicate where the restart point will be if the current call returns FALSE.
1332 * Data beyond this point must be rescanned after resumption, so move it to
1333 * the front of the buffer rather than discarding it.
1337 METHODDEF boolean fill_input_buffer( j_decompress_ptr cinfo )
1339 my_src_ptr src = (my_src_ptr) cinfo->src;
1342 nbytes = INPUT_BUF_SIZE;
1343 if (nbytes > src->memsize) nbytes = src->memsize;
1345 /* Insert a fake EOI marker */
1346 src->buffer[0] = (JOCTET) 0xFF;
1347 src->buffer[1] = (JOCTET) JPEG_EOI;
1350 memcpy( src->buffer, src->infile, INPUT_BUF_SIZE );
1351 src->infile = src->infile + nbytes;
1352 src->memsize = src->memsize - INPUT_BUF_SIZE;
1354 src->pub.next_input_byte = src->buffer;
1355 src->pub.bytes_in_buffer = nbytes;
1356 src->start_of_file = FALSE;
1361 * Initialize source --- called by jpeg_read_header
1362 * before any data is actually read.
1366 METHODDEF void init_source (j_decompress_ptr cinfo)
1368 my_src_ptr src = (my_src_ptr) cinfo->src;
1370 /* We reset the empty-input-file flag for each image,
1371 * but we don't clear the input buffer.
1372 * This is correct behavior for reading a series of images from one source.
1374 src->start_of_file = TRUE;
1378 * Skip data --- used to skip over a potentially large amount of
1379 * uninteresting data (such as an APPn marker).
1381 * Writers of suspendable-input applications must note that skip_input_data
1382 * is not granted the right to give a suspension return. If the skip extends
1383 * beyond the data currently in the buffer, the buffer can be marked empty so
1384 * that the next read will cause a fill_input_buffer call that can suspend.
1385 * Arranging for additional bytes to be discarded before reloading the input
1386 * buffer is the application writer's problem.
1390 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
1392 my_src_ptr src = (my_src_ptr) cinfo->src;
1394 /* Just a dumb implementation for now. Could use fseek() except
1395 * it doesn't work on pipes. Not clear that being smart is worth
1396 * any trouble anyway --- large skips are infrequent.
1398 if (num_bytes > 0) {
1399 src->infile = src->infile + num_bytes;
1400 src->pub.next_input_byte += (size_t) num_bytes;
1401 src->pub.bytes_in_buffer -= (size_t) num_bytes;
1407 * An additional method that can be provided by data source modules is the
1408 * resync_to_restart method for error recovery in the presence of RST markers.
1409 * For the moment, this source module just uses the default resync method
1410 * provided by the JPEG library. That method assumes that no backtracking
1416 * Terminate source --- called by jpeg_finish_decompress
1417 * after all data has been read. Often a no-op.
1419 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
1420 * application must deal with any cleanup that should happen even
1425 term_source (j_decompress_ptr cinfo)
1428 /* no work necessary here */
1432 jpeg_memory_src (j_decompress_ptr cinfo, byte *infile, int size)
1436 /* The source object and input buffer are made permanent so that a series
1437 * of JPEG images can be read from the same file by calling jpeg_stdio_src
1438 * only before the first one. (If we discarded the buffer at the end of
1439 * one image, we'd likely lose the start of the next one.)
1440 * This makes it unsafe to use this manager and a different source
1441 * manager serially with the same JPEG object. Caveat programmer.
1443 if (cinfo->src == NULL) { /* first time for this JPEG object? */
1444 cinfo->src = (struct jpeg_source_mgr *)
1445 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
1446 sizeof(my_source_mgr));
1447 src = (my_src_ptr) cinfo->src;
1448 src->buffer = (JOCTET *)
1449 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
1450 INPUT_BUF_SIZE * sizeof(JOCTET));
1453 src = (my_src_ptr) cinfo->src;
1454 src->pub.init_source = init_source;
1455 src->pub.fill_input_buffer = fill_input_buffer;
1456 src->pub.skip_input_data = skip_input_data;
1457 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
1458 src->pub.term_source = term_source;
1459 src->infile = infile;
1460 src->memsize = size;
1461 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
1462 src->pub.next_input_byte = NULL; /* until buffer loaded */
1465 int JPEGBlit( byte *wStatus, byte *data, int datasize )
1467 /* This struct contains the JPEG decompression parameters and pointers to
1468 * working space (which is allocated as needed by the JPEG library).
1470 struct jpeg_decompress_struct cinfo;
1471 /* We use our private extension JPEG error handler.
1472 * Note that this struct must live as long as the main JPEG parameter
1473 * struct, to avoid dangling-pointer problems.
1476 JSAMPARRAY buffer; /* Output row buffer */
1477 int row_stride; /* physical row width in output buffer */
1479 /* Step 1: allocate and initialize JPEG decompression object */
1481 /* We set up the normal JPEG error routines, then override error_exit. */
1482 cinfo.err = jpeg_std_error(&jerr);
1484 /* Now we can initialize the JPEG decompression object. */
1485 jpeg_create_decompress(&cinfo);
1487 /* Step 2: specify data source (eg, a file) */
1489 jpeg_memory_src(&cinfo, data, datasize);
1491 /* Step 3: read file parameters with jpeg_read_header() */
1493 (void) jpeg_read_header(&cinfo, TRUE);
1494 /* We can ignore the return value from jpeg_read_header since
1495 * (a) suspension is not possible with the stdio data source, and
1496 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
1497 * See libjpeg.doc for more info.
1500 /* Step 4: set parameters for decompression */
1502 /* In this example, we don't need to change any of the defaults set by
1503 * jpeg_read_header(), so we do nothing here.
1506 /* Step 5: Start decompressor */
1508 cinfo.dct_method = JDCT_IFAST;
1509 cinfo.dct_method = JDCT_FASTEST;
1510 cinfo.dither_mode = JDITHER_NONE;
1511 cinfo.do_fancy_upsampling = FALSE;
1512 // cinfo.out_color_space = JCS_GRAYSCALE;
1514 (void) jpeg_start_decompress(&cinfo);
1515 /* We can ignore the return value since suspension is not possible
1516 * with the stdio data source.
1519 /* We may need to do some setup of our own at this point before reading
1520 * the data. After jpeg_start_decompress() we have the correct scaled
1521 * output image dimensions available, as well as the output colormap
1522 * if we asked for color quantization.
1523 * In this example, we need to make an output work buffer of the right size.
1525 /* JSAMPLEs per row in output buffer */
1526 row_stride = cinfo.output_width * cinfo.output_components;
1528 /* Make a one-row-high sample array that will go away when done with image */
1529 buffer = (*cinfo.mem->alloc_sarray)
1530 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
1532 /* Step 6: while (scan lines remain to be read) */
1533 /* jpeg_read_scanlines(...); */
1535 /* Here we use the library's state variable cinfo.output_scanline as the
1536 * loop counter, so that we don't have to keep track ourselves.
1539 wStatus += (cinfo.output_height-1)*row_stride;
1540 while (cinfo.output_scanline < cinfo.output_height) {
1541 /* jpeg_read_scanlines expects an array of pointers to scanlines.
1542 * Here the array is only one element long, but you could ask for
1543 * more than one scanline at a time if that's more convenient.
1545 (void) jpeg_read_scanlines(&cinfo, &buffer[0], 1);
1547 /* Assume put_scanline_someplace wants a pointer and sample count. */
1548 memcpy( wStatus, &buffer[0][0], row_stride );
1551 unsigned int *buf = (unsigned int *)&buffer[0][0];
1552 unsigned int *out = (unsigned int *)wStatus;
1553 for(x=0;x<cinfo.output_width;x++) {
1554 unsigned int pixel = buf[x];
1555 byte *roof = (byte *)&pixel;
1556 byte temp = roof[0];
1562 wStatus -= row_stride;
1565 /* Step 7: Finish decompression */
1567 (void) jpeg_finish_decompress(&cinfo);
1568 /* We can ignore the return value since suspension is not possible
1569 * with the stdio data source.
1572 /* Step 8: Release JPEG decompression object */
1574 /* This is an important step since it will release a good deal of memory. */
1575 jpeg_destroy_decompress(&cinfo);
1577 /* At this point you may want to check to see whether any corrupt-data
1578 * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
1581 /* And we're done! */
1587 idCinematicLocal::RoQInterrupt
1590 void idCinematicLocal::RoQInterrupt(void) {
1593 iFile->Read( file, RoQFrameSize+8 );
1594 if ( RoQPlayed >= ROQSize ) {
1605 // new frame is ready
1612 normalBuffer0 = t[1];
1613 RoQPrepMcomp( roqF0, roqF1 );
1614 blitVQQuad32fs( qStatus[1], framedata);
1615 buf = image + screenDelta;
1617 normalBuffer0 = t[0];
1618 RoQPrepMcomp( roqF0, roqF1 );
1619 blitVQQuad32fs( qStatus[0], framedata );
1622 if (numQuads == 0) { // first frame
1623 memcpy(image+screenDelta, image, samplesPerLine*ysize);
1629 decodeCodeBook( framedata, (unsigned short)roq_flags );
1633 case ZA_SOUND_STEREO:
1636 if (numQuads == -1) {
1637 readQuadInfo( framedata );
1640 if (numQuads != 1) numQuads = 0;
1643 inMemory = ( roq_flags != 0 );
1644 RoQFrameSize = 0; // for header
1651 normalBuffer0 = t[0];
1652 JPEGBlit( image, framedata, RoQFrameSize );
1653 memcpy(image+screenDelta, image, samplesPerLine*ysize);
1662 // read in next frame data
1664 if ( RoQPlayed >= ROQSize ) {
1673 framedata += RoQFrameSize;
1674 roq_id = framedata[0] + framedata[1]*256;
1675 RoQFrameSize = framedata[2] + framedata[3]*256 + framedata[4]*65536;
1676 roq_flags = framedata[6] + framedata[7]*256;
1677 roqF0 = (char)framedata[7];
1678 roqF1 = (char)framedata[6];
1680 if (RoQFrameSize>65536||roq_id==0x1084) {
1681 common->DPrintf("roq_size>65536||roq_id==0x1084\n");
1688 if (inMemory && (status != FMV_EOF)) {
1689 inMemory = false; framedata += 8; goto redump;
1692 // one more frame hits the dust
1694 // assert(RoQFrameSize <= 65536);
1695 // r = Sys_StreamedRead( file, RoQFrameSize+8, 1, iFile );
1696 RoQPlayed += RoQFrameSize+8;
1701 idCinematicLocal::RoQ_init
1704 void idCinematicLocal::RoQ_init( void ) {
1708 /* get frame rate */
1709 roqFPS = file[ 6] + file[ 7]*256;
1711 if (!roqFPS) roqFPS = 30;
1715 roq_id = file[ 8] + file[ 9]*256;
1716 RoQFrameSize= file[10] + file[11]*256 + file[12]*65536;
1717 roq_flags = file[14] + file[15]*256;
1722 idCinematicLocal::RoQShutdown
1725 void idCinematicLocal::RoQShutdown( void ) {
1726 if ( status == FMV_IDLE ) {
1732 fileSystem->CloseFile( iFile );
1739 //===========================================
1743 idSndWindow::InitFromFile
1746 bool idSndWindow::InitFromFile( const char *qpath, bool looping ) {
1747 idStr fname = qpath;
1750 if ( !fname.Icmp( "waveform" ) ) {
1751 showWaveform = true;
1753 showWaveform = false;
1760 idSndWindow::ImageForTime
1763 cinData_t idSndWindow::ImageForTime( int milliseconds ) {
1764 return soundSystem->ImageForTime( milliseconds, showWaveform );
1769 idSndWindow::AnimationLength
1772 int idSndWindow::AnimationLength() {