From 2cb0df1ef3201bcdf2884d0a46a8390ad66775d5 Mon Sep 17 00:00:00 2001 From: withmorten Date: Tue, 21 Apr 2020 15:09:08 +0200 Subject: [PATCH 1/5] switch out milessdk with fake miles header and lib --- milessdk/include/mss.h | 4885 +--------------------------------------- milessdk/lib/mss32.lib | Bin 246322 -> 15316 bytes 2 files changed, 98 insertions(+), 4787 deletions(-) diff --git a/milessdk/include/mss.h b/milessdk/include/mss.h index fbc91c73..38371eb9 100644 --- a/milessdk/include/mss.h +++ b/milessdk/include/mss.h @@ -1,4805 +1,116 @@ -//############################################################################ -//## ## -//## Miles Sound System ## -//## ## -//## MSS.H: Miles Sound System main header file ## -//## ## -//## Version 1.00 of 15-Feb-95: Initial, derived from AIL.H V3.02 ## -//## 1.01 of 19-Jun-95: Added various functions for V3.03 release ## -//## 1.02 of 22-Nov-95: C++ typedef problem fixed, declspecs added ## -//## 1.03 of 15-Feb-96: Changes for 16 bit callbacks and multiple ## -//## 16 bit DLL loads (JKR) ## -//## 1.04 of 2-Nov-97: Changes made to handle DLS in future ## -//## versions ## -//## 1.05 of 1-Jan-98: Massive changes for version 4.0 ## -//## 1.06 of 17-Sep-98: Massive changes for version 5.0 ## -//## 1.07 of 2-Feb-99: Changes for new input API ## -//## 1.08 of 8-Feb-99: Changes for new filter helper functions ## -//## ## -//## Author: John Miles ## -//## ## -//############################################################################ -//## ## -//## Contact RAD Game Tools at 425-893-4300 for technical support. ## -//## ## -//############################################################################ +#pragma once -#ifndef MSS_VERSION +// fake mss.h header for use with re3, to make using mss32.dll possible +// gta3 uses miles 6.1a +// check https://github.com/withmorten/re3mss for more info -#define MSS_VERSION "6.1a" -#define MSS_MAJOR_VERSION 6 -#define MSS_MINOR_VERSION 1 -#define MSS_SUB_VERSION 1 -#define MSS_VERSION_DATE "06-Mar-01" +#include -#define MSS_COPYRIGHT "Copyright (C) 1991-2001, RAD Game Tools, Inc." - -#endif - -#ifndef MSS_H -#define MSS_H - -// IS_DOS for DOS -// IS_WINDOWS for Windows or Win32s -// IS_WIN32 for Win32s -// IS_WIN16 for Windows -// IS_32 for 32-bit DOS or Win32s -// IS_16 for 16-bit Windows -// IS_LE for little endian (PCs) -// IS_BE for big endian (Macs) -// IS_X86 for Intel -// IS_MAC for Mac -// IS_PPC for PPC Mac -// IS_68K for 68K Mac - - -#ifdef IS_DOS -#undef IS_DOS -#endif - -#ifdef IS_WINDOWS -#undef IS_WINDOWS -#endif - -#ifdef IS_WIN32 -#undef IS_WIN32 -#endif - -#ifdef IS_WIN16 -#undef IS_WIN16 -#endif - -#ifdef IS_32 -#undef IS_32 -#endif - -#ifdef IS_16 -#undef IS_16 -#endif - -#ifdef IS_LE -#undef IS_LE -#endif - -#ifdef IS_BE -#undef IS_BE -#endif - -#ifdef IS_X86 -#undef IS_X86 -#endif - -#ifdef IS_MAC -#undef IS_MAC -#endif - -#ifdef IS_PPC -#undef IS_PPC -#endif - -#ifdef IS_68K -#undef IS_68K -#endif - -#ifdef __DOS__ - #define IS_DOS - #define IS_32 - #define IS_LE - #define IS_X86 -#else - #ifdef _WIN32 - #define IS_WINDOWS - #define IS_WIN32 - #define IS_32 - #define IS_LE - #define IS_X86 - #else - #ifdef WIN32 - #define IS_WINDOWS - #define IS_WIN32 - #define IS_32 - #define IS_LE - #define IS_X86 - #else - #ifdef __NT__ - #define IS_WINDOWS - #define IS_WIN32 - #define IS_32 - #define IS_LE - #define IS_X86 - #else - #ifdef __WIN32__ - #define IS_WINDOWS - #define IS_WIN32 - #define IS_32 - #define IS_LE - #define IS_X86 - #else - #ifdef _WINDOWS - #define IS_WINDOWS - #define IS_WIN16 - #define IS_16 - #define IS_LE - #define IS_X86 - #else - #ifdef _WINDLL - #define IS_WINDOWS - #define IS_WIN16 - #define IS_16 - #define IS_LE - #define IS_X86 - #else - #ifdef WINDOWS - #define IS_WINDOWS - #define IS_WIN16 - #define IS_16 - #define IS_LE - #define IS_X86 - #else - #ifdef __WINDOWS__ - #define IS_WINDOWS - #define IS_WIN16 - #define IS_16 - #define IS_LE - #define IS_X86 - #else - #ifdef _Windows - #define IS_WINDOWS - #define IS_WIN16 - #define IS_16 - #define IS_LE - #define IS_X86 - #else - #if defined(macintosh) || defined(__powerc) || defined(powerc) || defined(__POWERPC__) || defined(__MC68K__) - #define IS_MAC - #define IS_32 - #define IS_BE - #if defined(__powerc) || defined(powerc) || defined(__POWERPC__) - #define IS_PPC - #else - #if defined(__MC68K__) - #define IS_68K - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif - #endif -#endif - -#if (!defined(IS_LE) && !defined(IS_BE)) - #error MSS.H did not detect your platform. Define __DOS__, _WINDOWS, WIN32, or macintosh. -#endif - - -#if defined(_PUSHPOP_SUPPORTED) || PRAGMA_STRUCT_PACKPUSH - #pragma pack(push,1) -#else - #pragma pack(1) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef IS_DOS - -#define AILCALLBACK __pascal -#define AILEXPORT cdecl -#define DXDEC extern -#define DXDEF -#define AILCALL cdecl -#define FAR -#define HIWORD(ptr) (((U32)ptr)>>16) -#define LOWORD(ptr) ((U16)((U32)ptr)) - -#define FOURCC U32 - -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((U32)(U8)(ch0) | ((U32)(U8)(ch1) << 8) | \ - ((U32)(U8)(ch2) << 16) | ((U32)(U8)(ch3) << 24 )) - -#define mmioFOURCC(w,x,y,z) MAKEFOURCC(w,x,y,z) - -#define AILLIBCALLBACK __pascal - -#define MSS_MAIN_DEF - -#define MSS_REDIST_DIR_NAME "DOS" - -#define MSS_DIR_SEP "\\" -#define MSS_DIR_UP ".." MSS_DIR_SEP -#define MSS_DIR_UP_TWO MSS_DIR_UP MSS_DIR_UP - -#else - -#ifdef IS_WINDOWS - -#define AILLIBCALLBACK WINAPI - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#ifndef WIN32_EXTRA_LEAN -#define WIN32_EXTRA_LEAN -#endif - -#ifndef STRICT -#define STRICT -#endif - -#include -#include - -#define MSS_MAIN_DEF __cdecl - -// -// If compiling MSS DLL, use __declspec(dllexport) for both -// declarations and definitions -// -// If compiling MSS16 library or application, use "extern" in declarations -// and nothing in definitions -// - -#ifdef IS_WIN32 - - #define AILEXPORT WINAPI - - #ifdef BUILD_MSS - #define DXDEC __declspec(dllexport) - #define DXDEF __declspec(dllexport) - #else - - #if 1 /*def __BORLANDC__*/ - #define DXDEC extern - #define DXDEF - #else - #define DXDEC __declspec(dllimport) - #endif - - #endif - - #define MSSDLLNAME "MSS32.DLL" - #define MSS_REDIST_DIR_NAME "WIN32" - - #define MSS_DIR_SEP "\\" - #define MSS_DIR_UP ".." MSS_DIR_SEP - #define MSS_DIR_UP_TWO MSS_DIR_UP MSS_DIR_UP - -#else - - #define AILEXPORT __export WINAPI - - #define DXDEC extern - #define DXDEF - - #define MSSDLLNAME "MSS16.DLL" - #define MSS_REDIST_DIR_NAME "WIN16" - - #define MSS_DIR_SEP "\\" - #define MSS_DIR_UP ".." MSS_DIR_SEP - #define MSS_DIR_UP_TWO MSS_DIR_UP MSS_DIR_UP - -#endif - -#define AILCALL WINAPI -#define AILCALLBACK AILEXPORT - -typedef LPVOID AILLPDIRECTSOUND; -typedef LPVOID AILLPDIRECTSOUNDBUFFER; - -#else - -#ifdef IS_MAC - -#include -#include -#include -#include // needed for GetResource, ReleaseResource - -#define FAR - -#define AILLIBCALLBACK //pascal -#define AILCALL //pascal -#define AILEXPORT //pascal -#define AILCALLBACK //pascal - -#ifdef BUILD_MSS - #define DXDEC __declspec(export) - #define DXDEF -#else - #define DXDEC extern - #define DXDEF -#endif - -#define MSS_REDIST_DIR_NAME "MAC" - -#define MSS_DIR_SEP ":" -#define MSS_DIR_UP ":" MSS_DIR_SEP -#define MSS_DIR_UP_TWO MSS_DIR_UP MSS_DIR_SEP - -#define HIWORD(ptr) (((U32)ptr)>>16) -#define LOWORD(ptr) ((U16)((U32)ptr)) - -#define FOURCC U32 - -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - (((U32)(U8)(ch0) << 24) | ((U32)(U8)(ch1) << 16) | \ - ((U32)(U8)(ch2) << 8) | ((U32)(U8)(ch3) )) -#endif - -#define mmioFOURCC(w,x,y,z) MAKEFOURCC(w,x,y,z) - -#define MSS_MAIN_DEF - -#endif - -#endif - -#endif - -#ifndef NULL -#define NULL 0 -#endif - -// -// Misc. constant definitions -// - -#define MAX_DRVRS 16 // Max. # of simultaneous drivers -#define MAX_TIMERS 16 // Max. # of simultaneous timers -#define MAX_NOTES 32 // Max # of notes "on" -#define FOR_NEST 4 // # of nested XMIDI FOR loops -#define NUM_CHANS 16 // # of possible MIDI channels -#define MAX_W_VOICES 16 // Max virtual wave synth voice cnt -#define MAX_W_ENTRIES 512 // 512 wave library entries max. -#ifdef IS_MAC -#define MAX_INSTR 150 // Max # of instruments 128 + 32 -#endif - -#define MIN_CHAN ( 1-1) // Min channel recognized (0-based) -#define MAX_CHAN (16-1) // Max channel recognized -#define MIN_LOCK_CHAN ( 2-1) // Min channel available for locking -#define MAX_LOCK_CHAN ( 9-1) // Max channel available for locking -#define PERCUSS_CHAN (10-1) // Percussion channel (no locking) - -#define AIL_MAX_FILE_HEADER_SIZE 4096 // AIL_set_named_sample_file() requires at least 4K - // of data or the entire file image, whichever is less, - // to determine sample format -#define DIG_F_16BITS_MASK 1 -#define DIG_F_STEREO_MASK 2 -#define DIG_F_ADPCM_MASK 4 - -#define DIG_F_MONO_8 0 // PCM data formats -#define DIG_F_MONO_16 (DIG_F_16BITS_MASK) -#define DIG_F_STEREO_8 (DIG_F_STEREO_MASK) -#define DIG_F_STEREO_16 (DIG_F_STEREO_MASK|DIG_F_16BITS_MASK) -#define DIG_F_ADPCM_MONO_16 (DIG_F_ADPCM_MASK |DIG_F_16BITS_MASK) -#define DIG_F_ADPCM_STEREO_16 (DIG_F_ADPCM_MASK |DIG_F_16BITS_MASK|DIG_F_STEREO_MASK) -#define DIG_F_USING_ASI 16 - -#define DIG_PCM_SIGN 0x0001 // (obsolete) -#define DIG_PCM_ORDER 0x0002 - -#define DIG_PCM_POLARITY 0x0004 // PCM flags used by driver hardware -#define DIG_PCM_SPLIT 0x0008 -#define DIG_BUFFER_SERVICE 0x0010 -#define DIG_DUAL_DMA 0x0020 -#define DIG_RECORDING_SUPPORTED 0x8000 - -#define WAVE_FORMAT_PCM 1 -#define WAVE_FORMAT_IMA_ADPCM 0x0011 - -#ifdef IS_DOS - -#define AIL3DIG 0 // .DIG driver -#define AIL3MDI 1 // .MDI driver - -#define DIG_DETECT_8_BIT_ONLY 0x0001 // Detect 8-bit DMA only -#define DIG_DETECT_16_BIT_ONLY 0x0002 // Detect 16-bit DMA only -#define DIG_DETECT_8_AND_16_BITS 0x0003 // Detect both 8- and 16-bit DMA - -#define DRV_INIT 0x300 // Functions common to .MDI and .DIG -#define DRV_GET_INFO 0x301 // drivers -#define DRV_SERVE 0x302 -#define DRV_PARSE_ENV 0x303 -#define DRV_VERIFY_IO 0x304 -#define DRV_INIT_DEV 0x305 -#define DRV_SHUTDOWN_DEV 0x306 - -#define DIG_HW_VOLUME 0x400 // .DIG driver functions -#define DIG_START_P_CMD 0x401 -#define DIG_STOP_P_REQ 0x402 -#define DIG_START_R_CMD 0x403 -#define DIG_STOP_R_REQ 0x404 -#define DIG_VSE 0x405 - -#define MDI_HW_VOLUME 0x500 // .MDI driver functions -#define MDI_INIT_INS_MGR 0x501 -#define MDI_MIDI_XMIT 0x502 -#define MDI_INSTALL_T_SET 0x503 -#define MDI_GET_T_STATUS 0x504 -#define MDI_PROT_UNPROT_T 0x505 -#define MDI_VSE 0x506 - -#else - -// -// Pass to AIL_midiOutOpen for NULL MIDI driver -// - -#define MIDI_NULL_DRIVER ((U32)(S32)-2) - -#endif - - -// -// Non-specific XMIDI/MIDI controllers and event types -// - -#define SYSEX_BYTE 105 -#define PB_RANGE 106 -#define CHAN_MUTE 107 -#define CALLBACK_PFX 108 -#define SEQ_BRANCH 109 -#define CHAN_LOCK 110 -#define CHAN_PROTECT 111 -#define VOICE_PROTECT 112 -#define TIMBRE_PROTECT 113 -#define PATCH_BANK_SEL 114 -#define INDIRECT_C_PFX 115 -#define FOR_LOOP 116 -#define NEXT_LOOP 117 -#define CLEAR_BEAT_BAR 118 -#define CALLBACK_TRIG 119 -#define SEQ_INDEX 120 - -#define GM_BANK_MSB 0 -#define MODULATION 1 -#define DATA_MSB 6 -#define PART_VOLUME 7 -#define PANPOT 10 -#define EXPRESSION 11 -#define GM_BANK_LSB 32 -#define DATA_LSB 38 -#define SUSTAIN 64 -#define REVERB 91 -#define CHORUS 93 -#define RPN_LSB 100 -#define RPN_MSB 101 -#define RESET_ALL_CTRLS 121 -#define ALL_NOTES_OFF 123 - -#define EV_NOTE_OFF 0x80 -#define EV_NOTE_ON 0x90 -#define EV_POLY_PRESS 0xa0 -#define EV_CONTROL 0xb0 -#define EV_PROGRAM 0xc0 -#define EV_CHAN_PRESS 0xd0 -#define EV_PITCH 0xe0 -#define EV_SYSEX 0xf0 -#define EV_ESC 0xf7 -#define EV_META 0xff - -#define META_EOT 0x2f -#define META_TEMPO 0x51 -#define META_TIME_SIG 0x58 - -// -// SAMPLE.system_data[] usage -// - -#define SSD_EOD_CALLBACK 0 // Application end-of-data callback if not NULL -#define VOC_BLK_PTR 1 // Pointer to current block -#define VOC_REP_BLK 2 // Pointer to beginning of repeat loop block -#define VOC_N_REPS 3 // # of iterations left in repeat loop -#define VOC_MARKER 4 // Marker to search for, or -1 if all -#define VOC_MARKER_FOUND 5 // Desired marker found if 1, else 0 -#define SSD_RELEASE 6 // Release sample handle upon termination if >0 -#ifdef IS_WINDOWS -#define SSD_EOD_CB_WIN32S 7 // Application end-of-data callback is in Win32s -#else -#define SSD_TEMP 7 // Temporary storage location for general use -#endif - -// -// Timer status values -// - -#define AILT_FREE 0 // Timer handle is free for allocation -#define AILT_STOPPED 1 // Timer is stopped -#define AILT_RUNNING 2 // Timer is running - -// -// SAMPLE.status flag values -// - -#define SMP_FREE 0x0001 // Sample is available for allocation - -#define SMP_DONE 0x0002 // Sample has finished playing, or has - // never been started - -#define SMP_PLAYING 0x0004 // Sample is playing - -#define SMP_STOPPED 0x0008 // Sample has been stopped - -#define SMP_PLAYINGBUTRELEASED 0x0010 // Sample is playing, but digital handle - // has been temporarily released - - - -// -// SEQUENCE.status flag values -// - -#define SEQ_FREE 0x0001 // Sequence is available for allocation - -#define SEQ_DONE 0x0002 // Sequence has finished playing, or has - // never been started - -#define SEQ_PLAYING 0x0004 // Sequence is playing - -#define SEQ_STOPPED 0x0008 // Sequence has been stopped - -#define SEQ_PLAYINGBUTRELEASED 0x0010 // Sequence is playing, but MIDI handle - // has been temporarily released - -#ifdef IS_DOS - -// -// MIDI driver types -// - -#define MDIDRVRTYPE_GM 0 // General MIDI driver (Roland-compatible) -#define MDIDRVRTYPE_FM_2 1 // 2-operator FM MIDI driver (OPL2) -#define MDIDRVRTYPE_FM_4 2 // 4-operator FM MIDI driver (OPL3) -#define MDIDRVRTYPE_SPKR 3 // Tandy or PC speaker "beep" driver - -// -// .INI installation result codes -// - -#define AIL_INIT_SUCCESS 0 // Driver installed successfully -#define AIL_NO_INI_FILE 1 // No MDI.INI or DIG.INI file exists -#define AIL_INIT_FAILURE 2 // Driver could not be initialized - -#ifdef __BORLANDC__ - - #ifndef REALPTR - #define REALPTR(x) ((void *) (U32) ((((U32) (x))>>16<<4) + ((x) & 0xffff) \ - - AIL_sel_base(_DS))) - #endif - -#else - - #ifndef REALPTR - #define REALPTR(x) ((void *) (U32) ((((U32) (x))>>16<<4) + ((x) & 0xffff))) - #endif - -#endif - -#else - -#ifdef IS_WINDOWS - -// -// AIL_set_direct_buffer_control() command values -// - -#define AILDS_RELINQUISH 0 // App returns control of secondary buffer -#define AILDS_SEIZE 1 // App takes control of secondary buffer -#define AILDS_SEIZE_LOOP 2 // App wishes to loop the secondary buffer - -#endif - -#endif - -// -// General type definitions for portability -// - -#ifndef C8 -#define C8 char -#endif - -#ifndef U8 -#define U8 unsigned char -#endif - -#ifndef S8 -#define S8 signed char -#endif - -#ifndef U16 -#define U16 unsigned short -#endif - -#ifndef S16 -#define S16 signed short -#endif - -#ifndef U32 -#define U32 unsigned long -#endif - -#ifndef S32 -#define S32 signed long -#endif - -#ifndef F32 -#define F32 float -#endif - -#ifndef F64 -#define F64 double -#endif - - -#ifndef REALFAR -#define REALFAR unsigned long -#endif - -#ifndef FILE_ERRS -#define FILE_ERRS - -#define AIL_NO_ERROR 0 -#define AIL_IO_ERROR 1 -#define AIL_OUT_OF_MEMORY 2 -#define AIL_FILE_NOT_FOUND 3 -#define AIL_CANT_WRITE_FILE 4 -#define AIL_CANT_READ_FILE 5 -#define AIL_DISK_FULL 6 - -#endif - -#define MIN_VAL 0 -#define NOM_VAL 1 -#define MAX_VAL 2 - -#ifndef YES -#define YES 1 -#endif - -#ifndef NO -#define NO 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -// -// Preference names and default values -// - -#define DIG_RESAMPLING_TOLERANCE 0 -#define DEFAULT_DRT 131 // Resampling triggered at +/- 0.2% - -#define DIG_MIXER_CHANNELS 1 -#define DEFAULT_DMC 64 // 64 allocatable SAMPLE structures - -#define DIG_DEFAULT_VOLUME 2 -#define DEFAULT_DDV 127 // Default sample volume = 127 (0-127) - -#define MDI_SERVICE_RATE 3 -#define DEFAULT_MSR 120 // XMIDI sequencer timing = 120 Hz - -#define MDI_SEQUENCES 4 -#define DEFAULT_MS 8 // 8 sequence handles/driver - -#define MDI_DEFAULT_VOLUME 5 -#define DEFAULT_MDV 127 // Default sequence volume = 127 (0-127) - -#define MDI_QUANT_ADVANCE 6 -#define DEFAULT_MQA 1 // Beat/bar count +1 interval - -#define MDI_ALLOW_LOOP_BRANCHING 7 -#define DEFAULT_ALB NO // Branches cancel XMIDI FOR loops - -#define MDI_DEFAULT_BEND_RANGE 8 -#define DEFAULT_MDBR 2 // Default pitch-bend range = 2 - -#ifdef IS_X86 - -#define MDI_DOUBLE_NOTE_OFF 9 -#define DEFAULT_MDNO NO // For stuck notes on SB daughterboards - -#endif - -#define DIG_ENABLE_RESAMPLE_FILTER 31 // Enable resampling filter by -#define DEFAULT_DERF YES // default - -#define DIG_DECODE_BUFFER_SIZE 32 // 2K decode buffer size by default -#define DEFAULT_DDBS 2048 - -#if defined(IS_WINDOWS) || defined(IS_MAC) - -#define MDI_SYSEX_BUFFER_SIZE 10 -#define DEFAULT_MSBS 1536 // Default sysex buffer = 1536 bytes - -#define DIG_OUTPUT_BUFFER_SIZE 11 -#define DEFAULT_DOBS 49152 // 48K output buffer size - -#define AIL_MM_PERIOD 12 -#define DEFAULT_AMP 5 // Default MM timer period = 5 msec. - -#endif - -#ifdef IS_WINDOWS - -#define DIG_DS_FRAGMENT_SIZE 34 -#define DEFAULT_DDFS 8 // Use 8 millisecond buffer fragments with DirectSound if MSS mixer in use - -#define DIG_DS_FRAGMENT_CNT 35 -#define DEFAULT_DDFC 96 // Use 96 buffer fragments with DirectSound if MSS mixer in use - -#define DIG_DS_MIX_FRAGMENT_CNT 42 -#define DEFAULT_DDMFC 8 // Mix ahead 8 buffer fragments - -#define DIG_DS_USE_PRIMARY 36 -#define DEFAULT_DDUP NO // Mix into secondary DirectSound buffer by default - -#define DIG_DS_DSBCAPS_CTRL3D 37 -#define DEFAULT_DDDC NO // Do not use DSBCAPS_CTRL3D by default - -#define DIG_DS_CREATION_HANDLER 38 -#define DEFAULT_DDCH NULL // Use DirectSoundCreate() by default - -#define AIL_TIMERS 13 -#define DEFAULT_AT 16 // 16 allocatable HTIMER handles - -#define DIG_MAX_CHAIN_ELEMENT_SIZE 14 -#define DEFAULT_MCES 8192 // max of 8192 bytes/waveOut buffer - -#define DIG_MIN_CHAIN_ELEMENT_TIME 45 -#define DEFAULT_MCET 100 // 100 milliseconds buffers - -#define DIG_USE_WAVEOUT 15 -#define DEFAULT_DUW NO // Use DirectSound by default - -#define DIG_DS_SECONDARY_SIZE 16 -#define DEFAULT_DDSS (32*1024L) // Must be 2^n -- use 32K by default - -#define DIG_DS_SAMPLE_CEILING 17 -#define DEFAULT_DDSC 44100 // Allow up to 44 kHz samples - -#define AIL_LOCK_PROTECTION 18 -#define DEFAULT_ALP NO // Don't suspend foreground thread by default - -#define AIL_WIN32S_CALLBACK_SIZE 19 -#define DEFAULT_WCS 4096 // Size of callback data in bytes - -#define AIL_MUTEX_PROTECTION 44 -#define DEFAULT_AMPR YES // Lock each call into Miles with a mutex - -#else - -#ifdef IS_DOS - -#define DIG_SERVICE_RATE 10 -#define DEFAULT_DSR 200 // DMA buffer-polling rate = 200 Hz - -#define DIG_HARDWARE_SAMPLE_RATE 11 -#define DEFAULT_DHSR NOM_VAL // Use nominal sample rate by default - -#define DIG_DMA_RESERVE 12 -#define DEFAULT_DDR 32768 // Reserve 32K real-mode mem for DMA - -#define DIG_LATENCY 13 -#define DEFAULT_DL 100 // Half-buffer size in ms = 100 - -#define DIG_USE_STEREO 14 -#define DEFAULT_DUS NO // Use mono output only - -#define DIG_USE_16_BITS 15 -#define DEFAULT_DU16 NO // Use 8-bit output by default - -#define DIG_ALLOW_16_BIT_DMA 16 -#define DEFAULT_DA16DMA YES // OK to use 16-bit DMA if necessary - -#define DIG_SS_LOCK 17 -#define DEFAULT_DSL NO // Don't disable IRQs while mixing - -#define AIL_SCAN_FOR_HARDWARE 18 -#define DEFAULT_ASH YES // Scan for I/O settings if necessary - -#define AIL_ALLOW_VDM_EXECUTION 19 -#define DEFAULT_AVE YES // Allow Windows "DOS box" execution - -#endif - -#endif - -// ---------------------------------- -// DLS Preference names and default values -// Unless otherwise specified, values must be established -// BEFORE calling DLSMSSOpen()! -// ---------------------------------- - -#define DLS_TIMEBASE 20 -#define DEFAULT_DTB 120 // 120 intervals/second by default - -#define DLS_VOICE_LIMIT 21 -#define DEFAULT_DVL 24 // 24 voices supported - -#define DLS_BANK_SELECT_ALIAS 22 -#define DEFAULT_DBSA NO // Do not treat controller 114 as bank - -#define DLS_STREAM_BOOTSTRAP 23 // Don't submit first stream buffer -#define DEFAULT_DSB YES // until at least 2 available - -#define DLS_VOLUME_BOOST 24 -#define DEFAULT_DVB 0 // Boost final volume by 0 dB - -#define DLS_ENABLE_FILTERING 25 // Filtering = on by default -#define DEFAULT_DEF YES // (may be changed at any time) - -#ifdef IS_X86 - -#define AIL_ENABLE_MMX_SUPPORT 27 // Enable MMX support if present -#define DEFAULT_AEMS YES // (may be changed at any time) - -#endif - -#define DLS_GM_PASSTHROUGH 28 // Pass unrecognized traffic on to -#define DEFAULT_DGP YES // default GM driver layer - // (may be changed at any time) - -#define DLS_ADPCM_TO_ASI_THRESHOLD 39 // Size in samples to switch to ASI -#define DEFAULT_DATAT 32768 - -// -// Add'l platform-independent prefs -// - -#define DIG_REVERB_BUFFER_SIZE 40 -#define DEFAULT_DRBS 0 // No reverb support by default - -#define DIG_INPUT_LATENCY 41 // Use >= 250-millisecond input buffers if -#define DEFAULT_DIL 250 // explicit size request cannot be satisfied - -#ifdef IS_WINDOWS - -#define DIG_USE_WAVEIN 43 -#define DEFAULT_DUWI YES // Use waveIn for input by default - -#endif - -#define N_PREFS 46 // # of preference types - -typedef struct _AILSOUNDINFO { - S32 format; - void const FAR* data_ptr; - U32 data_len; - U32 rate; - S32 bits; - S32 channels; - U32 samples; - U32 block_size; - void const FAR* initial_ptr; -} AILSOUNDINFO; - - -// for multi-processor machines - -#ifdef IS_WIN32 - -#ifdef BUILD_MSS - - #define MSSLockedIncrement(var) _asm { lock inc [var] } - #define MSSLockedDecrement(var) _asm { lock dec [var] } - - static void __MSSLockedIncrementAddr(void * addr) - { - _asm - { - mov eax,[addr] - lock inc dword ptr [eax] - } - } - - static void __MSSLockedDecrementAddr(void * addr) - { - _asm { - mov eax,[addr] - lock dec dword ptr [eax] - } - } - - #define MSSLockedIncrementPtr(var) __MSSLockedIncrementAddr(&(var)) - #define MSSLockedDecrementPtr(var) __MSSLockedDecrementAddr(&(var)) - -#else - - #define MSSLockedIncrement(var) (++var) - #define MSSLockedDecrement(var) (--var) - - #define MSSLockedIncrementPtr(var) (++var) - #define MSSLockedDecrementPtr(var) (--var) - -#endif - -#else - #define MSSLockedIncrement(var) (++var) - #define MSSLockedDecrement(var) (--var) - - #define MSSLockedIncrementPtr(var) (++var) - #define MSSLockedDecrementPtr(var) (--var) -#endif - -#ifndef RIB_H // RIB.H contents included if RIB.H not already included - -// #include "rib.h" - -#define RIB_H -#define ARY_CNT(x) (sizeof((x)) / sizeof((x)[0])) - -// ---------------------------------- -// RIB data types -// ---------------------------------- - -typedef S32 RIBRESULT; - -#define RIB_NOERR 0 // Success -- no error -#define RIB_NOT_ALL_AVAILABLE 1 // Some requested functions/attribs not available -#define RIB_NOT_FOUND 2 // Resource not found -#define RIB_OUT_OF_MEM 3 // Out of system RAM - -// -// Handle to interface provider -// +typedef char C8; +typedef uint8_t U8; +typedef int8_t S8; +typedef int16_t S16; +typedef uint16_t U16; +typedef int32_t S32; +typedef uint32_t U32; +typedef float F32; +typedef double F64; +typedef void *HSTREAM; typedef U32 HPROVIDER; - -// -// Handle representing token used to obtain attribute or preference -// data from RIB provider -// - -typedef U32 HATTRIB; - -// -// Handle representing an enumerated interface entry -// -// RIB_enumerate_interface() returns 1 if valid next entry found, else -// 0 if end of list reached -// - -typedef U32 HINTENUM; -#define HINTENUM_FIRST 0 - -// -// Handle representing an enumerated provider entry -// -// RIB_enumerate_providers() returns 1 if valid next entry found, else -// 0 if end of list reached -// +typedef void *H3DPOBJECT; +typedef H3DPOBJECT H3DSAMPLE; +typedef void *HSAMPLE; +typedef void *HDIGDRIVER; typedef U32 HPROENUM; #define HPROENUM_FIRST 0 -// -// Data types for RIB attributes and preferences -// - -typedef enum -{ - RIB_NONE = 0, // No type - RIB_CUSTOM, // Used for pointers to application-specific structures - RIB_DEC, // Used for 32-bit integer values to be reported in decimal - RIB_HEX, // Used for 32-bit integer values to be reported in hex - RIB_FLOAT, // Used for 32-bit single-precision FP values - RIB_PERCENT, // Used for 32-bit single-precision FP values to be reported as percentages - RIB_BOOL, // Used for Boolean-constrained integer values to be reported as TRUE or FALSE - RIB_STRING // Used for pointers to null-terminated ASCII strings -} -RIB_DATA_SUBTYPE; - -// -// RIB_ENTRY_TYPE structure, used to register an interface or request one -// - -typedef enum -{ - RIB_FUNCTION = 0, - RIB_ATTRIBUTE, // Attribute: read-only data type used for status/info communication - RIB_PREFERENCE // Preference: read/write data type used to control behavior -} -RIB_ENTRY_TYPE; - -// -// RIB_INTERFACE_ENTRY, used to represent a function or data entry in an -// interface -// - -typedef struct -{ - RIB_ENTRY_TYPE type; // See list above - C8 FAR *entry_name; // Name of desired function or attribute - U32 token; // Function pointer or attribute token - RIB_DATA_SUBTYPE subtype; // Data (attrib or preference) subtype -} -RIB_INTERFACE_ENTRY; - -// -// Standard RAD Interface Broker provider identification attributes -// - -#define PROVIDER_NAME (-100) // RIB_STRING name of decoder -#define PROVIDER_VERSION (-101) // RIB_HEX BCD version number - -// -// Standard function to obtain provider attributes (see PROVIDER_ defines -// above) -// -// Each provider of a searchable interface must export this function -// - -typedef U32 (AILCALL FAR *PROVIDER_QUERY_ATTRIBUTE) (HATTRIB index); - -// -// Macros to simplify interface registrations/requests for functions, -// attributes, and preferences -// - -#define FN(entry_name) { RIB_FUNCTION, #entry_name, (U32) &(entry_name), RIB_NONE } -#define REG_FN(entry_name) { RIB_FUNCTION, #entry_name, (U32) &(entry_name), RIB_NONE } - -#define AT(entry_name,ID) { RIB_ATTRIBUTE, (entry_name), (U32) &(ID), RIB_NONE } -#define REG_AT(entry_name,ID,subtype) { RIB_ATTRIBUTE, (entry_name), (U32) (ID), subtype } - -#define PR(entry_name,ID) { RIB_PREFERENCE, (entry_name), (U32) &(ID), RIB_NONE } -#define REG_PR(entry_name,ID,subtype) { RIB_PREFERENCE, (entry_name), (U32) (ID), subtype } - -#define RIB_register(x,y,z) RIB_register_interface (HPROVIDER(x), y, ARY_CNT(z), z) -#define RIB_unregister(x,y,z) RIB_unregister_interface(HPROVIDER(x), y, ARY_CNT(z), z) -#define RIB_unregister_all(x) RIB_unregister_interface(HPROVIDER(x), NULL, 0, NULL) -#define RIB_free_libraries() RIB_free_provider_library(HPROVIDER(NULL)); -#define RIB_request(x,y,z) RIB_request_interface (x, y, ARY_CNT(z), z) - -// ---------------------------------- -// Standard RIB API prototypes -// ---------------------------------- - -DXDEC HPROVIDER AILCALL RIB_alloc_provider_handle (U32 module); -DXDEC void AILCALL RIB_free_provider_handle (HPROVIDER provider); - -DXDEC HPROVIDER AILCALL RIB_load_provider_library (C8 const FAR *filename); -DXDEC void AILCALL RIB_free_provider_library (HPROVIDER provider); - -DXDEC HPROVIDER AILCALL RIB_provider_library_handle (void); - -DXDEC RIBRESULT AILCALL RIB_register_interface (HPROVIDER provider, - C8 const FAR *interface_name, - S32 entry_count, - RIB_INTERFACE_ENTRY const FAR *rlist); - -DXDEC RIBRESULT AILCALL RIB_unregister_interface (HPROVIDER provider, - C8 const FAR *interface_name, - S32 entry_count, - RIB_INTERFACE_ENTRY const FAR *rlist); - -DXDEC RIBRESULT AILCALL RIB_request_interface (HPROVIDER provider, - C8 const FAR *interface_name, - S32 entry_count, - RIB_INTERFACE_ENTRY FAR *rlist); - -DXDEC RIBRESULT AILCALL RIB_request_interface_entry (HPROVIDER provider, - C8 const FAR *interface_name, - RIB_ENTRY_TYPE entry_type, - C8 const FAR *entry_name, - U32 FAR *token); - -DXDEC S32 AILCALL RIB_enumerate_interface (HPROVIDER provider, - C8 FAR *interface_name, - RIB_ENTRY_TYPE type, - HINTENUM FAR *next, - RIB_INTERFACE_ENTRY FAR *dest); - -DXDEC S32 AILCALL RIB_enumerate_providers (C8 FAR *interface_name, - HPROENUM FAR *next, - HPROVIDER FAR *dest); - -DXDEC C8 FAR * AILCALL RIB_type_string (U32 data, - RIB_DATA_SUBTYPE subtype); - -DXDEC HPROVIDER AILCALL RIB_find_file_provider (C8 const FAR *interface_name, - C8 const FAR *attribute_name, - C8 const FAR *file_suffix); - -DXDEC HPROVIDER AILCALL RIB_find_provider (C8 const FAR *interface_name, - C8 const FAR *attribute_name, - C8 const FAR *attribute_value); - -DXDEC HPROVIDER AILCALL RIB_find_files_provider (C8 const FAR *interface_name, - C8 const FAR *attribute_name_1, - C8 const FAR *file_suffix_1, - C8 const FAR *attribute_name_2, - C8 const FAR *file_suffix_2); - -DXDEC HPROVIDER AILCALL RIB_find_file_dec_provider (C8 const FAR *interface_name, - C8 const FAR *attribute_name_1, - U32 attribute_value_1, - C8 const FAR *attribute_name_2, - C8 const FAR *file_suffix_2); - -DXDEC S32 AILCALL RIB_load_application_providers - (C8 const FAR *filespec); - -DXDEC void AILCALL RIB_set_provider_user_data (HPROVIDER provider, - U32 index, - S32 value); - -DXDEC S32 AILCALL RIB_provider_user_data (HPROVIDER provider, - U32 index); - -DXDEC void AILCALL RIB_set_provider_system_data - (HPROVIDER provider, - U32 index, - S32 value); - -DXDEC S32 AILCALL RIB_provider_system_data (HPROVIDER provider, - U32 index); - -DXDEC C8 FAR * AILCALL RIB_error (void); - -#endif - -#ifndef MSS_ASI_VERSION // MSSASI.H contents included if MSSASI.H not already included - -// #include "mssasi.h" - -#define AIL_ASI_VERSION 1 -#define AIL_ASI_REVISION 0 - -// -// Handle to stream being managed by ASI codec -// - -typedef S32 HASISTREAM; - -// -// ASI result codes -// - -typedef S32 ASIRESULT; - -#define ASI_NOERR 0 // Success -- no error -#define ASI_NOT_ENABLED 1 // ASI not enabled -#define ASI_ALREADY_STARTED 2 // ASI already started -#define ASI_INVALID_PARAM 3 // Invalid parameters used -#define ASI_INTERNAL_ERR 4 // Internal error in ASI driver -#define ASI_OUT_OF_MEM 5 // Out of system RAM -#define ASI_ERR_NOT_IMPLEMENTED 6 // Feature not implemented -#define ASI_NOT_FOUND 7 // ASI supported device not found -#define ASI_NOT_INIT 8 // ASI not initialized -#define ASI_CLOSE_ERR 9 // ASI not closed correctly - -// ---------------------------------- -// Application-provided ASI callbacks -// ---------------------------------- - -// -// AILASIFETCHCB: Called by ASI to obtain data from stream source -// -// offset normally will be either 0 at the first call made by the codec -// or -1 to specify a continuous stream, except when ASI_stream_seek() -// is called to restart the stream codec at a new stream offset. In this -// case, the application must execute the seek operation on the ASI codec's -// behalf. -// -// In response to this callback, the application should read the requested -// data and copy it to the specified destination buffer, returning the number -// of bytes copied (which can be less than bytes_requested if the end of -// the stream is reached). -// - -typedef S32 (AILCALLBACK FAR * AILASIFETCHCB) (U32 user, // User value passed to ASI_open_stream() - void FAR *dest, // Location to which stream data should be copied by app - S32 bytes_requested, // # of bytes requested by ASI codec - S32 offset); // If not -1, application should seek to this point in stream - -//############################################################################ -//## ## -//## Interface "ASI codec" ## -//## ## -//############################################################################ - -// -// Initialize ASI stream codec -// -// No other ASI functions may be called outside an ASI_startup() / -// ASI_shutdown() pair, except for the standard RIB function -// PROVIDER_query_attribute(). All provider attributes must be accessible -// without starting up the codec. -// - -typedef ASIRESULT (AILCALL FAR *ASI_STARTUP)(void); - -// -// Shut down ASI codec -// - -typedef ASIRESULT (AILCALL FAR * ASI_SHUTDOWN)(void); - -// -// Return codec error message, or NULL if no errors have occurred since -// last call -// -// The ASI error text state is global to all streams -// - -typedef C8 FAR * (AILCALL FAR * ASI_ERROR)(void); - -//############################################################################ -//## ## -//## Interface "ASI stream" ## -//## ## -//############################################################################ - -// -// Open a stream, returning handle to stream -// - -typedef HASISTREAM (AILCALL FAR *ASI_STREAM_OPEN) (U32 user, // User value passed to fetch callback - AILASIFETCHCB fetch_CB, // Source data fetch handler - U32 total_size); // Total size for %-done calculations (0=unknown) - -// -// Translate data in stream, returning # of bytes actually decoded or encoded -// -// Any number of bytes may be requested. Requesting more data than is -// available in the codec's internal buffer will cause the AILASIFETCHCB -// handler to be called to fetch more data from the stream. -// - -typedef S32 (AILCALL FAR *ASI_STREAM_PROCESS) (HASISTREAM stream, // Handle of stream - void FAR *buffer, // Destination for processed data - S32 buffer_size); // # of bytes to return in buffer - -// -// Restart stream decoding process at new offset -// -// Relevant for decoders only -// -// Seek destination is given as offset in bytes from beginning of stream -// -// At next ASI_stream_process() call, decoder will seek to the closest possible -// point in the stream which occurs at or after the specified position -// -// This function has no effect for decoders which do not support random -// seeks on a given stream type -// -// Warning: some decoders may need to implement seeking by reparsing -// the entire stream up to the specified offset, through multiple calls -// to the data-fetch callback. This operation may be extremely -// time-consuming on large files or slow network connections. -// -// A stream_offset value of -1 may be used to inform the decoder that the -// application has changed the input stream offset on its own, e.g. for a -// double-buffering application where the ASI decoder is not accessing the -// stream directly. ASI decoders should respond to this by flushing all -// internal buffers and resynchronizing themselves to the data stream. -// - -typedef ASIRESULT (AILCALL FAR *ASI_STREAM_SEEK) (HASISTREAM stream, - S32 stream_offset); - -// -// Retrieve an ASI stream attribute or preference value by index -// - -typedef S32 (AILCALL FAR *ASI_STREAM_ATTRIBUTE) (HASISTREAM stream, - HATTRIB attrib); - -// -// Set an ASI stream preference value by index -// - -typedef S32 (AILCALL FAR *ASI_STREAM_SET_PREFERENCE) (HASISTREAM stream, - HATTRIB preference, - void const FAR * value); - -// -// Close stream, freeing handle and all internally-allocated resources -// - -typedef ASIRESULT (AILCALL FAR *ASI_STREAM_CLOSE) (HASISTREAM stream); - -#endif - -//############################################################################ -//## ## -//## Interface "MSS 3D audio services" ## -//## ## -//############################################################################ - -// -// 3D positioning services -// - - -typedef struct h3DPOBJECT -{ - U32 junk; -} h3DPOBJECT; - -typedef h3DPOBJECT FAR * H3DPOBJECT; -typedef H3DPOBJECT H3DSAMPLE; - -// -// M3D result codes -// - typedef S32 M3DRESULT; -#define M3D_NOERR 0 // Success -- no error -#define M3D_NOT_ENABLED 1 // M3D not enabled -#define M3D_ALREADY_STARTED 2 // M3D already started -#define M3D_INVALID_PARAM 3 // Invalid parameters used -#define M3D_INTERNAL_ERR 4 // Internal error in M3D driver -#define M3D_OUT_OF_MEM 5 // Out of system RAM -#define M3D_ERR_NOT_IMPLEMENTED 6 // Feature not implemented -#define M3D_NOT_FOUND 7 // M3D supported device not found -#define M3D_NOT_INIT 8 // M3D not initialized -#define M3D_CLOSE_ERR 9 // M3D not closed correctly +#define M3D_NOERR 0 +enum { ENVIRONMENT_CAVE = 8 }; -typedef void (AILCALLBACK FAR* AIL3DSAMPLECB) (H3DSAMPLE sample); +#define AIL_3D_2_SPEAKER 0 +#define AIL_3D_HEADPHONE 1 +#define AIL_3D_4_SPEAKER 3 -typedef M3DRESULT (AILCALL FAR *M3D_STARTUP)(void); +#define DIG_MIXER_CHANNELS 1 -typedef M3DRESULT (AILCALL FAR *M3D_SHUTDOWN)(void); +#define DIG_F_MONO_16 1 +#define DIG_PCM_SIGN 1 -typedef C8 FAR * (AILCALL FAR *M3D_ERROR)(void); +#define SMP_PLAYING 4 -typedef S32 (AILCALL FAR *M3D_SET_PROVIDER_PREFERENCE)(HATTRIB preference, - void const FAR * value); - -typedef M3DRESULT (AILCALL FAR * M3D_ACTIVATE)(S32 enable); - -typedef H3DSAMPLE (AILCALL FAR * M3D_ALLOCATE_3D_SAMPLE_HANDLE)(void); - - -typedef void (AILCALL FAR * M3D_RELEASE_3D_SAMPLE_HANDLE)(H3DSAMPLE samp); - - -typedef void (AILCALL FAR * M3D_START_3D_SAMPLE)(H3DSAMPLE samp); - - -typedef void (AILCALL FAR * M3D_STOP_3D_SAMPLE)(H3DSAMPLE samp); - - -typedef void (AILCALL FAR * M3D_RESUME_3D_SAMPLE)(H3DSAMPLE samp); - -typedef void (AILCALL FAR * M3D_END_3D_SAMPLE)(H3DSAMPLE samp); - -typedef S32 (AILCALL FAR * M3D_SET_3D_SAMPLE_DATA)(H3DSAMPLE samp, - AILSOUNDINFO const FAR *info); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_VOLUME)(H3DSAMPLE samp, - S32 volume); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_PLAYBACK_RATE)(H3DSAMPLE samp, - S32 playback_rate); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_OFFSET)(H3DSAMPLE samp, - U32 offset); - - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_LOOP_COUNT)(H3DSAMPLE samp, - U32 loops); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_LOOP_BLOCK)(H3DSAMPLE S, - S32 loop_start_offset, - S32 loop_end_offset); - -typedef U32 (AILCALL FAR * M3D_3D_SAMPLE_STATUS)(H3DSAMPLE samp); - -typedef U32 (AILCALL FAR * M3D_3D_SAMPLE_ATTRIBUTE)(H3DSAMPLE samp, HATTRIB index); - -typedef S32 (AILCALL FAR * M3D_3D_SET_SAMPLE_PREFERENCE)(H3DSAMPLE samp, HATTRIB preference, void const FAR * value); - -typedef S32 (AILCALL FAR * M3D_3D_SAMPLE_VOLUME)(H3DSAMPLE samp); - -typedef S32 (AILCALL FAR * M3D_3D_SAMPLE_PLAYBACK_RATE)(H3DSAMPLE samp); - -typedef U32 (AILCALL FAR * M3D_3D_SAMPLE_OFFSET)(H3DSAMPLE samp); - -typedef U32 (AILCALL FAR * M3D_3D_SAMPLE_LENGTH)(H3DSAMPLE samp); - -typedef U32 (AILCALL FAR * M3D_3D_SAMPLE_LOOP_COUNT)(H3DSAMPLE samp); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_DISTANCES)(H3DSAMPLE samp, - F32 max_dist, - F32 min_dist); - - -typedef void (AILCALL FAR * M3D_3D_SAMPLE_DISTANCES)(H3DSAMPLE samp, - F32 FAR * max_dist, - F32 FAR * min_dist); - -typedef S32 (AILCALL FAR * M3D_ACTIVE_3D_SAMPLE_COUNT)(void); - -typedef H3DPOBJECT (AILCALL FAR * M3D_3D_OPEN_LISTENER)(void); - -typedef void (AILCALL FAR * M3D_3D_CLOSE_LISTENER)(H3DPOBJECT listener); - -typedef H3DPOBJECT (AILCALL FAR * M3D_3D_OPEN_OBJECT)(void); - -typedef void (AILCALL FAR * M3D_3D_CLOSE_OBJECT)(H3DPOBJECT obj); - -typedef void (AILCALL FAR * M3D_SET_3D_POSITION)(H3DPOBJECT obj, - F32 X, - F32 Y, - F32 Z); - -typedef void (AILCALL FAR * M3D_SET_3D_VELOCITY)(H3DPOBJECT obj, - F32 dX_per_ms, - F32 dY_per_ms, - F32 dZ_per_ms, - F32 magnitude); - -typedef void (AILCALL FAR * M3D_SET_3D_VELOCITY_VECTOR)(H3DPOBJECT obj, - F32 dX_per_ms, - F32 dY_per_ms, - F32 dZ_per_ms); - -typedef void (AILCALL FAR * M3D_SET_3D_ORIENTATION)(H3DPOBJECT obj, - F32 X_face, - F32 Y_face, - F32 Z_face, - F32 X_up, - F32 Y_up, - F32 Z_up); - -typedef void (AILCALL FAR * M3D_3D_POSITION)(H3DPOBJECT obj, - F32 FAR *X, - F32 FAR *Y, - F32 FAR *Z); - -typedef void (AILCALL FAR * M3D_3D_VELOCITY)(H3DPOBJECT obj, - F32 FAR *dX_per_ms, - F32 FAR *dY_per_ms, - F32 FAR *dZ_per_ms); - -typedef void (AILCALL FAR * M3D_3D_ORIENTATION)(H3DPOBJECT obj, - F32 FAR *X_face, - F32 FAR *Y_face, - F32 FAR *Z_face, - F32 FAR *X_up, - F32 FAR *Y_up, - F32 FAR *Z_up); - -typedef void (AILCALL FAR * M3D_3D_UPDATE_POSITION)(H3DPOBJECT obj, - F32 dt_milliseconds); - -typedef void (AILCALL FAR * M3D_3D_AUTO_UPDATE_POSITION)(H3DPOBJECT obj, - S32 enable); - -typedef S32 (AILCALL FAR * M3D_3D_ROOM_TYPE)(void); -typedef void (AILCALL FAR * M3D_SET_3D_ROOM_TYPE)(S32 EAX_room_type); -typedef S32 (AILCALL FAR * M3D_3D_SPEAKER_TYPE)(void); -typedef void (AILCALL FAR * M3D_SET_3D_SPEAKER_TYPE)(S32 speaker_type); -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_OBSTRUCTION)(H3DSAMPLE samp, F32 obstruction); -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_OCCLUSION)(H3DSAMPLE samp, F32 occlusion); -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_EFFECTS_LEVEL)(H3DSAMPLE samp, F32 effects_level); -typedef F32 (AILCALL FAR * M3D_3D_SAMPLE_OBSTRUCTION)(H3DSAMPLE samp); -typedef F32 (AILCALL FAR * M3D_3D_SAMPLE_OCCLUSION)(H3DSAMPLE samp); -typedef F32 (AILCALL FAR * M3D_3D_SAMPLE_EFFECTS_LEVEL)(H3DSAMPLE samp); - -typedef AIL3DSAMPLECB (AILCALL FAR * M3D_SET_3D_EOS)(H3DSAMPLE client,H3DSAMPLE samp,AIL3DSAMPLECB cb); - -typedef void (AILCALL FAR * M3D_SET_3D_SAMPLE_CONE)(H3DSAMPLE samp, F32 inner_angle, F32 outer_angle, S32 outer_volume); -typedef void (AILCALL FAR * M3D_3D_SAMPLE_CONE)(H3DSAMPLE samp, F32 FAR* inner_angle, F32 FAR* outer_angle, S32 FAR* outer_volume); - -//############################################################################ -//## ## -//## Interface "MSS mixer services" ## -//## ## -//############################################################################ - -// -// Operation flags used by mixer module -// - -#define M_DEST_STEREO 1 // Set to enable stereo mixer output -#define M_SRC_16 2 // Set to enable mixing of 16-bit samples -#define M_FILTER 4 // Set to enable filtering when resampling -#define M_SRC_STEREO 8 // Set to enable mixing of stereo input samples -#define M_VOL_SCALING 16 // Set to enable volume scalars other than 2047 -#define M_RESAMPLE 32 // Set to enable playback ratios other than 65536 -#define M_ORDER 64 // Set to reverse L/R stereo order for sample - -#ifdef IS_32 - -// -// Initialize mixer -// -// No other mixer functions may be called outside a MIXER_startup() / -// MIXER_shutdown() pair, except for the standard RIB function -// PROVIDER_query_attribute(). All provider attributes must be accessible -// without starting up the module. -// - -typedef void (AILCALL FAR *MIXER_STARTUP)(void); - -// -// Shut down mixer -// - -typedef void (AILCALL FAR *MIXER_SHUTDOWN)(void); - -// -// Flush mixer buffer -// - -typedef void (AILCALL FAR *MIXER_FLUSH) (S32 FAR *dest, - S32 len, - S32 FAR *reverb_buffer, - S32 reverb_level -#ifdef IS_X86 - ,U32 MMX_available -#endif - ); - -// -// Perform audio mixing operation -// - -typedef void (AILCALL FAR *MIXER_MERGE) (void const FAR * FAR *src, - U32 FAR *src_fract, - void const FAR *src_end, - S32 FAR * FAR *dest, - void FAR *dest_end, - S32 FAR *left_val, - S32 FAR *right_val, - S32 playback_ratio, - S32 scale_left, - S32 scale_right, - U32 operation -#ifdef IS_X86 - ,U32 MMX_available -#endif - ); - -// -// Translate mixer buffer contents to final output format -// - -#ifdef IS_MAC - -typedef void (AILCALL FAR *MIXER_COPY) (void const FAR *src, - S32 src_len, - void FAR *dest, - U32 operation, - U32 big_endian_output); -#else - -typedef void (AILCALL FAR *MIXER_COPY) (void const FAR *src, - S32 src_len, - void FAR *dest, - U32 operation, - U32 MMX_available); -#endif -#else - -// -// Initialize mixer -// -// No other mixer functions may be called outside a MIXER_startup() / -// MIXER_shutdown() pair, except for the standard RIB function -// PROVIDER_query_attribute(). All provider attributes must be accessible -// without starting up the module. -// - -typedef void (AILCALL FAR *MIXER_STARTUP)(void); - -// -// Shut down mixer -// - -typedef void (AILCALL FAR *MIXER_SHUTDOWN)(void); - -// -// Flush mixer buffer -// - -typedef void (AILCALL FAR *MIXER_FLUSH) (S32 FAR *dest, - S32 len, - S32 FAR *reverb_buffer, - S32 reverb_level, - U32 MMX_available); - -// -// Perform audio mixing operation -// - -typedef void (AILCALL FAR *MIXER_MERGE) (U32 src_sel, - U32 dest_sel, - U32 FAR *src_fract, - U32 FAR *src_offset, - U32 FAR *dest_offset, - U32 src_end_offset, - U32 dest_end_offset, - S32 FAR *left_val, - S32 FAR *right_val, - S32 playback_ratio, - S32 scale_both, - U32 operation); - -// -// Translate mixer buffer contents to final output format -// - -typedef void (AILCALL FAR *MIXER_COPY) (void const FAR *src, - S32 src_len, - void FAR *dest, - U32 operation, - U32 MMX_available); -#endif - -// -// Type definitions -// - -struct _DIG_DRIVER; - -struct _MDI_DRIVER; - -typedef struct _DIG_DRIVER FAR * HDIGDRIVER; // Handle to digital driver - -typedef struct _MDI_DRIVER FAR * HMDIDRIVER; // Handle to XMIDI driver - -typedef struct _SAMPLE FAR * HSAMPLE; // Handle to sample - -typedef struct _SEQUENCE FAR * HSEQUENCE; // Handle to sequence - -typedef S32 HTIMER; // Handle to timer - - -#ifdef IS_DOS - -// -// Type definitions -// - -typedef struct // I/O parameters structure +typedef struct _AILSOUNDINFO { - S16 IO; - S16 IRQ; - S16 DMA_8_bit; - S16 DMA_16_bit; - S32 IO_reserved[4]; -} -IO_PARMS; - -typedef struct // Standard MSS 3.X VDI driver header -{ - S8 ID[8]; // "AIL3xxx" ID string, followed by ^Z - - U32 driver_version; - - REALFAR common_IO_configurations; - U16 num_IO_configurations; - - REALFAR environment_string; - - IO_PARMS IO; - - S16 service_rate; - - U16 busy; - - U16 driver_num; // Driver number - - U16 this_ISR; // Offset of INT 66H dispatcher - REALFAR prev_ISR; // Pointer to previous INT 66H ISR - - S8 scratch[128]; // Shared scratch workspace - - S8 dev_name[80]; // Device name (VDI version >= 1.12 only) -} -VDI_HDR; - -typedef struct -{ - U16 minimum_physical_sample_rate; - U16 nominal_physical_sample_rate; - U16 maximum_physical_sample_rate; - - U16 minimum_DMA_half_buffer_size; - U16 maximum_DMA_half_buffer_size; - - U32 flags; -} -DIG_MODE; - -typedef struct -{ - U8 format_supported[16]; - DIG_MODE format_data[16]; -} -DIG_DDT; - -typedef struct -{ - REALFAR DMA_buffer_A; - REALFAR DMA_buffer_B; - S16 active_buffer; -} -DIG_DST; - -typedef struct -{ - REALFAR library_environment; - REALFAR GTL_suffix; - - U16 num_voices; - - U16 max_melodic_channel; - U16 min_melodic_channel; - U16 percussion_channel; -} -MDI_DDT; - -typedef struct -{ - S8 library_directory[128]; - S8 GTL_filename[128]; - - S8 MIDI_data[512]; -} -MDI_DST; - -typedef struct // Initialization file structure -{ - char device_name[128]; // Device name - char driver_name[128]; // Driver filename - IO_PARMS IO; // I/O parameters for driver -} -AIL_INI; - -typedef struct // Handle to driver -{ - REALFAR seg; // Seg:off pointer to driver (off=0) - U32 sel; // Selector for driver (off=0) - void *buf; // Protected-mode pointer to driver - U32 size; // Size of driver image - VDI_HDR *VHDR; // Pointer to driver header (same as buf) - S32 type; // AIL3DIG or AIL3MDI (see below) - - S32 initialized; // 1 if hardware successfully init'd, else 0 - - S32 PM_ISR; // -1 if no PM ISR hooked, else IRQ # - - HTIMER server; // DRV_SERVE periodic timer, if requested - - // Vector to high-level destructor, if any - - void (AILCALL *destructor)(HDIGDRIVER); - - // High-level descriptor (DIG_ or MDI_DRIVER) - void *descriptor; -} -AIL_DRIVER; - -typedef struct // VDI interface register structure -{ - S16 AX; - S16 BX; - S16 CX; - S16 DX; - S16 SI; - S16 DI; -} -VDI_CALL; - -#endif - -// -// Function pointer types -// - -typedef void (AILCALLBACK FAR* AILINCB) (void const FAR *data, S32 len, U32 user_data); - -typedef void (AILCALLBACK FAR* AILTIMERCB) (U32 user); - -typedef void (AILCALLBACK FAR* AILSAMPLECB) (HSAMPLE sample); - -typedef S32 (AILCALLBACK FAR* AILEVENTCB) (HMDIDRIVER hmi,HSEQUENCE seq,S32 status,S32 data_1,S32 data_2); - -typedef S32 (AILCALLBACK FAR* AILTIMBRECB) (HMDIDRIVER hmi,S32 bank,S32 patch); - -typedef S32 (AILCALLBACK FAR* AILPREFIXCB) (HSEQUENCE seq,S32 log,S32 data); - -typedef void (AILCALLBACK FAR* AILTRIGGERCB) (HSEQUENCE seq,S32 log,S32 data); - -typedef void (AILCALLBACK FAR* AILBEATCB) (HMDIDRIVER hmi,HSEQUENCE seq,S32 beat,S32 measure); - -typedef void (AILCALLBACK FAR* AILSEQUENCECB) (HSEQUENCE seq); - -// -// Handle to sample and driver being managed by pipeline filter -// - -typedef S32 HSAMPLESTATE; -typedef S32 HDRIVERSTATE; - -// -// Digital pipeline stages -// -// These are the points at which external modules may be installed into -// a given HSAMPLE or HDIGDRIVER's processing pipeline -// - -typedef enum -{ - DP_ASI_DECODER=0, // Must be "ASI codec stream" provider - DP_FILTER, // Must be "MSS pipeline filter" provider - DP_MERGE, // Must be "MSS mixer" provider - N_SAMPLE_STAGES, // Placeholder for end of list (= # of valid stages) - SAMPLE_ALL_STAGES // Used to signify all pipeline stages, for shutdown -} -SAMPLESTAGE; - -typedef enum -{ - DP_FLUSH = 0, // Must be "MSS mixer" provider - DP_DEFAULT_FILTER, // Must be "MSS pipeline filter" provider (sets the default) - DP_DEFAULT_MERGE, // Must be "MSS mixer" provider (sets the default) - DP_COPY, // Must be "MSS mixer" provider - N_DIGDRV_STAGES, // Placeholder for end of list (= # of valid stages) - DIGDRV_ALL_STAGES // Used to signify all pipeline stages, for shutdown -} -DIGDRVSTAGE; - -typedef struct - { - ASI_STREAM_OPEN ASI_stream_open; - ASI_STREAM_PROCESS ASI_stream_process; - ASI_STREAM_SEEK ASI_stream_seek; - ASI_STREAM_CLOSE ASI_stream_close; - ASI_STREAM_ATTRIBUTE ASI_stream_attribute; - ASI_STREAM_SET_PREFERENCE ASI_stream_set_preference; - - HATTRIB INPUT_BIT_RATE; - HATTRIB INPUT_SAMPLE_RATE; - HATTRIB INPUT_BITS; - HATTRIB INPUT_CHANNELS; - HATTRIB OUTPUT_BIT_RATE; - HATTRIB OUTPUT_SAMPLE_RATE; - HATTRIB OUTPUT_BITS; - HATTRIB OUTPUT_CHANNELS; - HATTRIB POSITION; - HATTRIB PERCENT_DONE; - HATTRIB MIN_INPUT_BLOCK_SIZE; - HATTRIB RAW_RATE; - HATTRIB RAW_BITS; - HATTRIB RAW_CHANNELS; - HATTRIB REQUESTED_RATE; - HATTRIB REQUESTED_BITS; - HATTRIB REQUESTED_CHANS; - - HASISTREAM stream; - } -ASISTAGE; - -typedef struct - { - MIXER_FLUSH MSS_mixer_flush; - MIXER_MERGE MSS_mixer_merge; - MIXER_COPY MSS_mixer_copy; - } -MIXSTAGE; - -typedef struct - { - struct _FLTPROVIDER FAR *provider; - HSAMPLESTATE sample_state; - } -FLTSTAGE; - -typedef struct -{ - S32 active; // Pass-through if 0, active if 1 - HPROVIDER provider; - - union - { - ASISTAGE ASI; - MIXSTAGE MIX; - FLTSTAGE FLT; - } - TYPE; -} -DPINFO; - -// -// Other data types -// - -typedef struct _AIL_INPUT_INFO // Input descriptor type -{ - U32 device_ID; // DS LPGUID or wave device ID - U32 hardware_format; // e.g., DIG_F_STEREO_16 - U32 hardware_rate; // e.g., 22050 - AILINCB callback; // Callback function to receive incoming data - S32 buffer_size; // Maximum # of bytes to be passed to callback (-1 to use DIG_INPUT_LATENCY) - U32 user_data; // this is a user defined value -} -AIL_INPUT_INFO; - -typedef struct _AILTIMER // Timer instance -{ - U32 status; - AILTIMERCB callback; - U32 user; - - S32 elapsed; - S32 value; - S32 callingCT; // Calling EXE's task number (16 bit only) - S32 callingDS; // Calling EXE's DS (used in 16 bit only) - S32 IsWin32s; // Is this a Win32s callback -} AILTIMERSTR; - -typedef struct _ADPCMDATATAG -{ - U32 blocksize; - U32 extrasamples; - U32 blockleft; - U32 step; - U32 savesrc; - U32 sample; - U32 destend; - U32 srcend; - U32 samplesL; - U32 samplesR; - U16 moresamples[16]; -} ADPCMDATA; - -typedef struct _SAMPLE // Sample instance -{ - char tag[4]; // HSAM - - HDIGDRIVER driver; // Driver for playback - - U32 status; // SMP_ flags: _FREE, _DONE, _PLAYING - - void const FAR *start[2]; // Sample buffer address (W) - U32 len [2]; // Sample buffer size in bytes (W) - U32 pos [2]; // Index to next byte (R/W) - U32 done [2]; // Nonzero if buffer with len=0 sent by app - S32 reset_ASI [2]; // Reset the ASI decoder at the end of the buffer - - U32 src_fract; // Fractional part of source address - S32 left_val; // Mixer source value from end of last buffer - S32 right_val; // Mixer source value from end of last buffer - - S32 current_buffer; // Buffer # active (0/1) - S32 last_buffer; // Last active buffer (for double-buffering) - S32 starved; // Buffer stream has run out of data - - S32 loop_count; // # of cycles-1 (1=one-shot, 0=indefinite) - S32 loop_start; // Starting offset of loop block (0=SOF) - S32 loop_end; // End offset of loop block (-1=EOF) - - S32 format; // DIG_F format (8/16 bits, mono/stereo) - U32 flags; // DIG_PCM_SIGN / DIG_PCM_ORDER (stereo only) - - S32 playback_rate; // Playback rate in hertz - - S32 volume; // Sample volume 0-127 - S32 pan; // Mono panpot/stereo balance (0=L ... 127=R) - - S32 left_scale; // Left/mono volume scalar 0-2047 - S32 right_scale; // Right volume scalar 0-2047 - - S32 service_type; // 1 if single-buffered; 2 if streamed - - AILSAMPLECB SOB; // Start-of-block callback function - AILSAMPLECB EOB; // End-of-buffer callback function - AILSAMPLECB EOS; // End-of-sample callback function - - S32 user_data [8]; // Miscellaneous user data - S32 system_data[8]; // Miscellaneous system data - - ADPCMDATA adpcm; - -#ifdef IS_WINDOWS - - S32 SOB_IsWin32s; // Is this a Win32s callback - S32 EOB_IsWin32s; // Is this a Win32s callback - S32 EOS_IsWin32s; // Is this a Win32s callback - - // - // DirectSound-specific data - // - - S32 secondary_buffer; // Secondary buffer index - - S32 service_interval; // Service sample every n ms - S32 service_tick; // Current service countdown value - S32 buffer_segment_size; // Buffer segment size to fill - - S32 prev_segment; // Previous segment # (0...n) - S32 prev_cursor; // Previous play cursor location - - S32 bytes_remaining; // # of bytes left to play (if not -1) - - S32 direct_control; // 1 if app controls buffer, 0 if MSS - -#endif - - S32 doeob; // Flags to trigger callbacks - S32 dosob; - S32 doeos; - - // - // Sample pipeline stages - // - - DPINFO pipeline[N_SAMPLE_STAGES]; - - // - // Reverb parms - // - - F32 reverb_level; // Level [0.0, 1.0] - F32 reverb_reflect_time; // Reflect time in milliseconds - F32 reverb_decay_time; // Decay time [0.1, 20.0] - S32 base_scale; // Original 12-bit volume scalar -} -SAMPLE; - -#if defined(IS_WINDOWS) || defined(IS_MAC) - -DXDEC U32 AILCALL AIL_get_timer_highest_delay (void); - -DXDEC void AILCALL AIL_serve(void); - -#ifdef IS_MAC - -typedef void * LPSTR; - -#define WHDR_DONE 0 - -typedef struct _WAVEIN -{ - long temp; -} * HWAVEIN; - -typedef struct _WAVEHDR -{ - S32 dwFlags; - S32 dwBytesRecorded; - S32 dwUser; - S32 temp; - void * lpData; - S32 dwBufferLength; - S32 longdwLoops; - S32 dwLoops; - void * lpNext; - U32 * reserved; - -} WAVEHDR, * LPWAVEHDR; - -#endif - -typedef struct _DIG_INPUT_DRIVER FAR *HDIGINPUT; // Handle to digital input driver - -typedef struct _DIG_INPUT_DRIVER // Handle to digital input driver -{ - C8 tag[4]; // HDIN - - HTIMER background_timer; // Background timer handle - - AIL_INPUT_INFO info; // Input device descriptor - - S32 input_enabled; // 1 if enabled, 0 if not - -#ifndef IS_MAC - - U32 callback_user; // Callback user value - - // - // Provider-independent data - // - - U32 DMA_size; // Size of each DMA sub-buffer in bytes - void FAR *DMA[2]; // Simulated DMA buffers - - U8 silence; // Silence value for current format (0 or 128) - - S32 device_active; // 1 if buffers submittable, 0 if not - - // - // waveOut-specific data - // - - HWAVEIN hWaveIn; // Handle to wave input device - volatile WAVEHDR wavehdr[2]; // Handles to wave headers - -#else - Boolean timer_started; - Boolean locked; - Boolean enter_lock; - U32 saved_period; - - void* my_vars; - - // - // Input related - // - - U32 input_buffer_size; - char * input_buffers[2]; - - // - // Mix related - // - - char * build_buffer; - U32 build_buffer_size; - - // - // Output related - // - struct - { - S8 * buffer; - S8 * buffer_end; - - U32 size; - S8 * right_margine; - S8 * current_head; - S8 * current_tail; - } output_buffer; - - S32 mix_operation; - S32 playback_ratio; - U32 src_fract; - S8 * current_head; - S32 left_val; - S32 right_val; - - U32 stored_sample_size; - U32 stored_number_of_channels; - - U32 last_rw_delta; - U32 period; - -#endif -} -DIG_INPUT_DRIVER; - -#endif - -typedef struct _DIG_DRIVER // Handle to digital audio driver -{ - char tag[4]; // HDIG - - HTIMER backgroundtimer; // Background timer handle - - S32 quiet; // # of consecutive quiet sample periods - - S32 n_active_samples; // # of samples being processed - - S32 master_volume; // Master sample volume 0-127 - - S32 DMA_rate; // Hardware sample rate - S32 hw_format; // DIG_F code in use - U32 hw_mode_flags; // DIG_PCM_ flags for mode in use - - S32 channels_per_sample; // # of channels per sample (1 or 2) - S32 bytes_per_channel; // # of bytes per channel (1 or 2) - S32 channels_per_buffer; // # of channels per half-buffer - S32 samples_per_buffer; // # of samples per half-buffer - - S32 playing; // Playback active if non-zero - -#ifdef IS_MAC - U32 n_samples_allocated; - U32 n_samples_used; - U32 n_samples_played; - SAMPLE *samples; // Pointer to SAMPLEs - - HDIGDRIVER next; // Pointer to next HDIGDRIVER in use - U32 reset_works; // TRUE if OK to do waveOutReset - U32 request_reset; // If nonzero, do waveOutReset ASAP - S32 released; // has the sound manager been released? - - ExtSoundHeader sound_header; - SndChannelPtr sound_channel; - SndCallBackUPP global_callback; - Ptr buffers[2]; - Boolean loaded[2]; - U32 work_buffer; - U32 play_buffer; - U32 load_pos; - U32 load_size; - Boolean load; - U32 start_time; - void* background_processor; - -#else - HSAMPLE samples; // Pointer to list of SAMPLEs -#endif - - S32 n_samples; // # of SAMPLEs - - S32 build_size; // # of bytes in build buffer - S32 FAR *build_buffer; // Build buffer (4 * samples_per_buffer) - - S32 system_data[8]; // Miscellaneous system data - - S32 buffer_size; // Size of each output buffer - -#ifdef IS_WINDOWS - - // - // waveOut-specific interface data - // - - HWAVEOUT hWaveOut; // Wave output driver - - U32 reset_works; // TRUE if OK to do waveOutReset - U32 request_reset; // If nonzero, do waveOutReset ASAP - - LPWAVEHDR first; // Pointer to first WAVEHDR in chain - S32 n_buffers; // # of output WAVEHDRs in chain - - LPWAVEHDR volatile FAR *return_list; // Circular list of returned WAVEHDRs - S32 volatile return_head; // Head of WAVEHDR list (insertion point) - S32 volatile return_tail; // Tail of WAVEHDR list (retrieval point) - - - U32 deviceid; // id from waveout open - PCMWAVEFORMAT wformat; // format from waveout open - - // - // DirectSound-specific interface data - // - - U32 guid; // The guid id of the ds driver - AILLPDIRECTSOUND pDS; // DirectSound output driver (don't - // use with Smacker directly anymore!) - - U32 ds_priority; // priority opened with - - S32 emulated_ds; // is ds emulated or not? - AILLPDIRECTSOUNDBUFFER lppdsb; // primary buffer or null - - U32 dsHwnd; // HWND used with DirectSound - - AILLPDIRECTSOUNDBUFFER FAR * lpbufflist; // List of pointers to secondary buffers - HSAMPLE FAR *samp_list; // HSAMPLE associated with each buffer - S32 FAR *sec_format; // DIG_F_ format for secondary buffer - S32 max_buffs; // Max. allowable # of secondary buffers - - // - // Misc. data - // - - S32 released; // has the sound manager been released? - - U32 foreground_timer; // Foreground timer handle - - HDIGDRIVER next; // Pointer to next HDIGDRIVER in use - S32 callingCT; // Calling EXE's task number (16 bit only) - S32 callingDS; // Calling EXE's DS (used in 16 bit only) - - // - // Vars for waveOut emulation - // - - S32 DS_initialized; - - AILLPDIRECTSOUNDBUFFER DS_sec_buff; // Secondary buffer (or NULL if none) - AILLPDIRECTSOUNDBUFFER DS_out_buff; // Output buffer (may be sec or prim) - S32 DS_buffer_size; // Size of entire output buffer - - S32 DS_frag_cnt; // Total fragment count and size, and - S32 DS_frag_size; // last fragment occupied by play cursor - S32 DS_last_frag; - S32 DS_last_write; - S32 DS_last_timer; - S32 DS_skip_time; - - S32 DS_use_default_format; // 1 to force use of default DS primary buffer format - -#else - - #ifdef IS_DOS - - // must be first in the DOS section - void *DMA[2]; // Protected-mode pointers to half-buffers - // (note that DMA[0] may != DMA_buf) - - - REALFAR DMA_seg; // Seg:off pointer to DMA buffers (off=0) - U32 DMA_sel; // Selector for DMA buffers (off=0) - void *DMA_buf; // Protected-mode pointer to DMA buffers - - S16 *buffer_flag; // Protected-mode pointer to buffer flag - S32 last_buffer; // Last active buffer flag value in driver - - AIL_DRIVER *drvr; // Base driver descriptor - - DIG_DDT *DDT; // Protected-mode pointer to DDT - DIG_DST *DST; // Protected-mode pointer to DST - - #endif - -#endif - -#ifdef IS_X86 - S32 use_MMX; // Use MMX with this driver if TRUE -#endif - - void FAR *decode_buffer; // Buffer used by optional ASI pipeline decoder - S32 decode_buffer_size; // # of bytes in decode buffer - - U32 us_count; - U32 ms_count; - U32 last_ms_polled; - U32 last_percent; - - // - // Digital driver pipeline stages - // - - DPINFO pipeline[N_DIGDRV_STAGES]; - - // - // Reverb buffer - // - - S32 FAR *reverb_buffer; - S32 reverb_buffer_size; - S32 reverb_buffer_position; - -#ifdef IS_WINDOWS - S32 no_wom_done; // don't process WOM_DONEs on this driver - U32 wom_done_buffers; -#endif -} -DIG_DRIVER; - -typedef struct // MIDI status log structure - { - S32 program [NUM_CHANS]; // Program Change - S32 pitch_l [NUM_CHANS]; // Pitch Bend LSB - S32 pitch_h [NUM_CHANS]; // Pitch Bend MSB - - S32 c_lock [NUM_CHANS]; // Channel Lock - S32 c_prot [NUM_CHANS]; // Channel Lock Protection - S32 c_mute [NUM_CHANS]; // Channel Mute - S32 c_v_prot [NUM_CHANS]; // Voice Protection - S32 bank [NUM_CHANS]; // Patch Bank Select - S32 gm_bank_l [NUM_CHANS]; // GM Bank Select - S32 gm_bank_m [NUM_CHANS]; // GM Bank Select - S32 indirect [NUM_CHANS]; // ICA indirect controller value - S32 callback [NUM_CHANS]; // Callback Trigger - - S32 mod [NUM_CHANS]; // Modulation - S32 vol [NUM_CHANS]; // Volume - S32 pan [NUM_CHANS]; // Panpot - S32 exp [NUM_CHANS]; // Expression - S32 sus [NUM_CHANS]; // Sustain - S32 reverb [NUM_CHANS]; // Reverb - S32 chorus [NUM_CHANS]; // Chorus - - S32 bend_range[NUM_CHANS]; // Bender Range (data MSB, RPN 0 assumed) - - S32 RPN_L [NUM_CHANS]; // RPN # LSB - S32 RPN_M [NUM_CHANS]; // RPN # MSB - } -CTRL_LOG; - -typedef struct _SEQUENCE // XMIDI sequence state table -{ - char tag[4]; // HSEQ - - HMDIDRIVER driver; // Driver for playback - - U32 status; // SEQ_ flags - - void const FAR *TIMB; // XMIDI IFF chunk pointers - void const FAR *RBRN; - void const FAR *EVNT; - - U8 const FAR *EVNT_ptr; // Current event pointer - - U8 FAR *ICA; // Indirect Controller Array - - AILPREFIXCB prefix_callback; // XMIDI Callback Prefix handler - AILTRIGGERCB trigger_callback; // XMIDI Callback Trigger handler - AILBEATCB beat_callback; // XMIDI beat/bar change handler - AILSEQUENCECB EOS; // End-of-sequence callback function - - S32 loop_count; // 0=one-shot, -1=indefinite, ... - - S32 interval_count; // # of intervals until next event - S32 interval_num; // # of intervals since start - - S32 volume; // Sequence volume 0-127 - S32 volume_target; // Target sequence volume 0-127 - S32 volume_accum; // Accumulated volume period - S32 volume_period; // Period for volume stepping - - S32 tempo_percent; // Relative tempo percentage 0-100 - S32 tempo_target; // Target tempo 0-100 - S32 tempo_accum; // Accumulated tempo period - S32 tempo_period; // Period for tempo stepping - S32 tempo_error; // Error counter for tempo DDA - - S32 beat_count; // Sequence playback position - S32 measure_count; - - S32 time_numerator; // Sequence timing data - S32 time_fraction; - S32 beat_fraction; - S32 time_per_beat; - - void const FAR *FOR_ptrs[FOR_NEST]; // Loop stack - S32 FOR_loop_count [FOR_NEST]; - - S32 chan_map [NUM_CHANS]; // Physical channel map for sequence - - CTRL_LOG shadow; // Controller values for sequence - - S32 note_count; // # of notes "on" - - S32 note_chan [MAX_NOTES]; // Channel for queued note (-1=free) - S32 note_num [MAX_NOTES]; // Note # for queued note - S32 note_time [MAX_NOTES]; // Remaining duration in intervals - - S32 user_data [8]; // Miscellaneous user data - S32 system_data[8]; // Miscellaneous system data - -#ifdef IS_WINDOWS - S32 PREFIX_IsWin32s; // Is this a Win32s callback - S32 TRIGGER_IsWin32s; // Is this a Win32s callback - S32 BEAT_IsWin32s; // Is this a Win32s callback - S32 EOS_IsWin32s; // Is this a Win32s callback -#endif -} SEQUENCE; - -#ifdef IS_MAC - -struct MIDIHDR; -struct MIDIOUT; -typedef struct MIDIOUT* HMIDIOUT; - -#endif - -typedef struct _MDI_DRIVER // Handle to XMIDI driver -{ - char tag[4]; // HMDI - - HTIMER timer; // XMIDI quantization timer - S32 interval_time; // XMIDI quantization timer interval in uS - - S32 disable; // > 0 to disable XMIDI service - - HSEQUENCE sequences; // Pointer to list of SEQUENCEs - S32 n_sequences; // # of SEQUENCEs - - S32 lock [NUM_CHANS]; // 1 if locked, 2 if protected, else 0 - HSEQUENCE locker[NUM_CHANS]; // HSEQUENCE which locked channel - HSEQUENCE owner [NUM_CHANS]; // HSEQUENCE which owned locked channel - HSEQUENCE user [NUM_CHANS]; // Last sequence to use channel - S32 state [NUM_CHANS]; // Lock state prior to being locked - - S32 notes [NUM_CHANS]; // # of active notes in channel - - AILEVENTCB event_trap; // MIDI event trap callback function - AILTIMBRECB timbre_trap; // Timbre request callback function - - S32 master_volume; // Master XMIDI note volume 0-127 - - S32 system_data[8]; // Miscellaneous system data - -#if defined(IS_WINDOWS) || defined(IS_MAC) - - S32 released; // has the hmidiout handle been released - U32 deviceid; // ID of the MIDI device - U8 FAR *sysdata; // SysEx buffer - -#endif - -#ifdef IS_WINDOWS - - S32 EVENT_IsWin32s; // Is this a Win32s callback - S32 TIMBRE_IsWin32s; // Is this a Win32s callback - - MIDIHDR FAR *mhdr; // SysEx header - - HMDIDRIVER next; // Pointer to next HMDIDRIVER in use - S32 callingCT; // Calling EXE's task number (16 bit only) - S32 callingDS; // Calling EXE's DS (used in 16 bit only) - - HMIDIOUT hMidiOut; // MIDI output driver - -#else - - #ifdef IS_DOS - - S32 message_count; // MIDI message count - S32 offset; // MIDI buffer offset - - AIL_DRIVER *drvr; // Base driver descriptor - - MDI_DDT *DDT; // Protected-mode pointer to DDT - MDI_DST *DST; // Protected-mode pointer to DST - #else - #ifdef IS_MAC - struct MIDIHDR FAR *mhdr; // SysEx header - HMDIDRIVER next; // Pointer to next HMDIDRIVER in use - HMIDIOUT hMidiOut; // MIDI output driver - U32 last_us_time; - long period_counter; - long current_period_sum; - #endif - #endif - -#endif - -} -MDI_DRIVER; - -typedef struct // XMIDI TIMB IFF chunk - { - S8 name[4]; - - U8 msb; - U8 lsb; - U8 lsb2; - U8 lsb3; - - U16 n_entries; - - U16 timbre[1]; - } -TIMB_chunk; - -typedef struct // XMIDI RBRN IFF entry - { - S16 bnum; - U32 offset; - } -RBRN_entry; - -typedef struct // Wave library entry -{ - S32 bank; // XMIDI bank, MIDI patch for sample - S32 patch; - - S32 root_key; // Root MIDI note # for sample (or -1) - - U32 file_offset; // Offset of wave data from start-of-file - U32 size; // Size of wave sample in bytes - - S32 format; // DIG_F format (8/16 bits, mono/stereo) - U32 flags; // DIG_PCM_SIGN / DIG_PCM_ORDER (stereo) - S32 playback_rate; // Playback rate in hertz -} -WAVE_ENTRY; - -typedef struct // Virtual "wave synthesizer" descriptor -{ - HMDIDRIVER mdi; // MIDI driver for use with synthesizer - HDIGDRIVER dig; // Digital driver for use with synthesizer - - WAVE_ENTRY FAR *library; // Pointer to wave library - - AILEVENTCB prev_event_fn; // Previous MIDI event trap function - AILTIMBRECB prev_timb_fn; // Previous timbre request trap function - - CTRL_LOG controls; // MIDI controller states - - WAVE_ENTRY FAR *wave [NUM_CHANS];// Pointer to WAVE_ENTRY for each channel - - HSAMPLE S [MAX_W_VOICES]; // List of HSAMPLE voices - S32 n_voices; // Actual # of voices allocated to synth - - S32 chan [MAX_W_VOICES]; // MIDI channel for each voice, or -1 - S32 note [MAX_W_VOICES]; // MIDI note number for voice - S32 root [MAX_W_VOICES]; // MIDI root note for voice - S32 rate [MAX_W_VOICES]; // Playback rate for voice - S32 vel [MAX_W_VOICES]; // MIDI note velocity for voice - U32 time [MAX_W_VOICES]; // Timestamp for voice - - U32 event; // Event counter for LRU timestamps -} -WAVE_SYNTH; - -typedef WAVE_SYNTH FAR * HWAVESYNTH;// Handle to virtual wave synthesizer - -// -// Handle to thread which called AIL_startup() -// -// This thread is suspended by MSS callback threads, to simulate DOS-style -// interrupt handler behavior -// - -#ifdef IS_WIN32 - -extern HANDLE hAppThread; - -#endif - -// -// Background flag for timers -// - -extern volatile S32 AIL_bkgnd_flag; - -// -// Global preference array -// - -extern S32 AIL_preference [N_PREFS]; - -// -// DIG_DRIVER list -// - -extern HDIGDRIVER DIG_first; - -// -// MDI_DRIVER list -// - -extern HMDIDRIVER MDI_first; - -// -// Miscellaneous system services -// - -#define FILE_READ_WITH_SIZE ((void FAR*)(S32)-1) - -#ifndef NO_OLD_SYS_FUNCTIONS - -#define MEM_alloc_lock AIL_mem_alloc_lock -#define MEM_free_lock AIL_mem_free_lock -#define FILE_error AIL_file_error -#define FILE_size AIL_file_size -#define FILE_read AIL_file_read -#define FILE_write AIL_file_write - -#ifdef IS_DOS - -#define MEM_alloc AIL_mem_alloc -#define MEM_free AIL_mem_free -#define MEM_use_malloc AIL_mem_use_malloc -#define MEM_use_free AIL_mem_use_free -#define MEM_alloc_DOS AIL_mem_alloc_DOS -#define MEM_free_DOS AIL_mem_free_DOS -#define VMM_lock_range AIL_vmm_lock_range -#define VMM_unlock_range AIL_vmm_unlock_range -#define VMM_lock AIL_vmm_lock -#define VMM_unlock AIL_vmm_unlock - -#endif - -#endif - -extern S32 AILCALLBACK DP_ASI_DECODER_callback(U32 user, - void FAR *dest, - S32 bytes_requested, - S32 offset); - -DXDEC void FAR * AILCALL AIL_mem_alloc_lock(U32 size); -DXDEC void AILCALL AIL_mem_free_lock (void FAR *ptr); - -DXDEC S32 AILCALL AIL_file_error (void); - -DXDEC S32 AILCALL AIL_file_size (char const FAR *filename); - -DXDEC void FAR * AILCALL AIL_file_read (char const FAR *filename, - void FAR *dest); - -DXDEC S32 AILCALL AIL_file_write (char const FAR *filename, - void const FAR *buf, - U32 len); - -DXDEC S32 AILCALL AIL_WAV_file_write - (char const FAR *filename, - void const FAR *buf, - U32 len, - S32 rate, - S32 format); - -DXDEC S32 AILCALL AIL_file_append (char const FAR *filename, - void const FAR *buf, U32 len); - -#ifdef IS_MAC - - -DXDEC S32 AILCALL AIL_file_fss_size(FSSpec const FAR *filename); - -DXDEC void FAR * AILCALL AIL_file_fss_read(FSSpec const FAR *filename, - void FAR *dest); - -DXDEC S32 AILCALL AIL_file_fss_write(FSSpec const FAR *filename, - void const FAR *buf, - U32 len); - -DXDEC S32 AILCALL AIL_file_fss_attrib_write - (FSSpec const FAR *filename, - void const FAR *buf, - U32 len, - U32 type, - U32 creator ); - -DXDEC S32 AILCALL AIL_WAV_file_fss_write - (FSSpec const FAR *filename, - void const FAR *buf, - U32 len, - S32 rate, - S32 format); - -DXDEC void * AILCALL AIL_mem_use_malloc(void * AILCALLBACK (*fn)(U32)); -DXDEC void * AILCALL AIL_mem_use_free (void AILCALLBACK (*fn)(void *)); - -#endif - -#ifdef IS_DOS - -extern void * AILCALLBACK (*AIL_mem_alloc) (U32); -extern void AILCALLBACK (*AIL_mem_free) (void *); - -void * cdecl AIL_mem_use_malloc(void * AILCALLBACK (*fn)(U32)); -void * cdecl AIL_mem_use_free (void AILCALLBACK (*fn)(void *)); - -// -// Other memory-management functions -// - -DXDEC S32 AILCALL AIL_mem_alloc_DOS (U32 n_paras, - void **protected_ptr, - U32 *segment_far_ptr, - U32 *selector); - -DXDEC void AILCALL AIL_mem_free_DOS (void *protected_ptr, - U32 segment_far_ptr, - U32 selector); - -DXDEC S32 AILCALL AIL_vmm_lock_range (void *p1, void *p2); -DXDEC S32 AILCALL AIL_vmm_unlock_range (void *p1, void *p2); - -DXDEC S32 AILCALL AIL_vmm_lock (void *start, U32 size); -DXDEC S32 AILCALL AIL_vmm_unlock (void *start, U32 size); - -DXDEC U32 AILCALL AIL_sel_base (U32 sel); - -DXDEC void AILCALL AIL_sel_set_limit (U32 sel, - U32 limit); -// -// Last IO_PARMS structure used to attempt device detection -// - -extern IO_PARMS AIL_last_IO_attempt; - -// -// Low-level support services -// - -DXDEC REALFAR AILCALL AIL_get_real_vect (U32 vectnum); - -DXDEC void AILCALL AIL_set_real_vect (U32 vectnum, - REALFAR real_ptr); - -DXDEC void AILCALL AIL_set_USE16_ISR (S32 IRQ, - REALFAR real_base, - U32 ISR_offset); - -DXDEC void AILCALL AIL_restore_USE16_ISR (S32 IRQ); - -DXDEC U32 AILCALL AIL_disable_interrupts (void); -DXDEC void AILCALL AIL_restore_interrupts (U32 FD_register); - -DXDEC void AILCALL AIL_switch_stack (void *stack, - U32 size, - U32 *SS, - void **ESP, - void **EBP); - -DXDEC void AILCALL AIL_restore_stack (U32 SS, - void *ESP, - void *EBP); - -DXDEC S32 AILCALL AIL_call_driver (AIL_DRIVER *drvr, - S32 fn, - VDI_CALL *in, - VDI_CALL *out); - -DXDEC S32 AILCALL AIL_read_INI (AIL_INI *INI, - char *filename); - -DXDEC U32 AILCALL AIL_interrupt_divisor (void); - -#endif - - -#ifdef __WATCOMC__ - -void MSSBreakPoint(); -#pragma aux MSSBreakPoint = "int 3"; - -#else - -#define MSSBreakPoint() __asm {int 3} - -#endif - - -// -// High-level support services -// - -#ifdef IS_MAC - -#if !defined(max) -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#if !defined(min) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#endif - -#ifdef IS_DOS - -#ifdef IS_WATCOM - -#if !defined(max) // Watcom stdlib.h doesn't define these for C++ -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#if !defined(min) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#endif - -#ifdef __SW_3R -extern S32 AILCALL AIL_startup_reg (void); -#define AIL_startup AIL_startup_reg -#else -extern S32 AILCALL AIL_startup_stack (void); -#define AIL_startup AIL_startup_stack -#endif - -#define AIL_quick_startup(ud,um,opr,opb,ops) AIL_quick_startup_with_start(&AIL_startup,ud,um,opr,opb,ops) - -#define AIL_get_preference(number) (AIL_preference[number]) - -#else - -DXDEC S32 AILCALL AIL_startup (void); - -DXDEC S32 AILCALL AIL_get_preference (U32 number); - -#endif - -DXDEC void AILCALL AIL_shutdown (void); - -DXDEC S32 AILCALL AIL_set_preference (U32 number, - S32 value); - -DXDEC char FAR *AILCALL AIL_last_error (void); - -DXDEC void AILCALL AIL_set_error (char const FAR * error_msg); - -// -// Low-level support services -// - -DXDEC void -#ifndef IS_MAC -__cdecl -#endif -AIL_debug_printf (C8 const FAR *fmt, ...); - -#ifdef IS_X86 - -DXDEC U32 AILCALL AIL_MMX_available (void); - -#endif - -DXDEC void AILCALL AIL_lock (void); -DXDEC void AILCALL AIL_unlock (void); - -#ifdef IS_WIN32 - -DXDEC void AILCALL AIL_lock_mutex (void); -DXDEC void AILCALL AIL_unlock_mutex (void); - -#endif - -DXDEC void AILCALL AIL_delay (S32 intervals); - -DXDEC S32 AILCALL AIL_background (void); - -// -// Process services -// - -DXDEC HTIMER AILCALL AIL_register_timer (AILTIMERCB fn); - -DXDEC U32 AILCALL AIL_set_timer_user (HTIMER timer, - U32 user); - -DXDEC void AILCALL AIL_set_timer_period (HTIMER timer, - U32 microseconds); - -DXDEC void AILCALL AIL_set_timer_frequency (HTIMER timer, - U32 hertz); - -DXDEC void AILCALL AIL_set_timer_divisor (HTIMER timer, - U32 PIT_divisor); - -DXDEC void AILCALL AIL_start_timer (HTIMER timer); -DXDEC void AILCALL AIL_start_all_timers (void); - -DXDEC void AILCALL AIL_stop_timer (HTIMER timer); -DXDEC void AILCALL AIL_stop_all_timers (void); - -DXDEC void AILCALL AIL_release_timer_handle (HTIMER timer); -DXDEC void AILCALL AIL_release_all_timers (void); - -#ifdef IS_WIN32 - -#ifndef BUILD_MSS - -// static function that handles shutdown -int __cdecl MSS_auto_cleanup(void); - -#ifdef _MSC_VER -// on MSVC, automatically register a cleanup function -//ODCODENOTE Remove -//#define AIL_startup() (MSS_auto_cleanup(),AIL_startup()) -#endif - -#endif - -DXDEC HWND AILCALL AIL_HWND (void); - -#else - #ifdef IS_MAC - DXDEC ProcessSerialNumber AIL_Process(void); - #endif -#endif - -// -// high-level digital services -// - -DXDEC HDIGDRIVER AILCALL AIL_open_digital_driver( U32 frequency, - S32 bits, - S32 channel, - U32 flags ); - -#define AIL_OPEN_DIGITAL_FORCE_PREFERENCE 1 - -DXDEC void AILCALL AIL_close_digital_driver( HDIGDRIVER dig ); - -#ifdef IS_WINDOWS - -#define AIL_MSS_version(str,len) \ -{ \ - HINSTANCE l=LoadLibrary(MSSDLLNAME); \ - if ((U32)l<=32) \ - *(str)=0; \ - else { \ - LoadString(l,1,str,len); \ - FreeLibrary(l); \ - } \ -} - -DXDEC S32 AILCALL AIL_waveOutOpen (HDIGDRIVER FAR *drvr, - LPHWAVEOUT FAR *lphWaveOut, - S32 wDeviceID, - LPWAVEFORMAT lpFormat); - -DXDEC void AILCALL AIL_waveOutClose (HDIGDRIVER drvr); - -DXDEC S32 AILCALL AIL_digital_handle_release(HDIGDRIVER drvr); - -DXDEC S32 AILCALL AIL_digital_handle_reacquire - (HDIGDRIVER drvr); - -#else - -#ifdef IS_MAC - -typedef struct MSS_VersionType_ -{ - Str255 version_name; -} MSS_VersionType; - -#define AIL_MSS_version(str,len) \ -{ \ - long _res = OpenResFile("\pMiles Shared Library"); \ - if (_res==-1) \ - { \ - str[0]=0; \ - } \ - else \ - { \ - Handle _H; \ - short _Err; \ - long _cur= CurResFile(); \ - UseResFile(_res); \ - _H = GetResource('vers', 2); \ - _Err = ResError(); \ - if((_Err != noErr) || (_H==0)) \ - { \ - str[0]=0; \ - UseResFile(_cur); \ - CloseResFile(_res); \ - } \ - else \ - { \ - if (GetHandleSize(_H)==0) \ - { \ - str[0]=0; \ - UseResFile(_cur); \ - CloseResFile(_res); \ - } \ - else \ - { \ - MSS_VersionType * _vt = (MSS_VersionType*)*_H; \ - if ((U32)_vt->version_name[6]>4) \ - _vt->version_name[6]-=4; \ - else \ - _vt->version_name[6]=0; \ - if (((U32)len) <= ((U32)_vt->version_name[6])) \ - _vt->version_name[6] = (U8)len-1; \ - memcpy( str, _vt->version_name+11, _vt->version_name[6] ); \ - str[_vt->version_name[6]]=0; \ - UseResFile(_cur); \ - CloseResFile(_res); \ - } \ - ReleaseResource(_H); \ - } \ - } \ -} - -DXDEC S32 AILCALL AIL_digital_handle_release(HDIGDRIVER drvr); - -DXDEC S32 AILCALL AIL_digital_handle_reacquire - (HDIGDRIVER drvr); - -#else - -// -// DOS installation services -// - -DXDEC IO_PARMS * AILCALL AIL_get_IO_environment (AIL_DRIVER *drvr); - -DXDEC AIL_DRIVER* AILCALL AIL_install_driver (U8 const *driver_image, - U32 n_bytes); - -DXDEC void AILCALL AIL_uninstall_driver (AIL_DRIVER *drvr); - -DXDEC S32 AILCALL AIL_install_DIG_INI (HDIGDRIVER *dig); - -DXDEC HDIGDRIVER AILCALL AIL_install_DIG_driver_file - (char const *filename, - IO_PARMS *IO); - -DXDEC void AILCALL AIL_uninstall_DIG_driver (HDIGDRIVER dig); - - -DXDEC HDIGDRIVER AILCALL AIL_install_DIG_driver_image - (void const *driver_image, - U32 size, - IO_PARMS *IO); -#endif -#endif - -DXDEC char FAR* AILCALL AIL_set_redist_directory(char const FAR*dir); - -DXDEC S32 AILCALL AIL_digital_CPU_percent (HDIGDRIVER dig); - -DXDEC S32 AILCALL AIL_digital_latency (HDIGDRIVER dig); - -DXDEC HSAMPLE AILCALL AIL_allocate_sample_handle - (HDIGDRIVER dig); - -DXDEC HSAMPLE AILCALL AIL_allocate_file_sample (HDIGDRIVER dig, - void const FAR *file_image, - S32 block); - -DXDEC void AILCALL AIL_release_sample_handle (HSAMPLE S); - -DXDEC void AILCALL AIL_init_sample (HSAMPLE S); - -DXDEC S32 AILCALL AIL_set_sample_file (HSAMPLE S, - void const FAR *file_image, - S32 block); - -DXDEC S32 AILCALL AIL_set_named_sample_file (HSAMPLE S, - C8 const FAR *file_type_suffix, - void const FAR *file_image, - S32 file_size, - S32 block); - -DXDEC HPROVIDER AILCALL AIL_set_sample_processor (HSAMPLE S, - SAMPLESTAGE pipeline_stage, - HPROVIDER provider); - -DXDEC HPROVIDER AILCALL AIL_set_digital_driver_processor - (HDIGDRIVER dig, - DIGDRVSTAGE pipeline_stage, - HPROVIDER provider); - -DXDEC void AILCALL AIL_set_sample_adpcm_block_size - (HSAMPLE S, - U32 blocksize); - -DXDEC void AILCALL AIL_set_sample_address (HSAMPLE S, - void const FAR *start, - U32 len); - -DXDEC void AILCALL AIL_set_sample_type (HSAMPLE S, - S32 format, - U32 flags); - -DXDEC void AILCALL AIL_start_sample (HSAMPLE S); - -DXDEC void AILCALL AIL_stop_sample (HSAMPLE S); - -DXDEC void AILCALL AIL_resume_sample (HSAMPLE S); - -DXDEC void AILCALL AIL_end_sample (HSAMPLE S); - -DXDEC void AILCALL AIL_set_sample_playback_rate - (HSAMPLE S, - S32 playback_rate); - -DXDEC void AILCALL AIL_set_sample_volume (HSAMPLE S, - S32 volume); - -DXDEC void AILCALL AIL_set_sample_pan (HSAMPLE S, - S32 pan); - -DXDEC void AILCALL AIL_set_sample_loop_count (HSAMPLE S, - S32 loop_count); - -DXDEC void AILCALL AIL_set_sample_loop_block (HSAMPLE S, - S32 loop_start_offset, - S32 loop_end_offset); - -DXDEC U32 AILCALL AIL_sample_status (HSAMPLE S); - -DXDEC S32 AILCALL AIL_sample_playback_rate (HSAMPLE S); - -DXDEC S32 AILCALL AIL_sample_volume (HSAMPLE S); - -DXDEC S32 AILCALL AIL_sample_pan (HSAMPLE S); - -DXDEC S32 AILCALL AIL_sample_loop_count (HSAMPLE S); - -DXDEC void AILCALL AIL_set_digital_master_volume - (HDIGDRIVER dig, - S32 master_volume); - -DXDEC S32 AILCALL AIL_digital_master_volume (HDIGDRIVER dig); - -DXDEC void AILCALL AIL_set_sample_reverb(HSAMPLE S, - F32 reverb_level, - F32 reverb_reflect_time, - F32 reverb_decay_time); - -DXDEC void AILCALL AIL_sample_reverb (HSAMPLE S, - F32 FAR *reverb_level, - F32 FAR *reverb_reflect_time, - F32 FAR *reverb_decay_time); - -// -// low-level digital services -// - -DXDEC S32 AILCALL AIL_minimum_sample_buffer_size(HDIGDRIVER dig, - S32 playback_rate, - S32 format); - -DXDEC S32 AILCALL AIL_sample_buffer_ready (HSAMPLE S); - -DXDEC void AILCALL AIL_load_sample_buffer (HSAMPLE S, - U32 buff_num, - void const FAR *buffer, - U32 len); - -DXDEC void AILCALL AIL_request_EOB_ASI_reset (HSAMPLE S, - U32 buff_num); - -DXDEC S32 AILCALL AIL_sample_buffer_info (HSAMPLE S, //) - U32 FAR *pos0, - U32 FAR *len0, - U32 FAR *pos1, - U32 FAR *len1); - -DXDEC U32 AILCALL AIL_sample_granularity (HSAMPLE S); - -DXDEC void AILCALL AIL_set_sample_position (HSAMPLE S, - U32 pos); - -DXDEC U32 AILCALL AIL_sample_position (HSAMPLE S); - -DXDEC AILSAMPLECB AILCALL AIL_register_SOB_callback - (HSAMPLE S, - AILSAMPLECB SOB); - -DXDEC AILSAMPLECB AILCALL AIL_register_EOB_callback - (HSAMPLE S, - AILSAMPLECB EOB); - -DXDEC AILSAMPLECB AILCALL AIL_register_EOS_callback - (HSAMPLE S, - AILSAMPLECB EOS); - -DXDEC AILSAMPLECB AILCALL AIL_register_EOF_callback - (HSAMPLE S, - AILSAMPLECB EOFILE); - -DXDEC void AILCALL AIL_set_sample_user_data (HSAMPLE S, - U32 index, - S32 value); - -DXDEC S32 AILCALL AIL_sample_user_data (HSAMPLE S, - U32 index); - -DXDEC S32 AILCALL AIL_active_sample_count (HDIGDRIVER dig); - -DXDEC void AILCALL AIL_digital_configuration (HDIGDRIVER dig, - S32 FAR *rate, - S32 FAR *format, - char FAR *string); -#ifdef IS_WIN32 - -DXDEC S32 AILCALL AIL_set_direct_buffer_control (HSAMPLE S, - U32 command); - -DXDEC void AILCALL AIL_get_DirectSound_info (HSAMPLE S, - AILLPDIRECTSOUND *lplpDS, - AILLPDIRECTSOUNDBUFFER *lplpDSB); - -DXDEC S32 AILCALL AIL_set_DirectSound_HWND(HDIGDRIVER dig, HWND wnd); - -#endif - -DXDEC void AILCALL AIL_set_sample_ms_position (HSAMPLE S, //) - S32 milliseconds); - -DXDEC void AILCALL AIL_sample_ms_position (HSAMPLE S, //) - S32 FAR * total_milliseconds, - S32 FAR * current_milliseconds); - - -// -// Digital input services -// - -#if defined(IS_WINDOWS) || defined (IS_MAC) - -DXDEC HDIGINPUT AILCALL AIL_open_input (AIL_INPUT_INFO FAR *info); - -DXDEC void AILCALL AIL_close_input (HDIGINPUT dig); - -DXDEC AIL_INPUT_INFO FAR * - AILCALL AIL_get_input_info (HDIGINPUT dig); - -DXDEC S32 AILCALL AIL_set_input_state (HDIGINPUT dig, - S32 enable); -#endif - - -// -// High-level XMIDI services -// - -DXDEC HMDIDRIVER AILCALL AIL_open_XMIDI_driver( U32 flags ); - -#define AIL_OPEN_XMIDI_NULL_DRIVER 1 - -DXDEC void AILCALL AIL_close_XMIDI_driver( HMDIDRIVER mdi ); - -#ifdef IS_MAC - -DXDEC S32 AILCALL AIL_MIDI_handle_release - (HMDIDRIVER mdi); - -DXDEC S32 AILCALL AIL_MIDI_handle_reacquire - (HMDIDRIVER mdi); - -#else - -#ifdef IS_WINDOWS - -DXDEC S32 AILCALL AIL_midiOutOpen(HMDIDRIVER FAR *drvr, - LPHMIDIOUT FAR *lphMidiOut, - S32 dwDeviceID); - -DXDEC void AILCALL AIL_midiOutClose (HMDIDRIVER mdi); - -DXDEC S32 AILCALL AIL_MIDI_handle_release - (HMDIDRIVER mdi); - -DXDEC S32 AILCALL AIL_MIDI_handle_reacquire - (HMDIDRIVER mdi); - -#else - -#ifdef IS_DOS - -DXDEC S32 AILCALL AIL_install_MDI_INI (HMDIDRIVER *mdi); - -DXDEC HMDIDRIVER AILCALL AIL_install_MDI_driver_file - (char const *filename, - IO_PARMS *IO); - -DXDEC void AILCALL AIL_uninstall_MDI_driver (HMDIDRIVER mdi); - - -DXDEC HMDIDRIVER AILCALL AIL_install_MDI_driver_image - (void const *driver_image, - U32 size, - IO_PARMS *IO); - -DXDEC S32 AILCALL AIL_MDI_driver_type (HMDIDRIVER mdi); - -DXDEC void AILCALL AIL_set_GTL_filename_prefix (char const*prefix); - -DXDEC S32 AILCALL AIL_timbre_status (HMDIDRIVER mdi, - S32 bank, - S32 patch); - -DXDEC S32 AILCALL AIL_install_timbre (HMDIDRIVER mdi, - S32 bank, - S32 patch); - -DXDEC void AILCALL AIL_protect_timbre (HMDIDRIVER mdi, - S32 bank, - S32 patch); - -DXDEC void AILCALL AIL_unprotect_timbre (HMDIDRIVER mdi, - S32 bank, - S32 patch); - -#endif - -#endif - -#endif - -DXDEC HSEQUENCE AILCALL AIL_allocate_sequence_handle - (HMDIDRIVER mdi); - -DXDEC void AILCALL AIL_release_sequence_handle - (HSEQUENCE S); - -DXDEC S32 AILCALL AIL_init_sequence (HSEQUENCE S, - void const FAR *start, - S32 sequence_num); - -DXDEC void AILCALL AIL_start_sequence (HSEQUENCE S); - -DXDEC void AILCALL AIL_stop_sequence (HSEQUENCE S); - -DXDEC void AILCALL AIL_resume_sequence (HSEQUENCE S); - -DXDEC void AILCALL AIL_end_sequence (HSEQUENCE S); - -DXDEC void AILCALL AIL_set_sequence_tempo (HSEQUENCE S, - S32 tempo, - S32 milliseconds); - -DXDEC void AILCALL AIL_set_sequence_volume (HSEQUENCE S, - S32 volume, - S32 milliseconds); - -DXDEC void AILCALL AIL_set_sequence_loop_count - (HSEQUENCE S, - S32 loop_count); - -DXDEC U32 AILCALL AIL_sequence_status (HSEQUENCE S); - -DXDEC S32 AILCALL AIL_sequence_tempo (HSEQUENCE S); - -DXDEC S32 AILCALL AIL_sequence_volume (HSEQUENCE S); - -DXDEC S32 AILCALL AIL_sequence_loop_count (HSEQUENCE S); - -DXDEC void AILCALL AIL_set_XMIDI_master_volume - (HMDIDRIVER mdi, - S32 master_volume); - -DXDEC S32 AILCALL AIL_XMIDI_master_volume (HMDIDRIVER mdi); - - -// -// Low-level XMIDI services -// - -DXDEC S32 AILCALL AIL_active_sequence_count (HMDIDRIVER mdi); - -DXDEC S32 AILCALL AIL_controller_value (HSEQUENCE S, - S32 channel, - S32 controller_num); - -DXDEC S32 AILCALL AIL_channel_notes (HSEQUENCE S, - S32 channel); - -DXDEC void AILCALL AIL_sequence_position (HSEQUENCE S, - S32 FAR *beat, - S32 FAR *measure); - -DXDEC void AILCALL AIL_branch_index (HSEQUENCE S, - U32 marker); - -DXDEC AILPREFIXCB AILCALL AIL_register_prefix_callback - (HSEQUENCE S, - AILPREFIXCB callback); - -DXDEC AILTRIGGERCB AILCALL AIL_register_trigger_callback - (HSEQUENCE S, - AILTRIGGERCB callback); - -DXDEC AILSEQUENCECB AILCALL AIL_register_sequence_callback - (HSEQUENCE S, - AILSEQUENCECB callback); - -DXDEC AILBEATCB AILCALL AIL_register_beat_callback (HSEQUENCE S, - AILBEATCB callback); - -DXDEC AILEVENTCB AILCALL AIL_register_event_callback (HMDIDRIVER mdi, - AILEVENTCB callback); - -DXDEC AILTIMBRECB AILCALL AIL_register_timbre_callback - (HMDIDRIVER mdi, - AILTIMBRECB callback); - -DXDEC void AILCALL AIL_set_sequence_user_data (HSEQUENCE S, - U32 index, - S32 value); - -DXDEC S32 AILCALL AIL_sequence_user_data (HSEQUENCE S, - U32 index); - -DXDEC void AILCALL AIL_register_ICA_array (HSEQUENCE S, - U8 FAR *array); - -DXDEC S32 AILCALL AIL_lock_channel (HMDIDRIVER mdi); - -DXDEC void AILCALL AIL_release_channel (HMDIDRIVER mdi, - S32 channel); - -DXDEC void AILCALL AIL_map_sequence_channel (HSEQUENCE S, - S32 seq_channel, - S32 new_channel); - -DXDEC S32 AILCALL AIL_true_sequence_channel (HSEQUENCE S, - S32 seq_channel); - -DXDEC void AILCALL AIL_send_channel_voice_message - (HMDIDRIVER mdi, - HSEQUENCE S, - S32 status, - S32 data_1, - S32 data_2); - -DXDEC void AILCALL AIL_send_sysex_message (HMDIDRIVER mdi, - void const FAR *buffer); - -DXDEC HWAVESYNTH - AILCALL AIL_create_wave_synthesizer (HDIGDRIVER dig, - HMDIDRIVER mdi, - void const FAR *wave_lib, - S32 polyphony); - -DXDEC void AILCALL AIL_destroy_wave_synthesizer (HWAVESYNTH W); - -DXDEC void AILCALL AIL_set_sequence_ms_position (HSEQUENCE S, //) - S32 milliseconds); - -DXDEC void AILCALL AIL_sequence_ms_position(HSEQUENCE S, //) - S32 FAR *total_milliseconds, - S32 FAR *current_milliseconds); - - - -// -// red book functions -// - -#ifdef IS_DOS -typedef struct _REDBOOKTRACKINFO { - U32 tracks; - U32 trackstarts[100]; -} REDBOOKTRACKINFO; -#endif - -typedef struct _REDBOOK { - U32 DeviceID; - U32 paused; - U32 pausedsec; - U32 lastendsec; -#ifdef IS_DOS - U32 readcontents; - REDBOOKTRACKINFO info; -#endif -#ifdef IS_MAC - short vDRefNum; -#endif -} REDBOOK; - -typedef struct _REDBOOK FAR* HREDBOOK; - -#define REDBOOK_ERROR 0 -#define REDBOOK_PLAYING 1 -#define REDBOOK_PAUSED 2 -#define REDBOOK_STOPPED 3 - - -DXDEC HREDBOOK AILCALL AIL_redbook_open(U32 which); - -#ifdef IS_MAC -DXDEC HREDBOOK AILCALL AIL_redbook_open_volume(char const * drive); -#else -DXDEC HREDBOOK AILCALL AIL_redbook_open_drive(S32 drive); -#endif - -DXDEC void AILCALL AIL_redbook_close(HREDBOOK hand); - -DXDEC void AILCALL AIL_redbook_eject(HREDBOOK hand); - -DXDEC void AILCALL AIL_redbook_retract(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_status(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_tracks(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_track(HREDBOOK hand); - -DXDEC void AILCALL AIL_redbook_track_info(HREDBOOK hand,U32 tracknum, - U32 FAR* startmsec,U32 FAR* endmsec); - -DXDEC U32 AILCALL AIL_redbook_id(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_position(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_play(HREDBOOK hand,U32 startmsec, U32 endmsec); - -DXDEC U32 AILCALL AIL_redbook_stop(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_pause(HREDBOOK hand); - -DXDEC U32 AILCALL AIL_redbook_resume(HREDBOOK hand); - -DXDEC S32 AILCALL AIL_redbook_volume(HREDBOOK hand); - -DXDEC S32 AILCALL AIL_redbook_set_volume(HREDBOOK hand, S32 volume); - -#ifdef IS_WIN16 - #define AIL_ms_count timeGetTime - DXDEC U32 AILCALL AIL_us_count(void); -#else - DXDEC U32 AILCALL AIL_ms_count(void); - DXDEC U32 AILCALL AIL_us_count(void); -#endif - - -typedef struct _STREAM FAR* HSTREAM; // Handle to stream - -typedef void (AILCALLBACK FAR* AILSTREAMCB) (HSTREAM stream); - -typedef struct _STREAM { - - S32 block_oriented; // 1 if this is an ADPCM or ASI-compressed stream - S32 using_ASI; // 1 if using ASI decoder to uncompress stream data - ASISTAGE FAR *ASI; // handy pointer to our ASI coded - - HSAMPLE samp; // the sample handle - - U32 fileh; // the open file handle - - U8 FAR* bufs[3]; // the data buffers - U32 bufsizes[3]; // the size of each buffer - S32 reset_ASI[3]; // should we reset the ASI at the end of the buffer? - S32 bufstart[3]; // offset of where this buffer started - void FAR* asyncs[3];// async read structures - - S32 loadedbufstart[2]; // offset of where the loaded buffer started - S32 loadedorder[2]; // order of the buffers as they were loaded - S32 loadorder; // incremented as each buffer is loaded - - S32 bufsize; // size of each buffer - S32 readsize; // size of each read block - - U32 buf1; // 0,1,2 (current buffer that we are reading into) - S32 size1; // holds the current amount of data read - - U32 buf2; // 0,1,2 (the next buffer that we are reading into) - S32 size2; // next buffer loaded up to - - U32 buf3; // 0,1,2 (the next buffer that we are reading into) - S32 size3; // next buffer loaded up to - - U32 datarate; // datarate in bytes per second - S32 filerate; // original datarate of the file - S32 filetype; // file format type - U32 fileflags; // file format flags (signed or unsigned) - S32 totallen; // total length of the sound data - - S32 substart; // subblock loop start - S32 sublen; // subblock loop len - S32 subpadding; // amount to pad the final block - - U32 blocksize; // ADPCM block size - S32 padding; // padding to be done - S32 padded; // padding done - - S32 loadedsome; // have we done any loads? - - U32 startpos; // point that the sound data begins - U32 totalread; // total bytes read from the disk - - U32 loopsleft; // how many loops are left - - U32 error; // read error has occurred - - S32 preload; // preload the file into the first buffer - U32 preloadpos; // position to use in preload - S32 noback; // no background processing - S32 alldone; // alldone - S32 primeamount; // amount to load after a seek - S32 readatleast; // forced amount to read on next service - - S32 playcontrol; // control: 0=stopped, 1=started, |8=paused, |16=sample paused - - AILSTREAMCB callback; // end of stream callback - - S32 user_data[8]; // Miscellaneous user data - void FAR* next; // pointer to next stream - -#if defined(IS_WINDOWS) || defined(IS_MAC) - S32 autostreaming; // are we autostreaming this stream -#endif - -#ifdef IS_WINDOWS - S32 cb_IsWin32s; // Is the callback win32s? -#endif - - S32 docallback; // set when it time to poll for a callback - -#ifdef IS_MAC - IOParam stream_param; - S32 donext; - S32 donext1; - U32 fillup; - U32 session; - U32 tamt; - U32 buf; - S32* size; - S32* done; - S32 done1; - S32 done2; - S32 done3; - Boolean force_quit; -#endif - -} MSTREAM_TYPE; - - -DXDEC HSTREAM AILCALL AIL_open_stream(HDIGDRIVER dig, char const FAR * filename, S32 stream_mem); - -DXDEC void AILCALL AIL_close_stream(HSTREAM stream); - -DXDEC S32 AILCALL AIL_service_stream(HSTREAM stream, S32 fillup); - -DXDEC void AILCALL AIL_start_stream(HSTREAM stream); - -DXDEC void AILCALL AIL_pause_stream(HSTREAM stream, S32 onoff); - -DXDEC void AILCALL AIL_set_stream_volume(HSTREAM stream,S32 volume); - -DXDEC void AILCALL AIL_set_stream_pan(HSTREAM stream,S32 pan); - -DXDEC S32 AILCALL AIL_stream_volume(HSTREAM stream); - -DXDEC S32 AILCALL AIL_stream_pan(HSTREAM stream); - -DXDEC void AILCALL AIL_set_stream_playback_rate(HSTREAM stream, S32 rate); - -DXDEC S32 AILCALL AIL_stream_playback_rate(HSTREAM stream); - -DXDEC S32 AILCALL AIL_stream_loop_count(HSTREAM stream); - -DXDEC void AILCALL AIL_set_stream_loop_count(HSTREAM stream, S32 count); - -DXDEC void AILCALL AIL_set_stream_loop_block (HSTREAM S, - S32 loop_start_offset, - S32 loop_end_offset); - -DXDEC S32 AILCALL AIL_stream_status(HSTREAM stream); - -DXDEC void AILCALL AIL_set_stream_position(HSTREAM stream,S32 offset); - -DXDEC S32 AILCALL AIL_stream_position(HSTREAM stream); - -DXDEC void AILCALL AIL_stream_info(HSTREAM stream, S32 FAR* datarate, S32 FAR* sndtype, S32 FAR* length, S32 FAR* memory); - -DXDEC AILSTREAMCB AILCALL AIL_register_stream_callback(HSTREAM stream, AILSTREAMCB callback); - -DXDEC void AILCALL AIL_auto_service_stream(HSTREAM stream, S32 onoff); - -DXDEC void AILCALL AIL_set_stream_user_data (HSTREAM S, - U32 index, - S32 value); - -DXDEC S32 AILCALL AIL_stream_user_data (HSTREAM S, - U32 index); - -DXDEC void AILCALL AIL_set_stream_ms_position (HSTREAM S, - S32 milliseconds); - -DXDEC void AILCALL AIL_stream_ms_position (HSTREAM S, //) - S32 FAR * total_milliseconds, - S32 FAR * current_milliseconds); - -DXDEC void AILCALL AIL_set_stream_reverb(HSTREAM S, - F32 reverb_level, - F32 reverb_reflect_time, - F32 reverb_decay_time); - -DXDEC void AILCALL AIL_stream_reverb (HSTREAM S, - F32 FAR *reverb_level, - F32 FAR *reverb_reflect_time, - F32 FAR *reverb_decay_time); - -DXDEC HPROVIDER AILCALL AIL_set_stream_processor (HSTREAM S, - SAMPLESTAGE pipeline_stage, - HPROVIDER provider); - -#ifdef IS_MAC -typedef struct MSS_FILE -{ - S32 file_type; // 0 = char*, 1 = FSSpec* - void const FAR* file; -} MSS_FILE; -#else -typedef char MSS_FILE; -#endif - -typedef U32 (AILCALLBACK FAR*AIL_file_open_callback) (MSS_FILE const FAR* Filename, - U32 FAR* FileHandle); - -typedef void (AILCALLBACK FAR*AIL_file_close_callback) (U32 FileHandle); - -#define AIL_FILE_SEEK_BEGIN 0 -#define AIL_FILE_SEEK_CURRENT 1 -#define AIL_FILE_SEEK_END 2 - -typedef S32 (AILCALLBACK FAR*AIL_file_seek_callback) (U32 FileHandle, - S32 Offset, - U32 Type); - -typedef U32 (AILCALLBACK FAR*AIL_file_read_callback) (U32 FileHandle, - void FAR* Buffer, - U32 Bytes); - -DXDEC void AILCALL AIL_set_file_callbacks (AIL_file_open_callback opencb, - AIL_file_close_callback closecb, - AIL_file_seek_callback seekcb, - AIL_file_read_callback readcb); - -#ifdef IS_32 - -typedef void FAR* (AILCALLBACK FAR*AIL_file_async_read_callback) (U32 FileHandle, - void FAR* Buffer, - U32 Bytes); - -typedef S32 (AILCALLBACK FAR*AIL_file_async_status_callback) (void FAR* async, - S32 wait, - U32 FAR* BytesRead); - -DXDEC void AILCALL AIL_set_file_async_callbacks (AIL_file_open_callback opencb, - AIL_file_close_callback closecb, - AIL_file_seek_callback seekcb, - AIL_file_async_read_callback areadcb, - AIL_file_async_status_callback statuscb); - -#endif - -// -// High-level DLS functions -// - -typedef struct _DLSFILEID { - S32 id; - struct _DLSFILEID FAR* next; -} DLSFILEID; - -typedef struct _DLSFILEID FAR* HDLSFILEID; - -typedef struct _DLSDEVICE { - void FAR* pGetPref; - void FAR* pSetPref; - void FAR* pMSSOpen; - void FAR* pOpen; - void FAR* pClose; - void FAR* pLoadFile; - void FAR* pLoadMem; - void FAR* pUnloadFile; - void FAR* pUnloadAll; - void FAR* pGetInfo; - void FAR* pCompact; - void FAR* pSetAttr; - S32 DLSHandle; - U32 format; - U32 buffer_size; - void FAR* buffer[2]; - HSAMPLE sample; - HMDIDRIVER mdi; - HDIGDRIVER dig; - HDLSFILEID first; -#ifdef IS_WINDOWS - HMODULE lib; -#else - #ifdef IS_DOS - char FAR* DOSname; - #endif -#endif -} DLSDEVICE; - -typedef struct _DLSDEVICE FAR* HDLSDEVICE; - -typedef struct _AILDLSINFO { - char Description[128]; - S32 MaxDLSMemory; - S32 CurrentDLSMemory; - S32 LargestSize; - S32 GMAvailable; - S32 GMBankSize; -} AILDLSINFO; - -#ifdef IS_DOS - -typedef struct _AILDOSDLS { - char FAR* description; - void FAR* pDLSOpen; - void FAR* pMSSOpen; - void FAR* pOpen; - void FAR* pClose; - void FAR* pLoadFile; - void FAR* pLoadMem; - void FAR* pUnloadFile; - void FAR* pUnloadAll; - void FAR* pGetInfo; - void FAR* pCompact; - void FAR* pSetAttr; -} AILDOSDLS; - -#endif - - -DXDEC HDLSDEVICE AILCALL AIL_DLS_open(HMDIDRIVER mdi, HDIGDRIVER dig, -#if defined(IS_WINDOWS) || defined(IS_MAC) - char const FAR * libname, -#else - AILDOSDLS const FAR * dosdls, -#endif - U32 flags, U32 rate, S32 bits, S32 channels); - -// -// Parameters for the dwFlag used in DLSClose() and flags in AIL_DLS_close -// - -#define RETAIN_DLS_COLLECTION 0x00000001 -#define RETURN_TO_BOOTUP_STATE 0x00000002 -#define RETURN_TO_GM_ONLY_STATE 0x00000004 -#define DLS_COMPACT_MEMORY 0x00000008 - -DXDEC void AILCALL AIL_DLS_close(HDLSDEVICE dls, U32 flags); - -DXDEC HDLSFILEID AILCALL AIL_DLS_load_file(HDLSDEVICE dls, char const FAR* filename, U32 flags); - -DXDEC HDLSFILEID AILCALL AIL_DLS_load_memory(HDLSDEVICE dls, void const FAR* memfile, U32 flags); - -// -// other parameters for AIL_DLS_unload -// - -#define AIL_DLS_UNLOAD_MINE 0 -#define AIL_DLS_UNLOAD_ALL ((HDLSFILEID)(U32)(S32)-1) - -DXDEC void AILCALL AIL_DLS_unload(HDLSDEVICE dls, HDLSFILEID dlsid); - -DXDEC void AILCALL AIL_DLS_compact(HDLSDEVICE dls); - -DXDEC void AILCALL AIL_DLS_get_info(HDLSDEVICE dls, AILDLSINFO FAR* info, S32 FAR* PercentCPU); - -DXDEC void AILCALL AIL_DLS_set_reverb(HDLSDEVICE dls, - F32 reverb_level, - F32 reverb_reflect_time, - F32 reverb_decay_time); - -DXDEC void AILCALL AIL_DLS_get_reverb(HDLSDEVICE dls, - F32 FAR* reverb_level, - F32 FAR* reverb_reflect_time, - F32 FAR* reverb_decay_time); - -DXDEC HPROVIDER AILCALL AIL_set_DLS_processor (HDLSDEVICE dev, - SAMPLESTAGE pipeline_stage, - HPROVIDER provider); - - -// -// Quick-integration service functions and data types -// - -typedef struct -{ - U32 const FAR *data; - S32 size; - S32 type; - void FAR *handle; - S32 status; - void FAR* next; - S32 speed; - S32 volume; - S32 extravol; - F32 rlevel; - F32 rrtime; - F32 rdtime; - HDLSFILEID dlsid; - void FAR* dlsmem; - void FAR* dlsmemunc; - S32 milliseconds; - S32 length; - S32 userdata; -} -AUDIO_TYPE; - - -#define QSTAT_DONE 1 // Data has finished playing -#define QSTAT_LOADED 2 // Data has been loaded, but not yet played -#define QSTAT_PLAYING 3 // Data is currently playing - -typedef AUDIO_TYPE FAR * HAUDIO; // Generic handle to any audio data type - -#define AIL_QUICK_USE_WAVEOUT 2 -#define AIL_QUICK_MIDI_AND_DLS 2 -#define AIL_QUICK_DLS_ONLY 3 -#define AIL_QUICK_MIDI_AND_VORTEX_DLS 4 -#define AIL_QUICK_MIDI_AND_SONICVIBES_DLS 5 - -DXDEC S32 AILCALL -#if defined(IS_WINDOWS) || defined(IS_MAC) - AIL_quick_startup ( -#else - AIL_quick_startup_with_start(void* startup, -#endif - S32 use_digital, - S32 use_MIDI, - U32 output_rate, - S32 output_bits, - S32 output_channels); - -DXDEC void AILCALL AIL_quick_shutdown (void); - -DXDEC void AILCALL AIL_quick_handles (HDIGDRIVER FAR* pdig, - HMDIDRIVER FAR* pmdi, - HDLSDEVICE FAR* pdls ); - -DXDEC HAUDIO AILCALL AIL_quick_load (char const FAR *filename); - -#ifdef IS_MAC -DXDEC HAUDIO AILCALL AIL_quick_fss_load (FSSpec const FAR *filename); -#endif - -DXDEC HAUDIO AILCALL AIL_quick_load_mem (void const FAR *mem, - U32 size); - -DXDEC HAUDIO AILCALL AIL_quick_copy (HAUDIO audio); - -DXDEC void AILCALL AIL_quick_unload (HAUDIO audio); - -DXDEC S32 AILCALL AIL_quick_play (HAUDIO audio, - U32 loop_count); - -DXDEC void AILCALL AIL_quick_halt (HAUDIO audio); - -DXDEC S32 AILCALL AIL_quick_status (HAUDIO audio); - -DXDEC HAUDIO AILCALL AIL_quick_load_and_play (char const FAR *filename, - U32 loop_count, - S32 wait_request); - -#ifdef IS_MAC -DXDEC HAUDIO AILCALL AIL_quick_fss_load_and_play (FSSpec const FAR *filename, - U32 loop_count, - S32 wait_request); -#endif - -DXDEC void AILCALL AIL_quick_set_speed (HAUDIO audio, S32 speed); - -DXDEC void AILCALL AIL_quick_set_volume (HAUDIO audio, S32 volume, S32 extravol); - -DXDEC void AILCALL AIL_quick_set_reverb (HAUDIO audio, - F32 reverb_level, - F32 reverb_reflect_time, - F32 reverb_decay_time); - -DXDEC void AILCALL AIL_quick_set_ms_position(HAUDIO audio,S32 milliseconds); - -DXDEC S32 AILCALL AIL_quick_ms_position(HAUDIO audio); - -DXDEC S32 AILCALL AIL_quick_ms_length(HAUDIO audio); - - -#define AIL_QUICK_XMIDI_TYPE 1 -#define AIL_QUICK_DIGITAL_TYPE 2 -#define AIL_QUICK_DLS_XMIDI_TYPE 3 -#define AIL_QUICK_MPEG_DIGITAL_TYPE 4 - -DXDEC S32 AILCALL AIL_quick_type(HAUDIO audio); - -// -// used for AIL_process -// - -typedef struct _AILMIXINFO { - AILSOUNDINFO Info; - ADPCMDATA mss_adpcm; - U32 src_fract; - S32 left_val; - S32 right_val; -} AILMIXINFO; - - - -DXDEC S32 AILCALL AIL_WAV_info(void const FAR* data, AILSOUNDINFO FAR* info); - -DXDEC S32 AILCALL AIL_size_processed_digital_audio( - U32 dest_rate, - U32 dest_format, - S32 num_srcs, - AILMIXINFO const FAR* src); - -DXDEC S32 AILCALL AIL_process_digital_audio( - void FAR *dest_buffer, - S32 dest_buffer_size, - U32 dest_rate, - U32 dest_format, - S32 num_srcs, - AILMIXINFO FAR* src); - -#define AIL_LENGTHY_INIT 0 -#define AIL_LENGTHY_SET_PREFERENCE 1 -#define AIL_LENGTHY_UPDATE 2 -#define AIL_LENGTHY_DONE 3 - -typedef S32 (AILCALLBACK FAR* AILLENGTHYCB)(U32 state,U32 user); - -typedef S32 (AILCALLBACK FAR* AILCODECSETPREF)(char const FAR* preference,U32 value); - -DXDEC S32 AILCALL AIL_compress_ASI(AILSOUNDINFO const FAR * info, //) - char const FAR* filename_ext, - void FAR* FAR* outdata, - U32 FAR* outsize, - AILLENGTHYCB callback); - -DXDEC S32 AILCALL AIL_decompress_ASI(void const FAR* indata, //) - U32 insize, - char const FAR* filename_ext, - void FAR* FAR* wav, - U32 FAR* wavsize, - AILLENGTHYCB callback); - -DXDEC S32 AILCALL AIL_compress_ADPCM(AILSOUNDINFO const FAR * info, - void FAR* FAR* outdata, U32 FAR* outsize); - -DXDEC S32 AILCALL AIL_decompress_ADPCM(AILSOUNDINFO const FAR * info, - void FAR* FAR* outdata, U32 FAR* outsize); - -DXDEC S32 AILCALL AIL_compress_DLS(void const FAR* dls, - char const FAR* compression_extension, - void FAR* FAR* mls, U32 FAR* mlssize, - AILLENGTHYCB callback); - -DXDEC S32 AILCALL AIL_merge_DLS_with_XMI(void const FAR* xmi, void const FAR* dls, - void FAR* FAR* mss, U32 FAR* msssize); - -DXDEC S32 AILCALL AIL_extract_DLS( void const FAR *source_image, //) - U32 source_size, - void FAR * FAR *XMI_output_data, - U32 FAR *XMI_output_size, - void FAR * FAR *DLS_output_data, - U32 FAR *DLS_output_size, - AILLENGTHYCB callback); - -#define AILFILTERDLS_USINGLIST 1 - -DXDEC S32 AILCALL AIL_filter_DLS_with_XMI(void const FAR* xmi, void const FAR* dls, - void FAR* FAR* dlsout, U32 FAR* dlssize, - S32 flags, AILLENGTHYCB callback); - -#define AILMIDITOXMI_USINGLIST 1 -#define AILMIDITOXMI_TOLERANT 2 - -DXDEC S32 AILCALL AIL_MIDI_to_XMI (void const FAR* MIDI, - U32 MIDI_size, - void FAR* FAR*XMIDI, - U32 FAR* XMIDI_size, - S32 flags); - -#define AILMIDILIST_ROLANDSYSEX 1 -#define AILMIDILIST_ROLANDUN 2 -#define AILMIDILIST_ROLANDAB 4 - -DXDEC S32 AILCALL AIL_list_MIDI (void const FAR* MIDI, - U32 MIDI_size, - char FAR* FAR* lst, - U32 FAR* lst_size, - S32 flags); -#define AILDLSLIST_ARTICULATION 1 -#define AILDLSLIST_DUMP_WAVS 2 - -DXDEC S32 AILCALL AIL_list_DLS (void const FAR* DLS, - char FAR* FAR* lst, - U32 FAR* lst_size, - S32 flags, - C8 FAR* title); - -#define AILFILETYPE_UNKNOWN 0 -#define AILFILETYPE_PCM_WAV 1 -#define AILFILETYPE_ADPCM_WAV 2 -#define AILFILETYPE_OTHER_WAV 3 -#define AILFILETYPE_VOC 4 -#define AILFILETYPE_MIDI 5 -#define AILFILETYPE_XMIDI 6 -#define AILFILETYPE_XMIDI_DLS 7 -#define AILFILETYPE_XMIDI_MLS 8 -#define AILFILETYPE_DLS 9 -#define AILFILETYPE_MLS 10 -#define AILFILETYPE_MPEG_L1_AUDIO 11 -#define AILFILETYPE_MPEG_L2_AUDIO 12 -#define AILFILETYPE_MPEG_L3_AUDIO 13 -#define AILFILETYPE_OTHER_ASI_WAV 14 - - -DXDEC S32 AILCALL AIL_file_type(void const FAR* data, U32 size); - -DXDEC S32 AILCALL AIL_find_DLS (void const FAR* data, U32 size, - void FAR* FAR* xmi, U32 FAR* xmisize, - void FAR* FAR* dls, U32 FAR* dlssize); - -#if defined(IS_WIN32) || defined(IS_MAC) - -// -// Auxiliary 2D interface calls -// - -DXDEC HDIGDRIVER AILCALL AIL_primary_digital_driver (HDIGDRIVER new_primary); - -// -// Filter result codes -// - -typedef S32 FLTRESULT; - -#define FLT_NOERR 0 // Success -- no error -#define FLT_NOT_ENABLED 1 // FLT not enabled -#define FLT_ALREADY_STARTED 2 // FLT already started -#define FLT_INVALID_PARAM 3 // Invalid parameters used -#define FLT_INTERNAL_ERR 4 // Internal error in FLT driver -#define FLT_OUT_OF_MEM 5 // Out of system RAM -#define FLT_ERR_NOT_IMPLEMENTED 6 // Feature not implemented -#define FLT_NOT_FOUND 7 // FLT supported device not found -#define FLT_NOT_INIT 8 // FLT not initialized -#define FLT_CLOSE_ERR 9 // FLT not closed correctly - -//############################################################################ -//## ## -//## Interface "MSS pipeline filter" ## -//## ## -//############################################################################ - -typedef FLTRESULT (AILCALL FAR *FLT_STARTUP)(void); - -typedef FLTRESULT (AILCALL FAR *FLT_SHUTDOWN)(void); - -typedef C8 FAR * (AILCALL FAR *FLT_ERROR)(void); - -typedef S32 (AILCALL FAR *FLT_SET_PROVIDER_PREFERENCE)(HATTRIB preference, - void const FAR* value); - -typedef HDRIVERSTATE (AILCALL FAR *FLT_OPEN_DRIVER) (HDIGDRIVER dig, - S32 FAR *build_buffer, - S32 build_buffer_size); - -typedef FLTRESULT (AILCALL FAR *FLT_CLOSE_DRIVER) (HDRIVERSTATE state); - -typedef void (AILCALL FAR *FLT_PREMIX_PROCESS) (HDRIVERSTATE driver -#ifdef IS_MAC - ,U32 buffer_size -#endif -); - -typedef void (AILCALL FAR *FLT_POSTMIX_PROCESS) (HDRIVERSTATE driver -#ifdef IS_MAC - ,U32 buffer_size -#endif -); - -//############################################################################ -//## ## -//## Interface "Pipeline filter sample services" ## -//## ## -//############################################################################ - -typedef HSAMPLESTATE (AILCALL FAR * FLTSMP_OPEN_SAMPLE) (HDRIVERSTATE driver, - HSAMPLE S); - -typedef FLTRESULT (AILCALL FAR * FLTSMP_CLOSE_SAMPLE) (HSAMPLESTATE state); - -typedef S32 (AILCALL FAR * FLTSMP_SAMPLE_PROCESS) (HSAMPLESTATE state, - void const FAR * FAR *orig_src, - U32 FAR * orig_src_fract, - void FAR * orig_src_end, - S32 FAR * FAR *build_dest, - void FAR * build_dest_end, - S32 FAR * left_val, - S32 FAR * right_val, - S32 playback_ratio, - S32 left_scale, - S32 right_scale, - S32 base_scale, - MIXSTAGE FAR * mixer_provider, - U32 mixer_operation); - -typedef S32 (AILCALL FAR * FLTSMP_SAMPLE_ATTRIBUTE) (HSAMPLESTATE state, - HATTRIB attribute); - -typedef S32 (AILCALL FAR * FLTSMP_SET_SAMPLE_PREFERENCE) (HSAMPLESTATE state, - HATTRIB preference, - void const FAR* value); - -// -// Pipeline filter calls -// - -DXDEC S32 AILCALL AIL_enumerate_filters (HPROENUM FAR *next, - HPROVIDER FAR *dest, - C8 FAR * FAR *name); - -DXDEC HDRIVERSTATE - AILCALL AIL_open_filter (HPROVIDER lib, - HDIGDRIVER dig); - -DXDEC void AILCALL AIL_close_filter (HDRIVERSTATE filter); - -DXDEC S32 AILCALL AIL_enumerate_filter_attributes - (HPROVIDER lib, - HINTENUM FAR * next, - RIB_INTERFACE_ENTRY FAR * dest); - -DXDEC void AILCALL AIL_filter_attribute (HPROVIDER lib, - C8 const FAR* name, - void FAR * val); - -DXDEC void AILCALL AIL_set_filter_preference - (HPROVIDER lib, - C8 const FAR* name, - void const FAR* val); - -DXDEC S32 AILCALL AIL_enumerate_filter_sample_attributes - (HPROVIDER lib, - HINTENUM FAR * next, - RIB_INTERFACE_ENTRY FAR * dest); - -DXDEC void AILCALL AIL_filter_sample_attribute - (HSAMPLE S, - C8 const FAR* name, - void FAR * val); - -DXDEC void AILCALL AIL_filter_stream_attribute - (HSTREAM S, - C8 const FAR* name, - void FAR* val); - -DXDEC void AILCALL AIL_filter_DLS_attribute - (HDLSDEVICE dls, - C8 const FAR* name, - void FAR * val); - -DXDEC void AILCALL AIL_set_filter_sample_preference - (HSAMPLE S, - C8 const FAR * name, - void const FAR * val); - -DXDEC void AILCALL AIL_set_filter_stream_preference - (HSTREAM S, - C8 const FAR * name, - void const FAR * val); - -DXDEC void AILCALL AIL_set_filter_DLS_preference - (HDLSDEVICE dls, - C8 const FAR * name, - void const FAR * val); - -typedef struct _FLTPROVIDER -{ - PROVIDER_QUERY_ATTRIBUTE PROVIDER_query_attribute; - - FLT_STARTUP startup; - FLT_ERROR error; - FLT_SHUTDOWN shutdown; - FLT_SET_PROVIDER_PREFERENCE set_provider_preference; - FLT_OPEN_DRIVER open_driver; - FLT_CLOSE_DRIVER close_driver; - FLT_PREMIX_PROCESS premix_process; - FLT_POSTMIX_PROCESS postmix_process; - - FLTSMP_OPEN_SAMPLE open_sample; - FLTSMP_CLOSE_SAMPLE close_sample; - FLTSMP_SAMPLE_PROCESS sample_process; - FLTSMP_SAMPLE_ATTRIBUTE sample_attribute; - FLTSMP_SET_SAMPLE_PREFERENCE set_sample_preference; - - HDIGDRIVER dig; - HPROVIDER provider; - HDRIVERSTATE driver_state; - - struct _FLTPROVIDER FAR *next; -} -FLTPROVIDER; - -// -// 3D provider calls -// - -DXDEC S32 AILCALL AIL_enumerate_3D_providers (HPROENUM FAR *next, - HPROVIDER FAR *dest, - C8 FAR * FAR *name); - -DXDEC M3DRESULT AILCALL AIL_open_3D_provider (HPROVIDER lib); - -DXDEC void AILCALL AIL_close_3D_provider (HPROVIDER lib); - -DXDEC S32 AILCALL AIL_enumerate_3D_provider_attributes - (HPROVIDER lib, - HINTENUM FAR * next, - RIB_INTERFACE_ENTRY FAR * dest); - -DXDEC void AILCALL AIL_3D_provider_attribute (HPROVIDER lib, - C8 const FAR* name, - void FAR * val); - -DXDEC void AILCALL AIL_set_3D_provider_preference(HPROVIDER lib, - C8 const FAR* name, - void const FAR* val); - -struct H3D -{ - H3DPOBJECT actual; - HPROVIDER owner; - S32 user_data[8]; -}; - -typedef struct _M3DPROVIDER -{ - PROVIDER_QUERY_ATTRIBUTE PROVIDER_query_attribute; - M3D_STARTUP startup; - M3D_ERROR error; - M3D_SHUTDOWN shutdown; - M3D_SET_PROVIDER_PREFERENCE set_provider_preference; - M3D_ACTIVATE activate; - M3D_ALLOCATE_3D_SAMPLE_HANDLE allocate_3D_sample_handle; - M3D_RELEASE_3D_SAMPLE_HANDLE release_3D_sample_handle; - M3D_START_3D_SAMPLE start_3D_sample; - M3D_STOP_3D_SAMPLE stop_3D_sample; - M3D_RESUME_3D_SAMPLE resume_3D_sample; - M3D_END_3D_SAMPLE end_3D_sample; - M3D_SET_3D_SAMPLE_DATA set_3D_sample_data; - M3D_SET_3D_SAMPLE_VOLUME set_3D_sample_volume; - M3D_SET_3D_SAMPLE_PLAYBACK_RATE set_3D_sample_playback_rate; - M3D_SET_3D_SAMPLE_OFFSET set_3D_sample_offset; - M3D_SET_3D_SAMPLE_LOOP_COUNT set_3D_sample_loop_count; - M3D_SET_3D_SAMPLE_LOOP_BLOCK set_3D_sample_loop_block; - M3D_3D_SAMPLE_STATUS sample_status; - M3D_3D_SAMPLE_VOLUME sample_volume; - M3D_3D_SAMPLE_PLAYBACK_RATE sample_playback_rate; - M3D_3D_SAMPLE_OFFSET sample_offset; - M3D_3D_SAMPLE_LENGTH sample_length; - M3D_3D_SAMPLE_LOOP_COUNT sample_loop_count; - M3D_SET_3D_SAMPLE_DISTANCES set_3D_sample_distances; - M3D_3D_SAMPLE_DISTANCES sample_distances; - M3D_ACTIVE_3D_SAMPLE_COUNT active_3D_sample_count; - M3D_3D_OPEN_LISTENER open_listener; - M3D_3D_CLOSE_LISTENER close_listener; - M3D_3D_OPEN_OBJECT open_object; - M3D_3D_CLOSE_OBJECT close_object; - M3D_SET_3D_POSITION set_3D_position; - M3D_SET_3D_VELOCITY set_3D_velocity; - M3D_SET_3D_VELOCITY_VECTOR set_3D_velocity_vector; - M3D_SET_3D_ORIENTATION set_3D_orientation; - M3D_3D_POSITION position; - M3D_3D_VELOCITY velocity; - M3D_3D_ORIENTATION orientation; - M3D_3D_UPDATE_POSITION update_position; - M3D_3D_AUTO_UPDATE_POSITION auto_update_position; - M3D_3D_SAMPLE_ATTRIBUTE sample_query_attribute; - M3D_3D_SET_SAMPLE_PREFERENCE set_sample_preference; - M3D_3D_ROOM_TYPE room_type; - M3D_SET_3D_ROOM_TYPE set_3D_room_type; - M3D_3D_SPEAKER_TYPE speaker_type; - M3D_SET_3D_SPEAKER_TYPE set_3D_speaker_type; - M3D_SET_3D_SAMPLE_OBSTRUCTION set_3D_sample_obstruction; - M3D_SET_3D_SAMPLE_OCCLUSION set_3D_sample_occlusion; - M3D_SET_3D_SAMPLE_CONE set_3D_sample_cone; - M3D_SET_3D_SAMPLE_EFFECTS_LEVEL set_3D_sample_effects_level; - M3D_3D_SAMPLE_OBSTRUCTION sample_obstruction; - M3D_3D_SAMPLE_OCCLUSION sample_occlusion; - M3D_3D_SAMPLE_CONE sample_cone; - M3D_3D_SAMPLE_EFFECTS_LEVEL sample_effects_level; - M3D_SET_3D_EOS set_3D_EOS; -} M3DPROVIDER; - -// -// Sample calls -// - -DXDEC H3DSAMPLE AILCALL AIL_allocate_3D_sample_handle - (HPROVIDER lib); - - -DXDEC void AILCALL AIL_release_3D_sample_handle - (H3DSAMPLE S); - - -DXDEC void AILCALL AIL_start_3D_sample (H3DSAMPLE S); - - -DXDEC void AILCALL AIL_stop_3D_sample (H3DSAMPLE S); - - -DXDEC void AILCALL AIL_resume_3D_sample (H3DSAMPLE S); - -DXDEC void AILCALL AIL_end_3D_sample (H3DSAMPLE S); - -DXDEC S32 AILCALL AIL_set_3D_sample_file (H3DSAMPLE S, - void const FAR*file_image); - -DXDEC S32 AILCALL AIL_set_3D_sample_info (H3DSAMPLE S, - AILSOUNDINFO const FAR*info); - -DXDEC void AILCALL AIL_set_3D_sample_volume (H3DSAMPLE S, - S32 volume); - -DXDEC void AILCALL AIL_set_3D_sample_offset (H3DSAMPLE S, - U32 offset); - -DXDEC void AILCALL AIL_set_3D_sample_playback_rate - (H3DSAMPLE S, - S32 playback_rate); - -DXDEC void AILCALL AIL_set_3D_sample_loop_count(H3DSAMPLE S, - U32 loops); - -DXDEC void AILCALL AIL_set_3D_sample_loop_block(H3DSAMPLE S, - S32 loop_start_offset, - S32 loop_end_offset); - -DXDEC U32 AILCALL AIL_3D_sample_status (H3DSAMPLE S); - -DXDEC S32 AILCALL AIL_3D_sample_volume (H3DSAMPLE S); - -DXDEC U32 AILCALL AIL_3D_sample_offset (H3DSAMPLE S); - -DXDEC S32 AILCALL AIL_3D_sample_playback_rate (H3DSAMPLE S); - -DXDEC U32 AILCALL AIL_3D_sample_length (H3DSAMPLE S); - -DXDEC U32 AILCALL AIL_3D_sample_loop_count (H3DSAMPLE S); - - -DXDEC S32 AILCALL AIL_3D_room_type (HPROVIDER lib); - -DXDEC void AILCALL AIL_set_3D_room_type (HPROVIDER lib, - S32 room_type); - -#define AIL_3D_2_SPEAKER 0 -#define AIL_3D_HEADPHONE 1 -#define AIL_3D_SURROUND 2 -#define AIL_3D_4_SPEAKER 3 - - -DXDEC S32 AILCALL AIL_3D_speaker_type (HPROVIDER lib); - -DXDEC void AILCALL AIL_set_3D_speaker_type (HPROVIDER lib, - S32 speaker_type); - - -// -// Changed the definition of distances to only be max and min, vs. front -// min/max and back min/max. Only RSX supported the concept of different -// front and distances, so we changed the API to make it more orthogonal -// to most of the 3D providers. Sorry in advance. -// - -DXDEC void AILCALL AIL_set_3D_sample_distances (H3DSAMPLE S, - F32 max_dist, - F32 min_dist); - - -DXDEC void AILCALL AIL_3D_sample_distances (H3DSAMPLE S, - F32 FAR * max_dist, - F32 FAR * min_dist); - -DXDEC S32 AILCALL AIL_active_3D_sample_count (HPROVIDER lib); - -DXDEC S32 AILCALL AIL_enumerate_3D_sample_attributes - (HPROVIDER lib, - HINTENUM FAR * next, - RIB_INTERFACE_ENTRY FAR * dest); - -DXDEC void AILCALL AIL_3D_sample_attribute (H3DSAMPLE samp, - C8 const FAR* name, - void FAR * val); - - -DXDEC void AILCALL AIL_set_3D_sample_preference (H3DSAMPLE samp, - C8 const FAR* name, - void const FAR* val); - -DXDEC void AILCALL AIL_set_3D_sample_obstruction (H3DSAMPLE S, - F32 obstruction); - -DXDEC void AILCALL AIL_set_3D_sample_occlusion (H3DSAMPLE S, - F32 occlusion); - -DXDEC void AILCALL AIL_set_3D_sample_cone (H3DSAMPLE S, - F32 inner_angle, - F32 outer_angle, - S32 outer_volume); - -DXDEC void AILCALL AIL_set_3D_sample_effects_level - (H3DSAMPLE S, - F32 effects_level); - -DXDEC F32 AILCALL AIL_3D_sample_obstruction (H3DSAMPLE S); - -DXDEC F32 AILCALL AIL_3D_sample_occlusion (H3DSAMPLE S); - -DXDEC void AILCALL AIL_3D_sample_cone (H3DSAMPLE S, - F32 FAR* inner_angle, - F32 FAR* outer_angle, - S32 FAR* outer_volume); - -DXDEC F32 AILCALL AIL_3D_sample_effects_level (H3DSAMPLE S); - - -DXDEC AIL3DSAMPLECB AILCALL AIL_register_3D_EOS_callback - (H3DSAMPLE S, - AIL3DSAMPLECB EOS); - - -// -// Positioning-object allocation calls -// - -DXDEC H3DPOBJECT AILCALL AIL_open_3D_listener (HPROVIDER lib); - -DXDEC void AILCALL AIL_close_3D_listener (H3DPOBJECT listener); - -DXDEC H3DPOBJECT AILCALL AIL_open_3D_object (HPROVIDER lib); - -DXDEC void AILCALL AIL_close_3D_object (H3DPOBJECT obj); - -// -// 3D object calls -// - -DXDEC void AILCALL AIL_set_3D_position (H3DPOBJECT obj, - F32 X, - F32 Y, - F32 Z); - -DXDEC void AILCALL AIL_set_3D_velocity (H3DPOBJECT obj, - F32 dX_per_ms, - F32 dY_per_ms, - F32 dZ_per_ms, - F32 magnitude); - -DXDEC void AILCALL AIL_set_3D_velocity_vector (H3DPOBJECT obj, - F32 dX_per_ms, - F32 dY_per_ms, - F32 dZ_per_ms); - -DXDEC void AILCALL AIL_set_3D_orientation (H3DPOBJECT obj, - F32 X_face, - F32 Y_face, - F32 Z_face, - F32 X_up, - F32 Y_up, - F32 Z_up); - -DXDEC void AILCALL AIL_3D_position (H3DPOBJECT obj, - F32 FAR *X, - F32 FAR *Y, - F32 FAR *Z); - -DXDEC void AILCALL AIL_3D_velocity (H3DPOBJECT obj, - F32 FAR *dX_per_ms, - F32 FAR *dY_per_ms, - F32 FAR *dZ_per_ms); - -DXDEC void AILCALL AIL_3D_orientation (H3DPOBJECT obj, - F32 FAR *X_face, - F32 FAR *Y_face, - F32 FAR *Z_face, - F32 FAR *X_up, - F32 FAR *Y_up, - F32 FAR *Z_up); - -DXDEC void AILCALL AIL_update_3D_position (H3DPOBJECT obj, - F32 dt_milliseconds); - -DXDEC void AILCALL AIL_auto_update_3D_position (H3DPOBJECT obj, - S32 enable); - -DXDEC void AILCALL AIL_set_3D_user_data (H3DPOBJECT obj, - U32 index, - S32 value); - -DXDEC S32 AILCALL AIL_3D_user_data (H3DPOBJECT obj, - U32 index); - -// Obsolete 3D function names: -#define AIL_set_3D_object_user_data AIL_set_3D_user_data -#define AIL_3D_object_user_data AIL_3D_user_data -#define AIL_3D_open_listener AIL_open_3D_listener -#define AIL_3D_close_listener AIL_close_3D_listener -#define AIL_3D_open_object AIL_open_3D_object -#define AIL_3D_close_object AIL_close_3D_object - -// -// RAD room types - currently the same as EAX -// - -enum -{ - ENVIRONMENT_GENERIC, // factory default - ENVIRONMENT_PADDEDCELL, - ENVIRONMENT_ROOM, // standard environments - ENVIRONMENT_BATHROOM, - ENVIRONMENT_LIVINGROOM, - ENVIRONMENT_STONEROOM, - ENVIRONMENT_AUDITORIUM, - ENVIRONMENT_CONCERTHALL, - ENVIRONMENT_CAVE, - ENVIRONMENT_ARENA, - ENVIRONMENT_HANGAR, - ENVIRONMENT_CARPETEDHALLWAY, - ENVIRONMENT_HALLWAY, - ENVIRONMENT_STONECORRIDOR, - ENVIRONMENT_ALLEY, - ENVIRONMENT_FOREST, - ENVIRONMENT_CITY, - ENVIRONMENT_MOUNTAINS, - ENVIRONMENT_QUARRY, - ENVIRONMENT_PLAIN, - ENVIRONMENT_PARKINGLOT, - ENVIRONMENT_SEWERPIPE, - ENVIRONMENT_UNDERWATER, - ENVIRONMENT_DRUGGED, - ENVIRONMENT_DIZZY, - ENVIRONMENT_PSYCHOTIC, - - ENVIRONMENT_COUNT // total number of environments -}; - -// -// enumerated values for EAX -// - -#ifndef EAX_H_INCLUDED - -enum -{ - EAX_ENVIRONMENT_GENERIC, // factory default - EAX_ENVIRONMENT_PADDEDCELL, - EAX_ENVIRONMENT_ROOM, // standard environments - EAX_ENVIRONMENT_BATHROOM, - EAX_ENVIRONMENT_LIVINGROOM, - EAX_ENVIRONMENT_STONEROOM, - EAX_ENVIRONMENT_AUDITORIUM, - EAX_ENVIRONMENT_CONCERTHALL, - EAX_ENVIRONMENT_CAVE, - EAX_ENVIRONMENT_ARENA, - EAX_ENVIRONMENT_HANGAR, - EAX_ENVIRONMENT_CARPETEDHALLWAY, - EAX_ENVIRONMENT_HALLWAY, - EAX_ENVIRONMENT_STONECORRIDOR, - EAX_ENVIRONMENT_ALLEY, - EAX_ENVIRONMENT_FOREST, - EAX_ENVIRONMENT_CITY, - EAX_ENVIRONMENT_MOUNTAINS, - EAX_ENVIRONMENT_QUARRY, - EAX_ENVIRONMENT_PLAIN, - EAX_ENVIRONMENT_PARKINGLOT, - EAX_ENVIRONMENT_SEWERPIPE, - EAX_ENVIRONMENT_UNDERWATER, - EAX_ENVIRONMENT_DRUGGED, - EAX_ENVIRONMENT_DIZZY, - EAX_ENVIRONMENT_PSYCHOTIC, - - EAX_ENVIRONMENT_COUNT // total number of environments -}; - -#define EAX_REVERBMIX_USEDISTANCE (-1.0F) - -#endif - -#else - -typedef struct _FLTPROVIDER -{ - U32 junk; -} FLTPROVIDER; - -#endif - -#ifdef __cplusplus -} -#endif - - -#if defined(_PUSHPOP_SUPPORTED) || PRAGMA_STRUCT_PACKPUSH - #pragma pack(pop) -#else - #pragma pack() -#endif - - -#endif + S32 format; + void const *data_ptr; + U32 data_len; + U32 rate; + S32 bits; + S32 channels; + U32 samples; + U32 block_size; + void const *initial_ptr; +} AILSOUNDINFO; + +#define DLLEXPORT extern "C" __declspec(dllexport) + +DLLEXPORT S32 WINAPI AIL_enumerate_3D_providers(HPROENUM *next, HPROVIDER *dest, C8 **name); +DLLEXPORT void WINAPI AIL_release_3D_sample_handle(H3DSAMPLE S); +DLLEXPORT void WINAPI AIL_close_3D_provider(HPROVIDER lib); +DLLEXPORT void WINAPI AIL_set_3D_provider_preference(HPROVIDER lib, C8 const *name, void const *val); +DLLEXPORT M3DRESULT WINAPI AIL_open_3D_provider(HPROVIDER lib); +DLLEXPORT C8 *WINAPI AIL_last_error(void); +DLLEXPORT S32 WINAPI AIL_3D_room_type(HPROVIDER lib); +DLLEXPORT void WINAPI AIL_set_3D_room_type(HPROVIDER lib, S32 room_type); +DLLEXPORT void WINAPI AIL_3D_provider_attribute(HPROVIDER lib, C8 const *name, void *val); +DLLEXPORT H3DSAMPLE WINAPI AIL_allocate_3D_sample_handle(HPROVIDER lib); +DLLEXPORT void WINAPI AIL_set_3D_sample_effects_level(H3DSAMPLE S, F32 effects_level); +DLLEXPORT void WINAPI AIL_set_3D_speaker_type(HPROVIDER lib, S32 speaker_type); +DLLEXPORT HSTREAM WINAPI AIL_open_stream(HDIGDRIVER dig, C8 const *filename, S32 stream_mem); +DLLEXPORT void WINAPI AIL_stream_ms_position(HSTREAM S, S32 *total_milliseconds, S32 *current_milliseconds); +DLLEXPORT void WINAPI AIL_close_stream(HSTREAM stream); +DLLEXPORT S32 WINAPI AIL_digital_handle_release(HDIGDRIVER drvr); +DLLEXPORT S32 WINAPI AIL_digital_handle_reacquire(HDIGDRIVER drvr); +DLLEXPORT C8 *WINAPI AIL_set_redist_directory(C8 const *dir); +DLLEXPORT S32 WINAPI AIL_startup(void); +DLLEXPORT S32 WINAPI AIL_set_preference(U32 number, S32 value); +DLLEXPORT HDIGDRIVER WINAPI AIL_open_digital_driver(U32 frequency, S32 bits, S32 channel, U32 flags); +DLLEXPORT void *WINAPI AIL_mem_alloc_lock(U32 size); +DLLEXPORT HSAMPLE WINAPI AIL_allocate_sample_handle(HDIGDRIVER dig); +DLLEXPORT void WINAPI AIL_init_sample(HSAMPLE S); +DLLEXPORT void WINAPI AIL_set_sample_type(HSAMPLE S, S32 format, U32 flags); +DLLEXPORT void WINAPI AIL_pause_stream(HSTREAM stream, S32 onoff); +DLLEXPORT void WINAPI AIL_release_sample_handle(HSAMPLE S); +DLLEXPORT void WINAPI AIL_mem_free_lock(void *ptr); +DLLEXPORT void WINAPI AIL_close_digital_driver(HDIGDRIVER dig); +DLLEXPORT void WINAPI AIL_shutdown(void); +DLLEXPORT void WINAPI AIL_set_3D_sample_volume(H3DSAMPLE S, S32 volume); +DLLEXPORT void WINAPI AIL_set_sample_volume(HSAMPLE S, S32 volume); +DLLEXPORT void WINAPI AIL_set_sample_address(HSAMPLE S, void const *start, U32 len); +DLLEXPORT S32 WINAPI AIL_set_3D_sample_info(H3DSAMPLE S, AILSOUNDINFO const *info); +DLLEXPORT void WINAPI AIL_set_3D_position(H3DPOBJECT obj, F32 X, F32 Y, F32 Z); +DLLEXPORT void WINAPI AIL_set_3D_sample_distances(H3DSAMPLE S, F32 max_dist, F32 min_dist); +DLLEXPORT void WINAPI AIL_set_sample_pan(HSAMPLE S, S32 pan); +DLLEXPORT void WINAPI AIL_set_sample_playback_rate(HSAMPLE S, S32 playback_rate); +DLLEXPORT void WINAPI AIL_set_3D_sample_playback_rate(H3DSAMPLE S, S32 playback_rate); +DLLEXPORT void WINAPI AIL_set_sample_loop_block(HSAMPLE S, S32 loop_start_offset, S32 loop_end_offset); +DLLEXPORT void WINAPI AIL_set_3D_sample_loop_block(H3DSAMPLE S, S32 loop_start_offset, S32 loop_end_offset); +DLLEXPORT void WINAPI AIL_set_sample_loop_count(HSAMPLE S, S32 loop_count); +DLLEXPORT void WINAPI AIL_set_3D_sample_loop_count(H3DSAMPLE S, S32 loops); +DLLEXPORT U32 WINAPI AIL_sample_status(HSAMPLE S); +DLLEXPORT U32 WINAPI AIL_3D_sample_status(H3DSAMPLE S); +DLLEXPORT void WINAPI AIL_start_sample(HSAMPLE S); +DLLEXPORT void WINAPI AIL_start_3D_sample(H3DSAMPLE S); +DLLEXPORT void WINAPI AIL_end_sample(HSAMPLE S); +DLLEXPORT void WINAPI AIL_end_3D_sample(H3DSAMPLE S); +DLLEXPORT void WINAPI AIL_set_stream_loop_count(HSTREAM stream, S32 count); +DLLEXPORT S32 WINAPI AIL_service_stream(HSTREAM stream, S32 fillup); +DLLEXPORT void WINAPI AIL_start_stream(HSTREAM stream); +DLLEXPORT void WINAPI AIL_set_stream_ms_position(HSTREAM S, S32 milliseconds); +DLLEXPORT void WINAPI AIL_set_stream_volume(HSTREAM stream, S32 volume); +DLLEXPORT void WINAPI AIL_set_stream_pan(HSTREAM stream, S32 pan); +DLLEXPORT S32 WINAPI AIL_stream_status(HSTREAM stream); diff --git a/milessdk/lib/mss32.lib b/milessdk/lib/mss32.lib index 031fd1bd1fb9a99f565c2db10248ed4ce340d9c5..f97091c75ff9988cd906e5e43e56b538c951a428 100644 GIT binary patch literal 15316 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 i23q>*k*v%nS}`yWsVXGb;q6vX1FOCgZF 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 Date: Tue, 21 Apr 2020 13:28:06 +0300 Subject: [PATCH 2/5] Crossplatform work continues --- src/animation/CutsceneMgr.cpp | 3 +- src/audio/sampman.cpp | 1 - src/control/Script.cpp | 1 - src/core/CdStream.cpp | 2 +- src/core/Game.cpp | 2 - src/core/Timer.cpp | 2 +- src/core/re3.cpp | 2 +- src/rw/TexRead.cpp | 3 -- src/save/GenericGameStorage.cpp | 3 +- src/save/PCSave.cpp | 9 ++-- src/skel/crossplatform.cpp | 81 +++++++++++++++++++++++++++++++++ src/skel/crossplatform.h | 65 ++++++++++++++++++++++++++ src/skel/events.cpp | 6 --- src/skel/win/win.cpp | 4 +- src/skel/win/win.h | 11 +++++ 15 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 src/skel/crossplatform.cpp create mode 100644 src/skel/crossplatform.h diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index 6d9b9755..334fe471 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -1,4 +1,3 @@ -#define WITHWINDOWS // just for VK_SPACE #include "common.h" #include "General.h" @@ -416,7 +415,7 @@ CCutsceneMgr::Update(void) || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown()) || CPad::GetPad(0)->GetLeftMouseJustDown() || CPad::GetPad(0)->GetEnterJustDown() - || CPad::GetPad(0)->GetCharJustDown(VK_SPACE)) + || CPad::GetPad(0)->GetCharJustDown(' ')) FinishCutscene(); } } diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp index a375b847..43d3835d 100644 --- a/src/audio/sampman.cpp +++ b/src/audio/sampman.cpp @@ -11,7 +11,6 @@ #include "sampman.h" #include "AudioManager.h" #include "MusicManager.h" -#include "Frontend.h" #include "Timer.h" diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ca676f52..073cb661 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1,7 +1,6 @@ #define WITHWINDOWS // for our script loading hack #include "common.h" - #include "Script.h" #include "ScriptCommands.h" diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp index 1ab1c8b0..ea79fb9a 100644 --- a/src/core/CdStream.cpp +++ b/src/core/CdStream.cpp @@ -1,4 +1,4 @@ -#include +#define WITHWINDOWS #include "common.h" #include "CdStream.h" diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 6f3eee29..bfe6eee3 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -1,7 +1,5 @@ #pragma warning( push ) #pragma warning( disable : 4005) -#define DIRECTINPUT_VERSION 0x0800 -#include #pragma warning( pop ) #include "common.h" #include "win.h" diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index 8f8570d7..aca7c1dc 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -1,4 +1,4 @@ -#include +#define WITHWINDOWS #include "common.h" #include "DMAudio.h" diff --git a/src/core/re3.cpp b/src/core/re3.cpp index e5f42696..0c96b262 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -1,6 +1,6 @@ #include #include -#include +#define WITHWINDOWS #include "common.h" #include "patcher.h" #include "Renderer.h" diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp index 258d520d..d1ff3dc0 100644 --- a/src/rw/TexRead.cpp +++ b/src/rw/TexRead.cpp @@ -1,9 +1,6 @@ #pragma warning( push ) #pragma warning( disable : 4005) -#define DIRECTINPUT_VERSION 0x0800 -#include #pragma warning( pop ) -#define WITHWINDOWS #include "common.h" #include "win.h" diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 5e483dc7..29f666df 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -1,5 +1,6 @@ -#define WITHWINDOWS #include "common.h" +#define USEALTERNATIVEWINFUNCS +#include "crossplatform.h" #include "main.h" #include "AudioScriptObject.h" diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp index 46185850..6f1b1b45 100644 --- a/src/save/PCSave.cpp +++ b/src/save/PCSave.cpp @@ -1,5 +1,6 @@ -#define WITHWINDOWS #include "common.h" +#define USEALTERNATIVEWINFUNCS +#include "crossplatform.h" #include "FileMgr.h" #include "GenericGameStorage.h" @@ -94,7 +95,7 @@ C_PcSave::PopulateSlotInfo() struct { int size; wchar FileName[24]; - _SYSTEMTIME SaveDateTime; + SYSTEMTIME SaveDateTime; } header; sprintf(savename, "%s%i%s", DefaultPCSaveFileName, i + 1, ".b"); int file = CFileMgr::OpenFile(savename, "rb"); @@ -110,8 +111,8 @@ C_PcSave::PopulateSlotInfo() } if (Slots[i + 1] == SLOT_OK) { if (CheckDataNotCorrupt(i, savename)) { - _SYSTEMTIME st; - memcpy(&st, &header.SaveDateTime, sizeof(_SYSTEMTIME)); + SYSTEMTIME st; + memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME)); const char *month; switch (st.wMonth) { diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp new file mode 100644 index 00000000..f9464bb6 --- /dev/null +++ b/src/skel/crossplatform.cpp @@ -0,0 +1,81 @@ +#include "common.h" +#define USEALTERNATIVEWINFUNCS +#include "crossplatform.h" + +// For internal use +// wMilliseconds is not needed +void tmToSystemTime(const tm *tm, SYSTEMTIME *out) { + out->wYear = tm->tm_year + 1900; + out->wMonth = tm->tm_mon + 1; + out->wDayOfWeek = tm->tm_wday; + out->wDay = tm->tm_mday; + out->wHour = tm->tm_hour; + out->wMinute = tm->tm_min; + out->wSecond = tm->tm_sec; +} + +void GetLocalTime_CP(SYSTEMTIME *out) { + time_t timestamp = time(nil); + tm *localTm = localtime(×tamp); + tmToSystemTime(localTm, out); +} + +#if !defined _WIN32 || defined __MINGW32__ +HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { + char newpathname[32]; + strncpy(newpathname, pathname, 32); + char* path = strtok(newpathname, "\\*"); + strncpy(firstfile->folder, path, sizeof(firstfile->folder)); + + // Both w/ extension and w/o extension is ok + if (strlen(path) + 2 != strlen(pathname)) + strncpy(firstfile->extension, strtok(NULL, "\\*"), sizeof(firstfile->extension)); + else + strncpy(firstfile->extension, "", sizeof(firstfile->extension)); + + HANDLE d; + if ((d = opendir(path)) == NULL || !FindNextFile(d, firstfile)) + return NULL; + + return d; +} + +bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) { + dirent *file; + static struct stat fileStats; + static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1]; + int extensionLen = strlen(finddata->extension); + while ((file = readdir(d)) != NULL) { + + // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type. + if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) && + (extensionLen == 0 || strncmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) { + + sprintf(relativepath, "%s/%s", finddata->folder, file->d_name); + realpath(relativepath, path); + stat(path, &fileStats); + strncpy(finddata->cFileName, file->d_name, sizeof(finddata->cFileName)); + finddata->ftLastWriteTime = fileStats.st_mtime; + return true; + } + } + return false; +} + +void GetDateFormat(int unused1, int unused2, SYSTEMTIME* in, int unused3, char* out, int size) { + tm linuxTime; + linuxTime.tm_year = in->wYear - 1900; + linuxTime.tm_mon = in->wMonth - 1; + linuxTime.tm_wday = in->wDayOfWeek; + linuxTime.tm_mday = in->wDay; + linuxTime.tm_hour = in->wHour; + linuxTime.tm_min = in->wMinute; + linuxTime.tm_sec = in->wSecond; + strftime(out, size, nl_langinfo(D_FMT), &linuxTime); +} + +void FileTimeToSystemTime(time_t* writeTime, SYSTEMTIME* out) { + tm *ptm = gmtime(writeTime); + tmToSystemTime(ptm, out); +} +#endif \ No newline at end of file diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h new file mode 100644 index 00000000..1b3ad7d6 --- /dev/null +++ b/src/skel/crossplatform.h @@ -0,0 +1,65 @@ +#include + +#ifndef MAX_PATH + #if !defined _WIN32 || defined __MINGW32__ + #define MAX_PATH PATH_MAX + #else + #define MAX_PATH 260 + #endif +#endif + +// Mostly wrappers around Windows functions + +// TODO: Remove USEALTERNATIVEWINFUNCS and don't use it anywhere when re3 becomes fully cross-platform, this is for testing +// Codes compatible with Windows and Linux +#if defined USEALTERNATIVEWINFUNCS || !defined _WIN32 || defined __MINGW32__ +#define DeleteFile unlink + +// Needed for save games +struct SYSTEMTIME { + uint16 wYear; + uint16 wMonth; + uint16 wDayOfWeek; + uint16 wDay; + uint16 wHour; + uint16 wMinute; + uint16 wSecond; + uint16 wMilliseconds; +}; + +#define GetLocalTime GetLocalTime_CP +#else +#include +#endif + +void GetLocalTime_CP(SYSTEMTIME* out); + + +// Only runs on GNU/POSIX/etc. +#if !defined _WIN32 || defined __MINGW32__ +#define OutputDebugString(s) re3_debug("[DBG-2]: " s "\n") + +#include +#include +#include +#include +#include + +typedef DIR* HANDLE; +#define INVALID_HANDLE_VALUE NULL +#define FindClose closedir +#define LOCALE_USER_DEFAULT 0 +#define DATE_SHORTDATE 0 + +struct WIN32_FIND_DATA { + char extension[32]; // for searching + char folder[32]; // for searching + char cFileName[256]; // because tSkinInfo has it 256 + time_t ftLastWriteTime; +}; + +HANDLE FindFirstFile(char*, WIN32_FIND_DATA*); +bool FindNextFile(HANDLE, WIN32_FIND_DATA*); +void FileTimeToSystemTime(time_t*, SYSTEMTIME*); +void GetDateFormat(int, int, SYSTEMTIME*, int, char*, int); +#endif \ No newline at end of file diff --git a/src/skel/events.cpp b/src/skel/events.cpp index 5d16d5b0..7116833d 100644 --- a/src/skel/events.cpp +++ b/src/skel/events.cpp @@ -2,18 +2,12 @@ #include "skeleton.h" #include "events.h" -//#include "main.h" - #define DIRECTINPUT_VERSION 0x0800 - #include #include "common.h" #include "Pad.h" #include "ControllerConfig.h" #include "Frontend.h" #include "Camera.h" - - - /* ***************************************************************************** */ diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index a534e903..d13d3c52 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1986,7 +1986,7 @@ WinMain(HINSTANCE instance, ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) ++gGameState; - else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) ) + else if ( CPad::GetPad(0)->GetCharJustDown(' ') ) ++gGameState; else if ( CPad::GetPad(0)->GetAltJustDown() ) ++gGameState; @@ -2022,7 +2022,7 @@ WinMain(HINSTANCE instance, ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) ++gGameState; - else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) ) + else if ( CPad::GetPad(0)->GetCharJustDown(' ') ) ++gGameState; else if ( CPad::GetPad(0)->GetAltJustDown() ) ++gGameState; diff --git a/src/skel/win/win.h b/src/skel/win/win.h index ca16c4a0..d6326294 100644 --- a/src/skel/win/win.h +++ b/src/skel/win/win.h @@ -5,6 +5,11 @@ #define RSREGSETBREAKALLOC(_name) /* No op */ #endif /* (!defined(RSREGSETBREAKALLOC)) */ +#ifndef _INC_WINDOWS +#define _X86_ +#include +#endif + enum eGameState { GS_START_UP = 0, @@ -17,7 +22,9 @@ enum eGameState GS_FRONTEND, GS_INIT_PLAYING_GAME, GS_PLAYING_GAME, +#ifndef MASTER GS_ANIMVIEWER, +#endif }; enum eWinVersion @@ -33,6 +40,7 @@ extern DWORD _dwOperatingSystemVersion; extern RwUInt32 gGameState; +#ifdef __DINPUT_INCLUDED__ /* platform specfic global data */ typedef struct { @@ -86,6 +94,7 @@ public: }; extern CJoySticks AllValidWinJoys; +#endif #ifdef __cplusplus extern "C" @@ -97,6 +106,7 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); RwBool IsForegroundApp(); +#ifdef __DINPUT_INCLUDED__ HRESULT _InputInitialise(); HRESULT _InputInitialiseMouse(); HRESULT CapturePad(RwInt32 padID); @@ -110,6 +120,7 @@ BOOL _InputTranslateKey(RsKeyCodes *rs, UINT flag, UINT key); void _InputTranslateShiftKeyUpDown(RsKeyCodes *rs);; BOOL _InputTranslateShiftKey(RsKeyCodes *rs, UINT key, BOOLEAN bDown); BOOL _InputIsExtended(INT flag); +#endif void InitialiseLanguage(); RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode); From 75acd781909378ba0395b0c52acee464c8221e72 Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Thu, 23 Apr 2020 11:24:03 +0300 Subject: [PATCH 3/5] ps2 particles, sampman oal started --- gamefiles/{ => TEXT}/JAPANESE.gxt | Bin gamefiles/{ => TEXT}/american.gxt | Bin gamefiles/{ => TEXT}/french.gxt | Bin gamefiles/{ => TEXT}/german.gxt | Bin gamefiles/{ => TEXT}/italian.gxt | Bin gamefiles/{ => TEXT}/polish.gxt | Bin gamefiles/{ => TEXT}/russian.gxt | Bin gamefiles/{ => TEXT}/spanish.gxt | Bin gamefiles/data/PARTICLE.CFG | 363 ++++ gamefiles/{ => data}/main_d.scm | Bin gamefiles/{ => data}/main_freeroam.scm | Bin gamefiles/{ => models}/fonts_j.txd | Bin gamefiles/{ => models}/fonts_p.txd | Bin gamefiles/{ => models}/fonts_r.txd | Bin gamefiles/{ => models}/menu.txd | Bin src/audio/AudioManager.cpp | 8 +- src/audio/AudioManager.h | 2 +- src/audio/miles/sampman_mss.cpp | 2257 +++++++++++++++++++++++ src/audio/miles/sampman_mss.h | 339 ++++ src/audio/openal/samp_oal.cpp | 1404 +++++++++++++++ src/audio/openal/samp_oal.h | 340 ++++ src/audio/sampman.cpp | 2262 +----------------------- src/audio/sampman.h | 342 +--- src/core/config.h | 5 + src/core/re3.cpp | 1 - src/objects/ParticleObject.cpp | 148 ++ src/peds/Ped.cpp | 113 +- src/render/Particle.cpp | 42 +- src/render/Particle.h | 4 - src/render/ParticleMgr.cpp | 3 +- src/render/ParticleMgr.h | 4 +- src/vehicles/Automobile.cpp | 86 +- src/vehicles/Boat.cpp | 55 +- 33 files changed, 5139 insertions(+), 2639 deletions(-) rename gamefiles/{ => TEXT}/JAPANESE.gxt (100%) rename gamefiles/{ => TEXT}/american.gxt (100%) rename gamefiles/{ => TEXT}/french.gxt (100%) rename gamefiles/{ => TEXT}/german.gxt (100%) rename gamefiles/{ => TEXT}/italian.gxt (100%) rename gamefiles/{ => TEXT}/polish.gxt (100%) rename gamefiles/{ => TEXT}/russian.gxt (100%) rename gamefiles/{ => TEXT}/spanish.gxt (100%) create mode 100644 gamefiles/data/PARTICLE.CFG rename gamefiles/{ => data}/main_d.scm (100%) rename gamefiles/{ => data}/main_freeroam.scm (100%) rename gamefiles/{ => models}/fonts_j.txd (100%) rename gamefiles/{ => models}/fonts_p.txd (100%) rename gamefiles/{ => models}/fonts_r.txd (100%) rename gamefiles/{ => models}/menu.txd (100%) create mode 100644 src/audio/miles/sampman_mss.cpp create mode 100644 src/audio/miles/sampman_mss.h create mode 100644 src/audio/openal/samp_oal.cpp create mode 100644 src/audio/openal/samp_oal.h diff --git a/gamefiles/JAPANESE.gxt b/gamefiles/TEXT/JAPANESE.gxt similarity index 100% rename from gamefiles/JAPANESE.gxt rename to gamefiles/TEXT/JAPANESE.gxt diff --git a/gamefiles/american.gxt b/gamefiles/TEXT/american.gxt similarity index 100% rename from gamefiles/american.gxt rename to gamefiles/TEXT/american.gxt diff --git a/gamefiles/french.gxt b/gamefiles/TEXT/french.gxt similarity index 100% rename from gamefiles/french.gxt rename to gamefiles/TEXT/french.gxt diff --git a/gamefiles/german.gxt b/gamefiles/TEXT/german.gxt similarity index 100% rename from gamefiles/german.gxt rename to gamefiles/TEXT/german.gxt diff --git a/gamefiles/italian.gxt b/gamefiles/TEXT/italian.gxt similarity index 100% rename from gamefiles/italian.gxt rename to gamefiles/TEXT/italian.gxt diff --git a/gamefiles/polish.gxt b/gamefiles/TEXT/polish.gxt similarity index 100% rename from gamefiles/polish.gxt rename to gamefiles/TEXT/polish.gxt diff --git a/gamefiles/russian.gxt b/gamefiles/TEXT/russian.gxt similarity index 100% rename from gamefiles/russian.gxt rename to gamefiles/TEXT/russian.gxt diff --git a/gamefiles/spanish.gxt b/gamefiles/TEXT/spanish.gxt similarity index 100% rename from gamefiles/spanish.gxt rename to gamefiles/TEXT/spanish.gxt diff --git a/gamefiles/data/PARTICLE.CFG b/gamefiles/data/PARTICLE.CFG new file mode 100644 index 00000000..8bb6d30b --- /dev/null +++ b/gamefiles/data/PARTICLE.CFG @@ -0,0 +1,363 @@ +; Author: Alexander Roger +; Date: 21/12/2000 +; +; Author: Andrzej Madajczyk +; Date: 26/02/2001 +; 14/03/2001 - Alpha (opacity) support added; +; 10/05/2001 - Drag/Friction Decceleration changed to constants; +; 28/08/2001 - Initial Color Variation added; +; +; +; +; +; Note! Last line of the file MUST BE ";the end\n", otherwise you'll get parsing error(s) of the file; +; +; +; +;Particle Systems Configuration Data:: Format +; +; +;A: Particle Type Name (max 20 chars) +; +;B/C/D: Render Colouring (r,g,b) (0-255) +; +;CV: Initial Color Variation (for r,g,b only, in %) (0-100); +; (i.e. Color=(100,100,100) and CV=20, then v=random(-20,20), real_color=(100+v, 100+v, 100+v)); +; +; +; +;B2/C2/D2: Fade Destination Color (r,g,b) (0-255) +; +;FT: Color Fade Time for (B,C,D)->(B2,C2,D2), (0 for none); +; +; +; +; +;E: Default Initial Radius (float) +;F: Expansion Rate (float) +; +; +; Color "Fade-to-Black" options: +;G: Initial Intensity (0-255) +;H: Fade Time (time between fade steps in frames) +;I: Fade Amount (-255 to 255) can get brighter or dimmer +; +; "Fade Alpha" options: +;GA: Initial Intensity (0-255) +;HA: Fade Time (time between fade steps in frames) +;IA: Fade Amount +; +; "Z Rotation" options: +;GZA: Initial Angle (0-1023) +;HZA: Change Time (time between steps in frames) +;IZA: Angle Change Amount +; +;GZR: Initial Z Radius +;HZR: Change Time (time between steps in frames) +;IZR: Z Radius Change Amount +; +; +;J: Animation Speed (0=no animation)(time between steps msec) +;K: Start Animation Frame ( 0 -> ) +;L: Final Animation Frame ( H -> ) +; +; +;M: Rotation Speed (0=None,i-deg/frame) +;N: Gravitational Acceleration (0=none, float) +;O: Drag/Friction Decceleration (int: 0=none, 50=0.50, 80=0.80, 90=0.90, 95=0.95, 96=0.96, 99=0.99) +; +;P: Default Life-Span of Particle (msec) +; +;Q: Position Random Error [position += (+/-)rand(a)] +;R: Velocity Random Error [velocity += (+/-)rand(b)] +;S: Expansion Rate Error [exp_rate += (+)rand(c)] +;T: Rotation Rate Error [rot_speed = (+/-)rand(d)] +;U: Life-Span Error Shape [shape distribution, e=0->all at default, e->Inf then shape->0] (max=255!!) +;V: Trail Length Multiplier [length *= (float) multiplier] (only used if trail flag active) +; +;CR:Particle Create Range (in meters: 0=no check); if particles are created enough far away from camera, they are deleted (not added to particle system); +; +; +;Z: Flags! Guide: 1=ZCHECK_FIRST, 2=ZCHECK_STEP, 4=DRAW_OPAQUE, 8=SCREEN_TRAIL, +; 16=SPEED_TRAIL, 32=RAND_VERT_V, 64=CYCLE_ANIM, 128=DRAW_DARK, 256=VERT_TRAIL +; 1024=DRAWTOP2D, 2048=CLIPOUT2D +; 4096=ZCHECK_BUMP, 8192=ZCHECK_BUMP_FIRST +; +; +; +;default: +;GUNFLASH 255 255 255 0 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0 +; +;good idea for fire-smudge? +;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0 +; +;current: +;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0 +; +; +;SPARK_SMALL 255 255 128 0 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.5 40 +; +; +; +; +; +; +; +; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z +; +SPARK 255 128 64 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 300 0.0 0.07 0.0 0 0 1.0 20.0 48 +SPARK_SMALL 255 255 128 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 500 0.0 0.05 0.0 0 0 0.6 20.0 40 +; +WHEEL_DIRT 8 24 8 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 30.0 4 +; +; +;WHEEL_WATER 24 24 24 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 0 +WHEEL_WATER 24 24 32 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.004 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 1 +; +; +BLOOD 128 128 128 0 0 0 0 0 0.02 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.03 1 2000 0.3 0.05 0.0 0 0 1.0 50.0 5 +BLOOD_SMALL 255 32 32 0 0 0 0 0 0.007 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.05 0.05 0.0 0 0 1.0 50.0 53 +;BLOOD_SPLAT 128 128 128 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 200 0.3 0.0 0.0 0 0 1.0 400.0 36 +BLOOD_SPURT 255 32 32 0 0 0 0 0 0.008 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.0 0.01 0.0 0 0 2.0 50.0 52 +DEBRIS 64 64 64 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 95 1000 0.2 0.0 0.0 0 0 1.0 50.0 4 +DEBRIS2 64 64 64 0 0 0 0 0 0.04 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 5 0.01 99 1000 0.03 0.04 0.0 0 0 1.0 50.0 38 +WATER 64 64 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 2000 0.0 0.0 0.0 0 0 1.0 100.0 0 +; +; +;FLAME 255 74 30 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 100 0.05 0.0 0.0 0 0 1.0 400.0 0 +;FLAME 255 74 30 0 0 255 0 400 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0 +FLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0 +; +; +; +;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.04 255 1 8 255 0 0 0 0 0 0.0 0 0.0 32 0 7 0 0.0 96 1000 0.1 0.0 0.0 0 0 1.0 400.0 0 +; +;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.05 255 0 6 255 0 0 0 0 0 0.0 0 0.0 1 0 7 0 -0.002 96 2000 0.1 0.02 0.02 3 0 1.0 200.0 0 +FIREBALL 255 74 30 0 0 0 0 0 0.1 0.02 255 0 6 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.003 96 2000 0.1 0.03 0.014 2.5 0 1.0 200.0 0 +; +; +; +GUNFLASH 170 170 170 0 0 0 0 0 0.1 0.0 255 1 50 255 0 0 0 0 0 0.0 0 0.0 51 0 3 0 0.0 1 250 0.0 0.0 0.0 0 0 1.0 35.0 0 +GUNFLASH_NOANIM 128 128 128 0 0 0 0 0 0.1 0.0 255 1 128 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 25 0.0 0.0 0.0 0 0 1.0 35.0 0 +; +GUNSMOKE 64 64 64 0 0 0 0 0 0.15 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 2 0 7 0 -0.002 95 1000 0.0 0.0 0.0 0 0 1.0 60.0 0 +GUNSMOKE2 255 255 255 0 0 0 0 0 0.05 0.02 255 0 0 255 0 8 0 0 0 0.0 0 0.0 0 0 3 4 -0.001 80 1400 0.05 0.05 0.01 3 0 1.0 60.0 4 +; +; +SMOKE 32 32 32 0 0 0 0 0 0.15 0.015 255 5 25 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.01 95 1000 0.05 0.05 0.01 3 0 1.0 150.0 0 +;SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 255 5 15 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 1000 0.05 0.05 0.01 3 0 1.0 400.0 0 +SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 128 5 11 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 3000 0.05 0.05 0.01 3 0 1.0 150.0 0 +; +; +; +;GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.001 95 2000 0.05 0.05 0.01 3 0 1.0 400.0 0 +GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.0005 95 4000 0.05 0.05 0.01 3 0 1.0 100.0 0 +SHARD 255 255 255 0 0 0 0 0 0.03 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0 +SPLASH 64 64 128 0 0 0 0 0 0.1 0.007 255 1 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 100.0 0 +;BLOOD_SPLASH 24 64 0 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0 +; +; +;CARFLAME 255 74 30 0 0 0 0 0 0.5 0.04 255 2 20 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 1000 0.4 0.0 0.0 0 0 1.0 400.0 64 +;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64 +;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64 +; +CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 100.0 0 +; +; +STEAM 64 64 64 0 0 0 0 0 0.5 0.05 255 1 16 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 85.0 0 +; +;default: +;STEAM2 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4 +STEAM2 255 255 255 0 0 0 0 0 0.5 0.015 255 0 0 192 0 1 0 0 10 0.5 1 0.02 32 0 4 0 -0.002 95 8000 0.01 0.03 0.0 0 0 1.0 85.0 4 +; +; +;STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4 +STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4 +STEAM_NY_SLOWMOTION 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.0015 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4 +; +; +;ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 2 16 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 250.0 4 +ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 0 10 0 0 0 0.0 0 0.0 32 0 4 1 -0.005 95 4000 0.03 0.03 0.02 0 0 1.0 85.0 4 +; +; +;RAINDROP 32 32 32 0 0 0 0 0 0.6 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.025 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1 +RAINDROP 64 64 64 0 0 0 0 0 0.4 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1 +RAINDROP_SMALL 16 16 16 0 0 0 0 0 0.3 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1 +RAIN_SPLASH 32 32 32 0 0 0 0 0 0.08 0.0 255 0 5 255 0 0 0 0 0 0.0 0 0.0 1 0 4 0 0.0 1 500 0.0 0.0 0.0 0 0 1.0 15.0 0 +RAIN_SPLASH_BIGGROW 128 128 128 0 0 0 0 0 0.5 0.06 255 0 2 255 0 0 0 0 0 0.0 0 0.0 2 1 4 0 0.0 1 5500 0.0 0.0 0.0 0 0 1.0 15.0 0 +RAIN_SPLASHUP 48 48 48 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 1 0 0.0 1 50 0.0 0.0 0.0 0 0 1.0 15.0 0 +; +WATERSPRAY 64 64 64 0 0 0 0 0 0.2 0.0 255 0 25 255 0 0 0 0 0 0.0 0 0.0 3 0 2 0 0.002 1 800 0.05 0.0 0.01 0 0 1.0 20.0 0 +; +; +; +;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.2 0.0 0.0 3 0 1.0 400.0 0 +;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.8 0.0 0.0 3 0 1.0 400.0 0 +;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.2 0.0 0.0 0 0 1.0 400.0 0 +;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.8 0.0 0.0 0 0 1.0 400.0 0 +; +;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 400.0 0 +;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 400.0 0 +EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 200.0 0 +EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 200.0 0 +EXPLOSION_MFAST 80 80 80 0 0 0 0 0 0.6 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.2 0.0 0.0 0 0 1.0 200.0 0 +EXPLOSION_LFAST 80 80 80 0 0 0 0 0 1.1 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.8 0.0 0.0 0 0 1.0 200.0 0 +; +; +; +; +;BOAT_SPLASH 32 64 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0 +;BOAT_THRUSTJET 24 32 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8 +;BOAT_SPLASH 16 32 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0 +;BOAT_THRUSTJET 8 24 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8 +;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 250.0 0 +;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.04 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4 +;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.35 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4 +;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.25 255 0 0 180 0 5 0 0 0 0.0 0 0.0 2 1 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 12 +; +; +;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.15 255 0 0 180 0 2 0 0 0 0.0 0 0.0 2 0 3 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 12 +;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.15 96 0 0 255 0 0 0 0 0 0.0 0 0.0 6 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288 +;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.05 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288 +; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z +CAR_SPLASH 48 48 60 0 0 0 0 0 1.0 0.00 128 1 4 128 0 0 0 0 0 0.0 0 0.0 0 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 150.0 272 +; +; +; +;BOAT_SPLASH 70 70 70 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0 +BOAT_SPLASH 64 64 64 0 0 0 0 0 0.2 0.2 255 0 2 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0 +; +; +;BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.8 0.1 255 0 0 120 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4 +BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.4 0.06 255 0 0 96 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4 +; +; +;BOAT_WAKE 255 255 255 0 0 0 0 0 2.0 0.2 255 0 0 128 0 1 0 0 0 0.0 0 0.0 0 0 0 0 0.03 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4 +BOAT_WAKE 255 255 255 0 0 0 0 0 1.5 0.45 255 0 0 192 0 2 0 0 0 0.0 0 0.0 0 0 0 0 0.0 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4 +; +; +; +; +; +; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z +WATER_HYDRANT 64 64 64 0 0 0 0 0 0.8 0.01 255 1 16 255 1 16 0 0 0 0.0 0 0.0 0 0 2 0 0.007 99 500 0.02 0.08 0.0 0 4 1.0 85.0 16 +WATER_CANNON 64 64 128 0 0 0 0 0 0.03 0.03 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0 +EXTINGUISH_STEAM 32 32 32 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0 +; +; +; +;PED_SPLASH 32 32 64 0 0 0 0 0 0.1 0.05 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0 +PED_SPLASH 48 48 60 0 0 0 0 0 0.1 0.06 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 50.0 256 +; +; +PEDFOOT_DUST 170 166 150 0 0 0 0 0 0.01 0.015 255 0 0 63 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0005 1 1000 0.0 0.0 0.0 0 0 1.0 6.0 4 +; +HELI_DUST 17 15 9 0 0 0 0 0 0.2 0.1 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 1 1000 0.2 0.05 0.0 0 0 1.0 85.0 0 +HELI_ATTACK 255 255 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 500 0.0 0.0 0.0 0 0 0.5 85.0 10 +; +; +;ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 150.0 4 +;ENGINE_SMOKE2 8 8 8 0 0 0 0 0 1.0 0.2 128 2 4 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 1000 0.0 0.0 0.0 0 3 1.0 150.0 4 +ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 52 0 2 10 0 80 0.0 0 0.0 0 0 5 2 -0.009 95 2000 0.11 0.03 0.01 1 0 1.0 85.0 4 +ENGINE_SMOKE2 9 9 9 80 0 0 0 0 1.0 0.06 128 0 1 140 0 5 10 0 80 0.0 0 0.0 0 0 0 2 0.002 1 1300 0.0 0.01 0.0 3 3 1.0 85.0 4 +; +; +CARFLAME_SMOKE 32 32 32 0 0 0 0 0 0.05 0.01 255 0 0 64 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.008 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4 +FIREBALL_SMOKE 32 32 32 0 0 0 0 0 0.05 0.03 255 0 0 128 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.004 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4 +; +PAINT_SMOKE 255 0 0 0 0 0 0 0 0.1 0.01 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 95 3000 0.0 0.005 0.0 0 0 1.0 85.0 0 +TREE_LEAVES 64 64 64 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0 +; +; +;CARCOLLISION_DUST 224 224 224 0 0 0 0 0 0.15 0.04 255 0 0 127 1 8 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 80.0 4 +CARCOLLISION_DUST 76 76 76 0 0 0 0 0 0.10 0.02 255 0 0 160 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0015 90 2000 0.02 0.02 0.0 0 0 1.0 30.0 4 +; +; +CAR_DEBRIS 32 32 32 0 0 0 0 0 0.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 50.0 4 +HELI_DEBRIS 32 32 32 0 0 0 0 0 1.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.065 90 1500 0.02 0.02 0.0 0 0 1.0 150.0 4 +; +; +; +;EXHAUST_FUMES 80 80 80 0 0 0 0 0 0.03 0.03 255 0 0 122 0 4 0 0 0 0.0 0 0.0 2 0 4 0 -0.001 95 1500 0.01 0.03 0.0 0 0 1.0 50.0 4 +EXHAUST_FUMES 98 98 108 0 0 0 0 0 0.03 0.06 255 0 0 152 0 12 0 0 0 0.0 0 0.0 2 0 4 0 -0.002 96 1000 0.01 0.03 0.0 0 0 1.0 25.0 4 +; +; +;RUBBER 40 40 40 0 0 0 0 0 0.4 0.005 255 21 20 255 0 0 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 400.0 4 +RUBBER_SMOKE 255 255 255 0 0 0 0 0 0.4 0.005 255 0 0 127 1 8 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 50.0 4 +;BURNINGRUBBER_SMOKE128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 192 1 6 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 4000 0.02 0.02 0.0 0 0 1.0 400.0 4 +BURNINGRUBBER_SMOKE 128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 128 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 50.0 4 +; +; +BULLETHIT_SMOKE 192 192 192 0 0 0 0 0 0.15 0.03 70 0 2 255 1 10 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 90 2000 0.04 0.02 0.0 0 0 1.0 150.0 0 +; +; +GUNSHELL_FIRST 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 0.0 12292 +GUNSHELL 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 12.0 4100 +GUNSHELL_BUMP1 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 8.0 4100 +GUNSHELL_BUMP2 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 400 0.02 0.02 0.0 0 0 1.0 8.0 4100 +; +; +TEST 255 64 64 0 0 0 0 0 0.2 0.025 255 1 20 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 3000 0.0 0.0 0.0 0 0 1.0 400.0 128 +; +; +;Particles with flag DRAWTOP2D should be placed last and VR (Visibility Range) set to 0! +; +;BIRD_FRONT 8 8 8 0 0 0 0 0 0.05 0.0 255 0 0 255 2 1 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 10000 0.0 0.0 0.0 0 0 1.0 0.0 3140 +BIRD_FRONT 8 8 8 0 0 0 0 0 1.05 0.0 255 0 0 255 2 2 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 8000 0.0 0.0 0.0 0 0 1.0 0.0 68 +; +RAINDROP_2D 32 32 32 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 0.0 3072 +; +; +; +; +; +; +; +; +; +; +; +; +; below is just backup of above values: +; +;SPARK 255 128 64 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 300 0.0 0.07 0.0 0 0 1.0 48 +;SPARK_SMALL 255 255 128 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.6 40 +;BLOOD 128 128 128 0.02 0.0 255 0 0 0 0 0 0 0.03 1.0 2000 0.3 0.05 0.0 0 0 1.0 6 +;BLOOD_SMALL 255 32 32 0.007 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.05 0.05 0.0 0 0 1.0 54 +;BLOOD_SPLAT 128 128 128 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 200 0.3 0.0 0.0 0 0 1.0 36 +;BLOOD_SPURT 255 32 32 0.008 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.0 0.01 0.0 0 0 2.0 52 +;DEBRIS 64 64 64 0.5 0.0 255 0 0 0 0 0 0 0.01 0.95 1000 0.2 0.0 0.0 0 0 1.0 4 +;DEBRIS2 64 64 64 0.04 0.0 255 0 0 0 0 0 5 0.01 0.99 1000 0.03 0.04 0.0 0 0 1.0 38 +;WATER 64 64 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 2000 0.0 0.0 0.0 0 0 1.0 0 +;FLAME 255 74 30 0.2 0.0 255 0 0 31 0 5 0 0.0 1.0 100 0.05 0.0 0.0 0 0 1.0 0 +;FIREBALL 255 74 30 0.1 0.04 255 0 8 31 0 8 0 0.0 0.96 1000 0.1 0.0 0.0 0 0 1.0 0 +;GUNFLASH 255 255 255 0.1 0.0 255 0 50 50 0 3 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0 +;GUNFLASHSTATIC 255 255 255 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 25 0.0 0.0 0.0 0 0 1.0 0 +;SMOKE 32 32 32 0.15 0.015 255 4 25 31 0 5 0 -0.01 0.95 1000 0.05 0.05 0.01 3 0 1.0 0 +;SHARD 255 255 255 0.03 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0 +;SPLASH 64 64 128 0.1 0.007 255 0 10 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;BLOOD_SPLASH 24 64 0 0.1 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0 +;RUBBER 40 40 40 0.4 0.005 255 1 25 31 0 5 0 0.0 1.0 1000 0.02 0.0 0.0 0 0 1.0 0 +;CARFLAME 255 74 30 0.5 0.04 255 1 20 31 0 5 0 0.0 1.0 1000 0.4 0.0 0.0 0 0 1.0 64 +;STEAM 64 64 64 0.5 0.05 255 0 16 31 0 5 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 0 +;RAINDROP 32 32 32 0.6 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1 +;RAIN_SPLASH 32 32 32 0.08 0.0 255 0 0 1 0 4 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;RAINDROP_SMALL 32 32 32 0.3 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1 +;EXPLOSION_MEDIUM 80 80 80 0.6 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.2 0.0 0.0 3 0 1.0 0 +;EXPLOSION_LARGE 80 80 80 1.1 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.8 0.0 0.0 3 0 1.0 0 +;BOAT_SPLASH 32 64 32 0.2 0.2 255 0 0 0 0 0 0 0.01 1.0 2000 0.0 0.0 0.0 0 0 1.0 0 +;BOAT_THRUSTJET 24 32 24 0.5 0.1 255 0 0 250 0 5 0 0.01 0.5 1000 0.0 0.0 0.0 0 4 1.0 8 +;WATER_HYDRANT 64 64 128 0.4 0.01 255 1 2 20 0 5 0 0.007 0.99 500 0.02 0.05 0.0 0 4 1.0 256 +;WATER_CANNON 64 64 128 0.03 0.03 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;EXTINGUISH_STEAM 32 32 32 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;PED_SPLASH 32 32 64 0.1 0.05 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;HELI_DUST 17 15 9 0.2 0.1 255 0 8 0 0 0 0 -0.001 1.0 1000 0.2 0.05 0.0 0 0 1.0 0 +;HELI_ATTACK 255 255 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.0 0.0 0 0 0.5 10 +;ENGINE_SMOKE 16 16 16 0.5 0.04 255 0 0 0 0 0 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 4 +;ENGINE_SMOKE2 4 4 4 1.0 0.2 255 1 4 0 0 0 0 0.001 1.0 1000 0.0 0.0 0.0 0 3 1.0 4 +;PAINT_SMOKE 255 0 0 0.1 0.01 255 0 8 0 0 0 0 0.0 0.95 3000 0.0 0.005 0.0 0 0 1.0 0 +;TREE_LEAVES 64 64 64 0.2 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0 +;TEST 255 64 64 0.2 0.05 255 0 16 0 0 0 0 0.0 1.0 3000 0.0 0.0 0.0 0 0 1.0 128 +; +; +;the end diff --git a/gamefiles/main_d.scm b/gamefiles/data/main_d.scm similarity index 100% rename from gamefiles/main_d.scm rename to gamefiles/data/main_d.scm diff --git a/gamefiles/main_freeroam.scm b/gamefiles/data/main_freeroam.scm similarity index 100% rename from gamefiles/main_freeroam.scm rename to gamefiles/data/main_freeroam.scm diff --git a/gamefiles/fonts_j.txd b/gamefiles/models/fonts_j.txd similarity index 100% rename from gamefiles/fonts_j.txd rename to gamefiles/models/fonts_j.txd diff --git a/gamefiles/fonts_p.txd b/gamefiles/models/fonts_p.txd similarity index 100% rename from gamefiles/fonts_p.txd rename to gamefiles/models/fonts_p.txd diff --git a/gamefiles/fonts_r.txd b/gamefiles/models/fonts_r.txd similarity index 100% rename from gamefiles/fonts_r.txd rename to gamefiles/models/fonts_r.txd diff --git a/gamefiles/menu.txd b/gamefiles/models/menu.txd similarity index 100% rename from gamefiles/menu.txd rename to gamefiles/models/menu.txd diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index f836f1c4..02bf532c 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -9548,6 +9548,9 @@ cAudioManager::ResetTimers(uint32 time) SampleManager.SetEffectsFadeVolume(0); SampleManager.SetMusicFadeVolume(0); MusicManager.ResetMusicAfterReload(); +#ifdef OPENAL + SampleManager.Service(); +#endif } } @@ -9603,6 +9606,9 @@ cAudioManager::ServiceSoundEffects() ProcessMissionAudio(); AdjustSamplesVolume(); ProcessActiveQueues(); +#ifdef WITHMILES + SampleManager.Service(); +#endif for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { cAudioScriptObject *object = (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]] @@ -9983,7 +9989,7 @@ cAudioManager::Terminate() m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0; PreTerminateGameSpecificShutdown(); - for(uint32 i = 0; i < DIGITALCHANNELS; i++) { + for(uint32 i = 0; i < MAX_SAMPLEBANKS; i++) { if(SampleManager.IsSampleBankLoaded(i)) SampleManager.UnloadSampleBank(i); } diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index 01fa055d..72d8ba41 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -581,6 +581,6 @@ public: uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); }; -static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error"); +//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error"); extern cAudioManager AudioManager; diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/miles/sampman_mss.cpp new file mode 100644 index 00000000..f3a6ba80 --- /dev/null +++ b/src/audio/miles/sampman_mss.cpp @@ -0,0 +1,2257 @@ +#include +#include +#include + +#include + +#include "eax.h" +#include "eax-util.h" +#include "mss.h" + +#include "sampman_mss.h" +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" + + +#pragma comment( lib, "mss32.lib" ) + +cSampleManager SampleManager; +int32 BankStartOffset[MAX_SAMPLEBANKS]; +/////////////////////////////////////////////////////////////// + +char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; +char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; + +FILE *fpSampleDescHandle; +FILE *fpSampleDataHandle; +bool bSampleBankLoaded [MAX_SAMPLEBANKS]; +int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; +int32 nSampleBankSize [MAX_SAMPLEBANKS]; +int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; +int32 _nSampleDataEndOffset; + +int32 nPedSlotSfx [MAX_PEDSFX]; +int32 nPedSlotSfxAddr[MAX_PEDSFX]; +uint8 nCurrentPedSlot; + +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; + +/////////////////////////////////////////////////////////////// +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry *pNext; + char *pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry *_pMP3List; +char _mp3DirectoryPath[MAX_PATH]; +HSTREAM mp3Stream [MAX_MP3STREAMS]; +int8 nStreamPan [MAX_MP3STREAMS]; +int8 nStreamVolume[MAX_MP3STREAMS]; +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; + +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) +bool _bUseHDDAudio; +char _aHDDPath[MAX_PATH]; +#endif +/////////////////////////////////////////////////////////////// + + +bool _bSampmanInitialised = false; + +// +// Miscellaneous globals / defines + +// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS + +EAXLISTENERPROPERTIES StartEAX3 = + {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; + +EAXLISTENERPROPERTIES FinishEAX3 = + {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; + +EAXLISTENERPROPERTIES EAX3Params; + +S32 prevprovider=-1; +S32 curprovider=-1; +S32 usingEAX=0; +S32 usingEAX3=0; +HPROVIDER opened_provider=0; +H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; +HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; +HDIGDRIVER DIG; +S32 speaker_type=0; + +U32 _maxSamples; +float _fPrevEaxRatioDestination; +bool _usingMilesFast2D; +float _fEffectsLevel; + + +struct +{ + HPROVIDER id; + char name[80]; +}providers[MAXPROVIDERS]; + +typedef struct provider_stuff +{ + char* name; + HPROVIDER id; +} provider_stuff; + + +static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) +{ + return( _stricmp(s1->name,s2->name) ); +} + +static void +add_providers() +{ + provider_stuff pi[MAXPROVIDERS]; + U32 n,i,j; + + SampleManager.SetNum3DProvidersAvailable(0); + + HPROENUM next = HPROENUM_FIRST; + + n=0; + while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n MAXCHANNELS ) + _maxSamples = MAXCHANNELS; + + SampleManager.SetSpeakerConfig(speaker_type); + + //obtain a 3D sample handles + for ( U32 i = 0; i < _maxSamples; ++i ) + { + opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); + if ( opened_samples[i] != NULL ) + AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); + } + + return true; + } + } + + return false; +} + +void +cSampleManager::SetSpeakerConfig(int32 which) +{ + switch ( which ) + { + case 1: + speaker_type=AIL_3D_2_SPEAKER; + break; + + case 2: + speaker_type=AIL_3D_HEADPHONE; + break; + + case 3: + speaker_type=AIL_3D_4_SPEAKER; + break; + + default: + return; + break; + } + + if (opened_provider) + AIL_set_3D_speaker_type(opened_provider, speaker_type); +} + +uint32 +cSampleManager::GetMaximumSupportedChannels(void) +{ + if ( _maxSamples > MAXCHANNELS ) + return MAXCHANNELS; + + return _maxSamples; +} + +int8 +cSampleManager::GetCurrent3DProviderIndex(void) +{ + return curprovider; +} + +int8 +cSampleManager::SetCurrent3DProvider(uint8 nProvider) +{ + S32 savedprovider = curprovider; + + if ( nProvider < m_nNumberOfProviders ) + { + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; + else + return -1; + } + else + return curprovider; +} + +static bool +_ResolveLink(char const *path, char *out) +{ + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + S32 total_ms; + WIN32_FIND_DATA fd; + + + if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) + { + GetLastError(); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + GetLastError(); + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + FILE *f = fopen("MP3\\MP3Report.txt", "w"); + + if ( f ) + { + fprintf(f, "MP3 Report File\n\n"); + fprintf(f, "\"%s\"", fd.cFileName); + } + + + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + bShortcut = false; + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + + if ( f ) + fclose(f); + + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + if ( f ) fprintf(f, " - OK\n"); + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( f ) fprintf(f, "\"%s\"", fd.cFileName); + + if ( filepathlen > 0 ) + { + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + { + bShortcut = false; + + if ( filepathlen > MAX_PATH ) + { + if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); + + continue; + } + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + if ( f ) fprintf(f, " - OK\n"); + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( f ) fprintf(f, "\"%s\"", fd.cFileName); + + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + { + bShortcut = false; + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + + if ( f ) fprintf(f, " - OK\n"); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + } + } + } + } + + if ( f ) + { + fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); + fclose(f); + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + +void +cSampleManager::ReleaseDigitalHandle(void) +{ + if ( DIG ) + { + prevprovider = curprovider; + release_existing(); + curprovider = -1; + AIL_digital_handle_release(DIG); + } +} + +void +cSampleManager::ReacquireDigitalHandle(void) +{ + if ( DIG ) + { + AIL_digital_handle_reacquire(DIG); + if ( prevprovider != -1 ) + set_new_provider(prevprovider); + } +} + +bool +cSampleManager::Initialise(void) +{ + TRACE("start"); + + if ( _bSampmanInitialised ) + return true; + + { + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = 22050; + m_aSamples[i].nLoopStart = 0; + m_aSamples[i].nLoopEnd = -1; + } + + m_nEffectsVolume = MAX_VOLUME; + m_nMusicVolume = MAX_VOLUME; + m_nEffectsFadeVolume = MAX_VOLUME; + m_nMusicFadeVolume = MAX_VOLUME; + + m_nMonoMode = 0; + } + + // miles + TRACE("MILES"); + { + curprovider = -1; + prevprovider = -1; + + _usingMilesFast2D = false; + usingEAX=0; + usingEAX3=0; + + _fEffectsLevel = 0.0f; + + _maxSamples = 0; + + opened_provider = NULL; + DIG = NULL; + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + opened_samples[i] = NULL; + } + + // banks + TRACE("banks"); + { + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + _nSampleDataEndOffset = 0; + + for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + } + + // pedsfx + TRACE("pedsfx"); + { + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + } + + // channel volume + TRACE("vol"); + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + nChannelVolume[i] = 0; + } + + TRACE("mss"); + { + AIL_set_redist_directory( "mss" ); + + AIL_startup(); + + AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); + + DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); + if ( DIG == NULL ) + { + OutputDebugString(AIL_last_error()); + Terminate(); + return false; + } + + add_providers(); + + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]); + if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + + } + + TRACE("cdrom"); + + S32 tatalms; + char filepath[MAX_PATH]; + + { + m_bInitialised = false; + + while (true) + { + int32 drive = 'C'; + + do + { + char latter[2]; + + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":\\"); + + if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[0]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + + bool bFileNotFound = false; + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + { + bFileNotFound = true; + break; + } + } + + if ( !bFileNotFound ) + { + m_bInitialised = true; + break; + } + else + { + m_bInitialised = false; + continue; + } + } + } + + } while ( ++drive <= 'Z' ); + + if ( !m_bInitialised ) + { +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + FrontEndMenuManager.WaitForUserCD(); + if ( FrontEndMenuManager.m_bQuitGameNoCD ) + { + Terminate(); + return false; + } + continue; +#else + m_bInitialised = true; +#endif + } + + break; + } + } + +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) + // hddaudio + /** + Option for user to play audio files directly from hard disk. + Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. + Grand Theft Auto III still requires the presence of the PLAY disc when started. + This may give better performance on some machines (though worse on others). + **/ + TRACE("hddaudio 1.1 patch"); + { + int32 streamLength[TOTAL_STREAMED_SOUNDS]; + + bool bFileNotFound = false; + char rootpath[MAX_PATH]; + + strcpy(_aHDDPath, m_szCDRomRootPath); + rootpath[0] = '\0'; + + FILE *f = fopen(StreamedNameTable[0], "rb"); + + if ( f ) + { + fclose(f); + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + strcpy(filepath, rootpath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + streamLength[i] = tatalms; + } + else + { + bFileNotFound = true; + break; + } + } + + } + else + bFileNotFound = true; + + if ( !bFileNotFound ) + { + strcpy(m_szCDRomRootPath, rootpath); + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + nStreamLength[i] = streamLength[i]; + + _bUseHDDAudio = true; + } + else + _bUseHDDAudio = false; + } +#endif + + TRACE("stream"); + { + for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) + { + mp3Stream [i] = NULL; + nStreamPan [i] = 63; + nStreamVolume[i] = 100; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); + if ( opened_2dsamples[i] ) + { + AIL_init_sample(opened_2dsamples[i]); + AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); + } + } + + TRACE("providerset"); + { + _bSampmanInitialised = true; + + U32 n = 0; + + while ( n < m_nNumberOfProviders ) + { + if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) + { + set_new_provider(n); + break; + } + n++; + } + + if ( n == m_nNumberOfProviders ) + { + Terminate(); + return false; + } + } + + TRACE("bank"); + + LoadSampleBank(SAMPLEBANK_MAIN); + + // mp3 + TRACE("mp3"); + { + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; + + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) + { + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; + } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; + else + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } + } + else + _CurMP3Pos = 0; + + _bIsMp3Active = false; + } + + TRACE("end"); + + return true; +} + +void +cSampleManager::Terminate(void) +{ + for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) + { + if ( mp3Stream[i] ) + { + AIL_pause_stream(mp3Stream[i], 1); + AIL_close_stream(mp3Stream[i]); + mp3Stream[i] = NULL; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + if ( opened_2dsamples[i] ) + { + AIL_release_sample_handle(opened_2dsamples[i]); + opened_2dsamples[i] = NULL; + } + } + + release_existing(); + + _DeleteMP3Entries(); + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]); + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0; + } + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0; + } + + if ( DIG ) + { + AIL_close_digital_driver(DIG); + DIG = NULL; + } + + AIL_shutdown(); + + _bSampmanInitialised = false; +} + +bool +cSampleManager::CheckForAnAudioFileOnCD(void) +{ +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + char filepath[MAX_PATH]; + +#if defined(GTA3_1_1_PATCH) + if (_bUseHDDAudio) + strcpy(filepath, _aHDDPath); + else + strcpy(filepath, m_szCDRomRootPath); +#else + strcpy(filepath, m_szCDRomRootPath); +#endif // #if defined(GTA3_1_1_PATCH) + + strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + + return true; + } + + return false; + +#else + return true; +#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) +} + +char +cSampleManager::GetCDAudioDriveLetter(void) +{ +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) + if (_bUseHDDAudio) + { + if ( strlen(_aHDDPath) != 0 ) + return _aHDDPath[0]; + else + return '\0'; + } + else + { + if ( strlen(m_szCDRomRootPath) != 0 ) + return m_szCDRomRootPath[0]; + else + return '\0'; + } +#else + if ( strlen(m_szCDRomRootPath) != 0 ) + return m_szCDRomRootPath[0]; + else + return '\0'; +#endif +} + +void +cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? +{ + if ( _bSampmanInitialised ) + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( i < MAXCHANNELS ) + { + if ( opened_samples[i] && GetChannelUsedFlag(i) ) + { + if ( nChannelVolume[i] ) + { + AIL_set_3D_sample_volume(opened_samples[i], + m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); + } + } + } + else + { + if ( opened_2dsamples[i - MAXCHANNELS] ) + { + if ( GetChannelUsedFlag(i - MAXCHANNELS) ) + { + if ( nChannelVolume[i - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], + m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14); + } + } + } + } + } + } +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ + m_nEffectsVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ + m_nMusicVolume = nVolume; +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ + m_nEffectsFadeVolume = nVolume; + UpdateEffectsVolume(); +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ + m_nMusicFadeVolume = nVolume; +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + if ( CTimer::GetIsCodePaused() ) + return false; + + if ( MusicManager.IsInitialised() + && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && nBank != SAMPLEBANK_MAIN ) + { + return false; + } + + if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + return false; + + if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] ) + return false; + + bSampleBankLoaded[nBank] = true; + + return true; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + bSampleBankLoaded[nBank] = false; +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + return bSampleBankLoaded[nBank]; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + uint8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; + if ( nComment == nPedSlotSfx[slot] ) + return true; + } + + return false; +} + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + uint8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; + if ( nComment == nPedSlotSfx[slot] ) + return slot; + } + + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + if ( CTimer::GetIsCodePaused() ) + return false; + + // no talking peds during cutsenes or the game end + if ( MusicManager.IsInitialised() ) + { + switch ( MusicManager.GetMusicMode() ) + { + case MUSICMODE_CUTSCENE: + { + return false; + + break; + } + + case MUSICMODE_FRONTEND: + { + if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED ) + return false; + + break; + } + } + } + + if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) + return false; + + if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) + return false; + + nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot; + nPedSlotSfx [nCurrentPedSlot] = nComment; + + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) + nCurrentPedSlot = 0; + + return true; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + return m_aSamples[nSample].nSize >> 1; +} + +bool +cSampleManager::UpdateReverb(void) +{ + if ( !usingEAX ) + return false; + + if ( AudioManager.GetFrameCounter() & 15 ) + return false; + + float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); + float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); + float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); + + float normy = norm(y, 5.0f, 40.0f); + float normx = norm(x, 5.0f, 40.0f); + float normz = norm(z, 5.0f, 40.0f); + + float fRatio; + + if ( normy == 0.0f ) + { + if ( normx == 0.0f ) + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = 0.5f; + } + else + { + fRatio = 0.3f; + } + } + else + { + if ( normx == 0.0f ) + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = 0.5f; + } + else + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = (normy+normx+normz) / 3.0f; + } + } + + fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + + if ( fRatio == _fPrevEaxRatioDestination ) + return false; + + if ( usingEAX3 ) + { + if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) + { + AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); + _fEffectsLevel = 1.0f - fRatio * 0.5f; + } + } + else + { + if ( _usingMilesFast2D ) + _fEffectsLevel = (1.0f - fRatio) * 0.4f; + else + _fEffectsLevel = (1.0f - fRatio) * 0.7f; + } + + _fPrevEaxRatioDestination = fRatio; + + return true; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( usingEAX ) + { + if ( nReverbFlag != 0 ) + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); + } + else + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); + } + } +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + int32 addr; + + if ( nSfx < SAMPLEBANK_MAX ) + { + if ( !IsSampleBankLoaded(nBank) ) + return false; + + addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + + addr = nPedSlotSfxAddr[slot]; + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); + return true; + } + else + return false; + } + else + { + AILSOUNDINFO info; + + info.format = WAVE_FORMAT_PCM; + info.data_ptr = (void *)addr; + info.channels = 1; + info.data_len = m_aSamples[nSfx].nSize; + info.rate = m_aSamples[nSfx].nFrequency; + info.bits = 16; + + if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) + { + OutputDebugString(AIL_last_error()); + return false; + } + + return true; + } +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] >>= 2; + } + + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); + +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + switch ( nChannel ) + { + case CHANNEL2D: + { + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] >>= 2; + } + + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], + m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } + + break; + } + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + switch ( nChannel ) + { + case CHANNEL2D: + { +#ifndef FIX_BUGS + if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG +#else + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) +#endif + AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); + + break; + } + } +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); + } +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); + } +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); + } +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; + else + return false; + } + else + { + if ( opened_samples[nChannel] ) + return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; + else + return false; + } + +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + AIL_start_3D_sample(opened_samples[nChannel]); + } +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + { + if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) + AIL_end_3D_sample(opened_samples[nChannel]); + } + } +} + +void +cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + + char filepath[MAX_PATH]; + + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_service_stream(mp3Stream[nStream], 1); + } + else + OutputDebugString(AIL_last_error()); + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_start_stream(mp3Stream[nStream]); + } +} + +bool +cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) +{ + uint32 position = nPos; + char filename[MAX_PATH]; + + if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + uint32 i = 0; + do { + if(i != 0 || _bIsMp3Active) { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if(mp3) { + mp3 = _pMP3List; + if(mp3 == NULL) { + _bIsMp3Active = false; + nFile = 0; + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count( + mp3Stream[nStream], 1); + AIL_set_stream_ms_position( + mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], + 0); + return true; + } + + return false; + } + } + + if(mp3->pLinkPath != NULL) + mp3Stream[nStream] = + AIL_open_stream(DIG, mp3->pLinkPath, 0); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + } + + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], 0); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + + _bIsMp3Active = false; + continue; + } + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + + tMP3Entry *e; + if ( !_GetMP3PosFromStreamPos(&position, &e) ) + { + if ( e == NULL ) + { + nFile = 0; + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count( + mp3Stream[nStream], 1); + AIL_set_stream_ms_position( + mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + + return false; + } + } + + if ( e->pLinkPath != NULL ) + mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); + else + { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + } + + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + + _bIsMp3Active = true; + + return true; + } + + _bIsMp3Active = false; + + } while(++i < nNumMP3s); + + position = 0; + nFile = 0; + } + + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + } + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + + AIL_close_stream(mp3Stream[nStream]); + mp3Stream[nStream] = NULL; + + if ( nStream == 0 ) + _bIsMp3Active = false; + } + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + S32 currentms; + + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( _bIsMp3Active ) + { + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if ( mp3 != NULL ) + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms + mp3->nTrackStreamPos; + } + else + return 0; + } + else + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms; + } + } + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + uint8 vol = nVolume; + + if ( m_bInitialised ) + { + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nStreamVolume[nStream] = vol; + nStreamPan[nStream] = nPan; + + if ( mp3Stream[nStream] ) + { + if ( nEffectFlag ) + AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + else + AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); + + AIL_set_stream_pan(mp3Stream[nStream], nPan); + } + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + if ( m_bInitialised ) + return nStreamLength[nStream]; + + return 0; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) + return true; + else + return false; + } + } + + return false; +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + int32 nBank = SAMPLEBANK_MAIN; + + fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); + if ( fpSampleDescHandle == NULL ) + return false; + + fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); + if ( fpSampleDataHandle == NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + return false; + } + + fseek(fpSampleDataHandle, 0, SEEK_END); + _nSampleDataEndOffset = ftell(fpSampleDataHandle); + rewind(fpSampleDataHandle); + + fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); + + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { +#ifdef FIX_BUGS + if (nBank >= MAX_SAMPLEBANKS) break; +#endif + if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i ) + { + nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; + nBank++; + } + } + + nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN]; + nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED]; + + return true; +} diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h new file mode 100644 index 00000000..ebedfb63 --- /dev/null +++ b/src/audio/miles/sampman_mss.h @@ -0,0 +1,339 @@ +#pragma once +#include "common.h" +#include "AudioSamples.h" + +#define MAX_VOLUME 127 + +struct tSample { + int32 nOffset; + uint32 nSize; + int32 nFrequency; + int32 nLoopStart; + int32 nLoopEnd; +}; + +enum +{ + SAMPLEBANK_MAIN, + SAMPLEBANK_PED, + MAX_SAMPLEBANKS, + SAMPLEBANK_INVALID +}; + +#define MAX_PEDSFX 7 +#define PED_BLOCKSIZE 79000 + +#define MAXPROVIDERS 64 + +#define MAXCHANNELS 28 +#define MAXCHANNELS_SURROUND 24 +#define MAX2DCHANNELS 1 +#define CHANNEL2D MAXCHANNELS + +#define MAX_MP3STREAMS 2 + +#define DIGITALRATE 32000 +#define DIGITALBITS 16 +#define DIGITALCHANNELS 2 + +#define MAX_DIGITAL_MIXER_CHANNELS 32 + +class cSampleManager +{ + uint8 m_nEffectsVolume; + uint8 m_nMusicVolume; + uint8 m_nEffectsFadeVolume; + uint8 m_nMusicFadeVolume; + uint8 m_nMonoMode; + char unk; + char m_szCDRomRootPath[80]; + bool m_bInitialised; + uint8 m_nNumberOfProviders; + char *m_aAudioProviders[MAXPROVIDERS]; + tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; + +public: + + + + cSampleManager(void) : + m_nNumberOfProviders(0) + { } + + ~cSampleManager(void) + { } + + void SetSpeakerConfig(int32 nConfig); + uint32 GetMaximumSupportedChannels(void); + + uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; } + void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; } + + char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; } + void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; } + + int8 GetCurrent3DProviderIndex(void); + int8 SetCurrent3DProvider(uint8 which); + + bool IsMP3RadioChannelAvailable(void); + + void ReleaseDigitalHandle (void); + void ReacquireDigitalHandle(void); + + bool Initialise(void); + void Terminate (void); + + bool CheckForAnAudioFileOnCD(void); + char GetCDAudioDriveLetter (void); + + void UpdateEffectsVolume(void); + + void SetEffectsMasterVolume(uint8 nVolume); + void SetMusicMasterVolume (uint8 nVolume); + void SetEffectsFadeVolume (uint8 nVolume); + void SetMusicFadeVolume (uint8 nVolume); + + bool LoadSampleBank (uint8 nBank); + void UnloadSampleBank (uint8 nBank); + bool IsSampleBankLoaded(uint8 nBank); + + bool IsPedCommentLoaded(uint32 nComment); + bool LoadPedComment (uint32 nComment); + + int32 _GetPedCommentSlot(uint32 nComment); + + int32 GetSampleBaseFrequency (uint32 nSample); + int32 GetSampleLoopStartOffset(uint32 nSample); + int32 GetSampleLoopEndOffset (uint32 nSample); + uint32 GetSampleLength (uint32 nSample); + + bool UpdateReverb(void); + + void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); + bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); + void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); + void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); + void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); + void SetChannelVolume (uint32 nChannel, uint32 nVolume); + void SetChannelPan (uint32 nChannel, uint32 nPan); + void SetChannelFrequency (uint32 nChannel, uint32 nFreq); + void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); + void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); + bool GetChannelUsedFlag (uint32 nChannel); + void StartChannel (uint32 nChannel); + void StopChannel (uint32 nChannel); + + void PreloadStreamedFile (uint8 nFile, uint8 nStream); + void PauseStream (uint8 nPauseFlag, uint8 nStream); + void StartPreloadedStreamedFile (uint8 nStream); + bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); + void StopStreamedFile (uint8 nStream); + int32 GetStreamedFilePosition (uint8 nStream); + void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); + int32 GetStreamedFileLength (uint8 nStream); + bool IsStreamPlaying (uint8 nStream); + bool InitialiseSampleBanks(void); +}; + +extern cSampleManager SampleManager; +extern int32 BankStartOffset[MAX_SAMPLEBANKS]; + +static char StreamedNameTable[][25]= +{ + "AUDIO\\HEAD.WAV", + "AUDIO\\CLASS.WAV", + "AUDIO\\KJAH.WAV", + "AUDIO\\RISE.WAV", + "AUDIO\\LIPS.WAV", + "AUDIO\\GAME.WAV", + "AUDIO\\MSX.WAV", + "AUDIO\\FLASH.WAV", + "AUDIO\\CHAT.WAV", + "AUDIO\\HEAD.WAV", + "AUDIO\\POLICE.WAV", + "AUDIO\\CITY.WAV", + "AUDIO\\WATER.WAV", + "AUDIO\\COMOPEN.WAV", + "AUDIO\\SUBOPEN.WAV", + "AUDIO\\JB.MP3", + "AUDIO\\BET.MP3", + "AUDIO\\L1_LG.MP3", + "AUDIO\\L2_DSB.MP3", + "AUDIO\\L3_DM.MP3", + "AUDIO\\L4_PAP.MP3", + "AUDIO\\L5_TFB.MP3", + "AUDIO\\J0_DM2.MP3", + "AUDIO\\J1_LFL.MP3", + "AUDIO\\J2_KCL.MP3", + "AUDIO\\J3_VH.MP3", + "AUDIO\\J4_ETH.MP3", + "AUDIO\\J5_DST.MP3", + "AUDIO\\J6_TBJ.MP3", + "AUDIO\\T1_TOL.MP3", + "AUDIO\\T2_TPU.MP3", + "AUDIO\\T3_MAS.MP3", + "AUDIO\\T4_TAT.MP3", + "AUDIO\\T5_BF.MP3", + "AUDIO\\S0_MAS.MP3", + "AUDIO\\S1_PF.MP3", + "AUDIO\\S2_CTG.MP3", + "AUDIO\\S3_RTC.MP3", + "AUDIO\\S5_LRQ.MP3", + "AUDIO\\S4_BDBA.MP3", + "AUDIO\\S4_BDBB.MP3", + "AUDIO\\S2_CTG2.MP3", + "AUDIO\\S4_BDBD.MP3", + "AUDIO\\S5_LRQB.MP3", + "AUDIO\\S5_LRQC.MP3", + "AUDIO\\A1_SSO.WAV", + "AUDIO\\A2_PP.WAV", + "AUDIO\\A3_SS.WAV", + "AUDIO\\A4_PDR.WAV", + "AUDIO\\A5_K2FT.WAV", + "AUDIO\\K1_KBO.MP3", + "AUDIO\\K2_GIS.MP3", + "AUDIO\\K3_DS.MP3", + "AUDIO\\K4_SHI.MP3", + "AUDIO\\K5_SD.MP3", + "AUDIO\\R0_PDR2.MP3", + "AUDIO\\R1_SW.MP3", + "AUDIO\\R2_AP.MP3", + "AUDIO\\R3_ED.MP3", + "AUDIO\\R4_GF.MP3", + "AUDIO\\R5_PB.MP3", + "AUDIO\\R6_MM.MP3", + "AUDIO\\D1_STOG.MP3", + "AUDIO\\D2_KK.MP3", + "AUDIO\\D3_ADO.MP3", + "AUDIO\\D5_ES.MP3", + "AUDIO\\D7_MLD.MP3", + "AUDIO\\D4_GTA.MP3", + "AUDIO\\D4_GTA2.MP3", + "AUDIO\\D6_STS.MP3", + "AUDIO\\A6_BAIT.WAV", + "AUDIO\\A7_ETG.WAV", + "AUDIO\\A8_PS.WAV", + "AUDIO\\A9_ASD.WAV", + "AUDIO\\K4_SHI2.MP3", + "AUDIO\\C1_TEX.MP3", + "AUDIO\\EL_PH1.MP3", + "AUDIO\\EL_PH2.MP3", + "AUDIO\\EL_PH3.MP3", + "AUDIO\\EL_PH4.MP3", + "AUDIO\\YD_PH1.MP3", + "AUDIO\\YD_PH2.MP3", + "AUDIO\\YD_PH3.MP3", + "AUDIO\\YD_PH4.MP3", + "AUDIO\\HD_PH1.MP3", + "AUDIO\\HD_PH2.MP3", + "AUDIO\\HD_PH3.MP3", + "AUDIO\\HD_PH4.MP3", + "AUDIO\\HD_PH5.MP3", + "AUDIO\\MT_PH1.MP3", + "AUDIO\\MT_PH2.MP3", + "AUDIO\\MT_PH3.MP3", + "AUDIO\\MT_PH4.MP3", + "AUDIO\\MISCOM.WAV", + "AUDIO\\END.MP3", + "AUDIO\\lib_a1.WAV", + "AUDIO\\lib_a2.WAV", + "AUDIO\\lib_a.WAV", + "AUDIO\\lib_b.WAV", + "AUDIO\\lib_c.WAV", + "AUDIO\\lib_d.WAV", + "AUDIO\\l2_a.WAV", + "AUDIO\\j4t_1.WAV", + "AUDIO\\j4t_2.WAV", + "AUDIO\\j4t_3.WAV", + "AUDIO\\j4t_4.WAV", + "AUDIO\\j4_a.WAV", + "AUDIO\\j4_b.WAV", + "AUDIO\\j4_c.WAV", + "AUDIO\\j4_d.WAV", + "AUDIO\\j4_e.WAV", + "AUDIO\\j4_f.WAV", + "AUDIO\\j6_1.WAV", + "AUDIO\\j6_a.WAV", + "AUDIO\\j6_b.WAV", + "AUDIO\\j6_c.WAV", + "AUDIO\\j6_d.WAV", + "AUDIO\\t4_a.WAV", + "AUDIO\\s1_a.WAV", + "AUDIO\\s1_a1.WAV", + "AUDIO\\s1_b.WAV", + "AUDIO\\s1_c.WAV", + "AUDIO\\s1_c1.WAV", + "AUDIO\\s1_d.WAV", + "AUDIO\\s1_e.WAV", + "AUDIO\\s1_f.WAV", + "AUDIO\\s1_g.WAV", + "AUDIO\\s1_h.WAV", + "AUDIO\\s1_i.WAV", + "AUDIO\\s1_j.WAV", + "AUDIO\\s1_k.WAV", + "AUDIO\\s1_l.WAV", + "AUDIO\\s3_a.WAV", + "AUDIO\\s3_b.WAV", + "AUDIO\\el3_a.WAV", + "AUDIO\\mf1_a.WAV", + "AUDIO\\mf2_a.WAV", + "AUDIO\\mf3_a.WAV", + "AUDIO\\mf3_b.WAV", + "AUDIO\\mf3_b1.WAV", + "AUDIO\\mf3_c.WAV", + "AUDIO\\mf4_a.WAV", + "AUDIO\\mf4_b.WAV", + "AUDIO\\mf4_c.WAV", + "AUDIO\\a1_a.WAV", + "AUDIO\\a3_a.WAV", + "AUDIO\\a5_a.WAV", + "AUDIO\\a4_a.WAV", + "AUDIO\\a4_b.WAV", + "AUDIO\\a4_c.WAV", + "AUDIO\\a4_d.WAV", + "AUDIO\\k1_a.WAV", + "AUDIO\\k3_a.WAV", + "AUDIO\\r1_a.WAV", + "AUDIO\\r2_a.WAV", + "AUDIO\\r2_b.WAV", + "AUDIO\\r2_c.WAV", + "AUDIO\\r2_d.WAV", + "AUDIO\\r2_e.WAV", + "AUDIO\\r2_f.WAV", + "AUDIO\\r2_g.WAV", + "AUDIO\\r2_h.WAV", + "AUDIO\\r5_a.WAV", + "AUDIO\\r6_a.WAV", + "AUDIO\\r6_a1.WAV", + "AUDIO\\r6_b.WAV", + "AUDIO\\lo2_a.WAV", + "AUDIO\\lo6_a.WAV", + "AUDIO\\yd2_a.WAV", + "AUDIO\\yd2_b.WAV", + "AUDIO\\yd2_c.WAV", + "AUDIO\\yd2_c1.WAV", + "AUDIO\\yd2_d.WAV", + "AUDIO\\yd2_e.WAV", + "AUDIO\\yd2_f.WAV", + "AUDIO\\yd2_g.WAV", + "AUDIO\\yd2_h.WAV", + "AUDIO\\yd2_ass.WAV", + "AUDIO\\yd2_ok.WAV", + "AUDIO\\h5_a.WAV", + "AUDIO\\h5_b.WAV", + "AUDIO\\h5_c.WAV", + "AUDIO\\ammu_a.WAV", + "AUDIO\\ammu_b.WAV", + "AUDIO\\ammu_c.WAV", + "AUDIO\\door_1.WAV", + "AUDIO\\door_2.WAV", + "AUDIO\\door_3.WAV", + "AUDIO\\door_4.WAV", + "AUDIO\\door_5.WAV", + "AUDIO\\door_6.WAV", + "AUDIO\\t3_a.WAV", + "AUDIO\\t3_b.WAV", + "AUDIO\\t3_c.WAV", + "AUDIO\\k1_b.WAV", + "AUDIO\\cat1.WAV" +}; diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp new file mode 100644 index 00000000..e8213cd9 --- /dev/null +++ b/src/audio/openal/samp_oal.cpp @@ -0,0 +1,1404 @@ +#include +#include +#include +//#include +#include +#include +#include "samp_oal.h" +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" + +#pragma comment( lib, "libmpg123.lib" ) +#pragma comment( lib, "OpenAL32.lib" ) + +cSampleManager SampleManager; +int32 BankStartOffset[MAX_SAMPLEBANKS]; + + +/////////////////////////////////////////////////////////////// +class MP3Stream +{ +public: + mpg123_handle *m_pMPG; + FILE *m_fpFile; + unsigned char *m_pBuf; + char m_aFilename[128]; + size_t m_nBufSize; + size_t m_nLengthInBytes; + long m_nRate; + int m_nBitRate; + int m_nChannels; + int m_nEncoding; + int m_nLength; + int m_nBlockSize; + int m_nNumBlocks; + ALuint m_alSource; + ALuint m_alBuffers[5]; + unsigned char *m_pBlocks; + bool m_bIsFree; + bool m_bIsOpened; + bool m_bIsPaused; + int m_nVolume; + + void Initialize(void); + bool FillBuffer(ALuint alBuffer); + void Update(void); + void SetPos(uint32 nPos); + int32 FillBuffers(); + MP3Stream(char *filename, ALuint source, ALuint *buffers); + ~MP3Stream() { Delete(); } + void Delete(); + +}; +/////////////////////////////////////////////////////////////// + +char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; +char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; + +FILE *fpSampleDescHandle; +FILE *fpSampleDataHandle; +bool bSampleBankLoaded [MAX_SAMPLEBANKS]; +int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; +int32 nSampleBankSize [MAX_SAMPLEBANKS]; +int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; +int32 _nSampleDataEndOffset; + +int32 nPedSlotSfx [MAX_PEDSFX]; +int32 nPedSlotSfxAddr[MAX_PEDSFX]; +uint8 nCurrentPedSlot; + + + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; + +/////////////////////////////////////////////////////////////// +ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS]; +ALuint ALStreamSources[MAX_STREAMS]; +ALuint ALStreamBuffers[MAX_STREAMS][5]; +struct +{ + ALuint buffer; + ALuint timer; +}ALBuffers[SAMPLEBANK_MAX]; + +ALuint pedBuffers[MAX_PEDSFX]; +//bank0Buffers + +uint32 nNumMP3s; + +MP3Stream *mp3Stream[MAX_STREAMS]; +int8 nStreamPan [MAX_STREAMS]; +int8 nStreamVolume[MAX_STREAMS]; + +float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS]; +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; +uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS]; +int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS]; +int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS]; +int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + + +cSampleManager::cSampleManager(void) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL); + free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); + + if ( fpSampleDescHandle != NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + } + + if ( fpSampleDataHandle != NULL ) + { + fclose(fpSampleDataHandle); + fpSampleDataHandle = NULL; + } +} + +void cSampleManager::SetSpeakerConfig(int32 nConfig) +{ + +} + +uint32 cSampleManager::GetMaximumSupportedChannels(void) +{ + return 20; +} + +uint32 cSampleManager::GetNum3DProvidersAvailable() +{ + return 1; +} + +void cSampleManager::SetNum3DProvidersAvailable(uint32 num) +{ + ; +} + +char *cSampleManager::Get3DProviderName(uint8 id) +{ + static char PROVIDER[256] = "OpenAL"; + return PROVIDER; +} + +void cSampleManager::Set3DProviderName(uint8 id, char *name) +{ + ; +} + +int8 cSampleManager::GetCurrent3DProviderIndex(void) +{ + return 0; +} + +int8 cSampleManager::SetCurrent3DProvider(uint8 which) +{ + return 0; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + + +void cSampleManager::ReleaseDigitalHandle(void) +{ + +} + +void cSampleManager::ReacquireDigitalHandle(void) +{ + +} + +bool +cSampleManager::Initialise(void) +{ + ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; + + m_pDevice = alcOpenDevice(NULL); + ASSERT(m_pDevice != NULL); + + m_pContext = alcCreateContext(m_pDevice, attr); + ASSERT(m_pContext != NULL); + + alcMakeContextCurrent(m_pContext); + + mpg123_init(); + + + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = MAX_FREQ; + m_aSamples[i].nLoopStart = 0; + m_aSamples[i].nLoopEnd = -1; + } + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + nStreamLength[i] = 3600000; + + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + mp3Stream[i] = NULL; + nStreamVolume[i] = 100; + nStreamPan[i] = 63; + } + + alGenSources(MAX_STREAMS, (ALuint *)ALStreamSources); + alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers); + + m_nMonoMode = 0; + + m_nEffectsVolume = MAX_VOLUME; + m_nMusicVolume = MAX_VOLUME; + m_nEffectsFadeVolume = MAX_VOLUME; + m_nMusicFadeVolume = MAX_VOLUME; + + + memset(alChannel, 0, sizeof(alChannel)); + memset(nChannelVolume, 0, sizeof(nChannelVolume)); + memset(ChannelSample, 0, sizeof(ChannelSample)); + + for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ ) + ChannelPitch[i] = 1.0f; + + + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + + alGenBuffers(MAX_PEDSFX, pedBuffers); + + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + ALBuffers[i].buffer = 0; + ALBuffers[i].timer = 0; + } + + alListenerf (AL_GAIN, 1.0f); + alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); + alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f); + ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; + alListenerfv(AL_ORIENTATION, orientation); + + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]); + ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL); + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX); + ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL); + + alGenSources(MAXCHANNELS, alChannel); + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + { + if ( alChannel[i] ) + alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE); + } + + alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]); + if ( alChannel[CHANNEL2D] ) + { + alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f); + } + + LoadSampleBank(SAMPLEBANK_MAIN); + + return true; +} + +void +cSampleManager::Terminate(void) +{ + mpg123_exit(); + alcMakeContextCurrent(NULL); + alcDestroyContext(m_pContext); + alcCloseDevice(m_pDevice); +} + +void +cSampleManager::UpdateSoundBuffers(void) +{ + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + if ( ALBuffers[i].timer > 0 ) + { + ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f); + + if ( ALBuffers[i].timer <= 0 ) + { + if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) ) + { + alDeleteBuffers(1, &ALBuffers[i].buffer); + + if ( alGetError() == AL_NO_ERROR ) + ALBuffers[i].buffer = 0; + else + ALBuffers[i].buffer = 120000; + } + } + } + } +} + +bool cSampleManager::CheckForAnAudioFileOnCD(void) +{ + return true; +} + +char cSampleManager::GetCDAudioDriveLetter(void) +{ + return '\0'; +} + +void +cSampleManager::SetEffectsMasterVolume(uint8 nVolume) +{ + m_nEffectsVolume = nVolume; +} + +void +cSampleManager::SetMusicMasterVolume(uint8 nVolume) +{ + m_nMusicVolume = nVolume; +} + +void +cSampleManager::SetEffectsFadeVolume(uint8 nVolume) +{ + m_nEffectsFadeVolume = nVolume; +} + +void +cSampleManager::SetMusicFadeVolume(uint8 nVolume) +{ + m_nMusicFadeVolume = nVolume; +} + +void +cSampleManager::SetMonoMode(uint8 nMode) +{ + m_nMonoMode = nMode; +} + +bool +cSampleManager::LoadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + if ( CTimer::GetIsCodePaused() ) + return false; + + if ( MusicManager.IsInitialised() + && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && nBank != SAMPLEBANK_MAIN ) + { + return false; + } + + if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + return false; + + if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] ) + return false; + + bSampleBankLoaded[nBank] = true; + + return true; +} + +void +cSampleManager::UnloadSampleBank(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + + ; // NOIMP +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + ASSERT( nBank < MAX_SAMPLEBANKS ); + return true; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + uint8 slot; + + for ( int32 i = 0; i < _TODOCONST(3); i++ ) + { + slot = nCurrentPedSlot - i - 1; + if ( nComment == nPedSlotSfx[slot] ) + return true; + } + + return false; +} + + +int32 +cSampleManager::_GetPedCommentSlot(uint32 nComment) +{ + uint8 slot; + + for (int32 i = 0; i < _TODOCONST(3); i++) + { + slot = nCurrentPedSlot - i - 1; + if (nComment == nPedSlotSfx[slot]) + return slot; + } + + return -1; +} + +bool +cSampleManager::LoadPedComment(uint32 nComment) +{ + ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); + + if ( CTimer::GetIsCodePaused() ) + return false; + + // no talking peds during cutsenes or the game end + if ( MusicManager.IsInitialised() ) + { + switch ( MusicManager.GetMusicMode() ) + { + case MUSICMODE_CUTSCENE: + { + return false; + + break; + } + + case MUSICMODE_FRONTEND: + { + if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED ) + return false; + + break; + } + } + } + + if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) + return false; + + if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) + return false; + + nPedSlotSfx[nCurrentPedSlot] = nComment; + + alBufferData(pedBuffers[nCurrentPedSlot], + AL_FORMAT_MONO16, + (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), + m_aSamples[nComment].nSize, + MAX_FREQ); + + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) + nCurrentPedSlot = 0; + + return true; +} + +int32 +cSampleManager::GetBankContainingSound(uint32 offset) +{ + if ( offset >= BankStartOffset[SAMPLEBANK_PED] ) + return SAMPLEBANK_PED; + + if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] ) + return SAMPLEBANK_MAIN; + + return SAMPLEBANK_INVALID; +} + +int32 +cSampleManager::GetSampleBaseFrequency(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); + return m_aSamples[nSample].nSize >> 1; +} + +bool cSampleManager::UpdateReverb(void) +{ + return false; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + ; // NOIMP +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + ALuint buffer; + + if ( nSfx < SAMPLEBANK_MAX ) + { + int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset; + int32 size = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize; + + void *data = malloc(size); + ASSERT(data != NULL); + + if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) + { + free(data); + return false; + } + + if ( fread(data, 1, size, fpSampleDataHandle) != size ) + { + free(data); + return false; + } + + ALuint buf; + alGenBuffers(1, &buf); + alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ); + free(data); + + if ( !IsSampleBankLoaded(nBank) ) + return false; + + ALBuffers[nSfx].buffer = buf; + ALBuffers[nSfx].timer = 120000; + + buffer = ALBuffers[nSfx].buffer; + + ChannelSample[nChannel] = nSfx; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + + buffer = pedBuffers[slot]; + } + + if ( buffer == 0 ) + { + TRACE("No buffer to play id %d", nSfx); + return false; + } + + if ( GetChannelUsedFlag(nChannel) ) + { + TRACE("Stopping channel %d - really!!!", nChannel); + StopChannel(nChannel); + } + + alSourcei(alChannel[nChannel], AL_BUFFER, 0); + currentChannelVolume [nChannel] = -1; + currentChannelFrequency [nChannel] = -1; + currentChannelMaxFrontDistance[nChannel] = -1; + + if ( alChannel[nChannel] ) + { + alSourcei(alChannel[nChannel], AL_BUFFER, buffer); + alSourcef(alChannel[nChannel], AL_PITCH, 1.0f); + ChannelPitch[nChannel] = 1.0f; + return true; + } + + return false; +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // reduce the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] >>= 2; + } + + uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14; + if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack + channelVol >>= 1; + + if ( alChannel[nChannel] ) + { + if ( currentChannelVolume[nChannel] != channelVol ) + { + ALfloat gain = ALfloat(channelVol) / MAX_VOLUME; + alSourcef(alChannel[nChannel], AL_GAIN, gain); + currentChannelVolume[nChannel] = channelVol; + } + } +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ); + } +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax ) + { + alSourcef(alChannel[nChannel], AL_MAX_DISTANCE, fMax); + alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f); + alSourcef(alChannel[nChannel], AL_MAX_GAIN, 1.0f); + currentChannelMaxFrontDistance[nChannel] = int32(fMax); + } + } +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nChannel == CHANNEL2D ) + { + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nChannelVolume[nChannel] = vol; + + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO + && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) + { + nChannelVolume[nChannel] >>= 2; + } + + uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14; + if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack + channelVol >>= 1; + + if ( alChannel[nChannel] ) + { + if ( currentChannelVolume[nChannel] != channelVol ) + { + ALfloat gain = ALfloat(channelVol) / MAX_VOLUME; + alSourcef(alChannel[nChannel], AL_GAIN, gain); + currentChannelVolume[nChannel] = channelVol; + } + } + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + ; // NOIMP +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + if ( currentChannelFrequency[nChannel] != nFreq ) + { + ALfloat pitch = ALfloat(nFreq) / MAX_FREQ; + alSourcef(alChannel[nChannel], AL_PITCH, pitch); + currentChannelFrequency[nChannel] = nFreq; + + if ( Abs(1.0f - pitch) < 0.01f ) + ChannelPitch[nChannel] = 1.0f; + else + ChannelPitch[nChannel] = pitch; + } + } +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + ; // NOIMP +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( nLoopCount != 0 ) + alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE); + else + alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE); +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + ALint sourceState; + alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState); + return sourceState == AL_PLAYING; + } + + return false; +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank + { + if ( ChannelPitch[nChannel] != 1.0f ) + ChannelPitch[nChannel] = 1.0f; + } + + alSourcef (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]); + alSourcePlay(alChannel[nChannel]); + } +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); + + if ( alChannel[nChannel] ) + { + alSourceStop(alChannel[nChannel]); + + currentChannelVolume [nChannel] = -1; + currentChannelFrequency [nChannel] = -1; + currentChannelMaxFrontDistance[nChannel] = -1; + ChannelPitch [nChannel] = 1.0f; + } +} + +void +cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) +{ + char filename[256]; + + ASSERT( nStream < MAX_STREAMS ); + + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + delete mp3Stream[nStream]; + mp3Stream[nStream] = NULL; + } + + strcpy(filename, StreamedNameTable[nFile]); + + MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + mp3Stream[nStream] = stream; + + if ( stream->m_bIsOpened ) + { + ; + } + else + { + delete stream; + mp3Stream[nStream] = NULL; + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream ) + { + if ( nPauseFlag != 0 ) + { + if ( !stream->m_bIsPaused ) + { + alSourcePause(stream->m_alSource); + stream->m_bIsPaused = true; + } + } + else + { + if ( stream->m_bIsPaused ) + { + alSourcef(stream->m_alSource, AL_PITCH, 1.0f); + alSourcePlay(stream->m_alSource); + stream->m_bIsPaused = false; + } + } + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream ) + { + stream->Initialize(); + if ( stream->m_bIsOpened ) + { + //NOTE: set pos here on mobile + + if ( stream->FillBuffers() != 0 ) + { + alSourcef(stream->m_alSource, AL_PITCH, 1.0f); + alSourcePlay(stream->m_alSource); + stream->m_bIsFree = false; + } + } + } +} + +bool +cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) +{ + char filename[256]; + + ASSERT( nStream < MAX_STREAMS ); + + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + delete mp3Stream[nStream]; + mp3Stream[nStream] = NULL; + } + + strcpy(filename, StreamedNameTable[nFile]); + + MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + mp3Stream[nStream] = stream; + + if ( stream->m_bIsOpened ) + { + stream->Initialize(); + nStreamLength[nFile] = stream->m_nLength; + //MusicManager.SetTrackInfoLength(nFile, stream->m_nLength); + + if ( stream->m_bIsOpened ) + { + if ( nPos != 0 ) + { + stream->SetPos(nPos); + } + + if ( stream->FillBuffers() != 0 ) + { + alSourcef(stream->m_alSource, AL_PITCH, 1.0f); + alSourcePlay(stream->m_alSource); + stream->m_bIsFree = false; + } + } + + return true; + } + else + { + delete stream; + mp3Stream[nStream] = NULL; + } + } + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream ) + { + delete stream; + mp3Stream[nStream] = NULL; + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream ) + { + return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate; + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + if ( nVolume > MAX_VOLUME ) + nVolume = MAX_VOLUME; + + if ( nPan > MAX_VOLUME ) + nPan = MAX_VOLUME; + + nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume; + nStreamPan [nStream] = nPan; + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream ) + { + uint32 vol; + if ( nEffectFlag ) + vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14; + else + vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14; + + if ( stream->m_nVolume != vol ) + { + if ( stream->m_bIsOpened ) + { + ALuint source = stream->m_alSource; + if ( source ) + { + ALfloat gain = ALfloat(vol) / MAX_VOLUME; + alSourcef(source, AL_GAIN, gain); + stream = mp3Stream[nStream]; + } + } + + stream->m_nVolume = vol; + } + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + ASSERT( nStream < TOTAL_STREAMED_SOUNDS ); + + return nStreamLength[nStream]; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + ASSERT( nStream < MAX_STREAMS ); + + MP3Stream *stream = mp3Stream[nStream]; + + if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused ) + { + ALint sourceState; + alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState); + if ( !stream->m_bIsFree || sourceState == AL_PLAYING ) + return true; + } + + return false; +} + +void +cSampleManager::Service(void) +{ + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + if ( mp3Stream[i] ) + mp3Stream[i]->Update(); + } + + UpdateSoundBuffers(); +} + +bool +cSampleManager::InitialiseSampleBanks(void) +{ + int32 nBank = SAMPLEBANK_MAIN; + + fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); + if ( fpSampleDescHandle == NULL ) + return false; + + fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); + if ( fpSampleDataHandle == NULL ) + { + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + return false; + } + + fseek(fpSampleDataHandle, 0, SEEK_END); + int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle); + rewind(fpSampleDataHandle); + + fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); + + fclose(fpSampleDescHandle); + fpSampleDescHandle = NULL; + + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i ) + { + nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; + nBank++; + } + } + + nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN]; + nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED]; + + return true; +} + +/* +sub_1D8D40 +PreloadSoundBank(tSample *,uchar) +CheckOpenALChannels(void) +*/ + +void MP3Stream::Initialize(void) +{ + if ( !m_bIsOpened ) + return; + + mpg123_format_none(m_pMPG); + + mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); + mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); + mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); + mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16); + + if ( mpg123_open_feed(m_pMPG) != MPG123_OK ) + return; + + const uint32 CHUNK_SIZE = 1024*5; + + if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE ) + { + Delete(); + return; + } + + m_nBufSize -= CHUNK_SIZE; + + mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE); + + if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK ) + { + Delete(); + return; + } + + mpg123_frameinfo info; + if ( mpg123_info(m_pMPG, &info) != MPG123_OK ) + { + Delete(); + return; + } + + m_nBitRate = info.bitrate; + m_nLength = 8 * m_nLengthInBytes / info.bitrate; + m_nBlockSize = mpg123_outblock(m_pMPG); + m_nNumBlocks = 5; + m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize); +} + +bool MP3Stream::FillBuffer(ALuint alBuffer) +{ + size_t done; + + uint8 *pBlockBuff = (uint8 *)m_pBlocks; + + bool fail = !(m_nBufSize > 1); + + int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done); + if ( alBuffer == 0 ) + { + if ( err == MPG123_OK ) + { + while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK ) + ; + } + + return true; + } + + int32 blocks = 0; + for ( blocks = 0; blocks < m_nNumBlocks; blocks++ ) + { + if ( err == MPG123_NEED_MORE ) + { + if ( fail ) + break; + + size_t readSize = m_nBufSize; + if ( readSize > 0x4000 ) + { + if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 ) + { + fail = true; + TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing"); + break; + } + + m_nBufSize -= 0x4000; + mpg123_feed(m_pMPG, m_pBuf, 0x4000); + } + else + { + if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize ) + { + fail = true; + break; + } + + m_nBufSize -= readSize; + mpg123_feed(m_pMPG, m_pBuf, readSize); + } + } + else if ( err == MPG123_OK ) + { + pBlockBuff += m_nBlockSize; + } + else + { + fail = true; + break; + } + + err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done); + } + + if ( blocks != 0 ) + { + if ( m_nChannels == 1 ) + alBufferData(alBuffer, AL_FORMAT_MONO16, m_pBlocks, m_nBlockSize*blocks, m_nRate); + else + alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate); + } + + if ( fail && blocks < m_nNumBlocks ) + m_bIsFree = true; + + return blocks != 0; +} + +void MP3Stream::Update(void) +{ + if ( !m_bIsOpened ) + return; + + if ( m_bIsFree ) + return; + + if ( !m_bIsPaused ) + { + ALint sourceState; + ALint buffersProcessed = 0; + + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); + + ALint looping = AL_FALSE; + alGetSourcei(m_alSource, AL_LOOPING, &looping); + + if ( looping == AL_TRUE ) + { + TRACE("stream set looping"); + alSourcei(m_alSource, AL_LOOPING, AL_TRUE); + } + + while( buffersProcessed-- ) + { + ALuint buffer; + + alSourceUnqueueBuffers(m_alSource, 1, &buffer); + + if ( !m_bIsFree && FillBuffer(buffer) ) + alSourceQueueBuffers(m_alSource, 1, &buffer); + } + + if ( sourceState != AL_PLAYING ) + { + alSourcef(m_alSource, AL_PITCH, 1.0f); + alSourcePlay(m_alSource); + } + } +} + +void MP3Stream::SetPos(uint32 nPos) +{ + uint32 pos = nPos; + if ( nPos > m_nLength ) + pos %= m_nLength; + + uint32 blockPos = m_nBitRate * pos / 8; + if ( blockPos > m_nLengthInBytes ) + blockPos %= m_nLengthInBytes; + + fseek(m_fpFile, blockPos, SEEK_SET); + + size_t done; + while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK ) + ; +} + +int32 MP3Stream::FillBuffers() +{ + int32 i = 0; + for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ ) + { + if ( !FillBuffer(m_alBuffers[i]) ) + break; + alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]); + } + + return i; +} + +MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers) +{ + strcpy(m_aFilename, filename); + memset(m_alBuffers, 0, sizeof(m_alBuffers)); + m_alSource = source; + memcpy(m_alBuffers, buffers, sizeof(m_alBuffers)); + m_nVolume = -1; + m_pBlocks = NULL; + m_pBuf = NULL; + m_pMPG = NULL; + m_bIsPaused = false; + m_bIsOpened = true; + m_bIsFree = true; + m_fpFile = fopen(m_aFilename, "rb"); + + if ( m_fpFile ) + { + m_nBufSize = filelength(fileno(m_fpFile)); + m_nLengthInBytes = m_nBufSize; + m_pMPG = mpg123_new(NULL, NULL); + m_pBuf = (unsigned char *)malloc(0x4000); + } + else + { + m_bIsOpened = false; + Delete(); + } +} + +void MP3Stream::Delete() +{ + if ( m_pMPG ) + { + mpg123_delete(m_pMPG); + m_pMPG = NULL; + } + + if ( m_fpFile ) + { + fclose(m_fpFile); + m_fpFile = NULL; + } + + if ( m_alSource ) + { + ALint sourceState = AL_STOPPED; + alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED ) + alSourceStop(m_alSource); + + ALint buffersQueued; + alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued); + + ALuint value; + while (buffersQueued--) + alSourceUnqueueBuffers(m_alSource, 1, &value); + + m_alSource = 0; + } + + if ( m_pBlocks ) + { + free(m_pBlocks); + m_pBlocks = NULL; + } + + if ( m_pBuf ) + { + free(m_pBuf); + m_pBuf = NULL; + } + + m_bIsOpened = false; +} \ No newline at end of file diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h new file mode 100644 index 00000000..8bbdbcc9 --- /dev/null +++ b/src/audio/openal/samp_oal.h @@ -0,0 +1,340 @@ +#pragma once +#include "common.h" +#include "AudioSamples.h" + +#define MAX_VOLUME 127 +//#define MAX_FREQ 22050 +#define MAX_FREQ 32000 + +struct tSample { + int32 nOffset; + uint32 nSize; + int32 nFrequency; + int32 nLoopStart; + int32 nLoopEnd; +}; + +enum +{ + SAMPLEBANK_MAIN, + SAMPLEBANK_PED, + MAX_SAMPLEBANKS, + SAMPLEBANK_INVALID +}; + +#define MAX_PEDSFX 7 +#define PED_BLOCKSIZE 79000 + + +//#define MAXCHANNELS 21 android +#define MAXCHANNELS 28 +#define MAX2DCHANNELS 1 +#define CHANNEL2D MAXCHANNELS + +#define MAX_STREAMS 2 + +struct ALCdevice_struct; +struct ALCcontext_struct; +typedef struct ALCdevice_struct ALCdevice; +typedef struct ALCcontext_struct ALCcontext; + +class cSampleManager +{ + int field_0; + ALCdevice *m_pDevice; + ALCcontext *m_pContext; + + uint8 m_nEffectsVolume; + uint8 m_nMusicVolume; + uint8 m_nEffectsFadeVolume; + uint8 m_nMusicFadeVolume; + uint8 m_nMonoMode; + char _pad0[3]; + tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; + +public: + + + + cSampleManager(void); + ~cSampleManager(void); + + void SetSpeakerConfig(int32 nConfig); + uint32 GetMaximumSupportedChannels(void); + + uint32 GetNum3DProvidersAvailable(); + void SetNum3DProvidersAvailable(uint32 num); + + char *Get3DProviderName(uint8 id); + void Set3DProviderName(uint8 id, char *name); + + int8 GetCurrent3DProviderIndex(void); + int8 SetCurrent3DProvider(uint8 which); + + bool IsMP3RadioChannelAvailable(void); + + void ReleaseDigitalHandle (void); + void ReacquireDigitalHandle(void); + + bool Initialise(void); + void Terminate (void); + + void UpdateSoundBuffers(void); + + bool CheckForAnAudioFileOnCD(void); + char GetCDAudioDriveLetter (void); + + void UpdateEffectsVolume(void); + + void SetEffectsMasterVolume(uint8 nVolume); + void SetMusicMasterVolume (uint8 nVolume); + void SetEffectsFadeVolume (uint8 nVolume); + void SetMusicFadeVolume (uint8 nVolume); + void SetMonoMode (uint8 nMode); + + bool LoadSampleBank (uint8 nBank); + void UnloadSampleBank (uint8 nBank); + bool IsSampleBankLoaded(uint8 nBank); + + bool IsPedCommentLoaded(uint32 nComment); + bool LoadPedComment (uint32 nComment); + int32 GetBankContainingSound(uint32 offset); + + int32 _GetPedCommentSlot(uint32 nComment); + + int32 GetSampleBaseFrequency (uint32 nSample); + int32 GetSampleLoopStartOffset(uint32 nSample); + int32 GetSampleLoopEndOffset (uint32 nSample); + uint32 GetSampleLength (uint32 nSample); + + bool UpdateReverb(void); + + void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); + bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); + void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); + void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); + void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); + void SetChannelVolume (uint32 nChannel, uint32 nVolume); + void SetChannelPan (uint32 nChannel, uint32 nPan); + void SetChannelFrequency (uint32 nChannel, uint32 nFreq); + void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); + void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); + bool GetChannelUsedFlag (uint32 nChannel); + void StartChannel (uint32 nChannel); + void StopChannel (uint32 nChannel); + + void PreloadStreamedFile (uint8 nFile, uint8 nStream); + void PauseStream (uint8 nPauseFlag, uint8 nStream); + void StartPreloadedStreamedFile (uint8 nStream); + bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); + void StopStreamedFile (uint8 nStream); + int32 GetStreamedFilePosition (uint8 nStream); + void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); + int32 GetStreamedFileLength (uint8 nStream); + bool IsStreamPlaying (uint8 nStream); + void Service(void); + bool InitialiseSampleBanks(void); +}; + +extern cSampleManager SampleManager; +extern int32 BankStartOffset[MAX_SAMPLEBANKS]; + +static char StreamedNameTable[][25]= +{ + "AUDIO\\HEAD.MP3", + "AUDIO\\CLASS.MP3", + "AUDIO\\KJAH.MP3", + "AUDIO\\RISE.MP3", + "AUDIO\\LIPS.MP3", + "AUDIO\\GAME.MP3", + "AUDIO\\MSX.MP3", + "AUDIO\\FLASH.MP3", + "AUDIO\\CHAT.MP3", + "AUDIO\\HEAD.MP3", + "AUDIO\\POLICE.MP3", + "AUDIO\\CITY.MP3", + "AUDIO\\WATER.MP3", + "AUDIO\\COMOPEN.MP3", + "AUDIO\\SUBOPEN.MP3", + "AUDIO\\JB.MP3", + "AUDIO\\BET.MP3", + "AUDIO\\L1_LG.MP3", + "AUDIO\\L2_DSB.MP3", + "AUDIO\\L3_DM.MP3", + "AUDIO\\L4_PAP.MP3", + "AUDIO\\L5_TFB.MP3", + "AUDIO\\J0_DM2.MP3", + "AUDIO\\J1_LFL.MP3", + "AUDIO\\J2_KCL.MP3", + "AUDIO\\J3_VH.MP3", + "AUDIO\\J4_ETH.MP3", + "AUDIO\\J5_DST.MP3", + "AUDIO\\J6_TBJ.MP3", + "AUDIO\\T1_TOL.MP3", + "AUDIO\\T2_TPU.MP3", + "AUDIO\\T3_MAS.MP3", + "AUDIO\\T4_TAT.MP3", + "AUDIO\\T5_BF.MP3", + "AUDIO\\S0_MAS.MP3", + "AUDIO\\S1_PF.MP3", + "AUDIO\\S2_CTG.MP3", + "AUDIO\\S3_RTC.MP3", + "AUDIO\\S5_LRQ.MP3", + "AUDIO\\S4_BDBA.MP3", + "AUDIO\\S4_BDBB.MP3", + "AUDIO\\S2_CTG2.MP3", + "AUDIO\\S4_BDBD.MP3", + "AUDIO\\S5_LRQB.MP3", + "AUDIO\\S5_LRQC.MP3", + "AUDIO\\A1_SSO.MP3", + "AUDIO\\A2_PP.MP3", + "AUDIO\\A3_SS.MP3", + "AUDIO\\A4_PDR.MP3", + "AUDIO\\A5_K2FT.MP3", + "AUDIO\\K1_KBO.MP3", + "AUDIO\\K2_GIS.MP3", + "AUDIO\\K3_DS.MP3", + "AUDIO\\K4_SHI.MP3", + "AUDIO\\K5_SD.MP3", + "AUDIO\\R0_PDR2.MP3", + "AUDIO\\R1_SW.MP3", + "AUDIO\\R2_AP.MP3", + "AUDIO\\R3_ED.MP3", + "AUDIO\\R4_GF.MP3", + "AUDIO\\R5_PB.MP3", + "AUDIO\\R6_MM.MP3", + "AUDIO\\D1_STOG.MP3", + "AUDIO\\D2_KK.MP3", + "AUDIO\\D3_ADO.MP3", + "AUDIO\\D5_ES.MP3", + "AUDIO\\D7_MLD.MP3", + "AUDIO\\D4_GTA.MP3", + "AUDIO\\D4_GTA2.MP3", + "AUDIO\\D6_STS.MP3", + "AUDIO\\A6_BAIT.MP3", + "AUDIO\\A7_ETG.MP3", + "AUDIO\\A8_PS.MP3", + "AUDIO\\A9_ASD.MP3", + "AUDIO\\K4_SHI2.MP3", + "AUDIO\\C1_TEX.MP3", + "AUDIO\\EL_PH1.MP3", + "AUDIO\\EL_PH2.MP3", + "AUDIO\\EL_PH3.MP3", + "AUDIO\\EL_PH4.MP3", + "AUDIO\\YD_PH1.MP3", + "AUDIO\\YD_PH2.MP3", + "AUDIO\\YD_PH3.MP3", + "AUDIO\\YD_PH4.MP3", + "AUDIO\\HD_PH1.MP3", + "AUDIO\\HD_PH2.MP3", + "AUDIO\\HD_PH3.MP3", + "AUDIO\\HD_PH4.MP3", + "AUDIO\\HD_PH5.MP3", + "AUDIO\\MT_PH1.MP3", + "AUDIO\\MT_PH2.MP3", + "AUDIO\\MT_PH3.MP3", + "AUDIO\\MT_PH4.MP3", + "AUDIO\\MISCOM.MP3", + "AUDIO\\END.MP3", + "AUDIO\\lib_a1.MP3", + "AUDIO\\lib_a2.MP3", + "AUDIO\\lib_a.MP3", + "AUDIO\\lib_b.MP3", + "AUDIO\\lib_c.MP3", + "AUDIO\\lib_d.MP3", + "AUDIO\\l2_a.MP3", + "AUDIO\\j4t_1.MP3", + "AUDIO\\j4t_2.MP3", + "AUDIO\\j4t_3.MP3", + "AUDIO\\j4t_4.MP3", + "AUDIO\\j4_a.MP3", + "AUDIO\\j4_b.MP3", + "AUDIO\\j4_c.MP3", + "AUDIO\\j4_d.MP3", + "AUDIO\\j4_e.MP3", + "AUDIO\\j4_f.MP3", + "AUDIO\\j6_1.MP3", + "AUDIO\\j6_a.MP3", + "AUDIO\\j6_b.MP3", + "AUDIO\\j6_c.MP3", + "AUDIO\\j6_d.MP3", + "AUDIO\\t4_a.MP3", + "AUDIO\\s1_a.MP3", + "AUDIO\\s1_a1.MP3", + "AUDIO\\s1_b.MP3", + "AUDIO\\s1_c.MP3", + "AUDIO\\s1_c1.MP3", + "AUDIO\\s1_d.MP3", + "AUDIO\\s1_e.MP3", + "AUDIO\\s1_f.MP3", + "AUDIO\\s1_g.MP3", + "AUDIO\\s1_h.MP3", + "AUDIO\\s1_i.MP3", + "AUDIO\\s1_j.MP3", + "AUDIO\\s1_k.MP3", + "AUDIO\\s1_l.MP3", + "AUDIO\\s3_a.MP3", + "AUDIO\\s3_b.MP3", + "AUDIO\\el3_a.MP3", + "AUDIO\\mf1_a.MP3", + "AUDIO\\mf2_a.MP3", + "AUDIO\\mf3_a.MP3", + "AUDIO\\mf3_b.MP3", + "AUDIO\\mf3_b1.MP3", + "AUDIO\\mf3_c.MP3", + "AUDIO\\mf4_a.MP3", + "AUDIO\\mf4_b.MP3", + "AUDIO\\mf4_c.MP3", + "AUDIO\\a1_a.MP3", + "AUDIO\\a3_a.MP3", + "AUDIO\\a5_a.MP3", + "AUDIO\\a4_a.MP3", + "AUDIO\\a4_b.MP3", + "AUDIO\\a4_c.MP3", + "AUDIO\\a4_d.MP3", + "AUDIO\\k1_a.MP3", + "AUDIO\\k3_a.MP3", + "AUDIO\\r1_a.MP3", + "AUDIO\\r2_a.MP3", + "AUDIO\\r2_b.MP3", + "AUDIO\\r2_c.MP3", + "AUDIO\\r2_d.MP3", + "AUDIO\\r2_e.MP3", + "AUDIO\\r2_f.MP3", + "AUDIO\\r2_g.MP3", + "AUDIO\\r2_h.MP3", + "AUDIO\\r5_a.MP3", + "AUDIO\\r6_a.MP3", + "AUDIO\\r6_a1.MP3", + "AUDIO\\r6_b.MP3", + "AUDIO\\lo2_a.MP3", + "AUDIO\\lo6_a.MP3", + "AUDIO\\yd2_a.MP3", + "AUDIO\\yd2_b.MP3", + "AUDIO\\yd2_c.MP3", + "AUDIO\\yd2_c1.MP3", + "AUDIO\\yd2_d.MP3", + "AUDIO\\yd2_e.MP3", + "AUDIO\\yd2_f.MP3", + "AUDIO\\yd2_g.MP3", + "AUDIO\\yd2_h.MP3", + "AUDIO\\yd2_ass.MP3", + "AUDIO\\yd2_ok.MP3", + "AUDIO\\h5_a.MP3", + "AUDIO\\h5_b.MP3", + "AUDIO\\h5_c.MP3", + "AUDIO\\ammu_a.MP3", + "AUDIO\\ammu_b.MP3", + "AUDIO\\ammu_c.MP3", + "AUDIO\\door_1.MP3", + "AUDIO\\door_2.MP3", + "AUDIO\\door_3.MP3", + "AUDIO\\door_4.MP3", + "AUDIO\\door_5.MP3", + "AUDIO\\door_6.MP3", + "AUDIO\\t3_a.MP3", + "AUDIO\\t3_b.MP3", + "AUDIO\\t3_c.MP3", + "AUDIO\\k1_b.MP3", + "AUDIO\\cat1.MP3" +}; diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp index a375b847..aa6b67dc 100644 --- a/src/audio/sampman.cpp +++ b/src/audio/sampman.cpp @@ -1,2257 +1,7 @@ -#include -#include -#include - -#include - -#include "eax.h" -#include "eax-util.h" -#include "mss.h" - -#include "sampman.h" -#include "AudioManager.h" -#include "MusicManager.h" -#include "Frontend.h" -#include "Timer.h" - - -#pragma comment( lib, "mss32.lib" ) - -cSampleManager SampleManager; -int32 BankStartOffset[MAX_SAMPLEBANKS]; -/////////////////////////////////////////////////////////////// - -char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; -char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; - -FILE *fpSampleDescHandle; -FILE *fpSampleDataHandle; -bool bSampleBankLoaded [MAX_SAMPLEBANKS]; -int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS]; -int32 nSampleBankSize [MAX_SAMPLEBANKS]; -int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS]; -int32 _nSampleDataEndOffset; - -int32 nPedSlotSfx [MAX_PEDSFX]; -int32 nPedSlotSfxAddr[MAX_PEDSFX]; -uint8 nCurrentPedSlot; - -uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; - -uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; - -/////////////////////////////////////////////////////////////// -struct tMP3Entry -{ - char aFilename[MAX_PATH]; - - uint32 nTrackLength; - uint32 nTrackStreamPos; - - tMP3Entry *pNext; - char *pLinkPath; -}; - -uint32 nNumMP3s; -tMP3Entry *_pMP3List; -char _mp3DirectoryPath[MAX_PATH]; -HSTREAM mp3Stream [MAX_MP3STREAMS]; -int8 nStreamPan [MAX_MP3STREAMS]; -int8 nStreamVolume[MAX_MP3STREAMS]; -uint32 _CurMP3Index; -int32 _CurMP3Pos; -bool _bIsMp3Active; - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) -bool _bUseHDDAudio; -char _aHDDPath[MAX_PATH]; -#endif -/////////////////////////////////////////////////////////////// - - -bool _bSampmanInitialised = false; - -// -// Miscellaneous globals / defines - -// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS - -EAXLISTENERPROPERTIES StartEAX3 = - {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; - -EAXLISTENERPROPERTIES FinishEAX3 = - {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; - -EAXLISTENERPROPERTIES EAX3Params; - -S32 prevprovider=-1; -S32 curprovider=-1; -S32 usingEAX=0; -S32 usingEAX3=0; -HPROVIDER opened_provider=0; -H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; -HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; -HDIGDRIVER DIG; -S32 speaker_type=0; - -U32 _maxSamples; -float _fPrevEaxRatioDestination; -bool _usingMilesFast2D; -float _fEffectsLevel; - - -struct -{ - HPROVIDER id; - char name[80]; -}providers[MAXPROVIDERS]; - -typedef struct provider_stuff -{ - char* name; - HPROVIDER id; -} provider_stuff; - - -static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) -{ - return( _stricmp(s1->name,s2->name) ); -} - -static void -add_providers() -{ - provider_stuff pi[MAXPROVIDERS]; - U32 n,i,j; - - SampleManager.SetNum3DProvidersAvailable(0); - - HPROENUM next = HPROENUM_FIRST; - - n=0; - while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n MAXCHANNELS ) - _maxSamples = MAXCHANNELS; - - SampleManager.SetSpeakerConfig(speaker_type); - - //obtain a 3D sample handles - for ( U32 i = 0; i < _maxSamples; ++i ) - { - opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); - if ( opened_samples[i] != NULL ) - AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); - } - - return true; - } - } - - return false; -} - -void -cSampleManager::SetSpeakerConfig(int32 which) -{ - switch ( which ) - { - case 1: - speaker_type=AIL_3D_2_SPEAKER; - break; - - case 2: - speaker_type=AIL_3D_HEADPHONE; - break; - - case 3: - speaker_type=AIL_3D_4_SPEAKER; - break; - - default: - return; - break; - } - - if (opened_provider) - AIL_set_3D_speaker_type(opened_provider, speaker_type); -} - -uint32 -cSampleManager::GetMaximumSupportedChannels(void) -{ - if ( _maxSamples > MAXCHANNELS ) - return MAXCHANNELS; - - return _maxSamples; -} - -int8 -cSampleManager::GetCurrent3DProviderIndex(void) -{ - return curprovider; -} - -int8 -cSampleManager::SetCurrent3DProvider(uint8 nProvider) -{ - S32 savedprovider = curprovider; - - if ( nProvider < m_nNumberOfProviders ) - { - if ( set_new_provider(nProvider) ) - return curprovider; - else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) - return curprovider; - else - return -1; - } - else - return curprovider; -} - -static bool -_ResolveLink(char const *path, char *out) -{ - IShellLink* psl; - WIN32_FIND_DATA fd; - char filepath[MAX_PATH]; - - CoInitialize(NULL); - - if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) - { - IPersistFile *ppf; - - if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) - { - WCHAR wpath[MAX_PATH]; - - MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); - - if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) - { - /* Resolve the link */ - if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) - { - strcpy(filepath, path); - - if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) - { - OutputDebugString(fd.cFileName); - - strcpy(out, filepath); - // FIX: Release the objects. Taken from SA. -#ifdef FIX_BUGS - ppf->Release(); - psl->Release(); -#endif - return true; - } - } - } - - ppf->Release(); - } - psl->Release(); - } - - return false; -} - -static void -_FindMP3s(void) -{ - tMP3Entry *pList; - bool bShortcut; - bool bInitFirstEntry; - HANDLE hFind; - char path[MAX_PATH]; - char filepath[MAX_PATH*2]; - S32 total_ms; - WIN32_FIND_DATA fd; - - - if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) - { - GetLastError(); - return; - } - - OutputDebugString("Finding MP3s..."); - strcpy(path, _mp3DirectoryPath); - strcat(path, "\\MP3\\"); - - strcpy(_mp3DirectoryPath, path); - OutputDebugString(_mp3DirectoryPath); - - strcat(path, "*"); - - hFind = FindFirstFile(path, &fd); - - if ( hFind == INVALID_HANDLE_VALUE ) - { - GetLastError(); - return; - } - - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( filepathlen <= 0) - { - FindClose(hFind); - return; - } - - FILE *f = fopen("MP3\\MP3Report.txt", "w"); - - if ( f ) - { - fprintf(f, "MP3 Report File\n\n"); - fprintf(f, "\"%s\"", fd.cFileName); - } - - - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - bShortcut = false; - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - OutputDebugString(fd.cFileName); - - _pMP3List = new tMP3Entry; - - if ( _pMP3List == NULL ) - { - FindClose(hFind); - - if ( f ) - fclose(f); - - return; - } - - nNumMP3s = 1; - - strcpy(_pMP3List->aFilename, fd.cFileName); - - _pMP3List->nTrackLength = total_ms; - - _pMP3List->pNext = NULL; - - pList = _pMP3List; - - if ( bShortcut ) - { - _pMP3List->pLinkPath = new char[MAX_PATH*2]; - strcpy(_pMP3List->pLinkPath, filepath); - } - else - { - _pMP3List->pLinkPath = NULL; - } - - if ( f ) fprintf(f, " - OK\n"); - - bInitFirstEntry = false; - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - - bInitFirstEntry = true; - } - - while ( true ) - { - if ( !FindNextFile(hFind, &fd) ) - break; - - if ( bInitFirstEntry ) - { - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - - if ( filepathlen > 0 ) - { - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - { - bShortcut = false; - - if ( filepathlen > MAX_PATH ) - { - if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); - - continue; - } - } - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - OutputDebugString(fd.cFileName); - - _pMP3List = new tMP3Entry; - - if ( _pMP3List == NULL) - break; - - nNumMP3s = 1; - - strcpy(_pMP3List->aFilename, fd.cFileName); - - _pMP3List->nTrackLength = total_ms; - _pMP3List->pNext = NULL; - - if ( bShortcut ) - { - _pMP3List->pLinkPath = new char [MAX_PATH*2]; - strcpy(_pMP3List->pLinkPath, filepath); - } - else - { - _pMP3List->pLinkPath = NULL; - } - - pList = _pMP3List; - - if ( f ) fprintf(f, " - OK\n"); - - bInitFirstEntry = false; - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - } - } - } - else - { - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( filepathlen > 0 ) - { - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - { - bShortcut = false; - } - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - pList->pNext = new tMP3Entry; - - tMP3Entry *e = pList->pNext; - - if ( e == NULL ) - break; - - pList = pList->pNext; - - strcpy(e->aFilename, fd.cFileName); - e->nTrackLength = total_ms; - e->pNext = NULL; - - if ( bShortcut ) - { - e->pLinkPath = new char [MAX_PATH*2]; - strcpy(e->pLinkPath, filepath); - } - else - { - e->pLinkPath = NULL; - } - - nNumMP3s++; - - OutputDebugString(fd.cFileName); - - if ( f ) fprintf(f, " - OK\n"); - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - } - } - } - } - - if ( f ) - { - fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); - fclose(f); - } - - FindClose(hFind); -} - -static void -_DeleteMP3Entries(void) -{ - tMP3Entry *e = _pMP3List; - - while ( e != NULL ) - { - tMP3Entry *next = e->pNext; - - if ( next == NULL ) - next = NULL; - - if ( e->pLinkPath != NULL ) - { -#ifndef FIX_BUGS - delete e->pLinkPath; // BUG: should be delete [] +#pragma once +#include "common.h" +#ifndef OPENAL +#include "miles\sampman_mss.cpp" #else - delete[] e->pLinkPath; -#endif - e->pLinkPath = NULL; - } - - delete e; - - if ( next ) - e = next; - else - e = NULL; - - nNumMP3s--; - } - - - if ( nNumMP3s != 0 ) - { - OutputDebugString("Not all MP3 entries were deleted"); - nNumMP3s = 0; - } - - _pMP3List = NULL; -} - -static tMP3Entry * -_GetMP3EntryByIndex(uint32 idx) -{ - uint32 n = ( idx < nNumMP3s ) ? idx : 0; - - if ( _pMP3List != NULL ) - { - tMP3Entry *e = _pMP3List; - - for ( uint32 i = 0; i < n; i++ ) - e = e->pNext; - - return e; - - } - - return NULL; -} - -static inline bool -_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) -{ - _CurMP3Index = 0; - - for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) - { - if ( *pPosition >= (*pEntry)->nTrackStreamPos - && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) - { - *pPosition -= (*pEntry)->nTrackStreamPos; - _CurMP3Pos = *pPosition; - - return true; - } - - _CurMP3Index++; - } - - *pPosition = 0; - *pEntry = _pMP3List; - _CurMP3Pos = 0; - _CurMP3Index = 0; - - return false; -} - -bool -cSampleManager::IsMP3RadioChannelAvailable(void) -{ - return nNumMP3s != 0; -} - -void -cSampleManager::ReleaseDigitalHandle(void) -{ - if ( DIG ) - { - prevprovider = curprovider; - release_existing(); - curprovider = -1; - AIL_digital_handle_release(DIG); - } -} - -void -cSampleManager::ReacquireDigitalHandle(void) -{ - if ( DIG ) - { - AIL_digital_handle_reacquire(DIG); - if ( prevprovider != -1 ) - set_new_provider(prevprovider); - } -} - -bool -cSampleManager::Initialise(void) -{ - TRACE("start"); - - if ( _bSampmanInitialised ) - return true; - - { - for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) - { - m_aSamples[i].nOffset = 0; - m_aSamples[i].nSize = 0; - m_aSamples[i].nFrequency = 22050; - m_aSamples[i].nLoopStart = 0; - m_aSamples[i].nLoopEnd = -1; - } - - m_nEffectsVolume = MAX_VOLUME; - m_nMusicVolume = MAX_VOLUME; - m_nEffectsFadeVolume = MAX_VOLUME; - m_nMusicFadeVolume = MAX_VOLUME; - - m_nMonoMode = 0; - } - - // miles - TRACE("MILES"); - { - curprovider = -1; - prevprovider = -1; - - _usingMilesFast2D = false; - usingEAX=0; - usingEAX3=0; - - _fEffectsLevel = 0.0f; - - _maxSamples = 0; - - opened_provider = NULL; - DIG = NULL; - - for ( int32 i = 0; i < MAXCHANNELS; i++ ) - opened_samples[i] = NULL; - } - - // banks - TRACE("banks"); - { - fpSampleDescHandle = NULL; - fpSampleDataHandle = NULL; - - _nSampleDataEndOffset = 0; - - for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) - { - bSampleBankLoaded[i] = false; - nSampleBankDiscStartOffset[i] = 0; - nSampleBankSize[i] = 0; - nSampleBankMemoryStartAddress[i] = 0; - } - } - - // pedsfx - TRACE("pedsfx"); - { - for ( int32 i = 0; i < MAX_PEDSFX; i++ ) - { - nPedSlotSfx[i] = NO_SAMPLE; - nPedSlotSfxAddr[i] = 0; - } - - nCurrentPedSlot = 0; - } - - // channel volume - TRACE("vol"); - { - for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) - nChannelVolume[i] = 0; - } - - TRACE("mss"); - { - AIL_set_redist_directory( "mss" ); - - AIL_startup(); - - AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); - - DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); - if ( DIG == NULL ) - { - OutputDebugString(AIL_last_error()); - Terminate(); - return false; - } - - add_providers(); - - if ( !InitialiseSampleBanks() ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]); - if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); - - } - - TRACE("cdrom"); - - S32 tatalms; - char filepath[MAX_PATH]; - - { - m_bInitialised = false; - - while (true) - { - int32 drive = 'C'; - - do - { - char latter[2]; - - latter[0] = drive; - latter[1] = '\0'; - - strcpy(m_szCDRomRootPath, latter); - strcat(m_szCDRomRootPath, ":\\"); - - if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[0]); - - FILE *f = fopen(filepath, "rb"); - - if ( f ) - { - fclose(f); - - bool bFileNotFound = false; - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - nStreamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - if ( !bFileNotFound ) - { - m_bInitialised = true; - break; - } - else - { - m_bInitialised = false; - continue; - } - } - } - - } while ( ++drive <= 'Z' ); - - if ( !m_bInitialised ) - { -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - FrontEndMenuManager.WaitForUserCD(); - if ( FrontEndMenuManager.m_bQuitGameNoCD ) - { - Terminate(); - return false; - } - continue; -#else - m_bInitialised = true; -#endif - } - - break; - } - } - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - // hddaudio - /** - Option for user to play audio files directly from hard disk. - Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. - Grand Theft Auto III still requires the presence of the PLAY disc when started. - This may give better performance on some machines (though worse on others). - **/ - TRACE("hddaudio 1.1 patch"); - { - int32 streamLength[TOTAL_STREAMED_SOUNDS]; - - bool bFileNotFound = false; - char rootpath[MAX_PATH]; - - strcpy(_aHDDPath, m_szCDRomRootPath); - rootpath[0] = '\0'; - - FILE *f = fopen(StreamedNameTable[0], "rb"); - - if ( f ) - { - fclose(f); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, rootpath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - streamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - } - else - bFileNotFound = true; - - if ( !bFileNotFound ) - { - strcpy(m_szCDRomRootPath, rootpath); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - nStreamLength[i] = streamLength[i]; - - _bUseHDDAudio = true; - } - else - _bUseHDDAudio = false; - } -#endif - - TRACE("stream"); - { - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) - { - mp3Stream [i] = NULL; - nStreamPan [i] = 63; - nStreamVolume[i] = 100; - } - } - - for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) - { - opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); - if ( opened_2dsamples[i] ) - { - AIL_init_sample(opened_2dsamples[i]); - AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); - } - } - - TRACE("providerset"); - { - _bSampmanInitialised = true; - - U32 n = 0; - - while ( n < m_nNumberOfProviders ) - { - if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) - { - set_new_provider(n); - break; - } - n++; - } - - if ( n == m_nNumberOfProviders ) - { - Terminate(); - return false; - } - } - - TRACE("bank"); - - LoadSampleBank(SAMPLEBANK_MAIN); - - // mp3 - TRACE("mp3"); - { - nNumMP3s = 0; - - _pMP3List = NULL; - - _FindMP3s(); - - if ( nNumMP3s != 0 ) - { - nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; - - for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) - { - e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; - nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; - } - - time_t t = time(NULL); - tm *localtm; - bool bUseRandomTable; - - if ( t == -1 ) - bUseRandomTable = true; - else - { - bUseRandomTable = false; - localtm = localtime(&t); - } - - int32 randval; - if ( bUseRandomTable ) - randval = AudioManager.GetRandomNumber(1); - else - randval = localtm->tm_sec * localtm->tm_min; - - _CurMP3Index = randval % nNumMP3s; - - tMP3Entry *randmp3 = _pMP3List; - for ( int32 i = randval % nNumMP3s; i > 0; --i) - randmp3 = randmp3->pNext; - - if ( bUseRandomTable ) - _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; - else - { - if ( localtm->tm_sec > 0 ) - { - int32 s = localtm->tm_sec; - _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; - } - else - _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; - } - } - else - _CurMP3Pos = 0; - - _bIsMp3Active = false; - } - - TRACE("end"); - - return true; -} - -void -cSampleManager::Terminate(void) -{ - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) - { - if ( mp3Stream[i] ) - { - AIL_pause_stream(mp3Stream[i], 1); - AIL_close_stream(mp3Stream[i]); - mp3Stream[i] = NULL; - } - } - - for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) - { - if ( opened_2dsamples[i] ) - { - AIL_release_sample_handle(opened_2dsamples[i]); - opened_2dsamples[i] = NULL; - } - } - - release_existing(); - - _DeleteMP3Entries(); - - if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 ) - { - AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]); - nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0; - } - - if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 ) - { - AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); - nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0; - } - - if ( DIG ) - { - AIL_close_digital_driver(DIG); - DIG = NULL; - } - - AIL_shutdown(); - - _bSampmanInitialised = false; -} - -bool -cSampleManager::CheckForAnAudioFileOnCD(void) -{ -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - char filepath[MAX_PATH]; - -#if defined(GTA3_1_1_PATCH) - if (_bUseHDDAudio) - strcpy(filepath, _aHDDPath); - else - strcpy(filepath, m_szCDRomRootPath); -#else - strcpy(filepath, m_szCDRomRootPath); -#endif // #if defined(GTA3_1_1_PATCH) - - strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); - - FILE *f = fopen(filepath, "rb"); - - if ( f ) - { - fclose(f); - - return true; - } - - return false; - -#else - return true; -#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) -} - -char -cSampleManager::GetCDAudioDriveLetter(void) -{ -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - if (_bUseHDDAudio) - { - if ( strlen(_aHDDPath) != 0 ) - return _aHDDPath[0]; - else - return '\0'; - } - else - { - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; - } -#else - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; -#endif -} - -void -cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? -{ - if ( _bSampmanInitialised ) - { - for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) - { - if ( i < MAXCHANNELS ) - { - if ( opened_samples[i] && GetChannelUsedFlag(i) ) - { - if ( nChannelVolume[i] ) - { - AIL_set_3D_sample_volume(opened_samples[i], - m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); - } - } - } - else - { - if ( opened_2dsamples[i - MAXCHANNELS] ) - { - if ( GetChannelUsedFlag(i - MAXCHANNELS) ) - { - if ( nChannelVolume[i - MAXCHANNELS] ) - { - AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], - m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14); - } - } - } - } - } - } -} - -void -cSampleManager::SetEffectsMasterVolume(uint8 nVolume) -{ - m_nEffectsVolume = nVolume; - UpdateEffectsVolume(); -} - -void -cSampleManager::SetMusicMasterVolume(uint8 nVolume) -{ - m_nMusicVolume = nVolume; -} - -void -cSampleManager::SetEffectsFadeVolume(uint8 nVolume) -{ - m_nEffectsFadeVolume = nVolume; - UpdateEffectsVolume(); -} - -void -cSampleManager::SetMusicFadeVolume(uint8 nVolume) -{ - m_nMusicFadeVolume = nVolume; -} - -bool -cSampleManager::LoadSampleBank(uint8 nBank) -{ - if ( CTimer::GetIsCodePaused() ) - return false; - - if ( MusicManager.IsInitialised() - && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && nBank != SAMPLEBANK_MAIN ) - { - return false; - } - - if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) - return false; - - if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] ) - return false; - - bSampleBankLoaded[nBank] = true; - - return true; -} - -void -cSampleManager::UnloadSampleBank(uint8 nBank) -{ - bSampleBankLoaded[nBank] = false; -} - -bool -cSampleManager::IsSampleBankLoaded(uint8 nBank) -{ - return bSampleBankLoaded[nBank]; -} - -bool -cSampleManager::IsPedCommentLoaded(uint32 nComment) -{ - uint8 slot; - - for ( int32 i = 0; i < _TODOCONST(3); i++ ) - { - slot = nCurrentPedSlot - i - 1; - if ( nComment == nPedSlotSfx[slot] ) - return true; - } - - return false; -} - -int32 -cSampleManager::_GetPedCommentSlot(uint32 nComment) -{ - uint8 slot; - - for ( int32 i = 0; i < _TODOCONST(3); i++ ) - { - slot = nCurrentPedSlot - i - 1; - if ( nComment == nPedSlotSfx[slot] ) - return slot; - } - - return -1; -} - -bool -cSampleManager::LoadPedComment(uint32 nComment) -{ - if ( CTimer::GetIsCodePaused() ) - return false; - - // no talking peds during cutsenes or the game end - if ( MusicManager.IsInitialised() ) - { - switch ( MusicManager.GetMusicMode() ) - { - case MUSICMODE_CUTSCENE: - { - return false; - - break; - } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED ) - return false; - - break; - } - } - } - - if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) - return false; - - if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) - return false; - - nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot; - nPedSlotSfx [nCurrentPedSlot] = nComment; - - if ( ++nCurrentPedSlot >= MAX_PEDSFX ) - nCurrentPedSlot = 0; - - return true; -} - -int32 -cSampleManager::GetSampleBaseFrequency(uint32 nSample) -{ - return m_aSamples[nSample].nFrequency; -} - -int32 -cSampleManager::GetSampleLoopStartOffset(uint32 nSample) -{ - return m_aSamples[nSample].nLoopStart; -} - -int32 -cSampleManager::GetSampleLoopEndOffset(uint32 nSample) -{ - return m_aSamples[nSample].nLoopEnd; -} - -uint32 -cSampleManager::GetSampleLength(uint32 nSample) -{ - return m_aSamples[nSample].nSize >> 1; -} - -bool -cSampleManager::UpdateReverb(void) -{ - if ( !usingEAX ) - return false; - - if ( AudioManager.GetFrameCounter() & 15 ) - return false; - - float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); - float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); - float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); - - float normy = norm(y, 5.0f, 40.0f); - float normx = norm(x, 5.0f, 40.0f); - float normz = norm(z, 5.0f, 40.0f); - - float fRatio; - - if ( normy == 0.0f ) - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - fRatio = 0.3f; - } - } - else - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = (normy+normx+normz) / 3.0f; - } - } - - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); - - if ( fRatio == _fPrevEaxRatioDestination ) - return false; - - if ( usingEAX3 ) - { - if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) - { - AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); - _fEffectsLevel = 1.0f - fRatio * 0.5f; - } - } - else - { - if ( _usingMilesFast2D ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; - else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; - } - - _fPrevEaxRatioDestination = fRatio; - - return true; -} - -void -cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( usingEAX ) - { - if ( nReverbFlag != 0 ) - { - if ( !b2d ) - AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); - } - else - { - if ( !b2d ) - AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); - } - } -} - -bool -cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - int32 addr; - - if ( nSfx < SAMPLEBANK_MAX ) - { - if ( !IsSampleBankLoaded(nBank) ) - return false; - - addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; - } - else - { - if ( !IsPedCommentLoaded(nSfx) ) - return false; - - int32 slot = _GetPedCommentSlot(nSfx); - - addr = nPedSlotSfxAddr[slot]; - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - { - AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); - return true; - } - else - return false; - } - else - { - AILSOUNDINFO info; - - info.format = WAVE_FORMAT_PCM; - info.data_ptr = (void *)addr; - info.channels = 1; - info.data_len = m_aSamples[nSfx].nSize; - info.rate = m_aSamples[nSfx].nFrequency; - info.bits = 16; - - if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) - { - OutputDebugString(AIL_last_error()); - return false; - } - - return true; - } -} - -void -cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) -{ - uint32 vol = nVolume; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - nChannelVolume[nChannel] = vol; - - // increase the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) - { - nChannelVolume[nChannel] >>= 2; - } - - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); - -} - -void -cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) -{ - if ( opened_samples[nChannel] ) - AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); -} - -void -cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) -{ - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); -} - -void -cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) -{ - uint32 vol = nVolume; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - switch ( nChannel ) - { - case CHANNEL2D: - { - nChannelVolume[nChannel] = vol; - - // increase the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) - { - nChannelVolume[nChannel] >>= 2; - } - - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - { - AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], - m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); - } - - break; - } - } -} - -void -cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) -{ - switch ( nChannel ) - { - case CHANNEL2D: - { -#ifndef FIX_BUGS - if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG -#else - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) -#endif - AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); - - break; - } - } -} - -void -cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); - } -} - -void -cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); - } -} - -void -cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); - } -} - -bool -cSampleManager::GetChannelUsedFlag(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; - else - return false; - } - else - { - if ( opened_samples[nChannel] ) - return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; - else - return false; - } - -} - -void -cSampleManager::StartChannel(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); - } - else - { - if ( opened_samples[nChannel] ) - AIL_start_3D_sample(opened_samples[nChannel]); - } -} - -void -cSampleManager::StopChannel(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); - } - else - { - if ( opened_samples[nChannel] ) - { - if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) - AIL_end_3D_sample(opened_samples[nChannel]); - } - } -} - -void -cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - AIL_close_stream(mp3Stream[nStream]); - } - - char filepath[MAX_PATH]; - - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[nFile]); - - mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_service_stream(mp3Stream[nStream], 1); - } - else - OutputDebugString(AIL_last_error()); - } - } -} - -void -cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); - } -} - -void -cSampleManager::StartPreloadedStreamedFile(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - AIL_start_stream(mp3Stream[nStream]); - } -} - -bool -cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) -{ - uint32 position = nPos; - char filename[MAX_PATH]; - - if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - AIL_close_stream(mp3Stream[nStream]); - } - - if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) - { - uint32 i = 0; - do { - if(i != 0 || _bIsMp3Active) { - if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; - - _CurMP3Pos = 0; - - tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); - - if(mp3) { - mp3 = _pMP3List; - if(mp3 == NULL) { - _bIsMp3Active = false; - nFile = 0; - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], - 0); - return true; - } - - return false; - } - } - - if(mp3->pLinkPath != NULL) - mp3Stream[nStream] = - AIL_open_stream(DIG, mp3->pLinkPath, 0); - else { - strcpy(filename, _mp3DirectoryPath); - strcat(filename, mp3->aFilename); - - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - } - - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], 0); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - - _bIsMp3Active = false; - continue; - } - if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) - position = 0; - - tMP3Entry *e; - if ( !_GetMP3PosFromStreamPos(&position, &e) ) - { - if ( e == NULL ) - { - nFile = 0; - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - - return false; - } - } - - if ( e->pLinkPath != NULL ) - mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); - else - { - strcpy(filename, _mp3DirectoryPath); - strcat(filename, e->aFilename); - - mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); - } - - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - - _bIsMp3Active = true; - - return true; - } - - _bIsMp3Active = false; - - } while(++i < nNumMP3s); - - position = 0; - nFile = 0; - } - - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - - mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - } - - return false; -} - -void -cSampleManager::StopStreamedFile(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - - AIL_close_stream(mp3Stream[nStream]); - mp3Stream[nStream] = NULL; - - if ( nStream == 0 ) - _bIsMp3Active = false; - } - } -} - -int32 -cSampleManager::GetStreamedFilePosition(uint8 nStream) -{ - S32 currentms; - - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - if ( _bIsMp3Active ) - { - tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); - - if ( mp3 != NULL ) - { - AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); - return currentms + mp3->nTrackStreamPos; - } - else - return 0; - } - else - { - AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); - return currentms; - } - } - } - - return 0; -} - -void -cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) -{ - uint8 vol = nVolume; - - if ( m_bInitialised ) - { - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - nStreamVolume[nStream] = vol; - nStreamPan[nStream] = nPan; - - if ( mp3Stream[nStream] ) - { - if ( nEffectFlag ) - AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); - else - AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); - - AIL_set_stream_pan(mp3Stream[nStream], nPan); - } - } -} - -int32 -cSampleManager::GetStreamedFileLength(uint8 nStream) -{ - if ( m_bInitialised ) - return nStreamLength[nStream]; - - return 0; -} - -bool -cSampleManager::IsStreamPlaying(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) - return true; - else - return false; - } - } - - return false; -} - -bool -cSampleManager::InitialiseSampleBanks(void) -{ - int32 nBank = SAMPLEBANK_MAIN; - - fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); - if ( fpSampleDescHandle == NULL ) - return false; - - fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); - if ( fpSampleDataHandle == NULL ) - { - fclose(fpSampleDescHandle); - fpSampleDescHandle = NULL; - - return false; - } - - fseek(fpSampleDataHandle, 0, SEEK_END); - _nSampleDataEndOffset = ftell(fpSampleDataHandle); - rewind(fpSampleDataHandle); - - fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); - - fclose(fpSampleDescHandle); - fpSampleDescHandle = NULL; - - for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) - { -#ifdef FIX_BUGS - if (nBank >= MAX_SAMPLEBANKS) break; -#endif - if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i ) - { - nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; - nBank++; - } - } - - nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN]; - nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED]; - - return true; -} +#include "openal\samp_oal.cpp" +#endif \ No newline at end of file diff --git a/src/audio/sampman.h b/src/audio/sampman.h index ebedfb63..f454d236 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -1,339 +1,7 @@ #pragma once #include "common.h" -#include "AudioSamples.h" - -#define MAX_VOLUME 127 - -struct tSample { - int32 nOffset; - uint32 nSize; - int32 nFrequency; - int32 nLoopStart; - int32 nLoopEnd; -}; - -enum -{ - SAMPLEBANK_MAIN, - SAMPLEBANK_PED, - MAX_SAMPLEBANKS, - SAMPLEBANK_INVALID -}; - -#define MAX_PEDSFX 7 -#define PED_BLOCKSIZE 79000 - -#define MAXPROVIDERS 64 - -#define MAXCHANNELS 28 -#define MAXCHANNELS_SURROUND 24 -#define MAX2DCHANNELS 1 -#define CHANNEL2D MAXCHANNELS - -#define MAX_MP3STREAMS 2 - -#define DIGITALRATE 32000 -#define DIGITALBITS 16 -#define DIGITALCHANNELS 2 - -#define MAX_DIGITAL_MIXER_CHANNELS 32 - -class cSampleManager -{ - uint8 m_nEffectsVolume; - uint8 m_nMusicVolume; - uint8 m_nEffectsFadeVolume; - uint8 m_nMusicFadeVolume; - uint8 m_nMonoMode; - char unk; - char m_szCDRomRootPath[80]; - bool m_bInitialised; - uint8 m_nNumberOfProviders; - char *m_aAudioProviders[MAXPROVIDERS]; - tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; - -public: - - - - cSampleManager(void) : - m_nNumberOfProviders(0) - { } - - ~cSampleManager(void) - { } - - void SetSpeakerConfig(int32 nConfig); - uint32 GetMaximumSupportedChannels(void); - - uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; } - void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; } - - char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; } - void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; } - - int8 GetCurrent3DProviderIndex(void); - int8 SetCurrent3DProvider(uint8 which); - - bool IsMP3RadioChannelAvailable(void); - - void ReleaseDigitalHandle (void); - void ReacquireDigitalHandle(void); - - bool Initialise(void); - void Terminate (void); - - bool CheckForAnAudioFileOnCD(void); - char GetCDAudioDriveLetter (void); - - void UpdateEffectsVolume(void); - - void SetEffectsMasterVolume(uint8 nVolume); - void SetMusicMasterVolume (uint8 nVolume); - void SetEffectsFadeVolume (uint8 nVolume); - void SetMusicFadeVolume (uint8 nVolume); - - bool LoadSampleBank (uint8 nBank); - void UnloadSampleBank (uint8 nBank); - bool IsSampleBankLoaded(uint8 nBank); - - bool IsPedCommentLoaded(uint32 nComment); - bool LoadPedComment (uint32 nComment); - - int32 _GetPedCommentSlot(uint32 nComment); - - int32 GetSampleBaseFrequency (uint32 nSample); - int32 GetSampleLoopStartOffset(uint32 nSample); - int32 GetSampleLoopEndOffset (uint32 nSample); - uint32 GetSampleLength (uint32 nSample); - - bool UpdateReverb(void); - - void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag); - bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank); - void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume); - void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ); - void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin); - void SetChannelVolume (uint32 nChannel, uint32 nVolume); - void SetChannelPan (uint32 nChannel, uint32 nPan); - void SetChannelFrequency (uint32 nChannel, uint32 nFreq); - void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd); - void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount); - bool GetChannelUsedFlag (uint32 nChannel); - void StartChannel (uint32 nChannel); - void StopChannel (uint32 nChannel); - - void PreloadStreamedFile (uint8 nFile, uint8 nStream); - void PauseStream (uint8 nPauseFlag, uint8 nStream); - void StartPreloadedStreamedFile (uint8 nStream); - bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream); - void StopStreamedFile (uint8 nStream); - int32 GetStreamedFilePosition (uint8 nStream); - void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream); - int32 GetStreamedFileLength (uint8 nStream); - bool IsStreamPlaying (uint8 nStream); - bool InitialiseSampleBanks(void); -}; - -extern cSampleManager SampleManager; -extern int32 BankStartOffset[MAX_SAMPLEBANKS]; - -static char StreamedNameTable[][25]= -{ - "AUDIO\\HEAD.WAV", - "AUDIO\\CLASS.WAV", - "AUDIO\\KJAH.WAV", - "AUDIO\\RISE.WAV", - "AUDIO\\LIPS.WAV", - "AUDIO\\GAME.WAV", - "AUDIO\\MSX.WAV", - "AUDIO\\FLASH.WAV", - "AUDIO\\CHAT.WAV", - "AUDIO\\HEAD.WAV", - "AUDIO\\POLICE.WAV", - "AUDIO\\CITY.WAV", - "AUDIO\\WATER.WAV", - "AUDIO\\COMOPEN.WAV", - "AUDIO\\SUBOPEN.WAV", - "AUDIO\\JB.MP3", - "AUDIO\\BET.MP3", - "AUDIO\\L1_LG.MP3", - "AUDIO\\L2_DSB.MP3", - "AUDIO\\L3_DM.MP3", - "AUDIO\\L4_PAP.MP3", - "AUDIO\\L5_TFB.MP3", - "AUDIO\\J0_DM2.MP3", - "AUDIO\\J1_LFL.MP3", - "AUDIO\\J2_KCL.MP3", - "AUDIO\\J3_VH.MP3", - "AUDIO\\J4_ETH.MP3", - "AUDIO\\J5_DST.MP3", - "AUDIO\\J6_TBJ.MP3", - "AUDIO\\T1_TOL.MP3", - "AUDIO\\T2_TPU.MP3", - "AUDIO\\T3_MAS.MP3", - "AUDIO\\T4_TAT.MP3", - "AUDIO\\T5_BF.MP3", - "AUDIO\\S0_MAS.MP3", - "AUDIO\\S1_PF.MP3", - "AUDIO\\S2_CTG.MP3", - "AUDIO\\S3_RTC.MP3", - "AUDIO\\S5_LRQ.MP3", - "AUDIO\\S4_BDBA.MP3", - "AUDIO\\S4_BDBB.MP3", - "AUDIO\\S2_CTG2.MP3", - "AUDIO\\S4_BDBD.MP3", - "AUDIO\\S5_LRQB.MP3", - "AUDIO\\S5_LRQC.MP3", - "AUDIO\\A1_SSO.WAV", - "AUDIO\\A2_PP.WAV", - "AUDIO\\A3_SS.WAV", - "AUDIO\\A4_PDR.WAV", - "AUDIO\\A5_K2FT.WAV", - "AUDIO\\K1_KBO.MP3", - "AUDIO\\K2_GIS.MP3", - "AUDIO\\K3_DS.MP3", - "AUDIO\\K4_SHI.MP3", - "AUDIO\\K5_SD.MP3", - "AUDIO\\R0_PDR2.MP3", - "AUDIO\\R1_SW.MP3", - "AUDIO\\R2_AP.MP3", - "AUDIO\\R3_ED.MP3", - "AUDIO\\R4_GF.MP3", - "AUDIO\\R5_PB.MP3", - "AUDIO\\R6_MM.MP3", - "AUDIO\\D1_STOG.MP3", - "AUDIO\\D2_KK.MP3", - "AUDIO\\D3_ADO.MP3", - "AUDIO\\D5_ES.MP3", - "AUDIO\\D7_MLD.MP3", - "AUDIO\\D4_GTA.MP3", - "AUDIO\\D4_GTA2.MP3", - "AUDIO\\D6_STS.MP3", - "AUDIO\\A6_BAIT.WAV", - "AUDIO\\A7_ETG.WAV", - "AUDIO\\A8_PS.WAV", - "AUDIO\\A9_ASD.WAV", - "AUDIO\\K4_SHI2.MP3", - "AUDIO\\C1_TEX.MP3", - "AUDIO\\EL_PH1.MP3", - "AUDIO\\EL_PH2.MP3", - "AUDIO\\EL_PH3.MP3", - "AUDIO\\EL_PH4.MP3", - "AUDIO\\YD_PH1.MP3", - "AUDIO\\YD_PH2.MP3", - "AUDIO\\YD_PH3.MP3", - "AUDIO\\YD_PH4.MP3", - "AUDIO\\HD_PH1.MP3", - "AUDIO\\HD_PH2.MP3", - "AUDIO\\HD_PH3.MP3", - "AUDIO\\HD_PH4.MP3", - "AUDIO\\HD_PH5.MP3", - "AUDIO\\MT_PH1.MP3", - "AUDIO\\MT_PH2.MP3", - "AUDIO\\MT_PH3.MP3", - "AUDIO\\MT_PH4.MP3", - "AUDIO\\MISCOM.WAV", - "AUDIO\\END.MP3", - "AUDIO\\lib_a1.WAV", - "AUDIO\\lib_a2.WAV", - "AUDIO\\lib_a.WAV", - "AUDIO\\lib_b.WAV", - "AUDIO\\lib_c.WAV", - "AUDIO\\lib_d.WAV", - "AUDIO\\l2_a.WAV", - "AUDIO\\j4t_1.WAV", - "AUDIO\\j4t_2.WAV", - "AUDIO\\j4t_3.WAV", - "AUDIO\\j4t_4.WAV", - "AUDIO\\j4_a.WAV", - "AUDIO\\j4_b.WAV", - "AUDIO\\j4_c.WAV", - "AUDIO\\j4_d.WAV", - "AUDIO\\j4_e.WAV", - "AUDIO\\j4_f.WAV", - "AUDIO\\j6_1.WAV", - "AUDIO\\j6_a.WAV", - "AUDIO\\j6_b.WAV", - "AUDIO\\j6_c.WAV", - "AUDIO\\j6_d.WAV", - "AUDIO\\t4_a.WAV", - "AUDIO\\s1_a.WAV", - "AUDIO\\s1_a1.WAV", - "AUDIO\\s1_b.WAV", - "AUDIO\\s1_c.WAV", - "AUDIO\\s1_c1.WAV", - "AUDIO\\s1_d.WAV", - "AUDIO\\s1_e.WAV", - "AUDIO\\s1_f.WAV", - "AUDIO\\s1_g.WAV", - "AUDIO\\s1_h.WAV", - "AUDIO\\s1_i.WAV", - "AUDIO\\s1_j.WAV", - "AUDIO\\s1_k.WAV", - "AUDIO\\s1_l.WAV", - "AUDIO\\s3_a.WAV", - "AUDIO\\s3_b.WAV", - "AUDIO\\el3_a.WAV", - "AUDIO\\mf1_a.WAV", - "AUDIO\\mf2_a.WAV", - "AUDIO\\mf3_a.WAV", - "AUDIO\\mf3_b.WAV", - "AUDIO\\mf3_b1.WAV", - "AUDIO\\mf3_c.WAV", - "AUDIO\\mf4_a.WAV", - "AUDIO\\mf4_b.WAV", - "AUDIO\\mf4_c.WAV", - "AUDIO\\a1_a.WAV", - "AUDIO\\a3_a.WAV", - "AUDIO\\a5_a.WAV", - "AUDIO\\a4_a.WAV", - "AUDIO\\a4_b.WAV", - "AUDIO\\a4_c.WAV", - "AUDIO\\a4_d.WAV", - "AUDIO\\k1_a.WAV", - "AUDIO\\k3_a.WAV", - "AUDIO\\r1_a.WAV", - "AUDIO\\r2_a.WAV", - "AUDIO\\r2_b.WAV", - "AUDIO\\r2_c.WAV", - "AUDIO\\r2_d.WAV", - "AUDIO\\r2_e.WAV", - "AUDIO\\r2_f.WAV", - "AUDIO\\r2_g.WAV", - "AUDIO\\r2_h.WAV", - "AUDIO\\r5_a.WAV", - "AUDIO\\r6_a.WAV", - "AUDIO\\r6_a1.WAV", - "AUDIO\\r6_b.WAV", - "AUDIO\\lo2_a.WAV", - "AUDIO\\lo6_a.WAV", - "AUDIO\\yd2_a.WAV", - "AUDIO\\yd2_b.WAV", - "AUDIO\\yd2_c.WAV", - "AUDIO\\yd2_c1.WAV", - "AUDIO\\yd2_d.WAV", - "AUDIO\\yd2_e.WAV", - "AUDIO\\yd2_f.WAV", - "AUDIO\\yd2_g.WAV", - "AUDIO\\yd2_h.WAV", - "AUDIO\\yd2_ass.WAV", - "AUDIO\\yd2_ok.WAV", - "AUDIO\\h5_a.WAV", - "AUDIO\\h5_b.WAV", - "AUDIO\\h5_c.WAV", - "AUDIO\\ammu_a.WAV", - "AUDIO\\ammu_b.WAV", - "AUDIO\\ammu_c.WAV", - "AUDIO\\door_1.WAV", - "AUDIO\\door_2.WAV", - "AUDIO\\door_3.WAV", - "AUDIO\\door_4.WAV", - "AUDIO\\door_5.WAV", - "AUDIO\\door_6.WAV", - "AUDIO\\t3_a.WAV", - "AUDIO\\t3_b.WAV", - "AUDIO\\t3_c.WAV", - "AUDIO\\k1_b.WAV", - "AUDIO\\cat1.WAV" -}; +#ifndef OPENAL +#include "miles\sampman_mss.h" +#else +#include "openal\samp_oal.h" +#endif \ No newline at end of file diff --git a/src/core/config.h b/src/core/config.h index b5022b9f..c52a708d 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -193,6 +193,11 @@ enum Config { #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) //#define USE_TXD_CDIMAGE // generate and load textures from txd.img //#define USE_TEXTURE_POOL +//#define OPENAL + +// Particle +//#define PC_PARTICLE +//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 // Pad #define XINPUT diff --git a/src/core/re3.cpp b/src/core/re3.cpp index e5f42696..3c2bc31f 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -372,7 +372,6 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil); DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil); #ifdef TOGGLEABLE_BETA_FEATURES - DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil); DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil); DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil); #endif diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp index fe448966..932a0b8a 100644 --- a/src/objects/ParticleObject.cpp +++ b/src/objects/ParticleObject.cpp @@ -169,7 +169,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_STEAM_NY; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 3; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 8; break; } @@ -187,7 +191,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_STEAM_NY; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 3; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 8; break; } @@ -205,7 +213,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_STEAM_NY; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 3; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 8; pobj->m_Color = CRGBA(16, 16, 16, 255); break; @@ -228,7 +240,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_CAR_SPLASH; pobj->m_nNumEffectCycles = 0; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 1; +#else + pobj->m_nSkipFrames = 3; +#endif pobj->m_nCreationChance = 0; break; } @@ -236,7 +252,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe case POBJECT_SPLASHES_AROUND: { pobj->m_ParticleType = PARTICLE_SPLASH; +#ifdef PC_PARTICLE pobj->m_nNumEffectCycles = 15; +#else + pobj->m_nNumEffectCycles = 30; +#endif pobj->m_nSkipFrames = 2; pobj->m_nCreationChance = 0; break; @@ -246,7 +266,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_FLAME; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 2; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 2; pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f); break; @@ -256,7 +280,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_FLAME; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 2; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 4; pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f); break; @@ -286,7 +314,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe { pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM; pobj->m_nNumEffectCycles = 1; +#ifdef PC_PARTICLE pobj->m_nSkipFrames = 3; +#else + pobj->m_nSkipFrames = 1; +#endif pobj->m_nCreationChance = 2; pobj->m_fRandVal = 0.01f; break; @@ -598,6 +630,7 @@ void CParticleObject::UpdateClose(void) case POBJECT_PED_WATER_SPLASH: { +#ifdef PC_PARTICLE CRGBA colorsmoke(255, 255, 255, 196); CVector pos = this->GetPosition(); @@ -699,12 +732,69 @@ void CParticleObject::UpdateClose(void) CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color); } +#else + CVector pos; + CVector vel; + + for ( int32 i = -2; i < 2; i++ ) + { + pos = this->GetPosition(); + pos += CVector(-0.75f, 0.5f * float(i), 0.0f); + vel = this->m_vecTarget; + vel.x += -1.5 * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color); + + pos = this->GetPosition(); + pos += CVector(0.75f, 0.5f * float(i), 0.0f); + + vel = this->m_vecTarget; + vel.x += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color); + + pos = this->GetPosition(); + pos += CVector(0.5f * float(i), -0.75, 0.0f); + + vel = this->m_vecTarget; + vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += -1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color); + + + pos = this->GetPosition(); + pos += CVector(0.5f * float(i), 0.75, 0.0f); + + vel = this->m_vecTarget; + vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color); + } + + + for ( int32 i = 0; i < 4; i++ ) + { + pos = this->GetPosition(); + + pos.x += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f); + pos.y += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f); + pos.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + + vel = this->m_vecTarget; + CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color); + } +#endif break; } case POBJECT_CAR_WATER_SPLASH: { +#ifdef PC_PARTICLE CRGBA colorsmoke(255, 255, 255, 196); CVector pos = this->GetPosition(); @@ -799,7 +889,65 @@ void CParticleObject::UpdateClose(void) splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f); CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color); } +#else + CVector pos; + CVector vel; + + for ( int32 i = -3; i < 4; i++ ) + { + pos = this->GetPosition(); + pos += CVector(-1.5f, 0.5f * float(i), 0.0f); + + + vel = this->m_vecTarget; + vel.x += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color); + + pos = this->GetPosition(); + pos += CVector(1.5f, 0.5f * float(i), 0.0f); + + vel = this->m_vecTarget; + vel.x += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color); + + + pos = this->GetPosition(); + pos += CVector(0.5f * float(i), -1.5f, 0.0f); + + vel = this->m_vecTarget; + vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color); + + + pos = this->GetPosition(); + pos += CVector(0.5f * float(i), 1.5f, 0.0f); + + + vel = this->m_vecTarget; + vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.y += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f); + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color); + } + + for ( int32 i = 0; i < 8; i++ ) + { + pos = this->GetPosition(); + pos.x += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f); + pos.y += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f); + + vel = this->m_vecTarget; + vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color); + } +#endif break; } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 1f15aa6c..f4cdff70 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2019,7 +2019,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) } static void -particleProduceFootDust(CPed *ped, CVector *pos, float size, int times) +particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times) { switch (ped->m_nSurfaceTouched) { @@ -2028,7 +2028,7 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times) case SURFACE_PAVEMENT: case SURFACE_SAND: for (int i = 0; i < times; ++i) { - CVector adjustedPos = *pos; + CVector adjustedPos = pos; adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); CParticle::AddParticle(PARTICLE_PEDFOOT_DUST, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, 0, 0); @@ -2040,16 +2040,27 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times) } static void -particleProduceFootSplash(CPed *ped, CVector *pos, float size, int times) +particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times) { +#ifdef PC_PARTICLE for (int i = 0; i < times; i++) { - CVector adjustedPos = *pos; + CVector adjustedPos = pos; adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); CVector direction = ped->GetForward() * -0.05f; CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, direction, nil, size, CRGBA(32, 32, 32, 32), 0, 0, CGeneral::GetRandomNumber() & 1, 200); } +#else + for ( int32 i = 0; i < times; i++ ) + { + CVector adjustedPos = pos; + adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); + adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f); + + CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 200); + } +#endif } void @@ -2080,6 +2091,50 @@ CPed::PlayFootSteps(void) } } +#ifdef GTA_PS2_STUFF + CAnimBlendAssociation *runStopAsoc = NULL; + + if ( IsPlayer() ) + { + runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP); + + if ( runStopAsoc == NULL ) + runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R); + } + + if ( runStopAsoc != NULL && runStopAsoc->blendAmount > 0.1f ) + { + { + CVector pos(0.0f, 0.0f, 0.0f); + RwFrame *parent = m_pFrames[PED_FOOTL]->frame; + while( parent ) + { + RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(parent)); + parent = RwFrameGetParent(parent); + } + + pos.z -= 0.1f; + pos += GetForward()*0.2f; + particleProduceFootDust(this, pos, 0.02f, 1); + } + + { + CVector pos(0.0f, 0.0f, 0.0f); + RwFrame *parent = m_pFrames[PED_FOOTR]->frame; + while( parent ) + { + RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(parent)); + parent = RwFrameGetParent(parent); + } + + pos.z -= 0.1f; + pos += GetForward()*0.2f; + particleProduceFootDust(this, pos, 0.02f, 1); + } + } +#endif + + if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) { float stepStart = 1 / 15.0f; float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart; @@ -2121,9 +2176,15 @@ CPed::PlayFootSteps(void) } if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) { if(IsPlayer()) - particleProduceFootDust(this, &footPos, 0.0f, 4); - } else if(stepPart == 2) { - particleProduceFootSplash(this, &footPos, 0.15f, 4); + particleProduceFootDust(this, footPos, 0.0f, 4); + } +#ifdef PC_PARTICLE + else if(stepPart == 2) +#else + else +#endif + { + particleProduceFootSplash(this, footPos, 0.15f, 4); } } } @@ -2131,6 +2192,7 @@ CPed::PlayFootSteps(void) if (m_nSurfaceTouched == SURFACE_PUDDLE) { float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude(); if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) { +#ifdef PC_PARTICLE float particleSize = pedSpeed * 2.0f; if (particleSize < 0.25f) @@ -2149,6 +2211,12 @@ CPed::PlayFootSteps(void) particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f); CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, CRGBA(255,255,255,255), 0, 0, 0, 0); +#else + CVector particlePos = (GetPosition() - 0.3f * GetUp()) + GetForward()*0.3f; + CVector particleDir = m_vecMoveSpeed * 0.45f; + particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f); + CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos-CVector(0.0f, 0.0f, 1.2f), particleDir, nil, 0.0f, CRGBA(155, 185, 155, 255)); +#endif } } } @@ -15114,7 +15182,11 @@ CPed::ProcessBuoyancy(void) bIsInTheAir = false; } pos.z = pos.z - 0.8f; +#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true); +#else + CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true); +#endif m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); m_nPedState = PED_IDLE; return; @@ -15143,6 +15215,7 @@ CPed::ProcessBuoyancy(void) } else { m_vecMoveSpeed.z = -0.01f; DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); +#ifdef PC_PARTICLE CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); float level = 0.0f; if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) @@ -15151,6 +15224,18 @@ CPed::ProcessBuoyancy(void) CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true); nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80; nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100; +#else + CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) + aBitForward.z = level + 0.5f; + + CVector vel = m_vecMoveSpeed * 0.1f; + vel.z = 0.18f; + CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true); + nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300; + nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60; +#endif } } } else @@ -15167,9 +15252,15 @@ CPed::ProcessBuoyancy(void) if (pos.z != 0.0f) { nGenerateWaterCircles = 0; for(int i = 0; i < 4; i++) { +#ifdef PC_PARTICLE pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0); +#else + pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); + pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); + CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f)); +#endif } } } @@ -15181,9 +15272,17 @@ CPed::ProcessBuoyancy(void) pos.z = level; if (pos.z >= 0.0f) { +#ifdef PC_PARTICLE pos.z += 0.25f; +#else + pos.z += 0.5f; +#endif nGenerateRaindrops = 0; +#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); +#else + CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true); +#endif } } } diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp index 0388e779..c855c860 100644 --- a/src/render/Particle.cpp +++ b/src/render/Particle.cpp @@ -12,9 +12,6 @@ #include "ParticleObject.h" #include "Particle.h" -#ifdef TOGGLEABLE_BETA_FEATURES -bool CParticle::bEnableBannedParticles = false; -#endif #define MAX_PARTICLES_ON_SCREEN (1000) @@ -388,8 +385,12 @@ void CParticle::Initialise() gpFlame5Tex = RwTextureRead("flame5", nil); +#ifdef FIX_BUGS + gpFlame5Raster = RwTextureGetRaster(gpFlame5Tex); +#else gpFlame5Raster = RwTextureGetRaster(gpFlame1Tex); // copy-paste bug ? - +#endif + gpRainDropSmallTex = RwTextureRead("rainsmall", nil); gpRainDropSmallRaster = RwTextureGetRaster(gpRainDropSmallTex); @@ -767,9 +768,8 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe { if ( CTimer::GetIsPaused() ) return NULL; -#ifdef TOGGLEABLE_BETA_FEATURES - if(!bEnableBannedParticles) -#endif + +#ifdef PC_PARTICLE if ( ( type == PARTICLE_ENGINE_SMOKE || type == PARTICLE_ENGINE_SMOKE2 || type == PARTICLE_ENGINE_STEAM @@ -782,6 +782,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe { return nil; } +#endif CParticle *pParticle = m_pUnusedListHead; @@ -853,6 +854,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe pParticle->m_nRotation = nRotation; +// PC only if ( pParticle->m_nRotation >= 360 ) pParticle->m_nRotation -= 360; else if ( pParticle->m_nRotation < 0 ) @@ -1348,12 +1350,13 @@ void CParticle::Update() particle->m_nAlpha = clamp(particle->m_nAlpha - psystem->m_nFadeAlphaAmount, 0, 255); - +#ifdef PC_PARTICLE if ( particle->m_nAlpha == 0 ) { bRemoveParticle = true; continue; } +#endif } else ++particle->m_nFadeAlphaTimer; @@ -1448,18 +1451,15 @@ void CParticle::Render() for ( int32 i = 0; i < MAX_PARTICLES; i++ ) { tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[i]; - +#ifdef PC_PARTICLE bool particleBanned = false; - +#endif CParticle *particle = psystem->m_pParticles; RwRaster **frames = psystem->m_ppRaster; - +#ifdef PC_PARTICLE tParticleType type = psystem->m_Type; -#ifdef TOGGLEABLE_BETA_FEATURES - if (!bEnableBannedParticles) -#endif if ( type == PARTICLE_ENGINE_SMOKE || type == PARTICLE_ENGINE_SMOKE2 || type == PARTICLE_ENGINE_STEAM @@ -1471,7 +1471,8 @@ void CParticle::Render() { particleBanned = true; } - +#endif + if ( particle ) { if ( (flags & DRAW_OPAQUE) != (psystem->Flags & DRAW_OPAQUE) @@ -1512,10 +1513,11 @@ void CParticle::Render() while ( particle != nil ) { bool canDraw = true; +#ifdef PC_PARTICLE if ( particle->m_nAlpha == 0 ) canDraw = false; - +#endif if ( canDraw && psystem->m_nFinalAnimationFrame != 0 && frames != nil ) { RwRaster *curFrame = frames[particle->m_nCurrentFrame]; @@ -1538,7 +1540,7 @@ void CParticle::Render() particle->m_fSize * 63.0f, particle->m_Color, particle->m_nColorIntensity, - (float)particle->m_nRotation, + (float)particle->m_nRotation, //DEGTORAD((float)particle->m_nRotation) ps2 particle->m_nAlpha); } else @@ -1564,8 +1566,10 @@ void CParticle::Render() if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) ) { +#ifdef PC_PARTICLE if ( (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w) && SCREEN_HEIGHT * fParticleScaleLimit >= h ) +#endif { if ( particle->m_nRotation != 0 ) { @@ -1576,7 +1580,7 @@ void CParticle::Render() particle->m_Color.blue, particle->m_nColorIntensity, 1.0f / coors.z, - float(particle->m_nRotation), + float(particle->m_nRotation), // DEGTORAD((float)particle->m_nRotation) ps2 particle->m_nAlpha); } else if ( psystem->Flags & SCREEN_TRAIL ) @@ -1601,7 +1605,6 @@ void CParticle::Render() fTrailLength = fDist; - //Float fRot = Atan2( vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)) ); float fRot = Asin(vecDist.x / fDist); fRotation = fRot; @@ -1653,7 +1656,6 @@ void CParticle::Render() fTrailLength = fDist; - //Float fRot = Atan2(vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist))); float fRot = Asin(vecDist.x / fDist); fRotation = fRot; diff --git a/src/render/Particle.h b/src/render/Particle.h index 8999f4f6..b71dc717 100644 --- a/src/render/Particle.h +++ b/src/render/Particle.h @@ -89,10 +89,6 @@ public: static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize); static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix); - -#ifdef TOGGLEABLE_BETA_FEATURES - static bool bEnableBannedParticles; -#endif }; VALIDATE_SIZE(CParticle, 0x68); \ No newline at end of file diff --git a/src/render/ParticleMgr.cpp b/src/render/ParticleMgr.cpp index 00391ac5..3387d471 100644 --- a/src/render/ParticleMgr.cpp +++ b/src/render/ParticleMgr.cpp @@ -8,8 +8,7 @@ cParticleSystemMgr mod_ParticleSystemManager; const char *ParticleFilename = "PARTICLE.CFG"; -//cParticleSystemMgr::cParticleSystemMgr() -void cParticleSystemMgr::ctor() +cParticleSystemMgr::cParticleSystemMgr() { memset(this, 0, sizeof(*this)); } diff --git a/src/render/ParticleMgr.h b/src/render/ParticleMgr.h index 0b4091de..70845a56 100644 --- a/src/render/ParticleMgr.h +++ b/src/render/ParticleMgr.h @@ -118,11 +118,11 @@ class cParticleSystemMgr public: tParticleSystemData m_aParticles[MAX_PARTICLES]; - cParticleSystemMgr() { ctor(); } void ctor(); + cParticleSystemMgr(); void Initialise(); void LoadParticleData(); - //void RangeCheck(tParticleSystemData *pData); + void RangeCheck(tParticleSystemData *pData) { } }; VALIDATE_SIZE(cParticleSystemMgr, 0x2420); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 1b14e7a2..74609e15 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -2848,6 +2848,7 @@ CAutomobile::ProcessBuoyancy(void) static uint32 nGenerateWaterCircles = 0; if(initialSpeed.z < -0.3f && impulse.z > 0.3f){ +#if defined(PC_PARTICLE) || defined (PS2_ALTERNATIVE_CARSPLASH) RwRGBA color; color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.45f*255; color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.45f*255; @@ -2856,6 +2857,30 @@ CAutomobile::ProcessBuoyancy(void) CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition(), CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.15f, 0.3f)), 0.0f, 75, color, true); +#else + CVector pos = (initialSpeed * 2.0f) + (GetPosition() + point); + + for ( int32 i = 0; i < 360; i += 4 ) + { + float fSin = Sin(float(i)); + float fCos = Cos(float(i)); + + CVector dir(fSin*0.01f, fCos*0.01f, CGeneral::GetRandomNumberInRange(0.25f, 0.45f)); + + CParticle::AddParticle(PARTICLE_CAR_SPLASH, + pos + CVector(fSin*4.5f, fCos*4.5f, 0.0f), + dir, NULL, 0.0f, CRGBA(225, 225, 255, 180)); + + for ( int32 j = 0; j < 3; j++ ) + { + float fMul = 1.5f * float(j + 1); + + CParticle::AddParticle(PARTICLE_CAR_SPLASH, + pos + CVector(fSin * fMul, fCos * fMul, 0.0f), + dir, NULL, 0.0f, CRGBA(225, 225, 255, 180)); + } + } +#endif nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300; nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60; @@ -2909,9 +2934,16 @@ CAutomobile::ProcessBuoyancy(void) CVector pos = m_aWheelColPoints[i].point + 0.3f*GetUp() - GetPosition(); CVector vSpeed = GetSpeed(pos); vSpeed.z = 0.0f; +#ifdef GTA_PS2_STUFF + // ps2 puddle physics + CVector moveForce = CTimer::GetTimeStep() * (m_fMass * (vSpeed * -0.003f)); + ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z); +#endif float fSpeed = vSpeed.MagnitudeSqr(); +#ifdef PC_PARTICLE if(fSpeed > sq(0.05f)){ fSpeed = Sqrt(fSpeed); + float size = Min((fSpeed < 0.15f ? 0.25f : 0.75f)*fSpeed, 0.6f); CVector right = 0.2f*fSpeed*GetRight() + 0.2f*vSpeed; @@ -2924,10 +2956,39 @@ CAutomobile::ProcessBuoyancy(void) CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, pos + GetPosition(), -0.6f*right, nil, size, smokeCol, 0, 0, 0, 0); - + if((CTimer::GetFrameCounter() & 0xF) == 0) DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed); } +#else + if ( ( (CTimer::GetFrameCounter() + i) & 3 ) == 0 ) + { + if(fSpeed > sq(0.05f)) + { + fSpeed = Sqrt(fSpeed); + CRGBA color(155, 185, 155, 255); + float boxY = GetColModel()->boundingBox.max.y; + CVector right = 0.5f * GetRight(); + + if ( i == 2 ) + { + CParticle::AddParticle(PARTICLE_PED_SPLASH, + GetPosition() + (boxY * GetForward()) + right, + 0.75f*m_vecMoveSpeed, NULL, 0.0f, color); + + } + else if ( i == 0 ) + { + CParticle::AddParticle(PARTICLE_PED_SPLASH, + GetPosition() + (boxY * GetForward()) - right, + 0.75f*m_vecMoveSpeed, NULL, 0.0f, color); + } + + if((CTimer::GetFrameCounter() & 0xF) == 0) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed); + } + } +#endif } } } @@ -3486,14 +3547,29 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed) } return 0; default: - // Is this even visible? - if(CWeather::WetRoads > 0.01f && CTimer::GetFrameCounter() & 1){ - CParticle::AddParticle(PARTICLE_WATERSPRAY, + if ( CWeather::WetRoads > 0.01f +#ifdef PC_PARTICLE + && CTimer::GetFrameCounter() & 1 +#endif + ) + { + CParticle::AddParticle( +#ifdef FIX_BUGS + PARTICLE_WHEEL_WATER, +#else + PARTICLE_WATERSPRAY, +#endif colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f), - CVector(0.0f, 0.0f, 1.0f), nil, +#ifdef PC_PARTICLE + CVector(0.0f, 0.0f, 1.0f), +#else + CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)), +#endif + nil, CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol); return 0; } + return 1; } } diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 42beeb6c..d31182cd 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -340,27 +340,46 @@ CBoat::ProcessControl(void) else jetPos.z = 0.0f; +#ifdef PC_PARTICLE CVector wakePos = GetPosition() + sternPos; wakePos.z -= 0.65f; +#else + CVector wakePos = GetPosition() + sternPos; + wakePos.z = -0.3f; +#endif CVector wakeDir = 0.75f * jetDir; CParticle::AddParticle(PARTICLE_BOAT_THRUSTJET, jetPos, jetDir, nil, 0.0f, jetColor); +#ifdef PC_PARTICLE CParticle::AddParticle(PARTICLE_CAR_SPLASH, jetPos, 0.25f * jetDir, nil, 1.0f, splashColor, CGeneral::GetRandomNumberInRange(0, 30), CGeneral::GetRandomNumberInRange(0, 90), 3); +#endif if(!cameraHack) CParticle::AddParticle(PARTICLE_BOAT_WAKE, wakePos, wakeDir, nil, 0.0f, jetColor); }else if((CTimer::GetFrameCounter() + m_randomSeed) & 1){ +#ifdef PC_PARTICLE jetDir.z = 0.018f; jetDir.x *= 0.01f; jetDir.y *= 0.01f; propellerWorld.z += 1.5f; - + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.5f, jetColor); +#else + jetDir.z = 0.018f; + jetDir.x *= 0.03f; + jetDir.y *= 0.03f; + propellerWorld.z += 1.0f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 0.0f, jetColor); +#endif + +#ifdef PC_PARTICLE CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.1f * jetDir, nil, 0.5f, splashColor, CGeneral::GetRandomNumberInRange(0, 30), CGeneral::GetRandomNumberInRange(0, 90), 3); +#endif } } }else if(!onLand){ @@ -416,36 +435,66 @@ CBoat::ProcessControl(void) } // Spray particles on sides of boat - if(m_nDeltaVolumeUnderWater > 75){ +#ifdef PC_PARTICLE + if(m_nDeltaVolumeUnderWater > 75) +#else + if(m_nDeltaVolumeUnderWater > 120) +#endif + { float speed = m_vecMoveSpeed.Magnitude(); float splash1Size = speed; - float splash2Size = m_nDeltaVolumeUnderWater * 0.005f * 0.2f; + float splash2Size = float(m_nDeltaVolumeUnderWater) * 0.005f * 0.2f; float front = 0.9f * GetColModel()->boundingBox.max.y; if(splash1Size > 0.75f) splash1Size = 0.75f; CVector dir, pos; // right +#ifdef PC_PARTICLE dir = -0.5f*m_vecMoveSpeed; dir.z += 0.1f*speed; dir += 0.5f*GetRight()*speed; pos = front*GetForward() + 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint; CWaterLevel::GetWaterLevel(pos, &pos.z, true); +#else + dir = 0.3f*m_vecMoveSpeed; + dir.z += 0.05f*speed; + dir += 0.5f*GetRight()*speed; + pos = (GetPosition() + m_vecBuoyancePoint) + (1.5f*GetRight()); +#endif + +#ifdef PC_PARTICLE CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor, CGeneral::GetRandomNumberInRange(0, 30), CGeneral::GetRandomNumberInRange(0, 90), 1); CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor); +#else + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size); +#endif + // left +#ifdef PC_PARTICLE dir = -0.5f*m_vecMoveSpeed; dir.z += 0.1f*speed; dir -= 0.5f*GetRight()*speed; pos = front*GetForward() - 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint; CWaterLevel::GetWaterLevel(pos, &pos.z, true); +#else + dir = 0.3f*m_vecMoveSpeed; + dir.z += 0.05f*speed; + dir -= 0.5f*GetRight()*speed; + pos = (GetPosition() + m_vecBuoyancePoint) - (1.5f*GetRight()); +#endif + +#ifdef PC_PARTICLE CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor, CGeneral::GetRandomNumberInRange(0, 30), CGeneral::GetRandomNumberInRange(0, 90), 1); CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor); +#else + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size); +#endif } m_fPrevVolumeUnderWater = m_fVolumeUnderWater; From 2925b7e0c391f2d44e1e3641e2387be6fb0be491 Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Thu, 23 Apr 2020 11:35:42 +0300 Subject: [PATCH 4/5] fix #ifdef --- src/audio/AudioManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 02bf532c..0c4b007f 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -9606,7 +9606,7 @@ cAudioManager::ServiceSoundEffects() ProcessMissionAudio(); AdjustSamplesVolume(); ProcessActiveQueues(); -#ifdef WITHMILES +#ifdef OPENAL SampleManager.Service(); #endif for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) { From 458eb3a4f079af4c118357fb3bd0594626151e9d Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Thu, 23 Apr 2020 16:40:19 +0300 Subject: [PATCH 5/5] removed fix that made no sense --- src/vehicles/Vehicle.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index c09375cc..57c5f3af 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -1002,21 +1002,15 @@ void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle) { if (pVehicle->pDriver) { -#ifndef FIX_BUGS - // this just isn't fair CDarkel::RegisterKillByPlayer(pVehicle->pDriver, WEAPONTYPE_UNIDENTIFIED); -#endif pVehicle->pDriver->FlagToDestroyWhenNextProcessed(); } for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) { if (pVehicle->pPassengers[i]) { -#ifndef FIX_BUGS - // this just isn't fair CDarkel::RegisterKillByPlayer(pVehicle->pPassengers[i], WEAPONTYPE_UNIDENTIFIED); -#endif pVehicle->pPassengers[i]->FlagToDestroyWhenNextProcessed(); } } CWorld::Remove(pVehicle); delete pVehicle; -} \ No newline at end of file +}