mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-13 07:14:59 +00:00
476 lines
11 KiB
C++
476 lines
11 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This code is based on the original source code of Lord Avalot d'Argent version 1.3.
|
|
* Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
|
|
*/
|
|
|
|
/*$I c:\sleep5\DSMI.INC*/ #include "graph.h"
|
|
/*#include "Crt.h"*/
|
|
|
|
namespace Avalanche {
|
|
|
|
const varying_string<255> song =
|
|
string("Golden slumbers kiss your eyes/Smiles awake you when you rise/") +
|
|
"Sleep, pretty Baron, do not cry/And I will sing a lullaby.%Care you " +
|
|
"know not, therefore sleep/While I o'er you watch do keep;/Sleep now, " +
|
|
"du Lustie, do not cry/And I will leave the castle.*Bye!";
|
|
|
|
const integer scardcount = 13;
|
|
|
|
const array < 0, scardcount - 1, integer > soundcards =
|
|
{{1, 2, 6, 3, 4, 5, 8, 9, 10, 7, 7, 7, 7}};
|
|
|
|
const array<1, 5, byte> holding = {
|
|
{
|
|
24, /* 0 : 24 */
|
|
64, /* 1 : 00 */
|
|
128, /* 2 : 00 */
|
|
152, /* 2 : 24 */
|
|
170
|
|
}
|
|
}; /* 2 : 42 */
|
|
|
|
integer gd, gm;
|
|
byte fv;
|
|
word *skellern;
|
|
word s, o;
|
|
boolean firstverse;
|
|
word nexthangon;
|
|
|
|
boolean nomusic;
|
|
|
|
integer getsoundhardware(psoundcard scard) {
|
|
integer sc, i, autosel, select;
|
|
char ch;
|
|
integer e;
|
|
|
|
|
|
|
|
integer getsoundhardware_result;
|
|
Lagain:
|
|
sc = detectgus(scard);
|
|
if (sc != 0) sc = detectpas(scard);
|
|
if (sc != 0) sc = detectaria(scard);
|
|
if (sc != 0) sc = detectsb(scard);
|
|
|
|
/* if no sound card found, zero scard */
|
|
if (sc != 0) fillchar(scard, sizeof(tsoundcard), 0);
|
|
|
|
autosel = -1;
|
|
/* if sc=0 then
|
|
for i:=0 to scardcount-1 do
|
|
if scard^.ID=soundcards[i].ID then begin
|
|
{ Set auto selection mark }
|
|
autosel:=i+1;
|
|
break;
|
|
end;*/
|
|
|
|
/* Print the list of sound cards */
|
|
|
|
val(paramstr(13), select, e);
|
|
|
|
/* Default entry? */
|
|
if (select == 0) select = autosel;
|
|
if (select != autosel) {
|
|
/* clear all assumptions */
|
|
sc = -1;
|
|
fillchar(scard, sizeof(tsoundcard), 0);
|
|
scard->id = soundcards[select - 1]; /* set correct ID */
|
|
}
|
|
|
|
/* Query I/O address */
|
|
if (scard->id == id_dac) scard->ioport = 0x378;
|
|
|
|
/* Read user input */
|
|
val(paramstr(15), i, e);
|
|
|
|
if (i != 0) scard->ioport = i;
|
|
if (sc != 1) /* Not autodetected */
|
|
switch (scard->id) {
|
|
case id_sb16:
|
|
case id_pas16:
|
|
case id_wss:
|
|
case id_aria:
|
|
case id_gus :
|
|
scard->samplesize = 2;
|
|
break; /* 16-bit card */
|
|
case id_sbpro:
|
|
case id_pas:
|
|
case id_pasplus:
|
|
scard->stereo = true;
|
|
break; /* enable stereo */
|
|
default: {
|
|
scard->samplesize = 1;
|
|
scard->stereo = false;
|
|
}
|
|
}
|
|
|
|
if (scard->id != id_dac) {
|
|
val(paramstr(17), i, e);
|
|
|
|
if (i != 0) scard->dmairq = i;
|
|
|
|
val(paramstr(16), i, e);
|
|
|
|
if (i != 0) scard->dmachannel = i;
|
|
} else {
|
|
/* Select correct DAC */
|
|
scard->maxrate = 44100;
|
|
if (select == 11) {
|
|
scard->stereo = true;
|
|
scard->dmachannel = 1; /* Special 'mark' */
|
|
scard->maxrate = 60000;
|
|
} else if (select == 12) {
|
|
scard->stereo = true;
|
|
scard->dmachannel = 2;
|
|
scard->maxrate = 60000;
|
|
if (scard->ioport == 0) scard->ioport = 0x378;
|
|
} else if (select == 13) {
|
|
scard->dmachannel = 0;
|
|
scard->ioport = 0x42; /* Special 'mark' */
|
|
scard->maxrate = 44100;
|
|
}
|
|
}
|
|
|
|
/* writeln('Your selection: ',select,' at ',scard^.ioPort,
|
|
' using IRQ ',scard^.dmaIRQ,' and DMA channel ',scard^.dmaChannel);
|
|
readln;*/
|
|
|
|
getsoundhardware_result = 0;
|
|
return getsoundhardware_result;
|
|
}
|
|
|
|
byte here() {
|
|
byte here_result;
|
|
here_result = (ampgetpattern % 3) * 64 + ampgetrow;
|
|
return here_result;
|
|
}
|
|
|
|
void hold(word amount) {
|
|
*skellern = 0;
|
|
do {
|
|
} while (!(*skellern >= amount));
|
|
}
|
|
|
|
void hangon(word forwhat) {
|
|
if (nomusic)
|
|
hold(40);
|
|
else
|
|
do {
|
|
if (keypressed()) exit(0);
|
|
} while (!(here() >= holding[forwhat]));
|
|
}
|
|
|
|
tsoundcard scard;
|
|
tmcpstruct mcpstrc;
|
|
tdds dds;
|
|
pmodule module;
|
|
tsdi_init sdi;
|
|
integer e,
|
|
bufsize;
|
|
char ch;
|
|
boolean v86,
|
|
vdsok;
|
|
longint a, rate,
|
|
tempseg;
|
|
string answer;
|
|
pointer temp;
|
|
word flags;
|
|
word curch;
|
|
byte modulevolume;
|
|
array<0, 4, tsampleinfo> sample;
|
|
array<0, 31, word> voltable;
|
|
|
|
int main(int argc, const char *argv[]) {
|
|
pio_initialize(argc, argv);
|
|
for (e = 1; e <= paramcount; e ++) answer = paramstr(e);
|
|
|
|
nomusic = paramstr(13) == '0';
|
|
|
|
if (! nomusic) {
|
|
/* Read sound card information */
|
|
if (getsoundhardware(&scard) == -1) exit(1);
|
|
|
|
|
|
/* Initialize Timer Service */
|
|
tsinit;
|
|
atexit(&tsclose);
|
|
if (scard.id == id_gus) {
|
|
/* Initialize GUS player */
|
|
#ifndef DPMI
|
|
scard.extrafield[2] = 1; /* GUS DMA transfer does not work in V86 */
|
|
#endif
|
|
gusinit(&scard);
|
|
atexit(&gusclose);
|
|
|
|
/* Initialize GUS heap manager */
|
|
gushminit;
|
|
|
|
/* Init CDI */
|
|
cdiinit;
|
|
|
|
/* Register GUS into CDI */
|
|
cdiregister(&cdi_gus, 0, 31);
|
|
|
|
/* Add GUS event player engine into Timer Service */
|
|
tsaddroutine(&gusinterrupt, gus_timer);
|
|
} else {
|
|
/* Initialize Virtual DMA Specification */
|
|
#ifndef DPMI
|
|
vdsok = vdsinit == 0;
|
|
#else
|
|
vdsok = false;
|
|
#endif
|
|
|
|
fillchar(mcpstrc, sizeof(tmcpstruct), 0);
|
|
|
|
/* Query for sampling rate */
|
|
val(paramstr(14), a, e);
|
|
if (a > 4000) rate = a;
|
|
else rate = 21000;
|
|
|
|
/* Query for quality */
|
|
mcpstrc.options = mcp_quality;
|
|
|
|
switch (scard.id) {
|
|
case id_sb : {
|
|
sdi = sdi_sb;
|
|
scard.maxrate = 22000;
|
|
}
|
|
break;
|
|
case id_sbpro : {
|
|
sdi = sdi_sbpro;
|
|
scard.maxrate = 22000;
|
|
}
|
|
break;
|
|
case id_pas:
|
|
case id_pasplus:
|
|
case id_pas16 : {
|
|
sdi = sdi_pas;
|
|
scard.maxrate = 44100;
|
|
}
|
|
break;
|
|
case id_sb16 : {
|
|
sdi = sdi_sb16;
|
|
scard.maxrate = 44100;
|
|
}
|
|
break;
|
|
case id_aria : {
|
|
sdi = sdi_aria;
|
|
scard.maxrate = 44100;
|
|
}
|
|
break;
|
|
case id_wss : {
|
|
sdi = sdi_wss;
|
|
scard.maxrate = 48000;
|
|
}
|
|
break;
|
|
#ifndef DPMI
|
|
case id_dac :
|
|
sdi = sdi_dac;
|
|
break; /* Only available in real mode */
|
|
#endif
|
|
}
|
|
|
|
mcpinitsounddevice(sdi, &scard);
|
|
a = mcp_tablesize;
|
|
mcpstrc.reqsize = 0;
|
|
|
|
/* Calculate mixing buffer size */
|
|
bufsize = (longint)(2800 * (integer)(scard.samplesize) << (byte)(scard.stereo)) *
|
|
(longint)(rate) / (longint)(22000);
|
|
mcpstrc.reqsize = 0;
|
|
if ((mcpstrc.options & mcp_quality) > 0)
|
|
if (scard.samplesize == 1) a += mcp_qualitysize;
|
|
else
|
|
a = mcp_tablesize16 + mcp_qualitysize16;
|
|
if ((longint)(bufsize) + (longint)(a) > 65500) bufsize = longint(65500) - a;
|
|
|
|
#ifdef DPMI
|
|
dpmiversion((byte)(e), (byte)(e), (byte)(e), flags);
|
|
v86 = (flags & 2) == 0;
|
|
#endif
|
|
|
|
/* Allocate volume table + mixing buffer */
|
|
#ifdef DPMI
|
|
|
|
/* In the V86 mode, the buffer must be allocated below 1M */
|
|
if (v86) {
|
|
tempseg = 0;
|
|
dpmiallocdos((a + longint(bufsize)) / longint(16) + longint(1), flags, (word)(tempseg));
|
|
} else {
|
|
#endif
|
|
getmem(temp, a + longint(bufsize));
|
|
if (temp == nil) exit(2);
|
|
#ifdef DPMI
|
|
tempseg = seg(temp);
|
|
}
|
|
#else
|
|
tempseg = seg(temp) + ofs(temp) / 16 + 1;
|
|
#endif
|
|
mcpstrc.bufferseg = tempseg;
|
|
mcpstrc.bufferphysical = -1;
|
|
|
|
if (vdsok && (scard.id != id_dac)) {
|
|
dds.size = bufsize;
|
|
dds.segment = tempseg;
|
|
dds.offset = 0;
|
|
|
|
/* Lock DMA buffer if VDS present */
|
|
if (vdslockdma(&dds) == 0) mcpstrc.bufferphysical = dds.address;
|
|
}
|
|
if (mcpstrc.bufferphysical == -1)
|
|
#ifdef DPMI
|
|
mcpstrc.bufferphysical = dpmigetlinearaddr(tempseg);
|
|
#else
|
|
mcpstrc.bufferphysical = (longint)(tempseg) << 4;
|
|
#endif
|
|
|
|
mcpstrc.buffersize = bufsize;
|
|
mcpstrc.samplingrate = rate;
|
|
/* Initialize Multi Channel Player */
|
|
if (mcpinit(&mcpstrc) != 0) exit(3);
|
|
atexit(&mcpclose);
|
|
|
|
/* Initialize Channel Distributor */
|
|
cdiinit;
|
|
|
|
/* Register MCP into CDI*/
|
|
cdiregister(&cdi_mcp, 0, 31);
|
|
}
|
|
|
|
/* Try to initialize AMP */
|
|
if (ampinit(0) != 0) exit(3);
|
|
atexit(&close);
|
|
|
|
/* Hook AMP player routine into Timer Service */
|
|
tsaddroutine(&interrupt, amp_timer);
|
|
|
|
#ifndef DPMI
|
|
/* If using DAC, then adjust DAC timer */
|
|
if (scard.id == id_dac) setdactimer(tsgettimerrate);
|
|
#endif
|
|
|
|
if (scard.id != id_gus) mcpstartvoice;
|
|
else gusstartvoice;
|
|
|
|
/* Load an example AMF */
|
|
module = amploadmod("golden.mod", 0);
|
|
if (module == nil) exit(4);
|
|
|
|
/* Is it MCP, Quality mode and 16-bit card? */
|
|
if ((scard.id != id_gus) && ((mcpstrc.options & mcp_quality) > 0)
|
|
&& (scard.samplesize == 2)) {
|
|
/* Open module+2 channels with amplified volumetable (4.7 gain) */
|
|
for (a = 1; a <= 32; a ++) voltable[a - longint(1)] = a * longint(150) / longint(32);
|
|
cdisetupchannels(0, module->channelcount + 2, &voltable);
|
|
} else {
|
|
/* Open module+2 channels with regular volumetable */
|
|
cdisetupchannels(0, module->channelcount + 2, nil);
|
|
}
|
|
|
|
curch = module->channelcount;
|
|
modulevolume = 64;
|
|
|
|
/***/ ampplaymodule(module, 0);
|
|
}
|
|
|
|
val(paramstr(2), s, e);
|
|
if (e != 0) exit(0);
|
|
val(paramstr(3), o, e);
|
|
if (e != 0) exit(0);
|
|
skellern = ptr(s, o + 1);
|
|
|
|
gd = 3;
|
|
gm = 0;
|
|
initgraph(gd, gm, "");
|
|
|
|
if (! nomusic) do {
|
|
} while (!(ampgetrow >= 10));
|
|
|
|
setcolor(9);
|
|
for (gd = 0; gd <= 320; gd ++) {
|
|
rectangle(320 - gd, 100 - gd / 2, 320 + gd, 100 + gd / 2);
|
|
}
|
|
|
|
|
|
gd = 50;
|
|
gm = 20;
|
|
firstverse = true;
|
|
|
|
hangon(1);
|
|
nexthangon = 2;
|
|
for (fv = 1; fv <= 255; fv ++) {
|
|
switch (song[fv]) {
|
|
case '/': {
|
|
gd = 50;
|
|
gm += 15;
|
|
hangon(nexthangon);
|
|
nexthangon += 1;
|
|
}
|
|
break;
|
|
|
|
case '%': {
|
|
gd = 50;
|
|
gm += 35;
|
|
if (nomusic)
|
|
hold(15);
|
|
else
|
|
do {
|
|
} while (!(ampgetpattern > 2));
|
|
nexthangon = 2;
|
|
hangon(1);
|
|
}
|
|
break;
|
|
|
|
case '*': {
|
|
gd += 24;
|
|
hangon(5);
|
|
}
|
|
break;
|
|
|
|
default: {
|
|
setcolor(1);
|
|
outtextxy(gd + 1, gm + 1, song[fv]);
|
|
setcolor(0);
|
|
outtextxy(gd , gm , song[fv]);
|
|
gd += 12;
|
|
}
|
|
}
|
|
if (song[fv] == ' ') hold(1);
|
|
if (keypressed()) exit(0);
|
|
}
|
|
|
|
if (nomusic)
|
|
hold(25);
|
|
else
|
|
do {
|
|
} while (!(ampgetmodulestatus != md_playing));
|
|
|
|
setcolor(0);
|
|
for (gd = 320; gd >= 0; gd --) rectangle(320 - gd, 100 - gd / 2, 320 + gd, 100 + gd / 2);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
} // End of namespace Avalanche.
|