This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/gall/gsnd.cpp
2005-10-25 06:11:09 +00:00

498 lines
9.1 KiB
C++

// This may look like C code, but it is really -*- C++ -*-
// ------------------------------------------------------------------
// The Goldware Library
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library 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
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// Sound class.
// ------------------------------------------------------------------
#include <cstdio>
#include <cstdlib>
#include <gutlos.h>
#if defined(__MSDOS__)
#include <gmemi86.h>
#include <gmemdbg.h>
#endif
#include <gstrall.h>
#include <gasmamis.h>
#include <gsndall.h>
#include <gfilutil.h>
// ------------------------------------------------------------------
#ifdef DEBUG
int debug = false;
#endif
// ------------------------------------------------------------------
gsnd::gsnd() {
#if defined(__MSDOS__)
mpx = -1;
#if (defined(__WATCOMC__) && defined(__386__)) || defined(__DJGPP__)
buffer = -1;
#else
buffer = NULL;
#endif
data = NULL;
#endif
api_open = false;
file_open = false;
}
// ------------------------------------------------------------------
gsnd::~gsnd() {
if(api_open)
close_api();
free_buffer();
}
// ------------------------------------------------------------------
#if defined(__MSDOS__)
int gsnd::call_api(uint al, uint bx) {
if(api_open) {
i86 cpu;
cpu.al(al);
cpu.ah(mpx);
cpu.bx(bx);
cpu.genint(0x2D);
return (int)cpu.ax();
}
return 0;
}
#endif
// ------------------------------------------------------------------
void gsnd::free_buffer() {
#if defined(__MSDOS__)
#if defined(__DJGPP__) || (defined(__WATCOMC__) && defined(__386__))
if(buffer != -1) {
__dpmi_free_dos_memory(buffer);
buffer = -1;
}
#else
if(buffer) {
farfree(buffer);
buffer = NULL;
}
#endif
#endif
}
// ------------------------------------------------------------------
int gsnd::open_api() {
#if defined(__MSDOS__)
i86 cpu;
// Installation check
for(mpx=0; mpx<256; mpx++) {
cpu.ah(mpx);
cpu.al(GSAPI_INSTALL_CHECK);
cpu.genint(0x2D);
if(cpu.al() == 0xFF) {
#ifdef DEBUG
if(debug) printf("gsnd: examining signature at %04X:%04X for mpx %u\n", cpu.dx(), cpu.di(), mpx);
#endif
amis_signature* signature = (amis_signature*)gmkfp(cpu.dx(), cpu.di());
#ifdef DEBUG
if(debug) printf("gsnd: version is %04X\n", cpu.cx());
if(debug) printf("gsnd: manufacturer is \"%8.8s\"\n", signature->manufacturer);
if(debug) printf("gsnd: product name is \"%8.8s\"\n", signature->product_name);
if(debug) printf("gsnd: description is \"%s\"\n", signature->product_description);
#endif
if((cpu.cx() >= 0x0100) and (cpu.cx() < 0x0200))
if(strnieql(signature->product_name, "GoldSAPI", 8))
break;
}
}
// Return if not installed
if(mpx >= 256) {
mpx = -1;
return -1;
}
// Call the open api function
cpu.al(GSAPI_OPEN_API);
cpu.ah(mpx);
cpu.genint(0x2D);
if(cpu.al()) {
#ifdef DEBUG
if(debug) printf("gsnd: open api returned %02Xh\n", cpu.al());
#endif
return cpu.al();
}
#ifdef DEBUG
if(debug) printf("gsnd: using data at %04X:%04X, length %u\n", cpu.dx(), cpu.di(), cpu.cx());
#endif
data = (gsapidata*)gmkfp(cpu.dx(), cpu.di());
key_value = cpu.bx();
api_open = true;
return 0;
#elif defined(GUTLOS_FUNCS)
api_open = true;
return 0;
#else
api_open = false;
return -1;
#endif
}
// ------------------------------------------------------------------
int gsnd::close_api() {
#if defined(__MSDOS__)
return call_api(GSAPI_CLOSE_API, key_value);
#elif defined(GUTLOS_FUNCS)
if(api_open) {
if(file_open)
close();
api_open = false;
}
return 0;
#else
return -1;
#endif
}
// ------------------------------------------------------------------
int gsnd::open(const char* file) {
#if defined(__MSDOS__)
strcpy(data->parameters, file);
try_again:
int retval = call_api(GSAPI_OPEN_AND_LOAD_FILE);
switch(retval) {
case 0x01:
close();
goto try_again;
case 0x02:
free_buffer();
#if defined(__DJGPP__) || (defined(__WATCOMC__) && defined(__386__))
int seg = __dpmi_allocate_dos_memory((data->buffer_length >> 4) + 1, &buffer);
if(seg == -1)
return -1;
data->buffer_segment = seg & 0xffff;
data->buffer_offset = 0;
#else
buffer = (char*)farmalloc(data->buffer_length);
if(buffer == NULL)
return false;
data->buffer_segment = FP_SEG(buffer);
data->buffer_offset = FP_OFF(buffer);
#endif
retval = call_api(GSAPI_OPEN_AND_LOAD_FILE);
}
if(retval == 0)
file_open = true;
#ifdef DEBUG
if(debug) printf("gsnd::open: retval = %04X\n", retval);
#endif
return retval;
#elif defined(GUTLOS_FUNCS)
if(file_open)
close();
char buf[GMAXPATH+sizeof("open alias noise wait")];
sprintf(buf, "open %s alias noise wait", file);
if(g_send_mci_string(buf, NULL)) {
file_open = true;
return 0;
}
return -1;
#else
NW(file);
return -1;
#endif
}
// ------------------------------------------------------------------
int gsnd::close() {
#if defined(__MSDOS__)
if(file_open) {
file_open = false;
return call_api(GSAPI_CLOSE_FILE);
}
return 1;
#elif defined(GUTLOS_FUNCS)
if(file_open) {
g_send_mci_string("close noise wait", NULL);
file_open = false;
return 0;
}
return 0xFFFF;
#else
return 0xFFFF;
#endif
}
// ------------------------------------------------------------------
int gsnd::play(uint sample_rate) {
#if defined(__MSDOS__)
return file_open ? call_api(GSAPI_PLAY, sample_rate) : 1;
#elif defined(GUTLOS_FUNCS)
NW(sample_rate);
if(file_open) {
g_send_mci_string("seek noise to start", NULL);
g_send_mci_string("play noise", NULL);
return 0;
}
return 1;
#else
NW(sample_rate);
return 1;
#endif
}
// ------------------------------------------------------------------
int gsnd::stop() {
#if defined(__MSDOS__)
return file_open ? call_api(GSAPI_STOP) : 1;
#elif defined(GUTLOS_FUNCS)
if(file_open) {
g_send_mci_string("stop noise wait", NULL);
return 0;
}
return 1;
#else
return 1;
#endif
}
// ------------------------------------------------------------------
int gsnd::pause() {
#if defined(__MSDOS__)
return file_open ? call_api(GSAPI_PAUSE) : 1;
#elif defined(GUTLOS_FUNCS)
if(file_open) {
g_send_mci_string("pause noise", NULL);
return 0;
}
return 1;
#else
return 1;
#endif
}
// ------------------------------------------------------------------
int gsnd::resume() {
#if defined(__MSDOS__)
return file_open ? call_api(GSAPI_RESUME) : 1;
#elif defined(GUTLOS_FUNCS)
if(file_open) {
g_send_mci_string("resume noise", NULL);
return 0;
}
return 1;
#else
return 1;
#endif
}
// ------------------------------------------------------------------
int gsnd::break_loop(int method) {
#if defined(__MSDOS__)
return file_open ? call_api(GSAPI_BREAK_LOOP, method) : 1;
#elif defined(GUTLOS_FUNCS)
NW(method);
return 0xFFFF;
#else
NW(method);
return 0xFFFF;
#endif
}
// ------------------------------------------------------------------
void gsnd::speaker(int onoff) {
#if defined(__MSDOS__)
call_api(GSAPI_SPEAKER_ON_OFF, onoff ? 1 : 0);
#elif defined(GUTLOS_FUNCS)
// Not implemented
NW(onoff);
#else
NW(onoff);
#endif
}
// ------------------------------------------------------------------
uint gsnd::get_sample_rate() {
#if defined(__MSDOS__)
return file_open ? data->sample_rate : 0;
#elif defined(GUTLOS_FUNCS)
return 0;
#else
return 0;
#endif
}
// ------------------------------------------------------------------
int gsnd::is_playing() {
#if defined(__MSDOS__)
if(file_open)
return make_bool_not(data->status == 0);
return false;
#elif defined(GUTLOS_FUNCS)
char return_buffer[BUFFERSIZE];
if(g_send_mci_string("status noise mode wait", return_buffer))
return strieql(return_buffer, "playing") or strieql(return_buffer, "seeking");
return 0;
#else
return 0;
#endif
}
// ------------------------------------------------------------------