aboutsummaryrefslogtreecommitdiff
path: root/backends/morphos/morphos_sound.cpp
diff options
context:
space:
mode:
authorMax Horn2002-08-21 16:07:07 +0000
committerMax Horn2002-08-21 16:07:07 +0000
commitce46866403fdcc479cf9d67e4d430409b15dadc3 (patch)
tree75ebfaa1ed13f549959d76d3ce101c3e66f5451b /backends/morphos/morphos_sound.cpp
parent662256f25dbe43abf67077a804e225738765f009 (diff)
downloadscummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.tar.gz
scummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.tar.bz2
scummvm-rg350-ce46866403fdcc479cf9d67e4d430409b15dadc3.zip
Initial revision
svn-id: r4785
Diffstat (limited to 'backends/morphos/morphos_sound.cpp')
-rw-r--r--backends/morphos/morphos_sound.cpp284
1 files changed, 284 insertions, 0 deletions
diff --git a/backends/morphos/morphos_sound.cpp b/backends/morphos/morphos_sound.cpp
new file mode 100644
index 0000000000..0585b8708b
--- /dev/null
+++ b/backends/morphos/morphos_sound.cpp
@@ -0,0 +1,284 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 Rüdiger Hanke
+ *
+ * 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.
+ *
+ * MorphOS sound support
+ *
+ * $Header$
+ *
+ */
+
+#include "stdafx.h"
+#include "scumm.h"
+
+#include <dos/dos.h>
+#include <exec/memory.h>
+#include <devices/ahi.h>
+#include <devices/amidi.h>
+
+#include <clib/alib_protos.h>
+#include <proto/exec.h>
+#include <proto/dos.h>
+#include <proto/ahi.h>
+
+#include "morphos.h"
+
+#define AHI_BUF_SIZE (8*1024)
+
+SignalSemaphore ScummMusicThreadRunning;
+SignalSemaphore ScummSoundThreadRunning;
+
+static MsgPort *ahiPort = NULL;
+static AHIRequest *ahiReq[2] = { NULL, NULL };
+static UWORD ahiCurBuf = 0;
+static bool ahiReqSent[2] = { false, false };
+static BYTE ahiDevice = -1;
+ UBYTE ahiUnit = AHI_DEFAULT_UNIT;
+static char *ahiBuf[2] = { NULL, NULL };
+
+static MsgPort *ScummMidiPort = NULL;
+ IOMidiRequest *ScummMidiRequest = NULL;
+static MsgPort *MusicTimerMsgPort = NULL;
+ timerequest *MusicTimerIORequest = NULL;
+
+bool init_morphos_music(ULONG MidiUnit)
+{
+ if (ScummMusicDriver && !stricmp(ScummMusicDriver, "-eamidi")) // just as ugly as the line below ...
+ {
+ MidiUnit = ScummMidiUnit; // Ugly fix, but ...
+ ScummMidiPort = CreateMsgPort();
+ if (ScummMidiPort)
+ {
+ ScummMidiRequest = (IOMidiRequest *) CreateIORequest(ScummMidiPort, sizeof (IOMidiRequest));
+ if (ScummMidiRequest)
+ {
+ ScummMidiRequest->amr_Version = 2;
+ if (OpenDevice("amidi.device", MidiUnit, (IORequest *) ScummMidiRequest, AMIDIF_MIDISERVER))
+ {
+ DeleteIORequest((IORequest *) ScummMidiRequest);
+ DeleteMsgPort(ScummMidiPort);
+ ScummMidiRequest = NULL;
+ ScummMidiPort = NULL;
+ }
+ }
+ else
+ {
+ DeleteMsgPort(ScummMidiPort);
+ ScummMidiPort = NULL;
+ }
+ }
+
+ if (!ScummMidiRequest)
+ {
+ warning("Could not open AMidi - music will not play");
+ return false;
+ }
+ }
+
+ MusicTimerMsgPort = CreateMsgPort();
+ if (MusicTimerMsgPort)
+ {
+ MusicTimerIORequest = (timerequest *) CreateIORequest(MusicTimerMsgPort, sizeof (timerequest));
+ if (MusicTimerIORequest)
+ {
+ if (OpenDevice("timer.device", UNIT_MICROHZ, (IORequest *) MusicTimerIORequest, 0))
+ {
+ DeleteIORequest((IORequest *) MusicTimerIORequest);
+ DeleteMsgPort(MusicTimerMsgPort);
+ MusicTimerIORequest = NULL;
+ MusicTimerMsgPort = NULL;
+ }
+ }
+ else
+ {
+ DeleteMsgPort(MusicTimerMsgPort);
+ MusicTimerMsgPort = NULL;
+ }
+ }
+
+ if (!MusicTimerIORequest)
+ {
+ warning("Could not open timer device - music will not play");
+ return false;
+ }
+
+ return true;
+}
+
+
+void exit_morphos_music()
+{
+ if (ScummMidiRequest)
+ {
+ CloseDevice((IORequest *) ScummMidiRequest);
+ DeleteIORequest((IORequest *) ScummMidiRequest);
+ DeleteMsgPort(ScummMidiPort);
+ }
+
+ if (MusicTimerIORequest)
+ {
+ CloseDevice((IORequest *) MusicTimerIORequest);
+ DeleteIORequest((IORequest *) MusicTimerIORequest);
+ DeleteMsgPort(MusicTimerMsgPort);
+ }
+}
+
+
+static bool init_morphos_sound()
+{
+ if (!(ahiPort = CreateMsgPort()))
+ return false;
+
+ if (!(ahiReq[0] = (AHIRequest *) CreateIORequest(ahiPort, sizeof (AHIRequest))))
+ {
+ DeleteMsgPort(ahiPort);
+ ahiPort = NULL;
+ return false;
+ }
+
+ if (!(ahiReq[1] = (AHIRequest *) AllocVec(sizeof (AHIRequest), MEMF_PUBLIC)))
+ {
+ DeleteIORequest(ahiReq[0]);
+ DeleteMsgPort(ahiPort);
+ ahiReq[0] = NULL;
+ ahiPort = NULL;
+ return false;
+ }
+
+ if (!(ahiBuf[0] = (char *) AllocVec(2*AHI_BUF_SIZE, MEMF_PUBLIC)))
+ {
+ FreeVec(ahiReq[1]);
+ DeleteIORequest(ahiReq[0]);
+ DeleteMsgPort(ahiPort);
+ ahiReq[0] = NULL;
+ ahiReq[1] = NULL;
+ ahiPort = NULL;
+ return false;
+ }
+ ahiBuf[1] = &ahiBuf[0][AHI_BUF_SIZE];
+
+ ahiReq[0]->ahir_Version = 4;
+ if (ahiDevice = OpenDevice(AHINAME, 0, (IORequest *) ahiReq[0], 0))
+ {
+ FreeVec(ahiBuf[0]);
+ FreeVec(ahiReq[1]);
+ DeleteIORequest(ahiReq[0]);
+ DeleteMsgPort(ahiPort);
+ ahiBuf[0] = NULL;
+ ahiReq[0] = NULL;
+ ahiReq[1] = NULL;
+ ahiPort = NULL;
+ return false;
+ }
+
+ CopyMem(ahiReq[0], ahiReq[1], sizeof (AHIRequest));
+
+ ahiCurBuf = 0;
+ ahiReqSent[0] = FALSE;
+ ahiReqSent[1] = FALSE;
+
+ return true;
+}
+
+
+static void exit_morphos_sound()
+{
+ if (ahiReq[1])
+ FreeVec(ahiReq[1]);
+
+ if (ahiReq[0])
+ {
+ CloseDevice((IORequest *) ahiReq[0]);
+ DeleteIORequest(ahiReq[0]);
+ }
+
+ if (ahiBuf[0])
+ FreeVec((APTR) ahiBuf[0]);
+
+ if (ahiPort)
+ DeleteMsgPort(ahiPort);
+}
+
+int morphos_sound_thread(OSystem_MorphOS *syst, ULONG SampleType)
+{
+ ULONG signals;
+ bool initialized;
+
+ ObtainSemaphore(&ScummSoundThreadRunning);
+
+ initialized = init_morphos_sound();
+ if (!initialized)
+ {
+ warning("Sound could not be initialized. The game may hang at some point (press Ctrl-z then).");
+ Wait(SIGBREAKF_CTRL_C);
+ }
+ else
+ {
+ for (;;)
+ {
+ while (!ahiReqSent[ahiCurBuf] || CheckIO((IORequest *) ahiReq[ahiCurBuf]))
+ {
+ AHIRequest *req = ahiReq[ahiCurBuf];
+ UWORD ahiOtherBuf = !ahiCurBuf;
+
+ if (ahiReqSent[ahiCurBuf])
+ WaitIO((IORequest *) req);
+
+ syst->fill_sound((byte *) ahiBuf[ahiCurBuf], AHI_BUF_SIZE);
+
+ req->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
+ req->ahir_Std.io_Command = CMD_WRITE;
+ req->ahir_Std.io_Data = ahiBuf[ahiCurBuf];
+ req->ahir_Std.io_Length = AHI_BUF_SIZE;
+ req->ahir_Type = SampleType;
+ req->ahir_Frequency = SAMPLES_PER_SEC;
+ req->ahir_Position = 0x8000;
+ req->ahir_Volume = 0x10000;
+ req->ahir_Link = (ahiReqSent[ahiOtherBuf] && !CheckIO((IORequest *) ahiReq[ahiOtherBuf])) ? ahiReq[ahiOtherBuf] : NULL;
+ SendIO((IORequest *)req);
+
+ ahiReqSent[ahiCurBuf] = true;
+ ahiCurBuf = ahiOtherBuf;
+ }
+
+ signals = Wait(SIGBREAKF_CTRL_C | (1 << ahiPort->mp_SigBit));
+
+ if (signals & SIGBREAKF_CTRL_C)
+ break;
+ }
+
+ if (ahiReqSent[ahiCurBuf])
+ {
+ AbortIO((IORequest *) ahiReq[ahiCurBuf]);
+ WaitIO((IORequest *) ahiReq[ahiCurBuf]);
+ ahiReqSent[ahiCurBuf] = false;
+ }
+
+ if (ahiReqSent[!ahiCurBuf])
+ {
+ AbortIO((IORequest *) ahiReq[!ahiCurBuf]);
+ WaitIO((IORequest *) ahiReq[!ahiCurBuf]);
+ ahiReqSent[!ahiCurBuf] = false;
+ }
+ }
+
+ exit_morphos_sound();
+
+ ReleaseSemaphore(&ScummSoundThreadRunning);
+ RemTask(NULL);
+ return 0;
+}
+