28 static int mve_playing;
31 static int micro_frame_delay = 0;
32 static int timer_started = 0;
34 static struct timeval timer_expire = { 0, 0 };
36 static int timer_expire;
40 #define MVE_AUDIO_BUFFERS 64 // total buffers to interact with stream
41 static int mve_audio_buffer_tail = 0;
42 static int mve_audio_playing = 0;
43 static int mve_audio_canplay = 0;
44 static int mve_audio_compressed = 0;
45 static int audiobuf_created;
73 static GLfloat glVertices[4][4] = {{0}};
74 static int g_screenWidth, g_screenHeight;
75 static float g_screenX, g_screenY;
76 static int g_truecolor = 0;
77 static ubyte g_palette[768];
78 static ubyte *g_pCurMap = NULL;
79 static int g_nMapLength = 0;
80 static int videobuf_created, video_inited;
82 static uint mve_video_skiptimer = 0;
83 static int mve_scale_video = 0;
111 micro_frame_delay = rate * subd;
116 static void mve_timer_start(
void)
121 gettimeofday(&timer_expire, NULL);
123 timer_expire.tv_usec += micro_frame_delay;
125 if (timer_expire.tv_usec > 1000000) {
126 nsec = timer_expire.tv_usec / 1000000;
127 timer_expire.tv_sec += nsec;
128 timer_expire.tv_usec -= nsec * 1000000;
132 timer_expire += micro_frame_delay;
138 static int mve_do_timer_wait(
void)
140 if (!timer_started) {
146 struct timespec ts, tsRem;
149 gettimeofday(&tv, NULL);
151 if (tv.tv_sec > timer_expire.tv_sec) {
155 if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) ) {
159 ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
160 ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
162 if (ts.tv_nsec < 0) {
163 ts.tv_nsec += 1000000000UL;
167 if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
169 if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
170 mprintf((
"MVE: Timer error! Aborting movie playback!\n"));
176 timer_expire.tv_usec += micro_frame_delay;
178 if (timer_expire.tv_usec > 1000000) {
179 nsec = timer_expire.tv_usec / 1000000;
180 timer_expire.tv_sec += nsec;
181 timer_expire.tv_usec -= nsec * 1000000;
188 if (tv > timer_expire) {
192 ts = timer_expire - tv;
197 timer_expire += micro_frame_delay;
203 static void mve_timer_stop()
206 timer_expire.tv_sec = 0;
207 timer_expire.tv_usec = 0;
221 if (audiobuf_created) {
227 mve_audio_canplay = 0;
231 int flags, sample_rate;
241 mas->
channels = (flags & 0x0001) ? 2 : 1;
242 mas->
bitsize = (flags & 0x0002) ? 16 : 8;
247 mve_audio_compressed = flags & 0x0004 ? 1 : 0;
249 mve_audio_compressed = 0;
254 mas->
format = AL_FORMAT_STEREO16;
256 mas->
format = AL_FORMAT_MONO16;
258 }
else if (mas->
bitsize == 8) {
260 mas->
format = AL_FORMAT_STEREO8;
262 mas->
format = AL_FORMAT_MONO8;
267 if (mas->
format == AL_INVALID) {
268 mve_audio_canplay = 0;
269 audiobuf_created = 1;
275 mve_audio_canplay = 1;
281 mve_audio_buffer_tail = 0;
283 audiobuf_created = 1;
289 if (mve_audio_canplay) {
290 ALint status, bqueued;
296 mve_audio_playing = 1;
298 if (status != AL_PLAYING && bqueued > 0) {
305 static void mve_audio_stop()
307 if (!audiobuf_created || mas == NULL) {
313 mve_audio_playing = 0;
335 static const int selected_chan=1;
339 if (mve_audio_canplay) {
343 if (chan & selected_chan) {
344 ALint bprocessed, bqueued, status;
349 while (bprocessed-- > 2) {
356 mprintf((
"MVE: Buffer underun (First is normal)\n"));
361 if ( (mve_audio_playing) && (status != AL_PLAYING) && (bqueued > 0) ) {
365 if (bqueued < MVE_AUDIO_BUFFERS) {
370 if (mve_audio_compressed) {
378 memcpy(buf, data, nsamp);
382 memset(buf, 0, nsamp);
395 if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS) {
396 mve_audio_buffer_tail = 0;
402 mprintf((
"MVE: Buffer overrun: Queue full\n"));
416 if (videobuf_created) {
437 nprintf((
"MOVIE",
"ERROR: Can't allocate video buffer"));
438 videobuf_created = 1;
449 g_truecolor = truecolor;
450 videobuf_created = 1;
458 if (screen_ratio > movie_ratio) {
474 if (mve_scale_video) {
486 gl_screenXW = g_screenX +
g_width;
488 gl_screenU =
i2fl(g_width) /
i2fl(wp2);
489 gl_screenV =
i2fl(g_height) /
i2fl(hp2);
492 glVertices[0][0] = g_screenX;
493 glVertices[0][1] = g_screenY;
494 glVertices[0][2] = 0;
495 glVertices[0][3] = 0;
497 glVertices[1][0] = g_screenX;
498 glVertices[1][1] = gl_screenYH;
499 glVertices[1][2] = 0;
500 glVertices[1][3] = gl_screenV;
502 glVertices[2][0] = gl_screenXW;
503 glVertices[2][1] = g_screenY;
504 glVertices[2][2] = gl_screenU;
505 glVertices[2][3] = 0;
507 glVertices[3][0] = gl_screenXW;
508 glVertices[3][1] = gl_screenYH;
509 glVertices[3][2] = gl_screenU;
510 glVertices[3][3] = gl_screenV;
525 static void mve_convert_and_draw()
532 ubyte *pSrcs8 = NULL;
546 pDests += ((g_screenWidth -
g_width) / 2) / 2;
549 pDests += ((g_screenHeight -
g_height) / 2) * g_screenWidth;
554 for (x = 0; x <
g_width; x++) {
557 pDests[
x] = (1<<15)|*pSrcs;
563 r = (g_palette[(*pSrcs8)*3] / 2);
564 g = (g_palette[(*pSrcs8)*3 + 1] / 2);
565 b = (g_palette[(*pSrcs8)*3 + 2] / 2);
574 pDests[
x] = (1<<15)|bit_16;
580 pDests += g_screenWidth;
589 mve_convert_and_draw();
593 if ( mve_video_skiptimer > (
uint)(micro_frame_delay/10) ) {
595 mve_video_skiptimer -= (micro_frame_delay/10);
599 mve_video_skiptimer = 0;
620 if ( mve_video_skiptimer == 0 ) {
623 mve_video_skiptimer = (
uint)(
f2fl(t2-t1) * 100000);
648 g_screenWidth =
width;
655 nprintf((
"MOVIE",
"ERROR: Can't allocate memory for pixelbuf"));
660 memset(
pixelbuf, 0, g_screenWidth * g_screenHeight * 2);
671 nprintf((
"MOVIE",
"ERROR: Can't create a GL texture"));
699 memset(g_palette, 0, 768);
710 memcpy(g_palette + 3*start, data+4, 3*count);
747 mve_audio_buffer_tail = 0;
748 mve_audio_playing = 0;
749 mve_audio_canplay = 0;
750 mve_audio_compressed = 0;
751 audiobuf_created = 0;
753 videobuf_created = 0;
762 int init_timer = 0, timer_error = 0;
765 if (!timer_started) {
769 while (cont && mve_playing && !timer_error) {
772 if (micro_frame_delay && !init_timer) {
777 timer_error = mve_do_timer_wait();
784 if (mve_scale_video) {
ushort mve_get_ushort(ubyte *data)
#define OpenAL_ErrorCheck(x, y)
WINGDIAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
int mve_get_int(ubyte *data)
GLfloat GLfloat GLfloat GLfloat h
void mve_video_data(ubyte *data, int len)
void Color(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha=255)
void SetTextureSource(gr_texture_source ts)
WINGDIAPI void APIENTRY glMatrixMode(GLenum mode)
int timer_get_microseconds()
WINGDIAPI void APIENTRY glLoadIdentity(void)
WINGDIAPI void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
void SetZbufferType(gr_zbuffer_type zt)
#define OpenAL_ErrorPrint(x)
ALuint *typedef ALuint *typedef ALenum
#define GL_UNSIGNED_SHORT_1_5_5_5_REV
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
opengl_texture_state Texture
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
void mve_init(MVESTREAM *mve)
GLenum GLuint GLenum GLsizei const GLchar * buf
#define GL_TEXTURE_WRAP_S
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
void mveaudio_uncompress(short *buffer, unsigned char *data)
WINGDIAPI void APIENTRY glPopMatrix(void)
void mve_audio_createbuf(ubyte minor, ubyte *data)
int mve_timer_create(ubyte *data)
void mve_video_codemap(ubyte *data, int len)
GLdouble GLdouble GLdouble r
short mve_get_short(ubyte *data)
void add_vertex_component(vertex_format_data::vertex_format format_type, uint stride, void *src)
ALuint *typedef ALuint *typedef ALint
WINGDIAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures)
void SetAlphaBlendMode(gr_alpha_blend ab)
WINGDIAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
GLenum GL_previous_texture_target
#define MVE_AUDIO_BUFFERS
#define GL_TEXTURE_MAG_FILTER
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
void SetTarget(GLenum tex_target)
void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out)
GLint GLint GLint GLint GLint x
void Enable(GLuint tex_id=0)
int bm_create(int bpp, int w, int h, void *data, int flags)
int mve_play_next_chunk(MVESTREAM *stream)
struct MVE_AUDIO_T mve_audio_t
void BindArrayBuffer(GLuint id)
int mve_video_createbuf(ubyte minor, ubyte *data)
GLboolean GLboolean GLboolean b
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define GL_TEXTURE_WRAP_T
void mve_video_palette(ubyte *data)
GLint GLsizei GLsizei height
WINGDIAPI void APIENTRY glPushMatrix(void)
fix timer_get_fixed_seconds()
#define GL_TEXTURE_MIN_FILTER
void opengl_set_texture_target(GLenum target)
int mve_audio_data(ubyte major, ubyte *data)
GLenum GLsizei GLenum GLenum const GLvoid * data
int mve_video_init(ubyte *data)
ALuint audio_buffer[MVE_AUDIO_BUFFERS]
void Delete(GLuint tex_id)
void gr_bitmap(int _x, int _y, int resize_mode)
WINGDIAPI void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
WINGDIAPI void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
WINGDIAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
void mve_play(MVESTREAM *mve)
void opengl_bind_vertex_layout(vertex_layout &layout)
void SetActiveUnit(GLuint id=0)
#define GL_TRIANGLE_STRIP