~ubuntu-branches/ubuntu/gutsy/pygame/gutsy

« back to all changes in this revision

Viewing changes to src/movie.c

  • Committer: Bazaar Package Importer
  • Author(s): Ed Boraas
  • Date: 2002-02-20 06:39:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020220063924-amlzj7tqkeods4eq
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    pygame - Python Game Library
 
3
    Copyright (C) 2000-2001  Pete Shinners
 
4
 
 
5
    This library is free software; you can redistribute it and/or
 
6
    modify it under the terms of the GNU Library General Public
 
7
    License as published by the Free Software Foundation; either
 
8
    version 2 of the License, or (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
    Library General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public
 
16
    License along with this library; if not, write to the Free
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
    Pete Shinners
 
20
    pete@shinners.org
 
21
*/
 
22
 
 
23
/*
 
24
 *  movie playback for pygame
 
25
 */
 
26
#include "pygame.h"
 
27
#include "smpeg.h"
 
28
 
 
29
 
 
30
typedef struct {
 
31
  PyObject_HEAD
 
32
  SMPEG* movie;
 
33
  PyObject* surftarget;
 
34
  PyObject* filesource;
 
35
} PyMovieObject;
 
36
#define PyMovie_AsSMPEG(x) (((PyMovieObject*)x)->movie)
 
37
 
 
38
 
 
39
staticforward PyTypeObject PyMovie_Type;
 
40
static PyObject* PyMovie_New(SMPEG*);
 
41
#define PyMovie_Check(x) ((x)->ob_type == &PyMovie_Type)
 
42
 
 
43
 
 
44
 
 
45
 
 
46
 
 
47
/* movie object methods */
 
48
 
 
49
    /*DOC*/ static char doc_movie_play[] =
 
50
    /*DOC*/    "Movie.play(loops=0) -> None\n"
 
51
    /*DOC*/    "start movie playback\n"
 
52
    /*DOC*/    "\n"
 
53
    /*DOC*/    "Starts playback of a movie. If audio or video is enabled\n"
 
54
    /*DOC*/    "for the Movie, those outputs will be created. \n"
 
55
    /*DOC*/    "\n"
 
56
    /*DOC*/    "You can specify an optional argument which will be the\n"
 
57
    /*DOC*/    "number of times the movie loops while playing.\n"
 
58
    /*DOC*/ ;
 
59
 
 
60
static PyObject* movie_play(PyObject* self, PyObject* args)
 
61
{
 
62
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
63
        int loops=0;
 
64
        if(!PyArg_ParseTuple(args, "|i", &loops))
 
65
                return NULL;
 
66
        Py_BEGIN_ALLOW_THREADS
 
67
        SMPEG_loop(movie, loops);
 
68
        SMPEG_play(movie);
 
69
        Py_END_ALLOW_THREADS
 
70
        RETURN_NONE
 
71
}
 
72
 
 
73
 
 
74
 
 
75
    /*DOC*/ static char doc_movie_stop[] =
 
76
    /*DOC*/    "Movie.stop() -> None\n"
 
77
    /*DOC*/    "stop movie playback\n"
 
78
    /*DOC*/    "\n"
 
79
    /*DOC*/    "Stops playback of a movie. If sound and video are being\n"
 
80
    /*DOC*/    "rendered, both will be stopped at their current position.\n"
 
81
    /*DOC*/ ;
 
82
 
 
83
static PyObject* movie_stop(PyObject* self, PyObject* args)
 
84
{
 
85
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
86
        if(!PyArg_ParseTuple(args, ""))
 
87
                return NULL;
 
88
        Py_BEGIN_ALLOW_THREADS
 
89
        SMPEG_stop(movie);
 
90
        Py_END_ALLOW_THREADS
 
91
        RETURN_NONE
 
92
}
 
93
 
 
94
 
 
95
    /*DOC*/ static char doc_movie_pause[] =
 
96
    /*DOC*/    "Movie.pause() -> None\n"
 
97
    /*DOC*/    "pause/resume movie playback\n"
 
98
    /*DOC*/    "\n"
 
99
    /*DOC*/    "This will temporarily stop playback of the movie. When called\n"
 
100
    /*DOC*/    "a second time, playback will resume where it left off.\n"
 
101
    /*DOC*/ ;
 
102
 
 
103
static PyObject* movie_pause(PyObject* self, PyObject* args)
 
104
{
 
105
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
106
        if(!PyArg_ParseTuple(args, ""))
 
107
                return NULL;
 
108
        Py_BEGIN_ALLOW_THREADS
 
109
        SMPEG_pause(movie);
 
110
        Py_END_ALLOW_THREADS
 
111
        RETURN_NONE
 
112
}
 
113
 
 
114
 
 
115
    /*DOC*/ static char doc_movie_rewind[] =
 
116
    /*DOC*/    "Movie.rewind() -> None\n"
 
117
    /*DOC*/    "set playback position to the beginning of the movie\n"
 
118
    /*DOC*/    "\n"
 
119
    /*DOC*/    "Sets the movie playback position to the start of\n"
 
120
    /*DOC*/    "the movie.\n"
 
121
    /*DOC*/ ;
 
122
 
 
123
static PyObject* movie_rewind(PyObject* self, PyObject* args)
 
124
{
 
125
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
126
        if(!PyArg_ParseTuple(args, ""))
 
127
                return NULL;
 
128
        Py_BEGIN_ALLOW_THREADS
 
129
        SMPEG_rewind(movie);
 
130
        Py_END_ALLOW_THREADS
 
131
        RETURN_NONE
 
132
}
 
133
 
 
134
    /*DOC*/ static char doc_movie_skip[] =
 
135
    /*DOC*/    "Movie.skip(seconds) -> None\n"
 
136
    /*DOC*/    "skip the movie playback position forward\n"
 
137
    /*DOC*/    "\n"
 
138
    /*DOC*/    "Sets the movie playback position ahead by the given\n"
 
139
    /*DOC*/    "amount of seconds. the seconds value is a floating\n"
 
140
    /*DOC*/    "point value\n"
 
141
    /*DOC*/ ;
 
142
 
 
143
static PyObject* movie_skip(PyObject* self, PyObject* args)
 
144
{
 
145
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
146
        float seconds;
 
147
        if(!PyArg_ParseTuple(args, "f", &seconds))
 
148
                return NULL;
 
149
        Py_BEGIN_ALLOW_THREADS
 
150
        SMPEG_skip(movie, seconds);
 
151
        Py_END_ALLOW_THREADS
 
152
        RETURN_NONE
 
153
}
 
154
 
 
155
 
 
156
    /*DOC*/ static char doc_movie_set_volume[] =
 
157
    /*DOC*/    "Movie.set_volume(val) -> None\n"
 
158
    /*DOC*/    "change volume for sound\n"
 
159
    /*DOC*/    "\n"
 
160
    /*DOC*/    "Set the play volume for this Movie. The volume value is between\n"
 
161
    /*DOC*/    "0.0 and 1.0.\n"
 
162
    /*DOC*/ ;
 
163
 
 
164
static PyObject* movie_set_volume(PyObject* self, PyObject* args)
 
165
{
 
166
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
167
        float value;
 
168
        int volume;
 
169
        if(!PyArg_ParseTuple(args, "f", &value))
 
170
                return NULL;
 
171
 
 
172
        Py_BEGIN_ALLOW_THREADS
 
173
        volume = (int)(value * 100);
 
174
        if(volume<0) volume = 0;
 
175
        if(volume>100) volume = 100;
 
176
        SMPEG_setvolume(movie, volume);
 
177
        Py_END_ALLOW_THREADS
 
178
        
 
179
        RETURN_NONE
 
180
}
 
181
 
 
182
 
 
183
    /*DOC*/ static char doc_movie_set_display[] =
 
184
    /*DOC*/    "Movie.set_display(Surface, [pos]) -> None\n"
 
185
    /*DOC*/    "change the video output surface\n"
 
186
    /*DOC*/    "\n"
 
187
    /*DOC*/    "Set the output surface for the Movie's video. You may\n"
 
188
    /*DOC*/    "also specify a position for the topleft corner of the\n"
 
189
    /*DOC*/    "video. The position defaults to (0,0) if not given.\n"
 
190
    /*DOC*/    "\n"
 
191
    /*DOC*/    "The position argument can optionally be a rectangle,\n"
 
192
    /*DOC*/    "in which case the video will be stretched to fill the\n"
 
193
    /*DOC*/    "rectangular area.\n"
 
194
    /*DOC*/    "\n"
 
195
    /*DOC*/    "You may also pass None as the destination Surface, and\n"
 
196
    /*DOC*/    "no video will be rendered for the movie playback.\n"
 
197
    /*DOC*/ ;
 
198
 
 
199
static PyObject* movie_set_display(PyObject* self, PyObject* args)
 
200
{
 
201
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
202
        PyObject* surfobj, *posobj=NULL;
 
203
        GAME_Rect *rect, temp;
 
204
        short x=0, y=0;
 
205
        if(!PyArg_ParseTuple(args, "O|O", &surfobj, &posobj))
 
206
                return NULL;
 
207
 
 
208
        Py_XDECREF(((PyMovieObject*)self)->surftarget);
 
209
        ((PyMovieObject*)self)->surftarget = NULL;
 
210
 
 
211
        if(PySurface_Check(surfobj))
 
212
        {
 
213
            SMPEG_Info info;
 
214
            SDL_Surface* surf;
 
215
 
 
216
                if(posobj == NULL)
 
217
                {
 
218
                        SMPEG_Info info;
 
219
                        SMPEG_getinfo(movie, &info);
 
220
                        SMPEG_scaleXY(movie, info.width, info.height);
 
221
                        x = y = 0;
 
222
                }
 
223
                else if(TwoShortsFromObj(posobj, &x, &y))
 
224
                {
 
225
                        SMPEG_Info info;
 
226
                        SMPEG_getinfo(movie, &info);
 
227
                        SMPEG_scaleXY(movie, info.width, info.height);
 
228
                }
 
229
                else if((rect = GameRect_FromObject(posobj, &temp)))
 
230
                {
 
231
                        x = rect->x;
 
232
                        y = rect->y;
 
233
                        SMPEG_scaleXY(movie, rect->w, rect->h);
 
234
                }
 
235
                else
 
236
                        return RAISE(PyExc_TypeError, "Invalid position argument");
 
237
 
 
238
            surf = PySurface_AsSurface(surfobj);
 
239
 
 
240
            SMPEG_getinfo(movie, &info);
 
241
            SMPEG_enablevideo(movie, 1);
 
242
            SMPEG_setdisplay(movie, surf, NULL, NULL);
 
243
            SMPEG_move(movie, x, y);
 
244
        }
 
245
        else
 
246
        {
 
247
            Py_BEGIN_ALLOW_THREADS
 
248
            SMPEG_enablevideo(movie, 0);
 
249
            Py_END_ALLOW_THREADS
 
250
            if(surfobj != Py_None)
 
251
                       return RAISE(PyExc_TypeError, "destination must be a Surface");
 
252
        }
 
253
 
 
254
        RETURN_NONE;
 
255
}
 
256
 
 
257
 
 
258
    /*DOC*/ static char doc_movie_has_video[] =
 
259
    /*DOC*/    "Movie.has_video() -> bool\n"
 
260
    /*DOC*/    "query if movie stream has video\n"
 
261
    /*DOC*/    "\n"
 
262
    /*DOC*/    "Returns a true value when the Movie object has a valid\n"
 
263
    /*DOC*/    "video stream.\n"
 
264
    /*DOC*/ ;
 
265
 
 
266
 
 
267
static PyObject* movie_has_video(PyObject* self, PyObject* args)
 
268
{
 
269
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
270
        SMPEG_Info info;
 
271
 
 
272
        if(!PyArg_ParseTuple(args, ""))
 
273
                return NULL;
 
274
 
 
275
        Py_BEGIN_ALLOW_THREADS
 
276
        SMPEG_getinfo(movie, &info);
 
277
        Py_END_ALLOW_THREADS
 
278
        return PyInt_FromLong(info.has_video);
 
279
}
 
280
 
 
281
    /*DOC*/ static char doc_movie_has_audio[] =
 
282
    /*DOC*/    "Movie.has_audio() -> bool\n"
 
283
    /*DOC*/    "query if movie stream has audio\n"
 
284
    /*DOC*/    "\n"
 
285
    /*DOC*/    "Returns a true value when the Movie object has a valid\n"
 
286
    /*DOC*/    "audio stream.\n"
 
287
    /*DOC*/ ;
 
288
 
 
289
static PyObject* movie_has_audio(PyObject* self, PyObject* args)
 
290
{
 
291
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
292
        SMPEG_Info info;
 
293
 
 
294
        if(!PyArg_ParseTuple(args, ""))
 
295
                return NULL;
 
296
 
 
297
        Py_BEGIN_ALLOW_THREADS
 
298
        SMPEG_getinfo(movie, &info);
 
299
        Py_END_ALLOW_THREADS
 
300
        return PyInt_FromLong(info.has_audio);
 
301
}
 
302
 
 
303
    /*DOC*/ static char doc_movie_get_size[] =
 
304
    /*DOC*/    "Movie.get_size() -> width,height\n"
 
305
    /*DOC*/    "query the size of the video image\n"
 
306
    /*DOC*/    "\n"
 
307
    /*DOC*/    "Returns the size of the video image the mpeg provides.\n"
 
308
    /*DOC*/ ;
 
309
 
 
310
static PyObject* movie_get_size(PyObject* self, PyObject* args)
 
311
{
 
312
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
313
        SMPEG_Info info;
 
314
 
 
315
        if(!PyArg_ParseTuple(args, ""))
 
316
                return NULL;
 
317
 
 
318
        Py_BEGIN_ALLOW_THREADS
 
319
        SMPEG_getinfo(movie, &info);
 
320
        Py_END_ALLOW_THREADS
 
321
        return Py_BuildValue("(ii)", info.width, info.height);
 
322
}
 
323
 
 
324
    /*DOC*/ static char doc_movie_get_frame[] =
 
325
    /*DOC*/    "Movie.get_frame() -> int\n"
 
326
    /*DOC*/    "query the current frame in the movie\n"
 
327
    /*DOC*/    "\n"
 
328
    /*DOC*/    "Gets the current video frame number for the movie.\n"
 
329
    /*DOC*/ ;
 
330
 
 
331
static PyObject* movie_get_frame(PyObject* self, PyObject* args)
 
332
{
 
333
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
334
        SMPEG_Info info;
 
335
 
 
336
        if(!PyArg_ParseTuple(args, ""))
 
337
                return NULL;
 
338
 
 
339
        Py_BEGIN_ALLOW_THREADS
 
340
        SMPEG_getinfo(movie, &info);
 
341
        Py_END_ALLOW_THREADS
 
342
        return PyInt_FromLong(info.current_frame);
 
343
}
 
344
 
 
345
    /*DOC*/ static char doc_movie_get_time[] =
 
346
    /*DOC*/    "Movie.get_time() -> float\n"
 
347
    /*DOC*/    "query the current time in the movie\n"
 
348
    /*DOC*/    "\n"
 
349
    /*DOC*/    "Gets the current time (in seconds) for the movie.\n"
 
350
    /*DOC*/    "(currently not working? SMPEG always reports 0)\n"
 
351
    /*DOC*/ ;
 
352
 
 
353
static PyObject* movie_get_time(PyObject* self, PyObject* args)
 
354
{
 
355
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
356
        SMPEG_Info info;
 
357
 
 
358
        if(!PyArg_ParseTuple(args, ""))
 
359
                return NULL;
 
360
 
 
361
        Py_BEGIN_ALLOW_THREADS
 
362
        SMPEG_getinfo(movie, &info);
 
363
        Py_END_ALLOW_THREADS
 
364
        return PyFloat_FromDouble(info.current_time);
 
365
}
 
366
 
 
367
    /*DOC*/ static char doc_movie_get_length[] =
 
368
    /*DOC*/    "Movie.get_length() -> float\n"
 
369
    /*DOC*/    "query playback time of the movie\n"
 
370
    /*DOC*/    "\n"
 
371
    /*DOC*/    "Returns the total time (in seconds) of the movie.\n"
 
372
    /*DOC*/ ;
 
373
 
 
374
static PyObject* movie_get_length(PyObject* self, PyObject* args)
 
375
{
 
376
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
377
        SMPEG_Info info;
 
378
 
 
379
        if(!PyArg_ParseTuple(args, ""))
 
380
                return NULL;
 
381
 
 
382
        Py_BEGIN_ALLOW_THREADS
 
383
        SMPEG_getinfo(movie, &info);
 
384
        Py_END_ALLOW_THREADS
 
385
        return PyFloat_FromDouble(info.total_time);
 
386
}
 
387
 
 
388
    /*DOC*/ static char doc_movie_get_busy[] =
 
389
    /*DOC*/    "Movie.get_busy() -> bool\n"
 
390
    /*DOC*/    "query the playback state\n"
 
391
    /*DOC*/    "\n"
 
392
    /*DOC*/    "Returns true if the movie is currently playing.\n"
 
393
    /*DOC*/ ;
 
394
 
 
395
static PyObject* movie_get_busy(PyObject* self, PyObject* args)
 
396
{
 
397
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
398
 
 
399
        if(!PyArg_ParseTuple(args, ""))
 
400
                return NULL;
 
401
 
 
402
        return PyInt_FromLong(SMPEG_status(movie) == SMPEG_PLAYING);
 
403
}
 
404
 
 
405
 
 
406
static PyMethodDef movie_builtins[] =
 
407
{
 
408
        { "play", movie_play, 1, doc_movie_play },
 
409
        { "stop", movie_stop, 1, doc_movie_stop },
 
410
        { "pause", movie_pause, 1, doc_movie_pause },
 
411
        { "rewind", movie_rewind, 1, doc_movie_rewind },
 
412
        { "skip", movie_skip, 1, doc_movie_skip },
 
413
 
 
414
        { "set_volume", movie_set_volume, 1, doc_movie_set_volume },
 
415
        { "set_display", movie_set_display, 1, doc_movie_set_display },
 
416
 
 
417
        { "has_video", movie_has_video, 1, doc_movie_has_video },
 
418
        { "has_audio", movie_has_audio, 1, doc_movie_has_audio },
 
419
        { "get_size", movie_get_size, 1, doc_movie_get_size },
 
420
        { "get_frame", movie_get_frame, 1, doc_movie_get_frame },
 
421
        { "get_time", movie_get_time, 1, doc_movie_get_time },
 
422
        { "get_length", movie_get_length, 1, doc_movie_get_length },
 
423
        { "get_busy", movie_get_busy, 1, doc_movie_get_busy },
 
424
 
 
425
        { NULL, NULL }
 
426
};
 
427
 
 
428
 
 
429
/*sound object internals*/
 
430
 
 
431
static void movie_dealloc(PyObject* self)
 
432
{
 
433
        SMPEG* movie = PyMovie_AsSMPEG(self);
 
434
        Py_BEGIN_ALLOW_THREADS
 
435
        SMPEG_delete(movie);
 
436
        Py_END_ALLOW_THREADS
 
437
        Py_XDECREF(((PyMovieObject*)self)->surftarget);
 
438
        Py_XDECREF(((PyMovieObject*)self)->filesource);
 
439
        PyObject_DEL(self);
 
440
}
 
441
 
 
442
 
 
443
static PyObject* movie_getattr(PyObject* self, char* attrname)
 
444
{
 
445
        return Py_FindMethod(movie_builtins, self, attrname);
 
446
}
 
447
 
 
448
 
 
449
    /*DOC*/ static char doc_Movie_MODULE[] =
 
450
    /*DOC*/    "The Movie object represents an opened MPEG file.\n"
 
451
    /*DOC*/    "You control playback similar to a Sound object.\n"
 
452
    /*DOC*/    "\n"
 
453
    /*DOC*/    "Movie objects have a target display Surface.\n"
 
454
    /*DOC*/    "The movie is rendered to this Surface in a background\n"
 
455
    /*DOC*/    "thread. If the Surface is the display surface, and\n"
 
456
    /*DOC*/    "the system supports it, the movie will render into a\n"
 
457
    /*DOC*/    "Hardware YUV overlay plane. If you don't set a display\n"
 
458
    /*DOC*/    "Surface, it will default to the display Surface.\n"
 
459
    /*DOC*/    "\n"
 
460
    /*DOC*/    "Movies are played back in background threads, so there\n"
 
461
    /*DOC*/    "is very little management needed on the user end. Just\n"
 
462
    /*DOC*/    "load the Movie, set the destination, and Movie.play()\n"
 
463
    /*DOC*/    "\n"
 
464
    /*DOC*/    "Movies will only playback audio if the pygame.mixer\n"
 
465
    /*DOC*/    "module is not initialized. It is easy to temporarily\n"
 
466
    /*DOC*/    "call pygame.mixer.quit() to disable audio, then create\n"
 
467
    /*DOC*/    "and play your movie. Finally calling pygame.mixer.init()\n"
 
468
    /*DOC*/    "again when finished with the Movie.\n"
 
469
    /*DOC*/    "\n"
 
470
    /*DOC*/ ;
 
471
 
 
472
static PyTypeObject PyMovie_Type =
 
473
{
 
474
        PyObject_HEAD_INIT(NULL)
 
475
        0,
 
476
        "Movie",
 
477
        sizeof(PyMovieObject),
 
478
        0,
 
479
        movie_dealloc,
 
480
        0,
 
481
        movie_getattr,
 
482
        NULL,                                   /*setattr*/
 
483
        NULL,                                   /*compare*/
 
484
        NULL,                                   /*repr*/
 
485
        NULL,                                   /*as_number*/
 
486
        NULL,                                   /*as_sequence*/
 
487
        NULL,                                   /*as_mapping*/
 
488
        (hashfunc)NULL,                 /*hash*/
 
489
        (ternaryfunc)NULL,              /*call*/
 
490
        (reprfunc)NULL,                 /*str*/
 
491
        0L,0L,0L,0L,
 
492
        doc_Movie_MODULE /* Documentation string */
 
493
};
 
494
 
 
495
 
 
496
 
 
497
 
 
498
/*movie module methods*/
 
499
 
 
500
 
 
501
    /*DOC*/ static char doc_Movie[] =
 
502
    /*DOC*/    "pygame.movie.Movie(file) -> Movie\n"
 
503
    /*DOC*/    "load a new MPEG stream\n"
 
504
    /*DOC*/    "\n"
 
505
    /*DOC*/    "Loads a new movie stream from a MPEG file. The file\n"
 
506
    /*DOC*/    "argument is either a filename, or any python file-like object\n"
 
507
    /*DOC*/ ;
 
508
 
 
509
static PyObject* Movie(PyObject* self, PyObject* arg)
 
510
{
 
511
        PyObject* file, *final, *filesource=NULL;
 
512
        char* name = NULL;
 
513
        SMPEG* movie=NULL;
 
514
        SMPEG_Info info;
 
515
        SDL_Surface* screen;
 
516
        char* error;
 
517
        int audioavail = 0;
 
518
        if(!PyArg_ParseTuple(arg, "O", &file))
 
519
                return NULL;
 
520
 
 
521
        if(!SDL_WasInit(SDL_INIT_AUDIO))
 
522
                audioavail = 1;
 
523
 
 
524
        if(PyString_Check(file) || PyUnicode_Check(file))
 
525
        {
 
526
                if(!PyArg_ParseTuple(arg, "s", &name))
 
527
                        return NULL;
 
528
                movie = SMPEG_new(name, &info, audioavail);
 
529
        }
 
530
        else if(PyFile_Check(file))
 
531
        {
 
532
                SDL_RWops *rw = SDL_RWFromFP(PyFile_AsFile(file), 0);
 
533
                movie = SMPEG_new_rwops(rw, &info, audioavail);
 
534
                filesource = file;
 
535
                Py_INCREF(file);
 
536
        }
 
537
        else
 
538
        {
 
539
                SDL_RWops *rw;
 
540
                if(!(rw = RWopsFromPythonThreaded(file)))
 
541
                        return NULL;
 
542
                Py_BEGIN_ALLOW_THREADS
 
543
                movie = SMPEG_new_rwops(rw, &info, audioavail);
 
544
                Py_END_ALLOW_THREADS
 
545
        }
 
546
 
 
547
        if(!movie)
 
548
                return RAISE(PyExc_SDLError, "Cannot create Movie object");
 
549
 
 
550
        error = SMPEG_error(movie);
 
551
        if(error)
 
552
        {
 
553
/* while this would seem correct, it causes a crash, so don't delete */
 
554
/*          SMPEG_delete(movie);*/
 
555
            return RAISE(PyExc_SDLError, error);
 
556
        }
 
557
 
 
558
        Py_BEGIN_ALLOW_THREADS
 
559
        SMPEG_enableaudio(movie, audioavail);
 
560
 
 
561
        screen = SDL_GetVideoSurface();
 
562
        if(screen)
 
563
                SMPEG_setdisplay(movie, screen, NULL, NULL);
 
564
        
 
565
        SMPEG_scaleXY(movie, info.width, info.height);
 
566
        Py_END_ALLOW_THREADS
 
567
 
 
568
        final = PyMovie_New(movie);
 
569
        if(!final)
 
570
                SMPEG_delete(movie);
 
571
        ((PyMovieObject*)final)->filesource = filesource;
 
572
 
 
573
        return final;
 
574
}
 
575
 
 
576
 
 
577
 
 
578
 
 
579
static PyMethodDef mixer_builtins[] =
 
580
{
 
581
        { "Movie", Movie, 1, doc_Movie },
 
582
 
 
583
        { NULL, NULL }
 
584
};
 
585
 
 
586
 
 
587
 
 
588
static PyObject* PyMovie_New(SMPEG* movie)
 
589
{
 
590
        PyMovieObject* movieobj;
 
591
        
 
592
        if(!movie)
 
593
                return RAISE(PyExc_RuntimeError, "unable to create movie.");
 
594
 
 
595
        movieobj = PyObject_NEW(PyMovieObject, &PyMovie_Type);
 
596
        if(movieobj)
 
597
                movieobj->movie = movie;
 
598
 
 
599
        movieobj->surftarget = NULL;
 
600
        movieobj->filesource = NULL;
 
601
 
 
602
        return (PyObject*)movieobj;
 
603
}
 
604
 
 
605
 
 
606
 
 
607
    /*DOC*/ static char doc_pygame_movie_MODULE[] =
 
608
    /*DOC*/    "The movie module is an optional pygame module that\n"
 
609
    /*DOC*/    "allows for decoding and playback of MPEG movie files.\n"
 
610
    /*DOC*/    "The module only contains a single function, Movie()\n"
 
611
    /*DOC*/    "which creates a new Movie object.\n"
 
612
    /*DOC*/    "\n"
 
613
    /*DOC*/    "Movies are played back in background threads, so there\n"
 
614
    /*DOC*/    "is very little management needed on the user end. Just\n"
 
615
    /*DOC*/    "load the Movie, set the destination, and Movie.play()\n"
 
616
    /*DOC*/    "\n"
 
617
    /*DOC*/    "Movies will only playback audio if the pygame.mixer\n"
 
618
    /*DOC*/    "module is not initialized. It is easy to temporarily\n"
 
619
    /*DOC*/    "call pygame.mixer.quit() to disable audio, then create\n"
 
620
    /*DOC*/    "and play your movie. Finally calling pygame.mixer.init()\n"
 
621
    /*DOC*/    "again when finished with the Movie.\n"
 
622
    /*DOC*/ ;
 
623
 
 
624
PYGAME_EXPORT
 
625
void initmovie(void)
 
626
{
 
627
        PyObject *module, *dict;
 
628
 
 
629
        PyType_Init(PyMovie_Type);
 
630
 
 
631
        /* create the module */
 
632
        module = Py_InitModule3("movie", mixer_builtins, doc_pygame_movie_MODULE);
 
633
        dict = PyModule_GetDict(module);
 
634
 
 
635
        PyDict_SetItemString(dict, "MovieType", (PyObject *)&PyMovie_Type);
 
636
 
 
637
        /*imported needed apis*/
 
638
        import_pygame_base();
 
639
        import_pygame_surface();
 
640
        import_pygame_rwobject();
 
641
        import_pygame_rect();
 
642
}
 
643