www.pudn.com > ngcd080s.zip > CDAUDIO.C
/************************************** **** CDAUDIO.C - CD-DA Player **** **************************************/ //-- Include files ----------------------------------------------------------- #include#include #include #include #include #include #include "../gui/gui.h" #include "../gui/rsc.h" #include "../ym2610/adpcm.h" #include "../ym2610/ym2610.h" //-- Definitions ------------------------------------------------------------- // Il s'agit d'une bidouille infame pour que DJGPP n'aligne pas les membres // unsigned short des structures sur des offsets pairs. (Ce qui bien sur fait // tout foirer et que j'ai mis deux jours a decouvrir!!) #define DW(id) (*((unsigned short *)(&id))) #define DD(id) (*((unsigned int *)(&id))) typedef unsigned char BYTE; typedef struct { BYTE b1; BYTE b2; } WORD; typedef struct { BYTE b1; BYTE b2; BYTE b3; BYTE b4; } DWORD; //-- Structures -------------------------------------------------------------- typedef struct { BYTE len1; BYTE unit; BYTE command; WORD status; BYTE reserved[8]; BYTE descriptor; WORD adr_off; WORD adr_seg; WORD len2; WORD secnum; WORD ptr_off; WORD ptr_seg; } IOCTLI; typedef struct { BYTE control; BYTE lowest; BYTE highest; DWORD total; } DISKINFO; typedef struct { BYTE control; BYTE track; DWORD loc; BYTE info; } TRACKINFO; typedef struct { BYTE len; BYTE unit; BYTE command; WORD status; BYTE reserved[8]; BYTE mode; DWORD loc; DWORD secnum; } PLAYREQ; typedef struct { BYTE len; BYTE unit; BYTE command; WORD status; BYTE reserved[8]; } STOPREQ; typedef struct { BYTE len; BYTE unit; BYTE command; WORD status; BYTE reserved[8]; BYTE media; WORD adr_off; WORD adr_seg; WORD bytes; WORD sector; DWORD volid; } VOLREQ; typedef struct { BYTE mode; BYTE input0; BYTE volume0; BYTE input1; BYTE volume1; BYTE input2; BYTE volume2; BYTE input3; BYTE volume3; } VOLINFO; typedef struct { BYTE control; BYTE mode; DWORD loc; } HEADINFO; //-- Imported Variables ------------------------------------------------------ extern char *global_error[80]; //-- Private Variables ------------------------------------------------------- static int cdda_min_track; static int cdda_max_track; static int cdda_disk_length; static int cdda_track_start; static int cdda_track_end; static int cdda_loop_counter; //-- Public Variables -------------------------------------------------------- __dpmi_regs _regs; int cdda_first_drive; int cdda_nb_of_drives; int cdda_current_drive; int cdda_current_track; int cdda_playing; char drive_list[26]; int nb_of_drives; int cdda_autoloop; int cdda_volume; //-- Function Prototypes ----------------------------------------------------- int cdda_init(void); int cdda_play(int); void cdda_stop(void); void cdda_resume(void); int cdda_get_volume(void); void cdda_set_volume(int); void cdda_shutdown(void); void cdda_loop_check(void); int cdda_get_disk_info(void); void cdda_build_drive_list(void); void audio_setup(void); extern DATAFILE *rsc; DIALOG audio_options[] = { /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */ {d_neo_border_proc, 0, 0, 240, 100, 0x0000, 0x0000, 0, 0, 0, 0, NULL}, {d_neo_fbox_proc, 2, 2, 235, 8, 0x0000, 0x10E3, 0, 0, 0, 0, NULL}, {d_text_proc, 10, 3, 0, 0, 0xFFFF, 0x10E3, 0, 0, 0, 0, "Audio Options"}, {d_text_proc, 10, 20, 0, 0, 0xFFFF, 0x9596, 0, 0, 0, 0, "CDDA Volume"}, {d_neo_slider_proc, 10, 30, 220, 10, 0xFFFF, 0x9596, 0, 0, 255, 0, NULL}, {d_text_proc, 10, 45, 0, 0, 0xFFFF, 0x9596, 0, 0, 0, 0, "Sound Volume"}, {d_neo_slider_proc, 10, 55, 220, 10, 0xFFFF, 0x9596, 0, 0, 255, 0, NULL}, {d_neo_button_proc, 87, 70, 65, 15, 0x0000, 0x0000, 'o', D_EXIT, 0, 0, "&OK"}, {NULL, 0, 0, 0, 0, 0x0000, 0x0000, 0, 0, 0, 0, NULL} }; //---------------------------------------------------------------------------- int cdda_init(void) { int i, j; IOCTLI cmd; DISKINFO di; strcpy((char*)global_error, ""); cdda_min_track = cdda_max_track = 0; cdda_current_track = 0; cdda_playing = 0; cdda_loop_counter = 0; memset(&_regs, 0, sizeof(_regs)); _regs.d.eax = 0x1500; _regs.d.ebx = 0; if (__dpmi_int(0x2f, &_regs) == 0) { cdda_first_drive = _regs.d.ecx; cdda_nb_of_drives = _regs.d.ebx; cdda_build_drive_list(); if (cdda_current_drive==-1) cdda_current_drive = cdda_first_drive; else { j = 0; for(i = 0;i < nb_of_drives;i++) { if (cdda_current_drive == drive_list[i]) j = 1; } if (j==0) cdda_current_drive = cdda_first_drive; } cdda_get_disk_info(); cdda_volume = get_config_int(NULL, "cddavol", 220); cdda_set_volume(cdda_volume); return 1; } strcpy((char *)global_error, "MSCDEX not present !"); return 0; } //---------------------------------------------------------------------------- int cdda_get_disk_info(void) { IOCTLI cmd; DISKINFO di; cmd.len1 = sizeof(IOCTLI); cmd.unit = 0; cmd.command = 3; cmd.descriptor = 0; DW(cmd.adr_seg) = (__tb>>4); DW(cmd.adr_off) = sizeof(IOCTLI); DW(cmd.len2) = 7; DW(cmd.secnum) = 0; DW(cmd.ptr_seg) = 0; DW(cmd.ptr_off) = 0; di.control = 10; dosmemput(&cmd, sizeof(IOCTLI), __tb); dosmemput(&di, sizeof(DISKINFO), (__tb + sizeof(IOCTLI))); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(IOCTLI), &cmd); dosmemget((__tb + sizeof(IOCTLI)), sizeof(DISKINFO), &di); cdda_min_track = cdda_max_track = 0; if (DW(cmd.status)&0x8000) return 0; cdda_min_track = di.lowest; cdda_max_track = di.highest; cdda_disk_length = DD(di.total); return 1; } //---------------------------------------------------------------------------- void cdda_build_drive_list(void) { int i; nb_of_drives = 0; for(i=0;i<26;i++) { _regs.x.ax = 0x150B; _regs.x.cx = i; __dpmi_int(0x2F, &_regs); if (_regs.x.ax != 0) { drive_list[nb_of_drives] = i; nb_of_drives++; } } } //---------------------------------------------------------------------------- int cdda_play(int track) { IOCTLI cmd; TRACKINFO trk; PLAYREQ prq; char h, m, s; char h2, m2, s2; if ((track cdda_max_track)) return 0; cmd.len1 = sizeof(IOCTLI); cmd.unit = 0; cmd.command = 3; cmd.descriptor=0; DW(cmd.adr_seg) = (__tb>>4); DW(cmd.adr_off) = sizeof(IOCTLI); DW(cmd.len2) = 7; DW(cmd.secnum) = 0; DW(cmd.ptr_seg) = 0; DW(cmd.ptr_off) = 0; trk.control = 11; trk.track = track; dosmemput(&cmd, sizeof(IOCTLI), __tb); dosmemput(&trk, sizeof(TRACKINFO), (__tb + sizeof(IOCTLI))); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(IOCTLI), &cmd); dosmemget((__tb + sizeof(IOCTLI)), sizeof(TRACKINFO), &trk); if (DW(cmd.status)&0x8000) return 0; cdda_track_start = DD(trk.loc); if (track==cdda_max_track) cdda_track_end = cdda_disk_length ; else { cmd.len1 = sizeof(IOCTLI); cmd.unit = 0; cmd.command = 3; cmd.descriptor=0; DW(cmd.adr_seg) = (__tb>>4); DW(cmd.adr_off) = sizeof(IOCTLI); DW(cmd.len2) = 7; DW(cmd.secnum) = 0; DW(cmd.ptr_seg) = 0; DW(cmd.ptr_off) = 0; trk.control = 11; trk.track = track+1; dosmemput(&cmd, sizeof(IOCTLI), __tb); dosmemput(&trk, sizeof(TRACKINFO), (__tb + sizeof(IOCTLI))); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(IOCTLI), &cmd); dosmemget((__tb + sizeof(IOCTLI)), sizeof(TRACKINFO), &trk); if (DW(cmd.status)&0x8000) return 0; cdda_track_end = DD(trk.loc); } h = cdda_track_end>>24; m = cdda_track_end>>16; s = cdda_track_end>>8; s -= 1; if (s<0) { m--; s += 60; if (m<0) { h--; m+=60; } } cdda_track_end = (h<<24) + (m<<16) + (s<<8); h2 = cdda_track_start>>24; m2 = cdda_track_start>>16; s2 = cdda_track_start>>8; h -= h2; m -= m2; s -= s2; if (s<0) { s += 60; m--; } if (m<0) { m += 60; h--; } prq.len = 22; prq.unit = 0; prq.command = 132; prq.mode = 1; DD(prq.loc) = cdda_track_start; DD(prq.secnum) = (h*270000) + (m*4500) + (s*75); cdda_loop_counter = (h*216000) + (m*3600) + (s*60); dosmemput(&prq, sizeof(PLAYREQ), __tb); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(PLAYREQ), &prq); if (DW(cmd.status)&0x8000) return 0; cdda_current_track = track; cdda_playing = 1; return 1; } //---------------------------------------------------------------------------- void cdda_stop(void) { STOPREQ cmd; cmd.len = 13; cmd.unit = 0; cmd.command = 133; dosmemput(&cmd, sizeof(STOPREQ), __tb); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); cdda_playing = 0; } //---------------------------------------------------------------------------- void cdda_resume(void) { STOPREQ cmd; cmd.len = 13; cmd.unit = 0; cmd.command = 136; dosmemput(&cmd, sizeof(STOPREQ), __tb); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); cdda_playing = 1; } //---------------------------------------------------------------------------- void cdda_shutdown(void) { cdda_stop(); } //---------------------------------------------------------------------------- void cdda_loop_check(void) { if (cdda_playing==1) { cdda_loop_counter--; if (cdda_loop_counter==0) { if (cdda_autoloop) cdda_play(cdda_current_track); else cdda_stop(); } } } //---------------------------------------------------------------------------- int cdda_get_volume(void) { VOLREQ cmd; VOLINFO vol; cmd.len = sizeof(VOLREQ); cmd.unit = 0; cmd.command = 3; cmd.media = 0; DW(cmd.sector) = 0; DD(cmd.volid) = 0; DW(cmd.adr_seg) = (__tb>>4); DW(cmd.adr_off) = sizeof(VOLREQ); DW(cmd.bytes) = 9; vol.mode = 4; dosmemput(&cmd, sizeof(VOLREQ), __tb); dosmemput(&vol, sizeof(VOLINFO), (__tb + sizeof(VOLREQ))); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(VOLREQ), &cmd); dosmemget((__tb + sizeof(VOLREQ)), sizeof(VOLINFO), &vol); return vol.volume0; } //---------------------------------------------------------------------------- void cdda_set_volume(int volume) { VOLREQ cmd; VOLINFO vol; vol.mode = 3; vol.input0 = 0; vol.input1 = 1; vol.input2 = 2; vol.input3 = 3; vol.volume0 = volume; vol.volume1 = volume; vol.volume2 = volume; vol.volume3 = volume; cmd.len = sizeof(VOLREQ); cmd.unit = 0; cmd.command = 12; cmd.media = 0; DW(cmd.adr_seg) = (__tb>>4); DW(cmd.adr_off) = sizeof(VOLREQ); DW(cmd.bytes) = 9; dosmemput(&cmd, sizeof(VOLREQ), __tb); dosmemput(&vol, sizeof(VOLINFO), (__tb + sizeof(VOLREQ))); memset(&_regs, 0, sizeof(_regs)); _regs.x.es = _regs.x.ds = _regs.x.cs = (__tb>>4); _regs.x.bx = 0; _regs.x.cx = cdda_current_drive; _regs.x.ax = 0x1510; __dpmi_int(0x2f, &_regs); dosmemget(__tb, sizeof(VOLREQ), &cmd); dosmemget((__tb + sizeof(VOLREQ)), sizeof(VOLINFO), &vol); } //---------------------------------------------------------------------------- void audio_setup(void) { audio_options[4].dp = rsc[SLIDER].dat; audio_options[4].d2 = cdda_get_volume(); audio_options[6].dp = rsc[SLIDER].dat; audio_options[6].d2 = sound_vol; centre_dialog(audio_options); popup_dialog(audio_options, 0); cdda_set_volume(audio_options[4].d2); set_config_int(NULL, "cddavol", audio_options[4].d2); sound_vol = audio_options[6].d2; set_config_int(NULL, "soundvol", audio_options[6].d2); }