[Scummvm-git-logs] scummvm master -> 252f95ec17644081a2b7b2caa8ed3d7f7020ccec

mistydemeo noreply at scummvm.org
Thu Aug 25 19:49:28 UTC 2022


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
252f95ec17 DIRECTOR: Implement AppleAudioCD


Commit: 252f95ec17644081a2b7b2caa8ed3d7f7020ccec
    https://github.com/scummvm/scummvm/commit/252f95ec17644081a2b7b2caa8ed3d7f7020ccec
Author: Misty De Meo (mistydemeo at gmail.com)
Date: 2022-08-25T12:49:24-07:00

Commit Message:
DIRECTOR: Implement AppleAudioCD

This XObj is specific to the Apple SCSI drive and was used in early
Mac games such as Alice (1991).

I haven't implemented the methods that operate on absolute times, because
they rely on a CD playback API that works on the full disc TOC. Unless
I've missed something, AudioCDManager doesn't implement that and there
isn't something else that does.

Changed paths:
    engines/director/director.h
    engines/director/lingo/xlibs/cdromxobj.cpp


diff --git a/engines/director/director.h b/engines/director/director.h
index 769d4499d1f..38e49f56a1f 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -22,6 +22,8 @@
 #ifndef DIRECTOR_DIRECTOR_H
 #define DIRECTOR_DIRECTOR_H
 
+#include "backends/audiocd/audiocd.h"
+
 #include "common/file.h"
 #include "common/hashmap.h"
 #include "common/hash-ptr.h"
@@ -215,6 +217,7 @@ public:
 	RandomState _rnd;
 	Graphics::MacWindowManager *_wm;
 	Graphics::PixelFormat _pixelformat;
+	AudioCDManager::Status _cdda_status;
 
 public:
 	int _colorDepth;
diff --git a/engines/director/lingo/xlibs/cdromxobj.cpp b/engines/director/lingo/xlibs/cdromxobj.cpp
index 231ec719400..7a1d7b85ebb 100644
--- a/engines/director/lingo/xlibs/cdromxobj.cpp
+++ b/engines/director/lingo/xlibs/cdromxobj.cpp
@@ -103,6 +103,7 @@
  *     position.
  */
 
+#include "backends/audiocd/audiocd.h"
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
@@ -118,7 +119,7 @@ const char *CDROMXObj::fileNames[] = {
 };
 
 static MethodProto xlibMethods[] = {
-	{ "new",			CDROMXObj::m_new,			 2, 2,	200 },	// D2
+	{ "new",			CDROMXObj::m_new,			 0, 0,	200 },	// D2
 	{ "Name",			CDROMXObj::m_name,		 	 0, 0,	200 },	// D2
 	{ "Play",			CDROMXObj::m_play,		 	 0, 0,	200 },	// D2
 	{ "PlayTrack",		CDROMXObj::m_playTrack,	 	 1, 1,	200 },	// D2
@@ -161,6 +162,7 @@ void CDROMXObj::close(int type) {
 	if (type == kXObj) {
 		CDROMXObject::cleanupMethods();
 		g_lingo->_globalvars[xlibName] = Datum();
+        g_director->_system->getAudioCDManager()->close();
 	}
 }
 
@@ -170,44 +172,74 @@ CDROMXObject::CDROMXObject(ObjectType ObjectType) :Object<CDROMXObject>("AppleAu
 }
 
 void CDROMXObj::m_new(int nargs) {
+    g_director->_system->getAudioCDManager()->open();
 	g_lingo->printSTUBWithArglist("CDROMXObj::m_new", nargs);
 	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_currentMe);
 }
 
+// Returns the name of the XObj
 void CDROMXObj::m_name(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_name", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+	g_lingo->push(Datum("AppleAudioCD"));
 }
 
 void CDROMXObj::m_play(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_play", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // This is a request to play the current track from the start,
+    // which we can't do if there's no track information.
+    if (g_director->_cdda_status.track == 0)
+        return;
+
+    g_director->_system->getAudioCDManager()->play(g_director->_cdda_status.track, -1, 0, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_playTrack(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_playTrack", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    int track = g_lingo->pop().asInt();
+    g_director->_system->getAudioCDManager()->play(track, -1, 0, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
+// Name format is "TRACK NN", with one-digit tracks padded with a leading space
 void CDROMXObj::m_playName(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_playName", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+	Common::String track = g_lingo->pop().asString();
+    if (track.size() < 8) {
+        warning("CDROMXObj::m_playName: specified name has an invalid format (provided string was %s)", track.c_str());
+        return;
+    }
+    Common::String trackNum = track.substr(6, 2);
+    // Remove the leading string as needed
+    if (trackNum.substr(0, 1) == " ")
+        trackNum = trackNum.substr(1, 1);
+
+    int trackNumI = atoi(trackNum.c_str());
+    if (trackNumI < 1) {
+        warning("CDROMXObj::m_playName: track number failed to parse (provided string was %s)", track.c_str());
+    }
+
+    g_director->_system->getAudioCDManager()->play(trackNumI, -1, 0, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_playAbsTime(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_playAbsTime", nargs);
-	g_lingo->dropStack(nargs);
+	Datum min = g_lingo->pop();
+    Datum sec = g_lingo->pop();
+    Datum frac = g_lingo->pop();
+    // Can't implement this without implementing a full CD TOC, since
+    // it doesn't interact with songs at the "track" level.
+    debug(5, "STUB: CDROMXObj::m_playAbsTime Request to play starting at %i:%i.%i", min.asInt(), sec.asInt(), frac.asInt());
 	g_lingo->push(Datum());
 }
 
 void CDROMXObj::m_playSegment(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_playSegment", nargs);
-	g_lingo->dropStack(nargs);
+    Datum startMin = g_lingo->pop();
+    Datum startSec = g_lingo->pop();
+    Datum startFrac = g_lingo->pop();
+    Datum endMin = g_lingo->pop();
+    Datum endSec = g_lingo->pop();
+    Datum endFrac = g_lingo->pop();
+    // Can't implement this without implementing a full CD TOC, since
+    // it doesn't interact with songs at the "track" level.
+	debug(5, "STUB: CDROMXObj::m_playSegment Request to play starting at %i:%i.%i and ending at %i:%i.%i", startMin.asInt(), startSec.asInt(), startFrac.asInt(), endMin.asInt(), endSec.asInt(), endFrac.asInt());
 	g_lingo->push(Datum());
 }
 
@@ -218,81 +250,137 @@ void CDROMXObj::m_askPlay(int nargs) {
 }
 
 void CDROMXObj::m_stepFwd(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_stepFwd", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    g_director->_system->getAudioCDManager()->play(g_director->_cdda_status.track + 1, -1, 0, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_stepBwd(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_stepBwd", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    int track = g_director->_cdda_status.track - 1;
+    if (track < 1)
+        track = 1;
+
+    g_director->_system->getAudioCDManager()->play(track, -1, 0, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_pause(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_pause", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // Leaves a trace of the current position so we can resume from it
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
+    g_director->_cdda_status.playing = false;
+    g_director->_system->getAudioCDManager()->stop();
 }
 
 void CDROMXObj::m_continue(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_continue", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // Can only resume if there's data to resume from
+    if (g_director->_cdda_status.track == 0)
+        return;
+
+    g_director->_system->getAudioCDManager()->play(g_director->_cdda_status.track, -1, g_director->_cdda_status.start, 0);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_stop(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_stop", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    g_director->_system->getAudioCDManager()->stop();
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_stopTrack(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_stopTrack", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    Datum track = g_lingo->pop();
+    AudioCDManager::Status status = g_director->_system->getAudioCDManager()->getStatus();
+
+    if (!status.playing)
+        return;
+
+    // stopTrack isn't "stop now", but "stop after this track".
+    // This play command ensures we continue from here and end with this
+    // track, regardless of previous commands.
+    g_director->_system->getAudioCDManager()->play(status.track, 1, status.start, status.start + status.duration);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_stopAbsTime(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_stopAbsTime", nargs);
+    Datum min = g_lingo->pop();
+    Datum sec = g_lingo->pop();
+    Datum frac = g_lingo->pop();
+    // Can't implement this without implementing a full CD TOC, since
+    // it doesn't interact with songs at the "track" level.
+    debug(5, "STUB: CDROMXObj::m_stopAbsTime Request to play starting at %i:%i.%i", min.asInt(), sec.asInt(), frac.asInt());
 	g_lingo->dropStack(nargs);
 	g_lingo->push(Datum());
 }
 
 void CDROMXObj::m_removeStop(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_removeStop", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    Datum track = g_lingo->pop();
+    AudioCDManager::Status status = g_director->_system->getAudioCDManager()->getStatus();
+
+    if (!status.playing)
+        return;
+
+    g_director->_system->getAudioCDManager()->play(status.track, -1, status.start, status.start + status.duration);
+    g_director->_cdda_status = g_director->_system->getAudioCDManager()->getStatus();
 }
 
 void CDROMXObj::m_eject(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_eject", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    warning("If you had had a CD drive, it would have ejected just now.");
 }
 
+// Valid strings are:
+// "Audio play in progress"
+// "Audio pause in operation"
+// "Audio muting on"
+// "Audio play operation completed"
+// "Error occurred during audio play"
+// "Not currently playing"
 void CDROMXObj::m_status(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_status", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // A fuller implementation could also track data to return the
+    // "pause" and "completed" states.
+    if (g_director->_system->getAudioCDManager()->isPlaying())
+        g_lingo->push(Datum("Audio play in progress"));
+    else
+        g_lingo->push(Datum("Not currently playing"));
 }
 
+// Valid strings are:
+// "Muting on (no audio)"
+// "Right channel through right channel only"
+// "Left channel through right channel only"
+// "Left and right channels through right channel only"
+// "Right channel through left channel only"
+// "Right channel through left and right channel"
+// "Right channel through left channel"
+// "Left channel through right channel"
+// "Right channel through left channel"
+// "Left and right channels through right channel"
+// "Left channel through left channel only"
+// "Left channel through left channel"
+// "Right channel through right channel (Stereo)"
+// "Left channel through left and right channel"
+// "Left channel through left channel"
+// "Left and right channels through right channel"
+// "Left and right channels through left channel only"
+// "Left and right channels through left channel"
+// "Left and right channels through left channel"
+// "Right channel through right channel"
+// "Left and right channels through left channel"
+// "Left channel through right channel"
+// "Left and right channels through"
+// "both left channel and right channel (Mono)"
 void CDROMXObj::m_playMode(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_playMode", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // For now, nothing to change modes is implemented, so just return
+    // a default
+	g_lingo->push(Datum("Right channel through right channel (Stereo)"));
 }
 
+// Valid strings are:
+// "audio channels without preemphasis"
+// "audio channels with preemphasis"
 void CDROMXObj::m_currentFormat(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_currentFormat", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+    // Preemphasis not implemented, so just return this
+	g_lingo->push(Datum("audio channels without preemphasis"));
 }
 
 void CDROMXObj::m_currentTrack(int nargs) {
-	g_lingo->printSTUBWithArglist("CDROMXObj::m_currentTrack", nargs);
-	g_lingo->dropStack(nargs);
-	g_lingo->push(Datum());
+	g_lingo->push(Datum(g_director->_cdda_status.track));
 }
 
 void CDROMXObj::m_currentTime(int nargs) {
@@ -301,6 +389,8 @@ void CDROMXObj::m_currentTime(int nargs) {
 	g_lingo->push(Datum());
 }
 
+// The next few methods depend on full TOC implementation, so they
+// can't be implemented right now.
 void CDROMXObj::m_firstTrack(int nargs) {
 	g_lingo->printSTUBWithArglist("CDROMXObj::m_firstTrack", nargs);
 	g_lingo->dropStack(nargs);
@@ -319,6 +409,8 @@ void CDROMXObj::m_totalTime(int nargs) {
 	g_lingo->push(Datum());
 }
 
+// The scan methods depend on absolute timing, so they also require
+// a full TOC.
 void CDROMXObj::m_scanFwd(int nargs) {
 	g_lingo->printSTUBWithArglist("CDROMXObj::m_scanFwd", nargs);
 	g_lingo->dropStack(nargs);




More information about the Scummvm-git-logs mailing list