scummvm/backends/PalmOS/Src/cd_msa.cpp
2006-02-11 12:47:47 +00:00

261 lines
7.2 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2006 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include <SonyClie.h>
#include "common/stdafx.h"
#include "common/system.h"
#include "cd_msa.h"
#include "start.h" // for appFileCreat
static void doErr(Err e, const Char *msg) {
Char err[100];
StrPrintF(err, "%ld : " , e);
StrCat(err,msg);
FrmCustomAlert(1000,err,0,0);
}
MsaCDPlayer::MsaCDPlayer(OSystem *sys) {
_sys = sys;
_msaRefNum = sysInvalidRefNum;
_msaLoops = 0;
_msaStopTime = 0;
_msaTrackEndSu = 0;
}
bool MsaCDPlayer::init() {
SonySysFtrSysInfoP sonySysFtrSysInfoP;
Err error = errNone;
if (!(error = FtrGet(sonySysFtrCreator, sonySysFtrNumSysInfoP, (UInt32*)&sonySysFtrSysInfoP))) {
// not found with audio adapter ?!
//if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrMsa) {
if ((error = SysLibFind(sonySysLibNameMsa, &_msaRefNum)))
if (error == sysErrLibNotFound)
error = SysLibLoad(sonySysFileTMsaLib, sonySysFileCMsaLib, &_msaRefNum);
// FIXME : still don't understand how this lib works, it seems to be very unstable
// and with the very bad documentation provided by Sony it's difficult to find out why
// this doesn't work the same way on build-in MP3 device and external MP3 devices
if (!error) {
//MsaLibClose(_msaRefNum, msaLibOpenModeAlbum); // close the lib if we previously let it open (?) Need to add Notify for sonySysNotifyMsaEnforceOpenEvent just in case ...
error = MsaLibOpen(_msaRefNum, msaLibOpenModeAlbum);
//if (error == msaErrAlreadyOpen)
// error = MsaLibEnforceOpen(_msaRefNum, msaLibOpenModeAlbum, appFileCreator);
//error = (error != msaErrStillOpen) ? error : errNone;
}
//}
}
// if (error)
// _msaRefNum = sysInvalidRefNum;
_isInitialized = (_msaRefNum != sysInvalidRefNum);
initInternal();
return _isInitialized;
}
void MsaCDPlayer::initInternal() {
if (!_isInitialized)
return;
Err e;
Char nameP[256];
UInt32 dummy, albumIterater = albumIteratorStart;
MemSet(&_msaAlbum, sizeof(_msaAlbum), 0);
_msaAlbum.maskflag = msa_INF_ALBUM;
_msaAlbum.code = msa_LANG_CODE_ASCII;
_msaAlbum.nameP = nameP;
_msaAlbum.fileNameLength = 256;
e = MsaAlbumEnumerate(_msaRefNum, &albumIterater, &_msaAlbum);
e = MsaSetAlbum(_msaRefNum, _msaAlbum.albumRefNum, &dummy);
// TODO : use RMC to control volume
MsaOutCapabilityType capability;
MsaOutGetCapability(_msaRefNum, &capability);
_volumeLLimit = capability.volumeLLimit;
_volumeRLimit = capability.volumeRLimit;
}
void MsaCDPlayer::setVolume(int volume) {
_volumeLevel = volume;
MsaOutSetVolume(_msaRefNum, (_volumeLLimit * volume) / 100, (_volumeRLimit * volume) / 100);
}
void MsaCDPlayer::release() {
if (_isInitialized) {
if (_msaRefNum != sysInvalidRefNum) {
// stop the current track if any (needed if we use enforce open to prevent the track to play after exit)
MsaStop(_msaRefNum, true);
MsaLibClose(_msaRefNum, msaLibOpenModeAlbum);
}
}
// self delete
delete this;
}
bool MsaCDPlayer::poll() {
if (!_isInitialized)
return false;
MsaPBStatus pb;
MsaGetPBStatus(_msaRefNum, &pb);
return (_msaLoops != 0 && (pb.currentSU < _msaTrackEndSu || pb.status != msa_STOPSTATUS));
}
void MsaCDPlayer::update() {
if (!_isInitialized)
return;
// get playback status
MsaPBStatus pb;
MsaGetPBStatus(_msaRefNum, &pb);
// stop replay upon request of stopCD()
if (_msaStopTime != 0 && _sys->getMillis() >= _msaStopTime) {
MsaStop(_msaRefNum, true);
_msaLoops = 0;
_msaStopTime = 0;
_msaTrackEndSu = 0;
return;
}
// not fully played nad still playing the correct track
// (when playing a full track the return SU is not correct
// and so we need to check if we are still playing the correct track)
if (pb.currentSU < _msaTrackEndSu) {
UInt16 trackNo;
MsaPBListIndexToTrackNo(_msaRefNum, pb.currentpblistindex, &trackNo);
if (trackNo == _msaTrack)
return;
}
MsaStop(_msaRefNum, true);
if (_msaLoops == 0)
return;
// track ends and last play, force stop if still playing
/* if (_msaLoops != 1 && pb.status != msa_STOPSTATUS) {
MsaStop(_msaRefNum, true);
return;
}
*/
// loop again ?
if (_msaLoops > 0)
_msaLoops--;
// loop if needed
if (_msaLoops != 0) {
if (_msaStartFrame == 0 && _msaDuration == 0)
MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP);
else
MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP);
}
}
void MsaCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */
if (!_isInitialized)
return;
_msaStopTime = _sys->getMillis() + 100;
_msaLoops = 0;
return;
}
void MsaCDPlayer::play(int track, int num_loops, int start_frame, int duration) {
if (!_isInitialized)
return;
if (!num_loops && !start_frame)
return;
_msaTrack = track + gVars->CD.firstTrack - 1; // first track >= 1 ?, not 0 (0=album)
_msaLoops = num_loops;
_msaStartFrame = TO_MSECS(start_frame);
_msaDuration = TO_MSECS(duration);
Err e;
MemHandle trackH;
// stop current play if any
MsaStop(_msaRefNum, true);
_msaStopTime = 0;
// retreive track infos
e = MsaGetTrackInfo(_msaRefNum, _msaTrack, 0, msa_LANG_CODE_ASCII, &trackH);
// track exists
if (!e && trackH) {
MsaTime msaTime;
MsaTrackInfo *trackP;
UInt32 SU, fullLength;
// FIXME (?) : this enable MsaSuToTime to return the right value in some cases
MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP);
MsaStop(_msaRefNum, true);
// get the msa time
trackP = (MsaTrackInfo *)MemHandleLock(trackH);
MsaSuToTime(_msaRefNum, trackP->totalsu, &msaTime);
SU = trackP->totalsu;
MemPtrUnlock(trackP);
MemHandleFree(trackH);
// MSA frame in milli-seconds
fullLength = FROM_MIN(msaTime.minute);
fullLength += FROM_SEC(msaTime.second);
fullLength += msaTime.frame;
if (_msaDuration > 0) {
_msaTrackLength = _msaDuration;
} else if (_msaStartFrame > 0) {
_msaTrackLength = fullLength;
_msaTrackLength -= _msaStartFrame;
} else {
_msaTrackLength = fullLength;
}
// try to play the track
if (start_frame == 0 && duration == 0) {
MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP);
_msaTrackEndSu = SU;
} else {
// FIXME : MsaTimeToSu doesn't work ... (may work with previous FIXME)
_msaTrackStartSu = (UInt32) ((float)(_msaStartFrame) / ((float)fullLength / (float)SU));
_msaTrackEndSu = (UInt32) ((float)(_msaTrackLength) / ((float)fullLength / (float)SU));
_msaTrackEndSu += _msaTrackStartSu;
if (_msaTrackEndSu > SU)
_msaTrackEndSu = SU;
MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP);
}
}
// TODO : use default track length if track not found
}