mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-21 19:31:13 +00:00
parent
88079c9c70
commit
bd5685d201
3 changed files with 163 additions and 0 deletions
|
@ -1785,6 +1785,8 @@ int plm_demux_has_headers(plm_demux_t *self) {
|
|||
plm_buffer_skip(self->buffer, 5); // misc flags
|
||||
self->num_video_streams = plm_buffer_read(self->buffer, 5);
|
||||
|
||||
/* hack for heretic2 */
|
||||
self->num_video_streams = 1;
|
||||
self->has_system_header = TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "input/header/input.h"
|
||||
#include "cinema/smacker.h"
|
||||
|
||||
#define PL_MPEG_IMPLEMENTATION
|
||||
#include "cinema/pl_mpeg.h"
|
||||
|
||||
// don't need HDR stuff
|
||||
#define STBI_NO_LINEAR
|
||||
#define STBI_NO_HDR
|
||||
|
@ -60,6 +63,7 @@ typedef enum
|
|||
{
|
||||
video_cin,
|
||||
video_smk,
|
||||
video_mpg
|
||||
} cinema_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -89,9 +93,14 @@ typedef struct
|
|||
|
||||
/* shared video buffer */
|
||||
void *raw_video;
|
||||
byte *audio_buf;
|
||||
size_t audio_pos;
|
||||
|
||||
/* smacker video */
|
||||
smk smk_video;
|
||||
|
||||
/* mpg video */
|
||||
plm_t *plm_video;
|
||||
} cinematics_t;
|
||||
|
||||
cinematics_t cin;
|
||||
|
@ -206,6 +215,18 @@ SCR_StopCinematic(void)
|
|||
cin.smk_video = NULL;
|
||||
}
|
||||
|
||||
if (cin.plm_video)
|
||||
{
|
||||
plm_destroy(cin.plm_video);
|
||||
cin.plm_video = NULL;
|
||||
}
|
||||
|
||||
if (cin.audio_buf)
|
||||
{
|
||||
Z_Free(cin.audio_buf);
|
||||
cin.audio_buf = NULL;
|
||||
}
|
||||
|
||||
if (cin.raw_video)
|
||||
{
|
||||
FS_FreeFile(cin.raw_video);
|
||||
|
@ -413,6 +434,79 @@ Huff1Decompress(cblock_t in)
|
|||
return out;
|
||||
}
|
||||
|
||||
static byte *
|
||||
SCR_ReadNextMPGFrame(void)
|
||||
{
|
||||
size_t count, i;
|
||||
byte *buffer;
|
||||
plm_frame_t *frame;
|
||||
|
||||
if (plm_has_ended(cin.plm_video))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = cin.height * cin.width * cin.color_bits / 8;
|
||||
buffer = Z_Malloc(count);
|
||||
frame = plm_decode_video(cin.plm_video);
|
||||
if (!frame)
|
||||
{
|
||||
Z_Free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
plm_frame_to_rgba(frame, buffer, frame->width * 4);
|
||||
|
||||
/* force untransparent image show */
|
||||
for (i=0; i < count; i += 4)
|
||||
{
|
||||
buffer[i + 3] = 255;
|
||||
}
|
||||
|
||||
if (cin.s_channels > 0)
|
||||
{
|
||||
/* Fix here if audio not in sync */
|
||||
count = cin.s_rate * cin.s_channels * cin.s_width / cin.fps;
|
||||
/* round up to channels and width */
|
||||
count = (count + (cin.s_channels * cin.s_width) - 1) & (~(cin.s_channels * cin.s_width) - 1);
|
||||
/* load enough sound data for single frame*/
|
||||
while (cin.audio_pos < count && cin.s_channels > 0)
|
||||
{
|
||||
plm_samples_t *samples;
|
||||
short *audiobuffer;
|
||||
|
||||
samples = plm_decode_audio(cin.plm_video);
|
||||
if (!samples || samples->count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
audiobuffer = (short *)(cin.audio_buf + cin.audio_pos);
|
||||
for (i=0; i < samples->count * cin.s_channels; i++)
|
||||
{
|
||||
audiobuffer[i] = samples->interleaved[i] * (1 << 15);
|
||||
}
|
||||
|
||||
cin.audio_pos += samples->count * cin.s_channels * cin.s_width;
|
||||
}
|
||||
|
||||
if (count > cin.audio_pos)
|
||||
{
|
||||
count = cin.audio_pos;
|
||||
}
|
||||
|
||||
S_RawSamples(count / (cin.s_width * cin.s_channels), cin.s_rate, cin.s_width, cin.s_channels,
|
||||
cin.audio_buf, Cvar_VariableValue("s_volume"));
|
||||
|
||||
/* cleanup already played buffer part */
|
||||
memmove(cin.audio_buf, cin.audio_buf + count, cin.audio_pos - count);
|
||||
cin.audio_pos -= count;
|
||||
}
|
||||
|
||||
cl.cinematicframe++;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static byte *
|
||||
SCR_ReadNextSMKFrame(void)
|
||||
{
|
||||
|
@ -584,6 +678,9 @@ SCR_RunCinematic(void)
|
|||
case video_smk:
|
||||
cin.pic_pending = SCR_ReadNextSMKFrame();
|
||||
break;
|
||||
case video_mpg:
|
||||
cin.pic_pending = SCR_ReadNextMPGFrame();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cin.pic_pending)
|
||||
|
@ -823,6 +920,69 @@ SCR_PlayCinematic(char *arg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dot && !strcmp(dot, ".mpg"))
|
||||
{
|
||||
int len;
|
||||
|
||||
Com_sprintf(name, sizeof(name), "video/%s", arg);
|
||||
|
||||
len = FS_LoadFile(name, &cin.raw_video);
|
||||
if (!cin.raw_video || len <= 0)
|
||||
{
|
||||
cl.cinematictime = 0; /* done */
|
||||
return;
|
||||
}
|
||||
|
||||
cin.plm_video = plm_create_with_memory(cin.raw_video, len, 0);
|
||||
if (!cin.plm_video || !cin.plm_video->demux)
|
||||
{
|
||||
FS_FreeFile(cin.raw_video);
|
||||
cin.raw_video = NULL;
|
||||
cl.cinematictime = 0; /* done */
|
||||
return;
|
||||
}
|
||||
|
||||
SCR_EndLoadingPlaque();
|
||||
|
||||
cin.color_bits = 32;
|
||||
cls.state = ca_active;
|
||||
|
||||
plm_set_loop(cin.plm_video, 0);
|
||||
plm_set_audio_enabled(cin.plm_video, 1);
|
||||
plm_set_audio_stream(cin.plm_video, 0);
|
||||
|
||||
cin.fps = plm_get_framerate(cin.plm_video);
|
||||
cin.width = plm_get_width(cin.plm_video);
|
||||
cin.height = plm_get_height(cin.plm_video);
|
||||
|
||||
if (plm_get_num_audio_streams(cin.plm_video) == 0)
|
||||
{
|
||||
/* No Sound */
|
||||
cin.s_channels = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cin.s_rate = plm_get_samplerate(cin.plm_video);
|
||||
/* set to default 2 bytes with 2 channels */
|
||||
cin.s_width = 2;
|
||||
cin.s_channels = 2;
|
||||
|
||||
/* Adjust the audio lead time according to the audio_spec buffer size */
|
||||
plm_set_audio_lead_time(cin.plm_video, 1.0f / cin.fps);
|
||||
|
||||
/* Allocate audio buffer for 2 frames */
|
||||
cin.audio_buf = Z_Malloc(cin.s_channels * cin.s_width * cin.s_rate * 2 / cin.fps);
|
||||
cin.audio_pos = 0;
|
||||
}
|
||||
|
||||
cl.cinematicframe = 0;
|
||||
cin.pic = SCR_ReadNextMPGFrame();
|
||||
cl.cinematictime = Sys_Milliseconds();
|
||||
|
||||
cin.video_type = video_mpg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dot && !strcmp(dot, ".smk"))
|
||||
{
|
||||
unsigned char trackmask, channels[7], depth[7];
|
||||
|
|
|
@ -545,6 +545,7 @@ SV_Map(qboolean attractloop, char *levelstring, qboolean loadgame, qboolean isau
|
|||
}
|
||||
|
||||
if ((l > 4) && (!strcmp(level + l - 4, ".cin") ||
|
||||
!strcmp(level + l - 4, ".mpg") ||
|
||||
!strcmp(level + l - 4, ".smk")))
|
||||
{
|
||||
#ifndef DEDICATED_ONLY
|
||||
|
|
Loading…
Reference in a new issue