scummvm/backends/PalmOS/Src/cd_msa.cpp
2003-09-23 15:49:33 +00:00

312 lines
8.9 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include <SonyClie.h>
#include "scumm.h"
#include "common/system.h"
#include "cd_msa.h"
#include "start.h" // for appFileCreator
MsaCDPlayer::MsaCDPlayer(OSystem *sys) {
_sys = sys;
_msaRefNum = sysInvalidRefNum;
}
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);
if (!error) {
// Char buf[100];
// StrPrintF(buf,"MSA refNum %ld, Try to open lib ...", refNum);
// FrmCustomAlert(1000,buf,0,0);
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);
/* switch (error) {
case msaErrAlreadyOpen:
FrmCustomAlert(1000,"msaErrAlreadyOpen",0,0);
break;
case msaErrMemory:
FrmCustomAlert(1000,"msaErrMemory",0,0);
break;
case msaErrDifferentMode:
FrmCustomAlert(1000,"msaErrDifferentMode",0,0);
break;
case expErrCardNotPresent:
FrmCustomAlert(1000,"expErrCardNotPresent",0,0);
break;
}
*/
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;
// Beeeeeep !!!
// MsaOutCapabilityType capability;
// MsaOutInit(_msaRefNum);
// MsaOutGetCapability(_msaRefNum, &capability);
// MsaOutSetBeepLevel(_msaRefNum, capability.beepMaxLebel);
// MsaOutStartBeep(_msaRefNum, 1000, msaOutBeepPatternOK);
Err e;
UInt32 dummy, albumIterater = albumIteratorStart;
Char nameP[256];
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);
// if (e) doErr(e, "MsaAlbumEnumerate");
e = MsaSetAlbum(_msaRefNum, _msaAlbum.albumRefNum, &dummy);
// if (e) doErr(e, "MsaSetAlbum");
// e = MsaGetPBRate(_msaRefNum, &_msaPBRate);
// if (e) doErr(e, "MsaGetPBRate");
// TODO : use RMC to control volume
// move this to setSolume
MsaOutSetVolume(_msaRefNum, 20, 20);
}
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 && (_sys->get_msecs() < _msaEndTime || pb.status != msa_STOPSTATUS));
}
void MsaCDPlayer::update() {
if (!_isInitialized)
return;
// stop replay upon request of stop_cdrom()
if (_msaStopTime != 0 && _sys->get_msecs() >= _msaStopTime) {
MsaStop(_msaRefNum, true);
_msaLoops = 0;
_msaStopTime = 0;
_msaEndTime = 0;
return;
}
// not fully played
if (_sys->get_msecs() < _msaEndTime)
return;
if (_msaLoops == 0) {
MsaStop(_msaRefNum, true);
return;
}
// track ends and last play, force stop if still playing
if (_msaLoops != 1) {
MsaPBStatus pb;
MsaGetPBStatus(_msaRefNum, &pb);
if (pb.status != msa_STOPSTATUS) {
// debug(0,"Stop It now");
MsaStop(_msaRefNum, true);
return;
}
}
// loop again ?
if (_msaLoops > 0) {
MsaStop(_msaRefNum, true); // stop if loop=0
_msaLoops--;
}
// loop if needed
if (_msaLoops != 0) {
MsaStop(_msaRefNum, true);
// debug(0,"Next loop : %d", _msaLoops);
_msaEndTime = _sys->get_msecs() + _msaTrackLength;
if (_msaStartFrame == 0 && _msaEndFrame == 0)
MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP);
else
MsaPlay(_msaRefNum, _msaTrack, _msaTrackStart, msa_PBRATE_SP);
}
}
static void doErr(Err e, const Char *msg) {
Char err[100];
StrPrintF(err, "%ld : " , e);
StrCat(err,msg);
FrmCustomAlert(1000,err,0,0);
}
void MsaCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */
if (!_isInitialized)
return;
_msaStopTime = _sys->get_msecs() + 100;
_msaLoops = 0;
return;
}
// frames are 1/75 sec
#define CD_FPS 75
#define TO_MSECS(frame) ((UInt32)((frame) * 1000 / CD_FPS))
// consider frame at 1/1000 sec
#define TO_SEC(msecs) ((UInt16)((msecs) / 1000))
#define TO_MIN(msecs) ((UInt16)(TO_SEC((msecs)) / 60))
#define FROM_MIN(mins) ((UInt32)((mins) * 60 * 1000))
#define FROM_SEC(secs) ((UInt32)((secs) * 1000))
#define FRAMES_TO_MSF(f, M,S,F) { \
int value = f; \
*(F) = value%CD_FPS; \
value /= CD_FPS; \
*(S) = value%60; \
value /= 60; \
*(M) = value; \
}
void MsaCDPlayer::play(int track, int num_loops, int start_frame, int duration) {
if (!_isInitialized)
return;
if (!num_loops && !start_frame)
return;
Err e;
/*
if (start_frame > 0)
start_frame += CD_FPS >> 1;
*/
if (duration > 0)
duration += 5;
// debug(0, ">> Request : track %d / loops : %d / start : %d / duration : %d", track, num_loops, start_frame, duration);
_msaLoops = num_loops;
_msaTrack = track + gVars->music.firstTrack - 1; // first track >= 1 ?, not 0 (0=album)
_msaStartFrame = TO_MSECS(start_frame);
_msaEndFrame = TO_MSECS(duration);
// debug(0, ">> To MSECS : start : %d / duration : %d", _msaStartFrame, _msaEndFrame);
// if gVars->MP3 audio track
// Err e;
MemHandle trackH;
// stop current play if any
MsaStop(_msaRefNum, true);
// retreive track infos
e = MsaGetTrackInfo(_msaRefNum, _msaTrack, 0, msa_LANG_CODE_ASCII, &trackH);
// if (e) doErr(e, "MsaGetTrackInfo");
// track exists
if (!e && trackH) {
MsaTime tTime;
UInt32 SU, fullLength;
MsaTrackInfo *tiP;
// FIXME : this enable MsaSuToTime to return the right value
MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP);
MsaStop(_msaRefNum, true);
tiP = (MsaTrackInfo *)MemHandleLock(trackH);
MsaSuToTime(_msaRefNum, tiP->totalsu, &tTime);
SU = tiP->totalsu;
MemPtrUnlock(tiP);
MemHandleFree(trackH);
// debug(0, ">> SU of track : %d (%d%:%d.%d)", SU, tTime.minute, tTime.second, tTime.frame);
// Char buf[200];
// StrPrintF(buf,"Track : %ld - %ld%:%ld.%ld (%ld)", track, tTime.minute, tTime.second, tTime.frame, SU);
// FrmCustomAlert(1000,buf,0,0);
_msaStopTime = 0;
fullLength = FROM_MIN(tTime.minute) + FROM_SEC(tTime.second) + tTime.frame;
// debug(0, ">> Full length : %d", fullLength);
if (_msaEndFrame > 0) {
_msaTrackLength = _msaEndFrame;
} 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);
} else {
// FIXME : MsaTimeToSu doesn't work ... (may work with previous FIXME)
_msaTrackStart = (UInt32) ((float)(_msaStartFrame) / ((float)fullLength / (float)SU));
// debug(0, ">> start at (float) : %d", _msaTrackStart);
/*
UInt32 f;
FRAMES_TO_MSF(start_frame, &tTime.minute, &tTime.second, &f)
tTime.frame = 0;
MsaTimeToSu(_msaRefNum, &tTime, &SU);
debug(0, ">> start at (MsaTimeToSu) : %d", SU);
*/
MsaPlay(_msaRefNum, _msaTrack, _msaTrackStart, msa_PBRATE_SP);
}
_msaEndTime = _sys->get_msecs() + _msaTrackLength;
// debug(0, ">> track length : %d / end : %d", _msaTrackLength, _msaEndTime);
}
}