/*
Ruby/SDL Ruby extension library for SDL
Copyright (C) 2001-2007 Ohbayashi Ippei
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_SMPEG
#include "rubysdl.h"
#include "smpeg/smpeg.h"
#ifdef HAVE_SDL_MIXER
#include "SDL_mixer.h"
#endif
static SMPEG_Filter* filters[3];
#define NULL_FILTER 0
#define BILINEAR_FILTER 1
#define DEBLOCKING_FILTER 2
#define NUM_FILTERS 3
static void setInfoToSMPEGInfo(VALUE obj,SMPEG_Info info)
{
rb_iv_set(obj,"@has_audio",BOOL(info.has_audio));
rb_iv_set(obj,"@has_video",BOOL(info.has_video));
rb_iv_set(obj,"@width",INT2NUM(info.width));
rb_iv_set(obj,"@height",INT2NUM(info.height));
rb_iv_set(obj,"@current_frame",INT2NUM(info.current_frame));
rb_iv_set(obj,"@current_fps",INT2NUM(info.current_fps));
rb_iv_set(obj,"@audio_string",rb_str_new2(info.audio_string));
rb_iv_set(obj,"@audio_current_frame",INT2NUM(info.audio_current_frame));
rb_iv_set(obj,"@current_offset",UINT2NUM(info.current_offset));
rb_iv_set(obj,"@total_size",UINT2NUM(info.total_size));
rb_iv_set(obj,"@current_time",UINT2NUM(info.current_time));
rb_iv_set(obj,"@total_time",UINT2NUM(info.total_time));
}
static VALUE smpeg_load(VALUE class,VALUE filename)
{
SMPEG *mpeg;
VALUE obj;
char error_msg[2048];
mpeg = SMPEG_new(GETCSTR(filename),NULL,0);
if( SMPEG_error(mpeg) ){
snprintf(error_msg,sizeof(error_msg),"Couldn't load %s: %s",
GETCSTR(filename),SMPEG_error(mpeg));
SMPEG_delete(mpeg);
rb_raise(eSDLError,"%s",error_msg);
}
obj = Data_Wrap_Struct(cMPEG,0,SMPEG_delete,mpeg);
rb_iv_set(obj,"enable_audio",Qtrue);
return obj;
}
static VALUE smpeg_getInfo(VALUE obj,VALUE infoObj)
{
SMPEG *mpeg;
SMPEG_Info info;
if( !rb_obj_is_kind_of(infoObj,cMPEGInfo) )
rb_raise(rb_eArgError,"type mismatch(expect SDL::MPEG::Info)");
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_getinfo(mpeg,&info);
setInfoToSMPEGInfo(infoObj,info);
return Qnil;
}
static VALUE smpeg_enableAudio(VALUE obj,VALUE enable)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
rb_iv_set(obj,"enable_audio",enable);
return Qnil;
}
static VALUE smpeg_enableVideo(VALUE obj,VALUE enable)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_enablevideo(mpeg,RTEST(enable));
return Qnil;
}
static VALUE smpeg_status(VALUE obj)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
return INT2FIX(SMPEG_status(mpeg));
}
static VALUE smpeg_setVolume(VALUE obj,VALUE volume)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_setvolume(mpeg,NUM2INT(volume));
return Qnil;
}
static VALUE smpeg_setDisplay(VALUE obj,VALUE dst)
{
SMPEG *mpeg;
SDL_Surface *surface;
if( !rb_obj_is_kind_of(dst,cSurface) )
rb_raise(rb_eArgError,"type mismatchi(expect Surface)");
Data_Get_Struct(obj,SMPEG,mpeg);
Data_Get_Struct(dst,SDL_Surface,surface);
SMPEG_setdisplay(mpeg,surface,NULL,NULL);
rb_iv_set(obj,"surface",dst);
return Qnil;
}
static VALUE smpeg_setLoop(VALUE obj,VALUE repeat)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_loop(mpeg,RTEST(repeat));
return Qnil;
}
static VALUE smpeg_scaleXY(VALUE obj,VALUE w,VALUE h)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_scaleXY(mpeg,NUM2INT(w),NUM2INT(h));
return Qnil;
}
static VALUE smpeg_scale(VALUE obj,VALUE scale)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_scale(mpeg,NUM2INT(scale));
return Qnil;
}
static VALUE smpeg_move(VALUE obj,VALUE x,VALUE y)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_move(mpeg,NUM2INT(x),NUM2INT(y));
return Qnil;
}
static VALUE smpeg_setDisplayRegion(VALUE obj,VALUE x,VALUE y,VALUE w,
VALUE h)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_setdisplayregion(mpeg,NUM2INT(x),NUM2INT(y),NUM2INT(w),NUM2INT(h));
return Qnil;
}
static VALUE smpeg_play(VALUE obj)
{
SMPEG *mpeg;
int use_audio;
Data_Get_Struct(obj,SMPEG,mpeg);
#ifdef HAVE_SDL_MIXER
use_audio = RTEST(rb_iv_get(obj,"enable_audio")) &&
Mix_QuerySpec( NULL, NULL, NULL );
if( use_audio ){
SDL_AudioSpec audiofmt;
Uint16 format;
int freq, channels;
SMPEG_enableaudio(mpeg, 0);
/* Tell SMPEG what the audio format is */
Mix_QuerySpec(&freq, &format, &channels);
audiofmt.format = format;
audiofmt.freq = freq;
audiofmt.channels = channels;
SMPEG_actualSpec(mpeg, &audiofmt);
/* Hook in the MPEG music mixer */
Mix_HookMusic(NULL,NULL);
Mix_HookMusic(SMPEG_playAudioSDL, mpeg);
SMPEG_enableaudio(mpeg, 1);
}
#else
SMPEG_enableaudio(mpeg, RTEST(rb_iv_get(obj,"enable_audio")));
#endif
SMPEG_play(mpeg);
return Qnil;
}
static VALUE smpeg_pause(VALUE obj)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_pause(mpeg);
return Qnil;
}
static VALUE smpeg_stop(VALUE obj)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_stop(mpeg);
#ifdef HAVE_SDL_MIXER
Mix_HookMusic(NULL,NULL);
#endif
return Qnil;
}
static VALUE smpeg_rewind(VALUE obj)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_rewind(mpeg);
return Qnil;
}
static VALUE smpeg_seek(VALUE obj,VALUE bytes)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_seek(mpeg,NUM2INT(bytes));
return Qnil;
}
static VALUE smpeg_skip(VALUE obj,VALUE seconds)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_skip(mpeg,NUM2DBL(seconds));
return Qnil;
}
static VALUE smpeg_renderFrame(VALUE obj,VALUE framenum)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
SMPEG_renderFrame(mpeg,NUM2INT(framenum));
return Qnil;
}
static VALUE smpeg_renderFinal(VALUE obj,VALUE dst, VALUE x, VALUE y)
{
SMPEG *mpeg;
SDL_Surface *surface;
if( !rb_obj_is_kind_of(dst,cSurface) )
rb_raise(rb_eArgError,"type mismatchi(expect Surface)");
Data_Get_Struct(obj,SMPEG,mpeg);
Data_Get_Struct(dst,SDL_Surface,surface);
SMPEG_renderFinal(mpeg, surface, NUM2INT(x), NUM2INT(y));
return Qnil;
}
static VALUE smpeg_setFilter(VALUE obj,VALUE filter)
{
SMPEG *mpeg;
Data_Get_Struct(obj,SMPEG,mpeg);
if( (NUM2INT(filter)<0) || (NUM2INT(filter)>=NUM_FILTERS) )
rb_raise(eSDLError,"There isn't that filter");
SMPEG_filter(mpeg,filters[NUM2INT(filter)]);
return Qnil;
}
static void defineConstForSMPEG()
{
rb_define_const(cMPEG,"ERROR",INT2FIX(SMPEG_ERROR));
rb_define_const(cMPEG,"STOPPED",INT2FIX(SMPEG_STOPPED));
rb_define_const(cMPEG,"PLAYING",INT2FIX(SMPEG_PLAYING));
rb_define_const(cMPEG,"NULL_FILTER",INT2FIX(NULL_FILTER));
rb_define_const(cMPEG,"BILINEAR_FILTER",INT2FIX(BILINEAR_FILTER));
rb_define_const(cMPEG,"DEBLOCKING_FILTER",INT2FIX(DEBLOCKING_FILTER));
}
void init_smpeg()
{
cMPEG = rb_define_class_under(mSDL,"MPEG",rb_cObject);
cMPEGInfo = rb_define_class_under(cMPEG,"Info",rb_cObject);
filters[NULL_FILTER] = SMPEGfilter_null();
filters[BILINEAR_FILTER] = SMPEGfilter_bilinear();
filters[DEBLOCKING_FILTER] = SMPEGfilter_deblocking();
defineConstForSMPEG();
rb_define_attr(cMPEGInfo,"has_audio",1,0);
rb_define_attr(cMPEGInfo,"has_video",1,0);
rb_define_attr(cMPEGInfo,"width",1,0);
rb_define_attr(cMPEGInfo,"height",1,0);
rb_define_attr(cMPEGInfo,"current_frame",1,0);
rb_define_attr(cMPEGInfo,"current_fps",1,0);
rb_define_attr(cMPEGInfo,"audio_string",1,0);
rb_define_attr(cMPEGInfo,"audio_current_frame",1,0);
rb_define_attr(cMPEGInfo,"current_offset",1,0);
rb_define_attr(cMPEGInfo,"total_size",1,0);
rb_define_attr(cMPEGInfo,"current_time",1,0);
rb_define_attr(cMPEGInfo,"total_time",1,0);
rb_define_singleton_method(cMPEG,"load",smpeg_load,1);
rb_define_singleton_method(cMPEG,"new",smpeg_load,1);
rb_define_method(cMPEG,"info",smpeg_getInfo,1);
rb_define_method(cMPEG,"enableAudio",smpeg_enableAudio,1);
rb_define_method(cMPEG,"enableVideo",smpeg_enableVideo,1);
rb_define_method(cMPEG,"status",smpeg_status,0);
rb_define_method(cMPEG,"setVolume",smpeg_setVolume,1);
rb_define_method(cMPEG,"setDisplay",smpeg_setDisplay,1);
rb_define_method(cMPEG,"setLoop",smpeg_setLoop,1);
rb_define_method(cMPEG,"scaleXY",smpeg_scaleXY,2);
rb_define_method(cMPEG,"scale",smpeg_scale,1);
rb_define_method(cMPEG,"move",smpeg_move,1);
rb_define_method(cMPEG,"setDisplayRegion",smpeg_setDisplayRegion,4);
rb_define_method(cMPEG,"play",smpeg_play,0);
rb_define_method(cMPEG,"pause",smpeg_pause,0);
rb_define_method(cMPEG,"stop",smpeg_stop,0);
rb_define_method(cMPEG,"rewind",smpeg_rewind,0);
rb_define_method(cMPEG,"seek",smpeg_seek,1);
rb_define_method(cMPEG,"skip",smpeg_skip,1);
rb_define_method(cMPEG,"renderFrame",smpeg_renderFrame,1);
rb_define_method(cMPEG,"renderFinal",smpeg_renderFinal,3);
rb_define_method(cMPEG,"setFilter",smpeg_setFilter,1);
}
#endif /* HAVE_SMPEG */
syntax highlighted by Code2HTML, v. 0.9.1