Initial commit. I made it compile on modern systems I think.

There may be some timidity fixes too, but those could have been done
to my rott fork too. I don't remember sorry.
This commit is contained in:
Marco Cawthorne 2022-02-14 00:13:05 -08:00
commit 8f7196e3e8
Signed by: eukara
GPG Key ID: C196CD8BA993248A
227 changed files with 154298 additions and 0 deletions

202
Makefile Executable file
View File

@ -0,0 +1,202 @@
#-----------------------------------------------------------------------------#
# Duke3D makefile.
#-----------------------------------------------------------------------------#
linux_ppc := false
beos := false
macosx := false
freebsd := false
solaris := false
shareware := false
controls_menu := true
#use_asm := true
#-----------------------------------------------------------------------------#
# If this makefile fails to detect Cygwin correctly, or you want to force
# the build process's behaviour, set it to "true" or "false" (w/o quotes).
#-----------------------------------------------------------------------------#
#cygwin := true
#cygwin := false
cygwin := autodetect
# you only need to set these for Cygwin at the moment.
SDL_INC_DIR = /cygdrive/c/SDL/include
SDL_LIB_DIR = /cygdrive/c/SDL/lib
CC = gcc
# need this for now.
ifeq ($(strip $(beos)),true)
use_asm := false
endif
# Don't touch anything below this line unless you know what you're doing.
ifeq ($(strip $(cygwin)),autodetect)
ifneq ($(strip $(shell gcc -v 2>&1 |grep "cygwin")),)
cygwin := true
else
cygwin := false
endif
endif
ifeq ($(strip $(cygwin)),true)
ifeq ($(strip $(SDL_INC_DIR)),please_set_me_cygwin_users)
$(error Cygwin users need to set the SDL_INC_DIR envr var.)
else
SDL_CFLAGS := -I$(SDL_INC_DIR)
endif
ifeq ($(strip $(SDL_LIB_DIR)),please_set_me_cygwin_users)
$(error Cygwin users need to set the SDL_LIB_DIR envr var.)
else
SDL_LDFLAGS := -L$(SDL_LIB_DIR) -lSDL
endif
else
ifneq ($(strip $(freebsd)),true)
SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs) -L.
endif
endif
ifeq ($(strip $(macosx)),true)
EXTRACFLAGS += -DPLATFORM_MACOSX=1
EXTRALDFLAGS += -lSDLmain
endif
ifeq ($(strip $(freebsd)),true)
EXTRACFLAGS += -DPLATFORM_FREEBSD=1
SDL_CFLAGS := $(shell sdl11-config --cflags)
SDL_LDFLAGS := $(shell sdl11-config --libs) -L.
endif
ifeq ($(strip $(linux_ppc)),true)
EXTRACFLAGS += -DPLATFORM_LINUXPPC=1
endif
ifneq ($(strip $(cygwin)),true)
ifneq ($(strip $(macosx)),true)
ifneq ($(strip $(beos)),true)
EXTRACFLAGS += -DUSE_EXECINFO=1
endif
endif
endif
ifeq ($(strip $(solaris)),true)
CC = cc
EXTRALDFLAGS += -lsocket -lnsl
CFLAGS += -DPLATFORM_SOLARIS
endif
ifeq ($(strip $(shareware)),true)
EXTRACFLAGS += -DVOLUMEONE
else
EXTRACFLAGS += -DVOLUMEALL
endif
ifeq ($(strip $(controls_menu)),true)
EXTRACFLAGS += -DCONTROLS_CONFIG_MENU=1
endif
BUILDOBJS := \
buildengine/cache1d.o \
buildengine/engine.o \
buildengine/sdl_driver.o \
buildengine/mmulti.o \
buildengine/pragmas.o \
buildengine/unix_compat.o
ifeq ($(strip $(use_asm)),true)
BUILDOBJS += buildengine/a_gnu.o buildengine/a_nasm.o
else
BUILDOBJS += buildengine/a.o
endif
CFLAGS=-m32 -c -g $(SDL_CFLAGS) -DUSE_SDL=1 -DPLATFORM_UNIX=1 $(EXTRACFLAGS)
ifeq ($(strip $(solaris)),true)
CFLAGS += -xO5 -xchar=u
else
# Always turn OFF strict aliasing, even when optimizing. Otherwise, this
# is just an accident waiting to happen... --ryan.
CFLAGS += -fno-strict-aliasing
CFLAGS += -W -Wall -Wno-unused -funsigned-char
ifeq ($(strip $(macosx)),true)
OPTIMIZE = -O3 -mdynamic-no-pic -falign-loops=16
else
OPTIMIZE = -O2
endif
endif
# Uncomment this to compile with the Intel compiler (v6.0)
#CC = icc
#CFLAGS = -g $(SDL_CFLAGS) -DUSE_SDL=1 -DPLATFORM_UNIX=1 -DUSE_I386_ASM=1 $(EXTRACFLAGS) -O2
LDLIBS = -lSDL -lSDL_mixer $(EXTRALDFLAGS)
ifeq ($(strip $(freebsd)),true)
LDLIBS = -lSDL_mixer $(EXTRALDFLAGS)
endif
# !!! FIXME: Do we even need this? It doesn't fly on MacOS X. --ryan.
#LDLIBS += -Wl,-E
.PHONY: duke3d build buildengine clean distclean
all: buildengine duke3d build
%.o : %.c
$(CC) $(CFLAGS) $(OPTIMIZE) -o $@ $<
# Animation playback crashes due to optimization error on MacOS X. --ryan.
ifeq ($(strip $(macosx)),true)
animlib.o : animlib.c
$(CC) $(CFLAGS) -o $@ $<
endif
# Animation playback crashes due to optimization error on Linux PPC. --Felipe Barriga.
ifeq ($(strip $(linux_ppc)),true)
animlib.o : animlib.c
$(CC) $(CFLAGS) -o $@ $<
endif
audiolib/audiolib.a:
$(MAKE) -C audiolib CC="$(CC)" CFLAGS="$(CFLAGS)" LDLIBS="$(LDLIBS)"
buildengine:
make -C buildengine
duke3d: \
actors.o \
animlib.o \
control.o \
config.o \
game.o \
gamedef.o \
global.o \
keyboard.o \
menues.o \
player.o \
premap.o \
rts.o \
scriplib.o \
sector.o \
sounds.o \
dukemusc.o \
audiolib/audiolib.a
$(CC) -m32 $^ $(BUILDOBJS) $(LDLIBS) -o $@
build: astub.o
$(CC) -m32 $^ $(BUILDOBJS) buildengine/build.o $(LDLIBS) -o $@
clean:
$(MAKE) -C audiolib clean
$(MAKE) -C buildengine clean
rm -rf duke3d build *.o
distclean: clean
$(MAKE) -C audiolib distclean
$(MAKE) -C buildengine distclean
rm -rf *~

42
_animlib.h Executable file
View File

@ -0,0 +1,42 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// ANIMLIB.H
//
/////////////////////////////////////////////////////////////////////////////
#ifndef _animlib_private_
#define _animlib_private_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
};
#endif
#endif

247
_functio.h Executable file
View File

@ -0,0 +1,247 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
// _functio.h
// file created by makehead.exe
// these headers contain default key assignments, as well as
// default button assignments and game function names
// axis defaults are also included
#ifndef _function_private_
#define _function_private_
#ifdef __cplusplus
extern "C" {
#endif
char * gamefunctions[] =
{
"Move_Forward",
"Move_Backward",
"Turn_Left",
"Turn_Right",
"Strafe",
"Fire",
"Open",
"Run",
"AutoRun",
"Jump",
"Crouch",
"Look_Up",
"Look_Down",
"Look_Left",
"Look_Right",
"Strafe_Left",
"Strafe_Right",
"Aim_Up",
"Aim_Down",
"Weapon_1",
"Weapon_2",
"Weapon_3",
"Weapon_4",
"Weapon_5",
"Weapon_6",
"Weapon_7",
"Weapon_8",
"Weapon_9",
"Weapon_10",
"Inventory",
"Inventory_Left",
"Inventory_Right",
"Holo_Duke",
"Jetpack",
"NightVision",
"MedKit",
"TurnAround",
"SendMessage",
"Map",
"Shrink_Screen",
"Enlarge_Screen",
"Center_View",
"Holster_Weapon",
"Show_Opponents_Weapon",
"Map_Follow_Mode",
"See_Coop_View",
"Mouse_Aiming",
"Toggle_Crosshair",
"Steroids",
"Quick_Kick",
"Next_Weapon",
"Previous_Weapon",
};
#ifdef __SETUP__
#define NUMKEYENTRIES 52
static char * keydefaults[] =
{
"Move_Forward", "Up", "Kpad8",
"Move_Backward", "Down", "Kpad2",
"Turn_Left", "Left", "Kpad4",
"Turn_Right", "Right", "KPad6",
"Strafe", "LAlt", "RAlt",
"Fire", "LCtrl", "RCtrl",
"Open", "Space", "",
"Run", "LShift", "RShift",
"AutoRun", "CapLck", "",
"Jump", "A", "/",
"Crouch", "Z", "",
"Look_Up", "PgUp", "Kpad9",
"Look_Down", "PgDn", "Kpad3",
"Look_Left", "Insert", "Kpad0",
"Look_Right", "Delete", "Kpad.",
"Strafe_Left", ",", "",
"Strafe_Right", ".", "",
"Aim_Up", "Home", "KPad7",
"Aim_Down", "End", "Kpad1",
"Weapon_1", "1", "",
"Weapon_2", "2", "",
"Weapon_3", "3", "",
"Weapon_4", "4", "",
"Weapon_5", "5", "",
"Weapon_6", "6", "",
"Weapon_7", "7", "",
"Weapon_8", "8", "",
"Weapon_9", "9", "",
"Weapon_10", "0", "",
"Inventory", "Enter", "KpdEnt",
"Inventory_Left", "[", "",
"Inventory_Right", "]", "",
"Holo_Duke", "H", "",
"Jetpack", "J", "",
"NightVision", "N", "",
"MedKit", "M", "",
"TurnAround", "BakSpc", "",
"SendMessage", "T", "",
"Map", "Tab", "",
"Shrink_Screen", "-", "Kpad-",
"Enlarge_Screen", "=", "Kpad+",
"Center_View", "KPad5", "",
"Holster_Weapon", "ScrLck", "",
"Show_Opponents_Weapon", "W", "",
"Map_Follow_Mode", "F", "",
"See_Coop_View", "K", "",
"Mouse_Aiming", "U", "",
"Toggle_Crosshair", "I", "",
"Steroids", "R", "",
"Quick_Kick", "`", "",
"Next_Weapon", "'", "",
"Previous_Weapon", ";", "",
};
static char * mousedefaults[] =
{
"Fire",
"Strafe",
"Move_Forward",
};
static char * mouseclickeddefaults[] =
{
"",
"Open",
"",
};
static char * joystickdefaults[] =
{
"Fire",
"Strafe",
"Run",
"Open",
"Aim_Down",
"Look_Right",
"Aim_Up",
"Look_Left",
};
static char * joystickclickeddefaults[] =
{
"",
"Inventory",
"Jump",
"Crouch",
"",
"",
"",
"",
};
static char * mouseanalogdefaults[] =
{
"analog_turning",
"analog_moving",
};
static char * mousedigitaldefaults[] =
{
"",
"",
"",
"",
};
static char * gamepaddigitaldefaults[] =
{
"Turn_Left",
"Turn_Right",
"Move_Forward",
"Move_Backward",
};
static char * joystickanalogdefaults[] =
{
"analog_turning",
"analog_moving",
"analog_strafing",
"",
};
static char * joystickdigitaldefaults[] =
{
"",
"",
"",
"",
"",
"",
"Run",
"",
};
#endif
#ifdef __cplusplus
};
#endif
#endif

54
_rts.h Executable file
View File

@ -0,0 +1,54 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#ifndef __rts_private__
#define __rts_private__
//===============
// TYPES
//===============
typedef struct
{
char name[8];
int32 handle,position,size;
} lumpinfo_t;
typedef struct
{
char identification[4]; // should be IWAD
int32 numlumps;
int32 infotableofs;
} wadinfo_t;
typedef struct
{
int32 filepos;
int32 size;
char name[8];
} filelump_t;
#endif

7138
actors.c Executable file

File diff suppressed because it is too large Load Diff

384
animlib.c Executable file
View File

@ -0,0 +1,384 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "duke3d.h"
#include "types.h"
#include "develop.h"
#include "util_lib.h"
#include "_animlib.h"
#include "animlib.h"
//****************************************************************************
//
// GLOBALS
//
//****************************************************************************
//****************************************************************************
//
// LOCALS
//
//****************************************************************************
anim_t * anim=NULL;
static boolean Anim_Started = false;
//****************************************************************************
//
// CheckAnimStarted ()
//
//****************************************************************************
void CheckAnimStarted ( char * funcname )
{
if (!Anim_Started)
Error("ANIMLIB_%s: Anim has not been initialized\n",funcname);
}
//****************************************************************************
//
// findpage ()
// - given a frame number return the large page number it resides in
//
//****************************************************************************
uint16 findpage (uint16 framenumber)
{
uint16 i;
CheckAnimStarted ( "findpage" );
for(i=0; i<anim->lpheader.nLps; i++)
{
if
(
anim->LpArray[i].baseRecord <= framenumber &&
anim->LpArray[i].baseRecord + anim->LpArray[i].nRecords > framenumber
)
return(i);
}
return(i);
}
//****************************************************************************
//
// loadpage ()
// - seek out and load in the large page specified
//
//****************************************************************************
void loadpage (uint16 pagenumber, uint16 *pagepointer)
{
int32 size;
byte * buffer;
CheckAnimStarted ( "loadpage" );
buffer = anim->buffer;
if (anim->curlpnum != pagenumber)
{
anim->curlpnum = pagenumber;
buffer += 0xb00 + (pagenumber*0x10000);
size = sizeof(lp_descriptor);
memcpy(&anim->curlp,buffer,size);
#if PLATFORM_BIGENDIAN
anim->curlp.baseRecord = BUILDSWAP_INTEL16(anim->curlp.baseRecord);
anim->curlp.nRecords = BUILDSWAP_INTEL16(anim->curlp.nRecords);
anim->curlp.nBytes = BUILDSWAP_INTEL16(anim->curlp.nBytes);
#endif
buffer += size + sizeof(uint16);
// most of pagepointer is 8-bit data, the 16-bit stuff is byteswapped
// on the fly in renderframe() and CPlayRunSkipDump(), below. --ryan.
memcpy(pagepointer,buffer,anim->curlp.nBytes+(anim->curlp.nRecords*2));
}
}
//****************************************************************************
//
// CPlayRunSkipDump ()
// - This version of the decompressor is here for portability to non PC's
//
//****************************************************************************
void CPlayRunSkipDump (char *srcP, char *dstP)
{
signed char cnt;
uint16 wordCnt;
byte pixel;
nextOp:
cnt = (signed char) *srcP++;
if (cnt > 0)
goto dump;
if (cnt == 0)
goto run;
cnt -= 0x80;
if (cnt == 0)
goto longOp;
/* shortSkip */
dstP += cnt; /* adding 7-bit count to 32-bit pointer */
goto nextOp;
dump:
do
{
*dstP++ = *srcP++;
} while (--cnt);
goto nextOp;
run:
wordCnt = (byte)*srcP++; /* 8-bit unsigned count */
pixel = *srcP++;
do
{
*dstP++ = pixel;
} while (--wordCnt);
goto nextOp;
longOp:
wordCnt = *((uint16 *)srcP);
#if PLATFORM_BIGENDIAN
wordCnt = BUILDSWAP_INTEL16(wordCnt);
#endif
srcP += sizeof(uint16);
if ((int16)wordCnt <= 0)
goto notLongSkip; /* Do SIGNED test. */
/* longSkip. */
dstP += wordCnt;
goto nextOp;
notLongSkip:
if (wordCnt == 0)
goto stop;
wordCnt -= 0x8000; /* Remove sign bit. */
if (wordCnt >= 0x4000)
goto longRun;
/* longDump. */
do
{
*dstP++ = *srcP++;
} while (--wordCnt);
goto nextOp;
longRun:
wordCnt -= 0x4000; /* Clear "longRun" bit. */
pixel = *srcP++;
do
{
*dstP++ = pixel;
} while (--wordCnt);
goto nextOp;
stop: /* all done */
;
}
//****************************************************************************
//
// renderframe ()
// - draw the frame sepcified from the large page in the buffer pointed to
//
//****************************************************************************
void renderframe (uint16 framenumber, uint16 *pagepointer)
{
uint16 offset=0;
uint16 i;
uint16 destframe;
uint16 pp1;
byte *ppointer;
CheckAnimStarted ( "renderframe" );
destframe = framenumber - anim->curlp.baseRecord;
for(i = 0; i < destframe; i++)
{
offset += BUILDSWAP_INTEL16(pagepointer[i]);
}
ppointer = (byte *)pagepointer;
ppointer+=anim->curlp.nRecords*2+offset;
if(ppointer[1])
{
uint16 pp1 = BUILDSWAP_INTEL16(((uint16 *)ppointer)[1]);
ppointer += (4 + (pp1 + (pp1 & 1)));
}
else
{
ppointer+=4;
}
CPlayRunSkipDump (ppointer, anim->imagebuffer);
}
//****************************************************************************
//
// drawframe ()
// - high level frame draw routine
//
//****************************************************************************
void drawframe (uint16 framenumber)
{
CheckAnimStarted ( "drawframe" );
loadpage(findpage(framenumber), anim->thepage);
renderframe(framenumber, anim->thepage);
}
//****************************************************************************
//
// ANIM_LoadAnim ()
//
//****************************************************************************
void ANIM_LoadAnim (char * buffer)
{
uint16 i;
int32 size;
assert(sizeof(lp_descriptor) == 6);
assert(sizeof(lpfileheader) == 128);
assert(sizeof(anim->LpArray) == 1536);
if (!Anim_Started) Anim_Started = true;
anim->buffer = buffer;
anim->curlpnum = 0xffff;
anim->currentframe = -1;
size = sizeof(lpfileheader);
memcpy(&anim->lpheader, buffer, size );
#if PLATFORM_BIGENDIAN
anim->lpheader.id = BUILDSWAP_INTEL32(anim->lpheader.id);
anim->lpheader.maxLps = BUILDSWAP_INTEL16(anim->lpheader.maxLps);
anim->lpheader.nLps = BUILDSWAP_INTEL16(anim->lpheader.nLps);
anim->lpheader.nRecords = BUILDSWAP_INTEL32(anim->lpheader.nRecords);
anim->lpheader.maxRecsPerLp = BUILDSWAP_INTEL16(anim->lpheader.maxRecsPerLp);
anim->lpheader.lpfTableOffset = BUILDSWAP_INTEL16(anim->lpheader.lpfTableOffset);
anim->lpheader.contentType = BUILDSWAP_INTEL32(anim->lpheader.contentType);
anim->lpheader.width = BUILDSWAP_INTEL16(anim->lpheader.width);
anim->lpheader.height = BUILDSWAP_INTEL16(anim->lpheader.height);
anim->lpheader.nFrames = BUILDSWAP_INTEL32(anim->lpheader.nFrames);
anim->lpheader.framesPerSecond = BUILDSWAP_INTEL16(anim->lpheader.framesPerSecond);
//uint16 pad2[29]; // 58 bytes of filler to round up to 128 bytes total.
#endif
buffer += size+128;
// load the color palette
for (i = 0; i < 768; i += 3)
{
anim->pal[i+2] = *buffer++;
anim->pal[i+1] = *buffer++;
anim->pal[i] = *buffer++;
buffer++;
}
// read in large page descriptors
size = sizeof(anim->LpArray);
memcpy(&anim->LpArray,buffer,size);
#if PLATFORM_BIGENDIAN
for (i = 0; i < sizeof (anim->LpArray) / sizeof (anim->LpArray[0]); i++)
{
lp_descriptor *d = &anim->LpArray[i];
d->baseRecord = BUILDSWAP_INTEL16(d->baseRecord);
d->nRecords = BUILDSWAP_INTEL16(d->nRecords);
d->nBytes = BUILDSWAP_INTEL16(d->nBytes);
}
#endif
}
//****************************************************************************
//
// ANIM_FreeAnim ()
//
//****************************************************************************
void ANIM_FreeAnim ( void )
{
if (Anim_Started)
{
// SafeFree(anim);
Anim_Started = false;
}
}
//****************************************************************************
//
// ANIM_NumFrames ()
//
//****************************************************************************
int32 ANIM_NumFrames ( void )
{
CheckAnimStarted ( "NumFrames" );
return anim->lpheader.nRecords;
}
//****************************************************************************
//
// ANIM_DrawFrame ()
//
//****************************************************************************
byte * ANIM_DrawFrame (int32 framenumber)
{
int32 cnt;
CheckAnimStarted ( "DrawFrame" );
if ((anim->currentframe != -1) && (anim->currentframe<=framenumber))
{
for (cnt = anim->currentframe; cnt < framenumber; cnt++)
drawframe (cnt);
}
else
{
for (cnt = 0; cnt < framenumber; cnt++)
drawframe (cnt);
}
anim->currentframe = framenumber;
return anim->imagebuffer;
}
//****************************************************************************
//
// ANIM_GetPalette ()
//
//****************************************************************************
byte * ANIM_GetPalette ( void )
{
CheckAnimStarted ( "GetPalette" );
return anim->pal;
}

155
animlib.h Executable file
View File

@ -0,0 +1,155 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//
// ANIMLIB.H
//
/////////////////////////////////////////////////////////////////////////////
#ifndef _animlib_public_
#define _animlib_public_
#ifdef __cplusplus
extern "C" {
#endif
// structure declarations for deluxe animate large page files */
typedef struct
{
uint32 id; // 4 character ID == "LPF " */
uint16 maxLps; // max # largePages allowed. 256 FOR NOW. */
uint16 nLps; // # largePages in this file. */
uint32 nRecords; // # records in this file. 65534 is current limit plus */
// one for last-to-first delta for looping the animation */
uint16 maxRecsPerLp; // # records permitted in an lp. 256 FOR NOW. */
uint16 lpfTableOffset; // Absolute Seek position of lpfTable. 1280 FOR NOW.
// The lpf Table is an array of 256 large page structures
// that is used to facilitate finding records in an anim
// file without having to seek through all of the Large
// Pages to find which one a specific record lives in. */
uint32 contentType; // 4 character ID == "ANIM" */
uint16 width; // Width of screen in pixels. */
uint16 height; // Height of screen in pixels. */
byte variant; // 0==ANIM. */
byte version; // 0==frame rate is multiple of 18 cycles/sec.
// 1==frame rate is multiple of 70 cycles/sec. */
byte hasLastDelta; // 1==Last record is a delta from last-to-first frame. */
byte lastDeltaValid; // 0==The last-to-first delta (if present) hasn't been
// updated to match the current first&last frames, so it
// should be ignored. */
byte pixelType; // /* 0==256 color. */
byte CompressionType;// /* 1==(RunSkipDump) Only one used FOR NOW. */
byte otherRecsPerFrm;// /* 0 FOR NOW. */
byte bitmaptype; // /* 1==320x200, 256-color. Only one implemented so far. */
byte recordTypes[32];// /* Not yet implemented. */
uint32 nFrames; // /* In case future version adds other records at end of
// file, we still know how many actual frames.
// NOTE: DOES include last-to-first delta when present. */
uint16 framesPerSecond; // Number of frames to play per second. */
uint16 pad2[29]; // 58 bytes of filler to round up to 128 bytes total. */
} lpfileheader;
// this is the format of a large page structure
typedef struct
{
uint16 baseRecord; // Number of first record in this large page.
uint16 nRecords; // Number of records in lp.
// bit 15 of "nRecords" == "has continuation from previous lp".
// bit 14 of "nRecords" == "final record continues on next lp".
uint16 nBytes; // Total number of bytes of contents, excluding header.
} lp_descriptor;
typedef struct
{
uint16 framecount; // current frame of anim
lpfileheader lpheader; // file header will be loaded into this structure
lp_descriptor LpArray[256]; // arrays of large page structs used to find frames
uint16 curlpnum; // initialize to an invalid Large page number
lp_descriptor curlp; // header of large page currently in memory
uint16 thepage[0x8000]; // buffer where current large page is loaded
byte imagebuffer[0x10000]; // buffer where anim frame is decoded
byte * buffer;
byte pal[768];
int32 currentframe;
} anim_t;
//****************************************************************************
//
// ANIM_LoadAnim ()
//
// Setup internal anim data structure
//
//****************************************************************************
void ANIM_LoadAnim (char * buffer);
//****************************************************************************
//
// ANIM_FreeAnim ()
//
// Free up internal anim data structure
//
//****************************************************************************
void ANIM_FreeAnim ( void );
//****************************************************************************
//
// ANIM_NumFrames ()
//
// returns the number of frames in the current anim
//
//****************************************************************************
int32 ANIM_NumFrames ( void );
//****************************************************************************
//
// ANIM_DrawFrame ()
//
// Draw the frame to a returned buffer
//
//****************************************************************************
byte * ANIM_DrawFrame (int32 framenumber);
//****************************************************************************
//
// ANIM_GetPalette ()
//
// return the palette of the anim
//****************************************************************************
byte * ANIM_GetPalette ( void );
extern anim_t * anim;
#ifdef __cplusplus
};
#endif
#endif

2365
astub.c Executable file

File diff suppressed because it is too large Load Diff

24
audiolib/Makefile Executable file
View File

@ -0,0 +1,24 @@
CC=gcc
AR=ar
RANLIB=ranlib
CFLAGS=-m32 -g -O2
LDLIBS=
CFLAGS += $(shell /usr/bin/32/sdl-config --cflags)
LDLIBS += $(shell /usr/bin/32/sdl-config --libs)
OBJ=fx_man.o dsl.o ll_man.o multivoc.o mv_mix.o mvreverb.o nodpmi.o \
pitch.o user.o usrhooks.o
audiolib.a: $(OBJ)
rm -rf $@
$(AR) rc $@ $^
ifneq ($(strip $(solaris)),true)
$(RANLIB) $@
endif
clean:
rm -rf audiolib.a *.o
distclean: clean
rm -rf *~

174
audiolib/_al_midi.h Executable file
View File

@ -0,0 +1,174 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef ___AL_MIDI_H
#define ___AL_MIDI_H
#define NO_ADLIB_DETECTION "NOAL"
#define STEREO_DETUNE 5
#define lobyte( num ) ( ( unsigned )*( ( char * )&( num ) ) )
#define hibyte( num ) ( ( unsigned )*( ( ( char * )&( num ) ) + 1 ) )
#define AL_VoiceNotFound -1
#define alFreqH 0xb0
#define alEffects 0xbd
/* Number of slots for the voices on the chip */
#define NumChipSlots 18
#define NUM_VOICES 9
#define NUM_CHANNELS 16
#define NOTE_ON 0x2000 /* Used to turn note on or toggle note */
#define NOTE_OFF 0x0000
#define MAX_VELOCITY 0x7f
#define MAX_OCTAVE 7
#define MAX_NOTE ( MAX_OCTAVE * 12 + 11 )
#define FINETUNE_MAX 31
#define FINETUNE_RANGE ( FINETUNE_MAX + 1 )
#define PITCHBEND_CENTER 1638400
#define note_off 0x80
#define note_on 0x90
#define poly_aftertouch 0xa0
#define control_change 0xb0
#define program_chng 0xc0
#define channel_aftertouch 0xd0
#define pitch_wheel 0xe0
#define MIDI_VOLUME 7
#define MIDI_PAN 10
#define MIDI_DETUNE 94
#define MIDI_ALL_NOTES_OFF 0x7B
#define MIDI_RESET_ALL_CONTROLLERS 0x79
#define MIDI_RPN_MSB 100
#define MIDI_RPN_LSB 101
#define MIDI_DATAENTRY_MSB 6
#define MIDI_DATAENTRY_LSB 38
#define MIDI_PITCHBEND_RPN 0
enum cromatic_scale
{
C = 0x157,
C_SHARP = 0x16B,
D_FLAT = 0x16B,
D = 0x181,
D_SHARP = 0x198,
E_FLAT = 0x198,
E = 0x1B0,
F_FLAT = 0x1B0,
E_SHARP = 0x1CA,
F = 0x1CA,
F_SHARP = 0x1E5,
G_FLAT = 0x1E5,
G = 0x202,
G_SHARP = 0x220,
A_FLAT = 0x220,
A = 0x241,
A_SHARP = 0x263,
B_FLAT = 0x263,
B = 0x287,
C_FLAT = 0x287,
B_SHARP = 0x2AE,
};
/* Definition of octave information to be ORed onto F-Number */
enum octaves
{
OCTAVE_0 = 0x0000,
OCTAVE_1 = 0x0400,
OCTAVE_2 = 0x0800,
OCTAVE_3 = 0x0C00,
OCTAVE_4 = 0x1000,
OCTAVE_5 = 0x1400,
OCTAVE_6 = 0x1800,
OCTAVE_7 = 0x1C00
};
typedef struct VOICE
{
struct VOICE *next;
struct VOICE *prev;
unsigned num;
unsigned key;
unsigned velocity;
unsigned channel;
unsigned pitchleft;
unsigned pitchright;
int timbre;
int port;
unsigned status;
} VOICE;
typedef struct
{
VOICE *start;
VOICE *end;
} VOICELIST;
typedef struct
{
VOICELIST Voices;
int Timbre;
int Pitchbend;
int KeyOffset;
unsigned KeyDetune;
unsigned Volume;
unsigned EffectiveVolume;
int Pan;
int Detune;
unsigned RPN;
short PitchBendRange;
short PitchBendSemiTones;
short PitchBendHundreds;
} CHANNEL;
typedef struct
{
unsigned char SAVEK[ 2 ];
unsigned char Level[ 2 ];
unsigned char Env1[ 2 ];
unsigned char Env2[ 2 ];
unsigned char Wave[ 2 ];
unsigned char Feedback;
signed char Transpose;
signed char Velocity;
} TIMBRE;
extern TIMBRE ADLIB_TimbreBank[ 256 ];
static void AL_ResetVoices( void );
static void AL_CalcPitchInfo( void );
static void AL_SetVoiceTimbre( int voice );
static void AL_SetVoiceVolume( int voice );
static int AL_AllocVoice( void );
static int AL_GetVoice( int channel, int key );
static void AL_SetVoicePitch( int voice );
static void AL_SetChannelVolume( int channel, int volume );
static void AL_SetChannelPan( int channel, int pan );
static void AL_SetChannelDetune( int channel, int detune );
#endif

133
audiolib/_blaster.h Executable file
View File

@ -0,0 +1,133 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: _BLASTER.H
author: James R. Dose
date: February 4, 1994
Private header for for BLASTER.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___BLASTER_H
#define ___BLASTER_H
#define VALID ( 1 == 1 )
#define INVALID ( !VALID )
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#define YES ( 1 == 1 )
#define NO ( !YES )
#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
#define BLASTER_MixerAddressPort 0x04
#define BLASTER_MixerDataPort 0x05
#define BLASTER_ResetPort 0x06
#define BLASTER_ReadPort 0x0A
#define BLASTER_WritePort 0x0C
#define BLASTER_DataAvailablePort 0x0E
#define BLASTER_Ready 0xAA
#define BLASTER_16BitDMAAck 0x0F
#define MIXER_DSP4xxISR_Ack 0x82
#define MIXER_DSP4xxISR_Enable 0x83
#define MIXER_MPU401_INT 0x4
#define MIXER_16BITDMA_INT 0x2
#define MIXER_8BITDMA_INT 0x1
#define MIXER_DisableMPU401Interrupts 0xB
#define MIXER_SBProOutputSetting 0x0E
#define MIXER_SBProStereoFlag 0x02
#define MIXER_SBProVoice 0x04
#define MIXER_SBProMidi 0x26
#define MIXER_SB16VoiceLeft 0x32
#define MIXER_SB16VoiceRight 0x33
#define MIXER_SB16MidiLeft 0x34
#define MIXER_SB16MidiRight 0x35
#define DSP_Version1xx 0x0100
#define DSP_Version2xx 0x0200
#define DSP_Version201 0x0201
#define DSP_Version3xx 0x0300
#define DSP_Version4xx 0x0400
#define DSP_SB16Version DSP_Version4xx
#define DSP_MaxNormalRate 22000
#define DSP_MaxHighSpeedRate 44000
#define DSP_8BitAutoInitRecord 0x2c
#define DSP_8BitHighSpeedAutoInitRecord 0x98
#define DSP_Old8BitADC 0x24
#define DSP_8BitAutoInitMode 0x1c
#define DSP_8BitHighSpeedAutoInitMode 0x90
#define DSP_SetBlockLength 0x48
#define DSP_Old8BitDAC 0x14
#define DSP_16BitDAC 0xB6
#define DSP_8BitDAC 0xC6
#define DSP_8BitADC 0xCe
#define DSP_SetTimeConstant 0x40
#define DSP_Set_DA_Rate 0x41
#define DSP_Set_AD_Rate 0x42
#define DSP_Halt8bitTransfer 0xd0
#define DSP_Continue8bitTransfer 0xd4
#define DSP_Halt16bitTransfer 0xd5
#define DSP_Continue16bitTransfer 0xd6
#define DSP_SpeakerOn 0xd1
#define DSP_SpeakerOff 0xd3
#define DSP_GetVersion 0xE1
#define DSP_Reset 0xFFFF
#define DSP_SignedBit 0x10
#define DSP_StereoBit 0x20
#define DSP_UnsignedMonoData 0x00
#define DSP_SignedMonoData ( DSP_SignedBit )
#define DSP_UnsignedStereoData ( DSP_StereoBit )
#define DSP_SignedStereoData ( DSP_SignedBit | DSP_StereoBit )
#define BlasterEnv_Address 'A'
#define BlasterEnv_Interrupt 'I'
#define BlasterEnv_8bitDma 'D'
#define BlasterEnv_16bitDma 'H'
#define BlasterEnv_Type 'T'
#define BlasterEnv_Midi 'P'
#define BlasterEnv_EmuAddress 'E'
#define CalcTimeConstant( rate, samplesize ) \
( ( 65536L - ( 256000000L / ( ( samplesize ) * ( rate ) ) ) ) >> 8 )
#define CalcSamplingRate( tc ) \
( 256000000L / ( 65536L - ( tc << 8 ) ) )
typedef struct
{
int IsSupported;
int HasMixer;
int MaxMixMode;
int MinSamplingRate;
int MaxSamplingRate;
} CARD_CAPABILITY;
#endif

164
audiolib/_guswave.h Executable file
View File

@ -0,0 +1,164 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
file: _GUSWAVE.H
author: James R. Dose
date: March 23, 1994
Private header for GUSWAVE.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___GUSWAVE_H
#define ___GUSWAVE_H
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#define LOADDS _loadds
#define VOC_8BIT 0x0
#define VOC_CT4_ADPCM 0x1
#define VOC_CT3_ADPCM 0x2
#define VOC_CT2_ADPCM 0x3
#define VOC_16BIT 0x4
#define VOC_ALAW 0x6
#define VOC_MULAW 0x7
#define VOC_CREATIVE_ADPCM 0x200
#define MAX_BLOCK_LENGTH 0x8000
#define GF1BSIZE 896L /* size of buffer per wav on GUS */
//#define GF1BSIZE 512L /* size of buffer per wav on GUS */
//#define VOICES 8 /* maximum amount of concurrent wav files */
#define VOICES 2 /* maximum amount of concurrent wav files */
#define MAX_VOICES 32 /* This should always be 32 */
#define MAX_VOLUME 4095
#define BUFFER 2048U /* size of DMA buffer for patch loading */
typedef enum
{
Raw,
VOC,
DemandFeed,
WAV
} wavedata;
typedef enum
{
NoMoreData,
KeepPlaying,
SoundDone
} playbackstatus;
typedef volatile struct VoiceNode
{
struct VoiceNode *next;
struct VoiceNode *prev;
wavedata wavetype;
int bits;
playbackstatus ( *GetSound )( struct VoiceNode *voice );
int num;
unsigned long mem; /* location in ultrasound memory */
int Active; /* this instance in use */
int GF1voice; /* handle to active voice */
char *NextBlock;
char *LoopStart;
char *LoopEnd;
unsigned LoopCount;
unsigned long LoopSize;
unsigned long BlockLength;
unsigned long PitchScale;
unsigned char *sound;
unsigned long length;
unsigned long SamplingRate;
unsigned long RateScale;
int Playing;
int handle;
int priority;
void ( *DemandFeed )( char **ptr, unsigned long *length );
unsigned long callbackval;
int Volume;
int Pan;
}
VoiceNode;
typedef struct
{
VoiceNode *start;
VoiceNode *end;
}
voicelist;
typedef volatile struct voicestatus
{
VoiceNode *Voice;
int playing;
}
voicestatus;
typedef struct
{
char RIFF[ 4 ];
unsigned long file_size;
char WAVE[ 4 ];
char fmt[ 4 ];
unsigned long format_size;
} riff_header;
typedef struct
{
unsigned short wFormatTag;
unsigned short nChannels;
unsigned long nSamplesPerSec;
unsigned long nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short nBitsPerSample;
} format_header;
typedef struct
{
unsigned char DATA[ 4 ];
unsigned long size;
} data_header;
playbackstatus GUSWAVE_GetNextVOCBlock( VoiceNode *voice );
VoiceNode *GUSWAVE_GetVoice( int handle );
int GUSWAVE_Play( VoiceNode *voice, int angle, int volume, int channels );
VoiceNode *GUSWAVE_AllocVoice( int priority );
static int GUSWAVE_InitVoices( void );
#endif

290
audiolib/_midi.h Executable file
View File

@ -0,0 +1,290 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: _MIDI.H
author: James R. Dose
date: May 25, 1994
Private header for MIDI.C. Midi song file playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___MIDI_H
#define ___MIDI_H
#define RELATIVE_BEAT( measure, beat, tick ) \
( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
//Bobby Prince thinks this may be 100
//#define GENMIDI_DefaultVolume 100
#define GENMIDI_DefaultVolume 90
#define MAX_FORMAT 1
#define NUM_MIDI_CHANNELS 16
#define TIME_PRECISION 16
#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd"
#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk"
#define MIDI_VOLUME 7
#define MIDI_PAN 10
#define MIDI_DETUNE 94
#define MIDI_RHYTHM_CHANNEL 9
#define MIDI_RPN_MSB 100
#define MIDI_RPN_LSB 101
#define MIDI_DATAENTRY_MSB 6
#define MIDI_DATAENTRY_LSB 38
#define MIDI_PITCHBEND_MSB 0
#define MIDI_PITCHBEND_LSB 0
#define MIDI_RUNNING_STATUS 0x80
#define MIDI_NOTE_OFF 0x8
#define MIDI_NOTE_ON 0x9
#define MIDI_POLY_AFTER_TCH 0xA
#define MIDI_CONTROL_CHANGE 0xB
#define MIDI_PROGRAM_CHANGE 0xC
#define MIDI_AFTER_TOUCH 0xD
#define MIDI_PITCH_BEND 0xE
#define MIDI_SPECIAL 0xF
#define MIDI_SYSEX 0xF0
#define MIDI_SYSEX_CONTINUE 0xF7
#define MIDI_META_EVENT 0xFF
#define MIDI_END_OF_TRACK 0x2F
#define MIDI_TEMPO_CHANGE 0x51
#define MIDI_TIME_SIGNATURE 0x58
#define MIDI_RESET_ALL_CONTROLLERS 0x79
#define MIDI_ALL_NOTES_OFF 0x7b
#define MIDI_MONO_MODE_ON 0x7E
#define MIDI_SYSTEM_RESET 0xFF
#define GET_NEXT_EVENT( track, data ) \
( data ) = *( track )->pos; \
( track )->pos += 1
#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf )
#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 )
#define EMIDI_INFINITE -1
#define EMIDI_END_LOOP_VALUE 127
#define EMIDI_ALL_CARDS 127
#define EMIDI_INCLUDE_TRACK 110
#define EMIDI_EXCLUDE_TRACK 111
#define EMIDI_PROGRAM_CHANGE 112
#define EMIDI_VOLUME_CHANGE 113
#define EMIDI_CONTEXT_START 114
#define EMIDI_CONTEXT_END 115
#define EMIDI_LOOP_START 116
#define EMIDI_LOOP_END 117
#define EMIDI_SONG_LOOP_START 118
#define EMIDI_SONG_LOOP_END 119
#define EMIDI_GeneralMIDI 0
#define EMIDI_SoundCanvas 1
#define EMIDI_AWE32 2
#define EMIDI_WaveBlaster 3
#define EMIDI_SoundBlaster 4
#define EMIDI_ProAudio 5
#define EMIDI_SoundMan16 6
#define EMIDI_Adlib 7
#define EMIDI_Soundscape 8
#define EMIDI_Ultrasound 9
#define EMIDI_AffectsCurrentCard( c, type ) \
( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
#define EMIDI_NUM_CONTEXTS 7
typedef struct
{
unsigned char *pos;
unsigned char *loopstart;
short loopcount;
short RunningStatus;
unsigned time;
long FPSecondsPerTick;
short tick;
short beat;
short measure;
short BeatsPerMeasure;
short TicksPerBeat;
short TimeBase;
long delay;
short active;
} songcontext;
typedef struct
{
unsigned char *start;
unsigned char *pos;
long delay;
short active;
short RunningStatus;
short currentcontext;
songcontext context[ EMIDI_NUM_CONTEXTS ];
char EMIDI_IncludeTrack;
char EMIDI_ProgramChange;
char EMIDI_VolumeChange;
} track;
static long _MIDI_ReadNumber( void *from, size_t size );
static long _MIDI_ReadDelta( track *ptr );
static void _MIDI_ResetTracks( void );
static void _MIDI_AdvanceTick( void );
static void _MIDI_MetaEvent( track *Track );
static void _MIDI_SysEx( track *Track );
static int _MIDI_InterpretControllerInfo( track *Track, int TimeSet,
int channel, int c1, int c2 );
//static
void _MIDI_ServiceRoutine( task *Task );
static int _MIDI_SendControlChange( int channel, int c1, int c2 );
static void _MIDI_SetChannelVolume( int channel, int volume );
static void _MIDI_SendChannelVolumes( void );
static int _MIDI_ProcessNextTick( void );
static void _MIDI_InitEMIDI( void );
/*
if ( c1 == EMIDI_LOOP_START )
{
if ( c2 == 0 )
{
Track->context[ 0 ].loopcount = EMIDI_INFINITE;
}
else
{
Track->context[ 0 ].loopcount = c2;
}
Track->context[ 0 ].pos = Track->pos;
Track->context[ 0 ].loopstart = Track->pos;
Track->context[ 0 ].RunningStatus = Track->RunningStatus;
Track->context[ 0 ].time = _MIDI_Time;
Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
Track->context[ 0 ].tick = _MIDI_Tick;
Track->context[ 0 ].beat = _MIDI_Beat;
Track->context[ 0 ].measure = _MIDI_Measure;
Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
Track->context[ 0 ].TimeBase = _MIDI_TimeBase;
break;
}
if ( ( c1 == EMIDI_LOOP_END ) &&
( c2 == EMIDI_END_LOOP_VALUE ) )
{
if ( ( Track->context[ 0 ].loopstart != NULL ) &&
( Track->context[ 0 ].loopcount != 0 ) )
{
if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
{
Track->context[ 0 ].loopcount--;
}
Track->pos = Track->context[ 0 ].loopstart;
Track->RunningStatus = Track->context[ 0 ].RunningStatus;
if ( !TimeSet )
{
_MIDI_Time = Track->context[ 0 ].time;
_MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
_MIDI_Tick = Track->context[ 0 ].tick;
_MIDI_Beat = Track->context[ 0 ].beat;
_MIDI_Measure = Track->context[ 0 ].measure;
_MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure;
_MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat;
_MIDI_TimeBase = Track->context[ 0 ].TimeBase;
TimeSet = TRUE;
}
}
break;
}
if ( c1 == MIDI_MONO_MODE_ON )
{
Track->pos++;
}
if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
{
_MIDI_SetChannelVolume( channel, c2 );
break;
}
else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
( Track->EMIDI_VolumeChange ) )
{
_MIDI_SetChannelVolume( channel, c2 );
break;
}
if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
( Track->EMIDI_ProgramChange ) )
{
_MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
break;
}
if ( c1 == EMIDI_CONTEXT_START )
{
break;
}
if ( c1 == EMIDI_CONTEXT_END )
{
if ( ( Track->currentcontext != _MIDI_Context ) ||
( Track->context[ _MIDI_Context ].pos == NULL )
{
break;
}
Track->currentcontext = _MIDI_Context;
Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
Track->pos = Track->context[ _MIDI_Context ].pos;
Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
if ( TimeSet )
{
break;
}
_MIDI_Time = Track->context[ _MIDI_Context ].time;
_MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
_MIDI_Tick = Track->context[ _MIDI_Context ].tick;
_MIDI_Beat = Track->context[ _MIDI_Context ].beat;
_MIDI_Measure = Track->context[ _MIDI_Context ].measure;
_MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure;
_MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat;
_MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase;
TimeSet = TRUE;
break;
}
if ( _MIDI_Funcs->ControlChange )
{
_MIDI_Funcs->ControlChange( channel, c1, c2 );
}
*/
#endif

286
audiolib/_multivc.h Executable file
View File

@ -0,0 +1,286 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
file: _MULTIVC.H
author: James R. Dose
date: December 20, 1993
Private header for MULTIVOC.C
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___MULTIVC_H
#define ___MULTIVC_H
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#define VOC_8BIT 0x0
#define VOC_CT4_ADPCM 0x1
#define VOC_CT3_ADPCM 0x2
#define VOC_CT2_ADPCM 0x3
#define VOC_16BIT 0x4
#define VOC_ALAW 0x6
#define VOC_MULAW 0x7
#define VOC_CREATIVE_ADPCM 0x200
#define T_SIXTEENBIT_STEREO 0
#define T_8BITS 1
#define T_MONO 2
#define T_16BITSOURCE 4
#define T_LEFTQUIET 8
#define T_RIGHTQUIET 16
#define T_DEFAULT T_SIXTEENBIT_STEREO
#define MV_MaxPanPosition 31
#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
#define MV_MaxTotalVolume 255
//#define MV_MaxVolume 63
#define MV_NumVoices 8
#define MIX_VOLUME( volume ) \
( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
// ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 )
//#define SILENCE_16BIT 0x80008000
#define SILENCE_16BIT 0
#define SILENCE_8BIT 0x80808080
//#define SILENCE_16BIT_PAS 0
#define MixBufferSize 256
#define NumberOfBuffers 16
#define TotalBufferSize ( MixBufferSize * NumberOfBuffers )
#define PI 3.1415926536
typedef enum
{
Raw,
VOC,
DemandFeed,
WAV
} wavedata;
typedef enum
{
NoMoreData,
KeepPlaying
} playbackstatus;
typedef struct VoiceNode
{
struct VoiceNode *next;
struct VoiceNode *prev;
wavedata wavetype;
char bits;
playbackstatus ( *GetSound )( struct VoiceNode *voice );
void ( *mix )( unsigned long position, unsigned long rate,
const char *start, unsigned long length );
char *NextBlock;
char *LoopStart;
char *LoopEnd;
unsigned LoopCount;
unsigned long LoopSize;
unsigned long BlockLength;
unsigned long PitchScale;
unsigned long FixedPointBufferSize;
char *sound;
unsigned long length;
unsigned long SamplingRate;
unsigned long RateScale;
unsigned long position;
int Playing;
int handle;
int priority;
void ( *DemandFeed )( char **ptr, unsigned long *length );
short *LeftVolume;
short *RightVolume;
unsigned long callbackval;
} VoiceNode;
typedef struct
{
VoiceNode *start;
VoiceNode *end;
} VList;
typedef struct
{
unsigned char left;
unsigned char right;
} Pan;
typedef signed short MONO16;
typedef signed char MONO8;
typedef struct
{
MONO16 left;
MONO16 right;
// unsigned short left;
// unsigned short right;
} STEREO16;
typedef struct
{
MONO16 left;
MONO16 right;
} SIGNEDSTEREO16;
typedef struct
{
// MONO8 left;
// MONO8 right;
char left;
char right;
} STEREO8;
typedef struct
{
char RIFF[ 4 ];
unsigned long file_size;
char WAVE[ 4 ];
char fmt[ 4 ];
unsigned long format_size;
} riff_header;
typedef struct
{
unsigned short wFormatTag;
unsigned short nChannels;
unsigned long nSamplesPerSec;
unsigned long nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short nBitsPerSample;
} format_header;
typedef struct
{
unsigned char DATA[ 4 ];
unsigned long size;
} data_header;
typedef MONO8 VOLUME8[ 256 ];
typedef MONO16 VOLUME16[ 256 ];
typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
static void MV_Mix( VoiceNode *voice, int buffer );
static void MV_PlayVoice( VoiceNode *voice );
static void MV_StopVoice( VoiceNode *voice );
static void MV_ServiceVoc( void );
static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice );
static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice );
static playbackstatus MV_GetNextRawBlock( VoiceNode *voice );
static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice );
static void MV_ServiceRecord( void );
static VoiceNode *MV_GetVoice( int handle );
static VoiceNode *MV_AllocVoice( int priority );
static short *MV_GetVolumeTable( int vol );
static void MV_SetVoiceMixMode( VoiceNode *voice );
static void MV_SetVoicePitch( VoiceNode *voice, unsigned long rate, int pitchoffset );
static void MV_CalcVolume( int MaxLevel );
static void MV_CalcPanTable( void );
#ifdef PLAT_DOS
#define ATR_INDEX 0x3c0
#define STATUS_REGISTER_1 0x3da
#define SetBorderColor(color) \
{ \
inp (STATUS_REGISTER_1); \
outp (ATR_INDEX,0x31); \
outp (ATR_INDEX,color); \
}
#endif
void ClearBuffer_DW( void *ptr, unsigned data, int length );
#ifdef PLAT_DOS
#pragma aux ClearBuffer_DW = \
"cld", \
"push es", \
"push ds", \
"pop es", \
"rep stosd", \
"pop es", \
parm [ edi ] [ eax ] [ ecx ] modify exact [ ecx edi ];
#endif
void MV_Mix8BitMono( unsigned long position, unsigned long rate,
const char *start, unsigned long length );
void MV_Mix8BitStereo( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_Mix16BitMono( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_Mix16BitStereo( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_Mix16BitMono16( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
const char *start, unsigned long length );
void MV_Mix8BitStereo16( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_Mix16BitStereo16( unsigned long position,
unsigned long rate, const char *start, unsigned long length );
void MV_16BitReverb( const char *src, char *dest, const VOLUME16 *volume, int count );
void MV_8BitReverb( const signed char *src, signed char *dest, const VOLUME16 *volume, int count );
void MV_16BitReverbFast( const char *src, char *dest, int count, int shift );
void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift );
#ifdef PLAT_DOS
#pragma aux MV_16BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
#pragma aux MV_8BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
#pragma aux MV_16BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
#pragma aux MV_8BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
#endif
#endif

250
audiolib/_pas16.h Executable file
View File

@ -0,0 +1,250 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: _PAS16.H
author: James R. Dose
date: March 27, 1994
Private header for for PAS16.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___PAS16_H
#define ___PAS16_H
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#define VALID ( 1 == 1 )
#define INVALID ( !VALID )
#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
#define STEREO 1
#define SIXTEEN_BIT 2
#define MONO_8BIT 0
#define STEREO_8BIT ( STEREO )
#define MONO_16BIT ( SIXTEEN_BIT )
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
#define PAS_MaxMixMode STEREO_16BIT
#define MONO_8BIT_SAMPLE_SIZE 1
#define MONO_16BIT_SAMPLE_SIZE 2
#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
#define PAS_RevisionBits 0xe0
#define AudioFilterControl 0xb8a
#define InterruptControl 0xb8b
#define InterruptStatus 0xb89
#define PCMDataRegister 0xf88
#define CrossChannelControl 0xf8a
#define SampleRateTimer 0x1388
#define SampleBufferCount 0x1389
#define LocalSpeakerTimerCount 0x138a
#define LocalTimerControl 0x138b
#define SampleSizeConfiguration 0x8389
#define AudioMuteFlag 0x20
#define SampleRateTimerGateFlag 0x40
#define SampleBufferCountGateFlag 0x80
#define SampleRateInterruptFlag 0x04
#define SampleBufferInterruptFlag 0x08
#define PAS_SampleSizeMask 0xf3
#define PAS_SignedSampleMask 0xe3
#define PAS_16BitSampleFlag 0x04
#define PAS_UnsignedSampleFlag 0x10
//bSC2msbinv equ 00010000b ;; invert MSB from standard method
#define PAS_OverSamplingMask 0xfc
#define PAS_1xOverSampling 0x00
#define PAS_2xOverSampling 0x01
#define PAS_4xOverSampling 0x03
#define PAS_StereoFlag 0x20
#define PAS_AudioMuteFlag 0x20
#define DEFAULT_BASE ( 0x0388 ^ 0x388 ) /* default base I/O address */
#define ALT_BASE_1 ( 0x0384 ^ 0x388 ) /* first alternate address */
#define ALT_BASE_2 ( 0x038C ^ 0x388 ) /* second alternate address */
#define ALT_BASE_3 ( 0x0288 ^ 0x388 ) /* third alternate address */
#define PAS_DMAEnable 0x80
#define PAS_ChannelConnectMask 0x0f
#define PAS_PCMStartDAC 0xD0
#define PAS_PCMStartADC 0xC0
#define PAS_PCMStopMask 0x3f
#define RECORD 0
#define PLAYBACK 1
#define SelectSampleRateTimer 0x36 // 00110110b
#define SelectSampleBufferCount 0x74 // 01110100b
#define CalcTimeInterval( rate ) \
( 1193180UL / ( rate ) )
#define CalcSamplingRate( interval ) \
( 1193180UL / ( interval ) )
#define MV_Signature 0x4d56
#define MV_SoundInt 0x2f
#define MV_CheckForDriver 0xbc00
#define MV_GetVersion 0xbc01
#define MV_GetPointerToStateTable 0xbc02
#define MV_GetPointerToFunctionTable 0xbc03
#define MV_GetDmaIrqInt 0xbc04
#define MV_SendCommandStructure 0xbc05
#define MV_GetDriverMessage 0xbc06
#define MV_SetHotkeyScanCodes 0xbc0a
#define MV_GetPathToDriver 0xbc0b
#define OUTPUTMIXER 0x00 /* output mixer H/W select */
#define INPUTMIXER 0x40 /* input mixer select */
#define DEFMIXER -1 /* use last mixer selected */
/* left channel values */
#define L_FM 0x01
#define L_IMIXER 0x02
#define L_EXT 0x03
#define L_INT 0x04
#define L_MIC 0x05
#define L_PCM 0x06
#define L_SPEAKER 0x07
#define L_FREE 0x00
#define L_SBDAC 0x00
/* right channel values */
#define R_FM 0x08
#define R_IMIXER 0x09
#define R_EXT 0x0A
#define R_INT 0x0B
#define R_MIC 0x0C
#define R_PCM 0x0D
#define R_SPEAKER 0x0E
#define R_FREE 0x0F
#define R_SBDAC 0x0F
typedef struct
{
unsigned char sysspkrtmr; /* 42 System Speaker Timer Address */
unsigned char systmrctlr; /* 43 System Timer Control */
unsigned char sysspkrreg; /* 61 System Speaker Register */
unsigned char joystick; /* 201 Joystick Register */
unsigned char lfmaddr; /* 388 Left FM Synth Address */
unsigned char lfmdata; /* 389 Left FM Synth Data */
unsigned char rfmaddr; /* 38A Right FM Synth Address */
unsigned char rfmdata; /* 38B Right FM Synth Data */
unsigned char dfmaddr; /* 788 Dual FM Synth Address */
unsigned char dfmdata; /* 789 Dual FM Synth Data */
unsigned char RESRVD1[1]; /* reserved */
unsigned char paudiomixr; /* 78B Paralllel Audio Mixer Control*/
unsigned char audiomixr; /* B88 Audio Mixer Control */
unsigned char intrctlrst; /* B89 Interrupt Status */
unsigned char audiofilt; /* B8A Audio Filter Control */
unsigned char intrctlr; /* B8B Interrupt Control */
unsigned char pcmdata; /* F88 PCM Data I/O Register */
unsigned char RESRVD2; /* reserved */
unsigned char crosschannel; /* F8A Cross Channel */
unsigned char RESRVD3; /* reserved */
unsigned short samplerate; /* 1388 Sample Rate Timer */
unsigned short samplecnt; /* 1389 Sample Count Register */
unsigned short spkrtmr; /* 138A Shadow Speaker Timer Count */
unsigned char tmrctlr; /* 138B Shadow Speaker Timer Control */
unsigned char mdirqvect; /* 1788 MIDI IRQ Vector Register */
unsigned char mdsysctlr; /* 1789 MIDI System Control Register */
unsigned char mdsysstat; /* 178A MIDI IRQ Status Register */
unsigned char mdirqclr; /* 178B MIDI IRQ Clear Register */
unsigned char mdgroup1; /* 1B88 MIDI Group #1 Register */
unsigned char mdgroup2; /* 1B89 MIDI Group #2 Register */
unsigned char mdgroup3; /* 1B8A MIDI Group #3 Register */
unsigned char mdgroup4; /* 1B8B MIDI Group #4 Register */
} MVState;
typedef struct
{
unsigned long SetMixer;
unsigned long SetVolume;
unsigned long SetFilter;
unsigned long SetCrossChannel;
unsigned long GetMixer;
unsigned long GetVolume;
unsigned long GetFilter;
unsigned long GetCrossChannel;
unsigned long ReadSound;
unsigned long FMSplit;
} MVFunc;
int PAS_CheckForDriver( void );
MVState *PAS_GetStateTable( void );
MVFunc *PAS_GetFunctionTable( void );
int PAS_GetCardSettings( void );
void PAS_EnableInterrupt( void );
void PAS_DisableInterrupt( void );
void interrupt far PAS_ServiceInterrupt( void );
//void interrupt PAS_ServiceInterrupt( void );
void PAS_Write( int Register, int Data );
int PAS_Read( int Register );
void PAS_SetSampleRateTimer( void );
void PAS_SetSampleBufferCount( void );
int PAS_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
int PAS_GetFilterSetting( int rate );
void PAS_BeginTransfer( int mode );
int PAS_TestAddress( int address );
int PAS_FindCard( void );
int PAS_CallMVFunction( unsigned long function, int ebx, int ecx, int edx );
void PAS_SaveState( void );
void PAS_RestoreState( void );
#pragma aux PAS_TestAddress = \
"mov dx, 0b8bh", \
"xor dx, ax", \
"in al, dx", \
"cmp al, 0ffh", \
"je TestExit", \
"mov ah, al", \
"xor al, 0e0h", \
"out dx, al", \
"jmp TestDelay1", \
"TestDelay1:", \
"jmp TestDelay2", \
"TestDelay2:", \
"in al, dx", \
"xchg al, ah", \
"out dx, al", \
"sub al, ah", \
"TestExit:", \
"and eax, 0ffh" \
parm [ eax ] modify exact [ eax dx ];
#endif

136
audiolib/_sndscap.h Executable file
View File

@ -0,0 +1,136 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: _SNDSCAP.H
author: James R. Dose
date: October 26, 1994
Private header for SNDSCAPE.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___SNDSCAP_H
#define ___SNDSCAP_H
#define VALID ( 1 == 1 )
#define INVALID ( !VALID )
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
#define STEREO 1
#define SIXTEEN_BIT 2
#define MONO_8BIT 0
#define STEREO_8BIT ( STEREO )
#define MONO_16BIT ( SIXTEEN_BIT )
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
#define SOUNDSCAPE_MaxMixMode STEREO_16BIT
#define MONO_8BIT_SAMPLE_SIZE 1
#define MONO_16BIT_SAMPLE_SIZE 2
#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
#define SOUNDSCAPE_DefaultSampleRate 11000
#define SOUNDSCAPE_DefaultMixMode MONO_8BIT
#define SOUNDSCAPE_MaxIrq 15
/* Ensoniq gate-array chip defines ... */
#define ODIE 0 /* ODIE gate array */
#define OPUS 1 /* OPUS gate array */
#define MMIC 2 /* MiMIC gate array */
/* relevant direct register defines - offsets from base address */
#define GA_HOSTCSTAT 2 /* host port ctrl/stat reg */
#define GA_HOSTDATA 3 /* host port data reg */
#define GA_REGADDR 4 /* indirect address reg */
#define GA_REGDATA 5 /* indirect data reg */
#define SB_IACK 0x22e /* SoundBlaster IACK register */
/* relevant indirect register defines */
#define GA_DMACHB 3 /* DMA chan B assign reg */
#define GA_INTCFG 4 /* interrupt configuration reg */
#define GA_DMACFG 5 /* DMA config reg */
#define GA_CDCFG 6 /* CD-ROM (AD-1848) config reg */
#define GA_HMCTL 9 /* host master control reg */
#define GA_CHIPSEL 10 /* programmable external chip select */
/* AD-1848 chip defines ... */
/* relevant direct register defines */
#define AD_REGADDR 0 /* indirect address reg */
#define AD_REGDATA 1 /* indirect data reg */
#define AD_STATUS 2 /* status register */
#define AD_OFFSET 8 /* for some boards, a fixed BasePort offset */
/* relevant indirect register defines */
#define AD_LEFTOUT 6 /* left DAC output control reg */
#define AD_RIGHTOUT 7 /* right DAC output control reg */
#define AD_FORMAT 8 /* clock and data format reg */
#define AD_CONFIG 9 /* interface config register */
#define AD_PINCTRL 10 /* external pin control reg */
#define AD_UCOUNT 14 /* upper count reg */
#define AD_LCOUNT 15 /* lower count reg */
/* some firmware command and communication defines */
#define SET_CTL 0x88 /* set a control value */
#define GET_CTL 0x89 /* get a control value */
#define SET_REV 0xb0 /* set synth reverb */
#define SYNTH_VOL 0x04 /* Synth Vol control number */
#define RXRDY 0x01 /* Receive-Ready bit mask */
#define TXRDY 0x02 /* Transmit-Ready bit mask */
/* some miscellaneous defines ... soundscape reg values, sytem int regs, ... */
#define INTCONT1 0x20 /* Interrupt Controller 1 control register */
#define INTCONT2 0xa0 /* Interrupt Controller 2 control register */
#define INTMASK1 0x21 /* Interrupt Controller 1 mask register */
#define INTMASK2 0xa1 /* Interrupt Controller 2 mask register */
#define VECTBASE1 0x08 /* vector base for XT interrupts */
#define VECTBASE2 0x70 /* vector base for AT extended interrupts */
#define EOI 0x20 /* End Of Interrupt command */
#define AUTO_OUT 0x58 /* DMA controller mode */
static void SOUNDSCAPE_EnableInterrupt( void );
static void SOUNDSCAPE_DisableInterrupt( void );
static void __interrupt __far SOUNDSCAPE_ServiceInterrupt( void );
static int ga_read( int rnum );
static void ga_write( int rnum, int value );
static int ad_read( int rnum );
static void ad_write( int rnum, int value );
static void tdelay( void );
static void pcm_format( void );
static int SOUNDSCAPE_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
static int SOUNDSCAPE_BeginPlayback( int length );
static void SOUNDSCAPE_LockEnd( void );
static void SOUNDSCAPE_UnlockMemory( void );
static int SOUNDSCAPE_LockMemory( void );
static unsigned short allocateTimerStack( unsigned short size );
static void deallocateTimerStack( unsigned short selector );
static int parse( char *val, char *str, FILE *p1 );
static int SOUNDSCAPE_FindCard( void );
static int SOUNDSCAPE_Setup( void );
#endif

552
audiolib/adlibfx.c Executable file
View File

@ -0,0 +1,552 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: ADLIBFX.C
author: James R. Dose
date: April 1, 1994
Low level routines to support Adlib sound effects created by Muse.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <dos.h>
#include <stdlib.h>
#include <conio.h>
#include "dpmi.h"
#include "task_man.h"
#include "interrup.h"
#include "al_midi.h"
#include "adlibfx.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
static void ADLIBFX_SendOutput( int reg, int data );
static void ADLIBFX_Service( task *Task );
static long ADLIBFX_LengthLeft;
static int ADLIBFX_Block;
static ALSound *ADLIBFX_Sound = NULL;
static char *ADLIBFX_SoundPtr = NULL;
static int ADLIBFX_Priority;
static unsigned long ADLIBFX_CallBackVal;
static void ( *ADLIBFX_CallBackFunc )( unsigned long ) = NULL;
static int ADLIBFX_SoundVolume;
static int ADLIBFX_TotalVolume = ADLIBFX_MaxVolume;
static task *ADLIBFX_ServiceTask = NULL;
static int ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
int ADLIBFX_Installed = FALSE;
int ADLIBFX_ErrorCode = ADLIBFX_Ok;
#define ADLIBFX_SetErrorCode( status ) \
ADLIBFX_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: ADLIBFX_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *ADLIBFX_ErrorString
(
int ErrorNumber
)
{
char *ErrorString;
switch( ErrorNumber )
{
case ADLIBFX_Warning :
case ADLIBFX_Error :
ErrorString = ADLIBFX_ErrorString( ADLIBFX_ErrorCode );
break;
case ADLIBFX_Ok :
ErrorString = "Adlib FX ok.";
break;
case ADLIBFX_NoVoices :
ErrorString = "No free voices available in Adlib FX.";
break;
case ADLIBFX_VoiceNotFound :
ErrorString = "No voice with matching handle found.";
break;
case ADLIBFX_DPMI_Error :
ErrorString = "DPMI Error in AdlibFX.";
break;
default :
ErrorString = "Unknown Adlib FX error code.";
break;
}
return( ErrorString );
}
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define ADLIBFX_LockStart ADLIBFX_SendOutput
/*---------------------------------------------------------------------
Function: ADLIBFX_SendOutput
Writes a byte of data to the specified register on the Adlib card.
---------------------------------------------------------------------*/
static void ADLIBFX_SendOutput
(
int reg,
int data
)
{
int i;
int adlib_port = 0x388;
unsigned flags;
flags = DisableInterrupts();
outp( adlib_port, reg );
for( i = 6; i ; i-- )
{
inp( adlib_port );
}
outp( adlib_port + 1, data );
for( i = 35; i ; i-- )
{
inp( adlib_port );
}
RestoreInterrupts( flags );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_Stop
Halts playback of the currently playing sound effect.
---------------------------------------------------------------------*/
int ADLIBFX_Stop
(
int handle
)
{
unsigned flags;
if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
{
ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
return( ADLIBFX_Warning );
}
flags = DisableInterrupts();
ADLIBFX_SendOutput( 0xb0, 0 );
ADLIBFX_Sound = NULL;
ADLIBFX_SoundPtr = NULL;
ADLIBFX_LengthLeft = 0;
ADLIBFX_Priority = 0;
RestoreInterrupts( flags );
if ( ADLIBFX_CallBackFunc )
{
ADLIBFX_CallBackFunc( ADLIBFX_CallBackVal );
}
return( ADLIBFX_Ok );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_Service
Task Manager routine to perform the playback of a sound effect.
---------------------------------------------------------------------*/
static void ADLIBFX_Service
(
task *Task
)
{
int value;
if ( ADLIBFX_SoundPtr )
{
value = *ADLIBFX_SoundPtr++;
if ( value != 0 )
{
ADLIBFX_SendOutput( 0xa0, value );
ADLIBFX_SendOutput( 0xb0, ADLIBFX_Block );
}
else
{
ADLIBFX_SendOutput( 0xb0, 0 );
}
ADLIBFX_LengthLeft--;
if ( ADLIBFX_LengthLeft <= 0 )
{
ADLIBFX_Stop( ADLIBFX_VoiceHandle );
}
}
}
/*---------------------------------------------------------------------
Function: ADLIBFX_SetVolume
Sets the volume of the currently playing sound effect.
---------------------------------------------------------------------*/
int ADLIBFX_SetVolume
(
int handle,
int volume
)
{
unsigned flags;
int carrierlevel;
flags = DisableInterrupts();
if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
{
RestoreInterrupts( flags );
ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
return( ADLIBFX_Warning );
}
volume = min( volume, ADLIBFX_MaxVolume );
volume = max( volume, 0 );
ADLIBFX_SoundVolume = volume;
volume *= ADLIBFX_TotalVolume;
volume /= ADLIBFX_MaxVolume;
carrierlevel = ADLIBFX_Sound->cScale & 0x3f;
carrierlevel ^= 0x3f;
carrierlevel *= ( volume / 2 ) + 0x80;
carrierlevel /= ADLIBFX_MaxVolume;
carrierlevel ^= 0x3f;
carrierlevel |= ADLIBFX_Sound->cScale & 0xc0;
ADLIBFX_SendOutput( 0x43, carrierlevel );
RestoreInterrupts( flags );
return( ADLIBFX_Ok );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_SetTotalVolume
Sets the total volume of the sound effect.
---------------------------------------------------------------------*/
int ADLIBFX_SetTotalVolume
(
int volume
)
{
volume = max( volume, 0 );
volume = min( volume, ADLIBFX_MaxVolume );
ADLIBFX_TotalVolume = volume;
ADLIBFX_SetVolume( ADLIBFX_VoiceHandle, ADLIBFX_SoundVolume );
return( ADLIBFX_Ok );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_GetTotalVolume
Returns the total volume of the sound effect.
---------------------------------------------------------------------*/
int ADLIBFX_GetTotalVolume
(
void
)
{
return( ADLIBFX_TotalVolume );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_VoiceAvailable
Checks if a voice can be play at the specified priority.
---------------------------------------------------------------------*/
int ADLIBFX_VoiceAvailable
(
int priority
)
{
if ( priority < ADLIBFX_Priority )
{
return( FALSE );
}
return( TRUE );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_Play
Starts playback of a Muse sound effect.
---------------------------------------------------------------------*/
int ADLIBFX_Play
(
ALSound *sound,
int volume,
int priority,
unsigned long callbackval
)
{
unsigned flags;
int carrierlevel;
if ( priority < ADLIBFX_Priority )
{
ADLIBFX_SetErrorCode( ADLIBFX_NoVoices );
return( ADLIBFX_Warning );
}
ADLIBFX_Stop( ADLIBFX_VoiceHandle );
ADLIBFX_VoiceHandle++;
if ( ADLIBFX_VoiceHandle < ADLIBFX_MinVoiceHandle )
{
ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
}
flags = DisableInterrupts();
ADLIBFX_LengthLeft = sound->length;
ADLIBFX_Priority = priority;
ADLIBFX_Sound = sound;
ADLIBFX_SoundPtr = &sound->data;
ADLIBFX_CallBackVal = callbackval;
ADLIBFX_Block = ( ( sound->block & 7 ) << 2 ) | 0x20;
volume = min( volume, ADLIBFX_MaxVolume );
volume = max( volume, 0 );
ADLIBFX_SoundVolume = volume;
volume *= ADLIBFX_TotalVolume;
volume /= ADLIBFX_MaxVolume;
carrierlevel = sound->cScale & 0x3f;
carrierlevel ^= 0x3f;
carrierlevel *= ( volume / 2 ) + 0x80;
carrierlevel /= ADLIBFX_MaxVolume;
carrierlevel ^= 0x3f;
carrierlevel |= sound->cScale & 0xc0;
ADLIBFX_SendOutput( 0x20, sound->mChar );
ADLIBFX_SendOutput( 0x40, sound->mScale );
ADLIBFX_SendOutput( 0x60, sound->mAttack );
ADLIBFX_SendOutput( 0x80, sound->mSus );
ADLIBFX_SendOutput( 0xe0, sound->mWave );
ADLIBFX_SendOutput( 0x23, sound->cChar );
ADLIBFX_SendOutput( 0x43, carrierlevel );
ADLIBFX_SendOutput( 0x63, sound->cAttack );
ADLIBFX_SendOutput( 0x83, sound->cSus );
ADLIBFX_SendOutput( 0xe3, sound->cWave );
ADLIBFX_SendOutput( 0xc0, 0 );
RestoreInterrupts( flags );
return( ADLIBFX_VoiceHandle );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_SoundPlaying
Checks if a sound effect is currently playing.
---------------------------------------------------------------------*/
int ADLIBFX_SoundPlaying
(
int handle
)
{
int status;
status = FALSE;
if ( ( handle == ADLIBFX_VoiceHandle ) && ( ADLIBFX_LengthLeft > 0 ) )
{
status = TRUE;
}
return( status );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void ADLIBFX_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: ADLIBFX_SetCallBack
Set the function to call when a voice stops.
---------------------------------------------------------------------*/
void ADLIBFX_SetCallBack
(
void ( *function )( unsigned long )
)
{
ADLIBFX_CallBackFunc = function;
}
/*---------------------------------------------------------------------
Function: ADLIBFX_Init
Initializes the sound effect engine.
---------------------------------------------------------------------*/
int ADLIBFX_Init
(
void
)
{
int status;
if ( ADLIBFX_Installed )
{
ADLIBFX_Shutdown();
}
status = DPMI_LockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
status |= DPMI_Lock( ADLIBFX_VoiceHandle );
status |= DPMI_Lock( ADLIBFX_Sound );
status |= DPMI_Lock( ADLIBFX_ErrorCode );
status |= DPMI_Lock( ADLIBFX_SoundPtr );
status |= DPMI_Lock( ADLIBFX_LengthLeft );
status |= DPMI_Lock( ADLIBFX_Priority );
status |= DPMI_Lock( ADLIBFX_CallBackFunc );
status |= DPMI_Lock( ADLIBFX_Block );
if ( status != DPMI_Ok )
{
ADLIBFX_SetErrorCode( ADLIBFX_DPMI_Error );
return( ADLIBFX_Error );
}
//JIM
// AL_ReserveVoice( 0 );
ADLIBFX_Stop( ADLIBFX_VoiceHandle );
ADLIBFX_ServiceTask = TS_ScheduleTask( &ADLIBFX_Service, 140, 2, NULL );
TS_Dispatch();
ADLIBFX_Installed = TRUE;
ADLIBFX_CallBackFunc = NULL;
ADLIBFX_SetErrorCode( ADLIBFX_Ok );
return( ADLIBFX_Ok );
}
/*---------------------------------------------------------------------
Function: ADLIBFX_Shutdown
Ends the use of the sound effect engine.
---------------------------------------------------------------------*/
int ADLIBFX_Shutdown
(
void
)
{
if ( ADLIBFX_Installed )
{
ADLIBFX_Stop( ADLIBFX_VoiceHandle );
TS_Terminate( ADLIBFX_ServiceTask );
ADLIBFX_ServiceTask = NULL;
//JIM
// AL_ReleaseVoice( 0 );
ADLIBFX_Installed = FALSE;
DPMI_UnlockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
DPMI_Unlock( ADLIBFX_VoiceHandle );
DPMI_Unlock( ADLIBFX_Sound );
DPMI_Unlock( ADLIBFX_ErrorCode );
DPMI_Unlock( ADLIBFX_SoundPtr );
DPMI_Unlock( ADLIBFX_LengthLeft );
DPMI_Unlock( ADLIBFX_Priority );
DPMI_Unlock( ADLIBFX_CallBackFunc );
DPMI_Unlock( ADLIBFX_Block );
}
ADLIBFX_SetErrorCode( ADLIBFX_Ok );
return( ADLIBFX_Ok );
}

80
audiolib/adlibfx.h Executable file
View File

@ -0,0 +1,80 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: ADLIBFX.H
author: James R. Dose
date: April 1, 1994
Public header for ADLIBFX.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __ADLIBFX_H
#define __ADLIBFX_H
enum ADLIBFX_Errors
{
ADLIBFX_Warning = -2,
ADLIBFX_Error = -1,
ADLIBFX_Ok = 0,
ADLIBFX_NoVoices,
ADLIBFX_VoiceNotFound,
ADLIBFX_DPMI_Error
};
typedef struct
{
unsigned long length;
short int priority;
char mChar, cChar;
char mScale, cScale;
char mAttack, cAttack;
char mSus, cSus;
char mWave, cWave;
char nConn;
char voice;
char mode;
char unused[ 3 ];
char block;
char data[];
} ALSound;
#define ADLIBFX_MaxVolume 255
#define ADLIBFX_MinVoiceHandle 1
char *ADLIBFX_ErrorString( int ErrorNumber );
int ADLIBFX_Stop( int handle );
int ADLIBFX_SetVolume( int handle, int volume );
int ADLIBFX_SetTotalVolume( int volume );
int ADLIBFX_GetTotalVolume( void );
int ADLIBFX_VoiceAvailable( int priority );
int ADLIBFX_Play( ALSound *sound, int volume, int priority, unsigned long callbackval );
int ADLIBFX_SoundPlaying( int handle );
void ADLIBFX_SetCallBack( void ( *function )( unsigned long ) );
int ADLIBFX_Init( void );
int ADLIBFX_Shutdown( void );
#pragma aux ADLIBFX_Shutdown frame;
void PCFX_UnlockMemory( void );
#pragma aux ADLIBFX_UnlockMemory frame;
int PCFX_LockMemory( void );
#endif

1510
audiolib/al_midi.c Executable file

File diff suppressed because it is too large Load Diff

58
audiolib/al_midi.h Executable file
View File

@ -0,0 +1,58 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __AL_MIDI_H
#define __AL_MIDI_H
enum AL_Errors
{
AL_Warning = -2,
AL_Error = -1,
AL_Ok = 0,
};
#define AL_MaxVolume 127
#define AL_DefaultChannelVolume 90
//#define AL_DefaultPitchBendRange 2
#define AL_DefaultPitchBendRange 200
#define ADLIB_PORT 0x388
void AL_SendOutputToPort( int port, int reg, int data );
void AL_SendOutput( int voice, int reg, int data );
void AL_StereoOn( void );
void AL_StereoOff( void );
int AL_ReserveVoice( int voice );
int AL_ReleaseVoice( int voice );
void AL_Shutdown( void );
int AL_Init( int soundcard );
void AL_SetMaxMidiChannel( int channel );
void AL_Reset( void );
void AL_NoteOff( int channel, int key, int velocity );
void AL_NoteOn( int channel, int key, int vel );
//Turned off to test if it works with Watcom 10a
// #pragma aux AL_NoteOn frame;
void AL_AllNotesOff( int channel );
void AL_ControlChange( int channel, int type, int data );
void AL_ProgramChange( int channel, int patch );
void AL_SetPitchBend( int channel, int lsb, int msb );
int AL_DetectFM( void );
void AL_RegisterTimbreBank( unsigned char *timbres );
#endif

45
audiolib/assert.h Executable file
View File

@ -0,0 +1,45 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __ASSERT_H
#define __ASSERT_H
#ifdef NDEBUG
#define ASSERT(f)
#else
#pragma aux _Assert aborts; /* _Assert will not return */
extern void _Assert( char *strFile, unsigned uLine ); /*prototype */
#define ASSERT(f) \
if (f) \
; \
else \
_Assert( __FILE__, __LINE__ )
#endif
#else
#error Multiple definition of ASSERT()
#endif

540
audiolib/awe32.c Executable file
View File

@ -0,0 +1,540 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: AWE32.C
author: James R. Dose
date: August 23, 1994
Cover functions for calling the AWE32 low-level library.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <conio.h>
#include <string.h>
#include "dpmi.h"
#include "blaster.h"
#include "ctaweapi.h"
#include "awe32.h"
#define _inp inp
#define _outp outp
/* DSP defines */
#define MPU_ACK_OK 0xfe
#define MPU_RESET_CMD 0xff
#define MPU_ENTER_UART 0x3f
static WORD wSBCBaseAddx; /* Sound Blaster base address */
static WORD wEMUBaseAddx; /* EMU8000 subsystem base address */
static WORD wMpuBaseAddx; /* MPU401 base address */
static unsigned short NoteFlags[ 128 ];
/* macros */
#define SBCPort( x ) ( ( x ) + wSBCBaseAddx )
#define MPUPort( x ) ( ( x ) + wMpuBaseAddx )
static SOUND_PACKET spSound =
{
0
};
static LONG lBankSizes[ MAXBANKS ] =
{
0
};
unsigned SetES( void );
#pragma aux SetES = \
"xor eax, eax" \
"mov ax, es" \
"mov bx, ds" \
"mov es, bx" \
modify [ eax ebx ];
void RestoreES( unsigned num );
#pragma aux RestoreES = \
"mov es, ax" \
parm [ eax ];
int AWE32_ErrorCode = AWE32_Ok;
#define AWE32_SetErrorCode( status ) \
AWE32_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: AWE32_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *AWE32_ErrorString
(
int ErrorNumber
)
{
char *ErrorString;
switch( ErrorNumber )
{
case AWE32_Warning :
case AWE32_Error :
ErrorString = AWE32_ErrorString( AWE32_ErrorCode );
break;
case AWE32_Ok :
ErrorString = "AWE32 ok.";
break;
case AWE32_SoundBlasterError :
ErrorString = BLASTER_ErrorString( BLASTER_Error );
break;
case AWE32_NotDetected :
ErrorString = "Could not detect AWE32.";
break;
case AWE32_UnableToInitialize :
ErrorString = "Unable to initialize AWE32.";
case AWE32_MPU401Error :
ErrorString = "MPU-401 initialization failed in AWE32.";
break;
case AWE32_DPMI_Error :
ErrorString = "DPMI Error in AWE32.";
break;
default :
ErrorString = "Unknown AWE32 error code.";
break;
}
return( ErrorString );
}
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define AWE32_LockStart AWE32_NoteOff
void AWE32_NoteOff
(
int channel,
int key,
int velocity
)
{
unsigned temp;
temp = SetES();
awe32NoteOff( channel, key, velocity );
RestoreES( temp );
NoteFlags[ key ] ^= ( 1 << channel );
}
void AWE32_NoteOn
(
int channel,
int key,
int velocity
)
{
unsigned temp;
temp = SetES();
awe32NoteOn( channel, key, velocity );
RestoreES( temp );
NoteFlags[ key ] |= ( 1 << channel );
}
void AWE32_PolyAftertouch
(
int channel,
int key,
int pressure
)
{
unsigned temp;
temp = SetES();
awe32PolyKeyPressure( channel, key, pressure );
RestoreES( temp );
}
void AWE32_ChannelAftertouch
(
int channel,
int pressure
)
{
unsigned temp;
temp = SetES();
awe32ChannelPressure( channel, pressure );
RestoreES( temp );
}
void AWE32_ControlChange
(
int channel,
int number,
int value
)
{
unsigned temp;
int i;
unsigned channelmask;
temp = SetES();
if ( number == 0x7b )
{
channelmask = 1 << channel;
for( i = 0; i < 128; i++ )
{
if ( NoteFlags[ i ] & channelmask )
{
awe32NoteOff( channel, i, 0 );
NoteFlags[ i ] ^= channelmask;
}
}
}
else
{
awe32Controller( channel, number, value );
}
RestoreES( temp );
}
void AWE32_ProgramChange
(
int channel,
int program
)
{
unsigned temp;
temp = SetES();
awe32ProgramChange( channel, program );
RestoreES( temp );
}
void AWE32_PitchBend
(
int channel,
int lsb,
int msb
)
{
unsigned temp;
temp = SetES();
awe32PitchBend( channel, lsb, msb );
RestoreES( temp );
}
/*---------------------------------------------------------------------
Function: AWE32_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void AWE32_LockEnd
(
void
)
{
}
/*
static int InitMPU
(
void
)
{
volatile DWORD dwCount;
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
_outp(MPUPort(1), MPU_RESET_CMD);
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
_inp(MPUPort(0));
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
_outp(MPUPort(1), MPU_RESET_CMD);
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
_inp(MPUPort(0));
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
_outp(MPUPort(1), MPU_ENTER_UART);
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
if (!dwCount) return TRUE;
if (_inp(MPUPort(0)) != MPU_ACK_OK) return TRUE;
// mask MPU-401 interrupt
_outp(SBCPort(0x4), 0x83);
_outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
return FALSE;
}
*/
/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
/*³ ShutdownMPU ³*/
/*³ Cleans up Sound Blaster to normal state. ³*/
/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
static void ShutdownMPU
(
void
)
{
volatile DWORD dwCount;
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
_outp(MPUPort(1), MPU_RESET_CMD);
for (dwCount=0; dwCount<0x2000; dwCount++) ;
_inp(MPUPort(0));
for (dwCount=0; dwCount<0x2000; dwCount++) ;
dwCount = 0x2000;
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
_outp(MPUPort(1), MPU_RESET_CMD);
for (dwCount=0; dwCount<0x2000; dwCount++) ;
_inp(MPUPort(0));
}
/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
/*³ LoadSBK ³*/
/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
static void LoadSBK
(
void
)
{
/* use embeded preset objects */
spSound.bank_no = 0; /* load as Bank 0 */
spSound.total_banks = 1; /* use 1 bank first */
lBankSizes[ 0 ] = 0; /* ram is not needed */
spSound.banksizes = lBankSizes;
awe32DefineBankSizes( &spSound );
awe32SoundPad.SPad1 = awe32SPad1Obj;
awe32SoundPad.SPad2 = awe32SPad2Obj;
awe32SoundPad.SPad3 = awe32SPad3Obj;
awe32SoundPad.SPad4 = awe32SPad4Obj;
awe32SoundPad.SPad5 = awe32SPad5Obj;
awe32SoundPad.SPad6 = awe32SPad6Obj;
awe32SoundPad.SPad7 = awe32SPad7Obj;
}
int AWE32_Init
(
void
)
{
int status;
BLASTER_CONFIG Blaster;
wSBCBaseAddx = 0x220;
wEMUBaseAddx = 0x620;
wMpuBaseAddx = 0x330;
status = BLASTER_GetCardSettings( &Blaster );
if ( status != BLASTER_Ok )
{
status = BLASTER_GetEnv( &Blaster );
if ( status != BLASTER_Ok )
{
AWE32_SetErrorCode( AWE32_SoundBlasterError );
return( AWE32_Error );
}
}
wSBCBaseAddx = Blaster.Address;
if ( wSBCBaseAddx == UNDEFINED )
{
wSBCBaseAddx = 0x220;
}
wMpuBaseAddx = Blaster.Midi;
if ( wMpuBaseAddx == UNDEFINED )
{
wMpuBaseAddx = 0x330;
}
wEMUBaseAddx = Blaster.Emu;
if ( wEMUBaseAddx <= 0 )
{
wEMUBaseAddx = wSBCBaseAddx + 0x400;
}
status = awe32Detect( wEMUBaseAddx );
if ( status )
{
AWE32_SetErrorCode( AWE32_NotDetected );
return( AWE32_Error );
}
status = awe32InitHardware();
if ( status )
{
AWE32_SetErrorCode( AWE32_UnableToInitialize );
return( AWE32_Error );
}
status = awe32InitMIDI();
if ( status )
{
AWE32_Shutdown();
AWE32_SetErrorCode( AWE32_MPU401Error )
return( AWE32_Error );
}
/*
status = InitMPU();
if ( status )
{
ShutdownMPU();
status = InitMPU();
if ( status )
{
ShutdownMPU();
status = InitMPU();
if ( status )
{
AWE32_Shutdown();
AWE32_SetErrorCode( AWE32_MPU401Error )
return( AWE32_Error );
}
}
}
*/
status = DPMI_LockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
status |= DPMI_Lock( wSBCBaseAddx );
status |= DPMI_Lock( wEMUBaseAddx );
status |= DPMI_Lock( wMpuBaseAddx );
status |= DPMI_Lock( spSound );
status |= DPMI_Lock( lBankSizes );
status |= DPMI_LockMemory( NoteFlags, sizeof( NoteFlags ) );
// Lock awe32 library
status = DPMI_LockMemoryRegion( __midieng_code, __midieng_ecode );
status = DPMI_LockMemoryRegion( __midieng_code(), __midieng_ecode() );
status = DPMI_LockMemoryRegion( __nrpn_code, __nrpn_ecode );
status = DPMI_LockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
status = DPMI_LockMemoryRegion( &__midivar_data, &__midivar_edata );
status = DPMI_LockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
status = DPMI_LockMemoryRegion( &__embed_data, &__embed_edata );
if ( status != DPMI_Ok )
{
ShutdownMPU();
awe32Terminate();
AWE32_SetErrorCode( AWE32_DPMI_Error );
return( AWE32_Error );
}
// Set the number of voices to use to 32
awe32NumG = 32;
awe32TotalPatchRam(&spSound);
LoadSBK();
awe32InitMIDI();
awe32InitNRPN();
memset( NoteFlags, 0, sizeof( NoteFlags ) );
return( AWE32_Ok );
}
void AWE32_Shutdown
(
void
)
{
ShutdownMPU();
awe32Terminate();
DPMI_UnlockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
DPMI_Unlock( wSBCBaseAddx );
DPMI_Unlock( wEMUBaseAddx );
DPMI_Unlock( wMpuBaseAddx );
DPMI_Unlock( spSound );
DPMI_Unlock( lBankSizes );
DPMI_UnlockMemory( NoteFlags, sizeof( NoteFlags ) );
// Unlock awe32 library
DPMI_UnlockMemoryRegion( __midieng_code, __midieng_ecode );
DPMI_UnlockMemoryRegion( __midieng_code(), __midieng_ecode() );
DPMI_UnlockMemoryRegion( __nrpn_code, __nrpn_ecode );
DPMI_UnlockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
DPMI_UnlockMemoryRegion( &__midivar_data, &__midivar_edata );
DPMI_UnlockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
DPMI_UnlockMemoryRegion( &__embed_data, &__embed_edata );
}

58
audiolib/awe32.h Executable file
View File

@ -0,0 +1,58 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: AWE32.H
author: James R. Dose
date: August 23, 1994
Public header for AWE32.C Cover functions for calling the
AWE32 low-level library.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __AWE32_H
#define __AWE32_H
enum AWE32_ERRORS
{
AWE32_Warning = -2,
AWE32_Error = -1,
AWE32_Ok = 0,
AWE32_SoundBlasterError,
AWE32_NotDetected,
AWE32_UnableToInitialize,
AWE32_MPU401Error,
AWE32_DPMI_Error
};
char *AWE32_ErrorString( int ErrorNumber );
int AWE32_Init( void );
void AWE32_Shutdown( void );
void AWE32_NoteOff( int channel, int key, int velocity );
void AWE32_NoteOn( int channel, int key, int velocity );
void AWE32_PolyAftertouch( int channel, int key, int pressure );
void AWE32_ChannelAftertouch( int channel, int pressure );
void AWE32_ControlChange( int channel, int number, int value );
void AWE32_ProgramChange( int channel, int program );
void AWE32_PitchBend( int channel, int lsb, int msb );
#endif

2330
audiolib/blaster.c Executable file

File diff suppressed because it is too large Load Diff

148
audiolib/blaster.h Executable file
View File

@ -0,0 +1,148 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: BLASTER.H
author: James R. Dose
date: February 4, 1994
Public header for BLASTER.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __BLASTER_H
#define __BLASTER_H
typedef struct
{
unsigned Address;
unsigned Type;
unsigned Interrupt;
unsigned Dma8;
unsigned Dma16;
unsigned Midi;
unsigned Emu;
} BLASTER_CONFIG;
extern BLASTER_CONFIG BLASTER_Config;
extern int BLASTER_DMAChannel;
#define UNDEFINED -1
enum BLASTER_ERRORS
{
BLASTER_Warning = -2,
BLASTER_Error = -1,
BLASTER_Ok = 0,
BLASTER_EnvNotFound,
BLASTER_AddrNotSet,
BLASTER_DMANotSet,
BLASTER_DMA16NotSet,
BLASTER_InvalidParameter,
BLASTER_CardNotReady,
BLASTER_NoSoundPlaying,
BLASTER_InvalidIrq,
BLASTER_UnableToSetIrq,
BLASTER_DmaError,
BLASTER_NoMixer,
BLASTER_DPMI_Error,
BLASTER_OutOfMemory
};
enum BLASTER_Types
{
SB = 1,
SBPro = 2,
SB20 = 3,
SBPro2 = 4,
SB16 = 6
};
#define BLASTER_MinCardType SB
#define BLASTER_MaxCardType SB16
#define STEREO 1
#define SIXTEEN_BIT 2
#define MONO_8BIT 0
#define STEREO_8BIT ( STEREO )
#define MONO_16BIT ( SIXTEEN_BIT )
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
#define BLASTER_MaxMixMode STEREO_16BIT
#define MONO_8BIT_SAMPLE_SIZE 1
#define MONO_16BIT_SAMPLE_SIZE 2
#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
#define BLASTER_DefaultSampleRate 11000
#define BLASTER_DefaultMixMode MONO_8BIT
#define BLASTER_MaxIrq 15
char *BLASTER_ErrorString( int ErrorNumber );
void BLASTER_EnableInterrupt( void );
void BLASTER_DisableInterrupt( void );
int BLASTER_WriteDSP( unsigned data );
int BLASTER_ReadDSP( void );
int BLASTER_ResetDSP( void );
int BLASTER_GetDSPVersion( void );
void BLASTER_SpeakerOn( void );
void BLASTER_SpeakerOff( void );
void BLASTER_SetPlaybackRate( unsigned rate );
unsigned BLASTER_GetPlaybackRate( void );
int BLASTER_SetMixMode( int mode );
void BLASTER_StopPlayback( void );
int BLASTER_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
int BLASTER_GetCurrentPos( void );
int BLASTER_DSP1xx_BeginPlayback( int length );
int BLASTER_DSP2xx_BeginPlayback( int length );
int BLASTER_DSP4xx_BeginPlayback( int length );
int BLASTER_BeginBufferedRecord( char *BufferStart, int BufferSize,
int NumDivisions, unsigned SampleRate, int MixMode,
void ( *CallBackFunc )( void ) );
int BLASTER_BeginBufferedPlayback( char *BufferStart,
int BufferSize, int NumDivisions, unsigned SampleRate,
int MixMode, void ( *CallBackFunc )( void ) );
void BLASTER_WriteMixer( int reg, int data );
int BLASTER_ReadMixer( int reg );
int BLASTER_GetVoiceVolume( void );
int BLASTER_SetVoiceVolume( int volume );
int BLASTER_GetMidiVolume( void );
int BLASTER_SetMidiVolume( int volume );
int BLASTER_CardHasMixer( void );
void BLASTER_SaveVoiceVolume( void );
void BLASTER_RestoreVoiceVolume( void );
void BLASTER_SaveMidiVolume( void );
void BLASTER_RestoreMidiVolume( void );
int BLASTER_GetEnv( BLASTER_CONFIG *Config );
int BLASTER_SetCardSettings( BLASTER_CONFIG Config );
int BLASTER_GetCardSettings( BLASTER_CONFIG *Config );
int BLASTER_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
void BLASTER_SetCallBack( void ( *func )( void ) );
void BLASTER_SetupWaveBlaster( void );
void BLASTER_ShutdownWaveBlaster( void );
int BLASTER_Init( void );
void BLASTER_Shutdown( void );
void BLASTER_UnlockMemory( void );
int BLASTER_LockMemory( void );
#endif

352
audiolib/ctaweapi.h Executable file
View File

@ -0,0 +1,352 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/****************************************************************************\
* *
* CTAWEAPI.H SB AWE32 DOS API header *
* *
* (C) Copyright Creative Technology Ltd. 1992-94. All rights reserved *
* worldwide. *
* *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
* PURPOSE. *
* *
* You have a royalty-free right to use, modify, reproduce and *
* distribute the Sample Files (and/or any modified version) in *
* any way you find useful, provided that you agree to *
* the Creative's Software Licensing Aggreement and you also agree that *
* Creative has no warranty obligations or liability for any Sample Files. *
* *
\****************************************************************************/
/****************************************************************************\
* File name : CTAWEAPI.H *
* *
* Programmer : Creative SB AWE32 Team *
* Creative Technology Ltd, 1994. All rights reserved. *
* *
* Version : 2.0b *
* *
\****************************************************************************/
#ifndef _CTAWEAPI
#define _CTAWEAPI
#define MAXBANKS 64 /* maximum number of banks */
#define MAXNRPN 32 /* maximum number of NRPN */
#if defined(__FLAT__) || defined(__HIGHC__) || defined(DOS386)
#define PACKETSIZE 8192 /* packet size for 32bit libraries */
#else
#define PACKETSIZE 512 /* packet size for real mode libraries */
#endif
#if defined(__FLAT__)
#define NEAR
#define FAR
#endif
#if defined(__SC__)
#pragma pack(1)
#if defined(DOS386)
#define NEAR
#define FAR
#endif
#endif
#if defined(__WATCOMC__)
#pragma pack(1)
#endif
#if defined(__HIGHC__)
#define NEAR
#define FAR
#define PASCAL _DCC((_DEFAULT_CALLING_CONVENTION|_CALLEE_POPS_STACK) & \
~ (_REVERSE_PARMS|_OVERLOADED))
#pragma Push_align_members(1)
#pragma Global_aliasing_convention("_%r")
#endif
typedef int BOOL;
#define FALSE 0
#define TRUE 1
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef short int SHORT;
typedef unsigned int UINT;
typedef signed long LONG;
#ifndef FAR
#define FAR __far
#endif
#ifndef HUGE
#define HUGE __huge
#endif
#ifndef PASCAL
#define PASCAL __pascal
#endif
typedef void FAR* LPVOID;
typedef BYTE FAR* LPBYTE;
typedef WORD FAR* LPWORD;
typedef DWORD FAR* LPDWORD;
#define LOBYTE(w) ((BYTE)(w))
#define HIBYTE(w) ((BYTE)(((UINT)(w) >> 8) & 0xFF))
#define LOWORD(l) ((WORD)(DWORD)(l))
#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
#if defined(__cplusplus)
extern "C" {
#endif
/* Start of modules */
extern int* __midieng_code(void);
extern int* __hardware_code(void);
extern int* __sbkload_code(void);
extern int* __nrpn_code(void);
extern int __midivar_data;
extern int __nrpnvar_data;
extern int __embed_data;
typedef char SCRATCH[702];
typedef char SOUNDFONT[124];
typedef char GCHANNEL[20];
typedef char MIDICHANNEL[32];
typedef char NRPNCHANNEL[96];
typedef struct {
SHORT bank_no; /* Slot number being used */
SHORT total_banks; /* Total number of banks */
LONG FAR* banksizes; /* Pointer to a list of bank sizes */
LONG file_size; /* exact size of the sound font file */
char FAR* data; /* Address of buffer of size >= PACKETSIZE */
char FAR* presets; /* Allocated memory for preset data */
LONG total_patch_ram; /* Total patch ram available */
SHORT no_sample_packets;/* Number of packets of sound sample to stream */
LONG sample_seek; /* Start file location of sound sample */
LONG preset_seek; /* Address of preset_seek location */
LONG preset_read_size; /* Number of bytes from preset_seek to allocate and read */
LONG preset_size; /* Preset actual size */
} SOUND_PACKET;
typedef struct {
SHORT tag; /* Must be 0x100 or 0x101 */
SHORT preset_size; /* Preset table of this size is required */
SHORT no_wave_packets; /* Number of packets of Wave sample to stream. */
LONG reserved;
SHORT bank_no; /* bank number */
char FAR* data; /* Address of packet of size PACKETSIZE */
char FAR* presets; /* Allocated memory for preset data */
LONG sample_size; /* Sample size, i.e. number of samples */
LONG samples_per_sec; /* Samples per second */
SHORT bits_per_sample; /* Bits per sample, 8 or 16 */
SHORT no_channels; /* Number of channels, 1=mono, 2=stereo */
SHORT looping; /* Looping? 0=no, 1=yes */
LONG startloop; /* if looping, then these are the addresses */
LONG endloop;
SHORT release; /* release time, 0=24ms, 8191=23.78s */
} WAVE_PACKET;
typedef struct {
LPBYTE SPad1;
LPBYTE SPad2;
LPBYTE SPad3;
LPBYTE SPad4;
LPBYTE SPad5;
LPBYTE SPad6;
LPBYTE SPad7;
} SOUNDPAD;
/* AWE32 variables */
extern WORD awe32NumG;
extern WORD awe32BaseAddx;
extern DWORD awe32DramSize;
/* MIDI variables */
extern SCRATCH awe32Scratch;
extern SOUNDFONT awe32SFont[4];
extern GCHANNEL awe32GChannel[32];
extern MIDICHANNEL awe32MIDIChannel[16];
extern SOUNDPAD awe32SoundPad;
/* NRPN variables */
extern NRPNCHANNEL awe32NRPNChannel[16];
/* SoundFont objects */
extern BYTE awe32SPad1Obj[];
extern BYTE awe32SPad2Obj[];
extern BYTE awe32SPad3Obj[];
extern BYTE awe32SPad4Obj[];
extern BYTE awe32SPad5Obj[];
extern BYTE awe32SPad6Obj[];
extern BYTE awe32SPad7Obj[];
/* AWE register functions */
extern void PASCAL awe32RegW(WORD, WORD);
extern WORD PASCAL awe32RegRW(WORD);
extern void PASCAL awe32RegDW(WORD, DWORD);
extern DWORD PASCAL awe32RegRDW(WORD);
/* MIDI support functions */
extern WORD PASCAL awe32InitMIDI(void);
extern WORD PASCAL awe32NoteOn(WORD, WORD, WORD);
extern WORD PASCAL awe32NoteOff(WORD, WORD, WORD);
extern WORD PASCAL awe32ProgramChange(WORD, WORD);
extern WORD PASCAL awe32Controller(WORD, WORD, WORD);
extern WORD PASCAL awe32PolyKeyPressure(WORD, WORD, WORD);
extern WORD PASCAL awe32ChannelPressure(WORD, WORD);
extern WORD PASCAL awe32PitchBend(WORD, WORD, WORD);
extern WORD PASCAL awe32Sysex(WORD, LPBYTE, WORD);
extern WORD PASCAL __awe32NoteOff(WORD, WORD, WORD, WORD);
extern WORD PASCAL __awe32IsPlaying(WORD, WORD, WORD, WORD);
/* NRPN support functions */
extern WORD PASCAL awe32InitNRPN(void);
/* Hardware support functions */
extern WORD PASCAL awe32Detect(WORD);
extern WORD PASCAL awe32InitHardware(void);
extern WORD PASCAL awe32Terminate(void);
/* SoundFont support functions */
extern WORD PASCAL awe32TotalPatchRam(SOUND_PACKET FAR*);
extern WORD PASCAL awe32DefineBankSizes(SOUND_PACKET FAR*);
extern WORD PASCAL awe32SFontLoadRequest(SOUND_PACKET FAR*);
extern WORD PASCAL awe32StreamSample(SOUND_PACKET FAR*);
extern WORD PASCAL awe32SetPresets(SOUND_PACKET FAR*);
extern WORD PASCAL awe32ReleaseBank(SOUND_PACKET FAR*);
extern WORD PASCAL awe32ReleaseAllBanks(SOUND_PACKET FAR*);
extern WORD PASCAL awe32WPLoadRequest(WAVE_PACKET FAR*);
extern WORD PASCAL awe32WPLoadWave(WAVE_PACKET FAR*);
extern WORD PASCAL awe32WPStreamWave(WAVE_PACKET FAR*);
extern WORD PASCAL awe32WPBuildSFont(WAVE_PACKET FAR*);
/* End of modules */
extern int* __midieng_ecode(void);
extern int* __hardware_ecode(void);
extern int* __sbkload_ecode(void);
extern int* __nrpn_ecode(void);
extern int __midivar_edata;
extern int __nrpnvar_edata;
extern int __embed_edata;
#if defined(__cplusplus)
}
#endif
#if defined(__SC__)
#pragma pack()
#endif
#if defined(__HIGHC__)
#pragma Pop_align_members
#pragma Global_aliasing_convention()
#pragma Alias(awe32RegW,"AWE32REGW")
#pragma Alias(awe32RegRW,"AWE32REGRW")
#pragma Alias(awe32RegDW,"AWE32REGDW")
#pragma Alias(awe32RegRDW,"AWE32REGRDW")
#pragma Alias(awe32InitMIDI,"AWE32INITMIDI")
#pragma Alias(awe32NoteOn,"AWE32NOTEON")
#pragma Alias(awe32NoteOff,"AWE32NOTEOFF")
#pragma Alias(awe32ProgramChange,"AWE32PROGRAMCHANGE")
#pragma Alias(awe32Controller,"AWE32CONTROLLER")
#pragma Alias(awe32PolyKeyPressure,"AWE32POLYKEYPRESSURE")
#pragma Alias(awe32ChannelPressure,"AWE32CHANNELPRESSURE")
#pragma Alias(awe32PitchBend,"AWE32PITCHBEND")
#pragma Alias(awe32Sysex,"AWE32SYSEX")
#pragma Alias(__awe32NoteOff,"__AWE32NOTEOFF")
#pragma Alias(__awe32IsPlaying,"__AWE32ISPLAYING")
#pragma Alias(awe32InitNRPN,"AWE32INITNRPN")
#pragma Alias(awe32Detect,"AWE32DETECT")
#pragma Alias(awe32InitHardware,"AWE32INITHARDWARE")
#pragma Alias(awe32Terminate,"AWE32TERMINATE")
#pragma Alias(awe32TotalPatchRam,"AWE32TOTALPATCHRAM")
#pragma Alias(awe32DefineBankSizes,"AWE32DEFINEBANKSIZES")
#pragma Alias(awe32SFontLoadRequest,"AWE32SFONTLOADREQUEST")
#pragma Alias(awe32StreamSample,"AWE32STREAMSAMPLE")
#pragma Alias(awe32SetPresets,"AWE32SETPRESETS")
#pragma Alias(awe32ReleaseBank,"AWE32RELEASEBANK")
#pragma Alias(awe32ReleaseAllBanks,"AWE32RELEASEALLBANKS")
#pragma Alias(awe32WPLoadRequest,"AWE32WPLOADREQUEST")
#pragma Alias(awe32WPLoadWave,"AWE32WPLOADWAVE")
#pragma Alias(awe32WPStreamWave,"AWE32WPSTREAMWAVE")
#pragma Alias(awe32WPBuildSFont,"AWE32WPBUILDSFONT")
#endif
#if defined(__WATCOMC__)
#pragma pack()
#pragma aux awe32NumG "_*"
#pragma aux awe32BaseAddx "_*"
#pragma aux awe32DramSize "_*"
#pragma aux awe32Scratch "_*"
#pragma aux awe32SFont "_*"
#pragma aux awe32GChannel "_*"
#pragma aux awe32MIDIChannel "_*"
#pragma aux awe32SoundPad "_*"
#pragma aux awe32NRPNChannel "_*"
#pragma aux awe32SPad1Obj "_*"
#pragma aux awe32SPad2Obj "_*"
#pragma aux awe32SPad3Obj "_*"
#pragma aux awe32SPad4Obj "_*"
#pragma aux awe32SPad5Obj "_*"
#pragma aux awe32SPad6Obj "_*"
#pragma aux awe32SPad7Obj "_*"
#pragma aux __midieng_code "_*"
#pragma aux __midieng_ecode "_*"
#pragma aux __hardware_code "_*"
#pragma aux __hardware_ecode "_*"
#pragma aux __sbkload_code "_*"
#pragma aux __sbkload_ecode "_*"
#pragma aux __nrpn_code "_*"
#pragma aux __nrpn_ecode "_*"
#pragma aux __midivar_data "_*"
#pragma aux __midivar_edata "_*"
#pragma aux __nrpnvar_data "_*"
#pragma aux __nrpnvar_edata "_*"
#pragma aux __embed_data "_*"
#pragma aux __embed_edata "_*"
#endif
#endif /* _CTAWEAPI */

251
audiolib/debugio.c Executable file
View File

@ -0,0 +1,251 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "debugio.h"
static unsigned short disp_offset = 160 * 24;
static void myutoa( unsigned num, char *string, int radix );
static void myitoa( int num, char *string, int radix );
void DB_SetXY
(
int x,
int y
)
{
disp_offset = ( x * 2 ) + ( y * 160 );
}
void DB_PutChar
(
char ch
)
{
int j;
char *disp_start = (char *)( 0xb0000 );
if ( disp_offset >= 160 * 24 )
{
for ( j = 160; j < 160 * 24; j += 2 )
{
*( disp_start + j - 160 ) = *( disp_start + j );
}
disp_offset = 160 * 23;
for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
if ( ch >= 32 )
{
*( disp_start + disp_offset ) = ch;
disp_offset = disp_offset + 2;
}
if ( ch == '\r' )
{
disp_offset = disp_offset / 160;
disp_offset = disp_offset * 160;
}
if ( ch == '\n' )
{
disp_offset = disp_offset + 160;
if ( disp_offset < 160 * 24 )
{
for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
160 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
}
}
int DB_PrintString
(
char *string
)
{
int count;
char *ptr;
ptr = string;
count = 0;
while ( *ptr )
{
DB_PutChar( *ptr );
count++;
ptr++;
}
return( count );
}
static void myutoa
(
unsigned num,
char *string,
int radix
)
{
int val;
int length;
int pos;
char temp[ 100 ];
length = 0;
do
{
val = num % radix;
if ( val < 10 )
{
temp[ length ] = '0' + val;
}
else
{
temp[ length ] = 'A' + val - 10;
}
num /= radix;
length++;
}
while( num > 0 );
pos = 0;
while( length > 0 )
{
length--;
string[ length ] = temp[ pos ];
pos++;
}
string[ pos ] = 0;
}
static void myitoa
(
int num,
char *string,
int radix
)
{
if ( num < 0 )
{
*string++ = '-';
num = -num;
}
myutoa( num, string, radix );
}
int DB_PrintNum
(
int number
)
{
char string[ 100 ];
int count;
myitoa( number, &string[ 0 ], 10 );
count = DB_PrintString( &string[ 0 ] );
return( count );
}
int DB_PrintUnsigned
(
unsigned long number,
int radix
)
{
char string[ 100 ];
int count;
myutoa( number, &string[ 0 ], radix );
count = DB_PrintString( &string[ 0 ] );
return( count );
}
int DB_printf
(
char *fmt,
...
)
{
va_list argptr;
int count;
char *ptr;
va_start( argptr, fmt );
ptr = fmt;
count = 0;
while( *ptr != 0 )
{
if ( *ptr == '%' )
{
ptr++;
switch( *ptr )
{
case 0 :
return( EOF );
break;
case 'd' :
count += DB_PrintNum( va_arg( argptr, int ) );
break;
case 's' :
count += DB_PrintString( va_arg( argptr, char * ) );
break;
case 'u' :
count += DB_PrintUnsigned( va_arg( argptr, int ), 10 );
break;
case 'x' :
case 'X' :
count += DB_PrintUnsigned( va_arg( argptr, int ), 16 );
break;
}
ptr++;
}
else
{
DB_PutChar( *ptr );
count++;
ptr++;
}
}
va_end( argptr );
return( count );
}

30
audiolib/debugio.h Executable file
View File

@ -0,0 +1,30 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __DEBUGIO_H
#define __DEBUGIO_H
void DB_SetXY( int x, int y );
void DB_PutChar( char ch );
int DB_PrintString( char *string );
int DB_PrintNum( int number );
int DB_PrintUnsigned( unsigned long number, int radix );
int DB_printf( char *fmt, ... );
#endif

379
audiolib/dma.c Executable file
View File

@ -0,0 +1,379 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: DMA.C
author: James R. Dose
date: February 4, 1994
Low level routines to for programming the DMA controller for 8 bit
and 16 bit transfers.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include "dma.h"
#define DMA_MaxChannel 7
#define VALID ( 1 == 1 )
#define INVALID ( !VALID )
#define BYTE 0
#define WORD 1
typedef struct
{
int Valid;
int Width;
int Mask;
int Mode;
int Clear;
int Page;
int Address;
int Length;
} DMA_PORT;
static const DMA_PORT DMA_PortInfo[ DMA_MaxChannel + 1 ] =
{
{ VALID, BYTE, 0xA, 0xB, 0xC, 0x87, 0x0, 0x1 },
{ VALID, BYTE, 0xA, 0xB, 0xC, 0x83, 0x2, 0x3 },
{ INVALID, BYTE, 0xA, 0xB, 0xC, 0x81, 0x4, 0x5 },
{ VALID, BYTE, 0xA, 0xB, 0xC, 0x82, 0x6, 0x7 },
{ INVALID, WORD, 0xD4, 0xD6, 0xD8, 0x8F, 0xC0, 0xC2 },
{ VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8B, 0xC4, 0xC6 },
{ VALID, WORD, 0xD4, 0xD6, 0xD8, 0x89, 0xC8, 0xCA },
{ VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8A, 0xCC, 0xCE },
};
int DMA_ErrorCode = DMA_Ok;
#define DMA_SetErrorCode( status ) \
DMA_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: DMA_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *DMA_ErrorString
(
int ErrorNumber
)
{
char *ErrorString;
switch( ErrorNumber )
{
case DMA_Error :
ErrorString = DMA_ErrorString( DMA_ErrorCode );
break;
case DMA_Ok :
ErrorString = "DMA channel ok.";
break;
case DMA_ChannelOutOfRange :
ErrorString = "DMA channel out of valid range.";
break;
case DMA_InvalidChannel :
ErrorString = "Unsupported DMA channel.";
break;
default :
ErrorString = "Unknown DMA error code.";
break;
}
return( ErrorString );
}
/*---------------------------------------------------------------------
Function: DMA_VerifyChannel
Verifies whether a DMA channel is available to transfer data.
---------------------------------------------------------------------*/
int DMA_VerifyChannel
(
int channel
)
{
int status;
int Error;
status = DMA_Ok;
Error = DMA_Ok;
if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
{
Error = DMA_ChannelOutOfRange;
status = DMA_Error;
}
else if ( DMA_PortInfo[ channel ].Valid == INVALID )
{
Error = DMA_InvalidChannel;
status = DMA_Error;
}
DMA_SetErrorCode( Error );
return( status );
}
/*---------------------------------------------------------------------
Function: DMA_SetupTransfer
Programs the specified DMA channel to transfer data.
---------------------------------------------------------------------*/
int DMA_SetupTransfer
(
int channel,
char *address,
int length,
int mode
)
{
DMA_PORT *Port;
int addr;
int ChannelSelect;
int Page;
int HiByte;
int LoByte;
int TransferLength;
int status;
status = DMA_VerifyChannel( channel );
if ( status == DMA_Ok )
{
Port = &DMA_PortInfo[ channel ];
ChannelSelect = channel & 0x3;
addr = ( int )address;
if ( Port->Width == WORD )
{
Page = ( addr >> 16 ) & 255;
HiByte = ( addr >> 9 ) & 255;
LoByte = ( addr >> 1 ) & 255;
// Convert the length in bytes to the length in words
TransferLength = ( length + 1 ) >> 1;
// The length is always one less the number of bytes or words
// that we're going to send
TransferLength--;
}
else
{
Page = ( addr >> 16 ) & 255;
HiByte = ( addr >> 8 ) & 255;
LoByte = addr & 255;
// The length is always one less the number of bytes or words
// that we're going to send
TransferLength = length - 1;
}
// Mask off DMA channel
outp( Port->Mask, 4 | ChannelSelect );
// Clear flip-flop to lower byte with any data
outp( Port->Clear, 0 );
// Set DMA mode
switch( mode )
{
case DMA_SingleShotRead :
outp( Port->Mode, 0x48 | ChannelSelect );
break;
case DMA_SingleShotWrite :
outp( Port->Mode, 0x44 | ChannelSelect );
break;
case DMA_AutoInitRead :
outp( Port->Mode, 0x58 | ChannelSelect );
break;
case DMA_AutoInitWrite :
outp( Port->Mode, 0x54 | ChannelSelect );
break;
}
// Send address
outp( Port->Address, LoByte );
outp( Port->Address, HiByte );
// Send page
outp( Port->Page, Page );
// Send length
outp( Port->Length, TransferLength );
outp( Port->Length, TransferLength >> 8 );
// enable DMA channel
outp( Port->Mask, ChannelSelect );
}
return( status );
}
/*---------------------------------------------------------------------
Function: DMA_EndTransfer
Ends use of the specified DMA channel.
---------------------------------------------------------------------*/
int DMA_EndTransfer
(
int channel
)
{
DMA_PORT *Port;
int ChannelSelect;
int status;
status = DMA_VerifyChannel( channel );
if ( status == DMA_Ok )
{
Port = &DMA_PortInfo[ channel ];
ChannelSelect = channel & 0x3;
// Mask off DMA channel
outp( Port->Mask, 4 | ChannelSelect );
// Clear flip-flop to lower byte with any data
outp( Port->Clear, 0 );
}
return( status );
}
/*---------------------------------------------------------------------
Function: DMA_GetCurrentPos
Returns the position of the specified DMA transfer.
---------------------------------------------------------------------*/
char *DMA_GetCurrentPos
(
int channel
)
{
DMA_PORT *Port;
unsigned long addr;
int status;
addr = NULL;
status = DMA_VerifyChannel( channel );
if ( status == DMA_Ok )
{
Port = &DMA_PortInfo[ channel ];
if ( Port->Width == WORD )
{
// Get address
addr = inp( Port->Address ) << 1;
addr |= inp( Port->Address ) << 9;
// Get page
addr |= inp( Port->Page ) << 16;
}
else
{
// Get address
addr = inp( Port->Address );
addr |= inp( Port->Address ) << 8;
// Get page
addr |= inp( Port->Page ) << 16;
}
}
return( ( char * )addr );
}
/*---------------------------------------------------------------------
Function: DMA_GetTransferCount
Returns how many bytes are left in the DMA's transfer.
---------------------------------------------------------------------*/
int DMA_GetTransferCount
(
int channel
)
{
DMA_PORT *Port;
int count;
int status;
status = DMA_Ok;
count = 0;
if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
{
status = DMA_ChannelOutOfRange;
}
else if ( DMA_PortInfo[ channel ].Valid == INVALID )
{
status = DMA_InvalidChannel;
}
if ( status == DMA_Ok )
{
Port = &DMA_PortInfo[ channel ];
outp( Port->Clear, 0 );
count = inp( Port->Length );
count += inp( Port->Length ) << 8;
if ( Port->Width == WORD )
{
count <<= 1;
}
}
DMA_SetErrorCode( status );
return( count );
}

83
audiolib/dma.h Executable file
View File

@ -0,0 +1,83 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
file: DMA.H
author: James R. Dose
date: February 4, 1994
Public header file for DMA.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __DMA_H
#define __DMA_H
enum DMA_ERRORS
{
DMA_Error = -1,
DMA_Ok = 0,
DMA_ChannelOutOfRange,
DMA_InvalidChannel
};
enum DMA_Modes
{
DMA_SingleShotRead,
DMA_SingleShotWrite,
DMA_AutoInitRead,
DMA_AutoInitWrite
};
char *DMA_ErrorString
(
int ErrorNumber
);
int DMA_VerifyChannel
(
int channel
);
int DMA_SetupTransfer
(
int channel,
char *address,
int length,
int mode
);
int DMA_EndTransfer
(
int channel
);
char *DMA_GetCurrentPos
(
int channel
);
int DMA_GetTransferCount
(
int channel
);
#endif

250
audiolib/dpmi.c Executable file
View File

@ -0,0 +1,250 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: DPMI.C
author: James R. Dose
date: April 8, 1994
Functions for performing DPMI calls.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <dos.h>
#include <string.h>
#include "dpmi.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
static union REGS Regs;
static struct SREGS SegRegs;
/*---------------------------------------------------------------------
Function: DPMI_GetRealModeVector
Returns the vector of a real mode interrupt.
---------------------------------------------------------------------*/
unsigned long DPMI_GetRealModeVector
(
int num
)
{
unsigned long vector;
Regs.x.eax = 0x0200;
Regs.h.bl = num;
int386( 0x31, &Regs, &Regs );
vector = Regs.w.cx & 0xffff;
vector <<= 16;
vector |= Regs.w.dx & 0xffff;
return( vector );
}
/*---------------------------------------------------------------------
Function: DPMI_SetRealModeVector
Sets the vector of a real mode interrupt.
---------------------------------------------------------------------*/
void DPMI_SetRealModeVector
(
int num,
unsigned long vector
)
{
Regs.x.eax = 0x0201;
Regs.h.bl = num;
Regs.w.dx = vector & 0xffff;
Regs.w.cx = ( vector >> 16 ) & 0xffff;
int386( 0x31, &Regs, &Regs );
}
/*---------------------------------------------------------------------
Function: DPMI_CallRealModeFunction
Performs a call to a real mode function.
---------------------------------------------------------------------*/
int DPMI_CallRealModeFunction
(
dpmi_regs *callregs
)
{
// Setup our registers to call DPMI
Regs.w.ax = 0x0301;
Regs.h.bl = 0;
Regs.h.bh = 0;
Regs.w.cx = 0;
SegRegs.es = FP_SEG( callregs );
Regs.x.edi = FP_OFF( callregs );
// Call Real-mode procedure with Far Return Frame
int386x( 0x31, &Regs, &Regs, &SegRegs );
if ( Regs.x.cflag )
{
return( DPMI_Error );
}
return( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemory
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemory
(
void *address,
unsigned length
)
{
unsigned linear;
// Thanks to DOS/4GW's zero-based flat memory model, converting
// a pointer of any type to a linear address is trivial.
linear = (unsigned) address;
// DPMI Lock Linear Region
Regs.w.ax = 0x600;
// Linear address in BX:CX
Regs.w.bx = (linear >> 16);
Regs.w.cx = (linear & 0xFFFF);
// Length in SI:DI
Regs.w.si = (length >> 16);
Regs.w.di = (length & 0xFFFF);
int386 (0x31, &Regs, &Regs);
// Return 0 if can't lock
if ( Regs.w.cflag )
{
return( DPMI_Error );
}
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemoryRegion
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
return( status );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemory
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemory
(
void *address,
unsigned length
)
{
unsigned linear;
// Thanks to DOS/4GW's zero-based flat memory model, converting
// a pointer of any type to a linear address is trivial.
linear = (unsigned) address;
// DPMI Unlock Linear Region
Regs.w.ax = 0x601;
// Linear address in BX:CX
Regs.w.bx = (linear >> 16);
Regs.w.cx = (linear & 0xFFFF);
// Length in SI:DI
Regs.w.si = (length >> 16);
Regs.w.di = (length & 0xFFFF);
int386 (0x31, &Regs, &Regs);
// Return 0 if can't unlock
if ( Regs.w.cflag )
{
return( DPMI_Error );
}
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemoryRegion
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
return( status );
}

102
audiolib/dpmi.h Executable file
View File

@ -0,0 +1,102 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: DPMI.H
author: James R. Dose
date: March 31, 1994
Inline functions for performing DPMI calls.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __DPMI_H
#define __DPMI_H
enum DPMI_Errors
{
DPMI_Warning = -2,
DPMI_Error = -1,
DPMI_Ok = 0
};
typedef struct
{
unsigned long EDI;
unsigned long ESI;
unsigned long EBP;
unsigned long Reserved;
unsigned long EBX;
unsigned long EDX;
unsigned long ECX;
unsigned long EAX;
unsigned short Flags;
unsigned short ES;
unsigned short DS;
unsigned short FS;
unsigned short GS;
unsigned short IP;
unsigned short CS;
unsigned short SP;
unsigned short SS;
} dpmi_regs;
unsigned long DPMI_GetRealModeVector( int num );
void DPMI_SetRealModeVector( int num, unsigned long vector );
int DPMI_CallRealModeFunction( dpmi_regs *callregs );
int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length );
int DPMI_FreeDOSMemory( int descriptor );
int DPMI_LockMemory( void *address, unsigned length );
int DPMI_LockMemoryRegion( void *start, void *end );
int DPMI_UnlockMemory( void *address, unsigned length );
int DPMI_UnlockMemoryRegion( void *start, void *end );
#define DPMI_Lock( variable ) \
( DPMI_LockMemory( (void *) &( variable ), sizeof( variable ) ) )
#define DPMI_Unlock( variable ) \
( DPMI_UnlockMemory( (void *) &( variable ), sizeof( variable ) ) )
#ifdef PLAT_DOS
#pragma aux DPMI_GetDOSMemory = \
"mov eax, 0100h", \
"add ebx, 15", \
"shr ebx, 4", \
"int 31h", \
"jc DPMI_Exit", \
"movzx eax, ax", \
"shl eax, 4", \
"mov [ esi ], eax", \
"mov [ edi ], edx", \
"sub eax, eax", \
"DPMI_Exit:", \
parm [ esi ] [ edi ] [ ebx ] modify exact [ eax ebx edx ];
#pragma aux DPMI_FreeDOSMemory = \
"mov eax, 0101h", \
"int 31h", \
"jc DPMI_Exit", \
"sub eax, eax", \
"DPMI_Exit:", \
parm [ edx ] modify exact [ eax ];
#endif
#endif

239
audiolib/dsl.c Executable file
View File

@ -0,0 +1,239 @@
#include <stdlib.h>
#include <string.h>
#include "dsl.h"
#include "util.h"
#include "SDL.h"
#include "SDL_mixer.h"
extern volatile int MV_MixPage;
static int DSL_ErrorCode = DSL_Ok;
static int mixer_initialized;
static void ( *_CallBackFunc )( void );
static volatile char *_BufferStart;
static int _BufferSize;
static int _NumDivisions;
static int _SampleRate;
static int _remainder;
static Mix_Chunk *blank;
static unsigned char *blank_buf;
/*
possible todo ideas: cache sdl/sdl mixer error messages.
*/
char *DSL_ErrorString( int ErrorNumber )
{
char *ErrorString;
switch (ErrorNumber) {
case DSL_Warning:
case DSL_Error:
ErrorString = DSL_ErrorString(DSL_ErrorCode);
break;
case DSL_Ok:
ErrorString = "SDL Driver ok.";
break;
case DSL_SDLInitFailure:
ErrorString = "SDL Audio initialization failed.";
break;
case DSL_MixerActive:
ErrorString = "SDL Mixer already initialized.";
break;
case DSL_MixerInitFailure:
ErrorString = "SDL Mixer initialization failed.";
break;
default:
ErrorString = "Unknown SDL Driver error.";
break;
}
return ErrorString;
}
static void DSL_SetErrorCode(int ErrorCode)
{
DSL_ErrorCode = ErrorCode;
}
int DSL_Init( void )
{
DSL_SetErrorCode(DSL_Ok);
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
DSL_SetErrorCode(DSL_SDLInitFailure);
return DSL_Error;
}
return DSL_Ok;
}
void DSL_Shutdown( void )
{
DSL_StopPlayback();
}
static void mixer_callback(int chan, void *stream, int len, void *udata)
{
Uint8 *stptr;
Uint8 *fxptr;
int copysize;
/* len should equal _BufferSize, else this is screwed up */
stptr = (Uint8 *)stream;
if (_remainder > 0) {
copysize = min(len, _remainder);
fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
_BufferSize]);
memcpy(stptr, fxptr+(_BufferSize-_remainder), copysize);
len -= copysize;
_remainder -= copysize;
stptr += copysize;
}
while (len > 0) {
/* new buffer */
_CallBackFunc();
fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
_BufferSize]);
copysize = min(len, _BufferSize);
memcpy(stptr, fxptr, copysize);
len -= copysize;
stptr += copysize;
}
_remainder = len;
}
int DSL_BeginBufferedPlayback( char *BufferStart,
int BufferSize, int NumDivisions, unsigned SampleRate,
int MixMode, void ( *CallBackFunc )( void ) )
{
Uint16 format;
Uint8 *tmp;
int channels;
int chunksize;
if (mixer_initialized) {
DSL_SetErrorCode(DSL_MixerActive);
return DSL_Error;
}
_CallBackFunc = CallBackFunc;
_BufferStart = BufferStart;
_BufferSize = (BufferSize / NumDivisions);
_NumDivisions = NumDivisions;
_SampleRate = SampleRate;
_remainder = 0;
format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16SYS : AUDIO_U8;
channels = (MixMode & STEREO) ? 2 : 1;
/*
23ms is typically ideal (11025,22050,44100)
46ms isn't bad
*/
chunksize = 512;
if (SampleRate >= 16000) chunksize *= 2;
if (SampleRate >= 32000) chunksize *= 2;
/*
// SDL mixer does this already
if (MixMode & SIXTEEN_BIT) chunksize *= 2;
if (MixMode & STEREO) chunksize *= 2;
*/
if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) {
DSL_SetErrorCode(DSL_MixerInitFailure);
return DSL_Error;
}
/*
Mix_SetPostMix(mixer_callback, NULL);
*/
/* have to use a channel because postmix will overwrite the music... */
Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
/* create a dummy sample just to allocate that channel */
blank_buf = (Uint8 *)malloc(4096);
memset(blank_buf, 0, 4096);
blank = Mix_QuickLoad_RAW(blank_buf, 4096);
Mix_PlayChannel(0, blank, -1);
mixer_initialized = 1;
return DSL_Ok;
}
void DSL_StopPlayback( void )
{
if (mixer_initialized) {
Mix_HaltChannel(0);
}
if (blank != NULL) {
Mix_FreeChunk(blank);
}
blank = NULL;
if (blank_buf != NULL) {
free(blank_buf);
}
blank_buf = NULL;
if (mixer_initialized) {
SDL_UnlockAudio(); /* just in case */
Mix_CloseAudio();
}
mixer_initialized = 0;
}
unsigned DSL_GetPlaybackRate( void )
{
return _SampleRate;
}
unsigned long DisableInterrupts( void )
{
SDL_LockAudio();
return 0;
}
void RestoreInterrupts( unsigned long flags )
{
SDL_UnlockAudio();
}

28
audiolib/dsl.h Executable file
View File

@ -0,0 +1,28 @@
#ifndef AUDIOLIB__DSL_H
#define AUDIOLIB__DSL_H
#define MONO_8BIT 0
#define STEREO 1
#define SIXTEEN_BIT 2
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
enum DSL_ERRORS
{
DSL_Warning = -2,
DSL_Error = -1,
DSL_Ok = 0,
DSL_SDLInitFailure,
DSL_MixerActive,
DSL_MixerInitFailure
};
char *DSL_ErrorString( int ErrorNumber );
int DSL_Init( void );
void DSL_StopPlayback( void );
unsigned DSL_GetPlaybackRate( void );
int DSL_BeginBufferedPlayback( char *BufferStart,
int BufferSize, int NumDivisions, unsigned SampleRate,
int MixMode, void ( *CallBackFunc )( void ) );
void DSL_Shutdown( void );
#endif

1376
audiolib/fx_man.c Executable file

File diff suppressed because it is too large Load Diff

135
audiolib/fx_man.h Executable file
View File

@ -0,0 +1,135 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: FX_MAN.H
author: James R. Dose
date: March 17, 1994
Public header for FX_MAN.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __FX_MAN_H
#define __FX_MAN_H
#include "sndcards.h"
typedef struct
{
int MaxVoices;
int MaxSampleBits;
int MaxChannels;
} fx_device;
#define MonoFx 1
#define StereoFx 2
typedef struct
{
unsigned long Address;
unsigned long Type;
unsigned long Interrupt;
unsigned long Dma8;
unsigned long Dma16;
unsigned long Midi;
unsigned long Emu;
} fx_blaster_config;
enum FX_ERRORS
{
FX_Warning = -2,
FX_Error = -1,
FX_Ok = 0,
FX_ASSVersion,
FX_BlasterError,
FX_SoundCardError,
FX_InvalidCard,
FX_MultiVocError,
FX_DPMI_Error
};
enum fx_BLASTER_Types
{
fx_SB = 1,
fx_SBPro = 2,
fx_SB20 = 3,
fx_SBPro2 = 4,
fx_SB16 = 6
};
char *FX_ErrorString( int ErrorNumber );
int FX_SetupCard( int SoundCard, fx_device *device );
int FX_GetBlasterSettings( fx_blaster_config *blaster );
int FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels );
int FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate );
int FX_Shutdown( void );
int FX_SetCallBack( void ( *function )( unsigned long ) );
void FX_SetVolume( int volume );
int FX_GetVolume( void );
void FX_SetReverseStereo( int setting );
int FX_GetReverseStereo( void );
void FX_SetReverb( int reverb );
void FX_SetFastReverb( int reverb );
int FX_GetMaxReverbDelay( void );
int FX_GetReverbDelay( void );
void FX_SetReverbDelay( int delay );
int FX_VoiceAvailable( int priority );
int FX_EndLooping( int handle );
int FX_SetPan( int handle, int vol, int left, int right );
int FX_SetPitch( int handle, int pitchoffset );
int FX_SetFrequency( int handle, int frequency );
int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
int priority, unsigned long callbackval );
int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend,
int pitchoffset, int vol, int left, int right, int priority,
unsigned long callbackval );
int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right,
int priority, unsigned long callbackval );
int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
int pitchoffset, int vol, int left, int right, int priority,
unsigned long callbackval );
int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,
int priority, unsigned long callbackval );
int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
int priority, unsigned long callbackval );
int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate,
int pitchoffset, int vol, int left, int right, int priority,
unsigned long callbackval );
int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart,
char *loopend, unsigned rate, int pitchoffset, int vol, int left,
int right, int priority, unsigned long callbackval );
int FX_Pan3D( int handle, int angle, int distance );
int FX_SoundActive( int handle );
int FX_SoundsPlaying( void );
int FX_StopSound( int handle );
int FX_StopAllSounds( void );
int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
int rate, int pitchoffset, int vol, int left, int right,
int priority, unsigned long callbackval );
int FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
void FX_StopRecord( void );
#endif

290
audiolib/gmtimbre.c Executable file
View File

@ -0,0 +1,290 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
typedef struct
{
unsigned char SAVEK[ 2 ];
unsigned char Level[ 2 ];
unsigned char Env1[ 2 ];
unsigned char Env2[ 2 ];
unsigned char Wave[ 2 ];
unsigned char Feedback;
signed char Transpose;
signed char Velocity;
} TIMBRE;
TIMBRE ADLIB_TimbreBank[ 256 ] =
{
{ { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0 },
{ { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0 },
{ { 49, 33 }, { 73, 0 }, { 242, 242 }, { 85, 118 }, { 0, 0 }, 8, 0 },
{ { 177, 97 }, { 14, 0 }, { 242, 243 }, { 59, 11 }, { 0, 0 }, 6, 0 },
{ { 1, 33 }, { 87, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
{ { 1, 33 }, { 147, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
{ { 33, 54 }, { 128, 14 }, { 162, 241 }, { 1, 213 }, { 0, 0 }, 8, 0 },
{ { 1, 1 }, { 146, 0 }, { 194, 194 }, { 168, 88 }, { 0, 0 }, 10, 0 },
{ { 12, 129 }, { 92, 0 }, { 246, 243 }, { 84, 181 }, { 0, 0 }, 0, 0 },
{ { 7, 17 }, { 151, 128 }, { 246, 245 }, { 50, 17 }, { 0, 0 }, 2, 0 },
{ { 23, 1 }, { 33, 0 }, { 86, 246 }, { 4, 4 }, { 0, 0 }, 2, 0 },
{ { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
{ { 24, 33 }, { 35, 0 }, { 247, 229 }, { 85, 216 }, { 0, 0 }, 0, 0 },
{ { 21, 1 }, { 145, 0 }, { 246, 246 }, { 166, 230 }, { 0, 0 }, 4, 0 },
{ { 69, 129 }, { 89, 128 }, { 211, 163 }, { 130, 227 }, { 0, 0 }, 12, 0 },
{ { 3, 129 }, { 73, 128 }, { 116, 179 }, { 85, 5 }, { 1, 0 }, 4, 0 },
{ { 113, 49 }, { 146, 0 }, { 246, 241 }, { 20, 7 }, { 0, 0 }, 2, 0 },
{ { 114, 48 }, { 20, 0 }, { 199, 199 }, { 88, 8 }, { 0, 0 }, 2, 0 },
{ { 112, 177 }, { 68, 0 }, { 170, 138 }, { 24, 8 }, { 0, 0 }, 4, 0 },
{ { 35, 177 }, { 147, 0 }, { 151, 85 }, { 35, 20 }, { 1, 0 }, 4, 0 },
{ { 97, 177 }, { 19, 128 }, { 151, 85 }, { 4, 4 }, { 1, 0 }, 0, 0 },
{ { 36, 177 }, { 72, 0 }, { 152, 70 }, { 42, 26 }, { 1, 0 }, 12, 0 },
{ { 97, 33 }, { 19, 0 }, { 145, 97 }, { 6, 7 }, { 1, 0 }, 10, 0 },
{ { 33, 161 }, { 19, 137 }, { 113, 97 }, { 6, 7 }, { 0, 0 }, 6, 0 },
{ { 2, 65 }, { 156, 128 }, { 243, 243 }, { 148, 200 }, { 1, 0 }, 12, 0 },
{ { 3, 17 }, { 84, 0 }, { 243, 241 }, { 154, 231 }, { 1, 0 }, 12, 0 },
{ { 35, 33 }, { 95, 0 }, { 241, 242 }, { 58, 248 }, { 0, 0 }, 0, 0 },
{ { 3, 33 }, { 135, 128 }, { 246, 243 }, { 34, 243 }, { 1, 0 }, 6, 0 },
{ { 3, 33 }, { 71, 0 }, { 249, 246 }, { 84, 58 }, { 0, 0 }, 0, 0 },
{ { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
{ { 35, 33 }, { 74, 0 }, { 149, 148 }, { 25, 25 }, { 1, 0 }, 8, 0 },
{ { 9, 132 }, { 161, 128 }, { 32, 209 }, { 79, 248 }, { 0, 0 }, 8, 0 },
{ { 33, 162 }, { 30, 0 }, { 148, 195 }, { 6, 166 }, { 0, 0 }, 2, 0 },
{ { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
{ { 49, 49 }, { 141, 0 }, { 241, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
{ { 49, 50 }, { 91, 0 }, { 81, 113 }, { 40, 72 }, { 0, 0 }, 12, 0 },
{ { 1, 33 }, { 139, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
{ { 1, 33 }, { 137, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
{ { 49, 49 }, { 139, 0 }, { 244, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
{ { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
{ { 49, 33 }, { 21, 0 }, { 221, 86 }, { 19, 38 }, { 1, 0 }, 8, 0 },
{ { 49, 33 }, { 22, 0 }, { 221, 102 }, { 19, 6 }, { 1, 0 }, 8, 0 },
{ { 113, 49 }, { 73, 0 }, { 209, 97 }, { 28, 12 }, { 1, 0 }, 8, 0 },
{ { 33, 35 }, { 77, 128 }, { 113, 114 }, { 18, 6 }, { 1, 0 }, 2, 0 },
{ { 241, 225 }, { 64, 0 }, { 241, 111 }, { 33, 22 }, { 1, 0 }, 2, 0 },
{ { 2, 1 }, { 26, 128 }, { 245, 133 }, { 117, 53 }, { 1, 0 }, 0, 0 },
{ { 2, 1 }, { 29, 128 }, { 245, 243 }, { 117, 244 }, { 1, 0 }, 0, 0 },
{ { 16, 17 }, { 65, 0 }, { 245, 242 }, { 5, 195 }, { 1, 0 }, 2, 0 },
{ { 33, 162 }, { 155, 1 }, { 177, 114 }, { 37, 8 }, { 1, 0 }, 14, 0 },
{ { 161, 33 }, { 152, 0 }, { 127, 63 }, { 3, 7 }, { 1, 1 }, 0, 0 },
{ { 161, 97 }, { 147, 0 }, { 193, 79 }, { 18, 5 }, { 0, 0 }, 10, 0 },
{ { 33, 97 }, { 24, 0 }, { 193, 79 }, { 34, 5 }, { 0, 0 }, 12, 0 },
{ { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
{ { 161, 97 }, { 144, 0 }, { 116, 113 }, { 57, 103 }, { 0, 0 }, 0, 0 },
{ { 113, 114 }, { 87, 0 }, { 84, 122 }, { 5, 5 }, { 0, 0 }, 12, 0 },
{ { 144, 65 }, { 0, 0 }, { 84, 165 }, { 99, 69 }, { 0, 0 }, 8, 0 },
{ { 33, 33 }, { 146, 1 }, { 133, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
{ { 33, 33 }, { 148, 5 }, { 117, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
{ { 33, 97 }, { 148, 0 }, { 118, 130 }, { 21, 55 }, { 0, 0 }, 12, 0 },
{ { 49, 33 }, { 67, 0 }, { 158, 98 }, { 23, 44 }, { 1, 1 }, 2, 0 },
{ { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
{ { 97, 34 }, { 138, 6 }, { 117, 116 }, { 31, 15 }, { 0, 0 }, 8, 0 },
{ { 161, 33 }, { 134, 13 }, { 114, 113 }, { 85, 24 }, { 1, 0 }, 0, 0 },
{ { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
{ { 49, 97 }, { 143, 0 }, { 147, 114 }, { 2, 11 }, { 1, 0 }, 8, 0 },
{ { 49, 97 }, { 142, 0 }, { 147, 114 }, { 3, 9 }, { 1, 0 }, 8, 0 },
{ { 49, 97 }, { 145, 0 }, { 147, 130 }, { 3, 9 }, { 1, 0 }, 10, 0 },
{ { 49, 97 }, { 142, 0 }, { 147, 114 }, { 15, 15 }, { 1, 0 }, 10, 0 },
{ { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
{ { 49, 33 }, { 144, 0 }, { 126, 139 }, { 23, 12 }, { 1, 1 }, 6, 0 },
{ { 49, 50 }, { 129, 0 }, { 117, 97 }, { 25, 25 }, { 1, 0 }, 0, 0 },
{ { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
{ { 225, 225 }, { 31, 0 }, { 133, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
{ { 225, 225 }, { 70, 0 }, { 136, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
{ { 161, 33 }, { 156, 0 }, { 117, 117 }, { 31, 10 }, { 0, 0 }, 2, 0 },
{ { 49, 33 }, { 139, 0 }, { 132, 101 }, { 88, 26 }, { 0, 0 }, 0, 0 },
{ { 225, 161 }, { 76, 0 }, { 102, 101 }, { 86, 38 }, { 0, 0 }, 0, 0 },
{ { 98, 161 }, { 203, 0 }, { 118, 85 }, { 70, 54 }, { 0, 0 }, 0, 0 },
{ { 98, 161 }, { 153, 0 }, { 87, 86 }, { 7, 7 }, { 0, 0 }, 11, 0 },
{ { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
{ { 34, 33 }, { 89, 0 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
{ { 33, 33 }, { 14, 0 }, { 255, 255 }, { 15, 15 }, { 1, 1 }, 0, 0 },
{ { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
{ { 33, 161 }, { 69, 0 }, { 102, 150 }, { 18, 10 }, { 0, 0 }, 0, 0 },
{ { 33, 34 }, { 139, 0 }, { 146, 145 }, { 42, 42 }, { 1, 0 }, 0, 0 },
{ { 162, 97 }, { 158, 64 }, { 223, 111 }, { 5, 7 }, { 0, 0 }, 2, 0 },
{ { 32, 96 }, { 26, 0 }, { 239, 143 }, { 1, 6 }, { 0, 2 }, 0, 0 },
{ { 33, 33 }, { 143, 128 }, { 241, 244 }, { 41, 9 }, { 0, 0 }, 10, 0 },
{ { 119, 161 }, { 165, 0 }, { 83, 160 }, { 148, 5 }, { 0, 0 }, 2, 0 },
{ { 97, 177 }, { 31, 128 }, { 168, 37 }, { 17, 3 }, { 0, 0 }, 10, 0 },
{ { 97, 97 }, { 23, 0 }, { 145, 85 }, { 52, 22 }, { 0, 0 }, 12, 0 },
{ { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
{ { 33, 162 }, { 151, 0 }, { 33, 66 }, { 67, 53 }, { 0, 0 }, 8, 0 },
{ { 161, 33 }, { 28, 0 }, { 161, 49 }, { 119, 71 }, { 1, 1 }, 0, 0 },
{ { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
{ { 161, 33 }, { 21, 0 }, { 17, 207 }, { 71, 7 }, { 1, 0 }, 0, 0 },
{ { 58, 81 }, { 206, 0 }, { 248, 134 }, { 246, 2 }, { 0, 0 }, 2, 0 },
{ { 33, 33 }, { 21, 0 }, { 33, 65 }, { 35, 19 }, { 1, 0 }, 0, 0 },
{ { 6, 1 }, { 91, 0 }, { 116, 165 }, { 149, 114 }, { 0, 0 }, 0, 0 },
{ { 34, 97 }, { 146, 131 }, { 177, 242 }, { 129, 38 }, { 0, 0 }, 12, 0 },
{ { 65, 66 }, { 77, 0 }, { 241, 242 }, { 81, 245 }, { 1, 0 }, 0, 0 },
{ { 97, 163 }, { 148, 128 }, { 17, 17 }, { 81, 19 }, { 1, 0 }, 6, 0 },
{ { 97, 161 }, { 140, 128 }, { 17, 29 }, { 49, 3 }, { 0, 0 }, 6, 0 },
{ { 164, 97 }, { 76, 0 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
{ { 2, 7 }, { 133, 3 }, { 210, 242 }, { 83, 246 }, { 0, 1 }, 0, 0 },
{ { 17, 19 }, { 12, 128 }, { 163, 162 }, { 17, 229 }, { 1, 0 }, 0, 0 },
{ { 17, 17 }, { 6, 0 }, { 246, 242 }, { 65, 230 }, { 1, 2 }, 4, 0 },
{ { 147, 145 }, { 145, 0 }, { 212, 235 }, { 50, 17 }, { 0, 1 }, 8, 0 },
{ { 4, 1 }, { 79, 0 }, { 250, 194 }, { 86, 5 }, { 0, 0 }, 12, 0 },
{ { 33, 34 }, { 73, 0 }, { 124, 111 }, { 32, 12 }, { 0, 1 }, 6, 0 },
{ { 49, 33 }, { 133, 0 }, { 221, 86 }, { 51, 22 }, { 1, 0 }, 10, 0 },
{ { 32, 33 }, { 4, 129 }, { 218, 143 }, { 5, 11 }, { 2, 0 }, 6, 0 },
{ { 5, 3 }, { 106, 128 }, { 241, 195 }, { 229, 229 }, { 0, 0 }, 6, 0 },
{ { 7, 2 }, { 21, 0 }, { 236, 248 }, { 38, 22 }, { 0, 0 }, 10, 0 },
{ { 5, 1 }, { 157, 0 }, { 103, 223 }, { 53, 5 }, { 0, 0 }, 8, 0 },
{ { 24, 18 }, { 150, 0 }, { 250, 248 }, { 40, 229 }, { 0, 0 }, 10, 0 },
{ { 16, 0 }, { 134, 3 }, { 168, 250 }, { 7, 3 }, { 0, 0 }, 6, 0 },
{ { 17, 16 }, { 65, 3 }, { 248, 243 }, { 71, 3 }, { 2, 0 }, 4, 0 },
{ { 1, 16 }, { 142, 0 }, { 241, 243 }, { 6, 2 }, { 2, 0 }, 14, 0 },
{ { 14, 192 }, { 0, 0 }, { 31, 31 }, { 0, 255 }, { 0, 3 }, 14, 0 },
{ { 6, 3 }, { 128, 136 }, { 248, 86 }, { 36, 132 }, { 0, 2 }, 14, 0 },
{ { 14, 208 }, { 0, 5 }, { 248, 52 }, { 0, 4 }, { 0, 3 }, 14, 0 },
{ { 14, 192 }, { 0, 0 }, { 246, 31 }, { 0, 2 }, { 0, 3 }, 14, 0 },
{ { 213, 218 }, { 149, 64 }, { 55, 86 }, { 163, 55 }, { 0, 0 }, 0, 0 },
{ { 53, 20 }, { 92, 8 }, { 178, 244 }, { 97, 21 }, { 2, 0 }, 10, 0 },
{ { 14, 208 }, { 0, 0 }, { 246, 79 }, { 0, 245 }, { 0, 3 }, 14, 0 },
{ { 38, 228 }, { 0, 0 }, { 255, 18 }, { 1, 22 }, { 0, 1 }, 14, 0 },
{ { 0, 0 }, { 0, 0 }, { 243, 246 }, { 240, 201 }, { 0, 2 }, 14, 0 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 52 },
{ { 0, 1 }, { 2, 0 }, { 255, 255 }, { 7, 8 }, { 0, 0 }, 0, 48 },
{ { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 58 },
{ { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 60 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 47 },
{ { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 49 },
{ { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 51 },
{ { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 54 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 57 },
{ { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 72 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 60 },
{ { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 76 },
{ { 14, 7 }, { 10, 93 }, { 228, 245 }, { 228, 229 }, { 3, 1 }, 6, 84 },
{ { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 36 },
{ { 78, 158 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 76 },
{ { 17, 16 }, { 69, 8 }, { 248, 243 }, { 55, 5 }, { 2, 0 }, 8, 84 },
{ { 14, 208 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 83 },
{ { 128, 16 }, { 0, 13 }, { 255, 255 }, { 3, 20 }, { 3, 0 }, 12, 84 },
{ { 14, 7 }, { 8, 81 }, { 248, 244 }, { 66, 228 }, { 0, 3 }, 14, 24 },
{ { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 77 },
{ { 1, 2 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 7, 60 },
{ { 1, 1 }, { 81, 0 }, { 250, 250 }, { 135, 183 }, { 0, 0 }, 6, 65 },
{ { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 59 },
{ { 1, 2 }, { 89, 0 }, { 250, 248 }, { 136, 182 }, { 0, 0 }, 6, 51 },
{ { 1, 0 }, { 0, 0 }, { 249, 250 }, { 10, 6 }, { 3, 0 }, 14, 45 },
{ { 0, 0 }, { 128, 0 }, { 249, 246 }, { 137, 108 }, { 3, 0 }, 14, 71 },
{ { 3, 12 }, { 128, 8 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 60 },
{ { 3, 12 }, { 133, 0 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 58 },
{ { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 53 },
{ { 14, 3 }, { 64, 0 }, { 200, 155 }, { 73, 105 }, { 0, 2 }, 14, 64 },
{ { 215, 199 }, { 220, 0 }, { 173, 141 }, { 5, 5 }, { 3, 0 }, 14, 71 },
{ { 215, 199 }, { 220, 0 }, { 168, 136 }, { 4, 4 }, { 3, 0 }, 14, 61 },
{ { 128, 17 }, { 0, 0 }, { 246, 103 }, { 6, 23 }, { 3, 3 }, 14, 61 },
{ { 128, 17 }, { 0, 9 }, { 245, 70 }, { 5, 22 }, { 2, 3 }, 14, 48 },
{ { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 48 },
{ { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 3, 0 }, 0, 69 },
{ { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 68 },
{ { 1, 2 }, { 88, 0 }, { 103, 117 }, { 231, 7 }, { 0, 0 }, 0, 63 },
{ { 65, 66 }, { 69, 8 }, { 248, 117 }, { 72, 5 }, { 0, 0 }, 0, 74 },
{ { 10, 30 }, { 64, 78 }, { 224, 255 }, { 240, 5 }, { 3, 0 }, 8, 60 },
{ { 10, 30 }, { 124, 82 }, { 224, 255 }, { 240, 2 }, { 3, 0 }, 8, 80 },
{ { 14, 0 }, { 64, 8 }, { 122, 123 }, { 74, 27 }, { 0, 2 }, 14, 64 },
{ { 14, 7 }, { 10, 64 }, { 228, 85 }, { 228, 57 }, { 3, 1 }, 6, 69 },
{ { 5, 4 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 73 },
{ { 2, 21 }, { 63, 0 }, { 0, 247 }, { 243, 245 }, { 3, 0 }, 8, 75 },
{ { 1, 2 }, { 79, 0 }, { 250, 248 }, { 141, 181 }, { 0, 0 }, 7, 68 },
{ { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 48 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 53 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 }
};

283
audiolib/gus.c Executable file
View File

@ -0,0 +1,283 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
file: GUS.C
author: James R. Dose
date: September 7, 1994
Gravis Ultrasound initialization routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "usrhooks.h"
#include "interrup.h"
#include "newgf1.h"
#include "gusmidi.h"
#include "guswave.h"
#include "_guswave.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
// size of DMA buffer for patch loading
#define DMABUFFSIZE 2048U
struct gf1_dma_buff GUS_HoldBuffer;
static int HoldBufferAllocated = FALSE;
static int GUS_Installed = 0;
extern VoiceNode GUSWAVE_Voices[ VOICES ];
extern int GUSWAVE_Installed;
unsigned long GUS_TotalMemory;
int GUS_MemConfig;
int GUS_AuxError = 0;
int GUS_ErrorCode = GUS_Ok;
#define GUS_SetErrorCode( status ) \
GUS_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: GUS_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *GUS_ErrorString
(
int ErrorNumber
)
{
char *ErrorString;
switch( ErrorNumber )
{
case GUS_Warning :
case GUS_Error :
ErrorString = GUS_ErrorString( GUS_ErrorCode );
break;
case GUS_Ok :
ErrorString = "Ultrasound music ok.";
break;
case GUS_OutOfMemory :
ErrorString = "Out of memory in GusMidi.";
break;
case GUS_OutOfDosMemory :
ErrorString = "Out of conventional (640K) memory in GusMidi.";
break;
case GUS_GF1Error :
ErrorString = gf1_error_str( GUS_AuxError );
break;
case GUS_InvalidIrq :
ErrorString = "Ultrasound IRQ must be 7 or less.";
break;
case GUS_ULTRADIRNotSet :
ErrorString = "ULTRADIR environment variable not set.";
break;
case GUS_MissingConfig :
// ErrorString = "Can't find GUSMIDI.INI file.";
ErrorString = "Can't find ULTRAMID.INI file.";
break;
case GUS_FileError :
ErrorString = strerror( GUS_AuxError );
break;
default :
ErrorString = "Unknown Ultrasound error code.";
break;
}
return( ErrorString );
}
/*---------------------------------------------------------------------
Function: D32DosMemAlloc
Allocate a block of Conventional memory.
---------------------------------------------------------------------*/
void *D32DosMemAlloc
(
unsigned size
)
{
union REGS r;
// DPMI allocate DOS memory
r.x.eax = 0x0100;
// Number of paragraphs requested
r.x.ebx = ( size + 15 ) >> 4;
int386( 0x31, &r, &r );
if ( r.x.cflag )
{
// Failed
return( NULL );
}
return( ( void * )( ( r.x.eax & 0xFFFF ) << 4 ) );
}
/*---------------------------------------------------------------------
Function: GUS_Init
Initializes the Gravis Ultrasound for sound and music playback.
---------------------------------------------------------------------*/
int GUS_Init
(
void
)
{
struct load_os os;
int ret;
if ( GUS_Installed > 0 )
{
GUS_Installed++;
return( GUS_Ok );
}
GUS_SetErrorCode( GUS_Ok );
GUS_Installed = 0;
GetUltraCfg( &os );
if ( os.forced_gf1_irq > 7 )
{
GUS_SetErrorCode( GUS_InvalidIrq );
return( GUS_Error );
}
if ( !HoldBufferAllocated )
{
GUS_HoldBuffer.vptr = D32DosMemAlloc( DMABUFFSIZE );
if ( GUS_HoldBuffer.vptr == NULL )
{
GUS_SetErrorCode( GUS_OutOfDosMemory );
return( GUS_Error );
}
GUS_HoldBuffer.paddr = ( unsigned long )GUS_HoldBuffer.vptr;
HoldBufferAllocated = TRUE;
}
os.voices = 24;
ret = gf1_load_os( &os );
if ( ret )
{
GUS_AuxError = ret;
GUS_SetErrorCode( GUS_GF1Error );
return( GUS_Error );
}
GUS_TotalMemory = gf1_mem_avail();
GUS_MemConfig = ( GUS_TotalMemory - 1 ) >> 18;
GUS_Installed = 1;
return( GUS_Ok );
}
/*---------------------------------------------------------------------
Function: GUS_Shutdown
Ends use of the Gravis Ultrasound. Must be called the same number
of times as GUS_Init.
---------------------------------------------------------------------*/
void GUS_Shutdown
(
void
)
{
if ( GUS_Installed > 0 )
{
GUS_Installed--;
if ( GUS_Installed == 0 )
{
gf1_unload_os();
}
}
}
/*---------------------------------------------------------------------
Function: GUSWAVE_Shutdown
Terminates use of the Gravis Ultrasound for digitized sound playback.
---------------------------------------------------------------------*/
void GUSWAVE_Shutdown
(
void
)
{
int i;
if ( GUSWAVE_Installed )
{
GUSWAVE_KillAllVoices();
// free memory
for ( i = 0; i < VOICES; i++ )
{
if ( GUSWAVE_Voices[ i ].mem != NULL )
{
gf1_free( GUSWAVE_Voices[ i ].mem );
GUSWAVE_Voices[ i ].mem = NULL;
}
}
GUS_Shutdown();
GUSWAVE_Installed = FALSE;
}
}

561
audiolib/gusmidi.c Executable file
View File

@ -0,0 +1,561 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/*********** ***********************************************************
file: GUSMIDI.C
author: James R. Dose
date: March 23, 1994
General MIDI playback functions for the Gravis Ultrasound
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
// Module MUST be compiled with structure allignment set to a maximum
// of 1 byte ( zp1 ).
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "usrhooks.h"
#include "interrup.h"
#include "newgf1.h"
#include "gusmidi.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
// size of DMA buffer for patch loading
#define DMABUFFSIZE 2048U
#define MAX_MEM_CONFIG 3
// size of patch array (128 perc, 128 melodic)
#define NUM_PATCHES 256
// size of largest patch name
#define BIGGEST_NAME 9
#define UNUSED_PATCH -1
static struct patch Patch[ NUM_PATCHES ];
static unsigned char *PatchWaves[ NUM_PATCHES ];
static int PatchMap[ NUM_PATCHES ][ MAX_MEM_CONFIG + 1 ];
static char ProgramName[ NUM_PATCHES ][ BIGGEST_NAME ];
static char PatchLoaded[ NUM_PATCHES ];
static char ConfigFileName[] = "ULTRAMID.INI";
static char ConfigDirectory[ 80 ] = { '\0' };
// The name of the configuration directory
static char InstrumentDirectory[ 80 ];
extern struct gf1_dma_buff GUS_HoldBuffer;
extern unsigned long GUS_TotalMemory;
extern int GUS_MemConfig;
static int GUSMIDI_Volume = 255;
extern int GUS_AuxError;
extern int GUS_ErrorCode;
int GUSMIDI_Installed = FALSE;
#define GUS_SetErrorCode( status ) \
GUS_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: GUS_GetPatchMap
Reads the patch map from disk.
---------------------------------------------------------------------*/
int GUS_GetPatchMap
(
char *name
)
{
char text[ 80 ];
char *ud;
int index;
int ignore;
FILE *fp;
for( index = 0; index < NUM_PATCHES; index++ )
{
PatchMap[ index ][ 0 ] = UNUSED_PATCH;
PatchMap[ index ][ 1 ] = UNUSED_PATCH;
PatchMap[ index ][ 2 ] = UNUSED_PATCH;
PatchMap[ index ][ 3 ] = UNUSED_PATCH;
ProgramName[ index ][ 0 ] = 0;
}
ud = getenv( "ULTRADIR" );
if ( ud == NULL )
{
GUS_SetErrorCode( GUS_ULTRADIRNotSet );
return( GUS_Error );
}
strcpy( InstrumentDirectory, ud );
strcat( InstrumentDirectory, "\\midi\\" );
strcpy( ConfigDirectory, ud );
strcat( ConfigDirectory, "\\midi\\" );
strcpy( text, name );
fp = fopen( text, "r" );
if ( fp == NULL )
{
strcpy( text, InstrumentDirectory );
strcat( text, name );
fp = fopen( text, "r" );
if ( fp == NULL )
{
GUS_SetErrorCode( GUS_MissingConfig );
return( GUS_Error );
}
}
while( 1 )
{
if ( fgets( text, 80, fp ) == NULL )
{
break;
}
if ( text[ 0 ] == '#' )
{
continue;
}
if ( sscanf( text, "%d", &index ) != 1 )
{
continue;
}
sscanf( text, "%d, %d, %d, %d, %d, %s\n", &ignore,
&PatchMap[ index ][ 0 ],
&PatchMap[ index ][ 1 ],
&PatchMap[ index ][ 2 ],
&PatchMap[ index ][ 3 ],
ProgramName[ index ] );
}
fclose( fp );
return( GUS_Ok );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_UnloadPatch
Unloads a patch from the GUS's memory.
---------------------------------------------------------------------*/
int GUSMIDI_UnloadPatch
(
int prognum
)
{
int prog;
unsigned flags;
prog = PatchMap[ prognum ][ GUS_MemConfig ];
if ( PatchLoaded[ prog ] )
{
flags = DisableInterrupts();
gf1_unload_patch( &Patch[ prog ] );
if ( PatchWaves[ prog ] != NULL )
{
USRHOOKS_FreeMem( PatchWaves[ prog ] );
PatchWaves[ prog ] = NULL;
}
// just in case sequence is still playing
Patch[ prog ].nlayers = 0;
PatchLoaded[ prog ] = FALSE;
RestoreInterrupts( flags );
}
return( GUS_Ok );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_LoadPatch
Loads a patch into the GUS's memory.
---------------------------------------------------------------------*/
int GUSMIDI_LoadPatch
(
int prognum
)
{
int prog;
char text[ 80 ];
int ret;
unsigned char *wave_buff;
struct patchinfo patchi;
int status;
prog = PatchMap[ prognum ][ GUS_MemConfig ];
if ( ( PatchLoaded[ prog ] ) || ( prog == UNUSED_PATCH ) )
{
return( GUS_Ok );
}
if ( !ProgramName[ prog ][ 0 ] )
{
return( GUS_Ok );
}
strcpy( text, InstrumentDirectory );
strcat( text, ProgramName[ prog ] );
strcat( text, ".pat" );
ret = gf1_get_patch_info( text, &patchi );
if ( ret != OK )
{
GUS_AuxError = ret;
GUS_SetErrorCode( GUS_GF1Error );
return( GUS_Error );
}
status = USRHOOKS_GetMem( &wave_buff, patchi.header.wave_forms *
sizeof( struct wave_struct ) );
if ( status != USRHOOKS_Ok )
{
GUS_SetErrorCode( GUS_OutOfMemory );
return( GUS_Error );
}
ret = gf1_load_patch( text, &patchi, &Patch[ prog ], &GUS_HoldBuffer,
DMABUFFSIZE, ( unsigned char * )wave_buff, PATCH_LOAD_8_BIT );
if ( ret != OK )
{
USRHOOKS_FreeMem( wave_buff );
GUS_AuxError = ret;
GUS_SetErrorCode( GUS_GF1Error );
return( GUS_Error );
}
PatchWaves[ prog ] = wave_buff;
PatchLoaded[ prog ] = TRUE;
return( GUS_Ok );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_ProgramChange
Selects the instrument to use on the specified MIDI channel.
---------------------------------------------------------------------*/
void GUSMIDI_ProgramChange
(
int channel,
int prognum
)
{
int prog;
prog = PatchMap[ prognum ][ GUS_MemConfig ];
if ( PatchLoaded[ prog ] )
{
gf1_midi_change_program( &Patch[ prog ], channel );
}
else
{
gf1_midi_change_program( NULL, channel );
}
}
/*---------------------------------------------------------------------
Function: GUSMIDI_NoteOn
Plays a note on the specified channel.
---------------------------------------------------------------------*/
void GUSMIDI_NoteOn
(
int chan,
int note,
int velocity
)
{
int prog;
if ( chan == 9 )
{
prog = PatchMap[ note + 128 ][ GUS_MemConfig ];
if ( PatchLoaded[ prog ] )
{
gf1_midi_note_on( &Patch[ note + 128 ], 1,
note, velocity, 9 );
}
}
else
{
gf1_midi_note_on( 0L, 1, note, velocity, chan );
}
}
/*---------------------------------------------------------------------
Function: GUSMIDI_NoteOff
Turns off a note on the specified channel.
---------------------------------------------------------------------*/
#pragma warn -par
void GUSMIDI_NoteOff
(
int chan,
int note,
int velocity
)
{
gf1_midi_note_off( note, chan );
}
#pragma warn .par
/*---------------------------------------------------------------------
Function: GUSMIDI_ControlChange
Sets the value of a controller on the specified channel.
---------------------------------------------------------------------*/
void GUSMIDI_ControlChange
(
int channel,
int number,
int value
)
{
gf1_midi_parameter( channel, number, value );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_PitchBend
Sets the pitch bend on the specified MIDI channel.
---------------------------------------------------------------------*/
void GUSMIDI_PitchBend
(
int channel,
int lsb,
int msb
)
{
gf1_midi_pitch_bend( channel, lsb, msb );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_ReleasePatches
Removes all the instruments from the GUS's memory.
---------------------------------------------------------------------*/
void GUSMIDI_ReleasePatches
(
void
)
{
int i;
for( i = 0; i < 256; i++ )
{
GUSMIDI_UnloadPatch( i );
}
}
/*---------------------------------------------------------------------
Function: GUSMIDI_SetVolume
Sets the total music volume.
---------------------------------------------------------------------*/
void GUSMIDI_SetVolume
(
int volume
)
{
// Set the minimum to 2 because 0 has a tremolo problem
volume = max( 2, volume );
volume = min( volume, 255 );
GUSMIDI_Volume = volume;
// range = 0 to 127
gf1_midi_synth_volume( 0, volume >> 1 );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_GetVolume
Returns the total music volume.
---------------------------------------------------------------------*/
int GUSMIDI_GetVolume
(
void
)
{
return( GUSMIDI_Volume );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_Init
Initializes the Gravis Ultrasound for music playback.
---------------------------------------------------------------------*/
int GUSMIDI_Init
(
void
)
{
int ret;
int i;
int startmem;
// unsigned long mem;
extern int GUSWAVE_Installed;
if ( GUSMIDI_Installed )
{
GUSMIDI_Shutdown();
}
ret = GUS_Init();
if ( ret != GUS_Ok )
{
return( ret );
}
if ( GUS_MemConfig < 0 )
{
GUS_MemConfig = 0;
}
if ( GUS_MemConfig > MAX_MEM_CONFIG )
{
GUS_MemConfig = MAX_MEM_CONFIG;
}
for( i = 0; i < NUM_PATCHES; i++ )
{
ProgramName[ i ][ 0 ] = '\0';
PatchWaves[ i ] = NULL;
PatchLoaded[ i ] = FALSE;
}
GUSMIDI_SetVolume( 255 );
GUSMIDI_Installed = TRUE;
ret = GUS_GetPatchMap( ConfigFileName );
if ( ret != GUS_Ok )
{
GUSMIDI_Shutdown();
return( ret );
}
// if ( !GUSWAVE_Installed )
// {
// mem = gf1_malloc( 8192 );
// }
startmem = gf1_mem_avail();
for( i = 0; i < NUM_PATCHES; i++ )
{
ret = GUSMIDI_LoadPatch( i );
if ( ret != GUS_Ok )
{
}
// if ( ret != GUS_Ok )
// {
// return( ret );
// }
}
// if ( !GUSWAVE_Installed )
// {
// gf1_free( mem );
// }
GUSMIDI_Installed = TRUE;
return( GUS_Ok );
}
/*---------------------------------------------------------------------
Function: GUSMIDI_Shutdown
Ends use of the Gravis Ultrasound for music playback.
---------------------------------------------------------------------*/
void GUSMIDI_Shutdown
(
void
)
{
GUSMIDI_ReleasePatches();
GUS_Shutdown();
GUSMIDI_Installed = FALSE;
}

59
audiolib/gusmidi.h Executable file
View File

@ -0,0 +1,59 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __GUSMIDI_H
#define __GUSMIDI_H
extern struct gf1_dma_buff GUS_HoldBuffer;
enum GUS_Errors
{
GUS_Warning = -2,
GUS_Error = -1,
GUS_Ok = 0,
GUS_OutOfMemory,
GUS_OutOfDosMemory,
GUS_OutOfDRAM,
GUS_GF1Error,
GUS_InvalidIrq,
GUS_ULTRADIRNotSet,
GUS_MissingConfig,
GUS_FileError
};
char *GUS_ErrorString( int ErrorNumber );
int GUS_GetPatchMap( char *name );
int GUSMIDI_UnloadPatch( int prog );
int GUSMIDI_LoadPatch( int prog );
void GUSMIDI_ProgramChange( int channel, int prog );
void GUSMIDI_NoteOn( int chan, int note, int velocity );
void GUSMIDI_NoteOff( int chan, int note, int velocity );
void GUSMIDI_ControlChange( int channel, int number, int value );
void GUSMIDI_PitchBend( int channel, int lsb, int msb );
void GUSMIDI_ReleasePatches( void );
void GUSMIDI_SetVolume( int volume );
int GUSMIDI_GetVolume( void );
int GUS_Init( void );
void GUS_Shutdown( void );
#pragma aux GUS_Shutdown frame;
int GUSMIDI_Init( void );
void GUSMIDI_Shutdown( void );
void *D32DosMemAlloc( unsigned size );
#endif

1773
audiolib/guswave.c Executable file

File diff suppressed because it is too large Load Diff

75
audiolib/guswave.h Executable file
View File

@ -0,0 +1,75 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: GUSWAVE.H
author: James R. Dose
date: March 23, 1994
Public header for for GUSWAVE.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __GUSWAVE_H
#define __GUSWAVE_H
#define GUSWAVE_MinVoiceHandle 1
enum GUSWAVE_Errors
{
GUSWAVE_Warning = -2,
GUSWAVE_Error = -1,
GUSWAVE_Ok = 0,
GUSWAVE_GUSError,
GUSWAVE_NotInstalled,
GUSWAVE_NoVoices,
GUSWAVE_UltraNoMem,
GUSWAVE_UltraNoMemMIDI,
GUSWAVE_VoiceNotFound,
GUSWAVE_InvalidVOCFile,
GUSWAVE_InvalidWAVFile
};
char *GUSWAVE_ErrorString( int ErrorNumber );
int GUSWAVE_VoicePlaying( int handle );
int GUSWAVE_VoicesPlaying( void );
int GUSWAVE_Kill( int handle );
int GUSWAVE_KillAllVoices( void );
int GUSWAVE_SetPitch( int handle, int pitchoffset );
int GUSWAVE_SetPan3D( int handle, int angle, int distance );
void GUSWAVE_SetVolume( int volume );
int GUSWAVE_GetVolume( void );
int GUSWAVE_VoiceAvailable( int priority );
int GUSWAVE_PlayVOC( char *sample, int pitchoffset, int angle, int volume,
int priority, unsigned long callbackval );
int GUSWAVE_PlayWAV( char *sample, int pitchoffset, int angle, int volume,
int priority, unsigned long callbackval );
int GUSWAVE_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
int channels, int bits, int rate, int pitchoffset, int angle,
int volume, int priority, unsigned long callbackval );
void GUSWAVE_SetCallBack( void ( *function )( unsigned long ) );
void GUSWAVE_SetReverseStereo( int setting );
int GUSWAVE_GetReverseStereo( void );
int GUSWAVE_Init( int numvoices );
void GUSWAVE_Shutdown( void );
#pragma aux GUSWAVE_Shutdown frame;
#endif

50
audiolib/interrup.h Executable file
View File

@ -0,0 +1,50 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: INTERRUP.H
author: James R. Dose
date: March 31, 1994
Inline functions for disabling and restoring the interrupt flag.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __INTERRUPT_H
#define __INTERRUPT_H
unsigned long DisableInterrupts( void );
void RestoreInterrupts( unsigned long flags );
#ifdef PLAT_DOS
#pragma aux DisableInterrupts = \
"pushfd", \
"pop eax", \
"cli" \
modify [ eax ];
#pragma aux RestoreInterrupts = \
"push eax", \
"popfd" \
parm [ eax ];
#endif
#endif

325
audiolib/irq.c Executable file
View File

@ -0,0 +1,325 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: IRQ.C
author: James R. Dose
date: August 26, 1994
Low level routines to set and restore IRQ's through DPMI.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <dos.h>
#include <stdlib.h>
#include "irq.h"
#define D32RealSeg(P) ( ( ( ( unsigned long )( P ) ) >> 4 ) & 0xFFFF )
#define D32RealOff(P) ( ( ( unsigned long )( P ) ) & 0xF )
typedef struct
{
unsigned long drdi;
unsigned long drsi;
unsigned long drbp;
unsigned long drxx;
unsigned long drbx;
unsigned long drdx;
unsigned long drcx;
unsigned long drax;
unsigned short drflags;
unsigned short dres;
unsigned short drds;
unsigned short drfs;
unsigned short drgs;
unsigned short drip;
unsigned short drcs;
unsigned short drsp;
unsigned short drss;
} DPMI_REGS;
static DPMI_REGS rmregs = { 0 };
static void ( __interrupt __far *IRQ_Callback )( void ) = NULL;
static char *IRQ_RealModeCode = NULL;
static unsigned short IRQ_CallBackSegment;
static unsigned short IRQ_CallBackOffset;
static unsigned short IRQ_RealModeSegment;
static unsigned short IRQ_RealModeOffset;
static unsigned long IRQ_ProtectedModeOffset;
static unsigned short IRQ_ProtectedModeSelector;
static union REGS Regs;
static struct SREGS SegRegs;
static void *D32DosMemAlloc
(
unsigned long size
)
{
// DPMI allocate DOS memory
Regs.x.eax = 0x0100;
// Number of paragraphs requested
Regs.x.ebx = ( size + 15 ) >> 4;
int386( 0x31, &Regs, &Regs );
if ( Regs.x.cflag != 0 )
{
// Failed
return ( ( unsigned long )0 );
}
return( ( void * )( ( Regs.x.eax & 0xFFFF ) << 4 ) );
}
// Intermediary function: DPMI calls this, making it
// easier to write in C
// handle 16-bit incoming stack
void fixebp
(
void
);
#pragma aux fixebp = \
"mov bx, ss" \
"lar ebx, ebx" \
"bt ebx, 22" \
"jc bigstk" \
"movzx esp, sp" \
"mov ebp, esp" \
"bigstk:" \
modify exact [ ebx ];
#pragma aux rmcallback parm [];
void rmcallback
(
unsigned short _far *stkp
)
{
// "Pop" the real mode return frame so we
// can resume where we left off
rmregs.drip = *stkp++;
rmregs.drcs = *stkp++;
rmregs.drsp = FP_OFF(stkp);
// Call protected-mode handler
IRQ_Callback();
}
static void _interrupt _cdecl callback_x
(
// regs pushed in this order by prologue
int rgs,
int rfs,
int res,
int rds,
int rdi,
int rsi,
int rbp,
int rsp,
int rbx,
int rdx,
int rcx,
int rax
)
{
// unsigned short _far *stkp;
// return;
fixebp();
rmcallback (MK_FP(rds, rsi));
}
/*
static void _interrupt _cdecl callback_x
(
// regs pushed in this order by prologue
int rgs,
int rfs,
int res,
int rds,
int rdi,
int rsi,
int rbp,
int rsp,
int rbx,
int rdx,
int rcx,
int rax
)
{
unsigned short _far *stkp;
fixebp();
stkp = MK_FP(rds, rsi);
// "Pop" the real mode return frame so we
// can resume where we left off
rmregs.drip = *stkp++;
rmregs.drcs = *stkp++;
rmregs.drsp = FP_OFF(stkp);
// Call protected-mode handler
IRQ_Callback();
}
*/
int IRQ_SetVector
(
int vector,
void ( __interrupt __far *function )( void )
)
{
void far *fp;
IRQ_Callback = function;
// Save the starting real-mode and protected-mode handler addresses
// DPMI get protected mode vector */
Regs.w.ax = 0x0204;
Regs.w.bx = vector;
int386( 0x31, &Regs, &Regs );
IRQ_ProtectedModeSelector = Regs.w.cx;
IRQ_ProtectedModeOffset = Regs.x.edx;
// DPMI get real mode vector
Regs.w.ax = 0x0200;
Regs.w.bx = vector;
int386( 0x31, &Regs, &Regs );
IRQ_RealModeSegment = Regs.w.cx;
IRQ_RealModeOffset = Regs.w.dx;
// Set up callback
// DPMI allocate real mode callback
Regs.w.ax = 0x0303;
fp = ( void far * )callback_x;
SegRegs.ds = FP_SEG( fp );
Regs.x.esi = FP_OFF( fp );
fp = ( void _far * )&rmregs;
SegRegs.es = FP_SEG( fp );
Regs.x.edi = FP_OFF( fp );
int386x( 0x31, &Regs, &Regs, &SegRegs );
IRQ_CallBackSegment = Regs.w.cx;
IRQ_CallBackOffset = Regs.w.dx;
if ( Regs.x.cflag != 0 )
{
return( IRQ_Error );
}
if ( IRQ_RealModeCode == NULL )
{
// Allocate 6 bytes of low memory for real mode interrupt handler
IRQ_RealModeCode = D32DosMemAlloc( 6 );
if ( IRQ_RealModeCode == NULL )
{
// Free callback
Regs.w.ax = 0x304;
Regs.w.cx = IRQ_CallBackSegment;
Regs.w.dx = IRQ_CallBackOffset;
int386x( 0x31, &Regs, &Regs, &SegRegs );
return( IRQ_Error );
}
}
// Poke code (to call callback) into real mode handler
// CALL FAR PTR (callback)
IRQ_RealModeCode[ 0 ] = '\x9A';
*( ( unsigned short * )&IRQ_RealModeCode[ 1 ] ) = IRQ_CallBackOffset;
*( ( unsigned short * )&IRQ_RealModeCode[ 3 ] ) = IRQ_CallBackSegment;
// IRET
IRQ_RealModeCode[ 5 ] = '\xCF';
// Install protected mode handler
// DPMI set protected mode vector
Regs.w.ax = 0x0205;
Regs.w.bx = vector;
fp = function;
Regs.w.cx = FP_SEG( fp );
Regs.x.edx = FP_OFF( fp );
int386( 0x31, &Regs, &Regs );
// Install callback address as real mode handler
// DPMI set real mode vector
Regs.w.ax = 0x0201;
Regs.w.bx = vector;
Regs.w.cx = D32RealSeg( IRQ_RealModeCode );
Regs.w.dx = D32RealOff( IRQ_RealModeCode );
int386( 0x31, &Regs, &Regs );
return( IRQ_Ok );
}
int IRQ_RestoreVector
(
int vector
)
{
// Restore original interrupt handlers
// DPMI set real mode vector
Regs.w.ax = 0x0201;
Regs.w.bx = vector;
Regs.w.cx = IRQ_RealModeSegment;
Regs.w.dx = IRQ_RealModeOffset;
int386( 0x31, &Regs, &Regs );
Regs.w.ax = 0x0205;
Regs.w.bx = vector;
Regs.w.cx = IRQ_ProtectedModeSelector;
Regs.x.edx = IRQ_ProtectedModeOffset;
int386( 0x31, &Regs, &Regs );
// Free callback
Regs.w.ax = 0x304;
Regs.w.cx = IRQ_CallBackSegment;
Regs.w.dx = IRQ_CallBackOffset;
int386x( 0x31, &Regs, &Regs, &SegRegs );
if ( Regs.x.cflag )
{
return( IRQ_Error );
}
return( IRQ_Ok );
}

54
audiolib/irq.h Executable file
View File

@ -0,0 +1,54 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: IRQ.H
author: James R. Dose
date: August 8, 1994
Public header for IRQ.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __IRQ_H
#define __IRQ_H
enum IRQ_ERRORS
{
IRQ_Warning = -2,
IRQ_Error = -1,
IRQ_Ok = 0,
};
#define VALID_IRQ( irq ) ( ( ( irq ) >= 0 ) && ( ( irq ) <= 15 ) )
int IRQ_SetVector
(
int vector,
void ( __interrupt *function )( void )
);
int IRQ_RestoreVector
(
int vector
);
#endif

290
audiolib/leetimbr.c Executable file
View File

@ -0,0 +1,290 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
typedef struct
{
unsigned char SAVEK[ 2 ];
unsigned char Level[ 2 ];
unsigned char Env1[ 2 ];
unsigned char Env2[ 2 ];
unsigned char Wave[ 2 ];
unsigned char Feedback;
signed char Transpose;
signed char Velocity;
} TIMBRE;
TIMBRE ADLIB_TimbreBank[ 256 ] =
{
{ { 33, 49 }, { 79, 0 }, { 242, 210 }, { 82, 115 }, { 0, 0 }, 6, 0 },
{ { 19, 17 }, { 198, 10 }, { 242, 241 }, { 245, 245 }, { 1, 0 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 3, 18 }, { 48, 16 }, { 246, 242 }, { 25, 244 }, { 0, 0 }, 15, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 178, 176 }, { 192, 134 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 178, 176 }, { 192, 128 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
{ { 130, 128 }, { 192, 134 }, { 145, 145 }, { 246, 246 }, { 1, 1 }, 9, 0 },
{ { 36, 49 }, { 79, 27 }, { 242, 82 }, { 11, 11 }, { 0, 0 }, 14, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 19, 49 }, { 150, 128 }, { 254, 242 }, { 33, 148 }, { 0, 0 }, 10, 0 },
{ { 1, 17 }, { 77, 0 }, { 242, 245 }, { 83, 116 }, { 1, 1 }, 8, 0 },
{ { 33, 40 }, { 1, 9 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
{ { 33, 40 }, { 1, 19 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
{ { 36, 194 }, { 138, 3 }, { 250, 145 }, { 111, 248 }, { 0, 0 }, 8, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 33 }, { 26, 0 }, { 241, 246 }, { 207, 72 }, { 0, 0 }, 10, 0 },
{ { 1, 34 }, { 29, 0 }, { 183, 196 }, { 34, 55 }, { 0, 0 }, 14, 0 },
{ { 49, 34 }, { 30, 0 }, { 242, 241 }, { 239, 104 }, { 0, 0 }, 14, 0 },
{ { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
{ { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
{ { 17, 49 }, { 5, 9 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
{ { 17, 49 }, { 5, 0 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
{ { 49, 114 }, { 138, 0 }, { 213, 97 }, { 25, 27 }, { 0, 0 }, 12, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
{ { 1, 17 }, { 156, 128 }, { 128, 240 }, { 5, 6 }, { 0, 0 }, 0, 0 },
{ { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
{ { 2, 1 }, { 153, 128 }, { 245, 246 }, { 85, 83 }, { 0, 0 }, 0, 0 },
{ { 192, 0 }, { 13, 0 }, { 165, 212 }, { 67, 35 }, { 2, 1 }, 0, 0 },
{ { 33, 32 }, { 88, 0 }, { 194, 97 }, { 227, 22 }, { 1, 3 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 34 }, { 22, 0 }, { 176, 179 }, { 129, 44 }, { 0, 1 }, 12, 0 },
{ { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
{ { 49, 97 }, { 28, 128 }, { 65, 146 }, { 11, 59 }, { 0, 0 }, 14, 0 },
{ { 49, 241 }, { 28, 0 }, { 65, 146 }, { 11, 27 }, { 0, 0 }, 10, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
{ { 225, 226 }, { 21, 3 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
{ { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
{ { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
{ { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
{ { 32, 49 }, { 78, 0 }, { 113, 82 }, { 104, 94 }, { 0, 0 }, 10, 0 },
{ { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 50, 97 }, { 154, 130 }, { 81, 162 }, { 27, 59 }, { 0, 0 }, 12, 0 },
{ { 50, 33 }, { 192, 0 }, { 155, 114 }, { 33, 7 }, { 0, 0 }, 4, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 162 }, { 131, 141 }, { 116, 101 }, { 23, 23 }, { 0, 0 }, 7, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 225, 98 }, { 236, 0 }, { 110, 101 }, { 143, 42 }, { 0, 0 }, 14, 0 },
{ { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 245, 242 }, { 154, 128 }, { 12, 96 }, { 199, 165 }, { 0, 0 }, 13, 0 },
{ { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
{ { 34, 33 }, { 89, 8 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
{ { 33, 33 }, { 29, 0 }, { 113, 129 }, { 14, 14 }, { 0, 0 }, 14, 0 },
{ { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 0, 17 }, { 13, 128 }, { 241, 80 }, { 255, 255 }, { 0, 0 }, 6, 0 },
{ { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
{ { 0, 49 }, { 16, 128 }, { 17, 176 }, { 239, 15 }, { 0, 0 }, 10, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 164, 97 }, { 76, 16 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 1, 1 }, { 0, 0 }, { 255, 255 }, { 7, 7 }, { 0, 0 }, 7, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 1, 221 }, { 0, 0 }, { 246, 31 }, { 0, 6 }, { 2, 3 }, 12, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
{ { 3, 15 }, { 0, 0 }, { 251, 245 }, { 43, 11 }, { 2, 0 }, 15, 36 },
{ { 33, 0 }, { 128, 0 }, { 255, 249 }, { 7, 7 }, { 0, 1 }, 14, 36 },
{ { 240, 229 }, { 192, 0 }, { 255, 251 }, { 255, 240 }, { 3, 0 }, 14, 48 },
{ { 33, 0 }, { 128, 0 }, { 255, 248 }, { 10, 25 }, { 0, 1 }, 14, 36 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 48 },
{ { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 69 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 52 },
{ { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 48 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 55 },
{ { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 57 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 58 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 60 },
{ { 1, 221 }, { 12, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 12, 62 },
{ { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 63 },
{ { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 70 },
{ { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 19 }, { 0, 2 }, 10, 70 },
{ { 14, 7 }, { 6, 68 }, { 248, 244 }, { 66, 228 }, { 3, 3 }, 14, 53 },
{ { 14, 0 }, { 64, 8 }, { 150, 183 }, { 79, 24 }, { 0, 2 }, 14, 48 },
{ { 1, 221 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 2, 3 }, 12, 84 },
{ { 2, 9 }, { 27, 0 }, { 245, 246 }, { 118, 214 }, { 2, 0 }, 4, 43 },
{ { 0, 223 }, { 9, 0 }, { 246, 147 }, { 0, 67 }, { 0, 2 }, 14, 56 },
{ { 128, 144 }, { 13, 0 }, { 248, 159 }, { 0, 4 }, { 2, 3 }, 14, 24 },
{ { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 65 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 48 },
{ { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 51 },
{ { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 54 },
{ { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 42 },
{ { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 39 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 128, 17 }, { 0, 0 }, { 255, 111 }, { 6, 22 }, { 3, 0 }, 14, 52 },
{ { 128, 17 }, { 0, 0 }, { 255, 79 }, { 6, 22 }, { 3, 0 }, 14, 52 },
{ { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 60 },
{ { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 66 },
{ { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 59 },
{ { 65, 66 }, { 69, 0 }, { 252, 105 }, { 69, 5 }, { 0, 0 }, 0, 91 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 109 },
{ { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
{ { 133, 132 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 79 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
{ { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 }
};

118
audiolib/linklist.h Executable file
View File

@ -0,0 +1,118 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __linklist_h
#define __linklist_h
#ifdef __cplusplus
extern "C" {
#endif
#define NewNode(type) ((type*)SafeMalloc(sizeof(type)))
#define LL_CreateNewLinkedList(rootnode,type,next,prev) \
{ \
(rootnode) = NewNode(type); \
(rootnode)->prev = (rootnode); \
(rootnode)->next = (rootnode); \
}
#define LL_AddNode(rootnode, newnode, next, prev) \
{ \
(newnode)->next = (rootnode); \
(newnode)->prev = (rootnode)->prev; \
(rootnode)->prev->next = (newnode); \
(rootnode)->prev = (newnode); \
}
#define LL_TransferList(oldroot,newroot,next,prev) \
{ \
if ((oldroot)->prev != (oldroot)) \
{ \
(oldroot)->prev->next = (newroot); \
(oldroot)->next->prev = (newroot)->prev; \
(newroot)->prev->next = (oldroot)->next; \
(newroot)->prev = (oldroot)->prev; \
(oldroot)->next = (oldroot); \
(oldroot)->prev = (oldroot); \
} \
}
#define LL_ReverseList(root,type,next,prev) \
{ \
type *newend,*trav,*tprev; \
\
newend = (root)->next; \
for(trav = (root)->prev; trav != newend; trav = tprev) \
{ \
tprev = trav->prev; \
LL_MoveNode(trav,newend,next,prev); \
} \
}
#define LL_RemoveNode(node,next,prev) \
{ \
(node)->prev->next = (node)->next; \
(node)->next->prev = (node)->prev; \
(node)->next = (node); \
(node)->prev = (node); \
}
#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \
{ \
type *hoya; \
\
hoya = (rootnode)->next; \
while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \
{ \
hoya = hoya->next; \
} \
LL_AddNode(hoya,(insertnode),next,prev); \
}
#define LL_MoveNode(node,newroot,next,prev) \
{ \
LL_RemoveNode((node),next,prev); \
LL_AddNode((newroot),(node),next,prev); \
}
#define LL_ListEmpty(list,next,prev) \
( \
((list)->next == (list)) && \
((list)->prev == (list)) \
)
#define LL_Free(list) SafeFree(list)
#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list)
#define LL_New LL_CreateNewLinkedList
#define LL_Remove LL_RemoveNode
#define LL_Add LL_AddNode
#define LL_Empty LL_ListEmpty
#define LL_Move LL_MoveNode
#ifdef __cplusplus
};
#endif
#endif

173
audiolib/ll_man.c Executable file
View File

@ -0,0 +1,173 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: LL_MAN.C
author: James R. Dose
date: January 1, 1994
Linked list management routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#define LOCKMEMORY
#include <stddef.h>
#include "ll_man.h"
#ifdef LOCKMEMORY
#include "dpmi.h"
#endif
#define OFFSET( structure, offset ) \
( *( ( char ** )&( structure )[ offset ] ) )
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define LL_LockStart LL_AddNode
void LL_AddNode
(
char *item,
char **head,
char **tail,
int next,
int prev
)
{
OFFSET( item, prev ) = NULL;
OFFSET( item, next ) = *head;
if ( *head )
{
OFFSET( *head, prev ) = item;
}
else
{
*tail = item;
}
*head = item;
}
void LL_RemoveNode
(
char *item,
char **head,
char **tail,
int next,
int prev
)
{
if ( OFFSET( item, prev ) == NULL )
{
*head = OFFSET( item, next );
}
else
{
OFFSET( OFFSET( item, prev ), next ) = OFFSET( item, next );
}
if ( OFFSET( item, next ) == NULL )
{
*tail = OFFSET( item, prev );
}
else
{
OFFSET( OFFSET( item, next ), prev ) = OFFSET( item, prev );
}
OFFSET( item, next ) = NULL;
OFFSET( item, prev ) = NULL;
}
/*---------------------------------------------------------------------
Function: LL_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void LL_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: LL_UnlockMemory
Unlocks all neccessary data.
---------------------------------------------------------------------*/
void LL_UnlockMemory
(
void
)
{
#ifdef LOCKMEMORY
DPMI_UnlockMemoryRegion( LL_LockStart, LL_LockEnd );
#endif
}
/*---------------------------------------------------------------------
Function: LL_LockMemory
Locks all neccessary data.
---------------------------------------------------------------------*/
int LL_LockMemory
(
void
)
{
#ifdef LOCKMEMORY
int status;
status = DPMI_LockMemoryRegion( LL_LockStart, LL_LockEnd );
if ( status != DPMI_Ok )
{
return( LL_Error );
}
#endif
return( LL_Ok );
}

76
audiolib/ll_man.h Executable file
View File

@ -0,0 +1,76 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: LL_MAN.H
author: James R. Dose
date: February 4, 1994
Public header for LL_MAN.C. Linked list management routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __LL_MAN_H
#define __LL_MAN_H
enum LL_Errors
{
LL_Warning = -2,
LL_Error = -1,
LL_Ok = 0
};
typedef struct list
{
void *start;
void *end;
} list;
void LL_AddNode( char *node, char **head, char **tail, int next, int prev );
void LL_RemoveNode( char *node, char **head, char **tail, int next, int prev );
void LL_UnlockMemory( void );
int LL_LockMemory( void );
#define LL_AddToHead( type, listhead, node ) \
LL_AddNode( ( char * )( node ), \
( char ** )&( ( listhead )->start ), \
( char ** )&( ( listhead )->end ), \
( int )&( ( type * ) 0 )->next, \
( int )&( ( type * ) 0 )->prev )
#define LL_AddToTail( type, listhead, node ) \
LL_AddNode( ( char * )( node ), \
( char ** )&( ( listhead )->end ), \
( char ** )&( ( listhead )->start ), \
( int )&( ( type * ) 0 )->prev, \
( int )&( ( type * ) 0 )->next )
#define LL_Remove( type, listhead, node ) \
LL_RemoveNode( ( char * )( node ), \
( char ** )&( ( listhead )->start ), \
( char ** )&( ( listhead )->end ), \
( int )&( ( type * ) 0 )->next, \
( int )&( ( type * ) 0 )->prev )
#define LL_NextNode( node ) ( ( node )->next )
#define LL_PreviousNode( node ) ( ( node )->prev )
#endif

2265
audiolib/midi.c Executable file

File diff suppressed because it is too large Load Diff

98
audiolib/midi.h Executable file
View File

@ -0,0 +1,98 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: MIDI.H
author: James R. Dose
date: May 25, 1994
Public header for MIDI.C. Midi song file playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MIDI_H
#define __MIDI_H
enum MIDI_Errors
{
MIDI_Warning = -2,
MIDI_Error = -1,
MIDI_Ok = 0,
MIDI_NullMidiModule,
MIDI_InvalidMidiFile,
MIDI_UnknownMidiFormat,
MIDI_NoTracks,
MIDI_InvalidTrack,
MIDI_NoMemory,
MIDI_DPMI_Error
};
#define MIDI_PASS_THROUGH 1
#define MIDI_DONT_PLAY 0
#define MIDI_MaxVolume 255
extern char MIDI_PatchMap[ 128 ];
typedef struct
{
void ( *NoteOff )( int channel, int key, int velocity );
void ( *NoteOn )( int channel, int key, int velocity );
void ( *PolyAftertouch )( int channel, int key, int pressure );
void ( *ControlChange )( int channel, int number, int value );
void ( *ProgramChange )( int channel, int program );
void ( *ChannelAftertouch )( int channel, int pressure );
void ( *PitchBend )( int channel, int lsb, int msb );
void ( *ReleasePatches )( void );
void ( *LoadPatch )( int number );
void ( *SetVolume )( int volume );
int ( *GetVolume )( void );
} midifuncs;
void MIDI_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
int MIDI_AllNotesOff( void );
void MIDI_SetUserChannelVolume( int channel, int volume );
void MIDI_ResetUserChannelVolume( void );
int MIDI_Reset( void );
int MIDI_SetVolume( int volume );
int MIDI_GetVolume( void );
void MIDI_SetMidiFuncs( midifuncs *funcs );
void MIDI_SetContext( int context );
int MIDI_GetContext( void );
void MIDI_SetLoopFlag( int loopflag );
void MIDI_ContinueSong( void );
void MIDI_PauseSong( void );
int MIDI_SongPlaying( void );
void MIDI_StopSong( void );
int MIDI_PlaySong( unsigned char *song, int loopflag );
void MIDI_SetTempo( int tempo );
int MIDI_GetTempo( void );
void MIDI_SetSongTick( unsigned long PositionInTicks );
void MIDI_SetSongTime( unsigned long milliseconds );
void MIDI_SetSongPosition( int measure, int beat, int tick );
void MIDI_GetSongPosition( songposition *pos );
void MIDI_GetSongLength( songposition *pos );
void MIDI_LoadTimbres( void );
void MIDI_UnlockMemory( void );
int MIDI_LockMemory( void );
#endif

451
audiolib/mpu401.c Executable file
View File

@ -0,0 +1,451 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: MPU401.C
author: James R. Dose
date: January 1, 1994
Low level routines to support sending of MIDI data to MPU401
compatible MIDI interfaces.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include "dpmi.h"
#include "user.h"
#include "mpu401.h"
#define MIDI_NOTE_OFF 0x80
#define MIDI_NOTE_ON 0x90
#define MIDI_POLY_AFTER_TCH 0xA0
#define MIDI_CONTROL_CHANGE 0xB0
#define MIDI_PROGRAM_CHANGE 0xC0
#define MIDI_AFTER_TOUCH 0xD0
#define MIDI_PITCH_BEND 0xE0
#define MIDI_META_EVENT 0xFF
#define MIDI_END_OF_TRACK 0x2F
#define MIDI_TEMPO_CHANGE 0x51
#define MIDI_MONO_MODE_ON 0x7E
#define MIDI_ALL_NOTES_OFF 0x7B
int MPU_BaseAddr = MPU_DefaultAddress;
//unsigned MPU_Delay = 500;
//unsigned MPU_Delay = 5000;
unsigned MPU_Delay = 0x5000;
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define MPU_LockStart MPU_SendMidi
/*---------------------------------------------------------------------
Function: MPU_SendMidi
Sends a byte of MIDI data to the music device.
---------------------------------------------------------------------*/
void MPU_SendMidi
(
int data
)
{
int port = MPU_BaseAddr + 1;
unsigned count;
count = MPU_Delay;
while( count > 0 )
{
// check if status port says we're ready for write
if ( !( inp( port ) & MPU_ReadyToWrite ) )
{
break;
}
count--;
}
port--;
// Send the midi data
outp( port, data );
}
/*---------------------------------------------------------------------
Function: MPU_NoteOff
Sends a full MIDI note off event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOff
(
int channel,
int key,
int velocity
)
{
MPU_SendMidi( MIDI_NOTE_OFF | channel );
MPU_SendMidi( key );
MPU_SendMidi( velocity );
}
/*---------------------------------------------------------------------
Function: MPU_NoteOn
Sends a full MIDI note on event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOn
(
int channel,
int key,
int velocity
)
{
MPU_SendMidi( MIDI_NOTE_ON | channel );
MPU_SendMidi( key );
MPU_SendMidi( velocity );
}
/*---------------------------------------------------------------------
Function: MPU_PolyAftertouch
Sends a full MIDI polyphonic aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_PolyAftertouch
(
int channel,
int key,
int pressure
)
{
MPU_SendMidi( MIDI_POLY_AFTER_TCH | channel );
MPU_SendMidi( key );
MPU_SendMidi( pressure );
}
/*---------------------------------------------------------------------
Function: MPU_ControlChange
Sends a full MIDI control change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ControlChange
(
int channel,
int number,
int value
)
{
MPU_SendMidi( MIDI_CONTROL_CHANGE | channel );
MPU_SendMidi( number );
MPU_SendMidi( value );
}
/*---------------------------------------------------------------------
Function: MPU_ProgramChange
Sends a full MIDI program change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ProgramChange
(
int channel,
int program
)
{
MPU_SendMidi( MIDI_PROGRAM_CHANGE | channel );
MPU_SendMidi( program );
}
/*---------------------------------------------------------------------
Function: MPU_ChannelAftertouch
Sends a full MIDI channel aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_ChannelAftertouch
(
int channel,
int pressure
)
{
MPU_SendMidi( MIDI_AFTER_TOUCH | channel );
MPU_SendMidi( pressure );
}
/*---------------------------------------------------------------------
Function: MPU_PitchBend
Sends a full MIDI pitch bend event out to the music device.
---------------------------------------------------------------------*/
void MPU_PitchBend
(
int channel,
int lsb,
int msb
)
{
MPU_SendMidi( MIDI_PITCH_BEND | channel );
MPU_SendMidi( lsb );
MPU_SendMidi( msb );
}
/*---------------------------------------------------------------------
Function: MPU_SendCommand
Sends a command to the MPU401 card.
---------------------------------------------------------------------*/
void MPU_SendCommand
(
int data
)
{
int port = MPU_BaseAddr + 1;
unsigned count;
count = 0xffff;
while( count > 0 )
{
// check if status port says we're ready for write
if ( !( inp( port ) & MPU_ReadyToWrite ) )
{
break;
}
count--;
}
outp( port, data );
}
/*---------------------------------------------------------------------
Function: MPU_Reset
Resets the MPU401 card.
---------------------------------------------------------------------*/
int MPU_Reset
(
void
)
{
int port = MPU_BaseAddr + 1;
unsigned count;
// Output "Reset" command via Command port
MPU_SendCommand( MPU_CmdReset );
// Wait for status port to be ready for read
count = 0xffff;
while( count > 0 )
{
if ( !( inp( port ) & MPU_ReadyToRead ) )
{
port--;
// Check for a successful reset
if ( inp( port ) == MPU_CmdAcknowledge )
{
return( MPU_Ok );
}
port++;
}
count--;
}
// Failed to reset : MPU-401 not detected
return( MPU_NotFound );
}
/*---------------------------------------------------------------------
Function: MPU_EnterUART
Sets the MPU401 card to operate in UART mode.
---------------------------------------------------------------------*/
int MPU_EnterUART
(
void
)
{
int port = MPU_BaseAddr + 1;
unsigned count;
// Output "Enter UART" command via Command port
MPU_SendCommand( MPU_CmdEnterUART );
// Wait for status port to be ready for read
count = 0xffff;
while( count > 0 )
{
if ( !( inp( port ) & MPU_ReadyToRead ) )
{
port--;
// Check for a successful reset
if ( inp( port ) == MPU_CmdAcknowledge )
{
return( MPU_Ok );
}
port++;
}
count--;
}
// Failed to reset : MPU-401 not detected
return( MPU_UARTFailed );
}
/*---------------------------------------------------------------------
Function: MPU_Init
Detects and initializes the MPU401 card.
---------------------------------------------------------------------*/
int MPU_Init
(
int addr
)
{
int status;
int count;
char *ptr;
ptr = USER_GetText( "MPUDELAY" );
if ( ptr != NULL )
{
MPU_Delay = ( unsigned )atol( ptr );
}
MPU_BaseAddr = addr;
count = 4;
while( count > 0 )
{
status = MPU_Reset();
if ( status == MPU_Ok )
{
return( MPU_EnterUART() );
}
count--;
}
return( status );
}
/*---------------------------------------------------------------------
Function: MPU_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void MPU_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: MPU_UnlockMemory
Locks all neccessary data.
---------------------------------------------------------------------*/
void MPU_UnlockMemory
(
void
)
{
DPMI_UnlockMemoryRegion( MPU_LockStart, MPU_LockEnd );
DPMI_Unlock( MPU_BaseAddr );
DPMI_Unlock( MPU_Delay );
}
/*---------------------------------------------------------------------
Function: MPU_LockMemory
Locks all neccessary data.
---------------------------------------------------------------------*/
int MPU_LockMemory
(
void
)
{
int status;
status = DPMI_LockMemoryRegion( MPU_LockStart, MPU_LockEnd );
status |= DPMI_Lock( MPU_BaseAddr );
status |= DPMI_Lock( MPU_Delay );
if ( status != DPMI_Ok )
{
MPU_UnlockMemory();
return( MPU_Error );
}
return( MPU_Ok );
}

61
audiolib/mpu401.h Executable file
View File

@ -0,0 +1,61 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __MPU401_H
#define __MPU401_H
#define MPU_DefaultAddress 0x330
enum MPU_ERRORS
{
MPU_Warning = -2,
MPU_Error = -1,
MPU_Ok = 0,
MPU_DPMI_Error
};
#define MPU_NotFound -1
#define MPU_UARTFailed -2
#define MPU_ReadyToWrite 0x40
#define MPU_ReadyToRead 0x80
#define MPU_CmdEnterUART 0x3f
#define MPU_CmdReset 0xff
#define MPU_CmdAcknowledge 0xfe
extern int MPU_BaseAddr;
extern unsigned MPU_Delay;
void MPU_SendCommand( int data );
void MPU_SendMidi( int data );
int MPU_Reset( void );
int MPU_EnterUART( void );
int MPU_Init( int addr );
void MPU_ResetMidi( void );
void MPU_NoteOff( int channel, int key, int velocity );
void MPU_NoteOn( int channel, int key, int velocity );
void MPU_PolyAftertouch( int channel, int key, int pressure );
void MPU_ControlChange( int channel, int number, int value );
void MPU_ProgramChange( int channel, int program );
void MPU_ChannelAftertouch( int channel, int pressure );
void MPU_PitchBend( int channel, int lsb, int msb );
void MPU_UnlockMemory( void );
int MPU_LockMemory( void );
#endif

3556
audiolib/multivoc.c Executable file

File diff suppressed because it is too large Load Diff

123
audiolib/multivoc.h Executable file
View File

@ -0,0 +1,123 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
file: MULTIVOC.H
author: James R. Dose
date: December 20, 1993
Public header for MULTIVOC.C
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MULTIVOC_H
#define __MULTIVOC_H
// platform.h is in buildengine, but I need the byteswapping macros... --ryan.
#include "../buildengine/platform.h"
#define MV_MinVoiceHandle 1
extern int MV_ErrorCode;
enum MV_Errors
{
MV_Warning = -2,
MV_Error = -1,
MV_Ok = 0,
MV_UnsupportedCard,
MV_NotInstalled,
MV_NoVoices,
MV_NoMem,
MV_VoiceNotFound,
MV_BlasterError,
MV_PasError,
MV_SoundScapeError,
MV_SoundSourceError,
MV_DPMI_Error,
MV_InvalidVOCFile,
MV_InvalidWAVFile,
MV_InvalidMixMode,
MV_SoundSourceFailure,
MV_IrqFailure,
MV_DMAFailure,
MV_DMA16Failure,
MV_NullRecordFunction
};
char *MV_ErrorString( int ErrorNumber );
int MV_VoicePlaying( int handle );
int MV_KillAllVoices( void );
int MV_Kill( int handle );
int MV_VoicesPlaying( void );
int MV_VoiceAvailable( int priority );
int MV_SetPitch( int handle, int pitchoffset );
int MV_SetFrequency( int handle, int frequency );
int MV_EndLooping( int handle );
int MV_SetPan( int handle, int vol, int left, int right );
int MV_Pan3D( int handle, int angle, int distance );
void MV_SetReverb( int reverb );
void MV_SetFastReverb( int reverb );
int MV_GetMaxReverbDelay( void );
int MV_GetReverbDelay( void );
void MV_SetReverbDelay( int delay );
int MV_SetMixMode( int numchannels, int samplebits );
int MV_StartPlayback( void );
void MV_StopPlayback( void );
int MV_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
void MV_StopRecord( void );
int MV_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
int rate, int pitchoffset, int vol, int left, int right,
int priority, unsigned long callbackval );
int MV_PlayRaw( char *ptr, unsigned long length,
unsigned rate, int pitchoffset, int vol, int left,
int right, int priority, unsigned long callbackval );
int MV_PlayLoopedRaw( char *ptr, unsigned long length,
char *loopstart, char *loopend, unsigned rate, int pitchoffset,
int vol, int left, int right, int priority,
unsigned long callbackval );
int MV_PlayWAV( char *ptr, int pitchoffset, int vol, int left,
int right, int priority, unsigned long callbackval );
int MV_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
int priority, unsigned long callbackval );
int MV_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
int pitchoffset, int vol, int left, int right, int priority,
unsigned long callbackval );
int MV_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,
int priority, unsigned long callbackval );
int MV_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
int priority, unsigned long callbackval );
int MV_PlayLoopedVOC( char *ptr, long loopstart, long loopend,
int pitchoffset, int vol, int left, int right, int priority,
unsigned long callbackval );
void MV_CreateVolumeTable( int index, int volume, int MaxVolume );
void MV_SetVolume( int volume );
int MV_GetVolume( void );
void MV_SetCallBack( void ( *function )( unsigned long ) );
void MV_SetReverseStereo( int setting );
int MV_GetReverseStereo( void );
int MV_Init( int soundcard, int MixRate, int Voices, int numchannels,
int samplebits );
int MV_Shutdown( void );
void MV_UnlockMemory( void );
int MV_LockMemory( void );
#endif

1035
audiolib/music.c Executable file

File diff suppressed because it is too large Load Diff

96
audiolib/music.h Executable file
View File

@ -0,0 +1,96 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: MUSIC.H
author: James R. Dose
date: March 25, 1994
Public header for MUSIC.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MUSIC_H
#define __MUSIC_H
#include "sndcards.h"
#ifndef PLAT_DOS
#define cdecl
#endif
extern int MUSIC_ErrorCode;
enum MUSIC_ERRORS
{
MUSIC_Warning = -2,
MUSIC_Error = -1,
MUSIC_Ok = 0,
MUSIC_ASSVersion,
MUSIC_SoundCardError,
MUSIC_MPU401Error,
MUSIC_InvalidCard,
MUSIC_MidiError,
MUSIC_TaskManError,
MUSIC_FMNotDetected,
MUSIC_DPMI_Error
};
typedef struct
{
unsigned long tickposition;
unsigned long milliseconds;
unsigned int measure;
unsigned int beat;
unsigned int tick;
} songposition;
#define MUSIC_LoopSong ( 1 == 1 )
#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
char *MUSIC_ErrorString( int ErrorNumber );
int MUSIC_Init( int SoundCard, int Address );
int MUSIC_Shutdown( void );
void MUSIC_SetMaxFMMidiChannel( int channel );
void MUSIC_SetVolume( int volume );
void MUSIC_SetMidiChannelVolume( int channel, int volume );
void MUSIC_ResetMidiChannelVolumes( void );
int MUSIC_GetVolume( void );
void MUSIC_SetLoopFlag( int loopflag );
int MUSIC_SongPlaying( void );
void MUSIC_Continue( void );
void MUSIC_Pause( void );
int MUSIC_StopSong( void );
int MUSIC_PlaySong( unsigned char *song, int loopflag );
void MUSIC_SetContext( int context );
int MUSIC_GetContext( void );
void MUSIC_SetSongTick( unsigned long PositionInTicks );
void MUSIC_SetSongTime( unsigned long milliseconds );
void MUSIC_SetSongPosition( int measure, int beat, int tick );
void MUSIC_GetSongPosition( songposition *pos );
void MUSIC_GetSongLength( songposition *pos );
int MUSIC_FadeVolume( int tovolume, int milliseconds );
int MUSIC_FadeActive( void );
void MUSIC_StopFade( void );
void MUSIC_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
void MUSIC_RegisterTimbreBank( unsigned char *timbres );
#endif

505
audiolib/mv_mix.asm Executable file
View File

@ -0,0 +1,505 @@
IDEAL
p386
MODEL flat
dataseg
CODESEG
MASM
ALIGN 4
EXTRN _MV_HarshClipTable:DWORD
EXTRN _MV_MixDestination:DWORD
EXTRN _MV_MixPosition:DWORD
EXTRN _MV_LeftVolume:DWORD
EXTRN _MV_RightVolume:DWORD
EXTRN _MV_SampleSize:DWORD
EXTRN _MV_RightChannelOffset:DWORD
;================
;
; MV_Mix8BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix8BitMono_
PUBLIC MV_Mix8BitMono_
; Two at once
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET apatch7+2 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET apatch8+2 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET apatch9+3 ; convice tasm to modify code...
mov [eax],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov eax,OFFSET apatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET apatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov eax,OFFSET apatch3+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET apatch4+2 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET apatch5+2 ; convice tasm to modify code...
mov [eax],edx
mov eax,OFFSET apatch6+2 ; convice tasm to modify code...
mov [eax],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je short exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 1 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
movzx eax, byte ptr [esi+edx] ; get third sample
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
ENDP MV_Mix8BitMono_
;================
;
; MV_Mix8BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix8BitStereo_
PUBLIC MV_Mix8BitStereo_
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET bpatch8+2 ; convice tasm to modify code...
mov [eax],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov eax,OFFSET bpatch6+3 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET bpatch7+2 ; convice tasm to modify code...
mov [eax],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET bpatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov ebx, _MV_RightVolume
mov eax,OFFSET bpatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET bpatch3+2 ; convice tasm to modify code...
mov [eax],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov eax,OFFSET bpatch4+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET bpatch5+2 ; convice tasm to modify code...
mov [eax],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 2 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
ENDP MV_Mix8BitStereo_
;================
;
; MV_Mix16BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix16BitMono_
PUBLIC MV_Mix16BitMono_
; Two at once
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET cpatch5+3 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET cpatch6+3 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET cpatch7+2 ; convice tasm to modify code...
add bl,bl
mov [eax],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET cpatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET cpatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET cpatch3+2 ; convice tasm to modify code...
mov [eax],edx
mov eax,OFFSET cpatch4+2 ; convice tasm to modify code...
mov [eax],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
ALIGN 4
mix16Mloop:
movsx edx, word ptr [edi] ; get current sample from destination
cpatch1:
movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
add ebx, edx ; mix second sample
mov [edi], ax ; write new sample to destination
mov edx, ebp ; begin calculating third sample
cmp ebx, -32768 ; Harsh clip sample
jge short m16skip3
mov ebx, -32768
jmp short m16skip4
m16skip3:
cmp ebx, 32767
jle short m16skip4
mov ebx, 32767
m16skip4:
cpatch3:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
cpatch6:
mov [edi + 2], bx ; write new sample to destination
shr eax, 16 ; finish calculation for fourth sample
cpatch4:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
cpatch7:
add edi, 4 ; move destination to third sample
movzx eax, byte ptr [esi+edx] ; get third sample
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
ENDP MV_Mix16BitMono_
;================
;
; MV_Mix16BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix16BitStereo_
PUBLIC MV_Mix16BitStereo_
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET dpatch6+2 ; convice tasm to modify code...
mov [eax],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov eax,OFFSET dpatch4+3 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET dpatch5+3 ; convice tasm to modify code...
mov [eax],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET dpatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov ebx, _MV_RightVolume
mov eax,OFFSET dpatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET dpatch3+2 ; convice tasm to modify code...
mov [eax],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
ALIGN 4
mix16Sloop:
dpatch1:
movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample
movsx edx, word ptr [edi] ; get current sample from destination
dpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
dpatch3:
add ebp,12345678h ; advance frac pointer
dpatch4:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
add ebx, edx ; mix right sample
mov [edi], ax ; write left sample to destination
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch5:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch6:
add edi, 4 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
ENDP MV_Mix16BitStereo_
ENDS
END

293
audiolib/mv_mix.c Executable file
View File

@ -0,0 +1,293 @@
#include "multivoc.h"
extern char *MV_MixDestination;
extern unsigned long MV_MixPosition;
extern char *MV_LeftVolume;
extern char *MV_RightVolume;
extern unsigned char *MV_HarshClipTable;
extern int MV_RightChannelOffset;
extern int MV_SampleSize;
void MV_Mix8BitMono( unsigned long position, unsigned long rate,
const char *start, unsigned long length )
{
const unsigned char *src;
unsigned char *dest;
unsigned int i;
src = (const unsigned char *)start;
dest = (unsigned char *)MV_MixDestination;
for (i = 0; i < length; i++) {
int s = src[position >> 16];
int d = *dest;
s = MV_LeftVolume[s * 2];
s += d;
s = MV_HarshClipTable[s + 0x80];
*dest = (s & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitStereo( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const unsigned char *src;
unsigned char *dest;
unsigned int i;
src = (const unsigned char *)start;
dest = (unsigned char *)MV_MixDestination;
for (i = 0; i < length; i++) {
int s = src[(position >> 16)];
int dl = dest[0];
int dr = dest[MV_RightChannelOffset];
dl += MV_LeftVolume[s * 2];
dr += MV_RightVolume[s * 2];
dl = MV_HarshClipTable[dl + 0x80];
dr = MV_HarshClipTable[dr + 0x80];
dest[0] = (dl & 0xff);
dest[MV_RightChannelOffset] = (dr & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitMono( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const short *MV_LeftVolumeS;
const unsigned char *src;
short *dest;
unsigned int i;
src = (const unsigned char *)start;
dest = (short *)MV_MixDestination;
MV_LeftVolumeS = (const short *)MV_LeftVolume;
for (i = 0; i < length; i++) {
int s = src[position >> 16];
int d = dest[0];
s = MV_LeftVolumeS[s];
s += d;
if (s < -32768) s = -32768;
if (s > 32767) s = 32767;
*dest = (short) s;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitStereo( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const short *MV_LeftVolumeS;
const short *MV_RightVolumeS;
const unsigned char *src;
short *dest;
unsigned int i;
src = (unsigned char *)start;
dest = (short *)MV_MixDestination;
MV_LeftVolumeS = (const short *)MV_LeftVolume;
MV_RightVolumeS = (const short *)MV_RightVolume;
for (i = 0; i < length; i++) {
int s = src[position >> 16];
int dl = dest[0];
int dr = dest[MV_RightChannelOffset/2];
dl += MV_LeftVolumeS[s];
dr += MV_RightVolumeS[s];
if (dl < -32768) dl = -32768;
if (dl > 32767) dl = 32767;
if (dr < -32768) dr = -32768;
if (dr > 32767) dr = 32767;
dest[0] = (short) dl;
dest[MV_RightChannelOffset/2] = (short) dr;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
const char *start, unsigned long length )
{
const char *src;
unsigned char *dest;
unsigned int i;
src = (const char *)start + 1;
dest = (unsigned char *)MV_MixDestination;
for (i = 0; i < length; i++) {
int s = (int)src[(position >> 16) * 2] + 0x80;
int d = *dest;
s = MV_LeftVolume[s * 2];
s += d;
s = MV_HarshClipTable[s + 0x80];
*dest = (s & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitStereo16( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const char *src;
unsigned char *dest;
unsigned int i;
src = (const char *)start + 1;
dest = (unsigned char *)MV_MixDestination;
for (i = 0; i < length; i++) {
int s = src[(position >> 16) * 2] + 0x80;
int dl = dest[0];
int dr = dest[MV_RightChannelOffset];
dl += MV_LeftVolume[s * 2];
dr += MV_RightVolume[s * 2];
dl = MV_HarshClipTable[dl + 0x80];
dr = MV_HarshClipTable[dr + 0x80];
dest[0] = (dl & 0xff);
dest[MV_RightChannelOffset] = (dr & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitMono16( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const short *MV_LeftVolumeS;
const unsigned char *src;
short *dest;
unsigned int i;
src = (const unsigned char *)start;
dest = (short *)MV_MixDestination;
MV_LeftVolumeS = (const short *)MV_LeftVolume;
for (i = 0; i < length; i++) {
int sl = src[(position >> 16) * 2 + 0];
int sh = src[(position >> 16) * 2 + 1] ^ 0x80;
int d = *dest;
sl = MV_LeftVolume[sl * 2 + 1];
sh = MV_LeftVolumeS[sh];
d = sl + sh + 0x80 + d;
if (d < -32768) d = -32768;
if (d > 32767) d = 32767;
*dest = (short) d;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitStereo16( unsigned long position,
unsigned long rate, const char *start, unsigned long length )
{
const short *MV_LeftVolumeS;
const short *MV_RightVolumeS;
const unsigned char *src;
short *dest;
unsigned int i;
src = (const unsigned char *)start;
dest = (short *)MV_MixDestination;
MV_LeftVolumeS = (const short *)MV_LeftVolume;
MV_RightVolumeS = (const short *)MV_RightVolume;
for (i = 0; i < length; i++) {
int sl = src[(position >> 16) * 2 + 0];
int sh = src[(position >> 16) * 2 + 1] ^ 0x80;
int dl = dest[0];
int dr = dest[MV_RightChannelOffset/2];
int sll = MV_LeftVolume[sl * 2 + 1];
int slh = MV_LeftVolumeS[sh];
int srl = MV_RightVolume[sl * 2 + 1];
int srh = MV_RightVolumeS[sh];
dl = sll + slh + 0x80 + dl;
dr = srl + srh + 0x80 + dr;
if (dl < -32768) dl = -32768;
if (dl > 32767) dl = 32767;
if (dr < -32768) dr = -32768;
if (dr > 32767) dr = 32767;
dest[0] = (short) dl;
dest[MV_RightChannelOffset/2] = (short) dr;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}

524
audiolib/mv_mix16.asm Executable file
View File

@ -0,0 +1,524 @@
IDEAL
p386
MODEL flat
dataseg
CODESEG
MASM
ALIGN 4
EXTRN _MV_HarshClipTable:DWORD
EXTRN _MV_MixDestination:DWORD
EXTRN _MV_MixPosition:DWORD
EXTRN _MV_LeftVolume:DWORD
EXTRN _MV_RightVolume:DWORD
EXTRN _MV_SampleSize:DWORD
EXTRN _MV_RightChannelOffset:DWORD
;================
;
; MV_Mix8BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix8BitMono16_
PUBLIC MV_Mix8BitMono16_
; Two at once
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET apatch7+2 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET apatch8+2 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET apatch9+3 ; convice tasm to modify code...
mov [eax],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov eax,OFFSET apatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET apatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov eax,OFFSET apatch3+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET apatch4+2 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET apatch5+2 ; convice tasm to modify code...
mov [eax],edx
mov eax,OFFSET apatch6+2 ; convice tasm to modify code...
mov [eax],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movsx eax, byte ptr [esi+2*eax] ; get first sample
movsx ebx, byte ptr [esi+2*ebx] ; get second sample
add eax, 80h
add ebx, 80h
ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 2 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movsx ebx, byte ptr [esi+2*eax] ; get fourth sample
movsx eax, byte ptr [esi+2*edx] ; get third sample
add ebx, 80h
add eax, 80h
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
ENDP MV_Mix8BitMono16_
;================
;
; MV_Mix8BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix8BitStereo16_
PUBLIC MV_Mix8BitStereo16_
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET bpatch8+2 ; convice tasm to modify code...
mov [eax],bl
; mov eax,OFFSET bpatch9+2 ; convice tasm to modify code...
; mov [eax],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov eax,OFFSET bpatch6+3 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET bpatch7+2 ; convice tasm to modify code...
mov [eax],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET bpatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov ebx, _MV_RightVolume
mov eax,OFFSET bpatch2+4 ; convice tasm to modify code...
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET bpatch3+2 ; convice tasm to modify code...
mov [eax],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov eax,OFFSET bpatch4+2 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET bpatch5+2 ; convice tasm to modify code...
mov [eax],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movsx ebx, byte ptr [esi+2*eax] ; get first sample
add ebx, 80h
ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 1 ; move destination to second sample
movsx ebx, byte ptr [esi+2*edx] ; get second sample
add ebx, 80h
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
ENDP MV_Mix8BitStereo16_
;================
;
; MV_Mix16BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix16BitMono16_
PUBLIC MV_Mix16BitMono16_
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET cpatch4+2 ; convice tasm to modify code...
mov [eax],bl
mov eax,OFFSET cpatch5+3 ; convice tasm to modify code...
mov [eax],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET cpatch2+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET cpatch1+4 ; convice tasm to modify code...
inc ebx
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET cpatch3+2 ; convice tasm to modify code...
mov [eax],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov ebx,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for first sample
movzx eax, word ptr [esi+2*ebx] ; get low byte of sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
movsx edx, word ptr [edi] ; get current sample from destination
ALIGN 4
mix16Mloop:
cpatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
add eax, edx ; mix low byte of sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
mov ebx, ebp ; begin calculating second sample
mov [edi], ax ; write new sample to destination
shr ebx, 16 ; finish calculation for second sample
cpatch3:
add ebp, 12345678h ; advance frac pointer
movzx eax, word ptr [esi+2*ebx] ; get second sample
cpatch4:
add edi, 2 ; move destination to second sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
ENDP MV_Mix16BitMono16_
;================
;
; MV_Mix16BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
PROC MV_Mix16BitStereo16_
PUBLIC MV_Mix16BitStereo16_
pushad
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov eax,OFFSET dpatch9+2 ; convice tasm to modify code...
mov [eax],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov eax,OFFSET dpatch7+3 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET dpatch8+3 ; convice tasm to modify code...
mov [eax],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov eax,OFFSET dpatch1+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET dpatch2+4 ; convice tasm to modify code...
inc ebx
mov [eax],ebx
mov ebx, _MV_RightVolume
mov eax,OFFSET dpatch3+4 ; convice tasm to modify code...
mov [eax],ebx
mov eax,OFFSET dpatch4+4 ; convice tasm to modify code...
inc ebx
mov [eax],ebx
; Rate scale ptr
mov eax,OFFSET dpatch5+2 ; convice tasm to modify code...
mov [eax],edx
; Source ptr
mov eax,OFFSET dpatch6+4 ; convice tasm to modify code...
mov [eax],esi
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; esi - scratch
; ecx - count
; edi - destination
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov ebx,ebp ; begin calculating first sample
shr ebx,16 ; finish calculation for first sample
movzx edx, word ptr [esi+2*ebx] ; get first sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
ALIGN 4
mix16Sloop:
; Left channel
dpatch1:
movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch2:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
; Right channel
dpatch3:
movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch4:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample
dpatch7:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
dpatch5:
add ebp,12345678h ; advance frac pointer
add eax, edx ; mix left sample
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
movsx edx, word ptr [edi+2] ; get current sample from destination
mov [edi], ax ; write left sample to destination
add ebx, edx ; mix right sample
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch8:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch9:
add edi, 4 ; move destination to second sample
dpatch6:
movzx edx, word ptr [2*edx+12345678h] ; get second sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
ENDP MV_Mix16BitStereo16_
ENDS
END

181
audiolib/mvreverb.asm Executable file
View File

@ -0,0 +1,181 @@
IDEAL
p386
MODEL flat
dataseg
CODESEG
MASM
ALIGN 4
;================
;
; MV_16BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
PROC MV_16BitReverb_
PUBLIC MV_16BitReverb_
mov esi, eax
lea edi, [edx - 2]
ALIGN 4
rev16loop:
movzx eax, word ptr [esi] ; get sample
add edi, 2
movzx edx, ah
sub ah, ah
movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample
xor edx, 80h
movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample
add esi, 2
lea eax, [ eax + edx + 80h ] ; mix high byte of sample
dec ecx ; decrement count
mov [edi], ax ; write new sample to destination
jnz rev16loop ; loop
ret
ENDP MV_16BitReverb_
;================
;
; MV_8BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
PROC MV_8BitReverb_
PUBLIC MV_8BitReverb_
mov esi, eax
lea edi, [edx - 1]
xor eax, eax
ALIGN 4
rev8loop:
; movzx eax, byte ptr [esi] ; get sample
mov al, byte ptr [esi] ; get sample
inc edi
; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample
mov al, byte ptr [2*eax+ebx] ; volume translate sample
inc esi
; add eax, 80h
add al, 80h
dec ecx ; decrement count
mov [edi], al ; write new sample to destination
jnz rev8loop ; loop
ret
ENDP MV_8BitReverb_
;================
;
; MV_16BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
PROC MV_16BitReverbFast_
PUBLIC MV_16BitReverbFast_
mov esi, eax
mov eax,OFFSET rpatch16+3
mov [eax],cl
lea edi, [edx - 2]
ALIGN 4
frev16loop:
mov ax, word ptr [esi] ; get sample
add edi, 2
rpatch16:
sar ax, 5 ;;;;Add 1 before shift
add esi, 2
mov [edi], ax ; write new sample to destination
dec ebx ; decrement count
jnz frev16loop ; loop
ret
ENDP MV_16BITREVERBFAST_
;================
;
; MV_8BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
PROC MV_8BitReverbFast_
PUBLIC MV_8BitReverbFast_
mov esi, eax
mov eax,OFFSET rpatch8+2
mov edi, edx
mov edx, 80h
mov [eax],cl
mov eax, 80h
shr eax, cl
dec edi
sub edx, eax
ALIGN 4
frev8loop:
mov al, byte ptr [esi] ; get sample
inc esi
mov ecx, eax
inc edi
rpatch8:
shr eax, 3
xor ecx, 80h ; flip the sign bit
shr ecx, 7 ; shift the sign down to 1
add eax, edx
add eax, ecx ; add sign bit to round to 0
dec ebx ; decrement count
mov [edi], al ; write new sample to destination
jnz frev8loop ; loop
ret
ENDP MV_8BITREVERBFAST_
ENDS
END

63
audiolib/mvreverb.c Executable file
View File

@ -0,0 +1,63 @@
#include "multivoc.h"
#include "_multivc.h"
void MV_16BitReverb( const char *src, char *dest, const VOLUME16 *volume, int count )
{
int i;
short *pdest = (short *)dest;
for (i = 0; i < count; i++) {
#if PLATFORM_BIGENDIAN
int sl = src[i*2+1];
int sh = src[i*2+0] ^ 0x80;
#else
int sl = src[i*2+0];
int sh = src[i*2+1] ^ 0x80;
#endif
sl = (*volume)[sl] >> 8;
sh = (*volume)[sh];
pdest[i] = (short)(sl + sh + 0x80);
}
}
void MV_8BitReverb( const signed char *src, signed char *dest, const VOLUME16 *volume, int count )
{
int i;
for (i = 0; i < count; i++) {
unsigned char s = (unsigned char) src[i];
s = (*volume)[s] & 0xff;
dest[i] = (char)(s + 0x80);
}
}
void MV_16BitReverbFast( const char *src, char *dest, int count, int shift )
{
int i;
short *pdest = (short *)dest;
const short *psrc = (const short *)src;
for (i = 0; i < count; i++) {
pdest[i] = psrc[i] >> shift;
}
}
void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift )
{
int i;
unsigned char sh = 0x80 - (0x80 >> shift);
for (i = 0; i < count; i++) {
unsigned char a = ((unsigned char) src[i]) >> shift;
unsigned char c = (((unsigned char) src[i]) ^ 0x80) >> 7;
dest[i] = (signed char) (a + sh + c);
}
}

310
audiolib/myprint.c Executable file
View File

@ -0,0 +1,310 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "myprint.h"
static unsigned short disp_offset = 160 * 24;
void DrawText
(
int x,
int y,
int ch,
int foreground,
int background
)
{
char *vid;
vid = ( char * )( 0xb0000 );
vid += y * 160;
vid += x * 2;
if ( ch != NONE )
{
*vid = ch;
}
vid++;
*vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
}
void TextBox
(
int x1,
int y1,
int x2,
int y2,
int ch,
int foreground,
int background
)
{
int x;
int y;
for( x = x1; x <= x2; x++ )
{
for( y = y1; y <= y2; y++ )
{
DrawText( x, y, ch, foreground, background );
}
}
}
void TextFrame
(
int x1,
int y1,
int x2,
int y2,
int type,
int foreground,
int background
)
{
int x;
int y;
if ( type == 0 )
{
for( x = x1 + 1; x < x2; x++ )
{
DrawText( x, y1, type, foreground, background );
DrawText( x, y2, type, foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawText( x1, y, type, foreground, background );
DrawText( x2, y, type, foreground, background );
}
}
if ( type == SINGLE_FRAME )
{
DrawText( x1, y1, 'Ú', foreground, background );
DrawText( x2, y1, '¿', foreground, background );
DrawText( x1, y2, 'À', foreground, background );
DrawText( x2, y2, 'Ù', foreground, background );
for( x = x1 + 1; x < x2; x++ )
{
DrawText( x, y1, 'Ä', foreground, background );
DrawText( x, y2, 'Ä', foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawText( x1, y, '³', foreground, background );
DrawText( x2, y, '³', foreground, background );
}
}
if ( type == DOUBLE_FRAME )
{
DrawText( x1, y1, 'É', foreground, background );
DrawText( x2, y1, '»', foreground, background );
DrawText( x1, y2, 'È', foreground, background );
DrawText( x2, y2, '¼', foreground, background );
for( x = x1 + 1; x < x2; x++ )
{
DrawText( x, y1, 'Í', foreground, background );
DrawText( x, y2, 'Í', foreground, background );
}
for( y = y1 + 1; y < y2; y++ )
{
DrawText( x1, y, 'º', foreground, background );
DrawText( x2, y, 'º', foreground, background );
}
}
}
void mysetxy
(
int x,
int y
)
{
disp_offset = ( x * 2 ) + ( y * 160 );
}
void myputch
(
char ch
)
{
int j;
char *disp_start = (char *)( 0xb0000 );
if ( disp_offset >= 160 * 24 )
{
for ( j = 160; j < 160 * 24; j += 2 )
{
*( disp_start + j - 160 ) = *( disp_start + j );
}
disp_offset = 160 * 23;
for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
if ( ch >= 32 )
{
*( disp_start + disp_offset ) = ch;
disp_offset = disp_offset + 2;
}
if ( ch == '\r' )
{
disp_offset = disp_offset / 160;
disp_offset = disp_offset * 160;
}
if ( ch == '\n' )
{
disp_offset = disp_offset + 160;
if ( disp_offset < 160 * 24 )
{
for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
160 ); j += 2 )
{
*( disp_start + j ) = ' ';
}
}
}
}
int printstring
(
char *string
)
{
int count;
char *ptr;
ptr = string;
count = 0;
while ( *ptr )
{
myputch( *ptr );
count++;
ptr++;
}
return( count );
}
int printnum
(
int number
)
{
char string[ 100 ];
int count;
itoa( number, string, 10 );
count = printstring( string );
return( count );
}
int printunsigned
(
unsigned long number,
int radix
)
{
char string[ 100 ];
int count;
ultoa( number, string, radix );
count = printstring( string );
return( count );
}
int myprintf
(
char *fmt,
...
)
{
va_list argptr;
int count;
char *ptr;
return( 0 );
// DEBUG
mysetxy( 0, 0 );
va_start( argptr, fmt );
ptr = fmt;
count = 0;
while( *ptr != 0 )
{
if ( *ptr == '%' )
{
ptr++;
switch( *ptr )
{
case 0 :
return( EOF );
break;
case 'd' :
count += printnum( va_arg( argptr, int ) );
break;
case 's' :
count += printstring( va_arg( argptr, char * ) );
break;
case 'u' :
count += printunsigned( va_arg( argptr, int ), 10 );
break;
case 'x' :
case 'X' :
count += printunsigned( va_arg( argptr, int ), 16 );
break;
}
ptr++;
}
else
{
myputch( *ptr );
count++;
ptr++;
}
}
va_end( argptr );
return( count );
}

43
audiolib/myprint.h Executable file
View File

@ -0,0 +1,43 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
#ifndef __MYPRINT_H
#define __MYPRINT_H
enum COLORS
{
BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,
LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
};
#define NONE -1
#define SINGLE_FRAME -1
#define DOUBLE_FRAME -2
void DrawText( int x, int y, int ch, int foreground, int background );
void TextBox( int x1, int y1, int x2, int y2, int ch, int foreground, int background );
void TextFrame( int x1, int y1, int x2, int y2, int type, int foreground, int background );
void mysetxy( int x, int y );
void myputch( char ch );
int printstring( char *string );
int printnum( int number );
int printunsigned( unsigned long number, int radix );
int myprintf( char *fmt, ... );
#endif

431
audiolib/newgf1.h Executable file
View File

@ -0,0 +1,431 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/***************************************************************************
* NAME: GF1.H
** COPYRIGHT:
** "Copyright (c) 1991,1992, by FORTE
**
** "This software is furnished under a license and may be used,
** copied, or disclosed only in accordance with the terms of such
** license and with the inclusion of the above copyright notice.
** This software or any other copies thereof may not be provided or
** otherwise made available to any other person. No title to and
** ownership of the software is hereby transfered."
****************************************************************************
* CREATION DATE: 07/01/92
*--------------------------------------------------------------------------*
* VERSION DATE NAME DESCRIPTION
*> 1.0 07/01/92 Original
***************************************************************************/
#ifndef _GF1_H /* allow header to be processed only once */
#define _GF1_H
/* error codes */
#define OK 0
#define NO_MORE_VOICES -1
#define BASE_NOT_FOUND 1
#define BAD_IRQ 2
#define BAD_DMA 3
#define OS_LOADED 4
#define NOT_LOADED 5
#define NO_MEMORY 6
#define DMA_BUSY 7
#define NO_MORE_HANDLERS 8
#define DMA_HUNG 9
#define CARD_NOT_FOUND 10
#define CARD_BEING_USED 11
#define NO_MORE_INTERRUPTS 12
#define BAD_TIMER 13
#define BAD_PATCH 14
#define OLD_PATCH 15
#define DOS_ERROR 16
#define FILE_NOT_FOUND 17
/* bits */
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
/* bounds for volume enveloping functions */
#define MIN_OFFSET 5U
#define MAX_OFFSET 251U
/* bounds for voice allocation */
#define MIN_VOICES 14
#define MAX_VOICES 32
/* DMA control bits */
#define DMA_ENABLE BIT0
#define DMA_READ BIT1
#define DMA_WIDTH_16 BIT2 /* width of DMA channel */
#define DMA_RATE_DIV_1 BIT3
#define DMA_RATE_DIV_2 BIT4
#define DMA_IRQ_ENABLE BIT5
#define DMA_IRQ_PRESENT BIT6
#define DMA_DATA_16 BIT6 /* width of data */
#define DMA_INVERT_MSB BIT7
/* SAMPLE control bits */
#define DMA_STEREO 2
/* DMA flags */
#define GF1_RECORD 0 /* use dma control or sample control */
#define GF1_DMA 1
/* MIDI control register */
#define MIDI_RESET (BIT0|BIT1)
#define MIDI_TD_INT BIT5
#define MIDI_RD_INT BIT7
/* MIDI_STATUS_REGISTER */
#define MIDI_RD BIT0
#define MIDI_TD BIT1
#define MIDI_ERR_FRAMING BIT4
#define MIDI_ERR_OVERRUN BIT5
/* digital playback flags */
#define TYPE_8BIT BIT0 /* 1 use 8 bit data */
/* 0 use 16 bit data */
#define TYPE_PRELOAD BIT1 /* preload data */
#define TYPE_INVERT_MSB BIT2 /* invert most significant bit during dma */
#define TYPE_STEREO BIT3 /* 1 for stereo data */
/* sound effects and digital music types */
#define SND_LOOP_MASK (BIT0|BIT1)
#define SND_LOOP_NONE 0
#define SND_LOOP 1
#define SND_LOOP_BIDIR 2
#define SND_8BIT (BIT2)
#define SND_BACKWARD (BIT3)
#define SOUND_PLAYING 2
#define SOUND_ACTIVE 1
/* patch macros */
#define HEADER_SIZE 12
#define ID_SIZE 10
#define DESC_SIZE 60
#define RESERVED_SIZE 40
#define PATCH_HEADER_RESERVED_SIZE 36
#define LAYER_RESERVED_SIZE 40
#define PATCH_DATA_RESERVED_SIZE 36
#define GF1_HEADER_TEXT "GF1PATCH110"
#define INST_NAME_SIZE 16
#define ENVELOPES 6
#define MAX_LAYERS 4
/* patch modes */
#define PATCH_16 BIT0
#define PATCH_UNSIGNED BIT1
#define PATCH_LOOPEN BIT2
#define PATCH_BIDIR BIT3
#define PATCH_BACKWARD BIT4
#define PATCH_SUSTAIN BIT5
#define PATCH_NO_SRELEASE BIT6
#define PATCH_FAST_REL BIT7
/* flags for patch loading */
#define PATCH_LOAD_8_BIT BIT0
/* digital playback callback reasons & return values */
#define DIG_DONE 0
#define DIG_MORE_DATA 1
#define DIG_BUFFER_DONE 2
#define DIG_PAUSE 3
/* log table used for vibrato and pitch bend. log table made public for
** developers use */
#define LOG_TAB_SIZE 12
extern long gf1_log_table[LOG_TAB_SIZE];
#if defined(__BORLANDC__)
#undef RFAR
#define RFAR far
#elif defined(_MSC_VER) && (_MSC_VER <= 600)
#define RFAR far
#elif defined(_MSC_VER) && (_MSC_VER > 600)
#define RFAR __far
#else
#undef RFAR
#define RFAR
#endif
/* structure definitions */
struct load_os
{
unsigned short voices;
unsigned short forced_base_port;
unsigned char forced_gf1_irq;
unsigned char forced_midi_irq;
unsigned char forced_channel_in;
unsigned char forced_channel_out;
};
struct patchheader
{
char header[ HEADER_SIZE ];
char gravis_id[ ID_SIZE ]; /* Id = "ID#000002" */
char description[ DESC_SIZE ];
unsigned char instruments;
char voices;
char channels;
unsigned short wave_forms;
unsigned short master_volume;
unsigned long data_size;
char reserved[ PATCH_HEADER_RESERVED_SIZE ];
};
struct instrumentdata
{
unsigned short instrument;
char instrument_name[ INST_NAME_SIZE ];
long instrument_size;
char layers;
char reserved[ RESERVED_SIZE ];
};
struct layerdata
{
char layer_duplicate;
char layer;
long layer_size;
char samples;
char reserved[ LAYER_RESERVED_SIZE ];
};
struct patchdata
{
char wave_name[7];
unsigned char fractions;
long wave_size;
long start_loop;
long end_loop;
unsigned short sample_rate;
long low_frequency;
long high_frequency;
long root_frequency;
short tune;
unsigned char balance;
unsigned char envelope_rate[ ENVELOPES ];
unsigned char envelope_offset[ ENVELOPES ];
unsigned char tremolo_sweep;
unsigned char tremolo_rate;
unsigned char tremolo_depth;
unsigned char vibrato_sweep;
unsigned char vibrato_rate;
unsigned char vibrato_depth;
char modes;
short scale_frequency;
unsigned short scale_factor; /* from 0 to 2048 or 0 to 2 */
char reserved[ PATCH_DATA_RESERVED_SIZE ];
};
struct wave_struct
{
unsigned long start_loop;
unsigned long end_loop;
long low_frequency;
long high_frequency;
long root_frequency;
unsigned long mem;
unsigned short scale_frequency;
unsigned short sample_rate;
unsigned short scale_factor;
unsigned short start_acc_low;
unsigned short start_acc_high;
unsigned short start_low;
unsigned short start_high;
unsigned short end_low;
unsigned short end_high;
unsigned short end_acc_low;
unsigned short end_acc_high;
unsigned short sample_ratio;
unsigned long wave_size;
unsigned char fractions;
unsigned char balance;
unsigned char envelope_rate[ ENVELOPES ];
unsigned char envelope_offset[ ENVELOPES ];
unsigned char tremolo_sweep;
unsigned char tremolo_rate;
unsigned char tremolo_depth;
unsigned char vibrato_sweep;
unsigned char vibrato_rate;
unsigned char vibrato_depth;
unsigned char modes;
};
struct patchinfo {
struct patchheader header;
struct instrumentdata idata;
};
struct patch {
short nlayers;
struct wave_struct RFAR *layer_waves[MAX_LAYERS];
short layer_nwaves[MAX_LAYERS];
unsigned short detune;
};
struct gf1_dma_buff {
unsigned char RFAR *vptr;
unsigned long paddr;
};
struct gf1_sound {
unsigned long mem_pos;
unsigned long start_loop;
unsigned long end_loop;
unsigned char type;
};
/* GLOBAL VARIABLES (flags) */
extern char gf1_linear_volumes;
extern char gf1_dig_use_extra_voice;
/* FUNCTION PROTOTYPES */
/* Initializeation routines */
int gf1_init_ports(int);
int gf1_load_os(struct load_os RFAR *os);
int gf1_unload_os(void);
void gf1_set_appname(char RFAR *);
void reset_ultra(int);
int gf1_asm_init(void);
unsigned char gf1_peek(unsigned long address);
void gf1_poke(unsigned long address, unsigned char data);
void gf1_poke_block(unsigned char RFAR *data, unsigned long address, unsigned long len, unsigned char dma_control);
char gf1_good_dram(unsigned long address);
int GetUltraCfg(struct load_os RFAR *os);
unsigned long gf1_malloc(unsigned long);
void gf1_free(unsigned long);
unsigned long gf1_mem_avail(void);
unsigned long gf1_mem_largest_avail(void);
void gf1_delay(void);
int gf1_allocate_voice(int priority, void (RFAR *steal_notify)(int));
void gf1_free_voice(unsigned int i);
void gf1_adjust_priority(int voice, int priority);
int gf1_dram_xfer(struct gf1_dma_buff RFAR *dptr, unsigned long size, unsigned long dram_address, unsigned char dma_control, unsigned short flags);
void gf1_stop_dma(void);
long convert_to_16bit(long address);
int gf1_wait_dma(void);
int gf1_dma_ready(void);
unsigned long gf1_amount_xferred(void);
int gf1_detect_card(unsigned short port);
char *gf1_error_str(int);
int gf1_play_digital(unsigned short priority, unsigned char RFAR *buffer,
unsigned long size, unsigned long gf1_addr, unsigned short volume,
unsigned short pan, unsigned short frequency, unsigned char type,
struct gf1_dma_buff RFAR *dptr,
int (RFAR *callback)(int, int, unsigned char RFAR * RFAR *, unsigned long RFAR *));
void gf1_restart_digital(int voice);
void gf1_start_digital(int voice);
void gf1_pause_digital(int voice);
void RFAR gf1_stop_digital(int voice);
void gf1_dig_set_dma_rate(unsigned short rate);
unsigned long gf1_digital_position(int voice);
int gf1_myatoi(void);
int gf1_update_waveform(struct wave_struct RFAR *wave_info);
int gf1_get_patch_info(char RFAR *patch_file, struct patchinfo RFAR *patch);
int gf1_load_patch(char RFAR *patch_file, struct patchinfo RFAR *patchinfo,
struct patch RFAR *patch,
struct gf1_dma_buff RFAR *dptr, unsigned short size,
unsigned char RFAR *wavemem, int flags);
void gf1_unload_patch(struct patch RFAR *patch);
void gf1_detune_patch(struct patch RFAR *patch, unsigned short detune);
unsigned short gf1_calc_fc(unsigned int sample_ratio,long root,long frequency);
void gf1_midi_stop_voice(int voice);
void gf1_midi_wait_voice(int voice);
unsigned short gf1_midi_status_note(int voice);
unsigned short gf1_midi_status_voice(int voice);
void RFAR gf1_midi_stop_note(int note_voice);
void gf1_midi_note_on(struct patch RFAR *patch, int priority, int note, int velocity, int channel);
void gf1_midi_note_off(int note, int channel);
void gf1_midi_silence_patch_notes(struct patch RFAR *patch);
void gf1_midi_patch_removed(struct patch RFAR *patch);
int gf1_enable_timer1(int (RFAR *callback)(void), int resolution);
int gf1_enable_timer2(int (RFAR *callback)(void), int resolution);
void gf1_disable_timer1(void);
void gf1_disable_timer2(void);
void gf1_channel_pitch_bend(int channel, unsigned int bend);
void gf1_midi_synth_volume(unsigned short synth, int master_volume);
void gf1_midi_change_program(struct patch RFAR *patch, int channel);
void gf1_midi_set_vibrato(int channel, int value);
void gf1_midi_change_volume(int channel, unsigned int volume);
void gf1_midi_set_balance(int balance, int channel);
void gf1_midi_channel_sustain(int channel, int sustain);
void gf1_midi_all_notes_off(int channel);
void gf1_midi_pitch_bend(int channel, int lsb, int msb);
void gf1_midi_parameter(int channel, int control, int value);
int gf1_midi_get_channel_notes(int channel, int notes[]);
int gf1_midi_get_channel_volume(int channel);
int gf1_midi_get_master_volume(void);
int gf1_midi_get_volume(int voice);
unsigned short gf1_read(int handle, void RFAR *io_buffer, unsigned short size);
unsigned short gf1_close_file(int handle);
unsigned int gf1_seek(int handle, unsigned long offset, int method);
int gf1_open(char RFAR *name);
#ifdef __FLAT__
int gf1_atoi(char RFAR **str, int base);
#else
int gf1_atoi(void);
#endif
void gf1_leave(void);
short gf1_enter(void);
void gf1_enter1(void);
int gf1_play_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);
void gf1_dig_set_vol(unsigned short voice, unsigned short vol);
void gf1_dig_set_pan(unsigned short voice, unsigned short pan);
int gf1_set_external_semaphore(void RFAR *addr);
int gf1_clear_external_semaphore(void RFAR *addr);
void gf1_midi_reset(int c);
int gf1_add_midi_recv_handler(int (RFAR *handler)());
int gf1_add_dma_handler(int (*handler)());
int gf1_add_voice_handler(int (*handler)(int));
int gf1_add_volume_handler(int (*handler)(int));
int gf1_add_timer_handler(int timer, int (RFAR *handler)(void));
void gf1_set_record_rate(unsigned long rate);
void gf1_create_patch(struct patch RFAR *patch);
int gf1_add_layer(struct patch RFAR *patch, int layer, char RFAR *wavemem);
void gf1_get_waveform_info(struct patch RFAR *patch, int layer, int waven,
struct wave_struct RFAR *wave);
void gf1_set_waveform_info(struct patch RFAR *patch, int layer, int waven,
struct wave_struct RFAR *wave);
void gf1_enable_line_in(void);
void gf1_disable_line_in(void);
void gf1_enable_mic_in(void);
void gf1_disable_mic_in(void);
void gf1_enable_output(void);
void gf1_disable_output(void);
void gf1_sound_volume(unsigned short voice, int volume,
unsigned long period /* us*10 */);
void gf1_sound_pan(unsigned short voice, unsigned short pan);
void gf1_sound_frequency(unsigned short voice, unsigned long freq);
void RFAR gf1_sound_stop(int voice);
void gf1_sound_mode(int voice, struct gf1_sound RFAR *sound,
unsigned char type);
int gf1_sound_start(unsigned short priority, struct gf1_sound RFAR *sound,
short volume, unsigned long period, short pan, unsigned long freq);
int gf1_sound_playing(int voice);
#endif

179
audiolib/nodpmi.c Executable file
View File

@ -0,0 +1,179 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: DPMI.C
author: James R. Dose
date: April 8, 1994
Functions for performing DPMI calls.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stdlib.h>
#include <string.h>
#include "dpmi.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
/*---------------------------------------------------------------------
Function: DPMI_GetRealModeVector
Returns the vector of a real mode interrupt.
---------------------------------------------------------------------*/
unsigned long DPMI_GetRealModeVector
(
int num
)
{
return 0;
}
/*---------------------------------------------------------------------
Function: DPMI_SetRealModeVector
Sets the vector of a real mode interrupt.
---------------------------------------------------------------------*/
void DPMI_SetRealModeVector
(
int num,
unsigned long vector
)
{
}
/*---------------------------------------------------------------------
Function: DPMI_CallRealModeFunction
Performs a call to a real mode function.
---------------------------------------------------------------------*/
int DPMI_CallRealModeFunction
(
dpmi_regs *callregs
)
{
return( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemory
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemory
(
void *address,
unsigned length
)
{
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_LockMemoryRegion
Locks a region of memory to keep the virtual memory manager from
paging the region out.
---------------------------------------------------------------------*/
int DPMI_LockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
return( status );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemory
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemory
(
void *address,
unsigned length
)
{
return ( DPMI_Ok );
}
/*---------------------------------------------------------------------
Function: DPMI_UnlockMemoryRegion
Unlocks a region of memory that was previously locked.
---------------------------------------------------------------------*/
int DPMI_UnlockMemoryRegion
(
void *start,
void *end
)
{
int status;
status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
return( status );
}
int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length )
{
/* Lovely... */
*ptr = (void *)malloc(length);
*descriptor = (int) *ptr;
return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
}
int DPMI_FreeDOSMemory( int descriptor )
{
free((void *)descriptor);
return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
}

115
audiolib/nomusic.c Executable file
View File

@ -0,0 +1,115 @@
#include "music.h"
char *MUSIC_ErrorString(int ErrorNumber)
{
return "";
}
int MUSIC_Init(int SoundCard, int Address)
{
return 0;
}
int MUSIC_Shutdown(void)
{
return 0;
}
void MUSIC_SetMaxFMMidiChannel(int channel)
{
}
void MUSIC_SetVolume(int volume)
{
}
void MUSIC_SetMidiChannelVolume(int channel, int volume)
{
}
void MUSIC_ResetMidiChannelVolumes(void)
{
}
int MUSIC_GetVolume(void)
{
return 0;
}
void MUSIC_SetLoopFlag(int loopflag)
{
}
int MUSIC_SongPlaying(void)
{
return 0;
}
void MUSIC_Continue(void)
{
}
void MUSIC_Pause(void)
{
}
int MUSIC_StopSong(void)
{
return 0;
}
int MUSIC_PlaySong(unsigned char *song, int loopflag)
{
return 0;
}
void MUSIC_SetContext(int context)
{
}
int MUSIC_GetContext(void)
{
return 0;
}
void MUSIC_SetSongTick(unsigned long PositionInTicks)
{
}
void MUSIC_SetSongTime(unsigned long milliseconds)
{
}
void MUSIC_SetSongPosition(int measure, int beat, int tick)
{
}
void MUSIC_GetSongPosition(songposition *pos)
{
}
void MUSIC_GetSongLength(songposition *pos)
{
}
int MUSIC_FadeVolume(int tovolume, int milliseconds)
{
return 0;
}
int MUSIC_FadeActive(void)
{
return 0;
}
void MUSIC_StopFade(void)
{
}
void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
{
}
void MUSIC_RegisterTimbreBank(unsigned char *timbres)
{
}

1924
audiolib/pas16.c Executable file

File diff suppressed because it is too large Load Diff

81
audiolib/pas16.h Executable file
View File

@ -0,0 +1,81 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: PAS16.H
author: James R. Dose
date: March 27, 1994
Public header for for PAS16.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __PAS16_H
#define __PAS16_H
enum PAS_ERRORS
{
PAS_Warning = -2,
PAS_Error = -1,
PAS_Ok = 0,
PAS_DriverNotFound,
PAS_DmaError,
PAS_InvalidIrq,
PAS_UnableToSetIrq,
PAS_Dos4gwIrqError,
PAS_NoSoundPlaying,
PAS_CardNotFound,
PAS_DPMI_Error,
PAS_OutOfMemory
};
#define PAS_MaxMixMode STEREO_16BIT
#define PAS_DefaultSampleRate 11000
#define PAS_DefaultMixMode MONO_8BIT
#define PAS_MaxIrq 15
#define PAS_MinSamplingRate 4000
#define PAS_MaxSamplingRate 44000
extern unsigned int PAS_DMAChannel;
char *PAS_ErrorString( int ErrorNumber );
void PAS_SetPlaybackRate( unsigned rate );
unsigned PAS_GetPlaybackRate( void );
int PAS_SetMixMode( int mode );
void PAS_StopPlayback( void );
int PAS_GetCurrentPos( void );
int PAS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
int PAS_BeginBufferedRecord( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
int PAS_SetPCMVolume( int volume );
int PAS_GetPCMVolume( void );
void PAS_SetFMVolume( int volume );
int PAS_GetFMVolume( void );
int PAS_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
void PAS_SetCallBack( void ( *func )( void ) );
int PAS_SaveMusicVolume( void );
void PAS_RestoreMusicVolume( void );
int PAS_Init( void );
void PAS_Shutdown( void );
void PAS_UnlockMemory( void );
int PAS_LockMemory( void );
#endif

258
audiolib/pitch.c Executable file
View File

@ -0,0 +1,258 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: PITCH.C
author: James R. Dose
date: June 14, 1993
Routines for pitch scaling.
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stdlib.h>
//#include <math.h>
#include "dpmi.h"
#include "standard.h"
#include "pitch.h"
#define MAXDETUNE 25
static unsigned long PitchTable[ 12 ][ MAXDETUNE ] =
{
{ 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
0x10e98 },
{ 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
0x11eaf },
{ 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
0x12fbc },
{ 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
0x141cb },
{ 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
0x154ee },
{ 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
0x16934 },
{ 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
0x17eae },
{ 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
0x1956f },
{ 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
0x1ad8b },
{ 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
0x1c716 },
{ 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
0x1e225 },
{ 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
0x1fed1 }
};
//static int PITCH_Installed = FALSE;
/*---------------------------------------------------------------------
Function: PITCH_Init
Initializes pitch table.
---------------------------------------------------------------------*/
/*
void PITCH_Init
(
void
)
{
int note;
int detune;
if ( !PITCH_Installed )
{
for( note = 0; note < 12; note++ )
{
for( detune = 0; detune < MAXDETUNE; detune++ )
{
PitchTable[ note ][ detune ] = 0x10000 *
pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
}
}
PITCH_Installed = TRUE;
}
}
*/
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define PITCH_LockStart PITCH_GetScale
/*---------------------------------------------------------------------
Function: PITCH_GetScale
Returns a fixed-point value to scale number the specified amount.
---------------------------------------------------------------------*/
unsigned long PITCH_GetScale
(
int pitchoffset
)
{
unsigned long scale;
int octaveshift;
int noteshift;
int note;
int detune;
// if ( !PITCH_Installed )
// {
// PITCH_Init();
// }
if ( pitchoffset == 0 )
{
return( PitchTable[ 0 ][ 0 ] );
}
noteshift = pitchoffset % 1200;
if ( noteshift < 0 )
{
noteshift += 1200;
}
note = noteshift / 100;
detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE );
octaveshift = ( pitchoffset - noteshift ) / 1200;
if ( detune < 0 )
{
detune += ( 100 / MAXDETUNE );
note--;
if ( note < 0 )
{
note += 12;
octaveshift--;
}
}
scale = PitchTable[ note ][ detune ];
if ( octaveshift < 0 )
{
scale >>= -octaveshift;
}
else
{
scale <<= octaveshift;
}
return( scale );
}
/*---------------------------------------------------------------------
Function: PITCH_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void PITCH_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: PITCH_UnlockMemory
Unlocks all neccessary data.
---------------------------------------------------------------------*/
void PITCH_UnlockMemory
(
void
)
{
DPMI_UnlockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
DPMI_Unlock( PitchTable );
// DPMI_Unlock( PITCH_Installed );
}
/*---------------------------------------------------------------------
Function: PITCH_LockMemory
Unlocks all neccessary data.
---------------------------------------------------------------------*/
int PITCH_LockMemory
(
void
)
{
int status;
status = DPMI_LockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
status |= DPMI_Lock( PitchTable );
// status |= DPMI_Lock( PITCH_Installed );
if ( status != DPMI_Ok )
{
PITCH_UnlockMemory();
return( PITCH_Error );
}
return( PITCH_Ok );
}

45
audiolib/pitch.h Executable file
View File

@ -0,0 +1,45 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: PITCH.H
author: James R. Dose
date: June 14, 1994
Public header for PITCH.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __PITCH_H
#define __PITCH_H
enum PITCH_ERRORS
{
PITCH_Warning = -2,
PITCH_Error = -1,
PITCH_Ok = 0,
};
//void PITCH_Init( void );
unsigned long PITCH_GetScale( int pitchoffset );
void PITCH_UnlockMemory( void );
int PITCH_LockMemory( void );
#endif

55
audiolib/sndcards.h Executable file
View File

@ -0,0 +1,55 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: SNDCARDS.H
author: James R. Dose
date: March 31, 1994
Contains enumerated type definitions for sound cards.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __SNDCARDS_H
#define __SNDCARDS_H
#define ASS_VERSION_STRING "1.12"
typedef enum
{
// ASS_NoSound,
SoundBlaster,
ProAudioSpectrum,
SoundMan16,
Adlib,
GenMidi,
SoundCanvas,
Awe32,
WaveBlaster,
SoundScape,
UltraSound,
SoundSource,
TandySoundSource,
PC,
NumSoundCards
} soundcardnames;
#endif

1661
audiolib/sndscape.c Executable file

File diff suppressed because it is too large Load Diff

73
audiolib/sndscape.h Executable file
View File

@ -0,0 +1,73 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: SNDSCAPE.H
author: James R. Dose
date: October 26, 1994
Public header for SNDSCAPE.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __SNDSCAPE_H
#define __SNDSCAPE_H
extern int SOUNDSCAPE_DMAChannel;
extern int SOUNDSCAPE_ErrorCode;
enum SOUNDSCAPE_ERRORS
{
SOUNDSCAPE_Warning = -2,
SOUNDSCAPE_Error = -1,
SOUNDSCAPE_Ok = 0,
SOUNDSCAPE_EnvNotFound,
SOUNDSCAPE_InitFileNotFound,
SOUNDSCAPE_MissingProductInfo,
SOUNDSCAPE_MissingPortInfo,
SOUNDSCAPE_MissingDMAInfo,
SOUNDSCAPE_MissingIRQInfo,
SOUNDSCAPE_MissingSBIRQInfo,
SOUNDSCAPE_MissingSBENABLEInfo,
SOUNDSCAPE_MissingWavePortInfo,
SOUNDSCAPE_HardwareError,
SOUNDSCAPE_NoSoundPlaying,
SOUNDSCAPE_InvalidSBIrq,
SOUNDSCAPE_UnableToSetIrq,
SOUNDSCAPE_DmaError,
SOUNDSCAPE_DPMI_Error,
SOUNDSCAPE_OutOfMemory
};
char *SOUNDSCAPE_ErrorString( int ErrorNumber );
void SOUNDSCAPE_SetPlaybackRate( unsigned rate );
unsigned SOUNDSCAPE_GetPlaybackRate( void );
int SOUNDSCAPE_SetMixMode( int mode );
void SOUNDSCAPE_StopPlayback( void );
int SOUNDSCAPE_GetCurrentPos( void );
int SOUNDSCAPE_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
int SOUNDSCAPE_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
void SOUNDSCAPE_SetCallBack( void ( *func )( void ) );
int SOUNDSCAPE_GetMIDIPort( void );
int SOUNDSCAPE_Init( void );
void SOUNDSCAPE_Shutdown( void );
#endif

658
audiolib/sndsrc.c Executable file
View File

@ -0,0 +1,658 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: SNDSRC.C
author: James R. Dose
date: March 26, 1994
Low level routines to support the Disney Sound Source.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#define STEREO 1
#define SIXTEEN_BIT 2
#define MONO_8BIT 0
#define STEREO_8BIT ( STEREO )
#define MONO_16BIT ( SIXTEEN_BIT )
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include "dpmi.h"
#include "task_man.h"
#include "sndcards.h"
#include "user.h"
#include "sndsrc.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
static int SS_Installed = FALSE;
static int SS_Port = SS_DefaultPort;
static int SS_OffCommand = 0xc;
static char *SS_BufferStart;
static char *SS_BufferEnd;
static char *SS_CurrentBuffer;
static int SS_BufferNum = 0;
static int SS_NumBuffers = 0;
static int SS_TotalBufferSize = 0;
static int SS_TransferLength = 0;
static int SS_CurrentLength = 0;
static char *SS_SoundPtr;
volatile int SS_SoundPlaying;
static task *SS_Timer;
void ( *SS_CallBack )( void );
int SS_ErrorCode = SS_Ok;
#define SS_SetErrorCode( status ) \
SS_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: SS_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *SS_ErrorString
(
int ErrorNumber
)
{
char *ErrorString;
switch( ErrorNumber )
{
case SS_Error :
ErrorString = SS_ErrorString( SS_ErrorCode );
break;
case SS_Ok :
ErrorString = "Sound Source ok.";
break;
case SS_NotFound :
ErrorString = "Could not detect Sound Source.";
break;
case SS_NoSoundPlaying :
ErrorString = "No sound playing in SndSrc.";
break;
case SS_DPMI_Error :
ErrorString = "DPMI Error in SndSrc.";
break;
default :
ErrorString = "Unknown Sound Source error code.";
break;
}
return( ErrorString );
}
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define SS_LockStart SS_ServiceInterrupt
/*---------------------------------------------------------------------
Function: SS_ServiceInterrupt
Handles interrupt generated by sound card at the end of a voice
transfer. Calls the user supplied callback function.
---------------------------------------------------------------------*/
static void SS_ServiceInterrupt
(
task *Task
)
{
int port = SS_Port;
int count;
count = 0;
while( ( inp( port + 1 ) & 0x40 ) == 0 )
{
outp( port, *SS_SoundPtr++ );
outp( port + 2, SS_OffCommand );
outp( port + 2, 4 );
SS_CurrentLength--;
if ( SS_CurrentLength == 0 )
{
// Keep track of current buffer
SS_CurrentBuffer += SS_TransferLength;
SS_BufferNum++;
if ( SS_BufferNum >= SS_NumBuffers )
{
SS_BufferNum = 0;
SS_CurrentBuffer = SS_BufferStart;
}
SS_CurrentLength = SS_TransferLength;
SS_SoundPtr = SS_CurrentBuffer;
// Call the caller's callback function
if ( SS_CallBack != NULL )
{
SS_CallBack();
}
}
count++;
// Only do at most 14 samples per tick
if ( count > 13 )
{
break;
}
}
}
/*---------------------------------------------------------------------
Function: SS_StopPlayback
Ends the transfer of digitized sound to the Sound Source.
---------------------------------------------------------------------*/
void SS_StopPlayback
(
void
)
{
if ( SS_SoundPlaying )
{
TS_Terminate( SS_Timer );
outp( SS_Port, 0x80 );
outp( SS_Port + 2, SS_OffCommand );
outp( SS_Port + 2, 4 );
SS_SoundPlaying = FALSE;
SS_BufferStart = NULL;
}
}
/*---------------------------------------------------------------------
Function: SS_GetCurrentPos
Returns the offset within the current sound being played.
---------------------------------------------------------------------*/
int SS_GetCurrentPos
(
void
)
{
int offset;
if ( !SS_SoundPlaying )
{
SS_SetErrorCode( SS_NoSoundPlaying );
return( SS_Warning );
}
offset = ( int )( ( ( unsigned long )SS_SoundPtr ) -
( ( unsigned long )SS_CurrentBuffer ) );
return( offset );
}
/*---------------------------------------------------------------------
Function: SS_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void SS_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: SS_BeginBufferedPlayback
Begins multibuffered playback of digitized sound on the Sound Source.
---------------------------------------------------------------------*/
int SS_BeginBufferedPlayback
(
char *BufferStart,
int BufferSize,
int NumDivisions,
void ( *CallBackFunc )( void )
)
{
if ( SS_SoundPlaying )
{
SS_StopPlayback();
}
SS_SetCallBack( CallBackFunc );
SS_BufferStart = BufferStart;
SS_CurrentBuffer = BufferStart;
SS_SoundPtr = BufferStart;
SS_TotalBufferSize = BufferSize;
SS_BufferEnd = BufferStart + BufferSize;
SS_TransferLength = BufferSize / NumDivisions;
SS_CurrentLength = SS_TransferLength;
SS_BufferNum = 0;
SS_NumBuffers = NumDivisions;
SS_SoundPlaying = TRUE;
// SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 438, 1, NULL );
SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 510, 1, NULL );
TS_Dispatch();
return( SS_Ok );
}
/*---------------------------------------------------------------------
Function: SS_GetPlaybackRate
Returns the rate at which the digitized sound will be played in
hertz.
---------------------------------------------------------------------*/
int SS_GetPlaybackRate
(
void
)
{
return( SS_SampleRate );
}
/*---------------------------------------------------------------------
Function: SS_SetMixMode
Sets the sound card to play samples in mono or stereo.
---------------------------------------------------------------------*/
int SS_SetMixMode
(
int mode
)
{
mode = MONO_8BIT;
return( mode );
}
/*---------------------------------------------------------------------
Function: SS_SetPort
Selects which port to use to write to the Sound Source.
---------------------------------------------------------------------*/
int SS_SetPort
(
int port
)
{
if ( SS_Installed )
{
SS_Shutdown();
}
SS_Port = port;
return( SS_Ok );
}
/*---------------------------------------------------------------------
Function: SS_SetCallBack
Specifies the user function to call at the end of a sound transfer.
---------------------------------------------------------------------*/
void SS_SetCallBack
(
void ( *func )( void )
)
{
SS_CallBack = func;
}
/*---------------------------------------------------------------------
Function: SS_TestTimer
Used as a delay in SS_TestSoundSource.
---------------------------------------------------------------------*/
void SS_TestTimer
(
task *Task
)
{
( *( int * )( Task->data ) )++;
}
/*---------------------------------------------------------------------
Function: SS_TestSoundSource
Detect if the Sound Source is located at the specified port.
---------------------------------------------------------------------*/
int SS_TestSoundSource
(
int port
)
{
int present;
task *timer;
volatile int ticks;
int i;
present = FALSE;
timer = TS_ScheduleTask( SS_TestTimer, 140, 1, &ticks );
TS_Dispatch();
outp( port + 2, 4 );
ticks = 0;
while( ticks < 4 )
{
// Do nothing for a while
}
TS_Terminate( timer );
if ( ( inp( port + 1 ) & 0x40 ) == 0 )
{
for( i = 32; i > 0; i-- )
{
outp( port, 0x80 );
outp( port + 2, SS_OffCommand );
outp( port + 2, 4 );
}
if ( inp( port + 1 ) & 0x40 )
{
present = TRUE;
}
}
outp( port + 2, SS_OffCommand );
return( present );
}
/*---------------------------------------------------------------------
Function: SS_DetectSoundSource
Detects which port the Sound Source is located.
---------------------------------------------------------------------*/
int SS_DetectSoundSource
(
void
)
{
if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT1 ) )
{
SS_Port = SS_Port1;
return( TRUE );
}
if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT2 ) )
{
SS_Port = SS_Port2;
return( TRUE );
}
if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT3 ) )
{
SS_Port = SS_Port3;
return( TRUE );
}
if ( SS_TestSoundSource( SS_Port1 ) )
{
SS_Port = SS_Port1;
return( TRUE );
}
if ( SS_TestSoundSource( SS_Port2 ) )
{
SS_Port = SS_Port2;
return( TRUE );
}
if ( SS_TestSoundSource( SS_Port3 ) )
{
SS_Port = SS_Port3;
return( TRUE );
}
return( FALSE );
}
/*---------------------------------------------------------------------
Function: SS_Init
Initializes the Sound Source prepares the module to play digitized
sounds.
---------------------------------------------------------------------*/
int SS_Init
(
int soundcard
)
{
int status;
if ( SS_Installed )
{
SS_Shutdown();
}
if ( ( soundcard == TandySoundSource ) ||
( USER_CheckParameter( SELECT_TANDY_SOUNDSOURCE ) ) )
{
// Tandy
SS_OffCommand = 0x0e;
}
else
{
// Disney
SS_OffCommand = 0x0c;
}
status = SS_DetectSoundSource();
if ( !status )
{
SS_SetErrorCode( SS_NotFound );
return( SS_Warning );
}
status = SS_LockMemory();
if ( status != SS_Ok )
{
SS_UnlockMemory();
return( status );
}
status = SS_Ok;
outp( SS_Port + 2, 4 );
SS_SoundPlaying = FALSE;
SS_SetCallBack( NULL );
SS_BufferStart = NULL;
SS_Installed = TRUE;
SS_SetErrorCode( status );
return( status );
}
/*---------------------------------------------------------------------
Function: SS_Shutdown
Ends transfer of sound data to the Sound Source.
---------------------------------------------------------------------*/
void SS_Shutdown
(
void
)
{
// Halt the transfer
SS_StopPlayback();
outp( SS_Port + 2, SS_OffCommand );
SS_SoundPlaying = FALSE;
SS_BufferStart = NULL;
SS_SetCallBack( NULL );
SS_UnlockMemory();
SS_Installed = FALSE;
}
/*---------------------------------------------------------------------
Function: SS_UnlockMemory
Unlocks all neccessary data.
---------------------------------------------------------------------*/
void SS_UnlockMemory
(
void
)
{
DPMI_UnlockMemoryRegion( SS_LockStart, SS_LockEnd );
DPMI_Unlock( SS_Installed );
DPMI_Unlock( SS_Port );
DPMI_Unlock( SS_OffCommand );
DPMI_Unlock( SS_BufferStart );
DPMI_Unlock( SS_BufferEnd );
DPMI_Unlock( SS_CurrentBuffer );
DPMI_Unlock( SS_BufferNum );
DPMI_Unlock( SS_NumBuffers );
DPMI_Unlock( SS_TotalBufferSize );
DPMI_Unlock( SS_TransferLength );
DPMI_Unlock( SS_CurrentLength );
DPMI_Unlock( SS_SoundPtr );
DPMI_Unlock( SS_SoundPlaying );
DPMI_Unlock( SS_Timer );
DPMI_Unlock( SS_CallBack );
DPMI_Unlock( SS_ErrorCode );
}
/*---------------------------------------------------------------------
Function: SS_LockMemory
Locks all neccessary data.
---------------------------------------------------------------------*/
int SS_LockMemory
(
void
)
{
int status;
status = DPMI_LockMemoryRegion( SS_LockStart, SS_LockEnd );
status |= DPMI_Lock( SS_Installed );
status |= DPMI_Lock( SS_Port );
status |= DPMI_Lock( SS_OffCommand );
status |= DPMI_Lock( SS_BufferStart );
status |= DPMI_Lock( SS_BufferEnd );
status |= DPMI_Lock( SS_CurrentBuffer );
status |= DPMI_Lock( SS_BufferNum );
status |= DPMI_Lock( SS_NumBuffers );
status |= DPMI_Lock( SS_TotalBufferSize );
status |= DPMI_Lock( SS_TransferLength );
status |= DPMI_Lock( SS_CurrentLength );
status |= DPMI_Lock( SS_SoundPtr );
status |= DPMI_Lock( SS_SoundPlaying );
status |= DPMI_Lock( SS_Timer );
status |= DPMI_Lock( SS_CallBack );
status |= DPMI_Lock( SS_ErrorCode );
if ( status != DPMI_Ok )
{
SS_UnlockMemory();
SS_SetErrorCode( SS_DPMI_Error );
return( SS_Error );
}
return( SS_Ok );
}

70
audiolib/sndsrc.h Executable file
View File

@ -0,0 +1,70 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: SNDSRC.H
author: James R. Dose
date: March 26, 1994
Public header for for SNDSRC.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __SNDSRC_H
#define __SNDSRC_H
enum SS_ERRORS
{
SS_Warning = -2,
SS_Error = -1,
SS_Ok = 0,
SS_NotFound,
SS_NoSoundPlaying,
SS_DPMI_Error
};
#define SELECT_SOUNDSOURCE_PORT1 "ss1"
#define SELECT_SOUNDSOURCE_PORT2 "ss2"
#define SELECT_SOUNDSOURCE_PORT3 "ss3"
#define SELECT_TANDY_SOUNDSOURCE "sst"
#define SS_Port1 0x3bc
#define SS_Port2 0x378
#define SS_Port3 0x278
#define SS_DefaultPort 0x378
#define SS_SampleRate 7000
#define SS_DMAChannel -1
char *SS_ErrorString( int ErrorNumber );
void SS_StopPlayback( void );
int SS_GetCurrentPos( void );
int SS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, void ( *CallBackFunc )( void ) );
int SS_GetPlaybackRate( void );
int SS_SetMixMode( int mode );
int SS_SetPort( int port );
void SS_SetCallBack( void ( *func )( void ) );
int SS_Init( int soundcard );
void SS_Shutdown( void );
void SS_UnlockMemory( void );
int SS_LockMemory( void );
#endif

72
audiolib/standard.h Executable file
View File

@ -0,0 +1,72 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: STANDARD.H
author: James R. Dose
date: May 25, 1994
Header containing standard definitions.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __STANDARD_H
#define __STANDARD_H
typedef int boolean;
typedef int errorcode;
#ifndef TRUE
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#endif
enum STANDARD_ERRORS
{
Warning = -2,
FatalError = -1,
Success = 0
};
#define BITSET( data, bit ) \
( ( ( data ) & ( bit ) ) == ( bit ) )
#define ARRAY_LENGTH( array ) \
( sizeof( array ) / sizeof( ( array )[ 0 ] ) )
#define WITHIN_BOUNDS( array, index ) \
( ( 0 <= ( index ) ) && ( ( index ) < ARRAY_LENGTH( array ) ) )
#define FOREVER for( ; ; )
#ifdef NDEBUG
#define DEBUGGING 0
#else
#define DEBUGGING 1
#endif
#define DEBUG_CODE \
if ( DEBUGGING == 0 ) \
{ \
} \
else
#endif

976
audiolib/task_man.c Executable file
View File

@ -0,0 +1,976 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: TASK_MAN.C
author: James R. Dose
date: July 25, 1994
Low level timer task scheduler.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
//#define USESTACK
#define LOCKMEMORY
#define NOINTS
#define USE_USRHOOKS
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <string.h>
#include "interrup.h"
#include "linklist.h"
#include "task_man.h"
#ifdef USESTACK
#include "dpmi.h"
#endif
#ifdef LOCKMEMORY
#include "dpmi.h"
#endif
#ifdef USE_USRHOOKS
#include "usrhooks.h"
#define FreeMem( ptr ) USRHOOKS_FreeMem( ( ptr ) )
#else
#define FreeMem( ptr ) free( ( ptr ) )
#endif
typedef struct
{
task *start;
task *end;
} tasklist;
/*---------------------------------------------------------------------
Global variables
---------------------------------------------------------------------*/
#ifdef USESTACK
// adequate stack size
#define kStackSize 2048
static unsigned short StackSelector = NULL;
static unsigned long StackPointer;
static unsigned short oldStackSelector;
static unsigned long oldStackPointer;
#endif
static task HeadTask;
static task *TaskList = &HeadTask;
static void ( __interrupt __far *OldInt8 )( void );
static volatile long TaskServiceRate = 0x10000L;
static volatile long TaskServiceCount = 0;
#ifndef NOINTS
static volatile int TS_TimesInInterrupt;
#endif
static char TS_Installed = FALSE;
volatile int TS_InInterrupt = FALSE;
/*---------------------------------------------------------------------
Function prototypes
---------------------------------------------------------------------*/
static void TS_FreeTaskList( void );
static void TS_SetClockSpeed( long speed );
static long TS_SetTimer( long TickBase );
static void TS_SetTimerToMaxTaskRate( void );
static void __interrupt __far TS_ServiceSchedule( void );
static void __interrupt __far TS_ServiceScheduleIntEnabled( void );
static void TS_AddTask( task *ptr );
static int TS_Startup( void );
static void RestoreRealTimeClock( void );
// These declarations are necessary to use the inline assembly pragmas.
extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
extern void SetStack(unsigned short selector,unsigned long stackptr);
// This function will get the current stack selector and pointer and save
// them off.
#pragma aux GetStack = \
"mov [edi],esp" \
"mov ax,ss" \
"mov [esi],ax" \
parm [esi] [edi] \
modify [eax esi edi];
// This function will set the stack selector and pointer to the specified
// values.
#pragma aux SetStack = \
"mov ss,ax" \
"mov esp,edx" \
parm [ax] [edx] \
modify [eax edx];
/**********************************************************************
Memory locked functions:
**********************************************************************/
#define TS_LockStart TS_FreeTaskList
/*---------------------------------------------------------------------
Function: TS_FreeTaskList
Terminates all tasks and releases any memory used for control
structures.
---------------------------------------------------------------------*/
static void TS_FreeTaskList
(
void
)
{
task *node;
task *next;
unsigned flags;
flags = DisableInterrupts();
node = TaskList->next;
while( node != TaskList )
{
next = node->next;
FreeMem( node );
node = next;
}
TaskList->next = TaskList;
TaskList->prev = TaskList;
RestoreInterrupts( flags );
}
/*---------------------------------------------------------------------
Function: TS_SetClockSpeed
Sets the rate of the 8253 timer.
---------------------------------------------------------------------*/
static void TS_SetClockSpeed
(
long speed
)
{
unsigned flags;
flags = DisableInterrupts();
if ( ( speed > 0 ) && ( speed < 0x10000L ) )
{
TaskServiceRate = speed;
}
else
{
TaskServiceRate = 0x10000L;
}
outp( 0x43, 0x36 );
outp( 0x40, TaskServiceRate );
outp( 0x40, TaskServiceRate >> 8 );
RestoreInterrupts( flags );
}
/*---------------------------------------------------------------------
Function: TS_SetTimer
Calculates the rate at which a task will occur and sets the clock
speed if necessary.
---------------------------------------------------------------------*/
static long TS_SetTimer
(
long TickBase
)
{
long speed;
speed = 1192030L / TickBase;
if ( speed < TaskServiceRate )
{
TS_SetClockSpeed( speed );
}
return( speed );
}
/*---------------------------------------------------------------------
Function: TS_SetTimerToMaxTaskRate
Finds the fastest running task and sets the clock to operate at
that speed.
---------------------------------------------------------------------*/
static void TS_SetTimerToMaxTaskRate
(
void
)
{
task *ptr;
long MaxServiceRate;
unsigned flags;
flags = DisableInterrupts();
MaxServiceRate = 0x10000L;
ptr = TaskList->next;
while( ptr != TaskList )
{
if ( ptr->rate < MaxServiceRate )
{
MaxServiceRate = ptr->rate;
}
ptr = ptr->next;
}
if ( TaskServiceRate != MaxServiceRate )
{
TS_SetClockSpeed( MaxServiceRate );
}
RestoreInterrupts( flags );
}
#ifdef NOINTS
/*---------------------------------------------------------------------
Function: TS_ServiceSchedule
Interrupt service routine
---------------------------------------------------------------------*/
static void __interrupt __far TS_ServiceSchedule
(
void
)
{
task *ptr;
task *next;
TS_InInterrupt = TRUE;
#ifdef USESTACK
// save stack
GetStack( &oldStackSelector, &oldStackPointer );
// set our stack
SetStack( StackSelector, StackPointer );
#endif
ptr = TaskList->next;
while( ptr != TaskList )
{
next = ptr->next;
if ( ptr->active )
{
ptr->count += TaskServiceRate;
//JIM
// if ( ptr->count >= ptr->rate )
while( ptr->count >= ptr->rate )
{
ptr->count -= ptr->rate;
ptr->TaskService( ptr );
}
}
ptr = next;
}
#ifdef USESTACK
// restore stack
SetStack( oldStackSelector, oldStackPointer );
#endif
TaskServiceCount += TaskServiceRate;
if ( TaskServiceCount > 0xffffL )
{
TaskServiceCount &= 0xffff;
_chain_intr( OldInt8 );
}
outp( 0x20,0x20 );
TS_InInterrupt = FALSE;
}
#else
/*---------------------------------------------------------------------
Function: TS_ServiceScheduleIntEnabled
Interrupt service routine with interrupts enabled.
---------------------------------------------------------------------*/
static void __interrupt __far TS_ServiceScheduleIntEnabled
(
void
)
{
task *ptr;
task *next;
TS_TimesInInterrupt++;
TaskServiceCount += TaskServiceRate;
if ( TaskServiceCount > 0xffffL )
{
TaskServiceCount &= 0xffff;
_chain_intr( OldInt8 );
}
outp( 0x20,0x20 );
if ( TS_InInterrupt )
{
return;
}
TS_InInterrupt = TRUE;
_enable();
#ifdef USESTACK
// save stack
GetStack( &oldStackSelector, &oldStackPointer );
// set our stack
SetStack( StackSelector, StackPointer );
#endif
while( TS_TimesInInterrupt )
{
ptr = TaskList->next ;
while( ptr != TaskList )
{
next = ptr->next;
if ( ptr->active )
{
ptr->count += TaskServiceRate;
if ( ptr->count >= ptr->rate )
{
ptr->count -= ptr->rate;
ptr->TaskService( ptr );
}
}
ptr = next;
}
TS_TimesInInterrupt--;
}
_disable();
#ifdef USESTACK
// restore stack
SetStack( oldStackSelector, oldStackPointer );
#endif
TS_InInterrupt = FALSE;
}
#endif
#ifdef USESTACK
/*---------------------------------------------------------------------
Function: allocateTimerStack
Allocate a block of memory from conventional (low) memory and return
the selector (which can go directly into a segment register) of the
memory block or 0 if an error occured.
---------------------------------------------------------------------*/
static unsigned short allocateTimerStack
(
unsigned short size
)
{
union REGS regs;
// clear all registers
memset( &regs, 0, sizeof( regs ) );
// DPMI allocate conventional memory
regs.w.ax = 0x100;
// size in paragraphs
regs.w.bx = ( size + 15 ) / 16;
int386( 0x31, &regs, &regs );
if (!regs.w.cflag)
{
// DPMI call returns selector in dx
// (ax contains real mode segment
// which is ignored here)
return( regs.w.dx );
}
// Couldn't allocate memory.
return( NULL );
}
/*---------------------------------------------------------------------
Function: deallocateTimerStack
Deallocate a block of conventional (low) memory given a selector to
it. Assumes the block was allocated with DPMI function 0x100.
---------------------------------------------------------------------*/
static void deallocateTimerStack
(
unsigned short selector
)
{
union REGS regs;
if ( selector != NULL )
{
// clear all registers
memset( &regs, 0, sizeof( regs ) );
regs.w.ax = 0x101;
regs.w.dx = selector;
int386( 0x31, &regs, &regs );
}
}
#endif
/*---------------------------------------------------------------------
Function: TS_Startup
Sets up the task service routine.
---------------------------------------------------------------------*/
static int TS_Startup
(
void
)
{
if ( !TS_Installed )
{
#ifdef LOCKMEMORY
int status;
status = TS_LockMemory();
if ( status != TASK_Ok )
{
TS_UnlockMemory();
return( status );
}
#endif
#ifdef USESTACK
StackSelector = allocateTimerStack( kStackSize );
if ( StackSelector == NULL )
{
#ifdef LOCKMEMORY
TS_UnlockMemory();
#endif
return( TASK_Error );
}
// Leave a little room at top of stack just for the hell of it...
StackPointer = kStackSize - sizeof( long );
#endif
//static const task *TaskList = &HeadTask;
TaskList->next = TaskList;
TaskList->prev = TaskList;
TaskServiceRate = 0x10000L;
TaskServiceCount = 0;
#ifndef NOINTS
TS_TimesInInterrupt = 0;
#endif
OldInt8 = _dos_getvect( 0x08 );
#ifdef NOINTS
_dos_setvect( 0x08, TS_ServiceSchedule );
#else
_dos_setvect( 0x08, TS_ServiceScheduleIntEnabled );
#endif
TS_Installed = TRUE;
}
return( TASK_Ok );
}
/*---------------------------------------------------------------------
Function: TS_Shutdown
Ends processing of all tasks.
---------------------------------------------------------------------*/
void TS_Shutdown
(
void
)
{
if ( TS_Installed )
{
TS_FreeTaskList();
TS_SetClockSpeed( 0 );
_dos_setvect( 0x08, OldInt8 );
#ifdef USESTACK
deallocateTimerStack( StackSelector );
StackSelector = NULL;
#endif
// Set Date and Time from CMOS
// RestoreRealTimeClock();
#ifdef LOCKMEMORY
TS_UnlockMemory();
#endif
TS_Installed = FALSE;
}
}
/*---------------------------------------------------------------------
Function: TS_ScheduleTask
Schedules a new task for processing.
---------------------------------------------------------------------*/
task *TS_ScheduleTask
(
void ( *Function )( task * ),
int rate,
int priority,
void *data
)
{
task *ptr;
#ifdef USE_USRHOOKS
int status;
ptr = NULL;
status = USRHOOKS_GetMem( &ptr, sizeof( task ) );
if ( status == USRHOOKS_Ok )
#else
ptr = malloc( sizeof( task ) );
if ( ptr != NULL )
#endif
{
if ( !TS_Installed )
{
status = TS_Startup();
if ( status != TASK_Ok )
{
FreeMem( ptr );
return( NULL );
}
}
ptr->TaskService = Function;
ptr->data = data;
ptr->rate = TS_SetTimer( rate );
ptr->count = 0;
ptr->priority = priority;
ptr->active = FALSE;
TS_AddTask( ptr );
}
return( ptr );
}
/*---------------------------------------------------------------------
Function: TS_AddTask
Adds a new task to our list of tasks.
---------------------------------------------------------------------*/
static void TS_AddTask
(
task *node
)
{
LL_SortedInsertion( TaskList, node, next, prev, task, priority );
}
/*---------------------------------------------------------------------
Function: TS_Terminate
Ends processing of a specific task.
---------------------------------------------------------------------*/
int TS_Terminate
(
task *NodeToRemove
)
{
task *ptr;
task *next;
unsigned flags;
flags = DisableInterrupts();
ptr = TaskList->next;
while( ptr != TaskList )
{
next = ptr->next;
if ( ptr == NodeToRemove )
{
LL_RemoveNode( NodeToRemove, next, prev );
NodeToRemove->next = NULL;
NodeToRemove->prev = NULL;
FreeMem( NodeToRemove );
TS_SetTimerToMaxTaskRate();
RestoreInterrupts( flags );
return( TASK_Ok );
}
ptr = next;
}
RestoreInterrupts( flags );
return( TASK_Warning );
}
/*---------------------------------------------------------------------
Function: TS_Dispatch
Begins processing of all inactive tasks.
---------------------------------------------------------------------*/
void TS_Dispatch
(
void
)
{
task *ptr;
unsigned flags;
flags = DisableInterrupts();
ptr = TaskList->next;
while( ptr != TaskList )
{
ptr->active = TRUE;
ptr = ptr->next;
}
RestoreInterrupts( flags );
}
/*---------------------------------------------------------------------
Function: TS_SetTaskRate
Sets the rate at which the specified task is serviced.
---------------------------------------------------------------------*/
void TS_SetTaskRate
(
task *Task,
int rate
)
{
unsigned flags;
flags = DisableInterrupts();
Task->rate = TS_SetTimer( rate );
TS_SetTimerToMaxTaskRate();
RestoreInterrupts( flags );
}
#ifdef LOCKMEMORY
/*---------------------------------------------------------------------
Function: TS_LockEnd
Used for determining the length of the functions to lock in memory.
---------------------------------------------------------------------*/
static void TS_LockEnd
(
void
)
{
}
/*---------------------------------------------------------------------
Function: TS_UnlockMemory
Unlocks all neccessary data.
---------------------------------------------------------------------*/
void TS_UnlockMemory
(
void
)
{
DPMI_UnlockMemoryRegion( TS_LockStart, TS_LockEnd );
DPMI_Unlock( TaskList );
DPMI_Unlock( OldInt8 );
DPMI_Unlock( TaskServiceRate );
DPMI_Unlock( TaskServiceCount );
DPMI_Unlock( TS_Installed );
#ifndef NOINTS
DPMI_Unlock( TS_TimesInInterrupt );
#endif
#ifdef USESTACK
DPMI_Unlock( StackSelector );
DPMI_Unlock( StackPointer );
DPMI_Unlock( oldStackSelector );
DPMI_Unlock( oldStackPointer );
#endif
}
/*---------------------------------------------------------------------
Function: TS_LockMemory
Locks all neccessary data.
---------------------------------------------------------------------*/
int TS_LockMemory
(
void
)
{
int status;
status = DPMI_LockMemoryRegion( TS_LockStart, TS_LockEnd );
status |= DPMI_Lock( TaskList );
status |= DPMI_Lock( OldInt8 );
status |= DPMI_Lock( TaskServiceRate );
status |= DPMI_Lock( TaskServiceCount );
status |= DPMI_Lock( TS_Installed );
#ifndef NOINTS
status |= DPMI_Lock( TS_TimesInInterrupt );
#endif
#ifdef USESTACK
status |= DPMI_Lock( StackSelector );
status |= DPMI_Lock( StackPointer );
status |= DPMI_Lock( oldStackSelector );
status |= DPMI_Lock( oldStackPointer );
#endif
if ( status != DPMI_Ok )
{
TS_UnlockMemory();
return( TASK_Error );
}
return( TASK_Ok );
}
#endif
/*
// Converts a hex byte to an integer
static int btoi
(
unsigned char bcd
)
{
unsigned b;
unsigned c;
unsigned d;
b = bcd / 16;
c = bcd - b * 16;
d = b * 10 + c;
return( d );
}
static void RestoreRealTimeClock
(
void
)
{
int read;
int i;
int hr;
int min;
int sec;
int cent;
int yr;
int mo;
int day;
int year;
union REGS inregs;
// Read Real Time Clock Time.
read = FALSE;
inregs.h.ah = 0x02;
for( i = 1; i <= 3; i++ )
{
int386( 0x1A, &inregs, &inregs );
if ( inregs.x.cflag == 0 )
{
read = TRUE;
}
}
if ( read )
{
//and convert BCD to integer format
hr = btoi( inregs.h.ch );
min = btoi( inregs.h.cl );
sec = btoi( inregs.h.dh );
// Read Real Time Clock Date.
inregs.h.ah = 0x04;
int386( 0x1A, &inregs, &inregs );
if ( inregs.x.cflag == 0 )
{
//and convert BCD to integer format
cent = btoi( inregs.h.ch );
yr = btoi( inregs.h.cl );
mo = btoi( inregs.h.dh );
day = btoi( inregs.h.dl );
year = cent * 100 + yr;
// Set System Time.
inregs.h.ch = hr;
inregs.h.cl = min;
inregs.h.dh = sec;
inregs.h.dl = 0;
inregs.h.ah = 0x2D;
int386( 0x21, &inregs, &inregs );
// Set System Date.
inregs.w.cx = year;
inregs.h.dh = mo;
inregs.h.dl = day;
inregs.h.ah = 0x2B;
int386( 0x21, &inregs, &inregs );
}
}
}
*/
/*
struct dostime_t time;
struct dosdate_t date;
outp(0x70,0);
time.second=inp(0x71);
outp(0x70,2);
time.minute=inp(0x71);
outp(0x70,4);
time.hour=inp(0x71);
outp(0x70,7);
date.day=inp(0x71);
outp(0x70,8);
date.month=inp(0x71);
outp(0x70,9);
date.year=inp(0x71);
time.second=(time.second&0x0f)+((time.second>>4)*10);
time.minute=(time.minute&0x0f)+((time.minute>>4)*10);
time.hour=(time.hour&0x0f)+((time.hour>>4)*10);
date.day=(date.day&0x0f)+((date.day>>4)*10);
date.month=(date.month&0x0f)+((date.month>>4)*10);
date.year=(date.year&0x0f)+((date.year>>4)*10);
_dos_settime(&time);
_dos_setdate(&date);
*/

68
audiolib/task_man.h Executable file
View File

@ -0,0 +1,68 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: TASK_MAN.C
author: James R. Dose
date: July 25, 1994
Public header for TASK_MAN.C, a low level timer task scheduler.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __TASK_MAN_H
#define __TASK_MAN_H
enum TASK_ERRORS
{
TASK_Warning = -2,
TASK_Error = -1,
TASK_Ok = 0
};
typedef struct task
{
struct task *next;
struct task *prev;
void ( *TaskService )( struct task * );
void *data;
long rate;
volatile long count;
int priority;
int active;
} task;
// TS_InInterrupt is TRUE during a taskman interrupt.
// Use this if you have code that may be used both outside
// and within interrupts.
extern volatile int TS_InInterrupt;
void TS_Shutdown( void );
task *TS_ScheduleTask( void ( *Function )( task * ), int rate,
int priority, void *data );
int TS_Terminate( task *ptr );
void TS_Dispatch( void );
void TS_SetTaskRate( task *Task, int rate );
void TS_UnlockMemory( void );
int TS_LockMemory( void );
#endif

133
audiolib/user.c Executable file
View File

@ -0,0 +1,133 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: USER.C
author: James R. Dose
date: April 26, 1994
Routines to parse command line options.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifdef PLAT_DOS
#include <dos.h>
#endif
#include <string.h>
#include "user.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#ifdef PLAT_DOS
extern int _argc;
extern char **_argv;
#endif
/*---------------------------------------------------------------------
Function: USER_CheckParameter
Checks if the specified string is present in the command line.
---------------------------------------------------------------------*/
int USER_CheckParameter
(
const char *parameter
)
{
#ifdef PLAT_DOS
int i;
int found;
char *ptr;
found = FALSE;
i = 1;
while( i < _argc )
{
ptr = _argv[ i ];
// Only check parameters preceded by - or /
if ( ( *ptr == '-' ) || ( *ptr == '/' ) )
{
ptr++;
if ( stricmp( parameter, ptr ) == 0 )
{
found = TRUE;
break;
}
}
i++;
}
return( found );
#else
return FALSE;
#endif
}
/*---------------------------------------------------------------------
Function: USER_GetText
Checks if the specified string is present in the command line
and returns a pointer to the text following it.
---------------------------------------------------------------------*/
char *USER_GetText
(
const char *parameter
)
{
#ifdef PLAT_DOS
int i;
char *text;
char *ptr;
text = NULL;
i = 1;
while( i < _argc )
{
ptr = _argv[ i ];
// Only check parameters preceded by - or /
if ( ( *ptr == '-' ) || ( *ptr == '/' ) )
{
ptr++;
if ( stricmp( parameter, ptr ) == 0 )
{
i++;
text = _argv[ i ];
break;
}
}
i++;
}
return( text );
#else
return NULL;
#endif
}

38
audiolib/user.h Executable file
View File

@ -0,0 +1,38 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: USER.H
author: James R. Dose
phone: (214)-271-1365 Ext #221
date: April 26, 1994
Public header for USER.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __USER_H
#define __USER_H
int USER_CheckParameter( const char *parameter );
char *USER_GetText( const char *parameter );
#endif

84
audiolib/usrhooks.c Executable file
View File

@ -0,0 +1,84 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: USRHOOKS.C
author: James R. Dose
date: July 26, 1994
This module contains cover functions for operations the library
needs that may be restricted by the calling program. This code
is left public for you to modify.
**********************************************************************/
#include <stdlib.h>
#include "usrhooks.h"
/*---------------------------------------------------------------------
Function: USRHOOKS_GetMem
Allocates the requested amount of memory and returns a pointer to
its location, or NULL if an error occurs. NOTE: pointer is assumed
to be dword aligned.
---------------------------------------------------------------------*/
int USRHOOKS_GetMem
(
void **ptr,
unsigned long size
)
{
void *memory;
memory = malloc( size );
if ( memory == NULL )
{
return( USRHOOKS_Error );
}
*ptr = memory;
return( USRHOOKS_Ok );
}
/*---------------------------------------------------------------------
Function: USRHOOKS_FreeMem
Deallocates the memory associated with the specified pointer.
---------------------------------------------------------------------*/
int USRHOOKS_FreeMem
(
void *ptr
)
{
if ( ptr == NULL )
{
return( USRHOOKS_Error );
}
free( ptr );
return( USRHOOKS_Ok );
}

55
audiolib/usrhooks.h Executable file
View File

@ -0,0 +1,55 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
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.
*/
/**********************************************************************
module: USRHOOKS.H
author: James R. Dose
date: July 26, 1994
Public header file for USRHOOKS.C.
This module contains cover functions for operations the library
needs that may be restricted by the calling program. The function
prototypes in this header should not be modified.
**********************************************************************/
#ifndef __USRHOOKS_H
#define __USRHOOKS_H
/*---------------------------------------------------------------------
Error definitions
---------------------------------------------------------------------*/
enum USRHOOKS_Errors
{
USRHOOKS_Warning = -2,
USRHOOKS_Error = -1,
USRHOOKS_Ok = 0
};
/*---------------------------------------------------------------------
Function Prototypes
---------------------------------------------------------------------*/
int USRHOOKS_GetMem( void **ptr, unsigned long size );
int USRHOOKS_FreeMem( void *ptr );
#endif

13
audiolib/util.h Executable file
View File

@ -0,0 +1,13 @@
#ifndef AUDIOLIB__UTIL_H
#define AUDIOLIB__UTIL_H
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#endif

77
buildengine/BUILDLIC.TXT Executable file
View File

@ -0,0 +1,77 @@
(Note from Ryan: This is Ken's BUILD license. It is NOT GPL. Please respect
his license, and also keep in mind that Ken does NOT work on the Linux port.
Please don't harrass him for bug fixes and enhancements to the Linux version.
He did the DOS version. --ryan.)
BUILD SOURCE CODE LICENSE TERMS: 06/20/2000
[1] I give you permission to make modifications to my Build source and
distribute it, BUT:
[2] Any derivative works based on my Build source may be distributed ONLY
through the INTERNET.
[3] Distribution of any derivative works MUST be done completely FREE of
charge - no commercial exploitation whatsoever.
[4] Anything you distribute which uses a part of my Build Engine source
code MUST include:
[A] The following message somewhere in the archive:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
[B] This text file "BUILDLIC.TXT" along with it.
[C] Any source files that you modify must include this message as well:
// This file has been modified from Ken Silverman's original release
[5] The use of the Build Engine for commercial purposes will require an
appropriate license arrangement with me. Contact information is
on my web site.
[6] I take no responsibility for damage to your system.
[7] Technical support: Before contacting me with questions, please read
and do ALL of the following!
[A] Look through ALL of my text files. There are 7 of them (including this
one). I like to think that I wrote them for a reason. You will find
many of your answers in the history section of BUILD.TXT and
BUILD2.TXT (they're located inside SRC.ZIP).
[B] If that doesn't satisfy you, then try going to:
"http://www.advsys.net/ken/buildsrc"
where I will maintain a Build Source Code FAQ (or perhaps I might
just provide a link to a good FAQ).
[C] I am willing to respond to questions, but ONLY if they come at a rate
that I can handle.
PLEASE TRY TO AVOID ASKING DUPLICATE QUESTIONS!
As my line of defense, I will post my current policy about
answering Build source questions (right below the E-mail address
on my web site.) You can check there to see if I'm getting
overloaded with questions or not.
If I'm too busy, it might say something like this:
I'm too busy to answer Build source questions right now.
Sorry, but don't expect a reply from me any time soon.
If I'm open for Build source questions, please state your question
clearly and don't include any unsolicited attachments unless
they're really small (like less than 50k). Assume that I have
a 28.8k modem. Also, don't leave out important details just
to make your question appear shorter - making me guess what
you're asking doesn't save me time!
----------------------------------------------------------------------------
-Ken S. (official web site: http://www.advsys.net/ken)

566
buildengine/CHANGELOG Executable file
View File

@ -0,0 +1,566 @@
/*
* CHANGELOG.
*
* Please do NOT harrass Ken Silverman about any code modifications
* (including this file) to BUILD.
*/
07112000 - Initial release from icculus. C code compiles, doesn't link, lots
of bastard assembly.
07122000 - LOTS of ASM cleanups by Andrew Henderson.
07132000 - Ryan adds some missing functionality: SDL equivalents for most of
the VESA functions, filelength(), and some other piddly stuff.
07142000 - Dan Olson cleans up the code a bunch, fills in a bunch of the
ASM routines with C equivalents, and puts some VESA replacements
in place. Other good stuff. Ryan cleans up some, too, put some
more stubs/implementations in place, and continues to flesh out
the SDL driver.
07212000 - A BUTTLOAD of updates. "build" links, and segfaults, because I
screwed up all the inline ASM that I did. Will be correcting,
shortly. "game" doesn't link yet. Haven't looked at it in detail.
Moved anything with i/o port calls into dos_driver.c, and put
stub equivalents in sdl_driver.c ... The setupmouse() function got
commented out because it was getting called before the video got
setup, I think. Will check. (never released.)
07272000 - Assembly in pragmas.c was borked (thanks to RYAN.), and is now
halfway fixed. Ryan will be fixing this completely Real Soon Now.
Other ASM may be screwey, too, if Ryan touched it, but the NASM
code that Andrew did is probably fine (mostly because he knows
what he's doing... :) )
07282000 - Fixed borked ASM code. Fixed a text file reading routine that
depended on finding DOS-style newlines. Moved some more stuff to
sdl_driver.c and dos_driver.c ...
07292000 - Fixes in pragmas.c by Dan Olson, who also knows more about this
inline ASM stuff than Ryan. Dan also cleaned up engine.c's ASM.
Thanks to Dan and Ryan, game.c now compiles, albeit with a
thousand warnings. "game" does not link yet.
07312000 - Thanks to Dan, "game" now links, other minor fixups by Ryan. Broke
up CHANGELOG into some standard docs. (README, CREDITS, etc...)
08012000 - Andrew does some graphic porting. Looks like we've got blocks where
fonts should be, and a mouse cursor. Huh. Ryan abstracts 0xa0000
addresses to VIDEOBASE define. Under non-DOS platforms, this is
currently "surface->pixels". Basic events were hooked up. Added
FreeVGA to README. Lots of fun new segfaults.
08042000 - Ryan gets the keyboard working apparently fully, and the mouse
sorta. The grid now draws correctly. No more segfaults on exit.
You can zoom in and out on the grid with the 'Z' and 'A' keys.
Fun, huh? sdl_driver's drawing routines (most notably, drawline16)
are MUCH more robust. Some minor structure changes. Other things
seem to work within build (space draws a line from a point to the
mouse, etc.), but I dunno what any of this means; must find a
BUILD HOWTO. Probably other stuff. Timer is hooked up, but SDL
won't fire a timer faster than every 10ms, or 100 times a second.
BUILD expects this timer to fire every 8.3~ seconds, or 120 times
a second. This may be problematic in the game, but it probably won't
be a problem in the BUILD editor, where it just handles keyboard
updates. An alternate timer system might get swapped in later.
Game still links, but aborts on initing the timer, since I need to
sync with the editor; Ken saw it fit to commit the mortal sin of
cut-and-paste instead of having a unified BUILD_Init() function,
so I need to update it to the new structure (using sdl_driver or
dos_driver, calling _platform_init(), blah blah blah...)
08052000 - Dan fixed an ASM screwup in getkensmessagecrc(). Ryan fixed the
mouse button event code. Added event thread, and some bits of
thread safety in sdl_driver.c. Mouse now seems to move okay if the
X11 cursor is hidden, and we grab the input. Goes to fullscreen
and grabs input by default; export BUILD_WINDOWED=y and
BUILD_NO_MOUSE_GRAB=y, respectively, to disable. Got myself a
copy of Duke3D Atomic Edition for the data files. Fixed the
#pragma packs in build.h. Fixed _platform_init() functions.
Improved SDL driver. Commented out a bunch of self-modifying ASM.
Dan got the fonts to display. Ryan got the correct palette loaded.
Lots of other little cleanups. Good stuff.
08062000 - Ryan fixed clear2dscreen() in SDL driver. It's (hopefully) correct,
now. Also, all that missing text should (hopefully) now display.
drawline16 is more correct now. Other little cleanups and
move-arounds. It seems that "pageoffset" is the big enemy around
here today. Hum.
08072000 - Ryan gets the BUILD title text to stop flickering. Prints our names
at exit (maybe someone will want to hump OUR legs, too). Added the
_idle() function to dos_driver and sdl_driver, and sprinkled some
calls through overheadeditor() in build.c ... ideally, we'd
eventually want to not have the editor wipe the surface and
redraw everything like mad constantly, but rather wipe and draw
as needed to choke the processor even less. Added implementation
of getfilenames() in build.c...seems to work well enough. Got
map loading dialog to appear (in the wrong place), but the arrow
keys don't seem to work to test further. Added caption to window's
title bar. Dan completely the Herculean effort of cleaning up
EVERY compiler warning in the editor. Other tinkering.
Adrian Neill and Christian Zander cleaned up all the compile
warnings in game.c and multi.c. Christian also supplied a shell
script to set the BUILD_* variables for developing. Ryan fixed
permissions of map files in saveboard() in engine.c. game.c had a
static variable called "sync" that conflicted with unistd.h's
sync() function, so the static's been changed to _sync. Fixed
more graphic stuff; pageoffset is just blindly set to zero on
Unix, now, and that seems to fix some stuff. printext16() was
changed to statusbar_printext16() in the appropriate places, so
I could remove my ypos += 336 hack in the actual implementation,
make this #define to regular printext16 on DOS, and be a one-line
function to add 336 to ypos in Unix. sdl_key_filter now has
support for extended keys; in init_new_res_vars(), just add keys
with values of 0xE0** where "**" is the normal value. This allowed
me to add the arrow keys and the keypad enter key. Tried loading
Ken's maps, and they WORK. With today's graphic fixes and the
arrow keys, you can select a file from the loading menu, and
navigate around in 2D mode. Cool. Switching to 3D mode segfaults
immediately. :) Changed sdl_driver to NOT double buffer, and
the SDL_Flip() call is now a screen-wide SDL_UpdateRect(). Added
Ken's maps for his test game to the archive.
08082000 - Added key bindings to sdl_driver: ALT-Enter (or ALT-Return) to
toggle between windowed and fullscreen, and CTRL-G to grab/ungrab
the mouse pointer. Increased sensitivity of mouse movement. Dan
fixed the editor's status bar; it now draws. I think Dan also
squashed the rest of the pageoffset annoyances in the editor.
Dan tracked down the line drawing problem, and Ryan patched some
ASM (clearbufbyte(), specifically), so you can add walls, now.
Things are REALLY starting to look good.
08092000 - ASM day. Fixes and fights from Dan and Ryan, with lots of wisdom
from Andrew. Realized that we were in violation of Ken Silverman's
license by not updating/including his copyright header on all
source files. This has been fixed; sorry, Ken. Other video stuff.
Tweakage. 3D mode no longer segfaults, but is still garbage.
08112000 - Fixed a bug; ALT-Enter wasn't changing sdl_flags, so next time you
changed resolutions, you went back to your original (non)windowed
state. Did the same for mouse grab state. Dan converted the ASM
for some more engine.c functions, and added a missing key to our
SDL scancode table. Hooked up keybindings in the (still not
functional) 3D mode. Discovered that we were missing some data
files. More sdl_driver tinkering. Moved stuff out of dos_driver's
_nextpage(), and back into the abstract engine.c section.
I don't know what I changed, but the sprite and vector squares
don't draw in the correct place anymore in engine.c's
draw2dscreen() ... culprit is something in sdl_driver.c...someone
diff this version against the last. Grrr. Generally, I'd fix this
before sending out a tarball, but it's 5:00a.m., and I need to get
something out the door here. Will fix for tommorow, and it doesn't
otherwise impede your use.
08122000 - Turned optimizations back on, and the broken drawing from last
night works again. Yikes. Dan stubbed out lots of the missing C
functions in a.c (someday, we'll fill really these in, I hope.),
and made mad progress on attacking our palette issues. Some compile
fixes (incomplete) to allow building without SUPERBUILD defined
(for removing voxel support...might be needed for pre-voxel games
like Duke3D...) The self-modifying ASM passes function parameters
in registers, so I needed to do an inline wrapper. This also now
sits in a.c. (Still crashes and otherwise doesn't WORK the same
in 3D mode, but still...) Added tiles000.art to the archive from
Duke3D shareware's duke3d.GRP file. I hope this doesn't violate
anyone's copyrights.
08132000 - (For reference, apparently GCC requires -O2 for inline asm to work.
That would explain the drawing barfs...) Dan fixed the status bar
(after Ryan broke it again. :) ), and moved krecipasm() into
a_linux.asm, since FPU opcodes don't inline correctly. Added Ken's
stuff.dat. As a milestone, 3D mode now seems to work a LITTLE.
Looking in the wrong place causes a segfault, and generally, what
very little draws seems mostly incorrect, but progress is being
made. Changed out all the collected data files with Ken's original
STUFF.DAT. initgroupfile() now aborts the program if it can't
open a data file. (Without stuff.dat, you get a blank surface, and
you have to blindly feel your way out of the program.) Dan also
started work on the command line tools, like kextract. Those are
in a separate tarball on the website.
08152000 - (Stuck at LinuxWorld...sorry for delays.) 3D mode now does not (by
default) segfault, and you can stumble around. Some walls seem to
render correctly. Lots of things cause segfaults. Disabled the MMX
overlays for now, as that is a little less self-modified code in
use. Dan fixed some keyboard scancodes (and also independently
fixed the same 3D mode things. hah. :) )
08192000 - Back from LinuxWorld. Added an obnoxious hall of mirrors detector
for 3D mode. _asm_slopevlin now returns immediately, which for now
stops most 3D mode segfaults. This will have to change, but it
helps for now. Put in a hack for checking frames-per-second.
Added some new keyboard scancodes.
08212000 - Another keyboard scancode added by Dan. Changed 3D mode to prompt
to save changes before dropping out of graphics mode; the stdio
thing was pretty obnoxious. Now we are basically waiting on a copy
of Watcom C to show up, so I can trace through the original code
and verify that I'm getting sane parameters and return values.
Needless to say, productivity has dropped off quite a bit.
08232000 - Dan found a screwup in the inlined dmulscale32()'s return value.
Consequently, now the hall of mirrors are gone. Cool. Walls seem
to render correctly all the time now. Other visual problems, and
no floors or ceilings, but this is a BIG win. Thanks, Dan! (A few
other ASM functions in pragmas.c had this problem. dmulscale32()
was the most noticable fix, though.)
08242000 - Dan added/fixed some more ASM. The SDL parachute is now in place,
so we will go back to the correct resolution, and the mouse
will ungrab in case of a segfault. A C version (mostly working?)
of qinterpolatedown16short() has been added to pragmas.c, and
the ASM version had a fix that allows ceilings to show (though they
render incorrectly in the correct place, and now certain sprites
segfault. Ugh. PageUp/PageDown scancodes now work, so you can
raise and lower ceilings and floors. Changed caption in titlebar
of windowed mode.
08292000 - Matt Helsley contributed some ASM -> C conversions, and some test
code to help with further porting. Cleaned up some cruft in the
sdl_driver. Dan nailed another clobber list issue in pragmas.c.
Thanks to Nicholas Vining, we now have a copy of Watcom C. Ryan
sat down and stepped through the ASM in gdb (NOT fun at all),
while Nicholas stepped through the DOS version in parallel.
Eventually we stumbled upon some misassembled opcodes; we ended
up filling some registers with a pointer, and not what the pointer
pointed at! Ryan went through a_linux.asm and fixed all these,
and now 3D mode is almost entirely FLAWLESS. This is so cool.
Bedtime; I hope you all enjoy this. :) Thanks Nicholas!
08302000 - GAME now works. There was something awful in multi.c, probably
memory corruption with a static initializer, so SDL_Init() would
die in XOpenDisplay(NULL). Yikes. I've stubbed out what game.c
needs for multiplayer and put it in multi_tcpip.c (guess what
THAT'S for. :) ). The original multiplayer code is completely
modem and COMit based, and is useless anywhere but DOS, so this
isn't a big loss. Added some support for building under Cygwin,
but not much. Note that distributing binaries of BUILD built with
Cygwin violates the GPL, due to newlib's license, so don't do it.
But you can try compiling your own local copies. Where the hell
did CONTRIB go? Quick rewrite of that file. Minor glitches and
sound (and networking?) are the only things pending.
08302000 - Temporary fix; either nsqrtasm() or its tables are not correct
(our C rewrite gives exactly the same results as the ASM version,
too), so we've replaced it with a call to the C runtime's sqrt()
function, which seems to work fine. I hacked at getting better
calls to timerhandler(); still not happy with the results.
I also fixed some stuff in sdl_driver.c, so you can have
resolutions > 320x200 in 3D mode. Use F4 in the game to change
modes. Dunno how you change it in the editor, but you'll note that
the 3D mode defaults to 640x480 now...this is where the editor
SHOULD be, but I had 320, 320 hardcoded in _setgamemode() for some
strange reason. Oh, and CONTRIB was lowercased. That's where it
went. URL for this project is now listed on Ken's homepage.
09012000 - Happy September. Code tree is now available via CVS, thanks to
Matt and "witten". Dan fixed another keysym. port i/o macros were
being called when changing to 3D mode in the editor; #ifdef'd to
PLATFORM_DOS, now. Misassembled opcode in msqrtasm() is now fixed,
so the function operates correctly. Removed the #if 0, so that
ASM now gets used.
09032000 - Dan fixed some printext16 calls in 2D mode. Added a BUILD_NOPENTIUM
environment variable: if set, it disables PentiumPro/PentiumII/MMX
optimizations. The code runs at more than 10fps less without
the Pentium overlays on my box (62fps to 50fps in the start of
nukeland.map at 640x480). I tried adding all the crazy compiler
optimizations I could think of. First, anything above -O2 causes
engine.c's compile to fail with a duplicate label from setgotpic.
This is an optimizer bug in inline asm. It cuts and pastes it
to inline it into each function, despite __volatile__ and the
lack of an inline keyword on the function where the ASM exists,
and you get a duplicate label. It's dumb. All the other
optimizations I threw at it worked, including pentiumpro
compilation, -fexpensive-optimizations, and -funroll-loops, but
there was absolutely NO increase in frame rate. I imagine most of
the time in 3D mode is being spent in a_linux.asm anyhow. If we
ever get this converted to C, those optimizations will be more
handy, I imagine, but for now, I've not committed the Makefile.
Cleaned up the README. After some tinkering, I managed to get
build to compile and RUN on Windows 98 with Cygwin. I can't
distribute binaries of this, as it would violate the GPL.
However, I will be merging the changes back into the main source
once I figure out the best way how. Mostly, the inline ASM needed
some hacks, but nothing I can cleanly #ifdef. Amazingly,
mprotect() worked identically on Linux and Cygwin. The mind
boggles. Changes that have made it into the CVS repository for the
Cygwin work follow: Removed dependency on the SDL event thread
(SDL_Init() fails on Win32 if you request an event thread), and
put SDL_PumpEvents() calls into _idle() and _nextpage(). This
seems to work fine, but there can be some breakage if there's a
keyboard polling loop somewhere that doesn't call either of these
functions. Added some %define macros to a_linux.asm to handle
C compilers that append an underscore to C identifiers. Updated the
Makefile for cygwin and other improvements.
09052000 - Checked if Duke3d maps can be edited. Apparently they can be,
but only sorta. Quitting from 2D mode only prompts you to save
if you've changed something, now. Fixed the CVS info in README.
Added Duke3D and Shadow Warrior data file info to README. Minor
cleanups in the Makefile. Moved VIDEOBASE defines to display.h.
_platform_init() now takes icon and titlebar titles, and has been
updated in all drivers.
02102001 - Someone on the 3DRealms Web Forums finds icculus.org:
http://www.3drealms.com/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=5&t=001318
02132001 - (Five months later...ugh.) Dan noticed that my webpage is being
discussed on the 3DRealms forums, so I went back into the code
and finished the work to get this running under Cygwin. Here's
the list of that work: Makefile is now more robust, added a
non-__attribute__ version of asm_prohlineasm4() to a.h, moved some
#includes in cache1d.c to prevent a double-definition of O_BINARY.
Fixed the inline asm in engine.c and pragmas.c to handle C
compilers that add underscores to identifiers. Removed the
SDL_HWSURFACE flag in sdl_driver.c (didn't realize this is
actually slower on most hardware, and it also breaks fullscreen
mode in Win32 on my box). Had to #ifndef CYGWIN the fnmatch stuff
in build.c until I find a portable, non-GPL solution.
02142001 - Dan Olson nailed an assembly bug that caused segfaults in the
2nd overhead view in Ken's game. After that fix was applied, I
tagged the current CVS as "final-non-win32", as I start the effort
to make this thing compile as a native win32 executable with
(gasp!) Watcom C. Lots of stuff is getting torn around, as
assumptions get challenged: PLATFORM_UNIX vs. PLATFORM_DOS? Now
there's a PLATFORM_WIN32. unix_compat.h's display stuff has been
moved to display.h, and all the files include "platform.h" instead
of unix_compat.h, which allows us to choose the correct
compatibility header at compile time (win32_compat.h,
unix_compat.h, or doscmpat.h). All the platform-specific includes
(io.h, and such) have been moved into their respective compat
header, which cleaned up a lot of mess. Just to keep it real with
Cygwin, the Makefile now autodetects Cygwin, and sets the build
properties accordingly. Using a non-Cygwin GCC on Linux doesn't
set the Cygwin-related properties. SDL_INC_DIR and SDL_LIB_DIR can
be set as environment variables, so you never need to touch the
Makefile directly with Cygwin. "make clean" now cleans up various
Watcom C output, and vi's annoying "~" backup files. Tons of
patches and enhancements and little cleanups just to get this
to build on Watcom. Thing builds now, but has lots of problems
running, which will be resolved, hopefully, tonight. The Linux
version still works fine, and presumably so will the Cygwin
version. Overall, the quality of the port's codebase is improving
through this effort. I wonder if the DOS version will build now...
02152001 - Did initial work to get a protected mode DOS binary running again.
Hey, why not? Not complete (compiles clean, no link). Lots of
cleanups, and again, this is improving the quality of the port's
codebase. As usual, the Linux, and presumably Cygwin, versions
still compile clean and run. Haven't tried Watcom/Win32 tonight.
Renamed dos_driver.c to dos_drvr.c, so you can build the DOS bits
on a regular FAT filesystem. Added a Makefile.dos for use with
Watcom C's wmake (based on Ken's original). Lots of other files
touched. Added a "make package" rule to the Makefile, to improve
the quality of my own life. Added (har) a FILEID.DIZ file, which
is really used for the package's zipfile comment, but I always
wanted to have one of those. :)
02182001 - Removed the ENDLINE_CHAR stuff in build.c; that textfile reading
code is now able to handle '\n', '\r', and "\r\n" endlines.
The findfirst/findnext/whatnot code now works on Linux, Cygwin,
and Watcom C (dos, and win32). It's still kludgy, though. More
compat header cleanups. Figured out how to get SDL working fully
with Watcom C (-ei command line to wcc386.exe, and declare your
SDL callbacks as __cdecl, etc.).
02192001 - More Watcom fixes; build.exe's 3D mode is now fully operational.
One graphical glitch in 2D mode, still, but otherwise appears
fully functional. Put safety checks in a.h. Put a fix in build.c's
overheadeditor(), so it doesn't try to reference element -1 in an
array when clicking the left mouse button. Other ASM cleanups.
Fixed an annoying function declaration in bstub.c. Fixed an
incorrect assumption in sdl_driver.c's VBE_setPalette() that was
exposed by game.c under Watcom/win32. One quick addition of the
keyword "extern" to game.c, and we have a working game.exe under
Windows that isn't GPL encumbered. Woohoo! Added a Watcom/win32
Makefile, updated the README, and released win32 binaries.
02202001 - Turned on more optimizations in the Watcom makefile, and cleaned
it up/abstracted it for public use. Added an nt_win option to that
makefile to make it not pop up a console window when started from
an icon. Added README-win32bins.txt to the CVS repository. Fixme
note to self added in engine.c, and an incorrect use of ASM in
pragmas.h was repaired. Now the drawpixel16 function is working,
closing the last bug specific to the Watcom/win32 port. Yay.
02212001 - Fixed the timer bug! It was a one line change in game.c, pointed
out by Matt Saettler. Amen. This led to a better abstraction:
PLATFORM_TIMER_HZ, defined in platform.h ... Removed the wedged-in
call to SDL_PumpEvents() in game.c...not needed anymore.
02222001 - Ported the codebase back to DOS. Point wmake.exe at Makefile.dos.
02262001 - Added code to enable write access to self-modified ASM memory pages
so this will work on WinNT and Win2K. Discovered it wasn't needed,
and the real problem is that Watcom produces an incorrect PE
header in the generated EXE files. Steven Fuller dug up a program
that fixes this, and did a ton of debugging. Added him to the
CONTRIB file. Fixed Makefile.w32 and changed the default builds
to optimized and not debug to make binary distribution easier.
Automated the packaging of binary releases in Makefile.
04262001 - EDuke 2.1 goes into private beta. Will it be the last release based
on Ken Silverman's original BUILD object code for Duke Nukem 3D?
05102001 - Embedded a Perl interpreter that runs a function in game.pl once
per frame into the KenBuild game. This is just a test for a future
project, and probably shouldn't be compiled by the average person.
Changes to the Makefile, game.c, game.pl, and buildperl.[ch] were
added. Changed all occurances of my email address from
lokigames.com to linuxgames.com. One or two comment tweaks
elsewhere. Updated README with SDL12 CVS instructions.
05192001 - Demands SDL_HWPALETTE, which seems to fix 8bit color targets. Added
other debugging info to sdl_driver.c, and put the (commented out)
starts of hardware surface/double buffering/page flipping support.
Updated TODO.
05222001 - Updated TODO again. Cleaned up engine.c's forward function
references. Put together engine.h, so that the engine's exported
functionality can be referenced via one header instead of a list
of function declarations plugged into every file. Made everything
that shouldn't be exported from engine.c static, but this is an
error-prone process, so it'll probably get tweaked as other Build
related code gets tried with this engine. Similar cleanups in
build.c, display.h, and elsewhere. Laid foundation for an OpenGL
renderer. No actual rendering is done, just context creation and
library setup when _setgamemode() is called on a system that uses
the SDL driver. This work may never get finished, but why not try?
Flip the "useopengl" flag in the Makefile to use this code.
Cleaned out a commented-out printf in maskwallscan(). Moved
New static flag in engine.c: initengine_called is set when
(surprise) initengine() is called. This is currently just used
with the MMX overlay code...now dommxoverlay is no longer exposed;
use setmmxoverlay() and getmmxoverlay() instead. Updated
build2.txt with this information. Removed global var: cachedebug
in engine.c, and put #define BUILD_CACHEDEBUG 0 at the top of the
source. Flip it to 1 if you ever need to tinker in the cache code.
Removed krecip() from engine.c, since nothing uses it (it just
wrapped krecipasm(), which IS used all over the place).
Other cleanups were made, along with update in build.txt. Lots of
code was touched in ways not appropriate to mention in polite
company.
05232001 - Added lookup.dat support code, thanks to TerminX's help. Changed
initgroupfile() to not exit() if the groupfile won't open().
instead, we check for failed return values in ExtInit() (bstub.c),
like we should have done from the start. Added check in ExtInit()
for the environment variable BUILD_GROUPFILE, which will be the
groupfile to open if the variable exists. If the variable isn't
set, we default to Ken's "stuff.dat". Between this and TerminX's
lookup.dat code, we should be able to wander around a Duke3D map
without segfaults all over the place. Changed initgroupfile() and
kopen4load() to take a (const char *) argument. Should probably
show some diligence in adding this elsewhere, too, for the sake
of cleanliness and bughunting. Added some more function
declarations to engine.h. Updated README with new info on
Mapster and Duke3D.
05262001 - Finally unearthed a copy of Watcom 11.0! Fixed up all the GNU
inline asm so that the Watcom preprocessor wouldn't puke on it,
and built new win32 binaries...apparently Watcom 11, unlike 10.6,
can make a PE header that WinNT and Win2000 will accept. Moved the
Win32 version up to SDL 1.2.0 from SDL-1.1.8, and added a Watcom
__cdecl pragma in display.h for SDL_VideoDriverName(). Updated
TODO.
05272001 - Added engine.h to dos_drvr.c to get the DOS binaries to compile.
Added README and CHANGELOG to the win32 and dos bin distros, and
updated README-dosbins.txt and README-win32bins.txt. Updated
README with info on Watcom 10 vs 11, porting to new OSes, etc.
Updated TODO, AGAIN. :) Wrote a hopefully-robust function that
toggles the screen surface between windowed and full screen
without using SDL_WM_ToggleFullScreen(), so that you can use
ALT-Enter on Win32. Accordingly, removed references to
SDL_WM_ToggleFullScreen() in display.h and sdl_driver.c ...
The new fullscreen toggle code throws up on Windows if you destroy
the window (via SDL_SetVideoMode()) while in the middle of
handling one of its events...we were processing all events via the
SDL event filter during the SDL_PumpEvents() call. I've added
handle_events() to sdl_driver.c, and replaced all the PumpEvents
calls with that. This gets its events via SDL_PollEvent(), and
passes them on to our filter manually. That's just generally better
practice anyhow. Put hardcoded environment variables in
sdl_driver.c into constants. Hall of mirror debugging, and all the
BUILDSDL output to stderr is now all compiled in, and trigged by
the existence of the BUILD_SDLDEBUG environment variable. Build
now always claims to have standard resolutions (up to the largest
your system claims to handle) available, and SDL will fake it if
they aren't there. This should fix the Win32 F4 problem, and
people without other modelines listed in their XF86Config. Also,
by setting the environment variable BUILD_SCREENRES, you can add
one window of any dimension to the list. For example,
"export BUILD_SCREENRES=666x666".
05282001 - Added a maximum screen resolution of 1600x1200. This can be raised
or lowered with an environment variable: export
BUILD_MAXSCREENRES=1024x768, if you like. Renamed
BUILD_NO_MOUSE_GRAB to BUILD_NOMOUSEGRAB for consistency. Renamed
BUILD_SCREENRES to BUILD_USERSCREENRES. Rewrote the spaghetti that
all this resolution management code had quickly become. The fight
with attempt_fullscreen_toggle() continues: gave up, and just
called setbrightness() to fix the palettes. Now tries to use
SDL_WM_ToggleFullscreen() first before doing it The Hard Way, and
just returns if there's no window manager reported by
SDL_GetVideoInfo->wm_available. All the debugging output (of which
there is still more added today) has been cleaned up and is
passed through a function called sdldebug() that is used like
fprintf(stderr), but adds the "BUILDSDL: " string to the front,
a newline to the end, and prints nothing if debugging is disabled.
TODO is, as usual, expanding. Added BUILD_HALLOFMIRRORS environment
var, so that it isn't bound to BUILD_SDLDEBUG anymore. The
BUILD_SDLDEBUG variable now needs a value: the file to write debug
information to. The value can be "-" to write to stdout. This is
for that obnoxious win32 platform. :)
05292001 - Added a hack for Windows systems using the "windib" driver.
Apparently windib has no way to distinguish between the return key
and the keypad enter, and they both come up as the former. Now, if
you hold down SHIFT while hitting either return or the keypad
enter, sdl_driver.c reports to the engine that the keypad enter
was pressed. Now I can get into 3D mode on WinNT 4.0. :)
05302001 - More toggle_fulscreen work. Check to see if the debug output file
was opened, and printf() a warning if not. setbuf(..., NULL) was
no longer called on stderr and stdout in sdl_driver.c's version
of _platform_init(), but the buffer is set to NULL for the debug
file now, which may or may not be stdout. Just for a goof, I added
vmWare virtual machine detection code, which returns false in the
portable C version, and does some lowlevel voodoo in i386 asm.
06012001 - Added sdldebug() output to list the version of SDL we compiled
against, and the version we are linked (dynamically) against.
06082001 - It's Neurotic Cleanup Day! Started putting support for compiling
with Visual C in place, and found how anal their anal settings
can be (does this beat -ansi -pendantic on Linux? Probably not.).
Converted all the "//" comments to "/*" (ugh), and added explicit
casting where needed. Replaced references to "long long" with
"__int64", which is #defined appropriately in the compat headers.
Now compiling the codebase with -ansi and -pendantic on Linux and
Cygwin. Changed PORTSIG in build.h. Moved the sound stubs out of
sdl_driver.c and into a #ifndef PLATFORM_DOS block in game.c; it's
KenBuild-specific, and I'm not interested in implementing it
cleanly, or at all, for non-DOS platforms. Cleaned up rest of
the forward references in game.c and build.c. Cleaned up the
OpenGL debugging output (it's now unified with the sdldebug()
code). Renamed a_linux.asm to a_nasm.asm, since it's used on Linux
and Windows (and probably everywhere else that there's an x86
system that isn't using Watcom). Implemented stricmp() on unix
(damned -ansi flag). Updated TODO and README. Changed the display
driver function _initkeys into initkeys. This will force a link
error in Build games, so they can be updated to call the driver's
init function; updated this in build.txt, too.
06122001 - Made mmulti.c compile with -ansi and -pedantic, as that might be
needed later. Testing the OpenGL waters again. Added string_dupe()
to replace strdup(), and changed a snprintf() call to sprintf() in
sdl_driver.c, so I could remove the _GNU_SOURCE define.
06132001 - Changed Unix makefile, so that you can (by setting usedlls=true)
compile buildengine.so and buildnet.so, and the game and build
binaries only statically link what is absolutely necessary. Setting
usedlls=false statically links all the Build code together,
although currently external libraries like SDL are still
linked dynamically. Platform drivers now need to store _argv and
_argc. Commented a few functions in engine.c as I start to grok
what each bit of code does.
06232001 - Cleaned up some whitespace issues in pragmas.c. The one SDL
dependency in engine.c has been abstracted into
_updateScreenRect() and implemented in the display drivers.
OpenGL should now always be compiled in unless you can't even
build it (and thus, I've officially flipped useopengl to "true"
in the Makefile). You can now choose your renderer at runtime by
setting the BUILD_RENDERER environment variable: Set it to
"software" for the usual drill, "opengl2d" for using OpenGL to
move the software-rendered framebuffer to the screen (got this
idea from zsnes. cool.), and "opengl3d" to try to render an actual
3D scene in OpenGL. Default is "software". The 3D stuff hasn't
even been started, since it'll need an actual implementation in
engine.c. The gl2D stuff is an hour's work. After the 3D
implementation is in there, I'll be adding Makefile flags and code
#ifdefs to prevent compilation of the software renderer, which
will end the need for most, if not all, of the assembly, and get
us running on different platforms. I know, easier said than done.
Other little cleanups and enhancements.
06242001 - Followed through on my threat, and split off most of the OpenGL
code into buildgl.c. :) Added more GL func pointers, and tried
(failingly) to get OpenGL2D more working. It's way too slow;
I guess all that conversion from 8-bit, through the lookup tables,
to 32-bit, back to whatever the screen depth is, etc is expensive.
Looks like it's just software rendering and full 3D. Sigh.
More SDL cleanups. (committed on Aug 1st).
07082001 - Implemented support for PhysicsFS in cache1d.c; this allows you to
replace your GRP file with a compressed ZIP file. This is optional,
since it's an extra dependency. PhysicsFS is another one of my
projects, and information and source for it can be found at:
http://www.icculus.org/physfs/ ... (committed on Aug 1st).
07162001 - Moved CVS repository to icculus.org. Updated README.
08012001 - Committed some stuff, fixed a bug in the PhysicsFS code. Flipped
the useopengl flag in the Makefile back to false for now. Added
PhysicsFS info to README. Changed all occurances of my email
address from linuxgames.com to clutteredmind.org.
08232001 - Moved a.c to a_gnu.c and pragmas.c to pragmas_gnu.c. Added
pragmas_visual.c and a_visualc.c, and got everything compiling on
Visual C. Added VisualC.zip. Unzip it and use those files to build
with Visual C. Updated Makefiles, READMEs, etc with the new
*_[gnu|visualc]* files. Cleanups elsewhere. Added a "distclean"
target which just calls "clean". The Visual C project doesn't work
right now; I gave up on it.
06232001 - Fixed a hang when lotagging a wall (closing bugzilla bug #25).
--ryan. (icculus@clutteredmind.org)
/* end of CHANGELOG ... */

17
buildengine/CONTRIB Executable file
View File

@ -0,0 +1,17 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
Ryan C. Gordon
Dan Olson
Andrew Henderson
Christian Zander
Adrian Neill
Matt Helsley
Nicholas Vining
Matt Saettler
Steven Fuller
Others I've probably forgotten (sorry! email me if you should be here. --ryan.)

198
buildengine/Engine.dsp Executable file
View File

@ -0,0 +1,198 @@
# Microsoft Developer Studio Project File - Name="Engine" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Engine - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Engine.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Engine.mak" CFG="Engine - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Engine - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Engine - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Engine - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "ReleaseVC6"
# PROP Intermediate_Dir "ReleaseVC6"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /GX /Ot /Ow /Oi /Op /Oy /Ob1 /I "SDL-1.2.5\include" /D "_LIB" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "USE_I386_ASM" /D "PLATFORM_WIN32" /D "UDP_NETWORKING" /YX /J /FD /c
# SUBTRACT CPP /Oa /Og /Os
# ADD BASE RSC /l 0xc09 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Engine - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "DebugVC6"
# PROP Intermediate_Dir "DebugVC6"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /Gm /GX /ZI /Od /I "SDL-1.2.5\include" /D "_LIB" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "USE_I386_ASM" /D "PLATFORM_WIN32" /D "UDP_NETWORKING" /FR /YX /J /FD /GZ /c
# ADD BASE RSC /l 0xc09 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Engine - Win32 Release"
# Name "Engine - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=a_nasm.asm
!IF "$(CFG)" == "Engine - Win32 Release"
# Begin Custom Build
TargetDir=.\ReleaseVC6
InputPath=a_nasm.asm
"$(TargetDir)\a_nasm.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
nasmw.exe -f win32 -DC_IDENTIFIERS_UNDERSCORED -o $(TargetDir)\a_nasm.obj $(InputPath)
# End Custom Build
!ELSEIF "$(CFG)" == "Engine - Win32 Debug"
# Begin Custom Build
TargetDir=.\DebugVC6
InputPath=a_nasm.asm
"$(TargetDir)\a_nasm.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
nasmw.exe -f win32 -DC_IDENTIFIERS_UNDERSCORED -o $(TargetDir)\a_nasm.obj $(InputPath)
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\a_visualc.c
# End Source File
# Begin Source File
SOURCE=.\cache1d.c
# End Source File
# Begin Source File
SOURCE=.\engine.c
# End Source File
# Begin Source File
SOURCE=.\mmulti.c
# End Source File
# Begin Source File
SOURCE=.\pragmas.c
# End Source File
# Begin Source File
SOURCE=.\sdl_driver.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\a.h
# End Source File
# Begin Source File
SOURCE=.\bstub.h
# End Source File
# Begin Source File
SOURCE=.\build.h
# End Source File
# Begin Source File
SOURCE=.\buildgl.h
# End Source File
# Begin Source File
SOURCE=.\buildperl.h
# End Source File
# Begin Source File
SOURCE=.\cache1d.h
# End Source File
# Begin Source File
SOURCE=.\display.h
# End Source File
# Begin Source File
SOURCE=.\engine.h
# End Source File
# Begin Source File
SOURCE=.\names.h
# End Source File
# Begin Source File
SOURCE=.\platform.h
# End Source File
# Begin Source File
SOURCE=.\pragmas.h
# End Source File
# Begin Source File
SOURCE=.\ves2.h
# End Source File
# Begin Source File
SOURCE=.\win32_compat.h
# End Source File
# End Group
# End Target
# End Project

200
buildengine/Engine.vcproj Executable file
View File

@ -0,0 +1,200 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Engine"
ProjectGUID="{2960B59D-CA80-4C18-A4DD-038C38A4113B}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\DebugVC7"
IntermediateDirectory=".\DebugVC7"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="SDL-1.2.5\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;USE_I386_ASM;PLATFORM_WIN32;UDP_NETWORKING=1"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
DefaultCharIsUnsigned="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Engine.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="wsock32.lib"
OutputFile=".\DebugVC7\Engine.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="0"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\ReleaseVC7"
IntermediateDirectory=".\ReleaseVC7"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
ImproveFloatingPointConsistency="TRUE"
FavorSizeOrSpeed="0"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories="SDL-1.2.5\include"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_I386_ASM;PLATFORM_WIN32;UDP_NETWORKING=1"
RuntimeLibrary="4"
DefaultCharIsUnsigned="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Engine.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="wsock32.lib"
OutputFile=".\ReleaseVC7\Engine.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="0"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="a_nasm.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="nasmw.exe -f win32 -dC_IDENTIFIERS_UNDERSCORED -o &quot;$(TargetDir)a_nasm.obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(TargetDir)\a_nasm.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="nasmw.exe -f win32 -dC_IDENTIFIERS_UNDERSCORED -o &quot;$(TargetDir)a_nasm.obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(TargetDir)\a_nasm.obj"/>
</FileConfiguration>
</File>
<File
RelativePath="a_visualc.c">
</File>
<File
RelativePath="cache1d.c">
</File>
<File
RelativePath="engine.c">
</File>
<File
RelativePath="mmulti.c">
</File>
<File
RelativePath="pragmas.c">
</File>
<File
RelativePath="sdl_driver.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="a.h">
</File>
<File
RelativePath="bstub.h">
</File>
<File
RelativePath="build.h">
</File>
<File
RelativePath="buildgl.h">
</File>
<File
RelativePath="buildperl.h">
</File>
<File
RelativePath="cache1d.h">
</File>
<File
RelativePath="display.h">
</File>
<File
RelativePath="doscmpat.h">
</File>
<File
RelativePath="engine.h">
</File>
<File
RelativePath="names.h">
</File>
<File
RelativePath="platform.h">
</File>
<File
RelativePath="pragmas.h">
</File>
<File
RelativePath="ves2.h">
</File>
<File
RelativePath="win32_compat.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

13
buildengine/FILEID.DIZ Executable file
View File

@ -0,0 +1,13 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
Port of BUILD engine from Ken Silverman's original DOS386 codebase to Linux
and Win32. BUILD is the engine that powers games like Duke Nukem 3D, Blood,
Shadow Warrior, Redneck Rampage, and others.
Please read the included README for all the dirty details.
--ryan. (icculus@clutteredmind.org)

337
buildengine/Makefile Executable file
View File

@ -0,0 +1,337 @@
# Makefile for building BUILD on Unix/Cygwin systems.
#
# Written by Ryan C. Gordon (icculus@clutteredmind.org)
# Do NOT contact Ken Silverman for support of BUILD on Unix or Linux.
#----------------------------------------------------------------------------
linux_ppc := false
beos := false
macosx := false
freebsd := false
solaris := false
linux64 := false
#-----------------------------------------------------------------------------#
# If this makefile fails to detect Cygwin correctly, or you want to force
# the build process's behaviour, set it to "true" or "false" (w/o quotes).
#-----------------------------------------------------------------------------#
#cygwin := true
#cygwin := false
cygwin := autodetect
#-----------------------------------------------------------------------------#
# You only need to set SDL_INC_DIR and SDL_LIB_DIR if you are using cygwin.
# SDL_INC_DIR is where SDL.h and associated headers can be found, and
# SDL_LIB_DIR is where SDL.lib and SDL.dll are located. These may be set as
# environment variables, if you'd prefer to not hack the Makefile.
#
# examples:
# SDL_INC_DIR := C:/2/SDL-1.1.8/include
# SDL_LIB_DIR := C:/2/SDL-1.1.8/lib
#-----------------------------------------------------------------------------#
ifeq ($(strip $(SDL_INC_DIR)),)
SDL_INC_DIR := please_set_me_cygwin_users
endif
ifeq ($(strip $(SDL_LIB_DIR)),)
SDL_LIB_DIR := please_set_me_cygwin_users
endif
CC = gcc
LINKER = gcc
#-----------------------------------------------------------------------------#
# To use a different platform's ASM or portable C, change this.
#-----------------------------------------------------------------------------#
#USE_ASM := -DUSE_I386_ASM
#-----------------------------------------------------------------------------#
# Don't touch this unless you know what you are doing.
#-----------------------------------------------------------------------------#
#useperl := true
useperl := false
#useopengl := true
useopengl := false
GL_INCLDIR := /usr/X11R6/include
#usedlls := true
usedlls := false
#usephysfs := true
usephysfs := false
#networking := stubbed
networking := udp
#-----------------------------------------------------------------------------#
# Everything below this line is probably okay.
#-----------------------------------------------------------------------------#
# been told this doesn't work on BeOS right now...
ifeq ($(strip $(beos)),true)
networking := stubbed
USE_ASM :=
endif
CFLAGS += -m32
LDFLAGS +=-m32 -L/usr/lib
ifeq ($(strip $(solaris)),true)
LINKER= cc
CC = cc
LDFLAGS += -lsocket -lnsl
CFLAGS += -DPLATFORM_SOLARIS
endif
ifeq ($(strip $(cygwin)),autodetect)
ifneq ($(strip $(shell gcc -v 2>&1 |grep "cygwin")),)
cygwin := true
else
cygwin := false
endif
endif
ifeq ($(strip $(cygwin)),true)
# (no choice on Cygwin right now...)
usedlls := false
ifeq ($(strip $(SDL_INC_DIR)),please_set_me_cygwin_users)
$(error Cygwin users need to set the SDL_INC_DIR envr var.)
else
SDL_CFLAGS := -I$(SDL_INC_DIR)
endif
ifeq ($(strip $(SDL_LIB_DIR)),please_set_me_cygwin_users)
$(error Cygwin users need to set the SDL_LIB_DIR envr var.)
else
SDL_LDFLAGS := -L$(SDL_LIB_DIR) -lSDL
endif
else
ifneq ($(strip $(freebsd)),true)
SDL_CFLAGS := $(shell /usr/bin/32/sdl-config --cflags)
SDL_LDFLAGS := $(shell /usr/bin/32/sdl-config --libs)
endif
endif
# Uncomment to use the Intel compiler (v6.0)
# Note: Version 6.0 Build 020312Z fails to compile engine.c
#CC = icc
#CFLAGS = -g $(SDL_CFLAGS) -DUSE_SDL=1 -O2
ifeq ($(strip $(cygwin)),true)
ASM = nasmw
DLL_EXT = .dll
EXE_EXT = .exe
ASMOBJFMT = win32
ASMDEFS = -dC_IDENTIFIERS_UNDERSCORED
CFLAGS += -DC_IDENTIFIERS_UNDERSCORED
else
ASM = nasm
DLL_EXT = .so
EXE_EXT =
ASMOBJFMT = elf
endif
ifeq ($(strip $(macosx)),true)
CFLAGS += -DPLATFORM_MACOSX=1 -faltivec -mdynamic-no-pic -falign-loops=32 -falign-functions=32
LDFLAGS += -framework AppKit -lSDL -lSDLmain
endif
ifeq ($(strip $(freebsd)),true)
CFLAGS += -DPLATFORM_FREEBSD=1
SDL_CFLAGS := $(shell sdl11-config --cflags)
SDL_LDFLAGS := $(shell sdl11-config --libs) -L.
endif
ifeq ($(strip $(linux_ppc)),true)
CFLAGS += -DPLATFORM_LINUXPPC=1
endif
ifeq ($(strip $(useopengl)),true)
CFLAGS += -DUSE_OPENGL -I$(GL_INCLDIR)
endif
ifeq ($(strip $(useperl)),true)
CFLAGS += -DUSE_PERL
LDPERL := $(shell perl -MExtUtils::Embed -e ldopts)
CCPERL := $(shell perl -MExtUtils::Embed -e ccopts)
# !!! can I lose the explicit path somehow?
PERLOBJS += buildperl.o /usr/lib/perl5/i386-linux/CORE/libperl.a
endif
ifeq ($(strip $(usephysfs)),true)
CFLAGS += -DUSE_PHYSICSFS
LDFLAGS += -lphysfs
endif
ifeq ($(strip $(usedlls)),true)
ENGINEBASE = buildengine
ENGINEDLL = $(strip $(ENGINEBASE))$(strip $(DLL_EXT))
NETBASE = buildnet
NETDLL = $(strip $(NETBASE))$(strip $(DLL_EXT))
endif
ifeq ($(strip $(networking)),stubbed)
CFLAGS += -DSTUB_NETWORKING=1
endif
ifeq ($(strip $(networking)),udp)
CFLAGS += -DUDP_NETWORKING=1
endif
# fixes code generation bug.
ifeq ($(strip $(beos)),true)
CFLAGS += -no-fpic
endif
ENGINESRCS = engine.c cache1d.c sdl_driver.c unix_compat.c
ifeq ($(strip $(USE_ASM)),-DUSE_I386_ASM)
ENGINESRCS += a_nasm.asm pragmas.c a_gnu.c
else
ENGINESRCS += a.c pragmas.c
endif
ifeq ($(strip $(useopengl)),true)
ENGINESRCS += buildgl.c
endif
NETSRCS = mmulti.c
GAMEEXE = game
GAMESRCS = game.c
#GAMESRCS += multi.c k.asm kdmeng.c
ifneq ($(strip $(usedlls)),true)
GAMESRCS += $(ENGINESRCS)
GAMESRCS += $(NETSRCS)
endif
BUILDEXE = build
BUILDSRCS = build.c bstub.c
ifneq ($(strip $(usedlls)),true)
BUILDSRCS += $(ENGINESRCS)
endif
ENGINEDIR = .
ASMFLAGS = -f $(ASMOBJFMT) $(ASMDEFS)
CFLAGS += $(USE_ASM) -DPLATFORM_UNIX -g $(SDL_CFLAGS)
LDFLAGS += -g $(SDL_LDFLAGS)
ifeq ($(strip $(solaris)),true)
CFLAGS += -xO5 -xchar=u
else
# Always turn OFF strict aliasing, even when optimizing. Otherwise, this is
# just an accident waiting to happen... --ryan.
CFLAGS += -fno-strict-aliasing
CFLAGS += -fno-omit-frame-pointer -Wall -O3 -funsigned-char
endif
# Rules for turning source files into .o files
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
%.o: %.asm
$(ASM) $(ASMFLAGS) -o $@ $<
# Rule for getting list of objects from source
ENGINEOBJS1 := $(ENGINESRCS:.c=.o)
ENGINEOBJS := $(ENGINEOBJS1:.asm=.o)
NETOBJS1 := $(NETSRCS:.c=.o)
NETOBJS := $(NETOBJS1:.asm=.o)
GAMEOBJS1 := $(GAMESRCS:.c=.o)
GAMEOBJS := $(GAMEOBJS1:.asm=.o)
BUILDOBJS1 := $(BUILDSRCS:.c=.o)
BUILDOBJS := $(BUILDOBJS1:.asm=.o)
CLEANUP = $(GAMEOBJS) $(BUILDOBJS) $(PERLOBJS) $(NETOBJS) \
$(GAMEEXE) $(BUILDEXE) $(ENGINEOBJS) $(ENGINEDLL) \
$(wildcard *.exe) $(wildcard *.obj) \
$(wildcard *~) $(wildcard *.err) \
$(wildcard .\#*) core
all: $(BUILDEXE) $(GAMEEXE)
ifeq ($(strip $(useperl)),true)
buildperl.o : buildperl.c
$(CC) -c -o $@ $< $(CFLAGS) $(CCPERL)
endif
ifeq ($(strip $(usedlls)),true)
$(ENGINEDLL) : $(ENGINEOBJS)
$(LINKER) -shared -o $(ENGINEDLL) $(LDFLAGS) $(ENGINEOBJS)
$(NETDLL) : $(NETOBJS)
$(LINKER) -shared -o $(NETDLL) $(LDFLAGS) $(NETOBJS)
endif
$(GAMEEXE) : $(ENGINEDLL) $(NETDLL) $(GAMEOBJS) $(PERLOBJS)
$(LINKER) -o $(GAMEEXE) $(LDFLAGS) $(LDPERL) $(PERLOBJS) $(GAMEOBJS) $(ENGINEDLL) $(NETDLL)
$(BUILDEXE) : $(ENGINEDLL) $(BUILDOBJS)
$(LINKER) -o $(BUILDEXE) $(LDFLAGS) $(BUILDOBJS) $(ENGINEDLL)
listclean:
@echo "A 'make clean' would remove" $(CLEANUP)
distclean: clean
clean:
rm -f $(CLEANUP)
#-----------------------------------------------------------------------------#
# This section is pretty much just for Ryan's use to make distributions.
# You Probably Should Not Touch.
#-----------------------------------------------------------------------------#
# These are the files needed in a binary distribution, regardless of what
# platform is being used.
BINSCOMMON = build$(strip $(EXE_EXT)) game$(strip $(EXE_EXT))
BINSCOMMON += ascboard.map boards.map evilal.map kensig.map nsnoal.map
BINSCOMMON += test.map nukeland.map
BINSCOMMON += stuff.dat
BINSCOMMON += BUILDLIC.TXT
BINSCOMMON += names.h
package: clean
cd .. ; zip -9rz ./BUILD-engine-$(shell date +%m%d%Y).zip buildengine -x "*CVS*" < buildengine/FILEID.DIZ
ifeq ($(strip $(cygwin)),true)
msbins: win32bins dosbins
win32bins:
wmake -f Makefile.w32 clean
wmake -f Makefile.w32
cp $(SDL_LIB_DIR)/SDL.dll .
echo -e "\r\n\r\n\r\nHEY YOU.\r\n\r\n\r\nTake a look at README-win32bins.txt FIRST.\r\n\r\n\r\n--ryan. (icculus@clutteredmind.org)\r\n\r\n" |zip -9rz ../BUILD-win32bins-$(shell date +%m%d%Y).zip $(BINSCOMMON) SDL.dll README-win32bins.txt README CHANGELOG
dosbins:
wmake -f Makefile.dos clean
wmake -f Makefile.dos
cp C:/WATCOM/BINW/DOS4GW.EXE .
echo -e "\r\n\r\n\r\nHEY YOU.\r\n\r\n\r\nTake a look at README-dosbins.txt FIRST.\r\n\r\n\r\n--ryan. (icculus@clutteredmind.org)\r\n\r\n" |zip -9rz ../BUILD-dosbins-$(shell date +%m%d%Y).zip $(BINSCOMMON) README-dosbins.txt README CHANGELOG DOS4GW.EXE
else
msbins: nocygwin
win32bins: nocygwin
dosbins: nocygwin
endif
nocygwin:
@echo This must be done on a Windows box in the Cygwin environment.
#-----------------------------------------------------------------------------#
# End packaging section.
#-----------------------------------------------------------------------------#
# end of Makefile ...

120
buildengine/Makefile.dos Executable file
View File

@ -0,0 +1,120 @@
#-----------------------------------------------------------------------------#
# Makefile for Watcom C 10.6 compilation for DOS i386 protected mode target.
#
# Written by Ryan C. Gordon. (icculus@clutteredmind.org)
#
# PLEASE FOLLOW ALL THE INSTRUCTIONS BEFORE BUILDING.
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# Don't touch this '!define BLANK ""' line.
#-----------------------------------------------------------------------------#
!define BLANK ""
#-----------------------------------------------------------------------------#
# Directory where Watcom C is installed. Should have an "h" child directory,
# so if you specify "C:\WATCOM", there should be a "C:\WATCOM\h" directory
# on your drive. DON'T ADD THE TRAILING '\' CHARACTER!
#-----------------------------------------------------------------------------#
WATCOMDIR = C:\WATCOM
#-----------------------------------------------------------------------------#
# When debugging, use "-d2", otherwise use the blank line.
#-----------------------------------------------------------------------------#
#DEBUGFLAGS = -d2
DEBUGFLAGS =
#-----------------------------------------------------------------------------#
# When debugging, use "d all", otherwise use the "op el" line.
#-----------------------------------------------------------------------------#
#LINKDEBUGFLAGS = d all
LINKDEBUGFLAGS = op el
#-----------------------------------------------------------------------------#
# Choose one, or mix and match. Releases should use the full line,
# debug builds should probably use the blank one.
#-----------------------------------------------------------------------------#
#OPTIMIZEFLAGS =
OPTIMIZEFLAGS = -oa -oe -of+ -ol -ol+ -om -oc -oi -or -otexan
#-----------------------------------------------------------------------------#
# Okay, you're done. Save this file and run "wmake -f Makefile.dos" ...
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# Don't touch anything below this line, unless you know what you're doing.
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
LINKSYS=dos4g
WATCOM_INC_DIR = $(WATCOMDIR)\h
INCLUDES = -i=$(WATCOM_INC_DIR)
DEFINES = -dUSE_I386_ASM -dPLATFORM_DOS
CFLAGS = $(INCLUDES) $(DEFINES) -w4 -we -e25 -ei -zq &
$(OPTIMIZEFLAGS) $(DEBUGFLAGS) -5r -bt=dos -mf
ASMFLAGS = $(INCLUDES) -mf -5r -w4 -we -e25 -zq
CC = wcc386.exe
ASM = wasm.exe
BUILDOBJS = a.obj bstub.obj build.obj cache1d.obj engine.obj &
multi_tcpip.obj dos_drvr.obj
GAMEOBJS = a.obj game.obj cache1d.obj engine.obj multi_tcpip.obj &
dos_drvr.obj kdmeng.obj k.obj
BUILDOBJS_COMMAS = a.obj,bstub.obj,build.obj,cache1d.obj,engine.obj,multi_tcpip.obj,dos_drvr.obj
GAMEOBJS_COMMAS = a.obj,game.obj,cache1d.obj,engine.obj,multi_tcpip.obj,dos_drvr.obj,kdmeng.obj,k.obj
all : project .SYMBOLIC
project : build.exe game.exe .SYMBOLIC
clean : .SYMBOLIC
erase *.obj
erase *.exe
erase *.o
erase *~
.asm.obj : .AUTODEPEND
*$(ASM) $[* $(ASMFLAGS)
.c.obj : .AUTODEPEND
*$(CC) $[* $(CFLAGS)
build.exe : $(BUILDOBJS) .AUTODEPEND
@%write build.lk1 NAME build
@%append build.lk1 FIL $(BUILDOBJS_COMMAS)
@%append build.lk1
!ifneq BLANK ""
*wlib -q -n -b build.imp
@%append build.lk1 LIBR build.imp
!endif
*wlink $(LINKDEBUGFLAGS) SYS $(LINKSYS) op c op maxe=25 op q @build.lk1
erase build.lk1
!ifneq BLANK ""
wrc -q -ad -t build.exe
!endif
game.exe : $(GAMEOBJS) .AUTODEPEND
@%write game.lk1 NAME game
@%append game.lk1 FIL $(GAMEOBJS_COMMAS)
@%append game.lk1
!ifneq BLANK ""
*wlib -q -n -b game.imp
@%append game.lk1 LIBR game.imp
!endif
*wlink $(LINKDEBUGFLAGS) SYS $(LINKSYS) op c op maxe=25 op q @game.lk1
erase game.lk1
!ifneq BLANK ""
wrc -q -ad -t game.exe
!endif
# end of Makefile.w32 ...

136
buildengine/Makefile.w32 Executable file
View File

@ -0,0 +1,136 @@
#-----------------------------------------------------------------------------#
# Makefile for creating Build with Watcom C for win32.
#
# Written by Ryan C. Gordon. (icculus@clutteredmind.org)
#
# PLEASE FOLLOW ALL THE INSTRUCTIONS BEFORE BUILDING.
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# Don't touch this '!define BLANK ""' line.
#-----------------------------------------------------------------------------#
!define BLANK ""
#-----------------------------------------------------------------------------#
# Directory where Watcom C is installed. Should have an "h" child directory,
# so if you specify "C:\WATCOM", there should be a "C:\WATCOM\h" directory
# on your drive. DON'T ADD THE TRAILING '\' CHARACTER!
#-----------------------------------------------------------------------------#
WATCOMDIR = C:\WATCOM
#-----------------------------------------------------------------------------#
# Directory where Simple Directmedia Layer (SDL) is installed. SDL can be
# downloaded from http://www.libsdl.org/. There should be "include" and "lib"
# child directories, so if you specify "C:\SDL-1.1.8", there should be
# C:\SDL-1.1.8\lib" and "C:\SDL-1.1.8\include" directories on your drive.
# DON'T ADD THE TRAILING '\' CHARACTER!
#-----------------------------------------------------------------------------#
SDLDIR = C:\SDL-1.2.0
#-----------------------------------------------------------------------------#
# When debugging, use "d all", otherwise use the "op el" line.
#-----------------------------------------------------------------------------#
#LINKDEBUGFLAGS = d all
LINKDEBUGFLAGS = op el
#-----------------------------------------------------------------------------#
# Choose one, or mix and match. Releases should use the full line,
# debug builds should probably use the blank one.
#-----------------------------------------------------------------------------#
#OPTIMIZEFLAGS =
OPTIMIZEFLAGS = -oa -oe -of+ -ol -ol+ -om -oc -oi -or -otexan
#-----------------------------------------------------------------------------#
# Set this to "nt" to create a console window for viewing stdio output
# along with the usual graphical windows. This is for debugging only.
# Set it to nt_win to just get the graphical windows. This is for release
# builds.
#-----------------------------------------------------------------------------#
#LINKSYS=nt
LINKSYS=nt_win
#-----------------------------------------------------------------------------#
# Okay, you're done. Save this file and run "wmake -f Makefile.w32" ...
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
# Don't touch anything below this line, unless you know what you're doing.
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
WATCOM_INC_DIR = $(WATCOMDIR)\h;$(WATCOMDIR)\h\nt
SDL_INC_DIR = $(SDLDIR)\include
SDL_LIB_DIR = $(SDLDIR)\lib
INCLUDES = -i=$(WATCOM_INC_DIR);$(SDL_INC_DIR)
DEFINES = -dUSE_I386_ASM -dPLATFORM_WIN32
CFLAGS = $(INCLUDES) $(DEFINES) -w4 -we -e25 -ei -zq &
$(OPTIMIZEFLAGS) $(DEBUGFLAGS) -bm -5r -bt=nt -mf
ASMFLAGS = $(INCLUDES) -mf -5r -w4 -we -e25 -zq
CC = wcc386.exe
ASM = wasm.exe
BUILDOBJS = a.obj bstub.obj build.obj cache1d.obj engine.obj &
multi_tcpip.obj sdl_driver.obj
GAMEOBJS = a.obj game.obj cache1d.obj engine.obj multi_tcpip.obj &
sdl_driver.obj
BUILDOBJS_COMMAS = a.obj,bstub.obj,build.obj,cache1d.obj,engine.obj,multi_tcpip.obj,sdl_driver.obj
GAMEOBJS_COMMAS = a.obj,game.obj,cache1d.obj,engine.obj,multi_tcpip.obj,sdl_driver.obj
all : project .SYMBOLIC
project : build.exe game.exe .SYMBOLIC
clean : .SYMBOLIC
erase *.obj
erase *.exe
erase *.o
erase *~
.asm.obj : .AUTODEPEND
*$(ASM) $[* $(ASMFLAGS)
.c.obj : .AUTODEPEND
*$(CC) $[* $(CFLAGS)
build.exe : $(BUILDOBJS) .AUTODEPEND
@%write build.lk1 NAME build
@%append build.lk1 FIL $(BUILDOBJS_COMMAS)
@%append build.lk1
!ifneq BLANK ""
*wlib -q -n -b build.imp
@%append build.lk1 LIBR build.imp
!endif
*wlink $(LINKDEBUGFLAGS) SYS $(LINKSYS) libp $(SDL_LIB_DIR) libf SDL.lib &
$(LINKDEBUGFLAGS) op c op maxe=25 op q @build.lk1
erase build.lk1
!ifneq BLANK ""
wrc -q -ad -t build.exe
!endif
game.exe : $(GAMEOBJS) .AUTODEPEND
@%write game.lk1 NAME game
@%append game.lk1 FIL $(GAMEOBJS_COMMAS)
@%append game.lk1
!ifneq BLANK ""
*wlib -q -n -b game.imp
@%append game.lk1 LIBR game.imp
!endif
*wlink $(LINKDEBUGFLAGS) SYS $(LINKSYS) libp $(SDL_LIB_DIR) libf SDL.lib &
$(LINKDEBUGFLAGS) op c op maxe=25 op q @game.lk1
erase game.lk1
!ifneq BLANK ""
wrc -q -ad -t game.exe
!endif
# end of Makefile.w32 ...

249
buildengine/README Executable file
View File

@ -0,0 +1,249 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
/*
* README.
*
* Please do NOT harrass Ken Silverman about any code modifications
* (including this file) to BUILD.
*/
(This code DOES run on Windows. Read on.)
For building on Linux, you NEED gcc 2.95.2 (or maybe later) to compile this
code correctly. You'll also need Netwide Assembler (NASM). Get it at:
http://www.kernel.org/pub/software/devel/nasm/
(May I reiterate? Earlier than 2.95.2 revisions of GCC and EGCS do NOT
compile this code correctly! It will run, but there will be all sorts of
strange graphic glitches and odd crashes.)
For building on Win32, you need Watcom C v11.0. With the Win32 target (Perhaps
they call it the "NT" target?) installed. You can maybe get by with Watcom C
version 10.x, but the binaries tend not to work on WinNT in that case. You
can also compile the code on Win32 with Cygwin and NASM. Read below for more
details in either case.
For building under DOS, you need Watcom C v11 or v10 with the DOS target
installed.
This code uses Simple Directmedia Layer (SDL) for graphics, sound, and other
platform abstractions. Build relies on a fairly recent SDL code snapshot.
Get SDL from CVS like this:
cvs -d :pserver:guest@cvs.lokigames.com:/cvs login
# password is "guest", without the quotes.
cvs -z3 -d :pserver:guest@cvs.lokigames.com:/cvs checkout SDL12
cd SDL12; ./autogen.sh; make; make install
CVS is also good if you want the up-to-the-minute changes of BUILD:
cvs -z3 -d:pserver:anonymous@icculus.org:/cvs/cvsroot login
# password is "anonymous", without the quotes.
cvs -z3 -d:anonymous@icculus.org:/cvs/cvsroot co buildengine
There is a win32 CVS client available for download here:
http://www.icculus.org/misc/cvs-over-ssh-win32.zip
You can get more information about CVS from http://cvshome.org/ ...
PLEASE READ THE CHANGELOG AND TODO FILE FOR DETAILS ON WHAT'S NEW AND
WHAT'S NEEDED! They're in the tarball.
Have fun!
--ryan. (icculus@clutteredmind.org)
INFO:
- Patches go to Ryan at icculus@clutteredmind.org.
- Please try to keep it so the original source can still be compiled with
Watcom C for DOS. Maybe if we do a good enough job, we can just get Ken
to make this his official version, although this is not the goal right now.
You may #ifdef DOSisms with PLATFORM_DOS, and Unixism with PLATFORM_UNIX, but
try not to touch the original code if you can circumvent it (i.e. reimplement
the functionality of missing functions in a separate file, #define
__interrupt to be blank, etc...) Reference unix_compat.[ch] and sdl_driver.c
for examples of this behaviour.
- See us in #loki at irc.openprojects.net with questions.
- This is NOT a Loki-sponsored project. We are (er...WERE) Loki employees
that get off on this stuff. Don't harrass info@lokigames.com about it.
- Yes, you CAN edit Duke3D maps with this. Sort of.
Find your DUKE3D.GRP file, and set this environment variable:
(on Windows: "set BUILD_GROUPFILE=C:\where\grpfile\is\DUKE3D.GRP")
(on Linux/bash: "export BUILD_GROUPFILE=/where/grpfile/is/DUKE3D.GRP")
Without this environment variable, Build looks for "stuff.dat" in the
current directory; that's KenBuild's groupfile.
Now go get a Duke3D map off the net and open it in build.
I haven't tried Blood, Shadow Warrior, or anything else, but someone sent
me screenshots of Shadow Warrior. Your mileage may vary.
Either way, there's lots of screenshots up at:
http://www.icculus.org/BUILD/screenshots/duke3d_data_files/
http://www.icculus.org/BUILD/screenshots/shadow_warrior_data_files/
There is still much missing from Build that is needed to use it as a Duke3D
editor, and that is not the focus of this project. It is DEFINITELY not
enough to PLAY duke3d, as there is no CON interpreter or correct physics
or enemy AI or equivilent sector tags etc.
If an editor is all you want, there is a project called Mapster
(http://mapster-rtcm.totalconversions.com/) that is a KenBuild source
modification to support all of DukeBUILD's features, and add some new
enhancements, too. Stay tuned, as there may be a win32 (and Linux?) version
of Mapster sooner or later.
In short, is this enough to play Duke/Shadow/Blood? No. But it's a good start.
- Can Windows users use this code? You bet. Binaries available.
- To build this from source under Windows:
You can use Cygwin, a Windows port of the GNU C compiler. Cygwin is free (as
in speech and beer), and can be downloaded from
http://sources.redhat.com/cygwin/. You will also need to have a development
version of SDL installed (I used the prebuilt SDL libraries under
Windows, look at http://www.libsdl.org/). And, as under Linux, you will
need NASM (http://www.kernel.org/pub/software/devel/nasm/). Make sure
nasmw.exe ends up somewhere in your PATH, and SDL is somewhere you have
access to. Once you have all this set up, unpack the BUILD sources.
Make sure you're in the buildengine directory. Set these two environment
variables:
export SDL_LIB_DIR=C:/where/i/installed/SDL-1.2.0/lib
export SDL_INC_DIR=C:/where/i/installed/SDL-1.2.0/include
(Yes, those directory separators are backwards; it is intentional.)
...then, type "make", and it should produce binaries for you if you did
everything right.
You will have to make sure that SDL.DLL and CYGWIN1.DLL are in your path
somewhere.
This isn't all as hard as it sounds. :)
- To build with Watcom C for Win32: Get SDL (as above). Unpack the source,
edit Makefile.w32 (instructions are in that file). Change the paths at the
top to point to your Watcom and SDL installs. Run "wmake -f Makefile.w32"
... that's all. I tried this with Watcom C 10.6 and 11.0 using the win32
(both "nt" and "nt_win") targets. Anything older than Watcom C 11.0 will
NOT build an EXE that will work on Windows NT 4.0 or Windows 2000, even
though the same binary will work on Windows 95 and 98. Your mileage may vary.
- If anyone wants to make this work with Visual C++ to make this easier
for Windows users, I'll happily accept your changes and additions.
- One more thing, about licensing. If you build this with Cygwin, you are
NOT permitted to release binaries, as Cygwin's POSIX-support DLL is
under the GPL license, which forbids distribution of code linked with it
that doesn't abide by the OpenSource definition (Ken's license does
not). Harrassing Ken Silverman to change his license to the GPL is not
only rude, it's unproductive. Distributing binaries built with Cygwin
opens you up to lawsuits from Red Hat and the Free Software
Foundation. Do the right thing; if you must distribute BUILD binaries,
don't build them with Cygwin.
- Does this code still work under DOS? Yup. You use Watcom C the same as you
would for the Windows target, except you use Makefile.dos. Note that the
Windows and Linux versions are better maintained, more stable, and support
more hardware. Don't ask Ken about the DOS port either. He probably wouldn't
recognize his own code after all the mangling we did. :)
- Wish your GRP files weren't so big? Convert them to PkZip format, build
the engine with PhysicsFS support, and set the environment variable
BUILD_GROUPFILE=mygroupfile.zip ... Look at PhysicsFS's homepage for more
information: http://www.icculus.org/physfs/ ...
GOOD REFERENCES:
- VESA i/o reference: http://pm.cse.rmit.edu.au/~steve/vbe/vbe20.htm
- http://www-cgi.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html
(THE Interrupt List, from Ralf Brown. Good stuff, here.)
- FreeVGA: A VGA documentation project.
http://www.goodnet.com/~tinara/FreeVGA/home.htm
- BUILD keyboard reference: http://home.online.no/~flovstak/duke/bkeys.htm
- mapFAQ: http://mapfaq.3dportal.com/
- Ken Silverman's homepage: http://www.advsys.net/ken/
- The Art of Assembly Language, complete text:
http://webster.cs.ucr.edu/Page_asm/ArtofAssembly/ArtofAsm.html
HOW TO FIX ALL YOUR "//" COMMENTS:
- We now compile BUILD with the most anal compiler settings available for any
given platform. This forces us to write cleaner, more portable, and less
buggy code, but sometimes it limits what we can get away with. Most notably:
comment syntax. There are some compilers on some platforms
(*coughcoughSolariscoughcough*) that are very anal about (the old version
of) the C specification they follow. Therefore, you can NOT use "//" single
line comments in code compiled on those toolchains. Since Ken used nothing
but // comments, I needed to automate the conversion process a little bit.
Here's the quick and dirty way to convert them, using Perl:
--- snip. ---
while (<STDIN>) {
chomp;
s/(.*)(?<!:)\/\/\s*(.*)\s*/$1\/\* $2 \*\//;
print("$_\n");
}
--- snip. ---
Just put that in a file, convert.pl, and run:
perl -w convert.pl < mysrc.c > myconvertedsrc.c
(patches to that code are welcome.)
TO PORT TO NEW COMPILERS AND TOOLCHAINS:
- Try to get nasm to generate object files that your linker can understand.
That is the easiest for the asm modules. Use a_nasm.asm, which is the NASM
version. a.asm is the Watcom Assembler (wasm) version that Ken distributed
with the original Build source release.
- The alternative is to write portable C code to avoid all the self-modifying
ASM. Have the appropriate amount of fun.
- There is inline assembly in engine.c, game.c, pragmas*.c, and pragmas.h.
Every compiler has their own syntax for this. Have more fun.
- Try to find clean syntax fixes that work everywhere instead of #ifdef'ing,
if you can. Platform.h is a good starting point.
TO PORT TO NEW OPERATING SYSTEMS:
- If Simple Directmedia Layer supports your OS, you're in luck. Just get
everything building (see above). If not, look at display.h for what you
need to implement, and sdl_driver.c and dos_drvr.c for examples. Consider
getting SDL working on your platform instead.
- Your platform needs at least an 8-bit linear framebuffer for video.
Otherwise, you can pray the OpenGL code gets written and is useful to you.
- The code doesn't necessarily NEED a keyboard, but the input device has GOT
to have a lot of buttons. The renderer itself doesn't deal with input, just
the apps (build, game, duke3d) that use it, so this may not be a problem,
depending on your needs. Some apps (the editor itself, for example) seem to
demand a mouse.
- Your platform needs to be 32-bit clean, in all likelihood. You might be able
to make enough band-aids to get this working otherwise. No one's tried it on
a 64-bit platform yet, partially due to all the (32-bit) assembly code.
16-bits or less will likely be a nightmare.
- Start in platform.h for an idea of where to add anything that's
platform-specific. If you can't get by on PLATFORM_UNIX, then define
PLATFORM_WHATEVER.
- Try not to wedge in platform dependent code, but find good abstractions.
TO PORT TO NEW PROCESSORS:
- You can either write new ASM for your processor, or better yet, implement
the stuff in portable C, so everyone can benefit.
- Most of your work will be in pragmas.*, a_linux.*, and a.*. Look for
USE_I386_ASM. Define your own version.
/* end of README ... */

48
buildengine/README-dosbins.txt Executable file
View File

@ -0,0 +1,48 @@
BUILD binaries for DOS (i386 and greater) systems.
These binaries are BETA quality. Expect crashes.
Bug reports to Ryan C. Gordon (icculus@clutteredmind.org).
I've only tested this briefly on a Windows 98 (second edition) box, in a DOS
window. YMMV.
Please feel free to report success and failure on different Windows platforms.
This does not play Duke3D, Shadow Warrior, Blood, or any other game but Ken's
test game ("KenBuild"). It can sort of edit Duke3D maps, but the BUILD.EXE on
your commercial Duke3D CD-ROM is better suited. You can also check out Mapster
(http://mapster-rtcm.totalconversions.com/), which might be useful to you.
Do NOT harrass Ken Silverman about these binaries. He did not compile them.
He did not release them. He is not maintaining this port and he does NOT want
to hear from YOU.
Here is his license text stuff:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
// This file has been modified from Ken Silverman's original release
The source code of the Build port (along with screenshots of it running) is
available from http://www.icculus.org/
Feel free to send me comments, complaints, suggestions, and donations.
Enjoy!
--ryan. (icculus@clutteredmind.org)
CHANGELOG of DOS binary releases:
02222001 - first binary release.
02262001 - Improved Makefile system. May not be packaging correctly, though.
05272001 - Compiled with Watcom C 11.0. Can sort of edit Duke3D maps. Read the
README. Lots of non-platform-specific fixes and enhancements. Read
the CHANGELOG.
// end of README-dosbins.txt ...

View File

@ -0,0 +1,71 @@
BUILD binaries for Win32 systems.
These binaries are BETA quality. Expect crashes.
The notable annoyances:
1) No sound.
2) No networking. Boohoo. :)
Bug reports to Ryan C. Gordon (icculus@clutteredmind.org).
I've only tested this briefly on a Windows 98 (second edition) box, and even
more briefly on WinNT 4.0 (Service Pack 6) under vmWare. YMMV.
Please feel free to report success and failure on different Windows platforms.
This, obviously, will not work on a Windows 3.1 platform, for that one
sadistic guy who's going to try it. :)
This does not play Duke3D, Shadow Warrior, Blood, or any other game but Ken's
test game ("KenBuild"). It can sort of edit Duke3D maps, but the DOS-based
BUILD.EXE on your commercial Duke CD-ROM is better suited. You can also check
out Mapster (http://mapster-rtcm.totalconversions.com).
Do NOT harrass Ken Silverman about these binaries. He did not compile them.
He did not release them. He did not port this to Windows and he does NOT want
to hear from YOU.
Here is his license text stuff:
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
// This file has been modified from Ken Silverman's original release
This code also relies on Simple Directmedia Layer (SDL) for graphics and input.
This excellent cross-platform library was put together by Sam Lantinga, and
is available to us under the LGPL license. That means that I can use it
freely, but I have to point you to a place where you can get the source
for yourself (the DLL is in this archive, though, so this is strictly FYI):
http://www.libsdl.org/
The source code of the Build port (along with screenshots of it running) is
available from http://www.icculus.org/
Feel free to send me comments, complaints, suggestions, and donations.
Enjoy!
--ryan. (icculus@clutteredmind.org)
CHANGELOG of win32 binary releases:
02192001 - first binary release.
02202001 - Fixed rendering bug in 2D editor, enabled optimizations,
disabled debugging. Disabled console window.
02212001 - Fixed too-slow gameplay (Thanks, Matt!).
02222001 - Ported back to DOS/386...since so much code got touched, it's
worth putting out a new binary to make sure nothing broke.
02262001 - Fixed WinNT/Win2k problems. Should run now. YMMV. Automated
packaging system, but not sure if everything is getting included.
time will tell.
05272001 - Built with Watcom C 11.0, so the things work under WinNT and Win2000
without editing the EXE. Updated to SDL 1.2.0. Can sorta edit Duke3D
maps now (see README) Lots of other non-platform-specific fixes and
updates. See the CHANGELOG.
// end of README-win32bins.txt ...

47
buildengine/TODO Executable file
View File

@ -0,0 +1,47 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
(questions to Ryan C. Gordon, icculus@clutteredmind.org)
NEXT ON TAP:
- extern "C" in every header.
- Litter the code with assertions.
- ASM->C port for non-intel boxes?
- Look for the string "!!!" ... these are TODOs in the source.
- Tie the window manager quit request to the program, so it reacts like an
ESC in 3D mode, and a "ESC, Q" in 2D mode. This will allows the user to
abort the shutdown, save if there are changes, etc...
- Make 2D mode only prompt to save changes on exit if there are changes to
save.
- Looking up/down in the editor seems to screw things up. This might not be
the case in 320x200 resolution. Look into it.
- Slopes are misdrawn in kensig.map. (still?)
- Sound.
- Networking.
- Port to Visual C?
- Port to Mingwin32? (the mprotect()s need to be #ifdef'd out. That should
be the biggest change.)
- Port to BeOS?
- Make a statically linked binary option in the Linux Makefile.
- Make a linuxbins target (like msbins target) in the Linux Makefile.
- Hardware surface/page flipping for more rendering speed?
- Can we sync to vblank in SDL?
- OpenGL? This would accelerate rendering, get us out of 8-bit hell, make it
prettier, and take out most of the ASM code, for porting to other processors.
But it will also give us all ulcers. :)
- Update Ken's docs, where applicable.
- Remove all possible global variables, and expose getter/setter functions
instead.
- There's an SDL_UpdateRect() call in engine.c (__printext256().) Do something
about it.
- Can we convert any existing tabs into equivalent spaces ASCII 32 chars, so
the align at 4-space tabstops? Tabs suck.
- Can we move those SDL __cdecl pragmas out of display.h?
- Long filenames confuse the editor's file "dialog".
- boardfilename (and others) in build.c and elsewhere are hardcoded to 13 chars.
- Might be worth moving all that resolution management code from sdl_driver.c
to engine.c ...
// end of TODO ...

2436
buildengine/a.asm Executable file

File diff suppressed because it is too large Load Diff

1090
buildengine/a.c Executable file

File diff suppressed because it is too large Load Diff

181
buildengine/a.h Executable file
View File

@ -0,0 +1,181 @@
/*
* "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
* Ken Silverman's official web site: "http://www.advsys.net/ken"
* See the included license file "BUILDLIC.TXT" for license info.
* This file IS NOT A PART OF Ken Silverman's original release
*/
#ifndef _INCLUDE_A_H_
#define _INCLUDE_A_H_
#if (defined __WATCOMC__)
#error Do not include this header with Watcom C.
#endif
#ifdef __cplusplus
extern "C" {
#endif
long mmxoverlay(void);
long sethlinesizes(long,long,long);
long setpalookupaddress(char *);
long setuphlineasm4(long,long);
long hlineasm4(long,long,long,long,long,long);
long setuprhlineasm4(long,long,long,long,long,long);
long rhlineasm4(long,long,long,long,long,long);
long setuprmhlineasm4(long,long,long,long,long,long);
long rmhlineasm4(long,long,long,long,long,long);
long setupqrhlineasm4(long,long,long,long,long,long);
long qrhlineasm4(long,long,long,long,long,long);
long setvlinebpl(long);
long fixtransluscence(long);
long prevlineasm1(long,long,long,long,long,long);
long vlineasm1(long,long,long,long,long,long);
long setuptvlineasm(long);
long tvlineasm1(long,long,long,long,long,long);
long setuptvlineasm2(long,long,long);
long tvlineasm2(long,long,long,long,long,long);
long mvlineasm1(long,long,long,long,long,long);
long setupvlineasm(long);
long vlineasm4(long,long);
long setupmvlineasm(long);
long mvlineasm4(long,long);
void setupspritevline(long,long,long,long,long,long);
void spritevline(long,long,long,long,long,long);
void msetupspritevline(long,long,long,long,long,long);
void mspritevline(long,long,long,long,long,long);
void tsetupspritevline(long,long,long,long,long,long);
void tspritevline(long,long,long,long,long,long);
long mhline(long,long,long,long,long,long);
long mhlineskipmodify(long,long,long,long,long,long);
long msethlineshift(long,long);
long thline(long,long,long,long,long,long);
long thlineskipmodify(long,long,long,long,long,long);
long tsethlineshift(long,long);
long setupslopevlin(long,long,long);
long slopevlin(long,long,long,long,long,long);
long settransnormal(void);
long settransreverse(void);
long setupdrawslab(long,long);
long drawslab(long,long,long,long,long,long);
long stretchhline(long,long,long,long,long,long);
long is_vmware_running(void);
/* !!! This part might be better stated as "USE_ASM". --ryan. */
#ifdef USE_I386_ASM
long asm_mmxoverlay(void);
long asm_sethlinesizes(long,long,long);
long asm_setpalookupaddress(char *);
long asm_setuphlineasm4(long,long);
long asm_hlineasm4(long,long,long,long,long,long);
long asm_setuprhlineasm4(long,long,long,long,long,long);
long asm_rhlineasm4(long,long,long,long,long,long);
long asm_setuprmhlineasm4(long,long,long,long,long,long);
long asm_rmhlineasm4(long,long,long,long,long,long);
long asm_setupqrhlineasm4(long,long,long,long,long,long);
long asm_qrhlineasm4(long,long,long,long,long,long);
long asm_setvlinebpl(long);
long asm_fixtransluscence(long);
long asm_prevlineasm1(long,long,long,long,long,long);
long asm_vlineasm1(long,long,long,long,long,long);
long asm_setuptvlineasm(long);
long asm_tvlineasm1(long,long,long,long,long,long);
long asm_setuptvlineasm2(long,long,long);
long asm_tvlineasm2(long,long,long,long,long,long);
long asm_mvlineasm1(long,long,long,long,long,long);
long asm_setupvlineasm(long);
long asm_vlineasm4(long,long);
long asm_setupmvlineasm(long);
long asm_mvlineasm4(long,long);
void asm_setupspritevline(long,long,long,long,long,long);
void asm_spritevline(long,long,long,long,long,long);
void asm_msetupspritevline(long,long,long,long,long,long);
void asm_mspritevline(long,long,long,long,long,long);
void asm_tsetupspritevline(long,long,long,long,long,long);
void asm_tspritevline(long,long,long,long,long,long);
long asm_mhline(long,long,long,long,long,long);
long asm_mhlineskipmodify(long,long,long,long,long,long);
long asm_msethlineshift(long,long);
long asm_thline(long,long,long,long,long,long);
long asm_thlineskipmodify(long,long,long,long,long,long);
long asm_tsethlineshift(long,long);
long asm_setupslopevlin(long,long,long);
long asm_slopevlin(long,long,long,long,long,long);
long asm_settransnormal(void);
long asm_settransreverse(void);
long asm_setupdrawslab(long,long);
long asm_drawslab(long,long,long,long,long,long);
long asm_stretchhline(long,long,long,long,long,long);
long asm_isvmwarerunning(void);
/*
* !!! I need a reference to this, for mprotect(), but the actual function
* !!! is never called in BUILD...just from other ASM routines. --ryan.
*/
long asm_prohlineasm4(void);
#if ((defined __GNUC__) && (!defined C_IDENTIFIERS_UNDERSCORED))
long asm_mmxoverlay(void) __attribute__ ((alias ("_asm_mmxoverlay")));
long asm_sethlinesizes(long,long,long) __attribute__ ((alias ("_asm_sethlinesizes")));
long asm_setpalookupaddress(char *) __attribute__ ((alias ("_asm_setpalookupaddress")));
long asm_setuphlineasm4(long,long) __attribute__ ((alias ("_asm_setuphlineasm4")));
long asm_hlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_hlineasm4")));
long asm_setuprhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_setuprhlineasm4")));
long asm_rhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_rhlineasm4")));
long asm_setuprmhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_setuprmhlineasm4")));
long asm_rmhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_rmhlineasm4")));
long asm_setupqrhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_setupqrhlineasm4")));
long asm_qrhlineasm4(long,long,long,long,long,long) __attribute__ ((alias ("_asm_qrhlineasm4")));
long asm_setvlinebpl(long) __attribute__ ((alias ("_asm_setvlinebpl")));
long asm_fixtransluscence(long) __attribute__ ((alias ("_asm_fixtransluscence")));
long asm_prevlineasm1(long,long,long,long,long,long) __attribute__ ((alias ("_asm_prevlineasm1")));
long asm_vlineasm1(long,long,long,long,long,long) __attribute__ ((alias ("_asm_vlineasm1")));
long asm_setuptvlineasm(long) __attribute__ ((alias ("_asm_setuptvlineasm")));
long asm_tvlineasm1(long,long,long,long,long,long) __attribute__ ((alias ("_asm_tvlineasm1")));
long asm_setuptvlineasm2(long,long,long) __attribute__ ((alias ("_asm_setuptvlineasm2")));
long asm_tvlineasm2(long,long,long,long,long,long) __attribute__ ((alias ("_asm_tvlineasm2")));
long asm_mvlineasm1(long,long,long,long,long,long) __attribute__ ((alias ("_asm_mvlineasm1")));
long asm_setupvlineasm(long) __attribute__ ((alias ("_asm_setupvlineasm")));
long asm_vlineasm4(long,long) __attribute__ ((alias ("_asm_vlineasm4")));
long asm_setupmvlineasm(long) __attribute__ ((alias ("_asm_setupmvlineasm")));
long asm_mvlineasm4(long,long) __attribute__ ((alias ("_asm_mvlineasm4")));
void asm_setupspritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_setupspritevline")));
void asm_spritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_spritevline")));
void asm_msetupspritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_msetupspritevline")));
void asm_mspritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_mspritevline")));
void asm_tsetupspritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_tsetupspritevline")));
void asm_tspritevline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_tspritevline")));
long asm_mhline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_mhline")));
long asm_mhlineskipmodify(long,long,long,long,long,long) __attribute__ ((alias ("_asm_mhlineskipmodify")));
long asm_msethlineshift(long,long) __attribute__ ((alias ("_asm_msethlineshift")));
long asm_thline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_thline")));
long asm_thlineskipmodify(long,long,long,long,long,long) __attribute__ ((alias ("_asm_thlineskipmodify")));
long asm_tsethlineshift(long,long) __attribute__ ((alias ("_asm_tsethlineshift")));
long asm_setupslopevlin(long,long,long) __attribute__ ((alias ("_asm_setupslopevlin")));
long asm_slopevlin(long,long,long,long,long,long) __attribute__ ((alias ("_asm_slopevlin")));
long asm_settransnormal(void) __attribute__ ((alias ("_asm_settransnormal")));
long asm_settransreverse(void) __attribute__ ((alias ("_asm_settransreverse")));
long asm_setupdrawslab(long,long) __attribute__ ((alias ("_asm_setupdrawslab")));
long asm_drawslab(long,long,long,long,long,long) __attribute__ ((alias ("_asm_drawslab")));
long asm_stretchhline(long,long,long,long,long,long) __attribute__ ((alias ("_asm_stretchhline")));
long asm_isvmwarerunning(void) __attribute__ ((alias ("_asm_isvmwarerunning")));
/*
* !!! I need a reference to this, for mprotect(), but the actual function
* !!! is never called in BUILD...just from other ASM routines. --ryan.
*/
long asm_prohlineasm4(void) __attribute__ ((alias ("_asm_prohlineasm4")));
#endif /* ELF/GCC */
#endif /* defined USE_I386_ASM */
#ifdef __cplusplus
}
#endif
#endif /* include-once-blocker. */
/* end of a.h ... */

Some files were not shown because too many files have changed in this diff Show More