/* RUDL - a C library wrapping SDL for use in Ruby. Copyright (C) 2001 Danny van Bruggen */ #include "rudl_cdrom.h" VALUE classCD; VALUE classCDROM; ////////////////// void initCD() { if(!SDL_WasInit(SDL_INIT_CDROM)){ DEBUG_S("Starting CDROM subsystem"); SDL_InitSubSystem(SDL_INIT_CDROM); } } void quitCD() { if(SDL_WasInit(SDL_INIT_CDROM)){ DEBUG_S("Stopping CDROM subsystem"); SDL_QuitSubSystem(SDL_INIT_CDROM); } } ////////////////// static VALUE createCDROMObject(int number) { VALUE newObject; SDL_CD* cd=SDL_CDOpen(number); SDL_ASSERT(cd); newObject=Data_Wrap_Struct(classCDROM, 0, SDL_CDClose, cd); rb_iv_set(newObject, "@id", INT2NUM(number)); return newObject; } SDL_CD* retrieveCDROMPointer(VALUE self) { SDL_CD* cd; Data_Get_Struct(self, SDL_CD, cd); SDL_ASSERT(cd); return cd; } /** @file CDROM @class CDROM @section Class methods A class for playing audio CD's. */ /** @method new( number ) Creates a new CDROM access object for unit @number. There can only be one CDROM object per unit. Numbering starts at 0. */ static VALUE cdrom_new(VALUE self, VALUE number) { initCD(); return createCDROMObject(NUM2INT(number)); } /** @method destroy Uninitializes the CDROM subsystem, which is normally not necessary. */ static VALUE cdrom_destroy(VALUE self, VALUE number) { quitCD(); return self; } /** @method count Returns the number of CDROMs installed. */ static VALUE cdrom_count(VALUE self) { initCD(); return INT2NUM(SDL_CDNumDrives()); } /** @section The you-know-what-they-do methods @method eject @method pause @method play( track_nr ) @method resume @method stop @method paused? @method empty? @method busy? These are the you-know-what-they-do methods. */ static VALUE cdrom_eject(VALUE self) { SDL_VERIFY(SDL_CDEject(retrieveCDROMPointer(self))!=-1); return self; } static VALUE cdrom_pause(VALUE self) { SDL_VERIFY(SDL_CDPause(retrieveCDROMPointer(self))!=-1); return self; } static VALUE cdrom_play(VALUE self, VALUE trackValue) { SDL_CD* cdrom=retrieveCDROMPointer(self); int track=NUM2INT(trackValue); int offset, length; SDL_CDStatus(cdrom); // ? RUDL_VERIFY(track >= 0 && track < cdrom->numtracks, "Invalid track number"); RUDL_VERIFY(cdrom->track[track].type == SDL_AUDIO_TRACK, "CD track type is not audio"); offset = cdrom->track[track].offset; length = cdrom->track[track].length; SDL_VERIFY(SDL_CDPlay(cdrom, offset, length-1)!=-1); return self; } static VALUE cdrom_resume(VALUE self) { SDL_VERIFY(SDL_CDResume(retrieveCDROMPointer(self))!=-1); return self; } static VALUE cdrom_stop(VALUE self) { SDL_VERIFY(SDL_CDStop(retrieveCDROMPointer(self))!=-1); return self; } static VALUE cdrom_paused_(VALUE self) { return INT2BOOL(SDL_CDStatus(retrieveCDROMPointer(self))==CD_PAUSED); } static VALUE cdrom_empty_(VALUE self) { return INT2BOOL(SDL_CDStatus(retrieveCDROMPointer(self))==CD_TRAYEMPTY); } static VALUE cdrom_busy_(VALUE self) { return INT2BOOL(SDL_CDStatus(retrieveCDROMPointer(self))==CD_PLAYING); } /** @section others @method current */ static VALUE cdrom_current(VALUE self) { SDL_CD* cdrom=retrieveCDROMPointer(self); int track; double seconds; SDL_CDStatus(cdrom); track = cdrom->cur_track; seconds = cdrom->cur_frame / (float)CD_FPS; return rb_ary_new3(2, INT2NUM(track), DBL2NUM(seconds)); } /** @method number Returns the unit number that was specified in @new. */ static VALUE cdrom_number(VALUE self) { return rb_iv_get(self, "@id"); } /** @method name Returns a string describing the CDROM. */ static VALUE cdrom_name(VALUE self) { VALUE tmp=rb_iv_get(self, "@id"); return rb_str_new2(SDL_CDName(NUM2INT(tmp))); } /** @method num_tracks Returns the number of tracks on the CD. */ static VALUE cdrom_num_tracks(VALUE self) { SDL_CD* cdrom=retrieveCDROMPointer(self); SDL_CDStatus(cdrom); return INT2NUM(cdrom->numtracks); } /** @method audiotrack?( track_nr ) Returns whether the specified track is an audiotrack. */ static VALUE cdrom_audiotrack_(VALUE self, VALUE trackValue) { SDL_CD* cdrom=retrieveCDROMPointer(self); int track=NUM2INT(trackValue); SDL_CDStatus(cdrom); RUDL_VERIFY(track >= 0 && track < cdrom->numtracks, "Invalid track number"); return INT2BOOL(cdrom->track[track].type == SDL_AUDIO_TRACK); } /** @method track_length( track_nr ) Returns the length of the track. Returns 0.0 when the track is not an audio track. */ static VALUE cdrom_track_length(VALUE self, VALUE trackValue) { SDL_CD* cdrom=retrieveCDROMPointer(self); int track=NUM2INT(trackValue); SDL_CDStatus(cdrom); RUDL_VERIFY(track >= 0 && track < cdrom->numtracks, "Invalid track number"); if(cdrom->track[track].type != SDL_AUDIO_TRACK){ return DBL2NUM(0.0); } return DBL2NUM(cdrom->track[track].length / (double)CD_FPS); } /** @method track_start( track_nr ) Returns the starting time of the track. */ static VALUE cdrom_track_start(VALUE self, VALUE trackValue) { SDL_CD* cdrom=retrieveCDROMPointer(self); int track=NUM2INT(trackValue); SDL_CDStatus(cdrom); RUDL_VERIFY(track >= 0 && track < cdrom->numtracks, "Invalid track number"); return DBL2NUM(cdrom->track[track].offset / (double)CD_FPS); } ////////////////// void initCDClasses() { classCDROM=rb_define_class_under(moduleRUDL, "CDROM", rb_cObject); rb_define_singleton_method(classCDROM, "new", cdrom_new, 1); rb_define_singleton_method(classCDROM, "destroy", cdrom_destroy, 0); rb_define_singleton_method(classCDROM, "count", cdrom_count, 0); rb_define_method(classCDROM, "eject", cdrom_eject, 0); rb_define_method(classCDROM, "busy?", cdrom_busy_, 0); rb_define_method(classCDROM, "current", cdrom_current, 0); rb_define_method(classCDROM, "empty?", cdrom_empty_, 0); rb_define_method(classCDROM, "number", cdrom_number, 0); rb_define_method(classCDROM, "name", cdrom_name, 0); rb_define_method(classCDROM, "num_tracks", cdrom_num_tracks, 0); rb_define_method(classCDROM, "audiotrack?", cdrom_audiotrack_, 1); rb_define_method(classCDROM, "track_length", cdrom_track_length, 1); rb_define_method(classCDROM, "track_start", cdrom_track_start, 1); rb_define_method(classCDROM, "pause", cdrom_pause, 0); rb_define_method(classCDROM, "paused?", cdrom_paused_, 0); rb_define_method(classCDROM, "play", cdrom_play, 1); rb_define_method(classCDROM, "resume", cdrom_resume, 0); rb_define_method(classCDROM, "stop", cdrom_stop, 0); }