363 lines
9.3 KiB
C
363 lines
9.3 KiB
C
/* ===========================================================================
|
|
* AScd: cdcontrol.c
|
|
* This is cd_control() function: accept orders from the ui player and send
|
|
* the appropriate commands to libworkman.
|
|
*
|
|
* Please do *not* modify this function as it is used without changes by
|
|
* several programs!
|
|
* ===========================================================================
|
|
* Copyright (c) 1999 Denis Bourez and Rob Malda. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Denis Bourez & Rob Malda
|
|
* 4. Neither the name of the author nor the names of any co-contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY DENIS BOUREZ AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL DENIS BOUREZ, ROB MALDA OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
* ===========================================================================
|
|
*/
|
|
|
|
#define CD_C_VERSION "1.4"
|
|
#include "ext.h"
|
|
|
|
void
|
|
cd_control(int order)
|
|
{
|
|
static int pos_changed = FALSE;
|
|
int currenttrack;
|
|
|
|
anomalie = 0;
|
|
wanna_play = FALSE;
|
|
|
|
#ifdef XFASCD
|
|
update_xpm = TRUE;
|
|
#endif
|
|
|
|
if (cur_cdmode != WM_CDM_EJECTED) {
|
|
if (cd->trk[cur_track - 1].data) datatrack = 1;
|
|
else datatrack = 0;
|
|
}
|
|
|
|
if ((cur_ntracks == 1) && (cd->trk[cur_track - 1].data)) {
|
|
|
|
/* only one track, and it's a data track. We ignore
|
|
all commands to avoid some funny things. Only the EJECT
|
|
commands are allowed */
|
|
|
|
if ((order != STOP) && (order != EJECT)) {
|
|
anomalie = 1;
|
|
return;
|
|
}
|
|
}
|
|
|
|
switch(order) {
|
|
|
|
case PLAY:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if (! pos_changed) {
|
|
wm_cd_status();
|
|
} else {
|
|
pos_changed = FALSE;
|
|
}
|
|
|
|
if (cur_track < 1) cur_track = 1;
|
|
|
|
/* don't play data tracks: */
|
|
|
|
if (! cd->trk[cur_track - 1].data) {
|
|
if (cur_cdmode != WM_CDM_EJECTED) {
|
|
if (cur_cdmode != WM_CDM_PAUSED) {
|
|
if (do_autorepeat) {
|
|
cur_track = 1;
|
|
do_autorepeat = FALSE;
|
|
}
|
|
|
|
/* skip data and avoid tracks */
|
|
while (((cd->trk[cur_track - 1].data) || ((cd->trk[cur_track - 1].avoid == 1) && (!ignore_avoid)) ) && (cur_track <= cur_ntracks)) cur_track++;
|
|
|
|
if (cur_track > cur_ntracks) cur_track--;
|
|
if (!(cd->trk[cur_track - 1].data)) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PAUSE:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
|
|
if (pos_changed) {
|
|
cur_track = wanted_track;
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
cur_cdmode = WM_CDM_PLAYING;
|
|
} else {
|
|
wm_cd_pause();
|
|
}
|
|
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
pos_changed = FALSE;
|
|
}
|
|
break;
|
|
|
|
case STOP: /* Civilized handler: STOP and EJECT combined */
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if ((cur_cdmode == WM_CDM_PLAYING) || (cur_cdmode == WM_CDM_PAUSED)) {
|
|
cur_cdmode = WM_CDM_PAUSED;
|
|
wm_cd_stop();
|
|
cur_cdmode = WM_CDM_STOPPED;
|
|
} else {
|
|
if (cur_cdmode != WM_CDM_EJECTED) {
|
|
currenttrack = 0;
|
|
wm_cd_eject();
|
|
}
|
|
}
|
|
pos_changed = FALSE;
|
|
break;
|
|
|
|
case STOPONLY: /* STOP, no more. Doesn't eject if CD is already stopped */
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if ((cur_cdmode == WM_CDM_PLAYING) || (cur_cdmode == WM_CDM_PAUSED)) {
|
|
cur_cdmode = WM_CDM_PAUSED;
|
|
wm_cd_stop();
|
|
cur_cdmode = WM_CDM_STOPPED;
|
|
}
|
|
pos_changed = FALSE;
|
|
break;
|
|
|
|
case EJECT: /* Troll handler: don't try to guess the current mode, just eject */
|
|
if (cur_cdmode != WM_CDM_EJECTED) {
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
currenttrack = 0;
|
|
wm_cd_eject();
|
|
}
|
|
break;
|
|
|
|
case CLOSETRAY: /* let's try this */
|
|
if (cur_cdmode == WM_CDM_EJECTED) {
|
|
/* commented, as current libworkman crashes when it receive this order */
|
|
/*wm_cd_closetray();*/
|
|
}
|
|
break;
|
|
|
|
case UPTRACK: /* next track */
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if (pos_changed) cur_track = wanted_track;
|
|
|
|
if (cur_track + 1 > cur_ntracks ) {
|
|
cur_track = 1;
|
|
} else {
|
|
cur_track ++;
|
|
}
|
|
if (cur_cdmode == WM_CDM_PAUSED) {
|
|
pos_changed = TRUE;
|
|
wanted_track = cur_track;
|
|
}
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
}
|
|
break;
|
|
|
|
case DNTRACK: /* previous track */
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if (pos_changed) cur_track = wanted_track;
|
|
|
|
if (cur_cdmode == WM_CDM_PAUSED) {
|
|
if (cur_pos_rel < 2 || pos_changed) cur_track--;
|
|
cur_pos_rel = 0;
|
|
pos_changed = TRUE;
|
|
} else if (cur_cdmode == WM_CDM_PLAYING) {
|
|
if (cur_pos_rel < 2) cur_track--;
|
|
cur_pos_rel = 0;
|
|
} else {
|
|
cur_track--;
|
|
}
|
|
if (cur_track < 1) cur_track = cur_ntracks;
|
|
if (cur_cdmode == WM_CDM_PAUSED) {
|
|
pos_changed = TRUE;
|
|
wanted_track = cur_track;
|
|
}
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
}
|
|
break;
|
|
|
|
case DIRECTTRACK: /* direct access to a random track */
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
|
|
if (direct_track < 1) direct_track = 1;
|
|
|
|
if (cur_cdmode == WM_CDM_PAUSED) pos_changed = TRUE;
|
|
cur_track = direct_track;
|
|
if (cur_track >= cur_ntracks + 1) cur_track = 1;
|
|
|
|
/* if it's a data track, skip it */
|
|
while ((cd->trk[cur_track - 1].data) && (cur_track <= cur_ntracks)) cur_track++;
|
|
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
}
|
|
break;
|
|
|
|
case CUE:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, cur_pos_rel + cue_time, cur_ntracks + 1);
|
|
}
|
|
break;
|
|
|
|
case REV:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
if ( (cur_cdmode == WM_CDM_PLAYING) && ( (cur_pos_rel - cue_time) >= 0 ) ) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, cur_pos_rel - cue_time, cur_ntracks + 1);
|
|
}
|
|
break;
|
|
|
|
case FIRST:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
cur_track = 1;
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
} else if (cur_cdmode == WM_CDM_PAUSED) {
|
|
pos_changed = TRUE;
|
|
wanted_track = cur_track;
|
|
}
|
|
break;
|
|
|
|
case LAST:
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
cur_track = cur_ntracks;
|
|
if (cur_cdmode == WM_CDM_PLAYING) {
|
|
wanna_play = TRUE;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
} else if (cur_cdmode == WM_CDM_PAUSED) {
|
|
pos_changed = TRUE;
|
|
wanted_track = cur_track;
|
|
}
|
|
break;
|
|
|
|
case LOOP:
|
|
if ( (loop_2 > loop_1) ||
|
|
(loop_end_track > loop_start_track) ) {
|
|
|
|
if (loop_start_track == 0) loop_start_track = 1;
|
|
intro_mode = 0;
|
|
if ( ( loop_2 > loop_1 )
|
|
|| ( loop_start_track != loop_end_track ) )
|
|
currenttrack = loop_start_track;
|
|
else {
|
|
loop_end_track = cur_ntracks;
|
|
currenttrack = loop_start_track = 1;
|
|
loop_1 = 0;
|
|
loop_2 =
|
|
thiscd.trk[ loop_end_track - 1 ].length - 1;
|
|
}
|
|
wm_cd_play(loop_start_track, loop_1, cur_ntracks + 1);
|
|
wanna_play = TRUE;
|
|
loop_mode = 1;
|
|
} else {
|
|
anomalie = 1;
|
|
}
|
|
break;
|
|
|
|
case DIRECTACCESS: /* direct access to a random position of the current track */
|
|
if (direct_access < 0) direct_access = 0;
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
wm_cd_status();
|
|
wm_cd_play(cur_track, direct_access, cur_ntracks + 1);
|
|
wanna_play = TRUE;
|
|
break;
|
|
|
|
case GLOBALACCESS:
|
|
if (direct_access < 0) direct_access = 0;
|
|
loop_mode = 0;
|
|
intro_mode = 0;
|
|
wm_cd_status();
|
|
wm_cd_play(1, direct_access, cur_ntracks + 1);
|
|
wanna_play = TRUE;
|
|
break;
|
|
|
|
case INTROSCAN:
|
|
if (! intro_mode) {
|
|
intro_mode = 1;
|
|
wm_cd_play(cur_track, 0, cur_ntracks + 1);
|
|
} else {
|
|
intro_mode = 0;
|
|
}
|
|
break;
|
|
|
|
case INTRONEXT:
|
|
wm_cd_pause();
|
|
currenttrack = cur_track;
|
|
currenttrack++;
|
|
if (cur_track +1 > cur_ntracks ) currenttrack = 1;
|
|
else currenttrack = cur_track + 1;
|
|
cur_pos_rel = 0;
|
|
wm_cd_play(currenttrack, 0, cur_ntracks + 1);
|
|
break;
|
|
|
|
case LOCACCESS:
|
|
if ( (loop_1 > 0) && (loop_start_track > 0) ) {
|
|
intro_mode = 0;
|
|
loop_mode = 0;
|
|
currenttrack = loop_start_track;
|
|
wm_cd_stop();
|
|
wm_cd_play(loop_start_track, loop_1, cur_ntracks + 1);
|
|
wanna_play = TRUE;
|
|
} else {
|
|
anomalie = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
char *cd_control_version(void)
|
|
{
|
|
char *s = NULL;
|
|
|
|
wm_strmcat(&s, CD_C_VERSION);
|
|
return s;
|
|
}
|