29 #include "../client.h"
30 #include "../renderer/r_draw.h"
31 #include "../sound/s_main.h"
32 #include "../sound/s_music.h"
41 #define ROQ_IDENT 0x1084
43 #define ROQ_QUAD_INFO 0x1001
44 #define ROQ_QUAD_CODEBOOK 0x1002
45 #define ROQ_QUAD_VQ 0x1011
46 #define ROQ_SOUND_MONO 0x1020
47 #define ROQ_SOUND_STEREO 0x1021
49 #define ROQ_CHUNK_HEADER_SIZE 8
51 #define ROQ_MAX_CHUNK_SIZE 65536
53 #define ROQ_SOUND_RATE 22050
55 #define ROQ_ID_FCC 0x4000
56 #define ROQ_ID_SLD 0x8000
57 #define ROQ_ID_CCC 0xC000
81 unsigned* frameBuffer[2];
102 #define ROQCIN (*((roqCinematic_t*)cin->codecData))
123 for (
int i = 0;
i < 4;
i++) {
125 const int yp = y + roqCin_quadOffsets2[1][
i];
126 const unsigned int* src = (
const unsigned int*)
ROQCIN.quadVectors + (indices[
i] * 4);
127 unsigned* dst =
ROQCIN.frameBuffer[0] + (yp *
ROQCIN.frameWidth + xp);
144 for (
int i = 0;
i < 4;
i++) {
146 const int yp = y + roqCin_quadOffsets4[1][
i];
147 const unsigned int* src = (
const unsigned int*)
ROQCIN.quadVectors + (indices[
i] * 4);
148 unsigned* dst =
ROQCIN.frameBuffer[0] + (yp *
ROQCIN.frameWidth + xp);
183 const int xp = x + 8 - (mv >> 4) - mx;
184 const int yp = y + 8 - (mv & 15) - my;
185 unsigned const* src =
ROQCIN.frameBuffer[1] + (yp *
ROQCIN.frameWidth + xp);
186 unsigned* dst =
ROQCIN.frameBuffer[0] + (y *
ROQCIN.frameWidth + x);
188 for (
int i = 0;
i < 4;
i++, src +=
ROQCIN.frameWidth, dst +=
ROQCIN.frameWidth) {
201 const int xp = x + 8 - (mv >> 4) - mx;
202 const int yp = y + 8 - (mv & 15) - my;
203 unsigned const* src =
ROQCIN.frameBuffer[1] + (yp *
ROQCIN.frameWidth + xp);
204 unsigned* dst =
ROQCIN.frameBuffer[0] + (y *
ROQCIN.frameWidth + x);
206 for (
int i = 0;
i < 8;
i++, src +=
ROQCIN.frameWidth, dst +=
ROQCIN.frameWidth) {
227 ROQCIN.frameWidth = data[0] | (data[1] << 8);
228 ROQCIN.frameHeight = data[2] | (data[3] << 8);
245 int numQuadVectors, numQuadCells;
248 numQuadVectors = (
ROQCIN.chunk.flags >> 8) & 0xFF;
249 numQuadCells = (
ROQCIN.chunk.flags >> 0) & 0xFF;
252 numQuadVectors = 256;
254 numQuadVectors = 256;
259 for (
int i = 0;
i < numQuadVectors;
i++) {
260 const int r = roqCin_yuvTable.
vr[data[5]];
261 const int g = roqCin_yuvTable.
ug[data[4]] + roqCin_yuvTable.
vg[data[5]];
262 const int b = roqCin_yuvTable.
ub[data[4]];
288 for (
int i = 0;
i < numQuadCells;
i++) {
289 ROQCIN.quadCells[
i].index[0] = data[0];
290 ROQCIN.quadCells[
i].index[1] = data[1];
291 ROQCIN.quadCells[
i].index[2] = data[2];
292 ROQCIN.quadCells[
i].index[3] = data[3];
312 const int xMot = (char)((
ROQCIN.chunk.flags >> 8) & 0xFF);
313 const int yMot = (char)((
ROQCIN.chunk.flags >> 0) & 0xFF);
318 for (
int y = yPos; y < yPos + 16; y += 8) {
319 for (
int x = xPos; x < xPos + 16; x += 8) {
322 vqFlag = data[index + 0] | (data[index + 1] << 8);
341 for (
int i = 0;
i < 4;
i++) {
343 const int yp = y + roqCin_quadOffsets4[1][
i];
347 vqFlag = data[index + 0] | (data[index + 1] << 8);
378 if (xPos >=
ROQCIN.frameWidth) {
379 xPos -=
ROQCIN.frameWidth;
382 if (yPos >=
ROQCIN.frameHeight)
391 unsigned*
const buffer =
ROQCIN.frameBuffer[0];
393 ROQCIN.frameBuffer[1] = buffer;
409 for (
int j = 0; i <
ROQCIN.chunk.size; i++, j += 2) {
411 samples[j] = (short)prev;
412 samples[j + 1] = (short)prev;
426 short prevL = (
ROQCIN.chunk.flags & 0xFF00) << 0;
427 short prevR = (
ROQCIN.chunk.flags & 0x00FF) << 8;
429 for (i = 0; i <
ROQCIN.chunk.size; i += 2) {
433 samples[i + 0] = prevL;
434 samples[i + 1] = prevR;
449 const int frame =
ROQCIN.currentFrame;
473 switch (
ROQCIN.chunk.id) {
508 if (!
ROQCIN.frameBuffer[1])
530 Com_Printf(
"CIN_ROQ_StopCinematic: Warning no opened file\n");
547 Com_Printf(
"WARNING: it seams there was already a roq running, it will be killed to start %s\n", fileName);
558 Com_Printf(
"Cinematic %s not found\n", fileName);
572 Com_Printf(
"CIN_PlayCinematic: invalid RoQ header\n");
582 ROQCIN.offset =
sizeof(header);
589 ROQCIN.frameBuffer[0] =
nullptr;
591 ROQCIN.frameBuffer[1] =
nullptr;
607 for (
int i = 0;
i < 128;
i++) {
608 const short s = (short)(
i *
i);
614 for (
int i = 0;
i < 4;
i++) {
622 for (
int i = 0;
i < 256;
i++) {
623 const float f = (float)(
i - 128);
624 roqCin_yuvTable.
vr[
i] =
Q_ftol(f * 1.40200f);
625 roqCin_yuvTable.
ug[
i] =
Q_ftol(f * 0.34414f);
626 roqCin_yuvTable.
vg[
i] =
Q_ftol(f * 0.71414f);
627 roqCin_yuvTable.
ub[
i] =
Q_ftol(f * 1.77200f);
static void CIN_ROQ_DrawCinematic(cinematic_t *cin)
static bool CIN_ROQ_DecodeChunk(cinematic_t *cin)
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
static void CIN_ROQ_DecodeVideo(cinematic_t *cin, const byte *data)
static yuvTable_t roqCin_yuvTable
memPool_t * vid_genericPool
void Com_Printf(const char *const fmt,...)
static void CIN_ROQ_DecodeSoundMono(cinematic_t *cin, const byte *data)
static short roqCin_sqrTable[256]
static void CIN_ROQ_DecodeSoundStereo(cinematic_t *cin, const byte *data)
#define ROQ_CHUNK_HEADER_SIZE
memPool_t * cl_genericPool
void Com_Error(int code, const char *fmt,...)
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void R_DrawTexture(int texnum, int x, int y, int w, int h)
Bind and draw a texture.
#define ROQ_QUAD_CODEBOOK
static void CIN_ROQ_ApplyVector4x4(cinematic_t *cin, int x, int y, const byte *indices)
static int roqCin_quadOffsets4[2][4]
void CIN_ROQ_CloseCinematic(cinematic_t *cin)
void M_StopMusicStream(musicStream_t *userdata)
void FS_CloseFile(qFILE *f)
static void CIN_ROQ_DecodeInfo(cinematic_t *cin, const byte *data)
static void CIN_ROQ_ApplyMotion4x4(cinematic_t *cin, int x, int y, int mx, int my, int mv)
static void CIN_ROQ_DecodeCodeBook(cinematic_t *cin, const byte *data)
int R_UploadData(const char *name, unsigned *frame, int width, int height)
Uploads image data.
bool CIN_ROQ_RunCinematic(cinematic_t *cin)
int CIN_ROQ_OpenCinematic(cinematic_t *cin, const char *fileName)
#define Mem_PoolAllocTypeN(type, n, pool)
musicStream_t musicStream
Header file for ROQ cinematics.
int FS_Read(void *buffer, int len, qFILE *f)
void M_AddToSampleBuffer(musicStream_t *userdata, int rate, int samples, const byte *data)
Add stereo samples with a 16 byte width to the stream buffer.
static void CIN_ROQ_ApplyVector2x2(cinematic_t *cin, int x, int y, const byte *indices)
static void CIN_ROQ_ApplyMotion8x8(cinematic_t *cin, int x, int y, int mx, int my, int mv)
GLsizei const GLvoid * data
#define Mem_PoolAllocType(type, pool)
bool Q_IsPowerOfTwo(int i)
Checks whether i is power of two value.
static byte CIN_ROQ_ClampByte(int value)
Clamps integer value into byte.
Header file for cinematics.
#define ROQ_MAX_CHUNK_SIZE
int CL_Milliseconds(void)
static int roqCin_quadOffsets2[2][4]