Hack MIDI back in for win32

MSVC still broken


git-svn-id: https://svn.eduke32.com/eduke32@1472 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2009-07-27 10:46:42 +00:00
parent 4f10a9e477
commit 505d3475ce
17 changed files with 3832 additions and 136 deletions

View file

@ -10,8 +10,6 @@ PRETTY_OUTPUT = 1
# SDK locations - adjust to match your setup # SDK locations - adjust to match your setup
DXROOT=../sdk/dx DXROOT=../sdk/dx
ALROOT = AL
# Engine options # Engine options
SUPERBUILD = 1 SUPERBUILD = 1
POLYMOST = 1 POLYMOST = 1
@ -124,7 +122,6 @@ GAMEOBJS=$(OBJ)/game.$o \
$(OBJ)/osdcmds.$o \ $(OBJ)/osdcmds.$o \
$(OBJ)/grpscan.$o \ $(OBJ)/grpscan.$o \
$(OBJ)/sounds.$o \ $(OBJ)/sounds.$o \
$(OBJ)/audiolib_musicstub.$o \
$(JMACTOBJ) $(JMACTOBJ)
EDITOROBJS=$(OBJ)/astub.$o \ EDITOROBJS=$(OBJ)/astub.$o \
@ -139,20 +136,19 @@ ifeq ($(PLATFORM),LINUX)
endif endif
ifeq ($(PLATFORM),DARWIN) ifeq ($(PLATFORM),DARWIN)
ALROOT = Apple
ifeq (1,$(SDL_FRAMEWORK)) ifeq (1,$(SDL_FRAMEWORK))
OURCFLAGS += -fno-pic -I$(ALROOT)/include -I/Library/Frameworks/SDL.framework/Headers \ OURCFLAGS += -fno-pic -IApple/include -I/Library/Frameworks/SDL.framework/Headers \
-I-I/Library/Frameworks/SDL_mixer.framework/Headers -I-I/Library/Frameworks/SDL_mixer.framework/Headers
LIBS += -read_only_relocs suppress -L$(ALROOT)/lib -lvorbisfile -lvorbis -logg -lm \ LIBS += -read_only_relocs suppress -LApple/lib -lvorbisfile -lvorbis -logg -lm \
-Wl,-framework,SDL -Wl,-framework,SDL_mixer $(ALROOT)/lib/libSDLmain.a \ -Wl,-framework,SDL -Wl,-framework,SDL_mixer Apple/lib/libSDLmain.a \
-Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \ -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \
-Wl,-framework,CoreMidi -Wl,-framework,AudioUnit \ -Wl,-framework,CoreMidi -Wl,-framework,AudioUnit \
-Wl,-framework,AudioToolbox -Wl,-framework,IOKit -Wl,-framework,AGL \ -Wl,-framework,AudioToolbox -Wl,-framework,IOKit -Wl,-framework,AGL \
-Wl,-framework,QuickTime -lm -Wl,-framework,QuickTime -lm
else else
OURCFLAGS += -fno-pic -I$(ALROOT)/include -I$(SDLROOT)/include -I$(SDLROOT)/include/SDL OURCFLAGS += -fno-pic -I$(SDLROOT)/include -I$(SDLROOT)/include/SDL
LIBS += -read_only_relocs suppress -L$(ALROOT)/lib -lvorbisfile -lvorbis -logg -lm -lSDL_mixer \ LIBS += -read_only_relocs suppress -lvorbisfile -lvorbis -logg -lm -lSDL_mixer \
-Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \ -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \
-Wl,-framework,CoreMidi -Wl,-framework,AudioUnit \ -Wl,-framework,CoreMidi -Wl,-framework,AudioUnit \
-Wl,-framework,AudioToolbox -Wl,-framework,IOKit -Wl,-framework,AGL \ -Wl,-framework,AudioToolbox -Wl,-framework,IOKit -Wl,-framework,AGL \
@ -162,12 +158,14 @@ ifeq ($(PLATFORM),DARWIN)
endif endif
ifeq ($(PLATFORM),WINDOWS) ifeq ($(PLATFORM),WINDOWS)
OURCFLAGS += -fno-pic -DUNDERSCORES -I$(DXROOT)/include -I$(ALROOT)/include # -I$(ENETROOT)/include OURCFLAGS += -fno-pic -DUNDERSCORES -I$(DXROOT)/include
NASMFLAGS+= -DUNDERSCORES -f win32 NASMFLAGS+= -DUNDERSCORES -f win32
LIBS += -L$(JAUDIOLIBDIR)/third-party/mingw32/lib -lvorbisfile -lvorbis -logg -lwsock32 -lws2_32 -lwinmm -ldsound LIBS += -L$(JAUDIOLIBDIR)/third-party/mingw32/lib -lvorbisfile -lvorbis -logg -lwsock32 -lws2_32 -lwinmm -ldsound
GAMEOBJS+= $(OBJ)/gameres.$o $(OBJ)/winbits.$o $(OBJ)/startwin.game.$o GAMEOBJS+= $(OBJ)/gameres.$o $(OBJ)/winbits.$o $(OBJ)/startwin.game.$o $(OBJ)/music.$o $(OBJ)/midi.$o $(OBJ)/mpu401.$o
EDITOROBJS+= $(OBJ)/buildres.$o EDITOROBJS+= $(OBJ)/buildres.$o
JAUDIOLIB=libjfaudiolib_win32.a JAUDIOLIB=libjfaudiolib_win32.a
else
GAMEOBJS+= $(OBJ)/audiolib_musicstub.$o
endif endif
ifeq ($(RENDERTYPE),SDL) ifeq ($(RENDERTYPE),SDL)

View file

@ -61,7 +61,7 @@ $(OBJ)/dsoundout.$o: $(SRC)/jaudiolib/dsoundout.c $(SRC)/jaudiolib/dsoundout.h
$(OBJ)/openal.$o: $(SRC)/jaudiolib/openal.c $(SRC)/jaudiolib/openal.h $(OBJ)/openal.$o: $(SRC)/jaudiolib/openal.c $(SRC)/jaudiolib/openal.h
$(OBJ)/dsl.$o: $(SRC)/jaudiolib/dsl.c $(SRC)/jaudiolib/dsl.h $(EINC)/compat.h $(OBJ)/dsl.$o: $(SRC)/jaudiolib/dsl.c $(SRC)/jaudiolib/dsl.h $(EINC)/compat.h
$(OBJ)/midi.$o: $(SRC)/jaudiolib/midi.c $(SRC)/jaudiolib/standard.h $(SRC)/jaudiolib/music.h $(SRC)/jaudiolib/_midi.h $(SRC)/jaudiolib/midi.h $(OBJ)/midi.$o: $(SRC)/midi.c $(SRC)/_midi.h $(SRC)/midi.h $(JAUDIOLIBDIR)/include/music.h
$(OBJ)/mpu401.$o: $(SRC)/jaudiolib/mpu401.c $(SRC)/jaudiolib/mpu401.h $(OBJ)/mpu401.$o: $(SRC)/mpu401.c $(SRC)/mpu401.h $(JAUDIOLIBDIR)/include/music.h
$(OBJ)/music.$o: $(SRC)/jaudiolib/music.c $(SRC)/jaudiolib/music.h $(SRC)/jaudiolib/midi.h $(SRC)/jaudiolib/mpu401.h $(OBJ)/music.$o: $(SRC)/music.c $(SRC)/midi.h $(SRC)/mpu401.h $(JAUDIOLIBDIR)/include/music.h

View file

@ -412,6 +412,18 @@
RelativePath=".\source\menus.c" RelativePath=".\source\menus.c"
> >
</File> </File>
<File
RelativePath=".\source\midi.c"
>
</File>
<File
RelativePath=".\source\mpu401.c"
>
</File>
<File
RelativePath=".\source\music.c"
>
</File>
<File <File
RelativePath=".\source\namesdyn.c" RelativePath=".\source\namesdyn.c"
> >

View file

@ -0,0 +1,282 @@
/*
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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
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
#include "compat.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_AffectsCurrentCard( c, type ) \
( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
#define EMIDI_NUM_CONTEXTS 7
typedef struct
{
char *pos;
char *loopstart;
int16_t loopcount;
int16_t RunningStatus;
unsigned time;
int32_t FPSecondsPerTick;
int16_t tick;
int16_t beat;
int16_t measure;
int16_t BeatsPerMeasure;
int16_t TicksPerBeat;
int16_t TimeBase;
int32_t delay;
int16_t active;
} songcontext;
typedef struct
{
char *start;
char *pos;
int32_t delay;
int16_t active;
int16_t RunningStatus;
int16_t currentcontext;
songcontext context[ EMIDI_NUM_CONTEXTS ];
char EMIDI_IncludeTrack;
char EMIDI_ProgramChange;
char EMIDI_VolumeChange;
} track;
static int32_t _MIDI_ReadNumber( void *from, size_t size );
static int32_t _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 int32_t _MIDI_InterpretControllerInfo( track *Track, int32_t TimeSet,
int32_t channel, int32_t c1, int32_t c2 );
static int32_t _MIDI_SendControlChange( int32_t channel, int32_t c1, int32_t c2 );
static void _MIDI_SetChannelVolume( int32_t channel, int32_t volume );
static void _MIDI_SendChannelVolumes( void );
static int32_t _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

View file

@ -579,6 +579,7 @@ void Net_GetPackets(void)
input_t *osyn, *nsyn; input_t *osyn, *nsyn;
sampletimer(); sampletimer();
MUSIC_Update();
G_HandleSpecialKeys(); G_HandleSpecialKeys();
@ -1072,6 +1073,7 @@ void faketimerhandler(void)
} }
sampletimer(); sampletimer();
MUSIC_Update();
if ((totalclock < ototalclock+TICSPERFRAME) || (ready2send == 0)) return; if ((totalclock < ototalclock+TICSPERFRAME) || (ready2send == 0)) return;
ototalclock += TICSPERFRAME; ototalclock += TICSPERFRAME;
@ -11525,6 +11527,8 @@ MAIN_LOOP_RESTART:
quitevent = 0; quitevent = 0;
} }
MUSIC_Update();
// only allow binds to function if the player is actually in a game (not in a menu, typing, et cetera) or demo // only allow binds to function if the player is actually in a game (not in a menu, typing, et cetera) or demo
bindsenabled = (g_player[myconnectindex].ps->gm == MODE_GAME || g_player[myconnectindex].ps->gm == MODE_DEMO); bindsenabled = (g_player[myconnectindex].ps->gm == MODE_GAME || g_player[myconnectindex].ps->gm == MODE_DEMO);
@ -13325,6 +13329,7 @@ FRAGBONUS:
Net_GetPackets(); Net_GetPackets();
handleevents(); handleevents();
MUSIC_Update();
if (g_player[myconnectindex].ps->gm&MODE_EOL) if (g_player[myconnectindex].ps->gm&MODE_EOL)
{ {

View file

@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/ */
/********************************************************************** /**********************************************************************
module: MUSIC.H module: MUSIC.H
@ -31,8 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __MUSIC_H #ifndef __MUSIC_H
#define __MUSIC_H #define __MUSIC_H
#include "inttypes.h" #include "compat.h"
#include "sndcards.h"
extern int32_t MUSIC_ErrorCode; extern int32_t MUSIC_ErrorCode;
@ -47,7 +47,6 @@ enum MUSIC_ERRORS
MUSIC_InvalidCard, MUSIC_InvalidCard,
MUSIC_MidiError, MUSIC_MidiError,
MUSIC_TaskManError, MUSIC_TaskManError,
MUSIC_FMNotDetected,
MUSIC_DPMI_Error MUSIC_DPMI_Error
}; };
@ -66,7 +65,6 @@ typedef struct
char *MUSIC_ErrorString( int32_t ErrorNumber ); char *MUSIC_ErrorString( int32_t ErrorNumber );
int32_t MUSIC_Init( int32_t SoundCard, int32_t Address ); int32_t MUSIC_Init( int32_t SoundCard, int32_t Address );
int32_t MUSIC_Shutdown( void ); int32_t MUSIC_Shutdown( void );
void MUSIC_SetMaxFMMidiChannel( int32_t channel );
void MUSIC_SetVolume( int32_t volume ); void MUSIC_SetVolume( int32_t volume );
void MUSIC_SetMidiChannelVolume( int32_t channel, int32_t volume ); void MUSIC_SetMidiChannelVolume( int32_t channel, int32_t volume );
void MUSIC_ResetMidiChannelVolumes( void ); void MUSIC_ResetMidiChannelVolumes( void );
@ -76,7 +74,7 @@ int32_t MUSIC_SongPlaying( void );
void MUSIC_Continue( void ); void MUSIC_Continue( void );
void MUSIC_Pause( void ); void MUSIC_Pause( void );
int32_t MUSIC_StopSong( void ); int32_t MUSIC_StopSong( void );
int32_t MUSIC_PlaySong( uint8_t *song, int32_t loopflag ); int32_t MUSIC_PlaySong( char *song, int32_t loopflag );
void MUSIC_SetContext( int32_t context ); void MUSIC_SetContext( int32_t context );
int32_t MUSIC_GetContext( void ); int32_t MUSIC_GetContext( void );
void MUSIC_SetSongTick( uint32_t PositionInTicks ); void MUSIC_SetSongTick( uint32_t PositionInTicks );
@ -88,6 +86,7 @@ int32_t MUSIC_FadeVolume( int32_t tovolume, int32_t milliseconds );
int32_t MUSIC_FadeActive( void ); int32_t MUSIC_FadeActive( void );
void MUSIC_StopFade( void ); void MUSIC_StopFade( void );
void MUSIC_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) ); void MUSIC_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) );
void MUSIC_RegisterTimbreBank( uint8_t *timbres ); void MUSIC_RegisterTimbreBank( char *timbres );
void MUSIC_Update(void);
#endif #endif

View file

@ -229,30 +229,13 @@ typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
#define MV_SetErrorCode( status ) \ #define MV_SetErrorCode( status ) \
MV_ErrorCode = ( status ); MV_ErrorCode = ( status );
static void MV_Mix( VoiceNode *voice, int32_t buffer );
void MV_PlayVoice( VoiceNode *voice ); 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 playbackstatus MV_GetNextVorbisBlock( VoiceNode *voice );
static void MV_ServiceRecord( void );
static VoiceNode *MV_GetVoice( int32_t handle );
VoiceNode *MV_AllocVoice( int32_t priority ); VoiceNode *MV_AllocVoice( int32_t priority );
static int16_t *MV_GetVolumeTable( int32_t vol );
void MV_SetVoiceMixMode( VoiceNode *voice ); void MV_SetVoiceMixMode( VoiceNode *voice );
void MV_SetVoiceVolume ( VoiceNode *voice, int32_t vol, int32_t left, int32_t right ); void MV_SetVoiceVolume ( VoiceNode *voice, int32_t vol, int32_t left, int32_t right );
static void MV_SetVoicePitch( VoiceNode *voice, uint32_t rate, int32_t pitchoffset );
static void MV_CalcVolume( int32_t MaxLevel );
static void MV_CalcPanTable( void );
void MV_ReleaseVorbisVoice( VoiceNode * voice ); void MV_ReleaseVorbisVoice( VoiceNode * voice );
// implemented in mix.c // implemented in mix.c

View file

@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "sndcards.h" #include "sndcards.h"
#include "drivers.h" #include "drivers.h"
#include "multivoc.h" #include "multivoc.h"

View file

@ -49,6 +49,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define LITTLE32 #define LITTLE32
#endif #endif
static void MV_Mix( VoiceNode *voice, int32_t buffer );
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 VoiceNode *MV_GetVoice( int32_t handle );
static int16_t *MV_GetVolumeTable( int32_t vol );
static void MV_SetVoicePitch( VoiceNode *voice, uint32_t rate, int32_t pitchoffset );
static void MV_CalcVolume( int32_t MaxLevel );
static void MV_CalcPanTable( void );
static inline uint16_t SWAP16(uint16_t s) static inline uint16_t SWAP16(uint16_t s)
{ {
return (s >> 8) | (s << 8); return (s >> 8) | (s << 8);
@ -399,7 +416,6 @@ void MV_ServiceVoc
{ {
VoiceNode *voice; VoiceNode *voice;
VoiceNode *next; VoiceNode *next;
char *buffer;
//int32_t flags; //int32_t flags;
// Toggle which buffer we'll mix next // Toggle which buffer we'll mix next
@ -528,7 +544,7 @@ playbackstatus MV_GetNextVOCBlock
int32_t lastblocktype; int32_t lastblocktype;
uint32_t blocklength; uint32_t blocklength;
uint32_t samplespeed; uint32_t samplespeed;
uint32_t tc; uint32_t tc = 0;
int32_t packtype; int32_t packtype;
int32_t voicemode; int32_t voicemode;
int32_t done; int32_t done;
@ -898,6 +914,7 @@ playbackstatus MV_GetNextWAVBlock
Starts recording of the waiting buffer. Starts recording of the waiting buffer.
---------------------------------------------------------------------*/ ---------------------------------------------------------------------*/
/*
static void MV_ServiceRecord static void MV_ServiceRecord
( (
void void
@ -917,6 +934,7 @@ static void MV_ServiceRecord
MV_MixPage = 0; MV_MixPage = 0;
} }
} }
*/
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------

View file

@ -109,7 +109,7 @@ static int32_t close_vorbis(void * datasource)
return 0; return 0;
} }
static int32_t tell_vorbis(void * datasource) static long tell_vorbis(void * datasource)
{ {
vorbis_data * vorb = (vorbis_data *) datasource; vorbis_data * vorb = (vorbis_data *) datasource;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,100 @@
/*
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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
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 )( int32_t channel, int32_t key, int32_t velocity );
void ( *NoteOn )( int32_t channel, int32_t key, int32_t velocity );
void ( *PolyAftertouch )( int32_t channel, int32_t key, int32_t pressure );
void ( *ControlChange )( int32_t channel, int32_t number, int32_t value );
void ( *ProgramChange )( int32_t channel, int32_t program );
void ( *ChannelAftertouch )( int32_t channel, int32_t pressure );
void ( *PitchBend )( int32_t channel, int32_t lsb, int32_t msb );
void ( *ReleasePatches )( void );
void ( *LoadPatch )( int32_t number );
void ( *SetVolume )( int32_t volume );
int32_t ( *GetVolume )( void );
void ( *FinishBuffer )( void );
} midifuncs;
void MIDI_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) );
int32_t MIDI_AllNotesOff( void );
void MIDI_SetUserChannelVolume( int32_t channel, int32_t volume );
void MIDI_ResetUserChannelVolume( void );
int32_t MIDI_Reset( void );
int32_t MIDI_SetVolume( int32_t volume );
int32_t MIDI_GetVolume( void );
void MIDI_SetMidiFuncs( midifuncs *funcs );
void MIDI_SetContext( int32_t context );
int32_t MIDI_GetContext( void );
void MIDI_SetLoopFlag( int32_t loopflag );
void MIDI_ContinueSong( void );
void MIDI_PauseSong( void );
int32_t MIDI_SongPlaying( void );
void MIDI_StopSong( void );
int32_t MIDI_PlaySong( char *song, int32_t loopflag );
void MIDI_SetTempo( int32_t tempo );
int32_t MIDI_GetTempo( void );
void MIDI_SetSongTick( uint32_t PositionInTicks );
void MIDI_SetSongTime( uint32_t milliseconds );
void MIDI_SetSongPosition( int32_t measure, int32_t beat, int32_t tick );
void MIDI_GetSongPosition( songposition *pos );
void MIDI_GetSongLength( songposition *pos );
void MIDI_LoadTimbres( void );
void MIDI_UpdateMusic(void);
void MIDI_SetDivision( int32_t division );
#endif

View file

@ -0,0 +1,495 @@
/*
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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
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 "mpu401.h"
#include "compat.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
static HMIDISTRM hmido = (HMIDISTRM)-1;
static MIDIOUTCAPS midicaps;
static DWORD mididevice = -1;
typedef struct
{
int32_t time;
int32_t stream;
int32_t event;
}
MIDIEVENTHEAD;
#define PAD(x) ((((x)+3)&(~3)))
#define BUFFERLEN (32*4*4)
#define NUMBUFFERS 6
static char eventbuf[NUMBUFFERS][BUFFERLEN];
static int32_t eventcnt[NUMBUFFERS];
static MIDIHDR bufferheaders[NUMBUFFERS];
int32_t _MPU_CurrentBuffer = 0;
int32_t _MPU_BuffersWaiting = 0;
extern uint32_t _MIDI_GlobalPositionInTicks;
uint32_t _MPU_LastEvent=0;
#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
/**********************************************************************
Memory locked functions:
**********************************************************************/
void MPU_FinishBuffer(int32_t buffer)
{
if (!eventcnt[buffer]) return;
ZeroMemory(&bufferheaders[buffer], sizeof(MIDIHDR));
bufferheaders[buffer].lpData = eventbuf[buffer];
bufferheaders[buffer].dwBufferLength =
bufferheaders[buffer].dwBytesRecorded = eventcnt[buffer];
midiOutPrepareHeader((HMIDIOUT)hmido, &bufferheaders[buffer], sizeof(MIDIHDR));
midiStreamOut(hmido, &bufferheaders[buffer], sizeof(MIDIHDR));
// printf("Sending %d bytes (buffer %d)\n",eventcnt[buffer],buffer);
_MPU_BuffersWaiting++;
}
void MPU_BeginPlayback(void)
{
_MPU_LastEvent = _MIDI_GlobalPositionInTicks;
if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido);
}
void MPU_Pause(void)
{
if (hmido != (HMIDISTRM)-1) midiStreamPause(hmido);
}
void MPU_Unpause(void)
{
if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido);
}
void CALLBACK MPU_MIDICallback(HMIDIOUT handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
int32_t i;
UNREFERENCED_PARAMETER(dwInstance);
UNREFERENCED_PARAMETER(dwParam2);
switch (uMsg)
{
case MOM_DONE:
midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR*)dwParam1, sizeof(MIDIHDR));
for (i=0;i<NUMBUFFERS;i++)
{
if (dwParam1 == (uint32_t)&bufferheaders[i])
{
eventcnt[i] = 0; // marks the buffer as free
// printf("Finished buffer %d\n",i);
_MPU_BuffersWaiting--;
break;
}
}
return;
default: return;
}
}
/*---------------------------------------------------------------------
Function: MPU_SendMidi
Queues a MIDI message to the music device.
---------------------------------------------------------------------*/
int32_t MPU_GetNextBuffer(void)
{
int32_t i;
for (i=0; i<NUMBUFFERS; i++)
{
if (eventcnt[i] == 0) return i;
}
return -1;
}
void MPU_SendMidi(char *data, int32_t count)
{
char *p;
int32_t padded, nextbuffer;
static int32_t masks[3] = { 0x000000ffl, 0x0000ffffl, 0x00ffffffl };
if (count <= 0) return;
if (count <= 3)
{
if (eventcnt[_MPU_CurrentBuffer] + 12 > BUFFERLEN)
{
// buffer over-full
nextbuffer = MPU_GetNextBuffer();
if (nextbuffer < 0)
{
// printf("All buffers full!\n");
return;
}
MPU_FinishBuffer(_MPU_CurrentBuffer);
_MPU_CurrentBuffer = nextbuffer;
}
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t*)data)) & masks[count-1]);
eventcnt[_MPU_CurrentBuffer] += 12;
}
else
{
padded = PAD(count);
if (eventcnt[_MPU_CurrentBuffer] + 12 + padded > BUFFERLEN)
{
// buffer over-full
nextbuffer = MPU_GetNextBuffer();
if (nextbuffer < 0)
{
// printf("All buffers full!\n");
return;
}
MPU_FinishBuffer(_MPU_CurrentBuffer);
_MPU_CurrentBuffer = nextbuffer;
}
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl);
p+=12; eventcnt[_MPU_CurrentBuffer] += 12;
for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++)
*(p++) = *(data++);
for (; padded>0; padded--, eventcnt[_MPU_CurrentBuffer]++)
*(p++) = 0;
}
_MPU_LastEvent = _MIDI_GlobalPositionInTicks;
}
/*---------------------------------------------------------------------
Function: MPU_SendMidiImmediate
Sends a MIDI message immediately to the the music device.
---------------------------------------------------------------------*/
void MPU_SendMidiImmediate(char *data, int32_t count)
{
MIDIHDR mhdr;
static int32_t masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl };
if (!count) return;
if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t*)data)) & masks[count-1]);
else
{
ZeroMemory(&mhdr, sizeof(mhdr));
mhdr.lpData = data;
mhdr.dwBufferLength = count;
midiOutPrepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
midiOutLongMsg((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
while (!(mhdr.dwFlags & MHDR_DONE)) ;
midiOutUnprepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
}
}
/*---------------------------------------------------------------------
Function: MPU_Reset
Resets the MPU401 card.
---------------------------------------------------------------------*/
int32_t MPU_Reset
(
void
)
{
midiStreamStop(hmido);
midiStreamClose(hmido);
return(MPU_Ok);
}
/*---------------------------------------------------------------------
Function: MPU_Init
Detects and initializes the MPU401 card.
---------------------------------------------------------------------*/
int32_t MPU_Init
(
int32_t addr
)
{
int32_t i;
for (i=0;i<NUMBUFFERS;i++) eventcnt[i]=0;
mididevice = addr;
if (midiOutGetDevCaps(mididevice, &midicaps, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR) return MPU_Error;
if (midiStreamOpen(&hmido,(LPUINT)&mididevice,1,(DWORD)MPU_MIDICallback,0L,CALLBACK_FUNCTION) != MMSYSERR_NOERROR) return(MPU_Error);
return(MPU_Ok);
}
/*---------------------------------------------------------------------
Function: MPU_NoteOff
Sends a full MIDI note off event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOff
(
int32_t channel,
int32_t key,
int32_t velocity
)
{
char msg[3];
msg[0] = (MIDI_NOTE_OFF | channel);
msg[1] = (key);
msg[2] = (velocity);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_NoteOn
Sends a full MIDI note on event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOn
(
int32_t channel,
int32_t key,
int32_t velocity
)
{
char msg[3];
msg[0] = (MIDI_NOTE_ON | channel);
msg[1] = (key);
msg[2] = (velocity);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_PolyAftertouch
Sends a full MIDI polyphonic aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_PolyAftertouch
(
int32_t channel,
int32_t key,
int32_t pressure
)
{
char msg[3];
msg[0] = (MIDI_POLY_AFTER_TCH | channel);
msg[1] = (key);
msg[2] = (pressure);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_ControlChange
Sends a full MIDI control change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ControlChange
(
int32_t channel,
int32_t number,
int32_t value
)
{
char msg[3];
msg[0] = (MIDI_CONTROL_CHANGE | channel);
msg[1] = (number);
msg[2] = (value);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_ProgramChange
Sends a full MIDI program change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ProgramChange
(
int32_t channel,
int32_t program
)
{
char msg[2];
msg[0] = (MIDI_PROGRAM_CHANGE | channel);
msg[1] = (program);
MPU_SendMidi(msg, 2);
}
/*---------------------------------------------------------------------
Function: MPU_ChannelAftertouch
Sends a full MIDI channel aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_ChannelAftertouch
(
int32_t channel,
int32_t pressure
)
{
char msg[2];
msg[0] = (MIDI_AFTER_TOUCH | channel);
msg[1] = (pressure);
MPU_SendMidi(msg, 2);
}
/*---------------------------------------------------------------------
Function: MPU_PitchBend
Sends a full MIDI pitch bend event out to the music device.
---------------------------------------------------------------------*/
void MPU_PitchBend
(
int32_t channel,
int32_t lsb,
int32_t msb
)
{
char msg[3];
msg[0] = (MIDI_PITCH_BEND | channel);
msg[1] = (lsb);
msg[2] = (msb);
MPU_SendMidi(msg, 3);
}
void MPU_SetTempo(int32_t tempo)
{
MIDIPROPTEMPO prop;
prop.cbStruct = sizeof(MIDIPROPTEMPO);
prop.dwTempo = 60000000l/tempo;
midiStreamProperty(hmido, (LPBYTE)&prop, MIDIPROP_SET|MIDIPROP_TEMPO);
}
void MPU_SetDivision(int32_t division)
{
MIDIPROPTIMEDIV prop;
prop.cbStruct = sizeof(MIDIPROPTIMEDIV);
prop.dwTimeDiv = division;
midiStreamProperty(hmido, (LPBYTE)&prop, MIDIPROP_SET|MIDIPROP_TIMEDIV);
}
void MPU_SetVolume(int32_t volume)
{
/*
HMIXER hmixer;
int32_t mixerid;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcdu;
MMRESULT mme;
if (mididevice < 0) return;
mme = mixerOpen(&hmixer, mididevice, 0,0, MIXER_OBJECTF_MIDIOUT);
if (mme) {
puts("Failed opening mixer");
return;
}
mixerGetID(hmixer, &mixerid, MIXER_OBJECTF_HMIXER);
printf("mixerid=%d\n",mixerid);
ZeroMemory(&mxcd,sizeof(mxcd));
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = (LPVOID)&mxcdu;
mxcdu.dwValue = (volume << 8) & 0xffff;
printf("set %d\n",mixerSetControlDetails((HMIXEROBJ)mididevice, &mxcd,
MIXER_OBJECTF_MIDIOUT|MIXER_SETCONTROLDETAILSF_VALUE));
mixerClose(hmixer);
*/
UNREFERENCED_PARAMETER(volume);
}
int32_t MPU_GetVolume(void)
{
// if (mididevice < 0) return 0;
return 0;
}

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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
#ifndef __MPU401_H
#define __MPU401_H
#include "compat.h"
#define MPU_DefaultAddress 0x330
enum MPU_ERRORS
{
MPU_Warning = -2,
MPU_Error = -1,
MPU_Ok = 0
};
#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 int32_t _MPU_CurrentBuffer;
extern int32_t _MPU_BuffersWaiting;
void MPU_SendMidi( char *data, int32_t count );
void MPU_SendMidiImmediate( char *data, int32_t count );
int32_t MPU_Reset( void );
int32_t MPU_Init( int32_t addr );
void MPU_NoteOff( int32_t channel, int32_t key, int32_t velocity );
void MPU_NoteOn( int32_t channel, int32_t key, int32_t velocity );
void MPU_PolyAftertouch( int32_t channel, int32_t key, int32_t pressure );
void MPU_ControlChange( int32_t channel, int32_t number, int32_t value );
void MPU_ProgramChange( int32_t channel, int32_t program );
void MPU_ChannelAftertouch( int32_t channel, int32_t pressure );
void MPU_PitchBend( int32_t channel, int32_t lsb, int32_t msb );
void MPU_SetTempo(int32_t tempo);
void MPU_SetDivision(int32_t division);
void MPU_SetVolume(int32_t volume);
int32_t MPU_GetVolume(void);
void MPU_BeginPlayback( void );
void MPU_Pause(void);
void MPU_Unpause(void);
#endif

View file

@ -0,0 +1,595 @@
/*
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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: MUSIC.C
author: James R. Dose
date: March 25, 1994
Device independant music playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "music.h"
#include "midi.h"
#include "mpu401.h"
#include "compat.h"
#include "duke3d.h"
#ifndef TRUE
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
# define max(a,b) ( ((a) > (b)) ? (a) : (b) )
#endif
int32_t MUSIC_SoundDevice = -1;
int32_t MUSIC_ErrorCode = MUSIC_Ok;
static midifuncs MUSIC_MidiFunctions;
int32_t MUSIC_InitMidi(int32_t card, midifuncs *Funcs, int32_t Address);
#define MUSIC_SetErrorCode( status ) \
MUSIC_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: MUSIC_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *MUSIC_ErrorString
(
int32_t ErrorNumber
)
{
char *ErrorString;
switch (ErrorNumber)
{
case MUSIC_Warning :
case MUSIC_Error :
ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode);
break;
case MUSIC_Ok :
ErrorString = "Music ok.";
break;
case MUSIC_ASSVersion :
ErrorString = "Apogee Sound System Version WinMM "
"Programmed by Jim Dose, Ported by Jonathon Fowler\n"
"(c) Copyright 1996 James R. Dose. All Rights Reserved.\n";
break;
case MUSIC_SoundCardError :
case MUSIC_MPU401Error :
ErrorString = "Could not detect MPU-401.";
break;
case MUSIC_InvalidCard :
ErrorString = "Invalid Music device.";
break;
case MUSIC_MidiError :
ErrorString = "Error playing MIDI file.";
break;
case MUSIC_TaskManError :
ErrorString = "TaskMan error.";
break;
case MUSIC_DPMI_Error :
ErrorString = "DPMI Error in MUSIC.";
break;
default :
ErrorString = "Unknown Music error code.";
break;
}
return(ErrorString);
}
/*---------------------------------------------------------------------
Function: MUSIC_Init
Selects which sound device to use.
---------------------------------------------------------------------*/
int32_t MUSIC_Init
(
int32_t SoundCard,
int32_t Address
)
{
int32_t i;
int32_t status;
for (i = 0; i < 128; i++)
{
MIDI_PatchMap[ i ] = i;
}
MUSIC_SoundDevice = SoundCard;
status = MUSIC_InitMidi(SoundCard, &MUSIC_MidiFunctions, Address);
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_Shutdown
Terminates use of sound device.
---------------------------------------------------------------------*/
int32_t MUSIC_Shutdown
(
void
)
{
int32_t status;
status = MUSIC_Ok;
MIDI_StopSong();
//MPU_Reset();
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetVolume
Sets the volume of music playback.
---------------------------------------------------------------------*/
void MUSIC_SetVolume
(
int32_t volume
)
{
volume = max(0, volume);
volume = min(volume, 255);
if (MUSIC_SoundDevice != -1)
{
MIDI_SetVolume(volume);
}
}
/*---------------------------------------------------------------------
Function: MUSIC_SetMidiChannelVolume
Sets the volume of music playback on the specified MIDI channel.
---------------------------------------------------------------------*/
void MUSIC_SetMidiChannelVolume
(
int32_t channel,
int32_t volume
)
{
MIDI_SetUserChannelVolume(channel, volume);
}
/*---------------------------------------------------------------------
Function: MUSIC_ResetMidiChannelVolumes
Sets the volume of music playback on all MIDI channels to full volume.
---------------------------------------------------------------------*/
void MUSIC_ResetMidiChannelVolumes
(
void
)
{
MIDI_ResetUserChannelVolume();
}
/*---------------------------------------------------------------------
Function: MUSIC_GetVolume
Returns the volume of music playback.
---------------------------------------------------------------------*/
int32_t MUSIC_GetVolume
(
void
)
{
if (MUSIC_SoundDevice == -1)
{
return(0);
}
return(MIDI_GetVolume());
}
/*---------------------------------------------------------------------
Function: MUSIC_SetLoopFlag
Set whether the music will loop or end when it reaches the end of
the song.
---------------------------------------------------------------------*/
void MUSIC_SetLoopFlag
(
int32_t loopflag
)
{
MIDI_SetLoopFlag(loopflag);
}
/*---------------------------------------------------------------------
Function: MUSIC_SongPlaying
Returns whether there is a song playing.
---------------------------------------------------------------------*/
int32_t MUSIC_SongPlaying
(
void
)
{
return(MIDI_SongPlaying());
}
/*---------------------------------------------------------------------
Function: MUSIC_Continue
Continues playback of a paused song.
---------------------------------------------------------------------*/
void MUSIC_Continue
(
void
)
{
MIDI_ContinueSong();
}
/*---------------------------------------------------------------------
Function: MUSIC_Pause
Pauses playback of a song.
---------------------------------------------------------------------*/
void MUSIC_Pause
(
void
)
{
MIDI_PauseSong();
}
/*---------------------------------------------------------------------
Function: MUSIC_StopSong
Stops playback of current song.
---------------------------------------------------------------------*/
int32_t MUSIC_StopSong
(
void
)
{
MUSIC_StopFade();
MIDI_StopSong();
MUSIC_SetErrorCode(MUSIC_Ok);
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_PlaySong
Begins playback of MIDI song.
---------------------------------------------------------------------*/
int32_t MUSIC_PlaySong
(
char *song,
int32_t loopflag
)
{
int32_t status;
{
MUSIC_StopSong();
status = MIDI_PlaySong(song, loopflag);
if (status != MIDI_Ok)
{
MUSIC_SetErrorCode(MUSIC_MidiError);
return(MUSIC_Warning);
}
}
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetContext
Sets the song context.
---------------------------------------------------------------------*/
void MUSIC_SetContext
(
int32_t context
)
{
MIDI_SetContext(context);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetContext
Returns the current song context.
---------------------------------------------------------------------*/
int32_t MUSIC_GetContext
(
void
)
{
return MIDI_GetContext();
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTick
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTick
(
uint32_t PositionInTicks
)
{
MIDI_SetSongTick(PositionInTicks);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTime
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTime
(
uint32_t milliseconds
)
{
MIDI_SetSongTime(milliseconds);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongPosition
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongPosition
(
int32_t measure,
int32_t beat,
int32_t tick
)
{
MIDI_SetSongPosition(measure, beat, tick);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongPosition
Returns the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_GetSongPosition
(
songposition *pos
)
{
MIDI_GetSongPosition(pos);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongLength
Returns the length of the song.
---------------------------------------------------------------------*/
void MUSIC_GetSongLength
(
songposition *pos
)
{
MIDI_GetSongLength(pos);
}
int32_t MUSIC_InitMidi
(
int32_t card,
midifuncs *Funcs,
int32_t Address
)
{
UNREFERENCED_PARAMETER(card);
UNREFERENCED_PARAMETER(Address);
Funcs->NoteOff = MPU_NoteOff;
Funcs->NoteOn = MPU_NoteOn;
Funcs->PolyAftertouch = MPU_PolyAftertouch;
Funcs->ControlChange = MPU_ControlChange;
Funcs->ProgramChange = MPU_ProgramChange;
Funcs->ChannelAftertouch = MPU_ChannelAftertouch;
Funcs->PitchBend = MPU_PitchBend;
Funcs->ReleasePatches = NULL;
Funcs->LoadPatch = NULL;
Funcs->SetVolume = NULL /*MPU_SetVolume*/;
Funcs->GetVolume = NULL /*MPU_GetVolume*/;
MIDI_SetMidiFuncs(Funcs);
return(MIDI_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_FadeVolume
Fades music volume from current level to another over a specified
period of time.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeVolume
(
int32_t tovolume,
int32_t milliseconds
)
{
UNREFERENCED_PARAMETER(milliseconds);
MIDI_SetVolume(tovolume);
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_FadeActive
Returns whether the fade routine is active.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeActive
(
void
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: MUSIC_StopFade
Stops fading the music.
---------------------------------------------------------------------*/
void MUSIC_StopFade
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_RerouteMidiChannel
Sets callback function to reroute MIDI commands from specified
function.
---------------------------------------------------------------------*/
void MUSIC_RerouteMidiChannel
(
int32_t channel,
int32_t(*function)(int32_t event, int32_t c1, int32_t c2)
)
{
MIDI_RerouteMidiChannel(channel, function);
}
/*---------------------------------------------------------------------
Function: MUSIC_RegisterTimbreBank
Halts playback of all sounds.
---------------------------------------------------------------------*/
void MUSIC_RegisterTimbreBank
(
char *timbres
)
{
UNREFERENCED_PARAMETER(timbres);
}
void MUSIC_Update(void)
{
MIDI_UpdateMusic();
}

View file

@ -39,7 +39,7 @@ int32_t backflag,g_numEnvSoundsPlaying,g_maxSoundPos = 0;
#define MUSIC_ID -65536 #define MUSIC_ID -65536
static int32_t MusicIsWaveform = 0; static int32_t MusicIsWaveform = 0;
static uint8_t * MusicPtr = 0; static char * MusicPtr = 0;
static int32_t MusicLen = 0; static int32_t MusicLen = 0;
static int32_t MusicVoice = -1; static int32_t MusicVoice = -1;
static int32_t MusicPaused = 0; static int32_t MusicPaused = 0;
@ -156,9 +156,9 @@ void S_MusicStartup(void)
{ {
MUSIC_SetVolume(ud.config.MusicVolume); MUSIC_SetVolume(ud.config.MusicVolume);
} }
/*
initprintf("Couldn't find selected sound card, or, error w/ sound card itself.\n");
initprintf("Couldn't find selected sound card, or, error w/ sound card itself.\n");
/*
S_SoundShutdown(); S_SoundShutdown();
uninittimer(); uninittimer();
uninitengine(); uninitengine();
@ -343,11 +343,11 @@ int32_t S_PlayMusic(const char *fn, const int32_t sel)
S_StopMusic(); S_StopMusic();
MusicLen = kfilelength(fp); MusicLen = kfilelength(fp);
MusicPtr = (uint8_t *) Bmalloc(MusicLen); MusicPtr = (char *) Bmalloc(MusicLen);
kread(fp, MusicPtr, MusicLen); kread(fp, MusicPtr, MusicLen);
kclose(fp); kclose(fp);
if (!memcmp(MusicPtr, "MThd", 4)) if (!Bmemcmp(MusicPtr, "MThd", 4))
{ {
MUSIC_PlaySong(MusicPtr, MUSIC_LoopSong); MUSIC_PlaySong(MusicPtr, MUSIC_LoopSong);
MusicIsWaveform = 0; MusicIsWaveform = 0;
@ -369,10 +369,8 @@ void S_StopMusic(void)
FX_StopSound(MusicVoice); FX_StopSound(MusicVoice);
MusicVoice = -1; MusicVoice = -1;
} }
else if (!MusicIsWaveform)
{
MUSIC_StopSong(); MUSIC_StopSong();
}
if (MusicPtr) if (MusicPtr)
{ {

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.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
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