FS2_Open
Open source remastering of the Freespace 2 engine
mveplayer.cpp
Go to the documentation of this file.
1 
2 
3 #ifdef SCP_UNIX
4 #include <errno.h>
5 #include <time.h>
6 #include <sys/time.h>
7 #endif
8 
9 #include "bmpman/bmpman.h"
10 #include "cutscene/movie.h"
11 #include "cutscene/mvelib.h"
12 #include "globalincs/pstypes.h"
13 #include "graphics/2d.h"
14 #include "graphics/gropengl.h"
15 #include "graphics/gropengldraw.h"
17 #include "graphics/gropenglstate.h"
19 #include "io/key.h"
20 #include "io/timer.h"
21 #include "osapi/osapi.h"
22 #include "sound/openal.h"
23 #include "sound/sound.h"
24 
25 
26 extern int Cmdline_noscalevid;
27 
28 static int mve_playing;
29 
30 // timer variables
31 static int micro_frame_delay = 0;
32 static int timer_started = 0;
33 #ifdef SCP_UNIX
34 static struct timeval timer_expire = { 0, 0 };
35 #else
36 static int timer_expire;
37 #endif
38 
39 // audio variables
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;
46 
47 // struct for the audio stream information
48 typedef struct MVE_AUDIO_T {
52  int channels;
53  int bitsize;
54  ALuint source_id;
56 } mve_audio_t;
57 
58 mve_audio_t *mas; // mve_audio_stream
59 
60 // audio decompressor
61 extern void mveaudio_uncompress(short *buffer, unsigned char *data);
62 
63 // video variables
65 void *g_vBuffers = NULL;
67 ushort *pixelbuf = NULL;
68 static GLuint GLtex = 0;
69 static GLfloat gl_screenYH = 0;
70 static GLfloat gl_screenXW = 0;
71 static GLfloat gl_screenU = 0;
72 static GLfloat gl_screenV = 0;
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;
81 static int hp2, wp2;
82 static uint mve_video_skiptimer = 0;
83 static int mve_scale_video = 0;
84 
85 // video externs from API graphics functions
86 extern void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out);
88 
89 // the decoders
90 extern void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
91 extern void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain);
92 
93 
94 /*************************
95  * general handlers
96  *************************/
98 {
99  mve_playing = 0;
100 }
101 
102 /*************************
103  * timer handlers
104  *************************/
105 
107 {
108  int rate = mve_get_int(data);
109  int subd = mve_get_short(data+4);
110 
111  micro_frame_delay = rate * subd;
112 
113  return 1;
114 }
115 
116 static void mve_timer_start(void)
117 {
118 #ifdef SCP_UNIX
119  int nsec = 0;
120 
121  gettimeofday(&timer_expire, NULL);
122 
123  timer_expire.tv_usec += micro_frame_delay;
124 
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;
129  }
130 #else
131  timer_expire = timer_get_microseconds();
132  timer_expire += micro_frame_delay;
133 #endif
134 
135  timer_started = 1;
136 }
137 
138 static int mve_do_timer_wait(void)
139 {
140  if (!timer_started) {
141  return 0;
142  }
143 
144 #ifdef SCP_UNIX
145  int nsec = 0;
146  struct timespec ts, tsRem;
147  struct timeval tv;
148 
149  gettimeofday(&tv, NULL);
150 
151  if (tv.tv_sec > timer_expire.tv_sec) {
152  goto end;
153  }
154 
155  if ( (tv.tv_sec == timer_expire.tv_sec) && (tv.tv_usec >= timer_expire.tv_usec) ) {
156  goto end;
157  }
158 
159  ts.tv_sec = timer_expire.tv_sec - tv.tv_sec;
160  ts.tv_nsec = 1000 * (timer_expire.tv_usec - tv.tv_usec);
161 
162  if (ts.tv_nsec < 0) {
163  ts.tv_nsec += 1000000000UL;
164  --ts.tv_sec;
165  }
166 
167  if ( (nanosleep(&ts, &tsRem) == -1) && (errno == EINTR) ) {
168  // so we got an error that was a signal interupt, try to sleep again with remainder of time
169  if ( (nanosleep(&tsRem, NULL) == -1) && (errno == EINTR) ) {
170  mprintf(("MVE: Timer error! Aborting movie playback!\n"));
171  return 1;
172  }
173  }
174 
175 end:
176  timer_expire.tv_usec += micro_frame_delay;
177 
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;
182  }
183 #else
184  int tv, ts, ts2;
185 
186  tv = timer_get_microseconds();
187 
188  if (tv > timer_expire) {
189  goto end;
190  }
191 
192  ts = timer_expire - tv;
193  ts2 = ts/1000;
194  Sleep(ts2);
195 
196 end:
197  timer_expire += micro_frame_delay;
198 #endif
199 
200  return 0;
201 }
202 
203 static void mve_timer_stop()
204 {
205 #ifdef SCP_UNIX
206  timer_expire.tv_sec = 0;
207  timer_expire.tv_usec = 0;
208 #else
209  timer_expire = 0;
210 #endif
211  timer_started = 0;
212 }
213 
214 /*************************
215  * audio handlers
216  *************************/
217 
218 // setup the audio information from the data stream
220 {
221  if (audiobuf_created) {
222  return;
223  }
224 
225  // if game sound disabled don't try and play movie audio
226  if (!Sound_enabled) {
227  mve_audio_canplay = 0;
228  return;
229  }
230 
231  int flags, sample_rate;
232 
233  mas = (mve_audio_t *) vm_malloc ( sizeof(mve_audio_t) );
234  memset(mas, 0, sizeof(mve_audio_t));
235 
236  mas->format = AL_INVALID;
237 
238  flags = mve_get_ushort(data + 2);
239  sample_rate = mve_get_ushort(data + 4);
240 
241  mas->channels = (flags & 0x0001) ? 2 : 1;
242  mas->bitsize = (flags & 0x0002) ? 16 : 8;
243 
244  mas->sample_rate = sample_rate;
245 
246  if (minor > 0) {
247  mve_audio_compressed = flags & 0x0004 ? 1 : 0;
248  } else {
249  mve_audio_compressed = 0;
250  }
251 
252  if (mas->bitsize == 16) {
253  if (mas->channels == 2) {
254  mas->format = AL_FORMAT_STEREO16;
255  } else if (mas->channels == 1) {
256  mas->format = AL_FORMAT_MONO16;
257  }
258  } else if (mas->bitsize == 8) {
259  if (mas->channels == 2) {
260  mas->format = AL_FORMAT_STEREO8;
261  } else if (mas->channels == 1) {
262  mas->format = AL_FORMAT_MONO8;
263  }
264  }
265 
266  // somethings wrong, bail now
267  if (mas->format == AL_INVALID) {
268  mve_audio_canplay = 0;
269  audiobuf_created = 1;
270  return;
271  }
272 
273  OpenAL_ErrorCheck( alGenSources(1, &mas->source_id), { mve_audio_canplay = 0; return; } );
274 
275  mve_audio_canplay = 1;
276 
277  OpenAL_ErrorPrint( alSourcef(mas->source_id, AL_GAIN, 1.0f) );
278 
279  memset(mas->audio_buffer, 0, MVE_AUDIO_BUFFERS * sizeof(ALuint));
280 
281  mve_audio_buffer_tail = 0;
282 
283  audiobuf_created = 1;
284 }
285 
286 // play and stream the audio
288 {
289  if (mve_audio_canplay) {
290  ALint status, bqueued;
291 
292  OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return );
293 
294  OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return );
295 
296  mve_audio_playing = 1;
297 
298  if (status != AL_PLAYING && bqueued > 0) {
299  OpenAL_ErrorPrint( alSourcePlay(mas->source_id) );
300  }
301  }
302 }
303 
304 // call this in shutdown to stop and close audio
305 static void mve_audio_stop()
306 {
307  if (!audiobuf_created || mas == NULL) {
308  return;
309  }
310 
311  ALint p = 0;
312 
313  mve_audio_playing = 0;
314 
315  OpenAL_ErrorPrint( alSourceStop(mas->source_id) );
316  OpenAL_ErrorPrint( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &p) );
317  OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, p, mas->audio_buffer) );
318  OpenAL_ErrorPrint( alDeleteSources(1, &mas->source_id) );
319 
320  for (int i = 0; i < MVE_AUDIO_BUFFERS; i++) {
321  // make sure that the buffer is real before trying to delete, it could crash for some otherwise
322  if ( (mas->audio_buffer[i] != 0) && alIsBuffer(mas->audio_buffer[i]) ) {
323  OpenAL_ErrorPrint( alDeleteBuffers(1, &mas->audio_buffer[i]) );
324  }
325  }
326 
327  if (mas != NULL) {
328  vm_free(mas);
329  mas = NULL;
330  }
331 }
332 
334 {
335  static const int selected_chan=1;
336  int chan;
337  int nsamp;
338 
339  if (mve_audio_canplay) {
340  chan = mve_get_ushort(data + 2);
341  nsamp = mve_get_ushort(data + 4);
342 
343  if (chan & selected_chan) {
344  ALint bprocessed, bqueued, status;
345  ALuint bid;
346 
347  OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_PROCESSED, &bprocessed), return 0 );
348 
349  while (bprocessed-- > 2) {
350  OpenAL_ErrorPrint( alSourceUnqueueBuffers(mas->source_id, 1, &bid) );
351  }
352 
353  OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_BUFFERS_QUEUED, &bqueued), return 0 );
354 
355  if (bqueued == 0) {
356  mprintf(("MVE: Buffer underun (First is normal)\n"));
357  }
358 
359  OpenAL_ErrorCheck( alGetSourcei(mas->source_id, AL_SOURCE_STATE, &status), return 0 );
360 
361  if ( (mve_audio_playing) && (status != AL_PLAYING) && (bqueued > 0) ) {
362  OpenAL_ErrorCheck( alSourcePlay(mas->source_id), return 0 );
363  }
364 
365  if (bqueued < MVE_AUDIO_BUFFERS) {
366  short *buf = NULL;
367 
368  /* HACK: +4 mveaudio_uncompress adds 4 more bytes */
369  if (major == 8) {
370  if (mve_audio_compressed) {
371  nsamp += 4;
372  buf = (short *)vm_malloc(nsamp);
373  mveaudio_uncompress(buf, data); /* XXX */
374  } else {
375  nsamp -= 8;
376  data += 8;
377  buf = (short *)vm_malloc(nsamp);
378  memcpy(buf, data, nsamp);
379  }
380  } else {
381  buf = (short *)vm_malloc(nsamp);
382  memset(buf, 0, nsamp); /* XXX */
383  }
384 
385  if (!mas->audio_buffer[mve_audio_buffer_tail]) {
386  OpenAL_ErrorCheck( alGenBuffers(1,&mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0; } );
387  }
388 
389  OpenAL_ErrorCheck( alBufferData(mas->audio_buffer[mve_audio_buffer_tail], mas->format, buf, nsamp, mas->sample_rate), { vm_free(buf); return 0; } );
390 
391  OpenAL_ErrorCheck( alSourceQueueBuffers(mas->source_id, 1, &mas->audio_buffer[mve_audio_buffer_tail]), { vm_free(buf); return 0;} );
392 
393  //fprintf(stderr,"Queued buffer %d(%d)\n", mve_audio_buftail, mas->audio_buffer[mve_audio_buftail]);
394 
395  if (++mve_audio_buffer_tail == MVE_AUDIO_BUFFERS) {
396  mve_audio_buffer_tail = 0;
397  }
398 
399  bqueued++;
400  vm_free(buf);
401  } else {
402  mprintf(("MVE: Buffer overrun: Queue full\n"));
403  }
404  }
405  }
406 
407  return 1;
408 }
409 
410 /*************************
411  * video handlers
412  *************************/
413 
415 {
416  if (videobuf_created) {
417  return 1;
418  }
419 
420  short w, h;
421  short truecolor;
422  w = mve_get_short(data);
423  h = mve_get_short(data+2);
424 
425  if (minor > 1) {
426  truecolor = mve_get_short(data+6);
427  } else {
428  truecolor = 0;
429  }
430 
431  g_width = w << 3;
432  g_height = h << 3;
433 
435 
436  if (g_vBackBuf1 == NULL) {
437  nprintf(("MOVIE", "ERROR: Can't allocate video buffer"));
438  videobuf_created = 1;
439  return 0;
440  }
441 
442  if (truecolor) {
443  g_vBackBuf2 = (ushort *)g_vBackBuf1 + (g_width * g_height);
444  } else {
445  g_vBackBuf2 = (ubyte *)g_vBackBuf1 + (g_width * g_height);
446  }
447  memset(g_vBackBuf1, 0, g_width * g_height * 4);
448 
449  g_truecolor = truecolor;
450  videobuf_created = 1;
451 
452  if (gr_screen.mode == GR_OPENGL) {
453  GLfloat scale_by = 1.0f;
454 
455  float screen_ratio = (float)gr_screen.center_w / (float)gr_screen.center_h;
456  float movie_ratio = (float)g_width / (float)g_height;
457 
458  if (screen_ratio > movie_ratio) {
459  scale_by = (float)gr_screen.center_h / (float)g_height;
460  } else {
461  scale_by = (float)gr_screen.center_w / (float)g_width;
462  }
463 
464  // don't bother setting anything if we aren't going to need it
465  if (!Cmdline_noscalevid && (scale_by != 1.0f)) {
467  glPushMatrix();
468  glLoadIdentity();
469 
470  glScalef( scale_by, scale_by, 1.0f );
471  mve_scale_video = 1;
472  }
473 
474  if (mve_scale_video) {
475  g_screenX = ((ceil((gr_screen.center_w / scale_by) - 0.5f) - g_width) / 2) + ceil((gr_screen.center_offset_x / scale_by) - 0.5f);
476  g_screenY = ((ceil((gr_screen.center_h / scale_by) - 0.5f) - g_height) / 2) + ceil((gr_screen.center_offset_y / scale_by) - 0.5f);
477  } else {
478  // centers on 1024x768, fills on 640x480
479  g_screenX = ((float)(gr_screen.center_w - g_width) / 2.0f) + gr_screen.center_offset_x;
480  g_screenY = ((float)(gr_screen.center_h - g_height) / 2.0f) + gr_screen.center_offset_y;
481  }
482 
483  // set additional values for screen width/height and UV coords
484  if (gr_screen.mode == GR_OPENGL) {
485  gl_screenYH = g_screenY + g_height;
486  gl_screenXW = g_screenX + g_width;
487 
488  gl_screenU = i2fl(g_width) / i2fl(wp2);
489  gl_screenV = i2fl(g_height) / i2fl(hp2);
490  }
491 
492  glVertices[0][0] = g_screenX;
493  glVertices[0][1] = g_screenY;
494  glVertices[0][2] = 0;
495  glVertices[0][3] = 0;
496 
497  glVertices[1][0] = g_screenX;
498  glVertices[1][1] = gl_screenYH;
499  glVertices[1][2] = 0;
500  glVertices[1][3] = gl_screenV;
501 
502  glVertices[2][0] = gl_screenXW;
503  glVertices[2][1] = g_screenY;
504  glVertices[2][2] = gl_screenU;
505  glVertices[2][3] = 0;
506 
507  glVertices[3][0] = gl_screenXW;
508  glVertices[3][1] = gl_screenYH;
509  glVertices[3][2] = gl_screenU;
510  glVertices[3][3] = gl_screenV;
511 
513 
514  vertex_layout vertex_def;
515 
516  vertex_def.add_vertex_component(vertex_format_data::POSITION2, sizeof(glVertices[0]), glVertices);
517  vertex_def.add_vertex_component(vertex_format_data::TEX_COORD, sizeof(glVertices[0]), &(glVertices[0][2]));
518 
519  opengl_bind_vertex_layout(vertex_def);
520  }
521 
522  return 1;
523 }
524 
525 static void mve_convert_and_draw()
526 {
527  ushort *pDests;
528  ushort *pSrcs = NULL;
530  int x, y;
531 
532  ubyte *pSrcs8 = NULL;
533  ubyte *pixels8 = (ubyte *)g_vBackBuf1;
534  ubyte r, g, b;
535  ushort bit_16;
536 
537  if (g_truecolor) {
538  pSrcs = pixels;
539  } else {
540  pSrcs8 = pixels8;
541  }
542  pDests = pixelbuf;
543 
544  if (gr_screen.mode != GR_OPENGL) {
545  if (g_screenWidth > g_width) {
546  pDests += ((g_screenWidth - g_width) / 2) / 2;
547  }
548  if (g_screenHeight > g_height) {
549  pDests += ((g_screenHeight - g_height) / 2) * g_screenWidth;
550  }
551  }
552 
553  for (y=0; y<g_height; y++) {
554  for (x = 0; x < g_width; x++) {
555  if (g_truecolor) {
556  Assert( pSrcs != NULL );
557  pDests[x] = (1<<15)|*pSrcs;
558  pSrcs++;
559  } else {
560  Assert( pSrcs8 != NULL );
561 
562  // grab rgb color
563  r = (g_palette[(*pSrcs8)*3] / 2);
564  g = (g_palette[(*pSrcs8)*3 + 1] / 2);
565  b = (g_palette[(*pSrcs8)*3 + 2] / 2);
566 
567  // stuff the color
568  bit_16 = (ushort)(r << Gr_t_red.shift);
569  bit_16 |= (ushort)(g << Gr_t_green.shift);
570  bit_16 |= (ushort)(b << Gr_t_blue.shift);
571  bit_16 |= (ushort)(Gr_t_alpha.mask);
572 
573  // stuff the pixel
574  pDests[x] = (1<<15)|bit_16;
575 
576  pSrcs8++;
577  }
578  }
579 
580  pDests += g_screenWidth;
581  }
582 
583 }
584 
586 {
588 
589  mve_convert_and_draw();
590 
591  // this thing is basically stupid but I don't care
592  // micro_frame_delay is divided by 10 to match mve_video_skiptimer overflow catch
593  if ( mve_video_skiptimer > (uint)(micro_frame_delay/10) ) {
594  // we are running slow so subtract desired time from actual and skip this frame
595  mve_video_skiptimer -= (micro_frame_delay/10);
596  return;
597  } else {
598  // zero out so we can get a new count
599  mve_video_skiptimer = 0;
600  }
601 
602  if (gr_screen.mode == GR_OPENGL) {
604 
606  } else {
607  // DDOI - This is probably really fricking slow
608  int bitmap = bm_create (16, g_screenWidth, g_screenHeight, pixelbuf, 0);
609  gr_set_bitmap (bitmap);
610  gr_bitmap ((int)g_screenX, (int)g_screenY, GR_RESIZE_FULL);
611  bm_release (bitmap);
612  }
613 
614  gr_flip();
615  os_poll();
616 
618 
619  // only get a new count if we are definitely through with old count
620  if ( mve_video_skiptimer == 0 ) {
621  // for a more accurate count convert the frame rate to a float and multiply
622  // by one-hundred-thousand before converting to an uint.
623  mve_video_skiptimer = (uint)(f2fl(t2-t1) * 100000);
624  }
625 
626  int k = key_inkey();
627  switch (k) {
628  case KEY_ESC:
629  case KEY_ENTER:
630  case KEY_SPACEBAR:
631  mve_playing = 0;
632  }
633 
634  //mprintf(("mve frame took this long: %.6f\n", f2fl(t2-t1) / 1000.0f));
635 }
636 
638 {
639  if (video_inited) {
640  return 1;
641  }
642 
643  short width, height;
644 
645  width = mve_get_short(data);
646  height = mve_get_short(data+2);
647 
648  g_screenWidth = width;
649  g_screenHeight = height;
650 
651  // DDOI - Allocate RGB565 pixel buffer
652  pixelbuf = (ushort *)vm_malloc(g_screenWidth * g_screenHeight * 2);
653 
654  if (pixelbuf == NULL) {
655  nprintf(("MOVIE", "ERROR: Can't allocate memory for pixelbuf"));
656  video_inited = 1;
657  return 0;
658  }
659 
660  memset(pixelbuf, 0, g_screenWidth * g_screenHeight * 2);
661 
662  if (gr_screen.mode == GR_OPENGL) {
664  opengl_tcache_get_adjusted_texture_size(g_screenWidth, g_screenHeight, &wp2, &hp2);
665 
666  glGenTextures(1, &GLtex);
667 
668  Assert( GLtex != 0 );
669 
670  if ( GLtex == 0 ) {
671  nprintf(("MOVIE", "ERROR: Can't create a GL texture"));
672  video_inited = 1;
673  return 0;
674  }
675 
676  gr_set_lighting(false, false);
678 
681  GL_state.Texture.Enable(GLtex);
682 
686 
691 
692  // NOTE: using NULL instead of pixelbuf crashes some drivers, but then so does pixelbuf
694 
695  // set our color so that we can make sure that it's correct
696  GL_state.Color(255, 255, 255, 255);
697  }
698 
699  memset(g_palette, 0, 768);
700  video_inited = 1;
701 
702  return 1;
703 }
704 
706 {
707  short start, count;
708  start = mve_get_short(data);
709  count = mve_get_short(data+2);
710  memcpy(g_palette + 3*start, data+4, 3*count);
711 }
712 
714 {
715  g_pCurMap = data;
716  g_nMapLength = len;
717 }
718 
720 {
721  ushort nFlags;
722  ubyte *temp;
723 
724  nFlags = mve_get_ushort(data+12);
725 
726  if (nFlags & 1) {
727  temp = (ubyte *)g_vBackBuf1;
729  g_vBackBuf2 = temp;
730  }
731 
732  if (g_truecolor) {
733  decodeFrame16((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
734  } else {
735  decodeFrame8((ubyte *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
736  }
737 }
738 
740 {
741  g_pCurMap = NULL;
742 }
743 
744 void mve_init(MVESTREAM *mve)
745 {
746  // reset to default values
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;
752 
753  videobuf_created = 0;
754  video_inited = 0;
755  mve_scale_video = 0;
756 
757  mve_playing = 1;
758 }
759 
760 void mve_play(MVESTREAM *mve)
761 {
762  int init_timer = 0, timer_error = 0;
763  int cont = 1;
764 
765  if (!timer_started) {
766  mve_timer_start();
767  }
768 
769  while (cont && mve_playing && !timer_error) {
770  cont = mve_play_next_chunk(mve);
771 
772  if (micro_frame_delay && !init_timer) {
773  mve_timer_start();
774  init_timer = 1;
775  }
776 
777  timer_error = mve_do_timer_wait();
778  }
779 }
780 
782 {
783  if (gr_screen.mode == GR_OPENGL) {
784  if (mve_scale_video) {
786  glPopMatrix();
787  }
788 
790  GL_state.Texture.Delete(GLtex);
791  glDeleteTextures(1, &GLtex);
792  GLtex = 0;
793  }
794 
795  if (pixelbuf != NULL) {
796  vm_free(pixelbuf);
797  pixelbuf = NULL;
798  }
799 
800  if (g_vBuffers != NULL) {
802  g_vBuffers = NULL;
803  }
804 
805  mve_audio_stop();
806  mve_timer_stop();
807 }
unsigned int GLuint
Definition: Gl.h:52
void * g_vBackBuf1
Definition: mveplayer.cpp:66
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
ushort mve_get_ushort(ubyte *data)
Definition: mvelib.cpp:26
#define GL_BGRA_EXT
Definition: Gl.h:1114
#define OpenAL_ErrorCheck(x, y)
Definition: openal.h:24
int key_inkey()
Definition: key.cpp:424
WINGDIAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
int mve_get_int(ubyte *data)
Definition: mvelib.cpp:33
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void gr_flip()
Definition: 2d.cpp:2113
void mve_video_display()
Definition: mveplayer.cpp:585
color_gun Gr_t_red
Definition: 2d.cpp:49
int shift
Definition: grinternal.h:29
int mode
Definition: 2d.h:371
void mve_video_data(ubyte *data, int len)
Definition: mveplayer.cpp:719
opengl_array_state Array
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()
Definition: timer.cpp:160
WINGDIAPI void APIENTRY glLoadIdentity(void)
Assert(pm!=NULL)
#define mprintf(args)
Definition: pstypes.h:238
WINGDIAPI void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
mve_audio_t * mas
Definition: mveplayer.cpp:58
int center_h
Definition: 2d.h:363
int sample_rate
Definition: mveplayer.cpp:50
GLclampf f
Definition: Glext.h:7097
void SetZbufferType(gr_zbuffer_type zt)
void mve_shutdown()
Definition: mveplayer.cpp:781
int center_offset_y
Definition: 2d.h:364
#define f2fl(fx)
Definition: floating.h:37
#define OpenAL_ErrorPrint(x)
Definition: openal.h:34
fix t2
Definition: animplay.cpp:37
ALuint *typedef ALuint *typedef ALenum
Definition: ds.cpp:133
int center_w
Definition: 2d.h:363
#define GL_UNSIGNED_SHORT_1_5_5_5_REV
Definition: Glext.h:74
ALenum format
Definition: mveplayer.cpp:49
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
Definition: decoder8.cpp:11
opengl_texture_state Texture
GLenum GL_texture_target
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
void mve_init(MVESTREAM *mve)
Definition: mveplayer.cpp:744
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
#define GL_TEXTURE_WRAP_S
Definition: Gl.h:944
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
#define GR_OPENGL
Definition: 2d.h:648
void mveaudio_uncompress(short *buffer, unsigned char *data)
Definition: mve_audio.cpp:44
WINGDIAPI void APIENTRY glPopMatrix(void)
GLint GLsizei width
Definition: Gl.h:1505
#define GL_BGRA
Definition: Glext.h:78
#define gr_set_lighting
Definition: 2d.h:924
void mve_audio_createbuf(ubyte minor, ubyte *data)
Definition: mveplayer.cpp:219
int mve_timer_create(ubyte *data)
Definition: mveplayer.cpp:106
void mve_video_codemap(ubyte *data, int len)
Definition: mveplayer.cpp:713
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
short mve_get_short(ubyte *data)
Definition: mvelib.cpp:19
#define GL_LINEAR
Definition: Gl.h:931
int g_height
Definition: mveplayer.cpp:64
unsigned int uint
Definition: pstypes.h:64
GLboolean GLboolean g
Definition: Glext.h:5781
void add_vertex_component(vertex_format_data::vertex_format format_type, uint stride, void *src)
Definition: 2d.h:1054
ALuint *typedef ALuint *typedef ALint
Definition: ds.cpp:133
void mve_end_chunk()
Definition: mveplayer.cpp:739
#define nprintf(args)
Definition: pstypes.h:239
int bytes_per_sec
Definition: mveplayer.cpp:51
int mask
Definition: grinternal.h:31
WINGDIAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures)
#define w(p)
Definition: modelsinc.h:68
void SetAlphaBlendMode(gr_alpha_blend ab)
#define KEY_ENTER
Definition: key.h:125
Definition: bmpman.h:101
GLuint buffer
Definition: Glext.h:5492
ushort * pixelbuf
Definition: mveplayer.cpp:67
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
Definition: mveplayer.cpp:40
#define GL_TEXTURE_MAG_FILTER
Definition: Gl.h:942
int Sound_enabled
Definition: sound.cpp:51
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: Glext.h:5180
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
Definition: Glext.h:5182
long fix
Definition: pstypes.h:54
unsigned char ubyte
Definition: pstypes.h:62
void Enable(GLuint tex_id=0)
void os_poll()
Definition: osapi.cpp:748
int bm_create(int bpp, int w, int h, void *data, int flags)
Definition: bmpman.cpp:469
#define GL_MODELVIEW
Definition: Gl.h:751
#define GL_CLAMP_TO_EDGE
Definition: Glext.h:81
color_gun Gr_t_blue
Definition: 2d.cpp:49
GLuint start
Definition: Gl.h:1502
#define GR_RESIZE_FULL
Definition: 2d.h:682
GLbitfield flags
Definition: Glext.h:6722
int mve_play_next_chunk(MVESTREAM *stream)
Definition: mvelib.cpp:299
#define vm_malloc(size)
Definition: pstypes.h:547
struct MVE_AUDIO_T mve_audio_t
void BindArrayBuffer(GLuint id)
int mve_video_createbuf(ubyte minor, ubyte *data)
Definition: mveplayer.cpp:414
color_gun Gr_t_alpha
Definition: 2d.cpp:49
fix t1
Definition: animplay.cpp:37
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
#define GL_TEXTURE_2D
Definition: Gl.h:570
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define GL_TEXTURE_WRAP_T
Definition: Gl.h:945
void mve_video_palette(ubyte *data)
Definition: mveplayer.cpp:705
opengl_state GL_state
GLint GLsizei GLsizei height
Definition: Gl.h:1505
#define KEY_ESC
Definition: key.h:124
WINGDIAPI void APIENTRY glPushMatrix(void)
void mve_end_movie()
Definition: mveplayer.cpp:97
fix timer_get_fixed_seconds()
Definition: timer.cpp:116
#define GL_TEXTURE_MIN_FILTER
Definition: Gl.h:943
screen gr_screen
Definition: 2d.cpp:46
void opengl_set_texture_target(GLenum target)
unsigned short ushort
Definition: pstypes.h:63
int mve_audio_data(ubyte major, ubyte *data)
Definition: mveplayer.cpp:333
color_gun Gr_t_green
Definition: 2d.cpp:49
int center_offset_x
Definition: 2d.h:364
GLfloat GLfloat p
Definition: Glext.h:8373
void Sleep(int mili)
void mve_audio_play()
Definition: mveplayer.cpp:287
GLenum GLsizei GLenum GLenum const GLvoid * data
Definition: Gl.h:1509
int mve_video_init(ubyte *data)
Definition: mveplayer.cpp:637
#define KEY_SPACEBAR
Definition: key.h:128
ALuint audio_buffer[MVE_AUDIO_BUFFERS]
Definition: mveplayer.cpp:55
#define i2fl(i)
Definition: floating.h:32
void Delete(GLuint tex_id)
GLint GLsizei count
Definition: Gl.h:1491
unsigned int GLenum
Definition: Gl.h:43
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
WINGDIAPI void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
GLenum GLsizei len
Definition: Glext.h:6283
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)
int temp
Definition: lua.cpp:4996
int g_width
Definition: mveplayer.cpp:64
int Cmdline_noscalevid
Definition: cmdline.cpp:328
void * g_vBackBuf2
Definition: mveplayer.cpp:66
void decodeFrame16(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
Definition: decoder16.cpp:16
#define GL_RGB5_A1
Definition: Gl.h:1006
void mve_play(MVESTREAM *mve)
Definition: mveplayer.cpp:760
void opengl_bind_vertex_layout(vertex_layout &layout)
ALuint source_id
Definition: mveplayer.cpp:54
void SetActiveUnit(GLuint id=0)
GLuint GLuint end
Definition: Gl.h:1502
GLint y
Definition: Gl.h:1505
void * g_vBuffers
Definition: mveplayer.cpp:65
float GLfloat
Definition: Gl.h:53
#define GL_TRIANGLE_STRIP
Definition: Gl.h:110