dockapps/ascd/ascd/cdcontrol.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;
}