Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
152
WWFLAT32/AUDIO/AUDIO.BAK
Normal file
152
WWFLAT32/AUDIO/AUDIO.BAK
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : AUDIO.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : March 10, 1995 *
|
||||
* *
|
||||
* Last Update : March 10, 1995 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwstd.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
/* AUD file header type */
|
||||
/*=========================================================================*/
|
||||
#define AUD_FLAG_STEREO 1
|
||||
#define AUD_FLAG_16BIT 2
|
||||
|
||||
// PWG 3-14-95: This structure used to have bit fields defined for Stereo
|
||||
// and Bits. These were removed because watcom packs them into a 32 bit
|
||||
// flag entry even though they could have fit in a 8 bit entry.
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
short int Rate; // Playback rate (hertz).
|
||||
long Size; // Size of data (bytes).
|
||||
long UncompSize; // Size of data (bytes).
|
||||
unsigned char Flags; // Holds flags for info
|
||||
// 1: Is the sample stereo?
|
||||
// 2: Is the sample 16 bits?
|
||||
unsigned char Compression; // What kind of compression for this sample?
|
||||
} AUDHeaderType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* There can be a different sound driver for sound effects, digitized */
|
||||
/* samples, and musical scores. Each one must be of these specified */
|
||||
/* types. */
|
||||
/*=========================================================================*/
|
||||
typedef enum {
|
||||
SAMPLE_NONE, // No digitized sounds will be played.
|
||||
SAMPLE_SB, // Sound Blaster digitized driver.
|
||||
SAMPLE_SBPRO, // Sound Blaster Pro digitized driver.
|
||||
SAMPLE_PAS, // Pro-Audio Spectrum digitized driver.
|
||||
SAMPLE_ADLIBG, // Adlib-Gold digitized driver.
|
||||
SAMPLE_TANDY, // Tandy 'compatible' driver.
|
||||
SAMPLE_PCSPKR, // PC speaker digitized driver (The Audio Solution driver).
|
||||
SAMPLE_ADLIB, // Adlib digitized driver (The Audio Solution driver).
|
||||
SAMPLE_TEMP=0x1000,
|
||||
SAMPLE_LAST
|
||||
} Sample_Type;
|
||||
|
||||
typedef enum {
|
||||
SCORE_NONE, // No scores will be played.
|
||||
SCORE_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SCORE_WWPCSPKR, // Westwood's PC-speaker driver (obsolete).
|
||||
SCORE_WWTANDY, // Westwood's PC-speaker driver with Tandy mod (obsolete).
|
||||
SCORE_PCSPKR, // PC speaker XMIDI driver.
|
||||
SCORE_TANDY, // Tandy XMIDI driver.
|
||||
SCORE_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SCORE_CANVAS, // Sound Canvas SC-55.
|
||||
SCORE_ADLIB, // Adlib XMIDI driver.
|
||||
SCORE_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SCORE_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SCORE_SBFM, // Sound Blaster XMIDI driver.
|
||||
SCORE_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SCORE_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver (Can't use with SFX_ALFX).
|
||||
SCORE_TEMP=0x1000,
|
||||
SCORE_LAST
|
||||
} Score_Type;
|
||||
|
||||
typedef enum {
|
||||
SFX_NONE, // No sound effects will be played.
|
||||
SFX_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SFX_WWPCSPKR, // Westwood's PC-speaker driver.
|
||||
SFX_WWTANDY, // Westwood's PC-speaker driver with Tandy mod.
|
||||
SFX_PCSPKR, // PC speaker XMIDI driver.
|
||||
SFX_TANDY, // Tandy XMIDI driver.
|
||||
SFX_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SFX_CANVAS, // Sound Canvas SC-55.
|
||||
SFX_ADLIB, // Adlib XMIDI driver.
|
||||
SFX_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SFX_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SFX_SBFM, // Sound Blaster XMIDI driver.
|
||||
SFX_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SFX_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver.
|
||||
SFX_TEMP=0x1000,
|
||||
SFX_LAST
|
||||
} SFX_Type;
|
||||
|
||||
typedef enum RateEnum {
|
||||
PLAYBACK_RATE_SLOW =11025,
|
||||
PLAYBACK_RATE_NORMAL =(11025 * 2),
|
||||
PLAYBACK_RATE_FAST =(11025 * 4),
|
||||
} RateType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following prototypes are for the file: SOUNDIO.CPP */
|
||||
/*=========================================================================*/
|
||||
int File_Stream_Sample(char const *filename, BOOL real_time_start = FALSE);
|
||||
int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start = FALSE);
|
||||
void cdecl _saveregs Sound_Callback(void);
|
||||
void cdecl far __saveregs __loadds maintenance_callback(void);
|
||||
void *Load_Sample(char const *filename);
|
||||
long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size);
|
||||
long Sample_Read(int fh, void *buffer, long size);
|
||||
void Free_Sample(void const *sample);
|
||||
BOOL Sound_Init(int sfx, int score, int sample, RateType rate, int bits_per_sample, int max_samples, int reverse_channels);
|
||||
BOOL Audio_Init(int sample, int address, int inter, int dma, RateType rate, int bits_per_sample, int max_samples, int reverse_channels = FALSE);
|
||||
void Sound_End(void);
|
||||
void Stop_Sample(int handle);
|
||||
BOOL Sample_Status(int handle);
|
||||
BOOL Is_Sample_Playing(void const * sample);
|
||||
void Stop_Sample_Playing(void const * sample);
|
||||
int Play_Sample(void const *sample, int priority=0xFF, int volume=0xFF, signed short panloc = 0x0);
|
||||
int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id);
|
||||
int Set_Sound_Vol(int volume);
|
||||
int Set_Score_Vol(int volume);
|
||||
void Fade_Sample(int handle, int ticks);
|
||||
int Get_Free_Sample_Handle(int priority);
|
||||
int Get_Digi_Handle(void);
|
||||
long Sample_Length(void const *sample);
|
||||
|
||||
extern int Misc;
|
||||
extern SFX_Type SoundType;
|
||||
extern Sample_Type SampleType;
|
153
WWFLAT32/AUDIO/AUDIO.H
Normal file
153
WWFLAT32/AUDIO/AUDIO.H
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : AUDIO.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : March 10, 1995 *
|
||||
* *
|
||||
* Last Update : March 10, 1995 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwstd.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
/* AUD file header type */
|
||||
/*=========================================================================*/
|
||||
#define AUD_FLAG_STEREO 1
|
||||
#define AUD_FLAG_16BIT 2
|
||||
|
||||
// PWG 3-14-95: This structure used to have bit fields defined for Stereo
|
||||
// and Bits. These were removed because watcom packs them into a 32 bit
|
||||
// flag entry even though they could have fit in a 8 bit entry.
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
short int Rate; // Playback rate (hertz).
|
||||
long Size; // Size of data (bytes).
|
||||
long UncompSize; // Size of data (bytes).
|
||||
unsigned char Flags; // Holds flags for info
|
||||
// 1: Is the sample stereo?
|
||||
// 2: Is the sample 16 bits?
|
||||
unsigned char Compression; // What kind of compression for this sample?
|
||||
} AUDHeaderType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* There can be a different sound driver for sound effects, digitized */
|
||||
/* samples, and musical scores. Each one must be of these specified */
|
||||
/* types. */
|
||||
/*=========================================================================*/
|
||||
typedef enum {
|
||||
SAMPLE_NONE, // No digitized sounds will be played.
|
||||
SAMPLE_SB, // Sound Blaster digitized driver.
|
||||
SAMPLE_SBPRO, // Sound Blaster Pro digitized driver.
|
||||
SAMPLE_PAS, // Pro-Audio Spectrum digitized driver.
|
||||
SAMPLE_ADLIBG, // Adlib-Gold digitized driver.
|
||||
SAMPLE_TANDY, // Tandy 'compatible' driver.
|
||||
SAMPLE_PCSPKR, // PC speaker digitized driver (The Audio Solution driver).
|
||||
SAMPLE_ADLIB, // Adlib digitized driver (The Audio Solution driver).
|
||||
SAMPLE_TEMP=0x1000,
|
||||
SAMPLE_LAST
|
||||
} Sample_Type;
|
||||
|
||||
typedef enum {
|
||||
SCORE_NONE, // No scores will be played.
|
||||
SCORE_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SCORE_WWPCSPKR, // Westwood's PC-speaker driver (obsolete).
|
||||
SCORE_WWTANDY, // Westwood's PC-speaker driver with Tandy mod (obsolete).
|
||||
SCORE_PCSPKR, // PC speaker XMIDI driver.
|
||||
SCORE_TANDY, // Tandy XMIDI driver.
|
||||
SCORE_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SCORE_CANVAS, // Sound Canvas SC-55.
|
||||
SCORE_ADLIB, // Adlib XMIDI driver.
|
||||
SCORE_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SCORE_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SCORE_SBFM, // Sound Blaster XMIDI driver.
|
||||
SCORE_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SCORE_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver (Can't use with SFX_ALFX).
|
||||
SCORE_TEMP=0x1000,
|
||||
SCORE_LAST
|
||||
} Score_Type;
|
||||
|
||||
typedef enum {
|
||||
SFX_NONE, // No sound effects will be played.
|
||||
SFX_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SFX_WWPCSPKR, // Westwood's PC-speaker driver.
|
||||
SFX_WWTANDY, // Westwood's PC-speaker driver with Tandy mod.
|
||||
SFX_PCSPKR, // PC speaker XMIDI driver.
|
||||
SFX_TANDY, // Tandy XMIDI driver.
|
||||
SFX_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SFX_CANVAS, // Sound Canvas SC-55.
|
||||
SFX_ADLIB, // Adlib XMIDI driver.
|
||||
SFX_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SFX_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SFX_SBFM, // Sound Blaster XMIDI driver.
|
||||
SFX_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SFX_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver.
|
||||
SFX_TEMP=0x1000,
|
||||
SFX_LAST
|
||||
} SFX_Type;
|
||||
|
||||
typedef enum RateEnum {
|
||||
PLAYBACK_RATE_SLOW =11025,
|
||||
PLAYBACK_RATE_NORMAL =(11025 * 2),
|
||||
PLAYBACK_RATE_FAST =(11025 * 4),
|
||||
} RateType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following prototypes are for the file: SOUNDIO.CPP */
|
||||
/*=========================================================================*/
|
||||
int File_Stream_Sample(char const *filename, BOOL real_time_start = FALSE);
|
||||
int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start = FALSE);
|
||||
void cdecl _saveregs Sound_Callback(void);
|
||||
void cdecl far __saveregs __loadds maintenance_callback(void);
|
||||
void *Load_Sample(char const *filename);
|
||||
long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size);
|
||||
long Sample_Read(int fh, void *buffer, long size);
|
||||
void Free_Sample(void const *sample);
|
||||
BOOL Sound_Init(int sfx, int score, int sample, RateType rate, int bits_per_sample, int max_samples, int reverse_channels);
|
||||
BOOL Audio_Init(int sample, int address, int inter, int dma, RateType rate, int bits_per_sample, int max_samples, int reverse_channels = FALSE);
|
||||
void Sound_End(void);
|
||||
void Stop_Sample(int handle);
|
||||
BOOL Sample_Status(int handle);
|
||||
BOOL Is_Sample_Playing(void const * sample);
|
||||
void Stop_Sample_Playing(void const * sample);
|
||||
int Play_Sample(void const *sample, int priority=0xFF, int volume=0xFF, signed short panloc = 0x0);
|
||||
int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id);
|
||||
int Set_Sound_Vol(int volume);
|
||||
int Set_Score_Vol(int volume);
|
||||
void Fade_Sample(int handle, int ticks);
|
||||
int Get_Free_Sample_Handle(int priority);
|
||||
int Get_Digi_Handle(void);
|
||||
long Sample_Length(void const *sample);
|
||||
|
||||
extern int Misc;
|
||||
extern SFX_Type SoundType;
|
||||
extern Sample_Type SampleType;
|
||||
extern short StreamLowImpact;
|
437
WWFLAT32/AUDIO/AUDUNCMP.ASM
Normal file
437
WWFLAT32/AUDIO/AUDUNCMP.ASM
Normal file
@@ -0,0 +1,437 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Audio Library *
|
||||
;* *
|
||||
;* File Name : AUDUNCMP.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil W. Gorrow *
|
||||
;* *
|
||||
;* Start Date : March 14, 1995 *
|
||||
;* *
|
||||
;* Last Update : June 26, 1995 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Decompress_Frame_Lock -- locks the JLB audio decompression code *
|
||||
;* Decompress_Frame_Unlock -- Unlocks the JLB audio compression code *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
CODESEG
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
CODE_2BIT EQU 0
|
||||
CODE_4BIT EQU 1
|
||||
CODE_RAW EQU 2
|
||||
CODE_SILENCE EQU 3
|
||||
MAGICNUMBER EQU 00000DEAFh
|
||||
MAGICNUMBER2 EQU 0BABEBABEh
|
||||
|
||||
_2bitdecode DB -2,-1,0,1
|
||||
_4bitdecode DB -9,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME -- Uncompresses a WW compressed audio frame *
|
||||
;* *
|
||||
;* INPUT: void * source - pointer to encoded audio data *
|
||||
;* void * dest - pointer to decompression area *
|
||||
;* long size - the maximum size of destination buffer *
|
||||
;* *
|
||||
;* OUTPUT: long - the number of bytes we uncompressed *
|
||||
;* *
|
||||
;* PROTO: long Decompress_Frame(void *, void *, long); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/14/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
GLOBAL Decompress_Frame:NEAR
|
||||
PROC Decompress_Frame C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG count:DWORD
|
||||
|
||||
LOCAL previous:BYTE
|
||||
LOCAL incount:DWORD
|
||||
|
||||
pushf
|
||||
cld
|
||||
mov [incount],0 ;Bytes read from source
|
||||
|
||||
|
||||
; Source, Dest and count must be valid.
|
||||
|
||||
cmp [source],0
|
||||
je ??fini
|
||||
|
||||
cmp [dest],0
|
||||
je ??fini
|
||||
|
||||
cmp [count],0
|
||||
je ??fini
|
||||
|
||||
mov esi,[source] ;Pointer to source data.
|
||||
mov edi,[dest] ;Pointer to destination data.
|
||||
mov ecx,[count] ;Number of bytes to fill dest buffer.
|
||||
mov dl,080h ;Previous sample (starting value).
|
||||
|
||||
??mainloop:
|
||||
cmp ecx,0 ;If dest full then exit
|
||||
jle ??fini
|
||||
|
||||
xor eax,eax
|
||||
mov al,[esi] ;Get code byte
|
||||
inc [incount]
|
||||
inc esi
|
||||
shl eax,2 ;AH contains code.
|
||||
shr al,2 ;AL contains sub-code data.
|
||||
|
||||
cmp ah,CODE_RAW ;Raw sequence?
|
||||
jne short ??try4bit
|
||||
|
||||
; The code contains either a 5 bit delta or a count of
|
||||
; raw samples to dump out.
|
||||
|
||||
test al,00100000b
|
||||
je short ??justraw
|
||||
|
||||
; The lower 5 bits are actually a signed delta.
|
||||
; Sign extend the delta and add it to the stream.
|
||||
|
||||
shl al,3
|
||||
sar al,3
|
||||
add dl,al
|
||||
mov [edi],dl
|
||||
dec ecx
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; The lower 5 bits hold a count of the number of raw
|
||||
; samples that follow this code. Dump these samples to
|
||||
; the output buffer.
|
||||
|
||||
??justraw:
|
||||
mov ebx,ecx
|
||||
xor ah,ah
|
||||
inc al
|
||||
mov ecx,eax
|
||||
shr ecx,1
|
||||
rep movsw
|
||||
adc ecx,ecx
|
||||
rep movsb
|
||||
mov ecx,ebx
|
||||
add [incount],eax
|
||||
sub ecx,eax
|
||||
dec edi
|
||||
mov dl,[edi] ;Set "previous" value.
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if this is a 4 bit delta code sequence.
|
||||
|
||||
??try4bit:
|
||||
inc al ;Following codes use AL+1
|
||||
cmp ah,CODE_4BIT
|
||||
jne short ??try2bit
|
||||
|
||||
; A sequence of 4bit deltas follow. AL equals the
|
||||
; number of nibble packed delta bytes to process.
|
||||
|
||||
??bit4loop:
|
||||
mov ah,[esi] ;Fetch nibble packed delta codes
|
||||
mov bl,ah
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
and ebx,00001111b
|
||||
add dl,[_4bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg1
|
||||
|
||||
popf
|
||||
jnc short ??ok1
|
||||
mov dl,0FFh
|
||||
jmp short ??ok1
|
||||
|
||||
??neg1:
|
||||
popf
|
||||
jc short ??ok1
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok1:
|
||||
mov dh,dl ;DH now holds new 'previous' sample.
|
||||
mov bl,ah
|
||||
shr bl,4
|
||||
add dh,[_4bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg2
|
||||
|
||||
popf
|
||||
jnc short ??ok2
|
||||
|
||||
mov dh,0FFh
|
||||
jmp short ??ok2
|
||||
|
||||
??neg2:
|
||||
popf
|
||||
jc short ??ok2
|
||||
|
||||
xor dh,dh
|
||||
|
||||
??ok2:
|
||||
mov [edi],dx ;Output the two sample bytes
|
||||
sub ecx,2
|
||||
add edi,2
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
mov dl,dh
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz short ??bit4loop
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if 2 bit deltas need to be processed.
|
||||
|
||||
??try2bit:
|
||||
cmp ah,CODE_2BIT
|
||||
jne ??zerodelta
|
||||
|
||||
; A sequence of 2bit deltas follow. AL equals the number of
|
||||
; packed delta bytes to process.
|
||||
|
||||
??bit2loop:
|
||||
mov ah,[esi] ;Fetch packed delat codes
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
mov bl,ah
|
||||
and ebx,000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg3
|
||||
|
||||
popf
|
||||
jnc short ??ok3
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok3
|
||||
|
||||
??neg3:
|
||||
popf
|
||||
jc short ??ok3
|
||||
xor dl,dl
|
||||
|
||||
??ok3:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,2
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg4
|
||||
|
||||
popf
|
||||
jnc short ??ok4
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok4
|
||||
|
||||
??neg4:
|
||||
popf
|
||||
jc short ??ok4
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok4:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,4
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg5
|
||||
|
||||
popf
|
||||
jnc short ??ok5
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok5
|
||||
|
||||
??neg5:
|
||||
popf
|
||||
jc short ??ok5
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok5:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,6
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg6
|
||||
|
||||
popf
|
||||
jnc short ??ok6
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok6
|
||||
|
||||
??neg6:
|
||||
popf
|
||||
jc short ??ok6
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok6:
|
||||
ror edx,8
|
||||
mov [edi],edx ;Output two sample bytes
|
||||
sub ecx,4
|
||||
add edi,4
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
rol edx,8
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz ??bit2loop
|
||||
jmp ??mainloop
|
||||
|
||||
; There is a run of zero deltas. Zero deltas merely duplicate
|
||||
; the 'previous' sample the requested number of times.
|
||||
|
||||
??zerodelta:
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
mov al,dl
|
||||
sub ecx,ebx
|
||||
xchg ecx,ebx
|
||||
rep stosb
|
||||
mov ecx,ebx
|
||||
jmp ??mainloop
|
||||
|
||||
??fini:
|
||||
popf
|
||||
mov eax,[incount]
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_LOCK -- locks the JLB audio decompression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is lock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL Decompress_Frame_Lock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL Decompress_Frame_Lock:NEAR
|
||||
PROC Decompress_Frame_Lock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame_Lock
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL Decompress_Frame_Unlock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL Decompress_Frame_Unlock:NEAR
|
||||
PROC Decompress_Frame_Unlock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
mov eax , 0601h
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame_Unlock
|
||||
|
||||
|
||||
|
||||
END
|
1448
WWFLAT32/AUDIO/DIFFTB.INC
Normal file
1448
WWFLAT32/AUDIO/DIFFTB.INC
Normal file
File diff suppressed because it is too large
Load Diff
47
WWFLAT32/AUDIO/FUNCTION.H
Normal file
47
WWFLAT32/AUDIO/FUNCTION.H
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following prototypes are for the file: SOUNDIO.CPP */
|
||||
/*=========================================================================*/
|
||||
|
||||
short Decompress_Frame(void * source, void * dest, short size);
|
||||
int cdecl Stream_Sample_Vol(void *buffer, long size, BOOL (*callback);
|
||||
int cdecl Stream_Sample(void *buffer, long size, BOOL (*callback);
|
||||
int cdecl File_Stream_Sample(char const *filename);
|
||||
int cdecl File_Stream_Sample_Vol(char const *filename, int volume);
|
||||
void cdecl _saveregs _loadds Sound_Callback(void);
|
||||
void cdecl far _saveregs _loadds maintenance_callback(void);
|
||||
void *cdecl Load_Sample(char const *filename);
|
||||
long cdecl Load_Sample_Into_Buffer(char const *filename, void *buffer, long size);
|
||||
long cdecl Sample_Read(int fh, void *buffer, long size);
|
||||
void cdecl Free_Sample(void const *sample);
|
||||
BOOL cdecl Sound_Init(int sfx, int score, int sample);
|
||||
void far VQA_TimerCallback(void);
|
||||
BOOL Audio_Init(int sample, int address, int inter, int dma);
|
||||
void cdecl Sound_End(void);
|
||||
void cdecl Stop_Sample(int handle);
|
||||
BOOL cdecl Sample_Status(int handle);
|
||||
BOOL cdecl Is_Sample_Playing(void const * sample);
|
||||
void cdecl Stop_Sample_Playing(void const * sample);
|
||||
int cdecl Play_Sample(void const *sample);
|
||||
int cdecl Play_Sample_Vol(void const *sample, int priority, int volume);
|
||||
int cdecl Set_Sound_Vol(int volume);
|
||||
int cdecl Set_Score_Vol(int volume);
|
||||
void cdecl Fade_Sample(int handle, int ticks);
|
1448
WWFLAT32/AUDIO/INDEXTB.INC
Normal file
1448
WWFLAT32/AUDIO/INDEXTB.INC
Normal file
File diff suppressed because it is too large
Load Diff
191
WWFLAT32/AUDIO/MAKEFILE
Normal file
191
WWFLAT32/AUDIO/MAKEFILE
Normal file
@@ -0,0 +1,191 @@
|
||||
#
|
||||
# Command & Conquer Red Alert(tm)
|
||||
# Copyright 2025 Electronic Arts Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#***************************************************************************
|
||||
#** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Project Name : Westwood Library .LIB makefile *
|
||||
#* *
|
||||
#* File Name : MAKEFILE *
|
||||
#* *
|
||||
#* Programmer : Julio R. Jerez *
|
||||
#* *
|
||||
#* Start Date : Jan 26, 1995 *
|
||||
#* *
|
||||
#* *
|
||||
#*-------------------------------------------------------------------------*
|
||||
#* *
|
||||
#* Required environment variables: *
|
||||
#* WWFLAT = your root WWFLAT path *
|
||||
#* WWVCS = root directory for wwlib version control archive *
|
||||
#* WATCOM = your Watcom installation path *
|
||||
#* *
|
||||
#* Required changes to makefile: *
|
||||
#* PROJ_NAME = name of the library you're building *
|
||||
#* OBJECTS = list of objects in your library *
|
||||
#* *
|
||||
#* Optional changes to makefile: *
|
||||
#* PROJ_DIR = full pathname of your working directory *
|
||||
#* .path.xxx = full pathname where various file types live *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Verify user's environment
|
||||
#---------------------------------------------------------------------------
|
||||
!ifndef %WWFLAT
|
||||
!error WWFLAT Environment var not configured.
|
||||
!endif
|
||||
|
||||
|
||||
!ifndef %WWVCS
|
||||
!error WWVCS Environment var not configured.
|
||||
!endif
|
||||
|
||||
!ifndef %WATCOM
|
||||
!error WATCOM Environment var not configured.
|
||||
!endif
|
||||
|
||||
|
||||
#===========================================================================
|
||||
# User-defined section: the user should tailor this section for each project
|
||||
#===========================================================================
|
||||
|
||||
PROJ_NAME = AUDIO
|
||||
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
|
||||
LIB_DIR = $(%WWFLAT)\lib
|
||||
|
||||
!include $(%WWFLAT)\project.cfg
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project-dependent variables
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
OBJECTS = &
|
||||
soundio.obj &
|
||||
soundint.obj &
|
||||
soundlck.obj &
|
||||
soscodec.obj &
|
||||
auduncmp.obj
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Path macros: one path for each file type.
|
||||
# These paths are used to tell make where to find/put each file type.
|
||||
#---------------------------------------------------------------------------
|
||||
.asm: $(PROJ_DIR)
|
||||
.c: $(PROJ_DIR)
|
||||
.cpp: $(PROJ_DIR)
|
||||
.h: $(PROJ_DIR)
|
||||
.obj: $(PROJ_DIR)
|
||||
.lib: $(%WWFLAT)\lib
|
||||
.exe: $(PROJ_DIR)
|
||||
|
||||
#===========================================================================
|
||||
# Pre-defined section: there should be little need to modify this section.
|
||||
#===========================================================================
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tools/commands
|
||||
#---------------------------------------------------------------------------
|
||||
C_CMD = wcc386
|
||||
CPP_CMD = wpp386
|
||||
LIB_CMD = wlib
|
||||
LINK_CMD = wlink
|
||||
ASM_CMD = tasm32
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Include & library paths
|
||||
# If LIB & INCLUDE are already defined, they are used in addition to the
|
||||
# WWLIB32 lib & include; otherwise, they're constructed from
|
||||
# BCDIR & TNTDIR
|
||||
#---------------------------------------------------------------------------
|
||||
LIBPATH = $(%WWFLAT)\LIB;$(%WATCOM)\LIB
|
||||
INCLUDEPATH = $(%WWFLAT)\INCLUDE;$(%WATCOM)\H
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Implicit rules
|
||||
# Compiler:
|
||||
# ($< = full dependent with path)
|
||||
# Assembler:
|
||||
# output obj's are constructed from .obj: & the $& macro
|
||||
# ($< = full dependent with path)
|
||||
# tasm's cfg file is not invoked as a response file.
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
.c.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
|
||||
$(C_CMD) $(CC_CFG) $<
|
||||
|
||||
.cpp.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
|
||||
$(CPP_CMD) $(CC_CFG) $<
|
||||
|
||||
.asm.obj: $(%WWFLAT)\project.cfg
|
||||
$(ASM_CMD) $(ASM_CFG) $<
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Default target: configuration files & library (in that order)
|
||||
#---------------------------------------------------------------------------
|
||||
all: $(LIB_DIR)\$(PROJ_NAME).lib .SYMBOLIC
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build the library
|
||||
# The original library is deleted by the librarian
|
||||
# Lib objects & -+ commands are constructed by substituting within the
|
||||
# $^@ macro (which expands to all target dependents, separated with
|
||||
# spaces)
|
||||
# Tlib's cfg file is not invoked as a response file.
|
||||
# All headers & source files are copied into WWFLAT\SRCDEBUG, for debugging
|
||||
#---------------------------------------------------------------------------
|
||||
$(LIB_DIR)\$(PROJ_NAME).lib: $(OBJECTS) objects.lbc
|
||||
copy *.lib $(%WWFLAT)\lib
|
||||
copy *.h $(%WWFLAT)\include
|
||||
copy *.inc $(%WWFLAT)\include
|
||||
copy *.cpp $(%WWFLAT)\srcdebug
|
||||
copy *.asm $(%WWFLAT)\srcdebug
|
||||
copy *.lib $(%WWFLAT)\lib
|
||||
$(LIB_CMD) $(LIB_CFG) $^@ @objects.lbc
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Objects now have a link file which is NOT generated everytime. Instead
|
||||
# it just has its own dependacy rule.
|
||||
#---------------------------------------------------------------------------
|
||||
objects.lbc : $(OBJECTS)
|
||||
%create $^@
|
||||
for %index in ($(OBJECTS)) do %append $^@ +%index
|
||||
|
||||
soundio.obj: .AUTODEPEND
|
||||
$(CPP_CMD) -zp4 -5s -mf -s -d2 /i=$(%WWFLAT)\include soundio.cpp
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Create the test directory and make it.
|
||||
#---------------------------------------------------------------------------
|
||||
test:
|
||||
mkdir test
|
||||
cd test
|
||||
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
|
||||
update
|
||||
wmake
|
||||
cd ..
|
||||
copy *.386 test
|
||||
|
||||
#**************************** End of makefile ******************************
|
||||
|
152
WWFLAT32/AUDIO/NEW/AUDIO.H
Normal file
152
WWFLAT32/AUDIO/NEW/AUDIO.H
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : AUDIO.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : March 10, 1995 *
|
||||
* *
|
||||
* Last Update : March 10, 1995 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwstd.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
/* AUD file header type */
|
||||
/*=========================================================================*/
|
||||
#define AUD_FLAG_STEREO 1
|
||||
#define AUD_FLAG_16BIT 2
|
||||
|
||||
// PWG 3-14-95: This structure used to have bit fields defined for Stereo
|
||||
// and Bits. These were removed because watcom packs them into a 32 bit
|
||||
// flag entry even though they could have fit in a 8 bit entry.
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
short int Rate; // Playback rate (hertz).
|
||||
long Size; // Size of data (bytes).
|
||||
long UncompSize; // Size of data (bytes).
|
||||
unsigned char Flags; // Holds flags for info
|
||||
// 1: Is the sample stereo?
|
||||
// 2: Is the sample 16 bits?
|
||||
unsigned char Compression; // What kind of compression for this sample?
|
||||
} AUDHeaderType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* There can be a different sound driver for sound effects, digitized */
|
||||
/* samples, and musical scores. Each one must be of these specified */
|
||||
/* types. */
|
||||
/*=========================================================================*/
|
||||
typedef enum {
|
||||
SAMPLE_NONE, // No digitized sounds will be played.
|
||||
SAMPLE_SB, // Sound Blaster digitized driver.
|
||||
SAMPLE_SBPRO, // Sound Blaster Pro digitized driver.
|
||||
SAMPLE_PAS, // Pro-Audio Spectrum digitized driver.
|
||||
SAMPLE_ADLIBG, // Adlib-Gold digitized driver.
|
||||
SAMPLE_TANDY, // Tandy 'compatible' driver.
|
||||
SAMPLE_PCSPKR, // PC speaker digitized driver (The Audio Solution driver).
|
||||
SAMPLE_ADLIB, // Adlib digitized driver (The Audio Solution driver).
|
||||
SAMPLE_TEMP=0x1000,
|
||||
SAMPLE_LAST
|
||||
} Sample_Type;
|
||||
|
||||
typedef enum {
|
||||
SCORE_NONE, // No scores will be played.
|
||||
SCORE_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SCORE_WWPCSPKR, // Westwood's PC-speaker driver (obsolete).
|
||||
SCORE_WWTANDY, // Westwood's PC-speaker driver with Tandy mod (obsolete).
|
||||
SCORE_PCSPKR, // PC speaker XMIDI driver.
|
||||
SCORE_TANDY, // Tandy XMIDI driver.
|
||||
SCORE_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SCORE_CANVAS, // Sound Canvas SC-55.
|
||||
SCORE_ADLIB, // Adlib XMIDI driver.
|
||||
SCORE_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SCORE_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SCORE_SBFM, // Sound Blaster XMIDI driver.
|
||||
SCORE_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SCORE_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver (Can't use with SFX_ALFX).
|
||||
SCORE_TEMP=0x1000,
|
||||
SCORE_LAST
|
||||
} Score_Type;
|
||||
|
||||
typedef enum {
|
||||
SFX_NONE, // No sound effects will be played.
|
||||
SFX_ALFX, // Westwood's ALFX adlib compatable driver.
|
||||
SFX_WWPCSPKR, // Westwood's PC-speaker driver.
|
||||
SFX_WWTANDY, // Westwood's PC-speaker driver with Tandy mod.
|
||||
SFX_PCSPKR, // PC speaker XMIDI driver.
|
||||
SFX_TANDY, // Tandy XMIDI driver.
|
||||
SFX_MT32, // MT-32 / LAPC-1 Roland XMIDI driver.
|
||||
SFX_CANVAS, // Sound Canvas SC-55.
|
||||
SFX_ADLIB, // Adlib XMIDI driver.
|
||||
SFX_ADLIBG, // Adlib Gold XMIDI driver.
|
||||
SFX_PASFM, // Pro Audio Spectrum XMIDI driver.
|
||||
SFX_SBFM, // Sound Blaster XMIDI driver.
|
||||
SFX_SBP1FM, // Sound Blaster Pro (YM3812) XMIDI driver.
|
||||
SFX_SBP2FM, // Sound Blaster Pro (OPL3) XMIDI driver.
|
||||
SFX_TEMP=0x1000,
|
||||
SFX_LAST
|
||||
} SFX_Type;
|
||||
|
||||
typedef enum RateEnum {
|
||||
PLAYBACK_RATE_SLOW =11025,
|
||||
PLAYBACK_RATE_NORMAL =(11025 * 2),
|
||||
PLAYBACK_RATE_FAST =(11025 * 4),
|
||||
} RateType;
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following prototypes are for the file: SOUNDIO.CPP */
|
||||
/*=========================================================================*/
|
||||
int File_Stream_Sample(char const *filename, BOOL real_time_start = FALSE);
|
||||
int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start = FALSE);
|
||||
void cdecl _saveregs Sound_Callback(void);
|
||||
void cdecl far __saveregs __loadds maintenance_callback(void);
|
||||
void *Load_Sample(char const *filename);
|
||||
long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size);
|
||||
long Sample_Read(int fh, void *buffer, long size);
|
||||
void Free_Sample(void const *sample);
|
||||
BOOL Sound_Init(int sfx, int score, int sample, RateType rate, int bits_per_sample, int max_samples, int reverse_channels);
|
||||
BOOL Audio_Init(int sample, int address, int inter, int dma, RateType rate, int bits_per_sample, int max_samples, int reverse_channels = FALSE);
|
||||
void Sound_End(void);
|
||||
void Stop_Sample(int handle);
|
||||
BOOL Sample_Status(int handle);
|
||||
BOOL Is_Sample_Playing(void const * sample);
|
||||
void Stop_Sample_Playing(void const * sample);
|
||||
int Play_Sample(void const *sample, int priority=0xFF, int volume=0xFF, signed short panloc = 0x0);
|
||||
int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id);
|
||||
int Set_Sound_Vol(int volume);
|
||||
int Set_Score_Vol(int volume);
|
||||
void Fade_Sample(int handle, int ticks);
|
||||
int Get_Free_Sample_Handle(int priority);
|
||||
int Get_Digi_Handle(void);
|
||||
long Sample_Length(void const *sample);
|
||||
|
||||
extern int Misc;
|
||||
extern SFX_Type SoundType;
|
||||
extern Sample_Type SampleType;
|
437
WWFLAT32/AUDIO/NEW/AUDUNCMP.ASM
Normal file
437
WWFLAT32/AUDIO/NEW/AUDUNCMP.ASM
Normal file
@@ -0,0 +1,437 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Audio Library *
|
||||
;* *
|
||||
;* File Name : AUDUNCMP.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil W. Gorrow *
|
||||
;* *
|
||||
;* Start Date : March 14, 1995 *
|
||||
;* *
|
||||
;* Last Update : June 26, 1995 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Decompress_Frame_Lock -- locks the JLB audio decompression code *
|
||||
;* Decompress_Frame_Unlock -- Unlocks the JLB audio compression code *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
CODESEG
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
CODE_2BIT EQU 0
|
||||
CODE_4BIT EQU 1
|
||||
CODE_RAW EQU 2
|
||||
CODE_SILENCE EQU 3
|
||||
MAGICNUMBER EQU 00000DEAFh
|
||||
MAGICNUMBER2 EQU 0BABEBABEh
|
||||
|
||||
_2bitdecode DB -2,-1,0,1
|
||||
_4bitdecode DB -9,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME -- Uncompresses a WW compressed audio frame *
|
||||
;* *
|
||||
;* INPUT: void * source - pointer to encoded audio data *
|
||||
;* void * dest - pointer to decompression area *
|
||||
;* long size - the maximum size of destination buffer *
|
||||
;* *
|
||||
;* OUTPUT: long - the number of bytes we uncompressed *
|
||||
;* *
|
||||
;* PROTO: long Decompress_Frame(void *, void *, long); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/14/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
GLOBAL Decompress_Frame:NEAR
|
||||
PROC Decompress_Frame C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG count:DWORD
|
||||
|
||||
LOCAL previous:BYTE
|
||||
LOCAL incount:DWORD
|
||||
|
||||
pushf
|
||||
cld
|
||||
mov [incount],0 ;Bytes read from source
|
||||
|
||||
|
||||
; Source, Dest and count must be valid.
|
||||
|
||||
cmp [source],0
|
||||
je ??fini
|
||||
|
||||
cmp [dest],0
|
||||
je ??fini
|
||||
|
||||
cmp [count],0
|
||||
je ??fini
|
||||
|
||||
mov esi,[source] ;Pointer to source data.
|
||||
mov edi,[dest] ;Pointer to destination data.
|
||||
mov ecx,[count] ;Number of bytes to fill dest buffer.
|
||||
mov dl,080h ;Previous sample (starting value).
|
||||
|
||||
??mainloop:
|
||||
cmp ecx,0 ;If dest full then exit
|
||||
jle ??fini
|
||||
|
||||
xor eax,eax
|
||||
mov al,[esi] ;Get code byte
|
||||
inc [incount]
|
||||
inc esi
|
||||
shl eax,2 ;AH contains code.
|
||||
shr al,2 ;AL contains sub-code data.
|
||||
|
||||
cmp ah,CODE_RAW ;Raw sequence?
|
||||
jne short ??try4bit
|
||||
|
||||
; The code contains either a 5 bit delta or a count of
|
||||
; raw samples to dump out.
|
||||
|
||||
test al,00100000b
|
||||
je short ??justraw
|
||||
|
||||
; The lower 5 bits are actually a signed delta.
|
||||
; Sign extend the delta and add it to the stream.
|
||||
|
||||
shl al,3
|
||||
sar al,3
|
||||
add dl,al
|
||||
mov [edi],dl
|
||||
dec ecx
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; The lower 5 bits hold a count of the number of raw
|
||||
; samples that follow this code. Dump these samples to
|
||||
; the output buffer.
|
||||
|
||||
??justraw:
|
||||
mov ebx,ecx
|
||||
xor ah,ah
|
||||
inc al
|
||||
mov ecx,eax
|
||||
shr ecx,1
|
||||
rep movsw
|
||||
adc ecx,ecx
|
||||
rep movsb
|
||||
mov ecx,ebx
|
||||
add [incount],eax
|
||||
sub ecx,eax
|
||||
dec edi
|
||||
mov dl,[edi] ;Set "previous" value.
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if this is a 4 bit delta code sequence.
|
||||
|
||||
??try4bit:
|
||||
inc al ;Following codes use AL+1
|
||||
cmp ah,CODE_4BIT
|
||||
jne short ??try2bit
|
||||
|
||||
; A sequence of 4bit deltas follow. AL equals the
|
||||
; number of nibble packed delta bytes to process.
|
||||
|
||||
??bit4loop:
|
||||
mov ah,[esi] ;Fetch nibble packed delta codes
|
||||
mov bl,ah
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
and ebx,00001111b
|
||||
add dl,[_4bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg1
|
||||
|
||||
popf
|
||||
jnc short ??ok1
|
||||
mov dl,0FFh
|
||||
jmp short ??ok1
|
||||
|
||||
??neg1:
|
||||
popf
|
||||
jc short ??ok1
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok1:
|
||||
mov dh,dl ;DH now holds new 'previous' sample.
|
||||
mov bl,ah
|
||||
shr bl,4
|
||||
add dh,[_4bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg2
|
||||
|
||||
popf
|
||||
jnc short ??ok2
|
||||
|
||||
mov dh,0FFh
|
||||
jmp short ??ok2
|
||||
|
||||
??neg2:
|
||||
popf
|
||||
jc short ??ok2
|
||||
|
||||
xor dh,dh
|
||||
|
||||
??ok2:
|
||||
mov [edi],dx ;Output the two sample bytes
|
||||
sub ecx,2
|
||||
add edi,2
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
mov dl,dh
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz short ??bit4loop
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if 2 bit deltas need to be processed.
|
||||
|
||||
??try2bit:
|
||||
cmp ah,CODE_2BIT
|
||||
jne ??zerodelta
|
||||
|
||||
; A sequence of 2bit deltas follow. AL equals the number of
|
||||
; packed delta bytes to process.
|
||||
|
||||
??bit2loop:
|
||||
mov ah,[esi] ;Fetch packed delat codes
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
mov bl,ah
|
||||
and ebx,000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg3
|
||||
|
||||
popf
|
||||
jnc short ??ok3
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok3
|
||||
|
||||
??neg3:
|
||||
popf
|
||||
jc short ??ok3
|
||||
xor dl,dl
|
||||
|
||||
??ok3:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,2
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg4
|
||||
|
||||
popf
|
||||
jnc short ??ok4
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok4
|
||||
|
||||
??neg4:
|
||||
popf
|
||||
jc short ??ok4
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok4:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,4
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg5
|
||||
|
||||
popf
|
||||
jnc short ??ok5
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok5
|
||||
|
||||
??neg5:
|
||||
popf
|
||||
jc short ??ok5
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok5:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,6
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushf
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg6
|
||||
|
||||
popf
|
||||
jnc short ??ok6
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok6
|
||||
|
||||
??neg6:
|
||||
popf
|
||||
jc short ??ok6
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok6:
|
||||
ror edx,8
|
||||
mov [edi],edx ;Output two sample bytes
|
||||
sub ecx,4
|
||||
add edi,4
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
rol edx,8
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz ??bit2loop
|
||||
jmp ??mainloop
|
||||
|
||||
; There is a run of zero deltas. Zero deltas merely duplicate
|
||||
; the 'previous' sample the requested number of times.
|
||||
|
||||
??zerodelta:
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
mov al,dl
|
||||
sub ecx,ebx
|
||||
xchg ecx,ebx
|
||||
rep stosb
|
||||
mov ecx,ebx
|
||||
jmp ??mainloop
|
||||
|
||||
??fini:
|
||||
popf
|
||||
mov eax,[incount]
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_LOCK -- locks the JLB audio decompression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is lock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL Decompress_Frame_Lock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL Decompress_Frame_Lock:NEAR
|
||||
PROC Decompress_Frame_Lock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame_Lock
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL Decompress_Frame_Unlock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL Decompress_Frame_Unlock:NEAR
|
||||
PROC Decompress_Frame_Unlock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
mov eax , 0601h
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame_Unlock
|
||||
|
||||
|
||||
|
||||
END
|
1448
WWFLAT32/AUDIO/NEW/DIFFTB.INC
Normal file
1448
WWFLAT32/AUDIO/NEW/DIFFTB.INC
Normal file
File diff suppressed because it is too large
Load Diff
47
WWFLAT32/AUDIO/NEW/FUNCTION.H
Normal file
47
WWFLAT32/AUDIO/NEW/FUNCTION.H
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following prototypes are for the file: SOUNDIO.CPP */
|
||||
/*=========================================================================*/
|
||||
|
||||
short Decompress_Frame(void * source, void * dest, short size);
|
||||
int cdecl Stream_Sample_Vol(void *buffer, long size, BOOL (*callback);
|
||||
int cdecl Stream_Sample(void *buffer, long size, BOOL (*callback);
|
||||
int cdecl File_Stream_Sample(char const *filename);
|
||||
int cdecl File_Stream_Sample_Vol(char const *filename, int volume);
|
||||
void cdecl _saveregs _loadds Sound_Callback(void);
|
||||
void cdecl far _saveregs _loadds maintenance_callback(void);
|
||||
void *cdecl Load_Sample(char const *filename);
|
||||
long cdecl Load_Sample_Into_Buffer(char const *filename, void *buffer, long size);
|
||||
long cdecl Sample_Read(int fh, void *buffer, long size);
|
||||
void cdecl Free_Sample(void const *sample);
|
||||
BOOL cdecl Sound_Init(int sfx, int score, int sample);
|
||||
void far VQA_TimerCallback(void);
|
||||
BOOL Audio_Init(int sample, int address, int inter, int dma);
|
||||
void cdecl Sound_End(void);
|
||||
void cdecl Stop_Sample(int handle);
|
||||
BOOL cdecl Sample_Status(int handle);
|
||||
BOOL cdecl Is_Sample_Playing(void const * sample);
|
||||
void cdecl Stop_Sample_Playing(void const * sample);
|
||||
int cdecl Play_Sample(void const *sample);
|
||||
int cdecl Play_Sample_Vol(void const *sample, int priority, int volume);
|
||||
int cdecl Set_Sound_Vol(int volume);
|
||||
int cdecl Set_Score_Vol(int volume);
|
||||
void cdecl Fade_Sample(int handle, int ticks);
|
1448
WWFLAT32/AUDIO/NEW/INDEXTB.INC
Normal file
1448
WWFLAT32/AUDIO/NEW/INDEXTB.INC
Normal file
File diff suppressed because it is too large
Load Diff
191
WWFLAT32/AUDIO/NEW/MAKEFILE
Normal file
191
WWFLAT32/AUDIO/NEW/MAKEFILE
Normal file
@@ -0,0 +1,191 @@
|
||||
#
|
||||
# Command & Conquer Red Alert(tm)
|
||||
# Copyright 2025 Electronic Arts Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#***************************************************************************
|
||||
#** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Project Name : Westwood Library .LIB makefile *
|
||||
#* *
|
||||
#* File Name : MAKEFILE *
|
||||
#* *
|
||||
#* Programmer : Julio R. Jerez *
|
||||
#* *
|
||||
#* Start Date : Jan 26, 1995 *
|
||||
#* *
|
||||
#* *
|
||||
#*-------------------------------------------------------------------------*
|
||||
#* *
|
||||
#* Required environment variables: *
|
||||
#* WWFLAT = your root WWFLAT path *
|
||||
#* WWVCS = root directory for wwlib version control archive *
|
||||
#* WATCOM = your Watcom installation path *
|
||||
#* *
|
||||
#* Required changes to makefile: *
|
||||
#* PROJ_NAME = name of the library you're building *
|
||||
#* OBJECTS = list of objects in your library *
|
||||
#* *
|
||||
#* Optional changes to makefile: *
|
||||
#* PROJ_DIR = full pathname of your working directory *
|
||||
#* .path.xxx = full pathname where various file types live *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Verify user's environment
|
||||
#---------------------------------------------------------------------------
|
||||
!ifndef %WWFLAT
|
||||
!error WWFLAT Environment var not configured.
|
||||
!endif
|
||||
|
||||
|
||||
!ifndef %WWVCS
|
||||
!error WWVCS Environment var not configured.
|
||||
!endif
|
||||
|
||||
!ifndef %WATCOM
|
||||
!error WATCOM Environment var not configured.
|
||||
!endif
|
||||
|
||||
|
||||
#===========================================================================
|
||||
# User-defined section: the user should tailor this section for each project
|
||||
#===========================================================================
|
||||
|
||||
PROJ_NAME = AUDIO
|
||||
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
|
||||
LIB_DIR = $(%WWFLAT)\lib
|
||||
|
||||
!include $(%WWFLAT)\project.cfg
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project-dependent variables
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
OBJECTS = &
|
||||
soundio.obj &
|
||||
soundint.obj &
|
||||
soundlck.obj &
|
||||
soscodec.obj &
|
||||
auduncmp.obj
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Path macros: one path for each file type.
|
||||
# These paths are used to tell make where to find/put each file type.
|
||||
#---------------------------------------------------------------------------
|
||||
.asm: $(PROJ_DIR)
|
||||
.c: $(PROJ_DIR)
|
||||
.cpp: $(PROJ_DIR)
|
||||
.h: $(PROJ_DIR)
|
||||
.obj: $(PROJ_DIR)
|
||||
.lib: $(%WWFLAT)\lib
|
||||
.exe: $(PROJ_DIR)
|
||||
|
||||
#===========================================================================
|
||||
# Pre-defined section: there should be little need to modify this section.
|
||||
#===========================================================================
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tools/commands
|
||||
#---------------------------------------------------------------------------
|
||||
C_CMD = wcc386
|
||||
CPP_CMD = wpp386
|
||||
LIB_CMD = wlib
|
||||
LINK_CMD = wlink
|
||||
ASM_CMD = tasm32
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Include & library paths
|
||||
# If LIB & INCLUDE are already defined, they are used in addition to the
|
||||
# WWLIB32 lib & include; otherwise, they're constructed from
|
||||
# BCDIR & TNTDIR
|
||||
#---------------------------------------------------------------------------
|
||||
LIBPATH = $(%WWFLAT)\LIB;$(%WATCOM)\LIB
|
||||
INCLUDEPATH = $(%WWFLAT)\INCLUDE;$(%WATCOM)\H
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Implicit rules
|
||||
# Compiler:
|
||||
# ($< = full dependent with path)
|
||||
# Assembler:
|
||||
# output obj's are constructed from .obj: & the $& macro
|
||||
# ($< = full dependent with path)
|
||||
# tasm's cfg file is not invoked as a response file.
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
.c.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
|
||||
$(C_CMD) $(CC_CFG) $<
|
||||
|
||||
.cpp.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
|
||||
$(CPP_CMD) $(CC_CFG) $<
|
||||
|
||||
.asm.obj: $(%WWFLAT)\project.cfg
|
||||
$(ASM_CMD) $(ASM_CFG) $<
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Default target: configuration files & library (in that order)
|
||||
#---------------------------------------------------------------------------
|
||||
all: $(LIB_DIR)\$(PROJ_NAME).lib .SYMBOLIC
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build the library
|
||||
# The original library is deleted by the librarian
|
||||
# Lib objects & -+ commands are constructed by substituting within the
|
||||
# $^@ macro (which expands to all target dependents, separated with
|
||||
# spaces)
|
||||
# Tlib's cfg file is not invoked as a response file.
|
||||
# All headers & source files are copied into WWFLAT\SRCDEBUG, for debugging
|
||||
#---------------------------------------------------------------------------
|
||||
$(LIB_DIR)\$(PROJ_NAME).lib: $(OBJECTS) objects.lbc
|
||||
copy *.lib $(%WWFLAT)\lib
|
||||
copy *.h $(%WWFLAT)\include
|
||||
copy *.inc $(%WWFLAT)\include
|
||||
copy *.cpp $(%WWFLAT)\srcdebug
|
||||
copy *.asm $(%WWFLAT)\srcdebug
|
||||
copy *.lib $(%WWFLAT)\lib
|
||||
$(LIB_CMD) $(LIB_CFG) $^@ @objects.lbc
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Objects now have a link file which is NOT generated everytime. Instead
|
||||
# it just has its own dependacy rule.
|
||||
#---------------------------------------------------------------------------
|
||||
objects.lbc : $(OBJECTS)
|
||||
%create $^@
|
||||
for %index in ($(OBJECTS)) do %append $^@ +%index
|
||||
|
||||
soundio.obj: .AUTODEPEND
|
||||
$(CPP_CMD) -zp4 -5s -mf -s -d2 /i=$(%WWFLAT)\include soundio.cpp
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Create the test directory and make it.
|
||||
#---------------------------------------------------------------------------
|
||||
test:
|
||||
mkdir test
|
||||
cd test
|
||||
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
|
||||
update
|
||||
wmake
|
||||
cd ..
|
||||
copy *.386 test
|
||||
|
||||
#**************************** End of makefile ******************************
|
||||
|
59
WWFLAT32/AUDIO/NEW/NYBBTB.INC
Normal file
59
WWFLAT32/AUDIO/NEW/NYBBTB.INC
Normal file
@@ -0,0 +1,59 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;* bNybbleTablexxxx - ADPCM Lookup table for nybbles
|
||||
;****************************************************************************
|
||||
|
||||
align 4
|
||||
|
||||
bNybbleTableLow DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
|
||||
align 4
|
||||
|
||||
bNybbleTableHigh DB 00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2
|
||||
DB 01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2
|
||||
DB 02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2
|
||||
DB 03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2
|
||||
DB 04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2
|
||||
DB 05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2
|
||||
DB 06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2
|
||||
DB 07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2
|
||||
DB 08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2
|
||||
DB 09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2
|
||||
DB 0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2
|
||||
DB 0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2
|
||||
DB 0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2
|
||||
DB 0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2
|
||||
DB 0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2
|
||||
DB 0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2
|
565
WWFLAT32/AUDIO/NEW/SOS.H
Normal file
565
WWFLAT32/AUDIO/NEW/SOS.H
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sos.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_DEFINED
|
||||
#define _SOS_DEFINED
|
||||
#include "sosdefs.h"
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
// error definition for sound operating system
|
||||
#define _SOS_ERR -1
|
||||
|
||||
// number of drivers allowed to be open at one time
|
||||
#define _SOS_MAX_DRIVERS 5
|
||||
|
||||
// structure definition for the capabilities
|
||||
typedef struct _tagCAPABILITIES
|
||||
{
|
||||
BYTE szDeviceName[ 32 ]; // device name
|
||||
WORD wDeviceVersion; // device version
|
||||
WORD wBitsPerSample; // bits per sound sample
|
||||
WORD wChannels; // stereo/mono sound card
|
||||
WORD wMinRate; // minimum rate
|
||||
WORD wMaxRate; // maximum rate
|
||||
WORD wMixerOnBoard; // board contains mixer
|
||||
WORD wMixerFlags; // mixer capabilities
|
||||
WORD wFlags; // miscellaneous flags
|
||||
short far * lpPortList; // list of usable ports
|
||||
short far * lpDMAList; // list of usable dma channels
|
||||
short far * lpIRQList; // list of usable irq channels
|
||||
short far * lpRateList; // list of usable rates, -1 if any in min to max
|
||||
WORD fBackground; // foreground or background driver
|
||||
WORD wDeviceID; // ID for the device
|
||||
WORD wTimerID; // ID for the timer
|
||||
|
||||
} _SOS_CAPABILITIES;
|
||||
|
||||
// far pointer to the device capabilities structure
|
||||
typedef _SOS_CAPABILITIES far * LPSOSDEVICECAPS;
|
||||
|
||||
// flag types for driver
|
||||
#define _FLAGS_SIGNED 0x8000
|
||||
|
||||
// devices that can be loaded
|
||||
#define _SOUND_BLASTER_8_MONO 0xe000
|
||||
#define _SOUND_BLASTER_8_ST 0xe001
|
||||
#define _SBPRO_8_ST _SOUND_BLASTER_8_ST
|
||||
#define _SBPRO_8_MONO 0xe00f
|
||||
#define _SOUND_MASTER_II_8_MONO 0xe002
|
||||
#define _MV_PAS_8_MONO 0xe003
|
||||
#define _MV_PAS_16_MONO 0xe004
|
||||
#define _MV_PAS_8_ST 0xe005
|
||||
#define _MV_PAS_16_ST 0xe006
|
||||
#define _ADLIB_GOLD_8_ST 0xe007
|
||||
#define _ADLIB_GOLD_16_ST 0xe008
|
||||
#define _ADLIB_GOLD_8_MONO 0xe009
|
||||
#define _ADLIB_GOLD_16_MONO 0xe00a
|
||||
#define _MICROSOFT_8_MONO 0xe00b
|
||||
#define _MICROSOFT_8_ST 0xe00c
|
||||
#define _MICROSOFT_16_MONO 0xe00d
|
||||
#define _MICROSOFT_16_ST 0xe00e
|
||||
#define _SOUND_SOURCE_8_MONO_PC 0xe010
|
||||
#define _SOUND_SOURCE_8_MONO_TANDY 0xe011
|
||||
#define _GENERAL_PORT_8_MONO 0xe012
|
||||
#define _GENERAL_PORT_8_MONO_R 0xe013
|
||||
#define _SIERRA_8_MONO 0xe014
|
||||
#define _SB16_8_MONO 0xe015
|
||||
#define _SB16_8_ST 0xe016
|
||||
#define _SB16_16_MONO 0xe017
|
||||
#define _SB16_16_ST 0xe018
|
||||
#define _ESS_AUDIODRIVE_8_MONO 0xe019
|
||||
#define _ESS_AUDIODRIVE_8_ST 0xe01a
|
||||
#define _ESS_AUDIODRIVE_16_MONO 0xe01b
|
||||
#define _ESS_AUDIODRIVE_16_ST 0xe01c
|
||||
#define _SOUNDSCAPE_8_MONO 0xe01d
|
||||
#define _SOUNDSCAPE_8_ST 0xe01e
|
||||
#define _SOUNDSCAPE_16_MONO 0xe01f
|
||||
#define _SOUNDSCAPE_16_ST 0xe020
|
||||
#define _RAP10_8_MONO 0xe021
|
||||
#define _RAP10_16_MONO 0xe022
|
||||
#define _GUS_8_MONO 0xe023
|
||||
#define _GUS_8_ST 0xe024
|
||||
#define _GUS_16_MONO 0xe025
|
||||
#define _GUS_16_ST 0xe026
|
||||
#define _GUS_MAX_8_MONO 0xe027
|
||||
#define _GUS_MAX_8_ST 0xe028
|
||||
#define _GUS_MAX_16_MONO 0xe029
|
||||
#define _GUS_MAX_16_ST 0xe02a
|
||||
#define _WAVEJAMMER_8_MONO 0xe02b
|
||||
#define _WAVEJAMMER_8_ST 0xe02c
|
||||
#define _WAVEJAMMER_16_MONO 0xe02d
|
||||
#define _WAVEJAMMER_16_ST 0xe02e
|
||||
#define _TEMPOCS_8_MONO 0xe02f
|
||||
#define _TEMPOCS_8_ST 0xe030
|
||||
#define _TEMPOCS_16_MONO 0xe031
|
||||
#define _TEMPOCS_16_ST 0xe032
|
||||
#define _WAVEJAMMERCD_8_MONO 0xe033
|
||||
#define _WAVEJAMMERCD_8_ST 0xe034
|
||||
#define _WAVEJAMMERCD_16_MONO 0xe035
|
||||
#define _WAVEJAMMERCD_16_ST 0xe036
|
||||
#define _SOUND_BLASTER_8_MONO_R 0xe050
|
||||
#define _MICROSOFT_8_MONO_R 0xe051
|
||||
#define _SOUND_MASTER_II_8_MONO_R 0xe052
|
||||
#define _ADLIB_GOLD_8_MONO_R 0xe053
|
||||
#define _MV_PAS_8_MONO_R 0xe054
|
||||
#define _RAP10_8_MONO_R 0xe058
|
||||
#define _RAP10_16_MONO_R 0xe059
|
||||
#define _SB16_8_MONO_R 0xe05a
|
||||
#define _SB16_8_ST_R 0xe05b
|
||||
#define _SB16_16_MONO_R 0xe05c
|
||||
#define _SB16_16_ST_R 0xe05d
|
||||
#define _MV_PAS_16_MONO_R 0xe060
|
||||
#define _SOUNDSCAPE_8_MONO_R 0xe061
|
||||
#define _SOUNDSCAPE_8_ST_R 0xe062
|
||||
#define _SOUNDSCAPE_16_MONO_R 0xe063
|
||||
#define _SOUNDSCAPE_16_ST_R 0xe064
|
||||
#define _ESS_AUDIODRIVE_8_MONO_R 0xe065
|
||||
#define _ESS_AUDIODRIVE_8_ST_R 0xe066
|
||||
#define _ESS_AUDIODRIVE_16_MONO_R 0xe067
|
||||
#define _ESS_AUDIODRIVE_16_ST_R 0xe068
|
||||
#define _SPEECH_THING_8_MONO 0xe090
|
||||
#define _YAMAHA_8_MONO 0xe106
|
||||
#define _INT_SPEAKER_8_MONO 0xe107
|
||||
|
||||
// call indexes for the loadable drivers
|
||||
enum
|
||||
{
|
||||
_DRV_INIT,
|
||||
_DRV_UNINIT,
|
||||
_DRV_SETRATE,
|
||||
_DRV_SETACTION,
|
||||
_DRV_START,
|
||||
_DRV_STOP,
|
||||
_DRV_PAUSE,
|
||||
_DRV_RESUME,
|
||||
_DRV_CAPABILITIES,
|
||||
_DRV_PLAY_FOREGROUND,
|
||||
_DRV_GET_FILL_INFO,
|
||||
_DRV_GET_CALL_FUNCTIONS,
|
||||
_DRV_SET_CALL_FUNCTIONS
|
||||
};
|
||||
|
||||
// fill info
|
||||
typedef struct _tagFillInfo
|
||||
{
|
||||
|
||||
LPSTR lpFillHandler; // pointer to fill handler
|
||||
LPWORD lpDMAFillCount; // pointer to dma count
|
||||
LPSTR lpSampleList; // pointer to sample list
|
||||
LPWORD lpDMAMasterVolume; // pointer to dma count
|
||||
|
||||
} _SOS_FILL_INFO;
|
||||
|
||||
// caps info structure
|
||||
typedef struct _tagCapsInfo
|
||||
{
|
||||
|
||||
LPSTR lpPortList; // pointer to port list
|
||||
LPSTR lpDMAList; // pointer to DMA list
|
||||
LPSTR lpIRQList; // pointer to IRQ list
|
||||
LPSTR lpRateList; // pointer to rate list
|
||||
|
||||
} _SOS_CAPS_INFO;
|
||||
|
||||
// maximum number of available voice
|
||||
#define _MAX_VOICES 32
|
||||
|
||||
// structure definition
|
||||
typedef struct _tagSAMPLE
|
||||
{
|
||||
LPSTR samplePtr; // pointer to data buffer
|
||||
LPSTR sampleData; // pointer to active data
|
||||
LPSTR sampleLoopPtr; // pointer for loop back
|
||||
|
||||
WORD sampleLength; // length of sample
|
||||
WORD sampleIndex; // index into sample
|
||||
WORD sampleLoopLength; // length of loop
|
||||
|
||||
WORD sampleBytesLeft; // bytes left to play in sample
|
||||
|
||||
WORD sampleLoopPoint; // byte count for loop point
|
||||
WORD sampleLoopEndLength; // length of remaining chunk
|
||||
|
||||
short sampleFlags; // control sample
|
||||
short sampleVolume; // volume control
|
||||
short sampleID; // sample ID
|
||||
|
||||
short sampleChannel; // channel to play sample on
|
||||
short sampleLoopCount; // loop count
|
||||
short sampleLastFill; // last fill position
|
||||
VOID ( far cdecl * sampleCallback )( WORD, WORD, WORD ); // callback function for sample
|
||||
|
||||
WORD samplePitchAdd;
|
||||
short samplePitchFraction;
|
||||
|
||||
short samplePort; // port to use for non-dma digitized
|
||||
|
||||
WORD sampleTotalBytes;
|
||||
WORD sampleByteLength;
|
||||
|
||||
short samplePanLocation;
|
||||
short samplePanSpeed;
|
||||
short samplePanDirection;
|
||||
short samplePanStart;
|
||||
short samplePanEnd;
|
||||
|
||||
short sampleDelayBytes;
|
||||
short sampleDelayRepeat;
|
||||
|
||||
WORD sampleADPCMPredicted;
|
||||
short sampleADPCMIndex;
|
||||
|
||||
short sampleRootNoteMIDI;
|
||||
|
||||
WORD sampleTemp1;
|
||||
|
||||
} _SOS_SAMPLE;
|
||||
|
||||
// enumeration for left or right channel
|
||||
enum
|
||||
{
|
||||
_LEFT_CHANNEL,
|
||||
_RIGHT_CHANNEL,
|
||||
_CENTER_CHANNEL,
|
||||
_INTERLEAVED
|
||||
};
|
||||
|
||||
// enumeration for foreground and background
|
||||
enum
|
||||
{
|
||||
_FOREGROUND,
|
||||
_BACKGROUND
|
||||
};
|
||||
|
||||
// defines for the sample flags
|
||||
#define _ACTIVE 0x8000
|
||||
#define _LOOPING 0x4000
|
||||
#define _FIRST_TIME 0x2000
|
||||
#define _PENDING_RELEASE 0x1000
|
||||
#define _CONTINUE_BLOCK 0x0800
|
||||
#define _PITCH_SHIFT 0x0400
|
||||
#define _PANNING 0x0200
|
||||
#define _VOLUME 0x0100
|
||||
#define _TRANSLATE16TO8 0x0080
|
||||
#define _STAGE_LOOP 0x0040
|
||||
#define _TRANSLATE8TO16 0x0020
|
||||
#define _STEREOTOMONO 0x0010
|
||||
|
||||
// defines for the wParam flags
|
||||
#define _SINGLE_SAMPLE 0x01
|
||||
|
||||
#define _SOS_DCAPS_AUTO_REINIT 0x01
|
||||
#define _SOS_DCAPS_MPU_401 0x02
|
||||
#define _SOS_DCAPS_OPL2 0x04
|
||||
#define _SOS_DCAPS_OPL3 0x08
|
||||
#define _SOS_DCAPS_OPL4 0x10
|
||||
#define _SOS_DCAPS_WAVETABLE 0x20
|
||||
#define _SOS_DCAPS_DL_SAMPLES 0x40
|
||||
#define _SOS_DCAPS_FIFO_DEVICE 0x80
|
||||
#define _SOS_DCAPS_ENV_NEEDED 0x100
|
||||
#define _SOS_DCAPS_PSEUDO_DMA1 0x200
|
||||
#define _SOS_DCAPS_SIGNED_DATA 0x8000
|
||||
|
||||
// file header structure
|
||||
typedef struct
|
||||
{
|
||||
// name ID
|
||||
BYTE szName[ 32 ];
|
||||
|
||||
// number of drivers in the file
|
||||
WORD wDrivers;
|
||||
|
||||
// offset of first driver
|
||||
WORD lOffset;
|
||||
|
||||
// size of the file
|
||||
WORD lFileSize;
|
||||
|
||||
} _FILEHEADER;
|
||||
|
||||
// driver header structure
|
||||
typedef struct
|
||||
{
|
||||
// name ID
|
||||
BYTE szName[ 32 ];
|
||||
|
||||
// offset of next driver
|
||||
WORD lNextDriver;
|
||||
|
||||
// size of current driver
|
||||
WORD wSize;
|
||||
|
||||
// id for the current device
|
||||
WORD wDeviceID;
|
||||
|
||||
// id for the type of DOS extender
|
||||
WORD wExtenderType;
|
||||
|
||||
} _DRIVERHEADER;
|
||||
|
||||
// device hardware information
|
||||
typedef struct
|
||||
{
|
||||
// port to be used
|
||||
WORD wPort;
|
||||
|
||||
// irq to use
|
||||
WORD wIRQ;
|
||||
|
||||
// dma channel to se
|
||||
WORD wDMA;
|
||||
|
||||
// extra parameter
|
||||
WORD wParam;
|
||||
|
||||
} _SOS_HARDWARE;
|
||||
|
||||
// structure definition for start sample
|
||||
typedef struct
|
||||
{
|
||||
// pointer to sample
|
||||
LPSTR lpSamplePtr;
|
||||
|
||||
// size of the sample
|
||||
WORD dwSampleSize;
|
||||
|
||||
// number of times to loop the sample -1 is infinite
|
||||
WORD wLoopCount;
|
||||
|
||||
// channel to play sample on
|
||||
WORD wChannel;
|
||||
|
||||
// volume to play sample at
|
||||
WORD wVolume;
|
||||
|
||||
// id for the sample
|
||||
WORD wSampleID;
|
||||
|
||||
// far pointer to the callback function
|
||||
VOID ( far cdecl *lpCallback )( WORD, WORD, WORD );
|
||||
|
||||
// port to use if driver is a non-dma background driver
|
||||
WORD wSamplePort;
|
||||
|
||||
// flags field
|
||||
WORD wSampleFlags;
|
||||
|
||||
// total length of sample including loops, etc..
|
||||
WORD dwSampleByteLength;
|
||||
|
||||
// loop point for the sample
|
||||
WORD dwSampleLoopPoint;
|
||||
WORD dwSampleLoopLength;
|
||||
|
||||
// pitch shifting components
|
||||
WORD dwSamplePitchAdd;
|
||||
WORD wSamplePitchFraction;
|
||||
|
||||
// pan components
|
||||
WORD wSamplePanLocation;
|
||||
WORD wSamplePanSpeed;
|
||||
WORD wSamplePanDirection;
|
||||
WORD wSamplePanStart;
|
||||
WORD wSamplePanEnd;
|
||||
|
||||
// delay parts
|
||||
WORD wSampleDelayBytes;
|
||||
WORD wSampleDelayRepeat;
|
||||
|
||||
// compression components
|
||||
WORD dwSampleADPCMPredicted;
|
||||
WORD wSampleADPCMIndex;
|
||||
|
||||
// root note for pitch shifting
|
||||
WORD wSampleRootNoteMIDI;
|
||||
|
||||
// filler for future upgrades
|
||||
WORD dwSampleTemp1;
|
||||
WORD dwSampleTemp2;
|
||||
WORD dwSampleTemp3;
|
||||
|
||||
} _SOS_START_SAMPLE;
|
||||
|
||||
// structure for initializing a driver
|
||||
typedef struct
|
||||
{
|
||||
WORD wBufferSize;
|
||||
LPSTR lpBuffer;
|
||||
BOOL wAllocateBuffer;
|
||||
WORD wSampleRate;
|
||||
WORD wParam;
|
||||
LONG dwParam;
|
||||
VOID ( far *lpFillHandler )( VOID );
|
||||
LPSTR lpDriverMemory;
|
||||
LPSTR lpDriverMemoryCS;
|
||||
LPSTR lpTimerMemory;
|
||||
LPSTR lpTimerMemoryCS;
|
||||
WORD wTimerID;
|
||||
WORD wPhysical;
|
||||
|
||||
} _SOS_INIT_DRIVER;
|
||||
|
||||
// define for the timer types to use
|
||||
#define _SOS_NORMAL_TIMER 0x00
|
||||
|
||||
// enumeration for the timer types
|
||||
enum
|
||||
{
|
||||
_TIMER_8_MONO = 0x1000,
|
||||
_TIMER_8_ST,
|
||||
_TIMER_16_MONO,
|
||||
_TIMER_16_ST,
|
||||
_TIMER_8_MONO_ULAW,
|
||||
_TIMER_8_ST_ULAW,
|
||||
_TIMER_16_MONO_ULAW,
|
||||
_TIMER_16_ST_ULAW,
|
||||
_TIMER_8_MONO_REC,
|
||||
_TIMER_8_MONO_ULAW_REC,
|
||||
_TIMER_UNDEFINED_1,
|
||||
_TIMER_UNDEFINED_2,
|
||||
_TIMER_UNDEFINED_3,
|
||||
_TIMER_UNDEFINED_4,
|
||||
_TIMER_UNDEFINED_5,
|
||||
_TIMER_UNDEFINED_6,
|
||||
_TIMER_UNDEFINED_7,
|
||||
_TIMER_UNDEFINED_8,
|
||||
_TIMER_UNDEFINED_9,
|
||||
_TIMER_UNDEFINED_A,
|
||||
_TIMER_UNDEFINED_B,
|
||||
_TIMER_UNDEFINED_C,
|
||||
_TIMER_UNDEFINED_D,
|
||||
_TIMER_UNDEFINED_E,
|
||||
_TIMER_UNDEFINED_F,
|
||||
_TIMER_UNDEFINED_10,
|
||||
_TIMER_UNDEFINED_11,
|
||||
_TIMER_UNDEFINED_12,
|
||||
_TIMER_UNDEFINED_13,
|
||||
_TIMER_UNDEFINED_14,
|
||||
_TIMER_UNDEFINED_15,
|
||||
_TIMER_UNDEFINED_16,
|
||||
_TIMER_8_SOUND_SOURCE,
|
||||
_TIMER_8_SOUND_SOURCE_TANDY,
|
||||
_TIMER_8_GENERAL_PORT,
|
||||
_TIMER_8_GENERAL_PORT_REC
|
||||
};
|
||||
|
||||
// define for no slots available
|
||||
#define _ERR_NO_SLOTS ( WORD )-1
|
||||
|
||||
// error codes for the system
|
||||
enum
|
||||
{
|
||||
_ERR_NO_ERROR,
|
||||
_ERR_DRIVER_NOT_LOADED,
|
||||
_ERR_INVALID_POINTER,
|
||||
_ERR_DETECT_INITIALIZED,
|
||||
_ERR_FAIL_ON_FILE_OPEN,
|
||||
_ERR_MEMORY_FAIL,
|
||||
_ERR_INVALID_DRIVER_ID,
|
||||
_ERR_NO_DRIVER_FOUND,
|
||||
_ERR_DETECTION_FAILURE,
|
||||
_ERR_DRIVER_LOADED,
|
||||
_ERR_INVALID_HANDLE,
|
||||
_ERR_NO_HANDLES,
|
||||
_ERR_PAUSED,
|
||||
_ERR_NOT_PAUSED,
|
||||
_ERR_INVALID_DATA,
|
||||
_ERR_DRV_FILE_FAIL,
|
||||
_ERR_INVALID_PORT,
|
||||
_ERR_INVALID_IRQ,
|
||||
_ERR_INVALID_DMA,
|
||||
_ERR_INVALID_DMA_IRQ
|
||||
};
|
||||
|
||||
// maximum number of timer events that can be registered
|
||||
#define _TIMER_MAX_EVENTS 0x10
|
||||
|
||||
// flags for the debugging system
|
||||
#define _SOS_DEBUG_NORMAL 0x0000
|
||||
#define _SOS_DEBUG_NO_TIMER 0x0001
|
||||
#define _SOS_TIMER_DPMI 0x0002
|
||||
|
||||
// define for types of DOS extenders
|
||||
#define _SOS_RATIONAL 0x8000
|
||||
#define _SOS_FLASHTECK 0x4000
|
||||
|
||||
// defines for the types of timers for different
|
||||
// dos extenders
|
||||
#define _SOS_TIMER_NEAR 0x8000
|
||||
#define _SOS_TIMER_FAR 0x4000
|
||||
|
||||
// values for callback information
|
||||
enum
|
||||
{
|
||||
_SAMPLE_PROCESSED,
|
||||
_SAMPLE_LOOPING,
|
||||
_SAMPLE_DONE
|
||||
};
|
||||
|
||||
// define for special 18.2 callback rate to dos
|
||||
#define _TIMER_DOS_RATE 0xff00
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#pragma aux int_3 = "int 3"
|
||||
|
||||
#pragma pack( 1 )
|
||||
typedef struct
|
||||
{
|
||||
unsigned region_size;
|
||||
unsigned offset;
|
||||
unsigned segment;
|
||||
unsigned short number_available;
|
||||
unsigned short number_used;
|
||||
unsigned page0;
|
||||
|
||||
} EVDS_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned region_size;
|
||||
unsigned offset;
|
||||
unsigned short segment;
|
||||
unsigned short ID;
|
||||
unsigned physical;
|
||||
|
||||
} VDS_STRUCT;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#include "sosdata.h"
|
||||
#include "sosfnct.h"
|
||||
|
||||
#endif
|
871
WWFLAT32/AUDIO/NEW/SOSCODEC.ASM
Normal file
871
WWFLAT32/AUDIO/NEW/SOSCODEC.ASM
Normal file
@@ -0,0 +1,871 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* Copyright (c) 1994, HMI, INC. All Rights Reserved
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* FILE
|
||||
;* soscodec.asm
|
||||
;*
|
||||
;* DESCRIPTION
|
||||
;* HMI SOS ADPCM compression/decompression.
|
||||
;*
|
||||
;* PROGRAMMER
|
||||
;* Nick Skrepetos
|
||||
;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom)
|
||||
;* Bill Petro (Added stereo support)
|
||||
;* DATE
|
||||
;* Febuary 15, 1995
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* PUBLIC
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI.
|
||||
IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI.
|
||||
|
||||
STRUC sCompInfo
|
||||
lpSource DD ? ;Compressed data pointer
|
||||
lpDest DD ? ;Uncompressed data pointer
|
||||
dwCompSize DD ? ;Compressed size
|
||||
dwUnCompSize DD ? ;Uncompressed size
|
||||
|
||||
dwSampleIndex DD ? ;Index into sample
|
||||
dwPredicted DD ? ;Next predicted value
|
||||
dwDifference DD ? ;Difference from last sample
|
||||
wCodeBuf DW ? ;Holds 2 nibbles for decompression
|
||||
wCode DW ? ;Current 4 bit code
|
||||
wStep DW ? ;Step value in table
|
||||
wIndex DW ? ;Index into step table
|
||||
|
||||
dwSampleIndex2 DD ? ;Index into sample
|
||||
dwPredicted2 DD ? ;Next predicted value
|
||||
dwDifference2 DD ? ;Difference from last sample
|
||||
wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
|
||||
wCode2 DW ? ;Current 4 bit code
|
||||
wStep2 DW ? ;Step value in table
|
||||
wIndex2 DW ? ;Index into step table
|
||||
|
||||
wBitSize DW ? ;Bit size for decompression
|
||||
wChannels DW ? ;number of channels
|
||||
ENDS sCompInfo
|
||||
|
||||
|
||||
DATASEG
|
||||
|
||||
|
||||
InitFlags DD 0 ; Flags to indicate what has been initialized.
|
||||
|
||||
|
||||
LABEL LockedDataStart BYTE
|
||||
|
||||
;* Index table for stepping into step table
|
||||
|
||||
wCODECIndexTab DD -1,-1,-1,-1,2,4,6,8
|
||||
DD -1,-1,-1,-1,2,4,6,8
|
||||
|
||||
|
||||
;Lookup table of replacement values
|
||||
;The actual sound value is replaced with an index to lookup in this table
|
||||
;The index only takes up a nibble(4bits) and represents an int(16bits)
|
||||
;Essentially:
|
||||
;Get a value
|
||||
;compare it with the value before it
|
||||
;find closest value in table and store the index into the table
|
||||
;if i'm going down then negitize it
|
||||
;go to next byte.
|
||||
|
||||
;Theory for stereo:
|
||||
;1)handle stereo and mono in two seperate loops. cleaner...
|
||||
;start at byte 0 and skip every other byte(or word) both write and read
|
||||
;when we get done
|
||||
; set start byte to 1 and do it again
|
||||
|
||||
|
||||
|
||||
|
||||
;This table essentialy round off to closes values in 3 distinct bands
|
||||
; precalculated and optimized(i guess) for human hearing.
|
||||
|
||||
wCODECStepTab DD 7, 8, 9, 10, 11, 12, 13,14
|
||||
DD 16, 17, 19, 21, 23, 25, 28, 31
|
||||
DD 34, 37, 41, 45, 50, 55, 60, 66
|
||||
DD 73, 80, 88, 97, 107, 118, 130, 143
|
||||
DD 157, 173, 190, 209, 230, 253, 279, 307
|
||||
DD 337, 371, 408, 449, 494, 544, 598, 658
|
||||
DD 724, 796, 876, 963, 1060, 1166, 1282, 1411
|
||||
DD 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024
|
||||
DD 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484
|
||||
DD 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899
|
||||
DD 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794
|
||||
DD 32767
|
||||
|
||||
wCode DD 0 ; this is to hold index into wCodeStep
|
||||
dwCODECByteIndex DD 0 ; this is when to stop compressing
|
||||
dwCODECBytesProcessed DD 0 ; this is how many so far compressed
|
||||
dwCODECTempStep DD 0 ; tempory storage for step value
|
||||
wCODECMask DW 0 ; Current mask
|
||||
|
||||
LABEL LockedDataEnd BYTE
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECInitStream - Initialize compression stream.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* sosCODECInitStream(CompInfo)
|
||||
;*
|
||||
;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Initialize compression stream for compression and decompression.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compression information structure.
|
||||
;*
|
||||
;* RESULT
|
||||
;* NONE
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL sosCODECInitStream:NEAR
|
||||
PROC sosCODECInitStream C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
|
||||
mov eax,[sSOSInfo]
|
||||
mov [(sCompInfo eax).wIndex],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo eax).wIndex2],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep2],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex2],0 ;start at head of index
|
||||
ret
|
||||
|
||||
ENDP sosCODECInitStream
|
||||
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECDecompressData - Decompress audio data.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* Size = sosCODECDecompressData(CompInfo, NumBytes)
|
||||
;*
|
||||
;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Decompress data from a 4:1 ADPCM compressed stream. The number of
|
||||
;* bytes decompressed is returned.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compress information structure.
|
||||
;* NumBytes - Number of bytes to compress.
|
||||
;*
|
||||
;* RESULT
|
||||
;* Size - Size of decompressed data.
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL sosCODECDecompressData:NEAR
|
||||
PROC sosCODECDecompressData C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
ARG wBytes:DWORD
|
||||
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
;*---------------------------------------------------------------------------
|
||||
;* Initialize
|
||||
;*---------------------------------------------------------------------------
|
||||
|
||||
mov ebx,[sSOSInfo]
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
|
||||
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??skipByteDivide
|
||||
|
||||
shr eax,1 ;Divide size by two
|
||||
|
||||
??skipByteDivide:
|
||||
mov [dwCODECByteIndex],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
|
||||
cmp [(sCompInfo ebx).wChannels],2 ;stereo check
|
||||
je ??mainloopl ;do left side first
|
||||
|
||||
; Determine if sample index is even or odd. This will determine
|
||||
; if we need to get a new token or not.
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;Main Mono Loop
|
||||
;---------------------------------------------------------------------------
|
||||
push ebp
|
||||
movzx edx,[(sCompInfo ebx).wIndex] ;preload index
|
||||
mov ebp, [dwCODECByteIndex]
|
||||
mov ecx,[(sCompInfo ebx).dwSampleIndex] ;preload SampleIndex
|
||||
|
||||
??mainloop:
|
||||
xor eax,eax ;get a new token
|
||||
test ecx,1 ;odd Sample??
|
||||
je short ??fetchToken ; if so get new token
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
|
||||
shr eax,4
|
||||
jmp short ??calcDifference
|
||||
align 4
|
||||
|
||||
??fetchToken:
|
||||
mov al,[esi] ;put in codebuf
|
||||
inc esi
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
|
||||
|
||||
??calcDifference:
|
||||
xor ecx,ecx
|
||||
and eax,000Fh
|
||||
mov cx,[(sCompInfo ebx).wStep] ;cx is step value
|
||||
mov [wCode],eax
|
||||
jmp [DWORD PTR JumpTable + eax*4]
|
||||
align 4
|
||||
|
||||
; note: it is important for speed reasons to keep the order the
|
||||
; following jumps entries as well as the "align 4" after some of
|
||||
; the jmp statements
|
||||
|
||||
??7:
|
||||
; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
|
||||
; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
|
||||
lea ecx,[ecx+ecx*2]
|
||||
lea eax,[ecx+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??6:
|
||||
; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
|
||||
; = ( x * 8 + x * 5 ) >> 8
|
||||
lea eax,[ecx+ecx*4]
|
||||
lea eax,[eax+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??5:
|
||||
; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
|
||||
; = ( 8 * x + 3 * x) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??4:
|
||||
; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
|
||||
lea eax,[ecx+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??3:
|
||||
; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
|
||||
; = ( 4x + 3x ) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??2:
|
||||
; eax = x/2 + x/8 = (4*x + x) >> 3
|
||||
lea eax,[ecx+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??1:
|
||||
; eax = x/4 + x/8 = (2x + x )>>8
|
||||
lea eax,[ecx+ecx*2]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??0:
|
||||
; eax = x/8 = x >> 3
|
||||
mov eax,ecx
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??15:
|
||||
; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
|
||||
; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
|
||||
lea ecx,[ecx+ecx*2]
|
||||
lea eax,[ecx+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??14:
|
||||
; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
|
||||
; = ( x * 8 + x * 5 ) >> 8
|
||||
lea eax,[ecx+ecx*4]
|
||||
lea eax,[eax+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??13:
|
||||
; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
|
||||
; = ( 8 * x + 3 * x) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??12:
|
||||
; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
|
||||
lea eax,[ecx+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??11:
|
||||
; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
|
||||
; = ( 4*x - 3*x ) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??10:
|
||||
; eax = x/2 + x/8 = (4*x + x) >> 3
|
||||
lea eax,[ecx+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??9:
|
||||
; eax = x/4 + x/8 = (2x + x )>>8
|
||||
lea eax,[ecx+ecx*2]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??8:
|
||||
; eax = x/8 = x >> 3
|
||||
mov eax,ecx ; !!important!! no need for align here
|
||||
|
||||
??neg_save_dif:
|
||||
sar eax,3 ; now we divide x>>3
|
||||
neg eax
|
||||
|
||||
??save_dif:
|
||||
mov ecx,[wCode] ; load offset into CODETab table
|
||||
mov [(sCompInfo ebx).dwDifference],eax ;Store wStep
|
||||
|
||||
; add difference to predicted value.
|
||||
add eax,[(sCompInfo ebx).dwPredicted]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflow
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflow:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflow
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflow:
|
||||
add edx,[wCODECIndexTab + ecx*4] ; won't hurt 486
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
mov ecx,[(sCompInfo ebx).dwSampleIndex] ;load dwSampleindex
|
||||
je short ??output16Bit
|
||||
; output 8 bit sample
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
inc edi
|
||||
jmp short ??adjustIndex
|
||||
align 4
|
||||
|
||||
??output16Bit:
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,2
|
||||
|
||||
??adjustIndex:
|
||||
cmp edx,8000h
|
||||
jb short ??checkOverflow
|
||||
mov edx,0 ;reset index to zero
|
||||
|
||||
??checkOverflow:
|
||||
inc ecx ; advance index and store step value
|
||||
cmp edx,88 ;check if wIndex > 88
|
||||
jbe short ??adjustStep
|
||||
mov edx,88 ;reset index to 88
|
||||
|
||||
??adjustStep:
|
||||
; advance index and store step value
|
||||
mov [(sCompInfo ebx).dwSampleIndex],ecx
|
||||
|
||||
; fetch wIndex so we can fetch new step value
|
||||
mov eax,[wCODECStepTab + edx*4]
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
dec ebp
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
jne ??mainloop
|
||||
pop ebp
|
||||
|
||||
mov eax,[wCode] ; these three lines do not
|
||||
mov [(sCompInfo ebx).wCode],ax ; seem to have any relevance
|
||||
|
||||
mov [(sCompInfo ebx).wIndex],dx ; save index
|
||||
jmp ??exitout
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Left Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopl:
|
||||
test [(sCompInfo ebx).dwSampleIndex],1
|
||||
je short ??fetchTokenl
|
||||
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
jmp short ??calcDifferencel
|
||||
|
||||
??fetchTokenl:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
|
||||
??calcDifferencel:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4l
|
||||
add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
|
||||
|
||||
??no4l:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2l
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no2l:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1l
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no1l:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8l
|
||||
neg [(sCompInfo ebx).dwDifference] ;Negate diff
|
||||
|
||||
??no8l:
|
||||
; add difference to predicted value.
|
||||
|
||||
mov eax,[(sCompInfo ebx).dwPredicted]
|
||||
add eax,[(sCompInfo ebx).dwDifference]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowl
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowl:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowl
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowl:
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitl
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo
|
||||
jmp short ??adjustIndexl
|
||||
|
||||
??output8Bitl:
|
||||
; output 8 bit sample
|
||||
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexl:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex],8000h
|
||||
jb short ??checkOverflowl
|
||||
mov [(sCompInfo ebx).wIndex],0
|
||||
jmp short ??adjustStepl ;reset index to zero
|
||||
|
||||
|
||||
??checkOverflowl:
|
||||
|
||||
cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
|
||||
jbe short ??adjustStepl
|
||||
mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
|
||||
|
||||
??adjustStepl:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex],1
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopl
|
||||
;----------------------------------------------------------------------------
|
||||
; Right Side Setup
|
||||
;----------------------------------------------------------------------------
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
inc esi ; skip left channel
|
||||
inc edi ; skip left channel
|
||||
cmp [(sCompInfo ebx).wBitSize],16 ;16 bit ??
|
||||
je short ??doByteDivide
|
||||
mov [dwCODECByteIndex],eax
|
||||
jmp short ??mainloopr
|
||||
|
||||
??doByteDivide:
|
||||
shr eax,1 ;Divide size by two
|
||||
inc edi ; 16 bit so skip 1 more
|
||||
mov [dwCODECByteIndex],eax
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Right Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopr:
|
||||
test [(sCompInfo ebx).dwSampleIndex2],1
|
||||
je short ??fetchTokenr
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf2]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
jmp short ??calcDifferencer
|
||||
|
||||
??fetchTokenr:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf2],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
|
||||
??calcDifferencer:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference2],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep2]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4r
|
||||
add [(sCompInfo ebx).dwDifference2],ecx ;Add wStep
|
||||
|
||||
??no4r:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2r
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no2r:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1r
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no1r:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8r
|
||||
neg [(sCompInfo ebx).dwDifference2] ;Negate diff
|
||||
|
||||
??no8r:
|
||||
; add difference to predicted value.
|
||||
mov eax,[(sCompInfo ebx).dwPredicted2]
|
||||
add eax,[(sCompInfo ebx).dwDifference2]
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowr
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowr:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowr
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowr:
|
||||
mov [(sCompInfo ebx).dwPredicted2],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitr
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo ***
|
||||
jmp short ??adjustIndexr
|
||||
|
||||
??output8Bitr:
|
||||
; output 8 bit sample
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexr:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode2]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex2],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex2],8000h
|
||||
jb short ??checkOverflowr
|
||||
; reset index to zero
|
||||
mov [(sCompInfo ebx).wIndex2],0
|
||||
jmp short ??adjustStepr
|
||||
|
||||
??checkOverflowr:
|
||||
; check if wIndex > 88
|
||||
cmp [(sCompInfo ebx).wIndex2],88
|
||||
jbe short ??adjustStepr
|
||||
mov [(sCompInfo ebx).wIndex2],88 ; reset index to 88
|
||||
|
||||
??adjustStepr:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex2]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex2],1
|
||||
mov [(sCompInfo ebx).wStep2],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopr
|
||||
|
||||
|
||||
??exitout:
|
||||
; don't think we need this but just in case i'll leave it here!!
|
||||
|
||||
; mov [(sCompInfo ebx).lpSource],esi
|
||||
; mov [(sCompInfo ebx).lpDest],edi
|
||||
; set up return value for number of bytes processed.
|
||||
mov eax,[dwCODECBytesProcessed]
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
JumpTable DD ??0
|
||||
DD ??1
|
||||
DD ??2
|
||||
DD ??3
|
||||
DD ??4
|
||||
DD ??5
|
||||
DD ??6
|
||||
DD ??7
|
||||
DD ??8
|
||||
DD ??9
|
||||
DD ??10
|
||||
DD ??11
|
||||
DD ??12
|
||||
DD ??13
|
||||
DD ??14
|
||||
DD ??15
|
||||
|
||||
|
||||
ENDP sosCODECDecompressData
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
;***************************************************************************
|
||||
;* sosCODEC_LOCK -- locks the JLB audio decompression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is lock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Lock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL sosCODEC_Lock:NEAR
|
||||
PROC sosCODEC_Lock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
;
|
||||
; Lock the code that is used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
or [InitFlags], IF_LOCKED_PM_CODE
|
||||
|
||||
;
|
||||
; Lock the data used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
or [InitFlags], IF_LOCKED_PM_DATA
|
||||
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Lock
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Unlock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL sosCODEC_Unlock:NEAR
|
||||
PROC sosCODEC_Unlock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
test [InitFlags],IF_LOCKED_PM_CODE
|
||||
jz ??code_not_locked
|
||||
|
||||
mov eax , 0601h
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
|
||||
??code_not_locked:
|
||||
test [InitFlags],IF_LOCKED_PM_DATA
|
||||
jz ??data_not_locked
|
||||
|
||||
mov ax,0601h ; set es to descriptor of data.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
|
||||
??data_not_locked:
|
||||
mov [InitFlags],0
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Unlock
|
||||
|
||||
END
|
||||
|
83
WWFLAT32/AUDIO/NEW/SOSCOMP.H
Normal file
83
WWFLAT32/AUDIO/NEW/SOSCOMP.H
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* File : soscomp.h
|
||||
* Date Created : 6/1/94
|
||||
* Description :
|
||||
*
|
||||
* Programmer(s) : Nick Skrepetos
|
||||
* Last Modification : 10/1/94 - 11:37:9 AM
|
||||
* Additional Notes : Modified by Denzil E. Long, Jr.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (c) 1994, HMI, Inc. All Rights Reserved *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_COMPRESS
|
||||
#define _SOS_COMPRESS
|
||||
|
||||
/* compression types */
|
||||
enum {
|
||||
_ADPCM_TYPE_1,
|
||||
};
|
||||
|
||||
/* define compression structure */
|
||||
typedef struct _tagCOMPRESS_INFO {
|
||||
char *lpSource;
|
||||
char *lpDest;
|
||||
unsigned long dwCompSize;
|
||||
unsigned long dwUnCompSize;
|
||||
unsigned long dwSampleIndex;
|
||||
long dwPredicted;
|
||||
long dwDifference;
|
||||
short wCodeBuf;
|
||||
short wCode;
|
||||
short wStep;
|
||||
short wIndex;
|
||||
|
||||
unsigned long dwSampleIndex2; //added BP for channel 2
|
||||
long dwPredicted2; //added BP for channel 2
|
||||
long dwDifference2; //added BP for channel 2
|
||||
short wCodeBuf2; //added BP for channel 2
|
||||
short wCode2; //added BP for channel 2
|
||||
short wStep2; //added BP for channel 2
|
||||
short wIndex2; //added BP for channel 2
|
||||
short wBitSize;
|
||||
short wChannels; //added BP for # of channels
|
||||
} _SOS_COMPRESS_INFO;
|
||||
|
||||
/* compressed file type header */
|
||||
typedef struct _tagCOMPRESS_HEADER {
|
||||
unsigned long dwType; // type of compression
|
||||
unsigned long dwCompressedSize; // compressed file size
|
||||
unsigned long dwUnCompressedSize; // uncompressed file size
|
||||
unsigned long dwSourceBitSize; // original bit size
|
||||
char szName[16]; // file type, for error checking
|
||||
} _SOS_COMPRESS_HEADER;
|
||||
|
||||
/* Prototypes */
|
||||
extern "C" {
|
||||
void sosCODECInitStream(_SOS_COMPRESS_INFO *);
|
||||
unsigned long sosCODECCompressData(_SOS_COMPRESS_INFO *, unsigned long);
|
||||
unsigned long sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
128
WWFLAT32/AUDIO/NEW/SOSDATA.H
Normal file
128
WWFLAT32/AUDIO/NEW/SOSDATA.H
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosdata.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_DATA
|
||||
#define _SOS_DATA
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#pragma pack(4)
|
||||
extern WORD _sosDIGIData_Start;
|
||||
extern WORD _sosDIGIData_End;
|
||||
extern WORD _wSOSDriverLinear[];
|
||||
extern WORD _wSOSTimerLinear[];
|
||||
extern LPSTR _lpSOSDriver[];
|
||||
extern LPSTR _lpSOSTimer[];
|
||||
extern LPSTR _lpSOSDriverCS[];
|
||||
extern LPSTR _lpSOSTimerCS[];
|
||||
extern BOOL _wSOSDriverLoaded[];
|
||||
extern BOOL _wSOSTimerLoaded[];
|
||||
extern BOOL _wSOSDriverInitialized[];
|
||||
extern WORD _wSOSOutputRate[];
|
||||
extern WORD _wSOSDMABuffersize[];
|
||||
extern LONG _dwSOSDMABufferPhysical[];
|
||||
extern LPSTR _lpSOSDMABuffer[];
|
||||
extern BOOL _wTimerUsed;
|
||||
extern VOID ( far *_lpSOSFillHandler[] )( VOID );
|
||||
extern WORD _wSOSTimerType[];
|
||||
extern WORD _wSOSDriverType[];
|
||||
extern _SOS_SAMPLE far * _lpSOSSampleList[][ _MAX_VOICES ];
|
||||
extern LPWORD _lpSOSDMAIrqCount[];
|
||||
extern LPWORD _lpSOSDMAFillCount[];
|
||||
extern WORD _wSOSTmrNextCount;
|
||||
extern VOID ( interrupt far *_lpSOSOldTimer )( VOID );
|
||||
extern WORD _wSOSDriverID[];
|
||||
extern _SOS_CAPABILITIES _sSOSDriverCaps[];
|
||||
extern WORD _wSOSDMAPortList[];
|
||||
extern BYTE _bSOSDMAChannel[];
|
||||
extern _SOS_INIT_DRIVER _sSOSDIGIInitDriver[];
|
||||
extern BYTE _pSOSDriverPath[];
|
||||
extern BYTE _pSOSTempDriverPath[];
|
||||
extern BOOL _wTIMERUsed;
|
||||
extern WORD _wTIMERValue;
|
||||
extern VOID ( far * _lpTIMEREvents[] )( VOID );
|
||||
extern WORD _wTIMEREventRate[];
|
||||
extern WORD _dwTIMEREventFraction[];
|
||||
extern WORD _dwTIMEREventFractionCurrent[];
|
||||
extern BYTE _bSOSMIDITimerSongHandler[];
|
||||
extern BYTE _bSOSMIDISongHandle;
|
||||
extern WORD _wSOSTimerMemHandle[];
|
||||
extern WORD _wSOSDriverMemHandle[];
|
||||
extern WORD _wSOSRealSeg[];
|
||||
|
||||
extern _FILEHEADER _sDETFileHeader;
|
||||
extern _DRIVERHEADER _sDETDriverHeader;
|
||||
extern _FILEHEADER sLOADFileHeader;
|
||||
extern _DRIVERHEADER sLOADDriverHeader;
|
||||
extern BOOL _wDETInitialized;
|
||||
extern WORD _wDETLinear;
|
||||
extern LPSTR _lpDETDriverBuffer;
|
||||
extern LPSTR _lpDETDriverBufferCS;
|
||||
extern WORD _hDETFile;
|
||||
extern DWORD _dwDETDriverIndex;
|
||||
extern WORD _wDETDriverIndexCur;
|
||||
extern WORD _wDETMemHandle;
|
||||
extern LPSOSDEVICECAPS _lpDETDeviceCaps;
|
||||
extern _SOS_CAPABILITIES _sDETCaps;
|
||||
extern PSTR _pSOSErrorStrings[];
|
||||
extern BOOL _wSOSBufferAllocated[];
|
||||
extern BOOL _wSOSSystemInitialized;
|
||||
extern VDS_STRUCT _sSOSVDSInfo;
|
||||
extern _SOS_FILL_INFO _sSOSFillInfo;
|
||||
extern WORD _wSOSTimerEventIndex;
|
||||
extern WORD _wSOSTimerEntered;
|
||||
extern WORD _wSOSDriverSize[];
|
||||
extern WORD _wSOSTimerSize[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern WORD _sosDIGIData1_Start;
|
||||
extern WORD _sosDIGIData1_End;
|
||||
extern WORD _sosDIGIData2_Start;
|
||||
extern WORD _sosDIGIData2_End;
|
||||
extern BYTE _bTIMERInstalled;
|
||||
extern BYTE _bTIMERDPMI;
|
||||
extern WORD wDetectPort;
|
||||
extern WORD wDetectIRQ;
|
||||
extern WORD wDetectDMA;
|
||||
extern WORD wDetectParam;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
83
WWFLAT32/AUDIO/NEW/SOSDEFS.H
Normal file
83
WWFLAT32/AUDIO/NEW/SOSDEFS.H
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosdefs.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef _SOSDEFS_DEFINED
|
||||
#define _SOSDEFS_DEFINED
|
||||
|
||||
#undef _TRUE
|
||||
#undef _FALSE
|
||||
#undef _NULL
|
||||
enum
|
||||
{
|
||||
_FALSE,
|
||||
_TRUE
|
||||
};
|
||||
|
||||
#define _NULL 0
|
||||
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
#endif
|
||||
typedef int BOOL;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned WORD;
|
||||
#ifndef LONG
|
||||
typedef signed long LONG;
|
||||
#endif
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
typedef BYTE * PBYTE;
|
||||
typedef char near * PSTR;
|
||||
typedef WORD * PWORD;
|
||||
typedef LONG * PLONG;
|
||||
typedef VOID * PVOID;
|
||||
|
||||
typedef BYTE far * LPBYTE;
|
||||
typedef BYTE far * LPSTR;
|
||||
typedef WORD far * LPWORD;
|
||||
typedef LONG far * LPLONG;
|
||||
typedef VOID far * LPVOID;
|
||||
|
||||
typedef BYTE huge * HPBYTE;
|
||||
typedef BYTE huge * HPSTR;
|
||||
typedef WORD huge * HPWORD;
|
||||
typedef LONG huge * HPLONG;
|
||||
typedef VOID huge * HPVOID;
|
||||
|
||||
typedef unsigned HANDLE;
|
||||
|
||||
#endif
|
||||
|
BIN
WWFLAT32/AUDIO/NEW/SOSDW1PS.LIB
Normal file
BIN
WWFLAT32/AUDIO/NEW/SOSDW1PS.LIB
Normal file
Binary file not shown.
218
WWFLAT32/AUDIO/NEW/SOSFNCT.H
Normal file
218
WWFLAT32/AUDIO/NEW/SOSFNCT.H
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosfnct.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_FUNCTIONS
|
||||
#define _SOS_FUNCTIONS
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
WORD sosDIGILockMemory ( VOID );
|
||||
WORD sosDIGIUnLockMemory ( VOID );
|
||||
WORD sosDIGIInitSystem ( LPSTR, WORD );
|
||||
WORD sosDIGIUnInitSystem ( VOID );
|
||||
WORD sosDIGIInitDriver ( WORD, _SOS_HARDWARE far *,
|
||||
_SOS_INIT_DRIVER far *, WORD far * );
|
||||
WORD sosDIGIUnInitDriver ( WORD, BOOL, BOOL );
|
||||
WORD sosDIGILoadDriver ( WORD, WORD, LPSTR far *, LPSTR far *, PSTR, PSTR, WORD * );
|
||||
WORD sosDIGIUnLoadDriver ( WORD );
|
||||
WORD sosDIGIGetDeviceCaps ( WORD, LPSOSDEVICECAPS );
|
||||
|
||||
#ifdef PHARLAP
|
||||
LPSTR sosDIGIAllocateBuffer ( WORD , WORD *, WORD * );
|
||||
#else
|
||||
LPSTR sosDIGIAllocateBuffer ( WORD , WORD *, WORD * );
|
||||
#endif
|
||||
|
||||
WORD sosDIGIStopSample ( WORD, WORD );
|
||||
WORD sosDIGISamplesPlaying ( WORD );
|
||||
BOOL sosDIGISampleDone ( WORD, WORD );
|
||||
BOOL sosDIGISampleFilling ( WORD, WORD );
|
||||
WORD sosDIGIStartSample ( WORD, _SOS_START_SAMPLE far * );
|
||||
WORD sosDIGIContinueSample ( WORD, WORD, _SOS_START_SAMPLE far * );
|
||||
|
||||
|
||||
WORD sosDIGIDetectInit ( LPSTR );
|
||||
WORD sosDIGIDetectUnInit ( VOID );
|
||||
WORD sosDIGIDetectFindHardware ( WORD, _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectFindFirst ( _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectFindNext ( _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectGetSettings ( _SOS_HARDWARE far * );
|
||||
WORD sosDIGIDetectGetCaps ( WORD, _SOS_CAPABILITIES far * );
|
||||
WORD sosDIGIDetectVerifySettings( _SOS_HARDWARE far * );
|
||||
PSTR sosGetErrorString ( WORD );
|
||||
|
||||
WORD sosDIGILoadTimer ( WORD , LPSTR far *, LPSTR far *, PSTR, PSTR, WORD * );
|
||||
WORD sosDIGIUnLoadTimer ( WORD );
|
||||
|
||||
WORD sosTIMERRegisterEvent ( WORD wCallRate, VOID ( far * lpTimerEvent )( VOID ), WORD far *lpTimerHandle );
|
||||
WORD sosTIMERInitSystem ( WORD, WORD );
|
||||
WORD sosTIMERUnInitSystem ( WORD );
|
||||
WORD sosTIMERSetRate ( WORD );
|
||||
WORD sosTIMERRemoveEvent ( WORD );
|
||||
WORD sosTIMERAlterEventRate ( WORD, WORD );
|
||||
WORD sosTIMERGetEventRate ( WORD );
|
||||
VOID far sosTIMEROldHandler ( VOID );
|
||||
VOID far sosTIMERHandler ( VOID );
|
||||
|
||||
// functions in soscntl.c
|
||||
WORD sosDIGISetSampleVolume ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetSampleVolume ( WORD, WORD );
|
||||
WORD sosDIGISetChannel ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetChannel ( WORD, WORD );
|
||||
WORD sosDIGIGetBytesProcessed ( WORD, WORD );
|
||||
WORD sosDIGIGetLoopCount ( WORD, WORD );
|
||||
WORD sosDIGISetPanLocation ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetPanLocation ( WORD, WORD );
|
||||
DWORD sosDIGISetPitch ( WORD, WORD, DWORD );
|
||||
DWORD sosDIGIGetPitch ( WORD, WORD );
|
||||
WORD sosDIGIGetDMAPosition ( WORD );
|
||||
WORD sosDIGISetPanSpeed ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetPanSpeed ( WORD, WORD );
|
||||
WORD sosDIGIGetSampleID ( WORD, WORD );
|
||||
WORD sosDIGIGetSampleHandle ( WORD, WORD );
|
||||
WORD sosDIGISetMasterVolume ( WORD, WORD );
|
||||
#ifdef PHARLAP
|
||||
VOID sosFreeVDSPage ( unsigned short, unsigned short, DWORD );
|
||||
WORD sosAllocVDSPage ( unsigned short *, unsigned short *, DWORD * );
|
||||
#else
|
||||
WORD sosAllocVDSPage ( LPSTR *, WORD *, WORD * );
|
||||
VOID sosFreeVDSPage ( WORD, WORD, LONG );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef PHARLAP
|
||||
extern int cdecl sosRealFree ( int );
|
||||
extern BOOL cdecl _sos_read( WORD, LPSTR, WORD, WORD * );
|
||||
extern int cdecl sosRealAlloc( int, int *, int * );
|
||||
extern void cdecl sosDRVFarMemCopy( LPSTR, LPSTR, WORD );
|
||||
extern int cdecl sosGetCS( VOID );
|
||||
extern int cdecl sosGetES( VOID );
|
||||
#else
|
||||
extern int cdecl sosRealAlloc ( int, int *, int * );
|
||||
extern int cdecl sosRealFree ( int );
|
||||
#endif
|
||||
|
||||
// sos driver functions
|
||||
extern WORD cdecl sosDRVLockMemory ( DWORD, DWORD );
|
||||
extern WORD cdecl sosDRVUnLockMemory ( DWORD, DWORD );
|
||||
extern void cdecl sosDRVGetCapsInfo ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDetDRVGetCapsInfo ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDRVGetCapsPtr ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDRVInit ( LPSTR, LPSTR, int, int, int, int, int, int );
|
||||
extern void cdecl sosDRVStart ( LPSTR, LPSTR, int, int );
|
||||
extern void cdecl sosDRVSetRate ( LPSTR, LPSTR, int );
|
||||
extern void cdecl sosDRVSetAction ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVStop ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVUnInit ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVGetFillInfo ( LPSTR, LPSTR, LPSTR, int, int, int, _SOS_FILL_INFO * );
|
||||
extern void cdecl sosFillSampleStructs ( PSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVExist ( LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVGetSettings ( LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVVerifySettings( LPSTR, WORD, WORD, WORD, LPSTR );
|
||||
extern WORD cdecl sosDIGIInitForWindows( WORD );
|
||||
extern WORD cdecl sosDIGIUnInitForWindows( WORD );
|
||||
extern LPSTR cdecl sosAllocateFarMem ( WORD, PSTR, WORD * );
|
||||
extern LPSTR cdecl sosCreateAliasCS ( LPSTR );
|
||||
extern VOID cdecl sosFreeSelector ( LPSTR, DWORD );
|
||||
extern LPSTR cdecl sosMAKEDOSPtr ( PSTR );
|
||||
extern VOID cdecl sosDetDRVSetEnvString ( DWORD, PSTR );
|
||||
extern PSTR cdecl sosDetDRVGetEnvString ( DWORD );
|
||||
extern VOID cdecl sosDetDRVEnvStringInit ( LPSTR, LPSTR );
|
||||
extern VOID cdecl sosDRVSetupCallFunctions( LPSTR, LPSTR, LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDRVGetFreeMemory ( VOID );
|
||||
extern WORD cdecl sosDRVAllocVDSStruct ( WORD, WORD *, WORD * );
|
||||
extern WORD cdecl sosDRVFreeVDSStruct ( WORD, WORD );
|
||||
extern WORD cdecl sosDRVIsWindowsActive ( VOID );
|
||||
extern WORD cdecl sosDRVVDSGetBuffer ( WORD );
|
||||
extern WORD cdecl sosDRVVDSFreeBuffer ( WORD );
|
||||
extern WORD cdecl getDS( VOID );
|
||||
extern WORD cdecl sosDRVMakeDMASelector ( WORD );
|
||||
extern WORD cdecl sosDRVFreeDMASelector ( WORD );
|
||||
|
||||
|
||||
extern void cdecl sosTIMERDRVInit( int wRate, void ( far * )( void ) );
|
||||
extern void cdecl sosTIMERDRVUnInit( void );
|
||||
extern void cdecl sosTIMERDRVHandler( void );
|
||||
extern void cdecl sosTIMERDRVFHandler( void );
|
||||
extern void cdecl sosTIMERDRVEnable( void );
|
||||
extern void cdecl sosTIMERDRVDisable( void );
|
||||
extern void cdecl sosTIMERDRVCallOld( void );
|
||||
extern void cdecl sosTIMERDRVSetRate( WORD );
|
||||
extern void cdecl sosDIGITimer_Start( void );
|
||||
extern void cdecl sosDIGITimer_End( void );
|
||||
extern void cdecl sosDIGIDrv_Start( void );
|
||||
extern void cdecl sosDIGIDrv_End( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// external functions for handling system initialization and
|
||||
// uninitialization
|
||||
WORD sosEXDIGInitDriver ( WORD, WORD, WORD, LPSTR,
|
||||
_SOS_HARDWARE far *, WORD * );
|
||||
WORD sosEXDIGIUnInitDriver ( VOID );
|
||||
|
||||
WORD sosEXDETFindDriver ( WORD, LPSTR, _SOS_HARDWARE far *,
|
||||
_SOS_CAPABILITIES far * );
|
||||
|
||||
// memory locking prototypes
|
||||
VOID sosDIGICaps_Start( VOID );
|
||||
VOID sosDIGICaps_End( VOID );
|
||||
VOID sosDIGIErr_Start( VOID );
|
||||
VOID sosDIGIErr_End( VOID );
|
||||
VOID sosDIGITmr_Start( VOID );
|
||||
VOID sosDIGITmr_End( VOID );
|
||||
VOID sosDIGIStart_Start( VOID );
|
||||
VOID sosDIGIStart_End( VOID );
|
||||
VOID sosDIGIPlyng_Start( VOID );
|
||||
VOID sosDIGIPlyng_End( VOID );
|
||||
VOID sosDIGIRate_Start( VOID );
|
||||
VOID sosDIGIRate_End( VOID );
|
||||
VOID sosDIGIDone_Start( VOID );
|
||||
VOID sosDIGIDone_End( VOID );
|
||||
VOID sosDIGIDetec_Start( VOID );
|
||||
VOID sosDIGIDetec_End( VOID );
|
||||
VOID sosDIGIInit_Start( VOID );
|
||||
VOID sosDIGIInit_End( VOID );
|
||||
VOID sosDIGILoad_Start( VOID );
|
||||
VOID sosDIGILoad_End( VOID );
|
||||
VOID sosDIGICntl_Start( VOID );
|
||||
VOID sosDIGICntl_End( VOID );
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
129
WWFLAT32/AUDIO/NEW/SOSRES.H
Normal file
129
WWFLAT32/AUDIO/NEW/SOSRES.H
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosres.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#define _SOS_RESOURCE
|
||||
#ifndef _SOS_RESOURCE
|
||||
#define _SOS_RESOURCE
|
||||
|
||||
// structure for resource file header
|
||||
typedef struct
|
||||
{
|
||||
// file version
|
||||
WORD wVersion;
|
||||
|
||||
// file size
|
||||
LONG dwFileSize;
|
||||
|
||||
// number of resources in file
|
||||
WORD wResCount;
|
||||
|
||||
// offset of resource data from top of file
|
||||
LONG dwResOffset;
|
||||
|
||||
// offset of sync track from top of file
|
||||
LONG dwSyncTrackOffset;
|
||||
|
||||
} _RES_FILE_HEADER;
|
||||
|
||||
// structure for resource block header
|
||||
typedef struct
|
||||
{
|
||||
// resource id
|
||||
WORD wID;
|
||||
|
||||
// resource type
|
||||
WORD wResType;
|
||||
|
||||
// offset of next block
|
||||
LONG dwNextBlock;
|
||||
|
||||
// size of the current resource information
|
||||
LONG dwResSize;
|
||||
|
||||
// rate to play block at
|
||||
WORD wBlockRate;
|
||||
|
||||
// id for the sync track to use
|
||||
WORD wSyncTrackID;
|
||||
|
||||
} _RES_BLOCK_HEADER;
|
||||
|
||||
// structure for sync mark tag
|
||||
typedef struct _tagSYNCMARK
|
||||
{
|
||||
// ID of the type of mark being used
|
||||
WORD wID;
|
||||
|
||||
// location in data of sync mark
|
||||
LONG dwSyncOffset;
|
||||
|
||||
// length of sync block
|
||||
LONG dwSyncSize;
|
||||
|
||||
// start sample data
|
||||
_SOS_START_SAMPLE sampleData;
|
||||
|
||||
} _RES_SYNCMARK;
|
||||
|
||||
typedef union
|
||||
{
|
||||
// structure for sync mark tag
|
||||
_RES_SYNCMARK syncMark;
|
||||
|
||||
} _RES_TAG;
|
||||
|
||||
// union for filter information for prepareWave
|
||||
typedef union
|
||||
{
|
||||
// filter type
|
||||
WORD wFilterID;
|
||||
|
||||
// structure for volume
|
||||
struct volume
|
||||
{
|
||||
WORD wVolume;
|
||||
};
|
||||
|
||||
// structure for delay
|
||||
struct delay
|
||||
{
|
||||
WORD wDelaySamples;
|
||||
};
|
||||
|
||||
} _SOS_FILTER;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
54
WWFLAT32/AUDIO/NEW/SOUND.BAK
Normal file
54
WWFLAT32/AUDIO/NEW/SOUND.BAK
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : SOUND.H *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 1, 1993 *
|
||||
* *
|
||||
* Last Update : September 1, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#define HMI_DRIVER TRUE
|
||||
#include "sos.h"
|
||||
#include "soscomp.h"
|
||||
|
||||
/*
|
||||
** Maximum number of sound effects that may run at once.
|
||||
*/
|
||||
#define MAX_SFX 4
|
||||
|
||||
/*
|
||||
** Size of temp HMI low memory staging buffer.
|
||||
*/
|
||||
#define SFX_MINI_STAGE_BUFFER_SIZE (1024*4)
|
||||
|
||||
#endif
|
54
WWFLAT32/AUDIO/NEW/SOUND.H
Normal file
54
WWFLAT32/AUDIO/NEW/SOUND.H
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : SOUND.H *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 1, 1993 *
|
||||
* *
|
||||
* Last Update : September 1, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#define HMI_DRIVER TRUE
|
||||
#include "sos.h"
|
||||
#include "soscomp.h"
|
||||
|
||||
/*
|
||||
** Maximum number of sound effects that may run at once.
|
||||
*/
|
||||
#define MAX_SFX 5
|
||||
|
||||
/*
|
||||
** Size of temp HMI low memory staging buffer.
|
||||
*/
|
||||
#define SFX_MINI_STAGE_BUFFER_SIZE (1024*4)
|
||||
|
||||
#endif
|
253
WWFLAT32/AUDIO/NEW/SOUNDINT.BAK
Normal file
253
WWFLAT32/AUDIO/NEW/SOUNDINT.BAK
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 23, 1995 [PWG] *
|
||||
* *
|
||||
* This file is the include file for the Westwood Sound Sytem defines and *
|
||||
* routines that are handled in an interrupt.
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
/*
|
||||
** Defines for true and false. These are included because we do not allow
|
||||
** the sound int to include any of the westwood standard headers. If we
|
||||
** did, there might be too much temptation to call another library function.
|
||||
** this would be bad, because then that function would not be locked.
|
||||
*/
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
** Define the different type of sound compression avaliable to the westwood
|
||||
** library.
|
||||
*/
|
||||
typedef enum {
|
||||
SCOMP_NONE=0, // No compression -- raw data.
|
||||
SCOMP_WESTWOOD=1, // Special sliding window delta compression.
|
||||
SCOMP_SONARC=33, // Sonarc frame compression.
|
||||
SCOMP_SOS=99 // SOS frame compression.
|
||||
} SCompressType;
|
||||
|
||||
/*
|
||||
** This is the safety overrun margin for the sonarc compressed
|
||||
** data frames. This value should be equal the maximum 'order' times
|
||||
** the maximum number of bytes per sample. It should be evenly divisible
|
||||
** by 16 to aid paragraph alignment.
|
||||
*/
|
||||
#define SONARC_MARGIN 32
|
||||
|
||||
|
||||
/*
|
||||
** Define the sample control structure which helps us to handle feeding
|
||||
** data to the sound interrupt.
|
||||
*/
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
/*
|
||||
** This flags whether this sample structure is active or not.
|
||||
*/
|
||||
unsigned Active:1;
|
||||
|
||||
/*
|
||||
** This flags whether the sample is loading or has been started.
|
||||
*/
|
||||
unsigned Loading:1;
|
||||
|
||||
/*
|
||||
** This semaphore ensures that simultaneous update of this structure won't
|
||||
** occur. This is necessary since both interrupt and regular code can modify
|
||||
** this structure.
|
||||
*/
|
||||
unsigned DontTouch:1;
|
||||
|
||||
/*
|
||||
** If this sample is really to be considered a score rather than
|
||||
** a sound effect, then special rules apply. These largely fall into
|
||||
** the area of volume control.
|
||||
*/
|
||||
unsigned IsScore:1;
|
||||
|
||||
/*
|
||||
** This is the original sample pointer. It is used to control the sample based on
|
||||
** pointer rather than handle. The handle method is necessary when more than one
|
||||
** sample could be playing simultaneously. The pointer method is necessary when
|
||||
** the dealing with a sample that may have stopped behind the programmer's back and
|
||||
** this occurance is not otherwise determinable. It is also used in
|
||||
** conjunction with original size to unlock a sample which has been DPMI
|
||||
** locked.
|
||||
*/
|
||||
void const *Original;
|
||||
long OriginalSize;
|
||||
|
||||
/*
|
||||
** These are pointers to the double buffers in low ram.
|
||||
*/
|
||||
VOID *Buffer[2];
|
||||
|
||||
/*
|
||||
** The number of bytes in the buffer that has been filled but is not
|
||||
** yet playing. This value is normally the size of the buffer,
|
||||
** except for the case of the last bit of the sample.
|
||||
*/
|
||||
LONG DataLength;
|
||||
|
||||
/*
|
||||
** This is the buffer index for the low buffer that
|
||||
** has been filled with data but not yet being
|
||||
** played.
|
||||
*/
|
||||
WORD Index;
|
||||
|
||||
/*
|
||||
** Pointer to the sound data that has not yet been copied
|
||||
** to the playback buffers.
|
||||
*/
|
||||
VOID *Source;
|
||||
|
||||
/*
|
||||
** This is the number of bytes remaining in the source data as
|
||||
** pointed to by the "Source" element.
|
||||
*/
|
||||
LONG Remainder;
|
||||
|
||||
/*
|
||||
** Samples maintain a priority which is used to determine
|
||||
** which sounds live or die when the maximum number of
|
||||
** sounds are being played.
|
||||
*/
|
||||
WORD Priority;
|
||||
|
||||
/*
|
||||
** This is the handle as returned by sosDIGIStartSample function.
|
||||
*/
|
||||
WORD Handle;
|
||||
|
||||
/*
|
||||
** This is the current volume of the sample as it is being played.
|
||||
*/
|
||||
WORD Volume;
|
||||
WORD Reducer; // Amount to reduce volume per tick.
|
||||
|
||||
/*
|
||||
** This flags whether the sample is in stereo.
|
||||
*/
|
||||
WORD Stereo;
|
||||
|
||||
/*
|
||||
** This is the compression that the sound data is using.
|
||||
*/
|
||||
SCompressType Compression;
|
||||
WORD TrailerLen; // Number of trailer bytes in buffer.
|
||||
BYTE Trailer[SONARC_MARGIN]; // Maximum number of 'order' samples needed.
|
||||
|
||||
|
||||
DWORD Pitch;
|
||||
WORD Flags;
|
||||
|
||||
/*
|
||||
** This flag indicates whether this sample needs servicing.
|
||||
** Servicing entails filling one of the empty low buffers.
|
||||
*/
|
||||
WORD Service;
|
||||
|
||||
/*
|
||||
** This flag is TRUE when the sample has stopped playing,
|
||||
** BUT there is more data available. The sample must be
|
||||
** restarted upon filling the low buffer.
|
||||
*/
|
||||
BOOL Restart;
|
||||
|
||||
/*
|
||||
** Streaming control handlers.
|
||||
*/
|
||||
BOOL (*Callback)(WORD id, WORD *odd, VOID **buffer, LONG *size);
|
||||
VOID *QueueBuffer; // Pointer to continued sample data.
|
||||
LONG QueueSize; // Size of queue buffer attached.
|
||||
WORD Odd; // Block number tracker (0..StreamBufferCount-1).
|
||||
int FilePending; // Number of buffers already filled ahead.
|
||||
long FilePendingSize; // Number of bytes in last filled buffer.
|
||||
|
||||
/*
|
||||
** The file variables are used when streaming directly off of the
|
||||
** hard drive.
|
||||
*/
|
||||
WORD FileHandle; // Streaming file handle (ERROR = not in use).
|
||||
VOID *FileBuffer; // Temporary streaming buffer (allowed to be freed).
|
||||
/*
|
||||
** The following structure is used if the sample if compressed using
|
||||
** the sos 16 bit compression Codec.
|
||||
*/
|
||||
_SOS_COMPRESS_INFO sosinfo;
|
||||
|
||||
} SampleTrackerType;
|
||||
|
||||
|
||||
typedef struct LockedData {
|
||||
unsigned int DigiHandle; // = -1;
|
||||
BOOL ServiceSomething; // = FALSE;
|
||||
long MagicNumber; // = 0xDEAF;
|
||||
VOID *UncompBuffer; // = NULL;
|
||||
long StreamBufferSize; // = (2*SFX_MINI_STAGE_BUFFER_SIZE)+128;
|
||||
short StreamBufferCount; // = 32;
|
||||
SampleTrackerType SampleTracker[MAX_SFX];
|
||||
unsigned int SoundVolume;
|
||||
unsigned int ScoreVolume;
|
||||
BOOL _int;
|
||||
int MaxSamples;
|
||||
int Rate;
|
||||
} LockedDataType;
|
||||
|
||||
extern LockedDataType LockedData;
|
||||
#pragma pack(4);
|
||||
|
||||
void Init_Locked_Data(void);
|
||||
void Unlock_Locked_Data(void);
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size);
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize);
|
||||
VOID far cdecl maintenance_callback(VOID);
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid);
|
||||
void far HMI_TimerCallback(void);
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size);
|
||||
void DPMI_Unlock(VOID const *ptr, long const size);
|
||||
extern "C" {
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size);
|
||||
void Mem_Copy(void *source, void *dest, unsigned long bytes_to_copy);
|
||||
long Decompress_Frame(void * source, void * dest, long size);
|
||||
int Decompress_Frame_Lock(void);
|
||||
int Decompress_Frame_Unlock(void);
|
||||
int sosCODEC_Lock(void);
|
||||
int sosCODEC_Unlock(void);
|
||||
void __GETDS(void);
|
||||
}
|
||||
|
549
WWFLAT32/AUDIO/NEW/SOUNDINT.CPP
Normal file
549
WWFLAT32/AUDIO/NEW/SOUNDINT.CPP
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 28, 1995 [PWG] *
|
||||
* *
|
||||
* This module contains all of the functions that are used within our *
|
||||
* sound interrupt. They are stored in a seperate module because memory *
|
||||
* around these functions must be locked or they will cause a read to *
|
||||
* be generated while in an interrupt. *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Simple_Copy -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* save_my_regs -- Inline function which will save assembly regs *
|
||||
* restore_my_regs -- Inline function which will restore saved registes *
|
||||
* Audio_Add_Long_To_Pointer -- Adds an offset to a ptr casted void *
|
||||
* Init_Locked_Data -- Initializes sound driver locked data *
|
||||
* Audio_Mem_Set -- Quick see routine to set memory to a value *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
#pragma pack(4)
|
||||
#include "soundint.h"
|
||||
//#include "mem.h"
|
||||
|
||||
/***************************************************************************
|
||||
** All routines past this point must be locked for the sound driver to **
|
||||
** function under a VCPI memory manager. These locks are unnecessary if **
|
||||
** the driver does not have to run under windows or does not use virtual **
|
||||
** memory. **
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* SAVE_MY_REGS -- Inline function which will save assembly regs *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux save_my_regs = \
|
||||
"pushfd" \
|
||||
"pushad" \
|
||||
"push ds" \
|
||||
"push es" \
|
||||
"push fs" \
|
||||
"push gs" \
|
||||
"push ds" \
|
||||
"pop es";
|
||||
|
||||
#pragma aux enable = \
|
||||
"sti";
|
||||
|
||||
#pragma aux disable = \
|
||||
"cli";
|
||||
|
||||
/***************************************************************************
|
||||
* RESTORE_MY_REGS -- Inline function which will restore saved registers *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux restore_my_regs = \
|
||||
"pop gs" \
|
||||
"pop fs" \
|
||||
"pop es" \
|
||||
"pop ds" \
|
||||
"popad" \
|
||||
"popfd";
|
||||
|
||||
/***************************************************************************
|
||||
* SIMPLE_COPY -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size)
|
||||
{
|
||||
|
||||
|
||||
long out = 0; // Number of bytes copied to the destination.
|
||||
|
||||
/*
|
||||
** It could happen that entering this routine, the source buffer
|
||||
** has been exhausted, but the alternate buffer is still valid.
|
||||
** Move the alternate into the primary position before proceeding.
|
||||
*/
|
||||
if (!(*ssize)) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = NULL;
|
||||
*altsize = 0;
|
||||
}
|
||||
|
||||
if (*source && *ssize) {
|
||||
long s; // Scratch length var.
|
||||
|
||||
/*
|
||||
** Copy as much as possible from the primary source, but no
|
||||
** more than the primary source has to offer.
|
||||
*/
|
||||
s = size;
|
||||
if (*ssize < s) s = *ssize;
|
||||
Mem_Copy(*source, *dest, s);
|
||||
*source = Audio_Add_Long_To_Pointer(*source, s);
|
||||
*ssize -= s;
|
||||
*dest = Audio_Add_Long_To_Pointer(*dest, s);
|
||||
size -= s;
|
||||
out += s;
|
||||
|
||||
/*
|
||||
** If the primary source was insufficient to fill the request, then
|
||||
** move the alternate into the primary position and try again.
|
||||
*/
|
||||
if (size) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = 0;
|
||||
*altsize = 0;
|
||||
out += Simple_Copy(source, ssize, alternate, altsize, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
return(out);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* *
|
||||
* This routine is used to copy the sound data (possibly compressed) to the destination *
|
||||
* buffer in raw format. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the source data (possibly compressed). *
|
||||
* *
|
||||
* dest -- Pointer to the destination buffer. *
|
||||
* *
|
||||
* size -- The size of the destination buffer. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes placed into the output buffer. This is usually *
|
||||
* the number of bytes requested except in the case when the source is exhausted. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/03/1994 JLB : Created. *
|
||||
* 09/04/1994 JLB : Revamped entirely. *
|
||||
*=============================================================================================*/
|
||||
#pragma argsused
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize)
|
||||
{
|
||||
|
||||
long s;
|
||||
long datasize = 0; // Output bytes.
|
||||
|
||||
switch (scomp) {
|
||||
default:
|
||||
|
||||
case SCOMP_NONE:
|
||||
datasize = Simple_Copy(source, ssize, alternate, altsize, &dest, size);
|
||||
break;
|
||||
|
||||
case SCOMP_WESTWOOD:
|
||||
case SCOMP_SOS:
|
||||
while (size > 0) {
|
||||
|
||||
/*
|
||||
** The block spans two buffers. It must be copied down to
|
||||
** a staging area before it can be decompressed.
|
||||
*/
|
||||
{
|
||||
long magic;
|
||||
unsigned short fsize;
|
||||
unsigned short dsize;
|
||||
void *fptr;
|
||||
void *dptr;
|
||||
void *mptr;
|
||||
|
||||
fptr = &fsize;
|
||||
dptr = &dsize;
|
||||
mptr = &magic;
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, sizeof(fsize));
|
||||
if (s < sizeof(fsize)) {
|
||||
return datasize;
|
||||
}
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dptr, sizeof(dsize));
|
||||
if (s < sizeof(dsize) || size < dsize) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &mptr, sizeof(magic));
|
||||
if (s < sizeof(magic) || magic != LockedData.MagicNumber) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the frame and uncompressed data size are identical, then this
|
||||
** indicates that the frame is not compressed. Just copy it directly
|
||||
** to the destination buffer in this case.
|
||||
*/
|
||||
if (fsize == dsize) {
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dest, fsize);
|
||||
if (s < dsize) {
|
||||
return (datasize);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** The frame was compressed, so copy it to the staging buffer, and then
|
||||
** uncompress it into the final destination buffer.
|
||||
*/
|
||||
fptr = LockedData.UncompBuffer;
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, fsize);
|
||||
if (s < fsize) {
|
||||
return (datasize);
|
||||
}
|
||||
if (scomp == SCOMP_WESTWOOD) {
|
||||
Decompress_Frame(LockedData.UncompBuffer, dest, dsize);
|
||||
} else {
|
||||
st->sosinfo.lpSource = (char *)LockedData.UncompBuffer;
|
||||
st->sosinfo.lpDest = (char *)dest;
|
||||
sosCODECDecompressData(&st->sosinfo, dsize);
|
||||
}
|
||||
dest = Audio_Add_Long_To_Pointer(dest, dsize);
|
||||
}
|
||||
datasize += dsize;
|
||||
size -= dsize;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return(datasize);
|
||||
}
|
||||
|
||||
VOID far cdecl maintenance_callback(VOID)
|
||||
{
|
||||
save_my_regs();
|
||||
int index;
|
||||
SampleTrackerType *st;
|
||||
|
||||
if (!LockedData._int && LockedData.DigiHandle != -1 && LockedData.ServiceSomething) {
|
||||
|
||||
LockedData._int++;
|
||||
enable();
|
||||
LockedData.ServiceSomething = FALSE;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
if (st->Active) {
|
||||
|
||||
/*
|
||||
** General service routine to handle moving small blocks from the
|
||||
** source into the low RAM staging buffers. If the source is
|
||||
** compressed, then this will also uncompress it as the copy
|
||||
** is performed.
|
||||
*/
|
||||
if (st->Service) {
|
||||
if (st->DontTouch) {
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
} else {
|
||||
st->Service = FALSE;
|
||||
|
||||
#if(FALSE)
|
||||
st->DataLength = SFX_MINI_STAGE_BUFFER_SIZE;
|
||||
#else
|
||||
st->DataLength = Sample_Copy( st,
|
||||
&st->Source,
|
||||
&st->Remainder,
|
||||
&st->QueueBuffer,
|
||||
&st->QueueSize,
|
||||
st->Buffer[st->Index],
|
||||
SFX_MINI_STAGE_BUFFER_SIZE,
|
||||
st->Compression,
|
||||
&st->Trailer[0],
|
||||
&st->TrailerLen);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** For file streamed samples, fill the queue pointer if needed.
|
||||
** This allows for delays in calling the Sound_Callback function.
|
||||
*/
|
||||
if (!st->DontTouch && !st->QueueBuffer && st->FilePending) {
|
||||
st->QueueBuffer = Audio_Add_Long_To_Pointer(st->FileBuffer, (long)(st->Odd%LockedData.StreamBufferCount)*(long)LockedData.StreamBufferSize);
|
||||
st->FilePending--;
|
||||
st->Odd++;
|
||||
if (!st->FilePending) {
|
||||
st->QueueSize = st->FilePendingSize;
|
||||
} else {
|
||||
st->QueueSize = LockedData.StreamBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** Advance to the next sample control structure.
|
||||
*/
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
|
||||
|
||||
if (!LockedData._int) {
|
||||
|
||||
LockedData._int++;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
/*
|
||||
** If there are any samples that require fading, then do so at this
|
||||
** time.
|
||||
*/
|
||||
if (st->Active && st->Reducer && st->Volume) {
|
||||
if (st->Reducer >= st->Volume) {
|
||||
st->Volume = 0;
|
||||
} else {
|
||||
st->Volume -= st->Reducer;
|
||||
}
|
||||
|
||||
if (st->IsScore) {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.ScoreVolume);
|
||||
} else {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.SoundVolume);
|
||||
}
|
||||
}
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
restore_my_regs();
|
||||
}
|
||||
/***********************************************************************************************
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* *
|
||||
* This routine is called in an interrupt to handle the double *
|
||||
* buffering of digital audio. This routine is the interface between *
|
||||
* the buffers maintained by Sound_Callback() and the HMI driver *
|
||||
* itself. *
|
||||
* *
|
||||
* INPUT: driverhandle -- The handle to the HMI driver. *
|
||||
* *
|
||||
* callsource -- Code indicating the reason for the callback. *
|
||||
* *
|
||||
* sampleid -- The ID number of the sample itself. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This is called in an interrupt so it return as quickly as *
|
||||
* possible. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid)
|
||||
{
|
||||
SampleTrackerType *st;
|
||||
int index;
|
||||
|
||||
|
||||
/*
|
||||
** Find the correct control structure for the handle specified.
|
||||
*/
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
st = &LockedData.SampleTracker[index];
|
||||
if (st->Active && st->Handle == sampleid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == LockedData.MaxSamples) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (driverhandle == LockedData.DigiHandle) {
|
||||
|
||||
switch (callsource) {
|
||||
|
||||
/*
|
||||
** The sample is now no longer audible. Don't stop the sample
|
||||
** tracking if a servicing is needed. If it is needed then
|
||||
** obviously the sample isn't quite done.
|
||||
*/
|
||||
case _SAMPLE_DONE:
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** The sample is finished processing, but not necessarily finished playing.
|
||||
*/
|
||||
case _SAMPLE_PROCESSED:
|
||||
if (st->DataLength && st->Active) {
|
||||
_SOS_START_SAMPLE start;
|
||||
long dlength;
|
||||
|
||||
dlength = st->DataLength;
|
||||
st->DataLength = 0;
|
||||
|
||||
Audio_Mem_Set(&start, 0, sizeof(start));
|
||||
start.lpSamplePtr = (LPSTR)st->Buffer[st->Index];
|
||||
|
||||
start.dwSampleSize = dlength-1;
|
||||
|
||||
start.wSampleFlags = st->Flags;
|
||||
start.lpCallback = (void cdecl (far *)(unsigned int, unsigned int, unsigned int))&DigiCallback;
|
||||
start.wLoopCount = 0;
|
||||
if (st->IsScore) {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.ScoreVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
} else {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.SoundVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
}
|
||||
|
||||
start.wChannel = st->Stereo;
|
||||
start.wSampleID = index+1;
|
||||
start.dwSamplePitchAdd = st->Pitch;
|
||||
st->Index ^= 1;
|
||||
|
||||
if (st->Remainder || st->QueueBuffer || st->Callback || st->FilePending) {
|
||||
st->Service = TRUE;
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
}
|
||||
|
||||
sosDIGIContinueSample(LockedData.DigiHandle, st->Handle, &start);
|
||||
} else {
|
||||
|
||||
/*
|
||||
** This is necessary because Stop_Sample may screw things
|
||||
** up, otherwise. Can't rely on the _SAMPLE_DONE call.
|
||||
*/
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** Sample is now looping (not used).
|
||||
*/
|
||||
case _SAMPLE_LOOPING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void far HMI_TimerCallback(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ADD_LONG_TO_POINTER -- Adds an offset to a ptr casted void *
|
||||
* *
|
||||
* INPUT: void * ptr - the pointer to add to *
|
||||
* long size - the size to add to it *
|
||||
* *
|
||||
* OUTPUT: void * ptr - the new location it will point to *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size)
|
||||
{
|
||||
return ((void *) ( (char const *) ptr + size));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* AUDIO_MEM_SET -- Quick see routine to set memory to a value *
|
||||
* *
|
||||
* INPUT: void const * - the memory that needs to be set *
|
||||
* unsigned char - the value to set the memory to *
|
||||
* long size - how big an area to set *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/28/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size)
|
||||
{
|
||||
unsigned char *temp = (unsigned char *)ptr;
|
||||
for (int lp = 0; lp < size; lp ++) {
|
||||
*temp++ = value;
|
||||
}
|
||||
}
|
253
WWFLAT32/AUDIO/NEW/SOUNDINT.H
Normal file
253
WWFLAT32/AUDIO/NEW/SOUNDINT.H
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 23, 1995 [PWG] *
|
||||
* *
|
||||
* This file is the include file for the Westwood Sound Sytem defines and *
|
||||
* routines that are handled in an interrupt.
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
/*
|
||||
** Defines for true and false. These are included because we do not allow
|
||||
** the sound int to include any of the westwood standard headers. If we
|
||||
** did, there might be too much temptation to call another library function.
|
||||
** this would be bad, because then that function would not be locked.
|
||||
*/
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
** Define the different type of sound compression avaliable to the westwood
|
||||
** library.
|
||||
*/
|
||||
typedef enum {
|
||||
SCOMP_NONE=0, // No compression -- raw data.
|
||||
SCOMP_WESTWOOD=1, // Special sliding window delta compression.
|
||||
SCOMP_SONARC=33, // Sonarc frame compression.
|
||||
SCOMP_SOS=99 // SOS frame compression.
|
||||
} SCompressType;
|
||||
|
||||
/*
|
||||
** This is the safety overrun margin for the sonarc compressed
|
||||
** data frames. This value should be equal the maximum 'order' times
|
||||
** the maximum number of bytes per sample. It should be evenly divisible
|
||||
** by 16 to aid paragraph alignment.
|
||||
*/
|
||||
#define SONARC_MARGIN 32
|
||||
|
||||
|
||||
/*
|
||||
** Define the sample control structure which helps us to handle feeding
|
||||
** data to the sound interrupt.
|
||||
*/
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
/*
|
||||
** This flags whether this sample structure is active or not.
|
||||
*/
|
||||
unsigned Active:1;
|
||||
|
||||
/*
|
||||
** This flags whether the sample is loading or has been started.
|
||||
*/
|
||||
unsigned Loading:1;
|
||||
|
||||
/*
|
||||
** This semaphore ensures that simultaneous update of this structure won't
|
||||
** occur. This is necessary since both interrupt and regular code can modify
|
||||
** this structure.
|
||||
*/
|
||||
unsigned DontTouch:1;
|
||||
|
||||
/*
|
||||
** If this sample is really to be considered a score rather than
|
||||
** a sound effect, then special rules apply. These largely fall into
|
||||
** the area of volume control.
|
||||
*/
|
||||
unsigned IsScore:1;
|
||||
|
||||
/*
|
||||
** This is the original sample pointer. It is used to control the sample based on
|
||||
** pointer rather than handle. The handle method is necessary when more than one
|
||||
** sample could be playing simultaneously. The pointer method is necessary when
|
||||
** the dealing with a sample that may have stopped behind the programmer's back and
|
||||
** this occurance is not otherwise determinable. It is also used in
|
||||
** conjunction with original size to unlock a sample which has been DPMI
|
||||
** locked.
|
||||
*/
|
||||
void const *Original;
|
||||
long OriginalSize;
|
||||
|
||||
/*
|
||||
** These are pointers to the double buffers in low ram.
|
||||
*/
|
||||
VOID *Buffer[2];
|
||||
|
||||
/*
|
||||
** The number of bytes in the buffer that has been filled but is not
|
||||
** yet playing. This value is normally the size of the buffer,
|
||||
** except for the case of the last bit of the sample.
|
||||
*/
|
||||
LONG DataLength;
|
||||
|
||||
/*
|
||||
** This is the buffer index for the low buffer that
|
||||
** has been filled with data but not yet being
|
||||
** played.
|
||||
*/
|
||||
WORD Index;
|
||||
|
||||
/*
|
||||
** Pointer to the sound data that has not yet been copied
|
||||
** to the playback buffers.
|
||||
*/
|
||||
VOID *Source;
|
||||
|
||||
/*
|
||||
** This is the number of bytes remaining in the source data as
|
||||
** pointed to by the "Source" element.
|
||||
*/
|
||||
LONG Remainder;
|
||||
|
||||
/*
|
||||
** Samples maintain a priority which is used to determine
|
||||
** which sounds live or die when the maximum number of
|
||||
** sounds are being played.
|
||||
*/
|
||||
WORD Priority;
|
||||
|
||||
/*
|
||||
** This is the handle as returned by sosDIGIStartSample function.
|
||||
*/
|
||||
WORD Handle;
|
||||
|
||||
/*
|
||||
** This is the current volume of the sample as it is being played.
|
||||
*/
|
||||
WORD Volume;
|
||||
WORD Reducer; // Amount to reduce volume per tick.
|
||||
|
||||
/*
|
||||
** This flags whether the sample is in stereo.
|
||||
*/
|
||||
WORD Stereo;
|
||||
|
||||
/*
|
||||
** This is the compression that the sound data is using.
|
||||
*/
|
||||
SCompressType Compression;
|
||||
WORD TrailerLen; // Number of trailer bytes in buffer.
|
||||
BYTE Trailer[SONARC_MARGIN]; // Maximum number of 'order' samples needed.
|
||||
|
||||
|
||||
DWORD Pitch;
|
||||
WORD Flags;
|
||||
|
||||
/*
|
||||
** This flag indicates whether this sample needs servicing.
|
||||
** Servicing entails filling one of the empty low buffers.
|
||||
*/
|
||||
WORD Service;
|
||||
|
||||
/*
|
||||
** This flag is TRUE when the sample has stopped playing,
|
||||
** BUT there is more data available. The sample must be
|
||||
** restarted upon filling the low buffer.
|
||||
*/
|
||||
BOOL Restart;
|
||||
|
||||
/*
|
||||
** Streaming control handlers.
|
||||
*/
|
||||
BOOL (*Callback)(WORD id, WORD *odd, VOID **buffer, LONG *size);
|
||||
VOID *QueueBuffer; // Pointer to continued sample data.
|
||||
LONG QueueSize; // Size of queue buffer attached.
|
||||
WORD Odd; // Block number tracker (0..StreamBufferCount-1).
|
||||
int FilePending; // Number of buffers already filled ahead.
|
||||
long FilePendingSize; // Number of bytes in last filled buffer.
|
||||
|
||||
/*
|
||||
** The file variables are used when streaming directly off of the
|
||||
** hard drive.
|
||||
*/
|
||||
WORD FileHandle; // Streaming file handle (ERROR = not in use).
|
||||
VOID *FileBuffer; // Temporary streaming buffer (allowed to be freed).
|
||||
/*
|
||||
** The following structure is used if the sample if compressed using
|
||||
** the sos 16 bit compression Codec.
|
||||
*/
|
||||
_SOS_COMPRESS_INFO sosinfo;
|
||||
|
||||
} SampleTrackerType;
|
||||
|
||||
|
||||
typedef struct LockedData {
|
||||
unsigned int DigiHandle; // = -1;
|
||||
BOOL ServiceSomething; // = FALSE;
|
||||
long MagicNumber; // = 0xDEAF;
|
||||
VOID *UncompBuffer; // = NULL;
|
||||
long StreamBufferSize; // = (2*SFX_MINI_STAGE_BUFFER_SIZE)+128;
|
||||
short StreamBufferCount; // = 32;
|
||||
SampleTrackerType SampleTracker[MAX_SFX];
|
||||
unsigned int SoundVolume;
|
||||
unsigned int ScoreVolume;
|
||||
BOOL _int;
|
||||
int MaxSamples;
|
||||
int Rate;
|
||||
} LockedDataType;
|
||||
|
||||
extern LockedDataType LockedData;
|
||||
#pragma pack(4);
|
||||
|
||||
void Init_Locked_Data(void);
|
||||
void Unlock_Locked_Data(void);
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size);
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize);
|
||||
VOID far cdecl maintenance_callback(VOID);
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid);
|
||||
void far HMI_TimerCallback(void);
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size);
|
||||
void DPMI_Unlock(VOID const *ptr, long const size);
|
||||
extern "C" {
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size);
|
||||
void Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy);
|
||||
long Decompress_Frame(void * source, void * dest, long size);
|
||||
int Decompress_Frame_Lock(void);
|
||||
int Decompress_Frame_Unlock(void);
|
||||
int sosCODEC_Lock(void);
|
||||
int sosCODEC_Unlock(void);
|
||||
void __GETDS(void);
|
||||
}
|
||||
|
1463
WWFLAT32/AUDIO/NEW/SOUNDIO.BAK
Normal file
1463
WWFLAT32/AUDIO/NEW/SOUNDIO.BAK
Normal file
File diff suppressed because it is too large
Load Diff
1463
WWFLAT32/AUDIO/NEW/SOUNDIO.CPP
Normal file
1463
WWFLAT32/AUDIO/NEW/SOUNDIO.CPP
Normal file
File diff suppressed because it is too large
Load Diff
147
WWFLAT32/AUDIO/NEW/SOUNDLCK.CPP
Normal file
147
WWFLAT32/AUDIO/NEW/SOUNDLCK.CPP
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDLCK.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 23, 1995 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <dos.h>
|
||||
#include <mem.h>
|
||||
#include "soundint.h"
|
||||
#include "wwmem.h"
|
||||
|
||||
LockedDataType LockedData;
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/***************************************************************************
|
||||
* INIT_LOCKED_DATA -- Initializes sound driver locked data *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void Init_Locked_Data(void)
|
||||
{
|
||||
/*
|
||||
** Initialize all of the data elements that need to be locked.
|
||||
*/
|
||||
LockedData.DigiHandle = -1;
|
||||
LockedData.ServiceSomething = FALSE;
|
||||
LockedData.MagicNumber = 0xDEAF;
|
||||
LockedData.UncompBuffer = NULL;
|
||||
LockedData.StreamBufferSize = (2*SFX_MINI_STAGE_BUFFER_SIZE)+128;
|
||||
LockedData.StreamBufferCount = 32;
|
||||
LockedData.SoundVolume = 255;
|
||||
LockedData.ScoreVolume = 255;
|
||||
LockedData._int = FALSE;
|
||||
LockedData.MaxSamples = MAX_SFX;
|
||||
|
||||
/*
|
||||
** Lock the sound specific c functions that will cause us problems if
|
||||
** they are swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Lock(&LockedData, 4096L);
|
||||
DPMI_Lock(Simple_Copy, 4096L);
|
||||
DPMI_Lock(Sample_Copy, 4096L);
|
||||
DPMI_Lock((void *)maintenance_callback, 4096L);
|
||||
DPMI_Lock((void *)DigiCallback, 4096L);
|
||||
DPMI_Lock((void *)HMI_TimerCallback, 4096L);
|
||||
DPMI_Lock(Audio_Add_Long_To_Pointer, 4096L);
|
||||
DPMI_Lock(DPMI_Unlock, 4096L);
|
||||
|
||||
/*
|
||||
** Lock the library functions that will cause us problems if they are
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Lock(Mem_Copy, 4096L);
|
||||
DPMI_Lock(Audio_Mem_Set, 4096L);
|
||||
DPMI_Lock(__GETDS, 4096L);
|
||||
|
||||
/*
|
||||
** Finally lock the two assembly modules that need locking. This can
|
||||
** be handled by calling the lock function that is local to thier module
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
Decompress_Frame_Lock();
|
||||
sosCODEC_Lock();
|
||||
}
|
||||
|
||||
void Unlock_Locked_Data(void)
|
||||
{
|
||||
/*
|
||||
** Lock the sound specific c functions that will cause us problems if
|
||||
** they are swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Unlock(&LockedData, 4096L);
|
||||
DPMI_Unlock(Simple_Copy, 4096L);
|
||||
DPMI_Unlock(Sample_Copy, 4096L);
|
||||
DPMI_Unlock((void *)maintenance_callback, 4096L);
|
||||
DPMI_Unlock((void *)DigiCallback, 4096L);
|
||||
DPMI_Unlock((void *)HMI_TimerCallback, 4096L);
|
||||
DPMI_Unlock(Audio_Add_Long_To_Pointer, 4096L);
|
||||
|
||||
/*
|
||||
** Lock the library functions that will cause us problems if they are
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Unlock(Mem_Copy, 4096L);
|
||||
DPMI_Unlock(Audio_Mem_Set, 4096L);
|
||||
DPMI_Unlock(__GETDS, 4096L);
|
||||
/*
|
||||
** Finally unlock the two assembly modules that need locking. This can
|
||||
** be handled by calling the lock function that is local to thier module
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
Decompress_Frame_Unlock();
|
||||
sosCODEC_Unlock();
|
||||
|
||||
/*
|
||||
** As a last step go though all of the sample tracker structures and make
|
||||
** sure all the samples have been properly unlocked.
|
||||
*/
|
||||
for (int id = 0; id < LockedData.MaxSamples; id++) {
|
||||
if (LockedData.SampleTracker[id].Original && !LockedData.SampleTracker[id].IsScore) {
|
||||
DPMI_Unlock(LockedData.SampleTracker[id].Original, LockedData.SampleTracker[id].OriginalSize);
|
||||
LockedData.SampleTracker[id].Original = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
59
WWFLAT32/AUDIO/NYBBTB.INC
Normal file
59
WWFLAT32/AUDIO/NYBBTB.INC
Normal file
@@ -0,0 +1,59 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;* bNybbleTablexxxx - ADPCM Lookup table for nybbles
|
||||
;****************************************************************************
|
||||
|
||||
align 4
|
||||
|
||||
bNybbleTableLow DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2
|
||||
|
||||
align 4
|
||||
|
||||
bNybbleTableHigh DB 00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2
|
||||
DB 01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2
|
||||
DB 02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2
|
||||
DB 03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2
|
||||
DB 04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2
|
||||
DB 05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2
|
||||
DB 06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2
|
||||
DB 07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2
|
||||
DB 08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2
|
||||
DB 09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2
|
||||
DB 0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2
|
||||
DB 0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2
|
||||
DB 0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2
|
||||
DB 0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2
|
||||
DB 0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2
|
||||
DB 0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2
|
565
WWFLAT32/AUDIO/SOS.H
Normal file
565
WWFLAT32/AUDIO/SOS.H
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sos.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_DEFINED
|
||||
#define _SOS_DEFINED
|
||||
#include "sosdefs.h"
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
// error definition for sound operating system
|
||||
#define _SOS_ERR -1
|
||||
|
||||
// number of drivers allowed to be open at one time
|
||||
#define _SOS_MAX_DRIVERS 5
|
||||
|
||||
// structure definition for the capabilities
|
||||
typedef struct _tagCAPABILITIES
|
||||
{
|
||||
BYTE szDeviceName[ 32 ]; // device name
|
||||
WORD wDeviceVersion; // device version
|
||||
WORD wBitsPerSample; // bits per sound sample
|
||||
WORD wChannels; // stereo/mono sound card
|
||||
WORD wMinRate; // minimum rate
|
||||
WORD wMaxRate; // maximum rate
|
||||
WORD wMixerOnBoard; // board contains mixer
|
||||
WORD wMixerFlags; // mixer capabilities
|
||||
WORD wFlags; // miscellaneous flags
|
||||
short far * lpPortList; // list of usable ports
|
||||
short far * lpDMAList; // list of usable dma channels
|
||||
short far * lpIRQList; // list of usable irq channels
|
||||
short far * lpRateList; // list of usable rates, -1 if any in min to max
|
||||
WORD fBackground; // foreground or background driver
|
||||
WORD wDeviceID; // ID for the device
|
||||
WORD wTimerID; // ID for the timer
|
||||
|
||||
} _SOS_CAPABILITIES;
|
||||
|
||||
// far pointer to the device capabilities structure
|
||||
typedef _SOS_CAPABILITIES far * LPSOSDEVICECAPS;
|
||||
|
||||
// flag types for driver
|
||||
#define _FLAGS_SIGNED 0x8000
|
||||
|
||||
// devices that can be loaded
|
||||
#define _SOUND_BLASTER_8_MONO 0xe000
|
||||
#define _SOUND_BLASTER_8_ST 0xe001
|
||||
#define _SBPRO_8_ST _SOUND_BLASTER_8_ST
|
||||
#define _SBPRO_8_MONO 0xe00f
|
||||
#define _SOUND_MASTER_II_8_MONO 0xe002
|
||||
#define _MV_PAS_8_MONO 0xe003
|
||||
#define _MV_PAS_16_MONO 0xe004
|
||||
#define _MV_PAS_8_ST 0xe005
|
||||
#define _MV_PAS_16_ST 0xe006
|
||||
#define _ADLIB_GOLD_8_ST 0xe007
|
||||
#define _ADLIB_GOLD_16_ST 0xe008
|
||||
#define _ADLIB_GOLD_8_MONO 0xe009
|
||||
#define _ADLIB_GOLD_16_MONO 0xe00a
|
||||
#define _MICROSOFT_8_MONO 0xe00b
|
||||
#define _MICROSOFT_8_ST 0xe00c
|
||||
#define _MICROSOFT_16_MONO 0xe00d
|
||||
#define _MICROSOFT_16_ST 0xe00e
|
||||
#define _SOUND_SOURCE_8_MONO_PC 0xe010
|
||||
#define _SOUND_SOURCE_8_MONO_TANDY 0xe011
|
||||
#define _GENERAL_PORT_8_MONO 0xe012
|
||||
#define _GENERAL_PORT_8_MONO_R 0xe013
|
||||
#define _SIERRA_8_MONO 0xe014
|
||||
#define _SB16_8_MONO 0xe015
|
||||
#define _SB16_8_ST 0xe016
|
||||
#define _SB16_16_MONO 0xe017
|
||||
#define _SB16_16_ST 0xe018
|
||||
#define _ESS_AUDIODRIVE_8_MONO 0xe019
|
||||
#define _ESS_AUDIODRIVE_8_ST 0xe01a
|
||||
#define _ESS_AUDIODRIVE_16_MONO 0xe01b
|
||||
#define _ESS_AUDIODRIVE_16_ST 0xe01c
|
||||
#define _SOUNDSCAPE_8_MONO 0xe01d
|
||||
#define _SOUNDSCAPE_8_ST 0xe01e
|
||||
#define _SOUNDSCAPE_16_MONO 0xe01f
|
||||
#define _SOUNDSCAPE_16_ST 0xe020
|
||||
#define _RAP10_8_MONO 0xe021
|
||||
#define _RAP10_16_MONO 0xe022
|
||||
#define _GUS_8_MONO 0xe023
|
||||
#define _GUS_8_ST 0xe024
|
||||
#define _GUS_16_MONO 0xe025
|
||||
#define _GUS_16_ST 0xe026
|
||||
#define _GUS_MAX_8_MONO 0xe027
|
||||
#define _GUS_MAX_8_ST 0xe028
|
||||
#define _GUS_MAX_16_MONO 0xe029
|
||||
#define _GUS_MAX_16_ST 0xe02a
|
||||
#define _WAVEJAMMER_8_MONO 0xe02b
|
||||
#define _WAVEJAMMER_8_ST 0xe02c
|
||||
#define _WAVEJAMMER_16_MONO 0xe02d
|
||||
#define _WAVEJAMMER_16_ST 0xe02e
|
||||
#define _TEMPOCS_8_MONO 0xe02f
|
||||
#define _TEMPOCS_8_ST 0xe030
|
||||
#define _TEMPOCS_16_MONO 0xe031
|
||||
#define _TEMPOCS_16_ST 0xe032
|
||||
#define _WAVEJAMMERCD_8_MONO 0xe033
|
||||
#define _WAVEJAMMERCD_8_ST 0xe034
|
||||
#define _WAVEJAMMERCD_16_MONO 0xe035
|
||||
#define _WAVEJAMMERCD_16_ST 0xe036
|
||||
#define _SOUND_BLASTER_8_MONO_R 0xe050
|
||||
#define _MICROSOFT_8_MONO_R 0xe051
|
||||
#define _SOUND_MASTER_II_8_MONO_R 0xe052
|
||||
#define _ADLIB_GOLD_8_MONO_R 0xe053
|
||||
#define _MV_PAS_8_MONO_R 0xe054
|
||||
#define _RAP10_8_MONO_R 0xe058
|
||||
#define _RAP10_16_MONO_R 0xe059
|
||||
#define _SB16_8_MONO_R 0xe05a
|
||||
#define _SB16_8_ST_R 0xe05b
|
||||
#define _SB16_16_MONO_R 0xe05c
|
||||
#define _SB16_16_ST_R 0xe05d
|
||||
#define _MV_PAS_16_MONO_R 0xe060
|
||||
#define _SOUNDSCAPE_8_MONO_R 0xe061
|
||||
#define _SOUNDSCAPE_8_ST_R 0xe062
|
||||
#define _SOUNDSCAPE_16_MONO_R 0xe063
|
||||
#define _SOUNDSCAPE_16_ST_R 0xe064
|
||||
#define _ESS_AUDIODRIVE_8_MONO_R 0xe065
|
||||
#define _ESS_AUDIODRIVE_8_ST_R 0xe066
|
||||
#define _ESS_AUDIODRIVE_16_MONO_R 0xe067
|
||||
#define _ESS_AUDIODRIVE_16_ST_R 0xe068
|
||||
#define _SPEECH_THING_8_MONO 0xe090
|
||||
#define _YAMAHA_8_MONO 0xe106
|
||||
#define _INT_SPEAKER_8_MONO 0xe107
|
||||
|
||||
// call indexes for the loadable drivers
|
||||
enum
|
||||
{
|
||||
_DRV_INIT,
|
||||
_DRV_UNINIT,
|
||||
_DRV_SETRATE,
|
||||
_DRV_SETACTION,
|
||||
_DRV_START,
|
||||
_DRV_STOP,
|
||||
_DRV_PAUSE,
|
||||
_DRV_RESUME,
|
||||
_DRV_CAPABILITIES,
|
||||
_DRV_PLAY_FOREGROUND,
|
||||
_DRV_GET_FILL_INFO,
|
||||
_DRV_GET_CALL_FUNCTIONS,
|
||||
_DRV_SET_CALL_FUNCTIONS
|
||||
};
|
||||
|
||||
// fill info
|
||||
typedef struct _tagFillInfo
|
||||
{
|
||||
|
||||
LPSTR lpFillHandler; // pointer to fill handler
|
||||
LPWORD lpDMAFillCount; // pointer to dma count
|
||||
LPSTR lpSampleList; // pointer to sample list
|
||||
LPWORD lpDMAMasterVolume; // pointer to dma count
|
||||
|
||||
} _SOS_FILL_INFO;
|
||||
|
||||
// caps info structure
|
||||
typedef struct _tagCapsInfo
|
||||
{
|
||||
|
||||
LPSTR lpPortList; // pointer to port list
|
||||
LPSTR lpDMAList; // pointer to DMA list
|
||||
LPSTR lpIRQList; // pointer to IRQ list
|
||||
LPSTR lpRateList; // pointer to rate list
|
||||
|
||||
} _SOS_CAPS_INFO;
|
||||
|
||||
// maximum number of available voice
|
||||
#define _MAX_VOICES 32
|
||||
|
||||
// structure definition
|
||||
typedef struct _tagSAMPLE
|
||||
{
|
||||
LPSTR samplePtr; // pointer to data buffer
|
||||
LPSTR sampleData; // pointer to active data
|
||||
LPSTR sampleLoopPtr; // pointer for loop back
|
||||
|
||||
WORD sampleLength; // length of sample
|
||||
WORD sampleIndex; // index into sample
|
||||
WORD sampleLoopLength; // length of loop
|
||||
|
||||
WORD sampleBytesLeft; // bytes left to play in sample
|
||||
|
||||
WORD sampleLoopPoint; // byte count for loop point
|
||||
WORD sampleLoopEndLength; // length of remaining chunk
|
||||
|
||||
short sampleFlags; // control sample
|
||||
short sampleVolume; // volume control
|
||||
short sampleID; // sample ID
|
||||
|
||||
short sampleChannel; // channel to play sample on
|
||||
short sampleLoopCount; // loop count
|
||||
short sampleLastFill; // last fill position
|
||||
VOID ( far cdecl * sampleCallback )( WORD, WORD, WORD ); // callback function for sample
|
||||
|
||||
WORD samplePitchAdd;
|
||||
short samplePitchFraction;
|
||||
|
||||
short samplePort; // port to use for non-dma digitized
|
||||
|
||||
WORD sampleTotalBytes;
|
||||
WORD sampleByteLength;
|
||||
|
||||
short samplePanLocation;
|
||||
short samplePanSpeed;
|
||||
short samplePanDirection;
|
||||
short samplePanStart;
|
||||
short samplePanEnd;
|
||||
|
||||
short sampleDelayBytes;
|
||||
short sampleDelayRepeat;
|
||||
|
||||
WORD sampleADPCMPredicted;
|
||||
short sampleADPCMIndex;
|
||||
|
||||
short sampleRootNoteMIDI;
|
||||
|
||||
WORD sampleTemp1;
|
||||
|
||||
} _SOS_SAMPLE;
|
||||
|
||||
// enumeration for left or right channel
|
||||
enum
|
||||
{
|
||||
_LEFT_CHANNEL,
|
||||
_RIGHT_CHANNEL,
|
||||
_CENTER_CHANNEL,
|
||||
_INTERLEAVED
|
||||
};
|
||||
|
||||
// enumeration for foreground and background
|
||||
enum
|
||||
{
|
||||
_FOREGROUND,
|
||||
_BACKGROUND
|
||||
};
|
||||
|
||||
// defines for the sample flags
|
||||
#define _ACTIVE 0x8000
|
||||
#define _LOOPING 0x4000
|
||||
#define _FIRST_TIME 0x2000
|
||||
#define _PENDING_RELEASE 0x1000
|
||||
#define _CONTINUE_BLOCK 0x0800
|
||||
#define _PITCH_SHIFT 0x0400
|
||||
#define _PANNING 0x0200
|
||||
#define _VOLUME 0x0100
|
||||
#define _TRANSLATE16TO8 0x0080
|
||||
#define _STAGE_LOOP 0x0040
|
||||
#define _TRANSLATE8TO16 0x0020
|
||||
#define _STEREOTOMONO 0x0010
|
||||
|
||||
// defines for the wParam flags
|
||||
#define _SINGLE_SAMPLE 0x01
|
||||
|
||||
#define _SOS_DCAPS_AUTO_REINIT 0x01
|
||||
#define _SOS_DCAPS_MPU_401 0x02
|
||||
#define _SOS_DCAPS_OPL2 0x04
|
||||
#define _SOS_DCAPS_OPL3 0x08
|
||||
#define _SOS_DCAPS_OPL4 0x10
|
||||
#define _SOS_DCAPS_WAVETABLE 0x20
|
||||
#define _SOS_DCAPS_DL_SAMPLES 0x40
|
||||
#define _SOS_DCAPS_FIFO_DEVICE 0x80
|
||||
#define _SOS_DCAPS_ENV_NEEDED 0x100
|
||||
#define _SOS_DCAPS_PSEUDO_DMA1 0x200
|
||||
#define _SOS_DCAPS_SIGNED_DATA 0x8000
|
||||
|
||||
// file header structure
|
||||
typedef struct
|
||||
{
|
||||
// name ID
|
||||
BYTE szName[ 32 ];
|
||||
|
||||
// number of drivers in the file
|
||||
WORD wDrivers;
|
||||
|
||||
// offset of first driver
|
||||
WORD lOffset;
|
||||
|
||||
// size of the file
|
||||
WORD lFileSize;
|
||||
|
||||
} _FILEHEADER;
|
||||
|
||||
// driver header structure
|
||||
typedef struct
|
||||
{
|
||||
// name ID
|
||||
BYTE szName[ 32 ];
|
||||
|
||||
// offset of next driver
|
||||
WORD lNextDriver;
|
||||
|
||||
// size of current driver
|
||||
WORD wSize;
|
||||
|
||||
// id for the current device
|
||||
WORD wDeviceID;
|
||||
|
||||
// id for the type of DOS extender
|
||||
WORD wExtenderType;
|
||||
|
||||
} _DRIVERHEADER;
|
||||
|
||||
// device hardware information
|
||||
typedef struct
|
||||
{
|
||||
// port to be used
|
||||
WORD wPort;
|
||||
|
||||
// irq to use
|
||||
WORD wIRQ;
|
||||
|
||||
// dma channel to se
|
||||
WORD wDMA;
|
||||
|
||||
// extra parameter
|
||||
WORD wParam;
|
||||
|
||||
} _SOS_HARDWARE;
|
||||
|
||||
// structure definition for start sample
|
||||
typedef struct
|
||||
{
|
||||
// pointer to sample
|
||||
LPSTR lpSamplePtr;
|
||||
|
||||
// size of the sample
|
||||
WORD dwSampleSize;
|
||||
|
||||
// number of times to loop the sample -1 is infinite
|
||||
WORD wLoopCount;
|
||||
|
||||
// channel to play sample on
|
||||
WORD wChannel;
|
||||
|
||||
// volume to play sample at
|
||||
WORD wVolume;
|
||||
|
||||
// id for the sample
|
||||
WORD wSampleID;
|
||||
|
||||
// far pointer to the callback function
|
||||
VOID ( far cdecl *lpCallback )( WORD, WORD, WORD );
|
||||
|
||||
// port to use if driver is a non-dma background driver
|
||||
WORD wSamplePort;
|
||||
|
||||
// flags field
|
||||
WORD wSampleFlags;
|
||||
|
||||
// total length of sample including loops, etc..
|
||||
WORD dwSampleByteLength;
|
||||
|
||||
// loop point for the sample
|
||||
WORD dwSampleLoopPoint;
|
||||
WORD dwSampleLoopLength;
|
||||
|
||||
// pitch shifting components
|
||||
WORD dwSamplePitchAdd;
|
||||
WORD wSamplePitchFraction;
|
||||
|
||||
// pan components
|
||||
WORD wSamplePanLocation;
|
||||
WORD wSamplePanSpeed;
|
||||
WORD wSamplePanDirection;
|
||||
WORD wSamplePanStart;
|
||||
WORD wSamplePanEnd;
|
||||
|
||||
// delay parts
|
||||
WORD wSampleDelayBytes;
|
||||
WORD wSampleDelayRepeat;
|
||||
|
||||
// compression components
|
||||
WORD dwSampleADPCMPredicted;
|
||||
WORD wSampleADPCMIndex;
|
||||
|
||||
// root note for pitch shifting
|
||||
WORD wSampleRootNoteMIDI;
|
||||
|
||||
// filler for future upgrades
|
||||
WORD dwSampleTemp1;
|
||||
WORD dwSampleTemp2;
|
||||
WORD dwSampleTemp3;
|
||||
|
||||
} _SOS_START_SAMPLE;
|
||||
|
||||
// structure for initializing a driver
|
||||
typedef struct
|
||||
{
|
||||
WORD wBufferSize;
|
||||
LPSTR lpBuffer;
|
||||
BOOL wAllocateBuffer;
|
||||
WORD wSampleRate;
|
||||
WORD wParam;
|
||||
LONG dwParam;
|
||||
VOID ( far *lpFillHandler )( VOID );
|
||||
LPSTR lpDriverMemory;
|
||||
LPSTR lpDriverMemoryCS;
|
||||
LPSTR lpTimerMemory;
|
||||
LPSTR lpTimerMemoryCS;
|
||||
WORD wTimerID;
|
||||
WORD wPhysical;
|
||||
|
||||
} _SOS_INIT_DRIVER;
|
||||
|
||||
// define for the timer types to use
|
||||
#define _SOS_NORMAL_TIMER 0x00
|
||||
|
||||
// enumeration for the timer types
|
||||
enum
|
||||
{
|
||||
_TIMER_8_MONO = 0x1000,
|
||||
_TIMER_8_ST,
|
||||
_TIMER_16_MONO,
|
||||
_TIMER_16_ST,
|
||||
_TIMER_8_MONO_ULAW,
|
||||
_TIMER_8_ST_ULAW,
|
||||
_TIMER_16_MONO_ULAW,
|
||||
_TIMER_16_ST_ULAW,
|
||||
_TIMER_8_MONO_REC,
|
||||
_TIMER_8_MONO_ULAW_REC,
|
||||
_TIMER_UNDEFINED_1,
|
||||
_TIMER_UNDEFINED_2,
|
||||
_TIMER_UNDEFINED_3,
|
||||
_TIMER_UNDEFINED_4,
|
||||
_TIMER_UNDEFINED_5,
|
||||
_TIMER_UNDEFINED_6,
|
||||
_TIMER_UNDEFINED_7,
|
||||
_TIMER_UNDEFINED_8,
|
||||
_TIMER_UNDEFINED_9,
|
||||
_TIMER_UNDEFINED_A,
|
||||
_TIMER_UNDEFINED_B,
|
||||
_TIMER_UNDEFINED_C,
|
||||
_TIMER_UNDEFINED_D,
|
||||
_TIMER_UNDEFINED_E,
|
||||
_TIMER_UNDEFINED_F,
|
||||
_TIMER_UNDEFINED_10,
|
||||
_TIMER_UNDEFINED_11,
|
||||
_TIMER_UNDEFINED_12,
|
||||
_TIMER_UNDEFINED_13,
|
||||
_TIMER_UNDEFINED_14,
|
||||
_TIMER_UNDEFINED_15,
|
||||
_TIMER_UNDEFINED_16,
|
||||
_TIMER_8_SOUND_SOURCE,
|
||||
_TIMER_8_SOUND_SOURCE_TANDY,
|
||||
_TIMER_8_GENERAL_PORT,
|
||||
_TIMER_8_GENERAL_PORT_REC
|
||||
};
|
||||
|
||||
// define for no slots available
|
||||
#define _ERR_NO_SLOTS ( WORD )-1
|
||||
|
||||
// error codes for the system
|
||||
enum
|
||||
{
|
||||
_ERR_NO_ERROR,
|
||||
_ERR_DRIVER_NOT_LOADED,
|
||||
_ERR_INVALID_POINTER,
|
||||
_ERR_DETECT_INITIALIZED,
|
||||
_ERR_FAIL_ON_FILE_OPEN,
|
||||
_ERR_MEMORY_FAIL,
|
||||
_ERR_INVALID_DRIVER_ID,
|
||||
_ERR_NO_DRIVER_FOUND,
|
||||
_ERR_DETECTION_FAILURE,
|
||||
_ERR_DRIVER_LOADED,
|
||||
_ERR_INVALID_HANDLE,
|
||||
_ERR_NO_HANDLES,
|
||||
_ERR_PAUSED,
|
||||
_ERR_NOT_PAUSED,
|
||||
_ERR_INVALID_DATA,
|
||||
_ERR_DRV_FILE_FAIL,
|
||||
_ERR_INVALID_PORT,
|
||||
_ERR_INVALID_IRQ,
|
||||
_ERR_INVALID_DMA,
|
||||
_ERR_INVALID_DMA_IRQ
|
||||
};
|
||||
|
||||
// maximum number of timer events that can be registered
|
||||
#define _TIMER_MAX_EVENTS 0x10
|
||||
|
||||
// flags for the debugging system
|
||||
#define _SOS_DEBUG_NORMAL 0x0000
|
||||
#define _SOS_DEBUG_NO_TIMER 0x0001
|
||||
#define _SOS_TIMER_DPMI 0x0002
|
||||
|
||||
// define for types of DOS extenders
|
||||
#define _SOS_RATIONAL 0x8000
|
||||
#define _SOS_FLASHTECK 0x4000
|
||||
|
||||
// defines for the types of timers for different
|
||||
// dos extenders
|
||||
#define _SOS_TIMER_NEAR 0x8000
|
||||
#define _SOS_TIMER_FAR 0x4000
|
||||
|
||||
// values for callback information
|
||||
enum
|
||||
{
|
||||
_SAMPLE_PROCESSED,
|
||||
_SAMPLE_LOOPING,
|
||||
_SAMPLE_DONE
|
||||
};
|
||||
|
||||
// define for special 18.2 callback rate to dos
|
||||
#define _TIMER_DOS_RATE 0xff00
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#pragma aux int_3 = "int 3"
|
||||
|
||||
#pragma pack( 1 )
|
||||
typedef struct
|
||||
{
|
||||
unsigned region_size;
|
||||
unsigned offset;
|
||||
unsigned segment;
|
||||
unsigned short number_available;
|
||||
unsigned short number_used;
|
||||
unsigned page0;
|
||||
|
||||
} EVDS_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned region_size;
|
||||
unsigned offset;
|
||||
unsigned short segment;
|
||||
unsigned short ID;
|
||||
unsigned physical;
|
||||
|
||||
} VDS_STRUCT;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#include "sosdata.h"
|
||||
#include "sosfnct.h"
|
||||
|
||||
#endif
|
871
WWFLAT32/AUDIO/SOSCODEC.ASM
Normal file
871
WWFLAT32/AUDIO/SOSCODEC.ASM
Normal file
@@ -0,0 +1,871 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* Copyright (c) 1994, HMI, INC. All Rights Reserved
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* FILE
|
||||
;* soscodec.asm
|
||||
;*
|
||||
;* DESCRIPTION
|
||||
;* HMI SOS ADPCM compression/decompression.
|
||||
;*
|
||||
;* PROGRAMMER
|
||||
;* Nick Skrepetos
|
||||
;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom)
|
||||
;* Bill Petro (Added stereo support)
|
||||
;* DATE
|
||||
;* Febuary 15, 1995
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* PUBLIC
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI.
|
||||
IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI.
|
||||
|
||||
STRUC sCompInfo
|
||||
lpSource DD ? ;Compressed data pointer
|
||||
lpDest DD ? ;Uncompressed data pointer
|
||||
dwCompSize DD ? ;Compressed size
|
||||
dwUnCompSize DD ? ;Uncompressed size
|
||||
|
||||
dwSampleIndex DD ? ;Index into sample
|
||||
dwPredicted DD ? ;Next predicted value
|
||||
dwDifference DD ? ;Difference from last sample
|
||||
wCodeBuf DW ? ;Holds 2 nibbles for decompression
|
||||
wCode DW ? ;Current 4 bit code
|
||||
wStep DW ? ;Step value in table
|
||||
wIndex DW ? ;Index into step table
|
||||
|
||||
dwSampleIndex2 DD ? ;Index into sample
|
||||
dwPredicted2 DD ? ;Next predicted value
|
||||
dwDifference2 DD ? ;Difference from last sample
|
||||
wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
|
||||
wCode2 DW ? ;Current 4 bit code
|
||||
wStep2 DW ? ;Step value in table
|
||||
wIndex2 DW ? ;Index into step table
|
||||
|
||||
wBitSize DW ? ;Bit size for decompression
|
||||
wChannels DW ? ;number of channels
|
||||
ENDS sCompInfo
|
||||
|
||||
|
||||
DATASEG
|
||||
|
||||
|
||||
InitFlags DD 0 ; Flags to indicate what has been initialized.
|
||||
|
||||
|
||||
LABEL LockedDataStart BYTE
|
||||
|
||||
;* Index table for stepping into step table
|
||||
|
||||
wCODECIndexTab DD -1,-1,-1,-1,2,4,6,8
|
||||
DD -1,-1,-1,-1,2,4,6,8
|
||||
|
||||
|
||||
;Lookup table of replacement values
|
||||
;The actual sound value is replaced with an index to lookup in this table
|
||||
;The index only takes up a nibble(4bits) and represents an int(16bits)
|
||||
;Essentially:
|
||||
;Get a value
|
||||
;compare it with the value before it
|
||||
;find closest value in table and store the index into the table
|
||||
;if i'm going down then negitize it
|
||||
;go to next byte.
|
||||
|
||||
;Theory for stereo:
|
||||
;1)handle stereo and mono in two seperate loops. cleaner...
|
||||
;start at byte 0 and skip every other byte(or word) both write and read
|
||||
;when we get done
|
||||
; set start byte to 1 and do it again
|
||||
|
||||
|
||||
|
||||
|
||||
;This table essentialy round off to closes values in 3 distinct bands
|
||||
; precalculated and optimized(i guess) for human hearing.
|
||||
|
||||
wCODECStepTab DD 7, 8, 9, 10, 11, 12, 13,14
|
||||
DD 16, 17, 19, 21, 23, 25, 28, 31
|
||||
DD 34, 37, 41, 45, 50, 55, 60, 66
|
||||
DD 73, 80, 88, 97, 107, 118, 130, 143
|
||||
DD 157, 173, 190, 209, 230, 253, 279, 307
|
||||
DD 337, 371, 408, 449, 494, 544, 598, 658
|
||||
DD 724, 796, 876, 963, 1060, 1166, 1282, 1411
|
||||
DD 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024
|
||||
DD 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484
|
||||
DD 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899
|
||||
DD 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794
|
||||
DD 32767
|
||||
|
||||
wCode DD 0 ; this is to hold index into wCodeStep
|
||||
dwCODECByteIndex DD 0 ; this is when to stop compressing
|
||||
dwCODECBytesProcessed DD 0 ; this is how many so far compressed
|
||||
dwCODECTempStep DD 0 ; tempory storage for step value
|
||||
wCODECMask DW 0 ; Current mask
|
||||
|
||||
LABEL LockedDataEnd BYTE
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECInitStream - Initialize compression stream.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* sosCODECInitStream(CompInfo)
|
||||
;*
|
||||
;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Initialize compression stream for compression and decompression.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compression information structure.
|
||||
;*
|
||||
;* RESULT
|
||||
;* NONE
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL sosCODECInitStream:NEAR
|
||||
PROC sosCODECInitStream C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
|
||||
mov eax,[sSOSInfo]
|
||||
mov [(sCompInfo eax).wIndex],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo eax).wIndex2],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep2],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex2],0 ;start at head of index
|
||||
ret
|
||||
|
||||
ENDP sosCODECInitStream
|
||||
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECDecompressData - Decompress audio data.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* Size = sosCODECDecompressData(CompInfo, NumBytes)
|
||||
;*
|
||||
;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Decompress data from a 4:1 ADPCM compressed stream. The number of
|
||||
;* bytes decompressed is returned.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compress information structure.
|
||||
;* NumBytes - Number of bytes to compress.
|
||||
;*
|
||||
;* RESULT
|
||||
;* Size - Size of decompressed data.
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL sosCODECDecompressData:NEAR
|
||||
PROC sosCODECDecompressData C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
ARG wBytes:DWORD
|
||||
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
;*---------------------------------------------------------------------------
|
||||
;* Initialize
|
||||
;*---------------------------------------------------------------------------
|
||||
|
||||
mov ebx,[sSOSInfo]
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
|
||||
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??skipByteDivide
|
||||
|
||||
shr eax,1 ;Divide size by two
|
||||
|
||||
??skipByteDivide:
|
||||
mov [dwCODECByteIndex],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
|
||||
cmp [(sCompInfo ebx).wChannels],2 ;stereo check
|
||||
je ??mainloopl ;do left side first
|
||||
|
||||
; Determine if sample index is even or odd. This will determine
|
||||
; if we need to get a new token or not.
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;Main Mono Loop
|
||||
;---------------------------------------------------------------------------
|
||||
push ebp
|
||||
movzx edx,[(sCompInfo ebx).wIndex] ;preload index
|
||||
mov ebp, [dwCODECByteIndex]
|
||||
mov ecx,[(sCompInfo ebx).dwSampleIndex] ;preload SampleIndex
|
||||
|
||||
??mainloop:
|
||||
xor eax,eax ;get a new token
|
||||
test ecx,1 ;odd Sample??
|
||||
je short ??fetchToken ; if so get new token
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
|
||||
shr eax,4
|
||||
jmp short ??calcDifference
|
||||
align 4
|
||||
|
||||
??fetchToken:
|
||||
mov al,[esi] ;put in codebuf
|
||||
inc esi
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
|
||||
|
||||
??calcDifference:
|
||||
xor ecx,ecx
|
||||
and eax,000Fh
|
||||
mov cx,[(sCompInfo ebx).wStep] ;cx is step value
|
||||
mov [wCode],eax
|
||||
jmp [DWORD PTR JumpTable + eax*4]
|
||||
align 4
|
||||
|
||||
; note: it is important for speed reasons to keep the order the
|
||||
; following jumps entries as well as the "align 4" after some of
|
||||
; the jmp statements
|
||||
|
||||
??7:
|
||||
; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
|
||||
; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
|
||||
lea ecx,[ecx+ecx*2]
|
||||
lea eax,[ecx+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??6:
|
||||
; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
|
||||
; = ( x * 8 + x * 5 ) >> 8
|
||||
lea eax,[ecx+ecx*4]
|
||||
lea eax,[eax+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??5:
|
||||
; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
|
||||
; = ( 8 * x + 3 * x) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??4:
|
||||
; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
|
||||
lea eax,[ecx+ecx*8]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??3:
|
||||
; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
|
||||
; = ( 4x + 3x ) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??2:
|
||||
; eax = x/2 + x/8 = (4*x + x) >> 3
|
||||
lea eax,[ecx+ecx*4]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??1:
|
||||
; eax = x/4 + x/8 = (2x + x )>>8
|
||||
lea eax,[ecx+ecx*2]
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??0:
|
||||
; eax = x/8 = x >> 3
|
||||
mov eax,ecx
|
||||
sar eax,3 ; now we divide x>>3
|
||||
jmp ??save_dif
|
||||
align 4
|
||||
|
||||
??15:
|
||||
; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
|
||||
; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
|
||||
lea ecx,[ecx+ecx*2]
|
||||
lea eax,[ecx+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??14:
|
||||
; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
|
||||
; = ( x * 8 + x * 5 ) >> 8
|
||||
lea eax,[ecx+ecx*4]
|
||||
lea eax,[eax+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??13:
|
||||
; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
|
||||
; = ( 8 * x + 3 * x) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??12:
|
||||
; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
|
||||
lea eax,[ecx+ecx*8]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??11:
|
||||
; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
|
||||
; = ( 4*x - 3*x ) >> 3
|
||||
lea eax,[ecx+ecx*2]
|
||||
lea eax,[eax+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??10:
|
||||
; eax = x/2 + x/8 = (4*x + x) >> 3
|
||||
lea eax,[ecx+ecx*4]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??9:
|
||||
; eax = x/4 + x/8 = (2x + x )>>8
|
||||
lea eax,[ecx+ecx*2]
|
||||
jmp ??neg_save_dif
|
||||
align 4
|
||||
|
||||
??8:
|
||||
; eax = x/8 = x >> 3
|
||||
mov eax,ecx ; !!important!! no need for align here
|
||||
|
||||
??neg_save_dif:
|
||||
sar eax,3 ; now we divide x>>3
|
||||
neg eax
|
||||
|
||||
??save_dif:
|
||||
mov ecx,[wCode] ; load offset into CODETab table
|
||||
mov [(sCompInfo ebx).dwDifference],eax ;Store wStep
|
||||
|
||||
; add difference to predicted value.
|
||||
add eax,[(sCompInfo ebx).dwPredicted]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflow
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflow:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflow
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflow:
|
||||
add edx,[wCODECIndexTab + ecx*4] ; won't hurt 486
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
mov ecx,[(sCompInfo ebx).dwSampleIndex] ;load dwSampleindex
|
||||
je short ??output16Bit
|
||||
; output 8 bit sample
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
inc edi
|
||||
jmp short ??adjustIndex
|
||||
align 4
|
||||
|
||||
??output16Bit:
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,2
|
||||
|
||||
??adjustIndex:
|
||||
cmp edx,8000h
|
||||
jb short ??checkOverflow
|
||||
mov edx,0 ;reset index to zero
|
||||
|
||||
??checkOverflow:
|
||||
inc ecx ; advance index and store step value
|
||||
cmp edx,88 ;check if wIndex > 88
|
||||
jbe short ??adjustStep
|
||||
mov edx,88 ;reset index to 88
|
||||
|
||||
??adjustStep:
|
||||
; advance index and store step value
|
||||
mov [(sCompInfo ebx).dwSampleIndex],ecx
|
||||
|
||||
; fetch wIndex so we can fetch new step value
|
||||
mov eax,[wCODECStepTab + edx*4]
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
dec ebp
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
jne ??mainloop
|
||||
pop ebp
|
||||
|
||||
mov eax,[wCode] ; these three lines do not
|
||||
mov [(sCompInfo ebx).wCode],ax ; seem to have any relevance
|
||||
|
||||
mov [(sCompInfo ebx).wIndex],dx ; save index
|
||||
jmp ??exitout
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Left Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopl:
|
||||
test [(sCompInfo ebx).dwSampleIndex],1
|
||||
je short ??fetchTokenl
|
||||
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
jmp short ??calcDifferencel
|
||||
|
||||
??fetchTokenl:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
|
||||
??calcDifferencel:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4l
|
||||
add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
|
||||
|
||||
??no4l:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2l
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no2l:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1l
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no1l:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8l
|
||||
neg [(sCompInfo ebx).dwDifference] ;Negate diff
|
||||
|
||||
??no8l:
|
||||
; add difference to predicted value.
|
||||
|
||||
mov eax,[(sCompInfo ebx).dwPredicted]
|
||||
add eax,[(sCompInfo ebx).dwDifference]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowl
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowl:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowl
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowl:
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitl
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo
|
||||
jmp short ??adjustIndexl
|
||||
|
||||
??output8Bitl:
|
||||
; output 8 bit sample
|
||||
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexl:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex],8000h
|
||||
jb short ??checkOverflowl
|
||||
mov [(sCompInfo ebx).wIndex],0
|
||||
jmp short ??adjustStepl ;reset index to zero
|
||||
|
||||
|
||||
??checkOverflowl:
|
||||
|
||||
cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
|
||||
jbe short ??adjustStepl
|
||||
mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
|
||||
|
||||
??adjustStepl:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex],1
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopl
|
||||
;----------------------------------------------------------------------------
|
||||
; Right Side Setup
|
||||
;----------------------------------------------------------------------------
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
inc esi ; skip left channel
|
||||
inc edi ; skip left channel
|
||||
cmp [(sCompInfo ebx).wBitSize],16 ;16 bit ??
|
||||
je short ??doByteDivide
|
||||
mov [dwCODECByteIndex],eax
|
||||
jmp short ??mainloopr
|
||||
|
||||
??doByteDivide:
|
||||
shr eax,1 ;Divide size by two
|
||||
inc edi ; 16 bit so skip 1 more
|
||||
mov [dwCODECByteIndex],eax
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Right Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopr:
|
||||
test [(sCompInfo ebx).dwSampleIndex2],1
|
||||
je short ??fetchTokenr
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf2]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
jmp short ??calcDifferencer
|
||||
|
||||
??fetchTokenr:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf2],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
|
||||
??calcDifferencer:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference2],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep2]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4r
|
||||
add [(sCompInfo ebx).dwDifference2],ecx ;Add wStep
|
||||
|
||||
??no4r:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2r
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no2r:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1r
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no1r:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8r
|
||||
neg [(sCompInfo ebx).dwDifference2] ;Negate diff
|
||||
|
||||
??no8r:
|
||||
; add difference to predicted value.
|
||||
mov eax,[(sCompInfo ebx).dwPredicted2]
|
||||
add eax,[(sCompInfo ebx).dwDifference2]
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowr
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowr:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowr
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowr:
|
||||
mov [(sCompInfo ebx).dwPredicted2],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitr
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo ***
|
||||
jmp short ??adjustIndexr
|
||||
|
||||
??output8Bitr:
|
||||
; output 8 bit sample
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexr:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode2]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex2],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex2],8000h
|
||||
jb short ??checkOverflowr
|
||||
; reset index to zero
|
||||
mov [(sCompInfo ebx).wIndex2],0
|
||||
jmp short ??adjustStepr
|
||||
|
||||
??checkOverflowr:
|
||||
; check if wIndex > 88
|
||||
cmp [(sCompInfo ebx).wIndex2],88
|
||||
jbe short ??adjustStepr
|
||||
mov [(sCompInfo ebx).wIndex2],88 ; reset index to 88
|
||||
|
||||
??adjustStepr:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex2]
|
||||
xor eax,eax
|
||||
shl ecx,2
|
||||
mov eax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex2],1
|
||||
mov [(sCompInfo ebx).wStep2],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopr
|
||||
|
||||
|
||||
??exitout:
|
||||
; don't think we need this but just in case i'll leave it here!!
|
||||
|
||||
; mov [(sCompInfo ebx).lpSource],esi
|
||||
; mov [(sCompInfo ebx).lpDest],edi
|
||||
; set up return value for number of bytes processed.
|
||||
mov eax,[dwCODECBytesProcessed]
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
JumpTable DD ??0
|
||||
DD ??1
|
||||
DD ??2
|
||||
DD ??3
|
||||
DD ??4
|
||||
DD ??5
|
||||
DD ??6
|
||||
DD ??7
|
||||
DD ??8
|
||||
DD ??9
|
||||
DD ??10
|
||||
DD ??11
|
||||
DD ??12
|
||||
DD ??13
|
||||
DD ??14
|
||||
DD ??15
|
||||
|
||||
|
||||
ENDP sosCODECDecompressData
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
;***************************************************************************
|
||||
;* sosCODEC_LOCK -- locks the JLB audio decompression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is lock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Lock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL sosCODEC_Lock:NEAR
|
||||
PROC sosCODEC_Lock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
;
|
||||
; Lock the code that is used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
or [InitFlags], IF_LOCKED_PM_CODE
|
||||
|
||||
;
|
||||
; Lock the data used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
or [InitFlags], IF_LOCKED_PM_DATA
|
||||
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Lock
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Unlock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL sosCODEC_Unlock:NEAR
|
||||
PROC sosCODEC_Unlock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
test [InitFlags],IF_LOCKED_PM_CODE
|
||||
jz ??code_not_locked
|
||||
|
||||
mov eax , 0601h
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
|
||||
??code_not_locked:
|
||||
test [InitFlags],IF_LOCKED_PM_DATA
|
||||
jz ??data_not_locked
|
||||
|
||||
mov ax,0601h ; set es to descriptor of data.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
|
||||
??data_not_locked:
|
||||
mov [InitFlags],0
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Unlock
|
||||
|
||||
END
|
||||
|
83
WWFLAT32/AUDIO/SOSCOMP.H
Normal file
83
WWFLAT32/AUDIO/SOSCOMP.H
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* File : soscomp.h
|
||||
* Date Created : 6/1/94
|
||||
* Description :
|
||||
*
|
||||
* Programmer(s) : Nick Skrepetos
|
||||
* Last Modification : 10/1/94 - 11:37:9 AM
|
||||
* Additional Notes : Modified by Denzil E. Long, Jr.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (c) 1994, HMI, Inc. All Rights Reserved *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_COMPRESS
|
||||
#define _SOS_COMPRESS
|
||||
|
||||
/* compression types */
|
||||
enum {
|
||||
_ADPCM_TYPE_1,
|
||||
};
|
||||
|
||||
/* define compression structure */
|
||||
typedef struct _tagCOMPRESS_INFO {
|
||||
char *lpSource;
|
||||
char *lpDest;
|
||||
unsigned long dwCompSize;
|
||||
unsigned long dwUnCompSize;
|
||||
unsigned long dwSampleIndex;
|
||||
long dwPredicted;
|
||||
long dwDifference;
|
||||
short wCodeBuf;
|
||||
short wCode;
|
||||
short wStep;
|
||||
short wIndex;
|
||||
|
||||
unsigned long dwSampleIndex2; //added BP for channel 2
|
||||
long dwPredicted2; //added BP for channel 2
|
||||
long dwDifference2; //added BP for channel 2
|
||||
short wCodeBuf2; //added BP for channel 2
|
||||
short wCode2; //added BP for channel 2
|
||||
short wStep2; //added BP for channel 2
|
||||
short wIndex2; //added BP for channel 2
|
||||
short wBitSize;
|
||||
short wChannels; //added BP for # of channels
|
||||
} _SOS_COMPRESS_INFO;
|
||||
|
||||
/* compressed file type header */
|
||||
typedef struct _tagCOMPRESS_HEADER {
|
||||
unsigned long dwType; // type of compression
|
||||
unsigned long dwCompressedSize; // compressed file size
|
||||
unsigned long dwUnCompressedSize; // uncompressed file size
|
||||
unsigned long dwSourceBitSize; // original bit size
|
||||
char szName[16]; // file type, for error checking
|
||||
} _SOS_COMPRESS_HEADER;
|
||||
|
||||
/* Prototypes */
|
||||
extern "C" {
|
||||
void sosCODECInitStream(_SOS_COMPRESS_INFO *);
|
||||
unsigned long sosCODECCompressData(_SOS_COMPRESS_INFO *, unsigned long);
|
||||
unsigned long sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
128
WWFLAT32/AUDIO/SOSDATA.H
Normal file
128
WWFLAT32/AUDIO/SOSDATA.H
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosdata.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_DATA
|
||||
#define _SOS_DATA
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#pragma pack(4)
|
||||
extern WORD _sosDIGIData_Start;
|
||||
extern WORD _sosDIGIData_End;
|
||||
extern WORD _wSOSDriverLinear[];
|
||||
extern WORD _wSOSTimerLinear[];
|
||||
extern LPSTR _lpSOSDriver[];
|
||||
extern LPSTR _lpSOSTimer[];
|
||||
extern LPSTR _lpSOSDriverCS[];
|
||||
extern LPSTR _lpSOSTimerCS[];
|
||||
extern BOOL _wSOSDriverLoaded[];
|
||||
extern BOOL _wSOSTimerLoaded[];
|
||||
extern BOOL _wSOSDriverInitialized[];
|
||||
extern WORD _wSOSOutputRate[];
|
||||
extern WORD _wSOSDMABuffersize[];
|
||||
extern LONG _dwSOSDMABufferPhysical[];
|
||||
extern LPSTR _lpSOSDMABuffer[];
|
||||
extern BOOL _wTimerUsed;
|
||||
extern VOID ( far *_lpSOSFillHandler[] )( VOID );
|
||||
extern WORD _wSOSTimerType[];
|
||||
extern WORD _wSOSDriverType[];
|
||||
extern _SOS_SAMPLE far * _lpSOSSampleList[][ _MAX_VOICES ];
|
||||
extern LPWORD _lpSOSDMAIrqCount[];
|
||||
extern LPWORD _lpSOSDMAFillCount[];
|
||||
extern WORD _wSOSTmrNextCount;
|
||||
extern VOID ( interrupt far *_lpSOSOldTimer )( VOID );
|
||||
extern WORD _wSOSDriverID[];
|
||||
extern _SOS_CAPABILITIES _sSOSDriverCaps[];
|
||||
extern WORD _wSOSDMAPortList[];
|
||||
extern BYTE _bSOSDMAChannel[];
|
||||
extern _SOS_INIT_DRIVER _sSOSDIGIInitDriver[];
|
||||
extern BYTE _pSOSDriverPath[];
|
||||
extern BYTE _pSOSTempDriverPath[];
|
||||
extern BOOL _wTIMERUsed;
|
||||
extern WORD _wTIMERValue;
|
||||
extern VOID ( far * _lpTIMEREvents[] )( VOID );
|
||||
extern WORD _wTIMEREventRate[];
|
||||
extern WORD _dwTIMEREventFraction[];
|
||||
extern WORD _dwTIMEREventFractionCurrent[];
|
||||
extern BYTE _bSOSMIDITimerSongHandler[];
|
||||
extern BYTE _bSOSMIDISongHandle;
|
||||
extern WORD _wSOSTimerMemHandle[];
|
||||
extern WORD _wSOSDriverMemHandle[];
|
||||
extern WORD _wSOSRealSeg[];
|
||||
|
||||
extern _FILEHEADER _sDETFileHeader;
|
||||
extern _DRIVERHEADER _sDETDriverHeader;
|
||||
extern _FILEHEADER sLOADFileHeader;
|
||||
extern _DRIVERHEADER sLOADDriverHeader;
|
||||
extern BOOL _wDETInitialized;
|
||||
extern WORD _wDETLinear;
|
||||
extern LPSTR _lpDETDriverBuffer;
|
||||
extern LPSTR _lpDETDriverBufferCS;
|
||||
extern WORD _hDETFile;
|
||||
extern DWORD _dwDETDriverIndex;
|
||||
extern WORD _wDETDriverIndexCur;
|
||||
extern WORD _wDETMemHandle;
|
||||
extern LPSOSDEVICECAPS _lpDETDeviceCaps;
|
||||
extern _SOS_CAPABILITIES _sDETCaps;
|
||||
extern PSTR _pSOSErrorStrings[];
|
||||
extern BOOL _wSOSBufferAllocated[];
|
||||
extern BOOL _wSOSSystemInitialized;
|
||||
extern VDS_STRUCT _sSOSVDSInfo;
|
||||
extern _SOS_FILL_INFO _sSOSFillInfo;
|
||||
extern WORD _wSOSTimerEventIndex;
|
||||
extern WORD _wSOSTimerEntered;
|
||||
extern WORD _wSOSDriverSize[];
|
||||
extern WORD _wSOSTimerSize[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern WORD _sosDIGIData1_Start;
|
||||
extern WORD _sosDIGIData1_End;
|
||||
extern WORD _sosDIGIData2_Start;
|
||||
extern WORD _sosDIGIData2_End;
|
||||
extern BYTE _bTIMERInstalled;
|
||||
extern BYTE _bTIMERDPMI;
|
||||
extern WORD wDetectPort;
|
||||
extern WORD wDetectIRQ;
|
||||
extern WORD wDetectDMA;
|
||||
extern WORD wDetectParam;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
83
WWFLAT32/AUDIO/SOSDEFS.H
Normal file
83
WWFLAT32/AUDIO/SOSDEFS.H
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosdefs.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef _SOSDEFS_DEFINED
|
||||
#define _SOSDEFS_DEFINED
|
||||
|
||||
#undef _TRUE
|
||||
#undef _FALSE
|
||||
#undef _NULL
|
||||
enum
|
||||
{
|
||||
_FALSE,
|
||||
_TRUE
|
||||
};
|
||||
|
||||
#define _NULL 0
|
||||
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
#endif
|
||||
typedef int BOOL;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned WORD;
|
||||
#ifndef LONG
|
||||
typedef signed long LONG;
|
||||
#endif
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
typedef BYTE * PBYTE;
|
||||
typedef char near * PSTR;
|
||||
typedef WORD * PWORD;
|
||||
typedef LONG * PLONG;
|
||||
typedef VOID * PVOID;
|
||||
|
||||
typedef BYTE far * LPBYTE;
|
||||
typedef BYTE far * LPSTR;
|
||||
typedef WORD far * LPWORD;
|
||||
typedef LONG far * LPLONG;
|
||||
typedef VOID far * LPVOID;
|
||||
|
||||
typedef BYTE huge * HPBYTE;
|
||||
typedef BYTE huge * HPSTR;
|
||||
typedef WORD huge * HPWORD;
|
||||
typedef LONG huge * HPLONG;
|
||||
typedef VOID huge * HPVOID;
|
||||
|
||||
typedef unsigned HANDLE;
|
||||
|
||||
#endif
|
||||
|
BIN
WWFLAT32/AUDIO/SOSDW1PS.LIB
Normal file
BIN
WWFLAT32/AUDIO/SOSDW1PS.LIB
Normal file
Binary file not shown.
218
WWFLAT32/AUDIO/SOSFNCT.H
Normal file
218
WWFLAT32/AUDIO/SOSFNCT.H
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosfnct.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _SOS_FUNCTIONS
|
||||
#define _SOS_FUNCTIONS
|
||||
|
||||
#pragma pack(4)
|
||||
|
||||
WORD sosDIGILockMemory ( VOID );
|
||||
WORD sosDIGIUnLockMemory ( VOID );
|
||||
WORD sosDIGIInitSystem ( LPSTR, WORD );
|
||||
WORD sosDIGIUnInitSystem ( VOID );
|
||||
WORD sosDIGIInitDriver ( WORD, _SOS_HARDWARE far *,
|
||||
_SOS_INIT_DRIVER far *, WORD far * );
|
||||
WORD sosDIGIUnInitDriver ( WORD, BOOL, BOOL );
|
||||
WORD sosDIGILoadDriver ( WORD, WORD, LPSTR far *, LPSTR far *, PSTR, PSTR, WORD * );
|
||||
WORD sosDIGIUnLoadDriver ( WORD );
|
||||
WORD sosDIGIGetDeviceCaps ( WORD, LPSOSDEVICECAPS );
|
||||
|
||||
#ifdef PHARLAP
|
||||
LPSTR sosDIGIAllocateBuffer ( WORD , WORD *, WORD * );
|
||||
#else
|
||||
LPSTR sosDIGIAllocateBuffer ( WORD , WORD *, WORD * );
|
||||
#endif
|
||||
|
||||
WORD sosDIGIStopSample ( WORD, WORD );
|
||||
WORD sosDIGISamplesPlaying ( WORD );
|
||||
BOOL sosDIGISampleDone ( WORD, WORD );
|
||||
BOOL sosDIGISampleFilling ( WORD, WORD );
|
||||
WORD sosDIGIStartSample ( WORD, _SOS_START_SAMPLE far * );
|
||||
WORD sosDIGIContinueSample ( WORD, WORD, _SOS_START_SAMPLE far * );
|
||||
|
||||
|
||||
WORD sosDIGIDetectInit ( LPSTR );
|
||||
WORD sosDIGIDetectUnInit ( VOID );
|
||||
WORD sosDIGIDetectFindHardware ( WORD, _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectFindFirst ( _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectFindNext ( _SOS_CAPABILITIES far *, WORD far * );
|
||||
WORD sosDIGIDetectGetSettings ( _SOS_HARDWARE far * );
|
||||
WORD sosDIGIDetectGetCaps ( WORD, _SOS_CAPABILITIES far * );
|
||||
WORD sosDIGIDetectVerifySettings( _SOS_HARDWARE far * );
|
||||
PSTR sosGetErrorString ( WORD );
|
||||
|
||||
WORD sosDIGILoadTimer ( WORD , LPSTR far *, LPSTR far *, PSTR, PSTR, WORD * );
|
||||
WORD sosDIGIUnLoadTimer ( WORD );
|
||||
|
||||
WORD sosTIMERRegisterEvent ( WORD wCallRate, VOID ( far * lpTimerEvent )( VOID ), WORD far *lpTimerHandle );
|
||||
WORD sosTIMERInitSystem ( WORD, WORD );
|
||||
WORD sosTIMERUnInitSystem ( WORD );
|
||||
WORD sosTIMERSetRate ( WORD );
|
||||
WORD sosTIMERRemoveEvent ( WORD );
|
||||
WORD sosTIMERAlterEventRate ( WORD, WORD );
|
||||
WORD sosTIMERGetEventRate ( WORD );
|
||||
VOID far sosTIMEROldHandler ( VOID );
|
||||
VOID far sosTIMERHandler ( VOID );
|
||||
|
||||
// functions in soscntl.c
|
||||
WORD sosDIGISetSampleVolume ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetSampleVolume ( WORD, WORD );
|
||||
WORD sosDIGISetChannel ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetChannel ( WORD, WORD );
|
||||
WORD sosDIGIGetBytesProcessed ( WORD, WORD );
|
||||
WORD sosDIGIGetLoopCount ( WORD, WORD );
|
||||
WORD sosDIGISetPanLocation ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetPanLocation ( WORD, WORD );
|
||||
DWORD sosDIGISetPitch ( WORD, WORD, DWORD );
|
||||
DWORD sosDIGIGetPitch ( WORD, WORD );
|
||||
WORD sosDIGIGetDMAPosition ( WORD );
|
||||
WORD sosDIGISetPanSpeed ( WORD, WORD, WORD );
|
||||
WORD sosDIGIGetPanSpeed ( WORD, WORD );
|
||||
WORD sosDIGIGetSampleID ( WORD, WORD );
|
||||
WORD sosDIGIGetSampleHandle ( WORD, WORD );
|
||||
WORD sosDIGISetMasterVolume ( WORD, WORD );
|
||||
#ifdef PHARLAP
|
||||
VOID sosFreeVDSPage ( unsigned short, unsigned short, DWORD );
|
||||
WORD sosAllocVDSPage ( unsigned short *, unsigned short *, DWORD * );
|
||||
#else
|
||||
WORD sosAllocVDSPage ( LPSTR *, WORD *, WORD * );
|
||||
VOID sosFreeVDSPage ( WORD, WORD, LONG );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef PHARLAP
|
||||
extern int cdecl sosRealFree ( int );
|
||||
extern BOOL cdecl _sos_read( WORD, LPSTR, WORD, WORD * );
|
||||
extern int cdecl sosRealAlloc( int, int *, int * );
|
||||
extern void cdecl sosDRVFarMemCopy( LPSTR, LPSTR, WORD );
|
||||
extern int cdecl sosGetCS( VOID );
|
||||
extern int cdecl sosGetES( VOID );
|
||||
#else
|
||||
extern int cdecl sosRealAlloc ( int, int *, int * );
|
||||
extern int cdecl sosRealFree ( int );
|
||||
#endif
|
||||
|
||||
// sos driver functions
|
||||
extern WORD cdecl sosDRVLockMemory ( DWORD, DWORD );
|
||||
extern WORD cdecl sosDRVUnLockMemory ( DWORD, DWORD );
|
||||
extern void cdecl sosDRVGetCapsInfo ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDetDRVGetCapsInfo ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDRVGetCapsPtr ( LPSTR, LPSTR, _SOS_CAPABILITIES far * );
|
||||
extern void cdecl sosDRVInit ( LPSTR, LPSTR, int, int, int, int, int, int );
|
||||
extern void cdecl sosDRVStart ( LPSTR, LPSTR, int, int );
|
||||
extern void cdecl sosDRVSetRate ( LPSTR, LPSTR, int );
|
||||
extern void cdecl sosDRVSetAction ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVStop ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVUnInit ( LPSTR, LPSTR );
|
||||
extern void cdecl sosDRVGetFillInfo ( LPSTR, LPSTR, LPSTR, int, int, int, _SOS_FILL_INFO * );
|
||||
extern void cdecl sosFillSampleStructs ( PSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVExist ( LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVGetSettings ( LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDetDRVVerifySettings( LPSTR, WORD, WORD, WORD, LPSTR );
|
||||
extern WORD cdecl sosDIGIInitForWindows( WORD );
|
||||
extern WORD cdecl sosDIGIUnInitForWindows( WORD );
|
||||
extern LPSTR cdecl sosAllocateFarMem ( WORD, PSTR, WORD * );
|
||||
extern LPSTR cdecl sosCreateAliasCS ( LPSTR );
|
||||
extern VOID cdecl sosFreeSelector ( LPSTR, DWORD );
|
||||
extern LPSTR cdecl sosMAKEDOSPtr ( PSTR );
|
||||
extern VOID cdecl sosDetDRVSetEnvString ( DWORD, PSTR );
|
||||
extern PSTR cdecl sosDetDRVGetEnvString ( DWORD );
|
||||
extern VOID cdecl sosDetDRVEnvStringInit ( LPSTR, LPSTR );
|
||||
extern VOID cdecl sosDRVSetupCallFunctions( LPSTR, LPSTR, LPSTR, LPSTR );
|
||||
extern WORD cdecl sosDRVGetFreeMemory ( VOID );
|
||||
extern WORD cdecl sosDRVAllocVDSStruct ( WORD, WORD *, WORD * );
|
||||
extern WORD cdecl sosDRVFreeVDSStruct ( WORD, WORD );
|
||||
extern WORD cdecl sosDRVIsWindowsActive ( VOID );
|
||||
extern WORD cdecl sosDRVVDSGetBuffer ( WORD );
|
||||
extern WORD cdecl sosDRVVDSFreeBuffer ( WORD );
|
||||
extern WORD cdecl getDS( VOID );
|
||||
extern WORD cdecl sosDRVMakeDMASelector ( WORD );
|
||||
extern WORD cdecl sosDRVFreeDMASelector ( WORD );
|
||||
|
||||
|
||||
extern void cdecl sosTIMERDRVInit( int wRate, void ( far * )( void ) );
|
||||
extern void cdecl sosTIMERDRVUnInit( void );
|
||||
extern void cdecl sosTIMERDRVHandler( void );
|
||||
extern void cdecl sosTIMERDRVFHandler( void );
|
||||
extern void cdecl sosTIMERDRVEnable( void );
|
||||
extern void cdecl sosTIMERDRVDisable( void );
|
||||
extern void cdecl sosTIMERDRVCallOld( void );
|
||||
extern void cdecl sosTIMERDRVSetRate( WORD );
|
||||
extern void cdecl sosDIGITimer_Start( void );
|
||||
extern void cdecl sosDIGITimer_End( void );
|
||||
extern void cdecl sosDIGIDrv_Start( void );
|
||||
extern void cdecl sosDIGIDrv_End( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// external functions for handling system initialization and
|
||||
// uninitialization
|
||||
WORD sosEXDIGInitDriver ( WORD, WORD, WORD, LPSTR,
|
||||
_SOS_HARDWARE far *, WORD * );
|
||||
WORD sosEXDIGIUnInitDriver ( VOID );
|
||||
|
||||
WORD sosEXDETFindDriver ( WORD, LPSTR, _SOS_HARDWARE far *,
|
||||
_SOS_CAPABILITIES far * );
|
||||
|
||||
// memory locking prototypes
|
||||
VOID sosDIGICaps_Start( VOID );
|
||||
VOID sosDIGICaps_End( VOID );
|
||||
VOID sosDIGIErr_Start( VOID );
|
||||
VOID sosDIGIErr_End( VOID );
|
||||
VOID sosDIGITmr_Start( VOID );
|
||||
VOID sosDIGITmr_End( VOID );
|
||||
VOID sosDIGIStart_Start( VOID );
|
||||
VOID sosDIGIStart_End( VOID );
|
||||
VOID sosDIGIPlyng_Start( VOID );
|
||||
VOID sosDIGIPlyng_End( VOID );
|
||||
VOID sosDIGIRate_Start( VOID );
|
||||
VOID sosDIGIRate_End( VOID );
|
||||
VOID sosDIGIDone_Start( VOID );
|
||||
VOID sosDIGIDone_End( VOID );
|
||||
VOID sosDIGIDetec_Start( VOID );
|
||||
VOID sosDIGIDetec_End( VOID );
|
||||
VOID sosDIGIInit_Start( VOID );
|
||||
VOID sosDIGIInit_End( VOID );
|
||||
VOID sosDIGILoad_Start( VOID );
|
||||
VOID sosDIGILoad_End( VOID );
|
||||
VOID sosDIGICntl_Start( VOID );
|
||||
VOID sosDIGICntl_End( VOID );
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
129
WWFLAT32/AUDIO/SOSRES.H
Normal file
129
WWFLAT32/AUDIO/SOSRES.H
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File : sosres.h
|
||||
|
||||
Programmer(s) : Don Fowler, Nick Skrepetos
|
||||
Date :
|
||||
|
||||
Purpose : Include Files For Zortech C++ Compiler
|
||||
|
||||
Last Updated :
|
||||
|
||||
****************************************************************************
|
||||
Copyright(c) 1993,1994 Human Machine Interfaces
|
||||
All Rights Reserved
|
||||
****************************************************************************/
|
||||
|
||||
#define _SOS_RESOURCE
|
||||
#ifndef _SOS_RESOURCE
|
||||
#define _SOS_RESOURCE
|
||||
|
||||
// structure for resource file header
|
||||
typedef struct
|
||||
{
|
||||
// file version
|
||||
WORD wVersion;
|
||||
|
||||
// file size
|
||||
LONG dwFileSize;
|
||||
|
||||
// number of resources in file
|
||||
WORD wResCount;
|
||||
|
||||
// offset of resource data from top of file
|
||||
LONG dwResOffset;
|
||||
|
||||
// offset of sync track from top of file
|
||||
LONG dwSyncTrackOffset;
|
||||
|
||||
} _RES_FILE_HEADER;
|
||||
|
||||
// structure for resource block header
|
||||
typedef struct
|
||||
{
|
||||
// resource id
|
||||
WORD wID;
|
||||
|
||||
// resource type
|
||||
WORD wResType;
|
||||
|
||||
// offset of next block
|
||||
LONG dwNextBlock;
|
||||
|
||||
// size of the current resource information
|
||||
LONG dwResSize;
|
||||
|
||||
// rate to play block at
|
||||
WORD wBlockRate;
|
||||
|
||||
// id for the sync track to use
|
||||
WORD wSyncTrackID;
|
||||
|
||||
} _RES_BLOCK_HEADER;
|
||||
|
||||
// structure for sync mark tag
|
||||
typedef struct _tagSYNCMARK
|
||||
{
|
||||
// ID of the type of mark being used
|
||||
WORD wID;
|
||||
|
||||
// location in data of sync mark
|
||||
LONG dwSyncOffset;
|
||||
|
||||
// length of sync block
|
||||
LONG dwSyncSize;
|
||||
|
||||
// start sample data
|
||||
_SOS_START_SAMPLE sampleData;
|
||||
|
||||
} _RES_SYNCMARK;
|
||||
|
||||
typedef union
|
||||
{
|
||||
// structure for sync mark tag
|
||||
_RES_SYNCMARK syncMark;
|
||||
|
||||
} _RES_TAG;
|
||||
|
||||
// union for filter information for prepareWave
|
||||
typedef union
|
||||
{
|
||||
// filter type
|
||||
WORD wFilterID;
|
||||
|
||||
// structure for volume
|
||||
struct volume
|
||||
{
|
||||
WORD wVolume;
|
||||
};
|
||||
|
||||
// structure for delay
|
||||
struct delay
|
||||
{
|
||||
WORD wDelaySamples;
|
||||
};
|
||||
|
||||
} _SOS_FILTER;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
54
WWFLAT32/AUDIO/SOUND.BAK
Normal file
54
WWFLAT32/AUDIO/SOUND.BAK
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : SOUND.H *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 1, 1993 *
|
||||
* *
|
||||
* Last Update : September 1, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#define HMI_DRIVER TRUE
|
||||
#include "sos.h"
|
||||
#include "soscomp.h"
|
||||
|
||||
/*
|
||||
** Maximum number of sound effects that may run at once.
|
||||
*/
|
||||
#define MAX_SFX 4
|
||||
|
||||
/*
|
||||
** Size of temp HMI low memory staging buffer.
|
||||
*/
|
||||
#define SFX_MINI_STAGE_BUFFER_SIZE (1024*4)
|
||||
|
||||
#endif
|
54
WWFLAT32/AUDIO/SOUND.H
Normal file
54
WWFLAT32/AUDIO/SOUND.H
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : SOUND.H *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 1, 1993 *
|
||||
* *
|
||||
* Last Update : September 1, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#define HMI_DRIVER TRUE
|
||||
#include "sos.h"
|
||||
#include "soscomp.h"
|
||||
|
||||
/*
|
||||
** Maximum number of sound effects that may run at once.
|
||||
*/
|
||||
#define MAX_SFX 5
|
||||
|
||||
/*
|
||||
** Size of temp HMI low memory staging buffer.
|
||||
*/
|
||||
#define SFX_MINI_STAGE_BUFFER_SIZE (1024*4)
|
||||
|
||||
#endif
|
549
WWFLAT32/AUDIO/SOUNDINT.BAK
Normal file
549
WWFLAT32/AUDIO/SOUNDINT.BAK
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 28, 1995 [PWG] *
|
||||
* *
|
||||
* This module contains all of the functions that are used within our *
|
||||
* sound interrupt. They are stored in a seperate module because memory *
|
||||
* around these functions must be locked or they will cause a read to *
|
||||
* be generated while in an interrupt. *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Simple_Copy -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* save_my_regs -- Inline function which will save assembly regs *
|
||||
* restore_my_regs -- Inline function which will restore saved registes *
|
||||
* Audio_Add_Long_To_Pointer -- Adds an offset to a ptr casted void *
|
||||
* Init_Locked_Data -- Initializes sound driver locked data *
|
||||
* Audio_Mem_Set -- Quick see routine to set memory to a value *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
#pragma pack(4)
|
||||
#include "soundint.h"
|
||||
//#include "mem.h"
|
||||
|
||||
/***************************************************************************
|
||||
** All routines past this point must be locked for the sound driver to **
|
||||
** function under a VCPI memory manager. These locks are unnecessary if **
|
||||
** the driver does not have to run under windows or does not use virtual **
|
||||
** memory. **
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* SAVE_MY_REGS -- Inline function which will save assembly regs *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux save_my_regs = \
|
||||
"pushfd" \
|
||||
"pushad" \
|
||||
"push ds" \
|
||||
"push es" \
|
||||
"push fs" \
|
||||
"push gs" \
|
||||
"push ds" \
|
||||
"pop es";
|
||||
|
||||
#pragma aux enable = \
|
||||
"sti";
|
||||
|
||||
#pragma aux disable = \
|
||||
"cli";
|
||||
|
||||
/***************************************************************************
|
||||
* RESTORE_MY_REGS -- Inline function which will restore saved registers *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux restore_my_regs = \
|
||||
"pop gs" \
|
||||
"pop fs" \
|
||||
"pop es" \
|
||||
"pop ds" \
|
||||
"popad" \
|
||||
"popfd";
|
||||
|
||||
/***************************************************************************
|
||||
* SIMPLE_COPY -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size)
|
||||
{
|
||||
|
||||
|
||||
long out = 0; // Number of bytes copied to the destination.
|
||||
|
||||
/*
|
||||
** It could happen that entering this routine, the source buffer
|
||||
** has been exhausted, but the alternate buffer is still valid.
|
||||
** Move the alternate into the primary position before proceeding.
|
||||
*/
|
||||
if (!(*ssize)) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = NULL;
|
||||
*altsize = 0;
|
||||
}
|
||||
|
||||
if (*source && *ssize) {
|
||||
long s; // Scratch length var.
|
||||
|
||||
/*
|
||||
** Copy as much as possible from the primary source, but no
|
||||
** more than the primary source has to offer.
|
||||
*/
|
||||
s = size;
|
||||
if (*ssize < s) s = *ssize;
|
||||
Mem_Copy(*source, *dest, s);
|
||||
*source = Audio_Add_Long_To_Pointer(*source, s);
|
||||
*ssize -= s;
|
||||
*dest = Audio_Add_Long_To_Pointer(*dest, s);
|
||||
size -= s;
|
||||
out += s;
|
||||
|
||||
/*
|
||||
** If the primary source was insufficient to fill the request, then
|
||||
** move the alternate into the primary position and try again.
|
||||
*/
|
||||
if (size) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = 0;
|
||||
*altsize = 0;
|
||||
out += Simple_Copy(source, ssize, alternate, altsize, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
return(out);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* *
|
||||
* This routine is used to copy the sound data (possibly compressed) to the destination *
|
||||
* buffer in raw format. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the source data (possibly compressed). *
|
||||
* *
|
||||
* dest -- Pointer to the destination buffer. *
|
||||
* *
|
||||
* size -- The size of the destination buffer. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes placed into the output buffer. This is usually *
|
||||
* the number of bytes requested except in the case when the source is exhausted. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/03/1994 JLB : Created. *
|
||||
* 09/04/1994 JLB : Revamped entirely. *
|
||||
*=============================================================================================*/
|
||||
#pragma argsused
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize)
|
||||
{
|
||||
|
||||
long s;
|
||||
long datasize = 0; // Output bytes.
|
||||
|
||||
switch (scomp) {
|
||||
default:
|
||||
|
||||
case SCOMP_NONE:
|
||||
datasize = Simple_Copy(source, ssize, alternate, altsize, &dest, size);
|
||||
break;
|
||||
|
||||
case SCOMP_WESTWOOD:
|
||||
case SCOMP_SOS:
|
||||
while (size > 0) {
|
||||
|
||||
/*
|
||||
** The block spans two buffers. It must be copied down to
|
||||
** a staging area before it can be decompressed.
|
||||
*/
|
||||
{
|
||||
long magic;
|
||||
unsigned short fsize;
|
||||
unsigned short dsize;
|
||||
void *fptr;
|
||||
void *dptr;
|
||||
void *mptr;
|
||||
|
||||
fptr = &fsize;
|
||||
dptr = &dsize;
|
||||
mptr = &magic;
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, sizeof(fsize));
|
||||
if (s < sizeof(fsize)) {
|
||||
return datasize;
|
||||
}
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dptr, sizeof(dsize));
|
||||
if (s < sizeof(dsize) || size < dsize) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &mptr, sizeof(magic));
|
||||
if (s < sizeof(magic) || magic != LockedData.MagicNumber) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the frame and uncompressed data size are identical, then this
|
||||
** indicates that the frame is not compressed. Just copy it directly
|
||||
** to the destination buffer in this case.
|
||||
*/
|
||||
if (fsize == dsize) {
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dest, fsize);
|
||||
if (s < dsize) {
|
||||
return (datasize);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** The frame was compressed, so copy it to the staging buffer, and then
|
||||
** uncompress it into the final destination buffer.
|
||||
*/
|
||||
fptr = LockedData.UncompBuffer;
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, fsize);
|
||||
if (s < fsize) {
|
||||
return (datasize);
|
||||
}
|
||||
if (scomp == SCOMP_WESTWOOD) {
|
||||
Decompress_Frame(LockedData.UncompBuffer, dest, dsize);
|
||||
} else {
|
||||
st->sosinfo.lpSource = (char *)LockedData.UncompBuffer;
|
||||
st->sosinfo.lpDest = (char *)dest;
|
||||
sosCODECDecompressData(&st->sosinfo, dsize);
|
||||
}
|
||||
dest = Audio_Add_Long_To_Pointer(dest, dsize);
|
||||
}
|
||||
datasize += dsize;
|
||||
size -= dsize;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return(datasize);
|
||||
}
|
||||
|
||||
VOID far cdecl maintenance_callback(VOID)
|
||||
{
|
||||
save_my_regs();
|
||||
int index;
|
||||
SampleTrackerType *st;
|
||||
|
||||
if (!LockedData._int && LockedData.DigiHandle != -1 && LockedData.ServiceSomething) {
|
||||
|
||||
LockedData._int++;
|
||||
enable();
|
||||
LockedData.ServiceSomething = FALSE;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
if (st->Active) {
|
||||
|
||||
/*
|
||||
** General service routine to handle moving small blocks from the
|
||||
** source into the low RAM staging buffers. If the source is
|
||||
** compressed, then this will also uncompress it as the copy
|
||||
** is performed.
|
||||
*/
|
||||
if (st->Service) {
|
||||
if (st->DontTouch) {
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
} else {
|
||||
st->Service = FALSE;
|
||||
|
||||
#if(FALSE)
|
||||
st->DataLength = SFX_MINI_STAGE_BUFFER_SIZE;
|
||||
#else
|
||||
st->DataLength = Sample_Copy( st,
|
||||
&st->Source,
|
||||
&st->Remainder,
|
||||
&st->QueueBuffer,
|
||||
&st->QueueSize,
|
||||
st->Buffer[st->Index],
|
||||
SFX_MINI_STAGE_BUFFER_SIZE,
|
||||
st->Compression,
|
||||
&st->Trailer[0],
|
||||
&st->TrailerLen);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** For file streamed samples, fill the queue pointer if needed.
|
||||
** This allows for delays in calling the Sound_Callback function.
|
||||
*/
|
||||
if (!st->DontTouch && !st->QueueBuffer && st->FilePending) {
|
||||
st->QueueBuffer = Audio_Add_Long_To_Pointer(st->FileBuffer, (long)(st->Odd%LockedData.StreamBufferCount)*(long)LockedData.StreamBufferSize);
|
||||
st->FilePending--;
|
||||
st->Odd++;
|
||||
if (!st->FilePending) {
|
||||
st->QueueSize = st->FilePendingSize;
|
||||
} else {
|
||||
st->QueueSize = LockedData.StreamBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** Advance to the next sample control structure.
|
||||
*/
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
|
||||
|
||||
if (!LockedData._int) {
|
||||
|
||||
LockedData._int++;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
/*
|
||||
** If there are any samples that require fading, then do so at this
|
||||
** time.
|
||||
*/
|
||||
if (st->Active && st->Reducer && st->Volume) {
|
||||
if (st->Reducer >= st->Volume) {
|
||||
st->Volume = 0;
|
||||
} else {
|
||||
st->Volume -= st->Reducer;
|
||||
}
|
||||
|
||||
if (st->IsScore) {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.ScoreVolume);
|
||||
} else {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.SoundVolume);
|
||||
}
|
||||
}
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
restore_my_regs();
|
||||
}
|
||||
/***********************************************************************************************
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* *
|
||||
* This routine is called in an interrupt to handle the double *
|
||||
* buffering of digital audio. This routine is the interface between *
|
||||
* the buffers maintained by Sound_Callback() and the HMI driver *
|
||||
* itself. *
|
||||
* *
|
||||
* INPUT: driverhandle -- The handle to the HMI driver. *
|
||||
* *
|
||||
* callsource -- Code indicating the reason for the callback. *
|
||||
* *
|
||||
* sampleid -- The ID number of the sample itself. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This is called in an interrupt so it return as quickly as *
|
||||
* possible. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid)
|
||||
{
|
||||
SampleTrackerType *st;
|
||||
int index;
|
||||
|
||||
|
||||
/*
|
||||
** Find the correct control structure for the handle specified.
|
||||
*/
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
st = &LockedData.SampleTracker[index];
|
||||
if (st->Active && st->Handle == sampleid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == LockedData.MaxSamples) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (driverhandle == LockedData.DigiHandle) {
|
||||
|
||||
switch (callsource) {
|
||||
|
||||
/*
|
||||
** The sample is now no longer audible. Don't stop the sample
|
||||
** tracking if a servicing is needed. If it is needed then
|
||||
** obviously the sample isn't quite done.
|
||||
*/
|
||||
case _SAMPLE_DONE:
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** The sample is finished processing, but not necessarily finished playing.
|
||||
*/
|
||||
case _SAMPLE_PROCESSED:
|
||||
if (st->DataLength && st->Active) {
|
||||
_SOS_START_SAMPLE start;
|
||||
long dlength;
|
||||
|
||||
dlength = st->DataLength;
|
||||
st->DataLength = 0;
|
||||
|
||||
Audio_Mem_Set(&start, 0, sizeof(start));
|
||||
start.lpSamplePtr = (LPSTR)st->Buffer[st->Index];
|
||||
|
||||
start.dwSampleSize = dlength-1;
|
||||
|
||||
start.wSampleFlags = st->Flags;
|
||||
start.lpCallback = (void cdecl (far *)(unsigned int, unsigned int, unsigned int))&DigiCallback;
|
||||
start.wLoopCount = 0;
|
||||
if (st->IsScore) {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.ScoreVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
} else {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.SoundVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
}
|
||||
|
||||
start.wChannel = st->Stereo;
|
||||
start.wSampleID = index+1;
|
||||
start.dwSamplePitchAdd = st->Pitch;
|
||||
st->Index ^= 1;
|
||||
|
||||
if (st->Remainder || st->QueueBuffer || st->Callback || st->FilePending) {
|
||||
st->Service = TRUE;
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
}
|
||||
|
||||
sosDIGIContinueSample(LockedData.DigiHandle, st->Handle, &start);
|
||||
} else {
|
||||
|
||||
/*
|
||||
** This is necessary because Stop_Sample may screw things
|
||||
** up, otherwise. Can't rely on the _SAMPLE_DONE call.
|
||||
*/
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** Sample is now looping (not used).
|
||||
*/
|
||||
case _SAMPLE_LOOPING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void far HMI_TimerCallback(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ADD_LONG_TO_POINTER -- Adds an offset to a ptr casted void *
|
||||
* *
|
||||
* INPUT: void * ptr - the pointer to add to *
|
||||
* long size - the size to add to it *
|
||||
* *
|
||||
* OUTPUT: void * ptr - the new location it will point to *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size)
|
||||
{
|
||||
return ((void *) ( (char const *) ptr + size));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* AUDIO_MEM_SET -- Quick see routine to set memory to a value *
|
||||
* *
|
||||
* INPUT: void const * - the memory that needs to be set *
|
||||
* unsigned char - the value to set the memory to *
|
||||
* long size - how big an area to set *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/28/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size)
|
||||
{
|
||||
unsigned char *temp = (unsigned char *)ptr;
|
||||
for (int lp = 0; lp < size; lp ++) {
|
||||
*temp++ = value;
|
||||
}
|
||||
}
|
549
WWFLAT32/AUDIO/SOUNDINT.CPP
Normal file
549
WWFLAT32/AUDIO/SOUNDINT.CPP
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 28, 1995 [PWG] *
|
||||
* *
|
||||
* This module contains all of the functions that are used within our *
|
||||
* sound interrupt. They are stored in a seperate module because memory *
|
||||
* around these functions must be locked or they will cause a read to *
|
||||
* be generated while in an interrupt. *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Simple_Copy -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* save_my_regs -- Inline function which will save assembly regs *
|
||||
* restore_my_regs -- Inline function which will restore saved registes *
|
||||
* Audio_Add_Long_To_Pointer -- Adds an offset to a ptr casted void *
|
||||
* Init_Locked_Data -- Initializes sound driver locked data *
|
||||
* Audio_Mem_Set -- Quick see routine to set memory to a value *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
#pragma pack(4)
|
||||
#include "soundint.h"
|
||||
//#include "mem.h"
|
||||
|
||||
/***************************************************************************
|
||||
** All routines past this point must be locked for the sound driver to **
|
||||
** function under a VCPI memory manager. These locks are unnecessary if **
|
||||
** the driver does not have to run under windows or does not use virtual **
|
||||
** memory. **
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* SAVE_MY_REGS -- Inline function which will save assembly regs *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux save_my_regs = \
|
||||
"pushfd" \
|
||||
"pushad" \
|
||||
"push ds" \
|
||||
"push es" \
|
||||
"push fs" \
|
||||
"push gs" \
|
||||
"push ds" \
|
||||
"pop es";
|
||||
|
||||
#pragma aux enable = \
|
||||
"sti";
|
||||
|
||||
#pragma aux disable = \
|
||||
"cli";
|
||||
|
||||
/***************************************************************************
|
||||
* RESTORE_MY_REGS -- Inline function which will restore saved registers *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#pragma aux restore_my_regs = \
|
||||
"pop gs" \
|
||||
"pop fs" \
|
||||
"pop es" \
|
||||
"pop ds" \
|
||||
"popad" \
|
||||
"popfd";
|
||||
|
||||
/***************************************************************************
|
||||
* SIMPLE_COPY -- Copyies 1 or 2 source chuncks to a dest *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size)
|
||||
{
|
||||
|
||||
|
||||
long out = 0; // Number of bytes copied to the destination.
|
||||
|
||||
/*
|
||||
** It could happen that entering this routine, the source buffer
|
||||
** has been exhausted, but the alternate buffer is still valid.
|
||||
** Move the alternate into the primary position before proceeding.
|
||||
*/
|
||||
if (!(*ssize)) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = NULL;
|
||||
*altsize = 0;
|
||||
}
|
||||
|
||||
if (*source && *ssize) {
|
||||
long s; // Scratch length var.
|
||||
|
||||
/*
|
||||
** Copy as much as possible from the primary source, but no
|
||||
** more than the primary source has to offer.
|
||||
*/
|
||||
s = size;
|
||||
if (*ssize < s) s = *ssize;
|
||||
Mem_Copy(*source, *dest, s);
|
||||
*source = Audio_Add_Long_To_Pointer(*source, s);
|
||||
*ssize -= s;
|
||||
*dest = Audio_Add_Long_To_Pointer(*dest, s);
|
||||
size -= s;
|
||||
out += s;
|
||||
|
||||
/*
|
||||
** If the primary source was insufficient to fill the request, then
|
||||
** move the alternate into the primary position and try again.
|
||||
*/
|
||||
if (size) {
|
||||
*source = *alternate;
|
||||
*ssize = *altsize;
|
||||
*alternate = 0;
|
||||
*altsize = 0;
|
||||
out += Simple_Copy(source, ssize, alternate, altsize, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
return(out);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Sample_Copy -- Copies sound data from source format to raw format. *
|
||||
* *
|
||||
* This routine is used to copy the sound data (possibly compressed) to the destination *
|
||||
* buffer in raw format. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the source data (possibly compressed). *
|
||||
* *
|
||||
* dest -- Pointer to the destination buffer. *
|
||||
* *
|
||||
* size -- The size of the destination buffer. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes placed into the output buffer. This is usually *
|
||||
* the number of bytes requested except in the case when the source is exhausted. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/03/1994 JLB : Created. *
|
||||
* 09/04/1994 JLB : Revamped entirely. *
|
||||
*=============================================================================================*/
|
||||
#pragma argsused
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize)
|
||||
{
|
||||
|
||||
long s;
|
||||
long datasize = 0; // Output bytes.
|
||||
|
||||
switch (scomp) {
|
||||
default:
|
||||
|
||||
case SCOMP_NONE:
|
||||
datasize = Simple_Copy(source, ssize, alternate, altsize, &dest, size);
|
||||
break;
|
||||
|
||||
case SCOMP_WESTWOOD:
|
||||
case SCOMP_SOS:
|
||||
while (size > 0) {
|
||||
|
||||
/*
|
||||
** The block spans two buffers. It must be copied down to
|
||||
** a staging area before it can be decompressed.
|
||||
*/
|
||||
{
|
||||
long magic;
|
||||
unsigned short fsize;
|
||||
unsigned short dsize;
|
||||
void *fptr;
|
||||
void *dptr;
|
||||
void *mptr;
|
||||
|
||||
fptr = &fsize;
|
||||
dptr = &dsize;
|
||||
mptr = &magic;
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, sizeof(fsize));
|
||||
if (s < sizeof(fsize)) {
|
||||
return datasize;
|
||||
}
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dptr, sizeof(dsize));
|
||||
if (s < sizeof(dsize) || size < dsize) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &mptr, sizeof(magic));
|
||||
if (s < sizeof(magic) || magic != LockedData.MagicNumber) {
|
||||
return datasize;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the frame and uncompressed data size are identical, then this
|
||||
** indicates that the frame is not compressed. Just copy it directly
|
||||
** to the destination buffer in this case.
|
||||
*/
|
||||
if (fsize == dsize) {
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &dest, fsize);
|
||||
if (s < dsize) {
|
||||
return (datasize);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** The frame was compressed, so copy it to the staging buffer, and then
|
||||
** uncompress it into the final destination buffer.
|
||||
*/
|
||||
fptr = LockedData.UncompBuffer;
|
||||
s = Simple_Copy(source, ssize, alternate, altsize, &fptr, fsize);
|
||||
if (s < fsize) {
|
||||
return (datasize);
|
||||
}
|
||||
if (scomp == SCOMP_WESTWOOD) {
|
||||
Decompress_Frame(LockedData.UncompBuffer, dest, dsize);
|
||||
} else {
|
||||
st->sosinfo.lpSource = (char *)LockedData.UncompBuffer;
|
||||
st->sosinfo.lpDest = (char *)dest;
|
||||
sosCODECDecompressData(&st->sosinfo, dsize);
|
||||
}
|
||||
dest = Audio_Add_Long_To_Pointer(dest, dsize);
|
||||
}
|
||||
datasize += dsize;
|
||||
size -= dsize;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return(datasize);
|
||||
}
|
||||
|
||||
VOID far cdecl maintenance_callback(VOID)
|
||||
{
|
||||
save_my_regs();
|
||||
int index;
|
||||
SampleTrackerType *st;
|
||||
|
||||
if (!LockedData._int && LockedData.DigiHandle != -1 && LockedData.ServiceSomething) {
|
||||
|
||||
LockedData._int++;
|
||||
enable();
|
||||
LockedData.ServiceSomething = FALSE;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
if (st->Active) {
|
||||
|
||||
/*
|
||||
** General service routine to handle moving small blocks from the
|
||||
** source into the low RAM staging buffers. If the source is
|
||||
** compressed, then this will also uncompress it as the copy
|
||||
** is performed.
|
||||
*/
|
||||
if (st->Service) {
|
||||
if (st->DontTouch) {
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
} else {
|
||||
st->Service = FALSE;
|
||||
|
||||
#if(FALSE)
|
||||
st->DataLength = SFX_MINI_STAGE_BUFFER_SIZE;
|
||||
#else
|
||||
st->DataLength = Sample_Copy( st,
|
||||
&st->Source,
|
||||
&st->Remainder,
|
||||
&st->QueueBuffer,
|
||||
&st->QueueSize,
|
||||
st->Buffer[st->Index],
|
||||
SFX_MINI_STAGE_BUFFER_SIZE,
|
||||
st->Compression,
|
||||
&st->Trailer[0],
|
||||
&st->TrailerLen);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** For file streamed samples, fill the queue pointer if needed.
|
||||
** This allows for delays in calling the Sound_Callback function.
|
||||
*/
|
||||
if (!st->DontTouch && !st->QueueBuffer && st->FilePending) {
|
||||
st->QueueBuffer = Audio_Add_Long_To_Pointer(st->FileBuffer, (long)(st->Odd%LockedData.StreamBufferCount)*(long)LockedData.StreamBufferSize);
|
||||
st->FilePending--;
|
||||
st->Odd++;
|
||||
if (!st->FilePending) {
|
||||
st->QueueSize = st->FilePendingSize;
|
||||
} else {
|
||||
st->QueueSize = LockedData.StreamBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** Advance to the next sample control structure.
|
||||
*/
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
|
||||
|
||||
if (!LockedData._int) {
|
||||
|
||||
LockedData._int++;
|
||||
st = &LockedData.SampleTracker[0];
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
|
||||
/*
|
||||
** If there are any samples that require fading, then do so at this
|
||||
** time.
|
||||
*/
|
||||
if (st->Active && st->Reducer && st->Volume) {
|
||||
if (st->Reducer >= st->Volume) {
|
||||
st->Volume = 0;
|
||||
} else {
|
||||
st->Volume -= st->Reducer;
|
||||
}
|
||||
|
||||
if (st->IsScore) {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.ScoreVolume);
|
||||
} else {
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, (st->Volume>>8) * LockedData.SoundVolume);
|
||||
}
|
||||
}
|
||||
st++;
|
||||
}
|
||||
LockedData._int--;
|
||||
}
|
||||
restore_my_regs();
|
||||
}
|
||||
/***********************************************************************************************
|
||||
* DigiCallback -- Low level double buffering handler. *
|
||||
* *
|
||||
* This routine is called in an interrupt to handle the double *
|
||||
* buffering of digital audio. This routine is the interface between *
|
||||
* the buffers maintained by Sound_Callback() and the HMI driver *
|
||||
* itself. *
|
||||
* *
|
||||
* INPUT: driverhandle -- The handle to the HMI driver. *
|
||||
* *
|
||||
* callsource -- Code indicating the reason for the callback. *
|
||||
* *
|
||||
* sampleid -- The ID number of the sample itself. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This is called in an interrupt so it return as quickly as *
|
||||
* possible. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid)
|
||||
{
|
||||
SampleTrackerType *st;
|
||||
int index;
|
||||
|
||||
|
||||
/*
|
||||
** Find the correct control structure for the handle specified.
|
||||
*/
|
||||
for (index = 0; index < LockedData.MaxSamples; index++) {
|
||||
st = &LockedData.SampleTracker[index];
|
||||
if (st->Active && st->Handle == sampleid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == LockedData.MaxSamples) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (driverhandle == LockedData.DigiHandle) {
|
||||
|
||||
switch (callsource) {
|
||||
|
||||
/*
|
||||
** The sample is now no longer audible. Don't stop the sample
|
||||
** tracking if a servicing is needed. If it is needed then
|
||||
** obviously the sample isn't quite done.
|
||||
*/
|
||||
case _SAMPLE_DONE:
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** The sample is finished processing, but not necessarily finished playing.
|
||||
*/
|
||||
case _SAMPLE_PROCESSED:
|
||||
if (st->DataLength && st->Active) {
|
||||
_SOS_START_SAMPLE start;
|
||||
long dlength;
|
||||
|
||||
dlength = st->DataLength;
|
||||
st->DataLength = 0;
|
||||
|
||||
Audio_Mem_Set(&start, 0, sizeof(start));
|
||||
start.lpSamplePtr = (LPSTR)st->Buffer[st->Index];
|
||||
|
||||
start.dwSampleSize = dlength-1;
|
||||
|
||||
start.wSampleFlags = st->Flags;
|
||||
start.lpCallback = (void cdecl (far *)(unsigned int, unsigned int, unsigned int))&DigiCallback;
|
||||
start.wLoopCount = 0;
|
||||
if (st->IsScore) {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.ScoreVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
} else {
|
||||
start.wVolume = (st->Volume>>8) * LockedData.SoundVolume;
|
||||
sosDIGISetSampleVolume(LockedData.DigiHandle, st->Handle, start.wVolume);
|
||||
}
|
||||
|
||||
start.wChannel = st->Stereo;
|
||||
start.wSampleID = index+1;
|
||||
start.dwSamplePitchAdd = st->Pitch;
|
||||
st->Index ^= 1;
|
||||
|
||||
if (st->Remainder || st->QueueBuffer || st->Callback || st->FilePending) {
|
||||
st->Service = TRUE;
|
||||
LockedData.ServiceSomething = TRUE;
|
||||
}
|
||||
|
||||
sosDIGIContinueSample(LockedData.DigiHandle, st->Handle, &start);
|
||||
} else {
|
||||
|
||||
/*
|
||||
** This is necessary because Stop_Sample may screw things
|
||||
** up, otherwise. Can't rely on the _SAMPLE_DONE call.
|
||||
*/
|
||||
st->Active = FALSE;
|
||||
if (!st->IsScore) {
|
||||
// DPMI_Unlock(st->Original, st->OriginalSize);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** Sample is now looping (not used).
|
||||
*/
|
||||
case _SAMPLE_LOOPING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void far HMI_TimerCallback(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ADD_LONG_TO_POINTER -- Adds an offset to a ptr casted void *
|
||||
* *
|
||||
* INPUT: void * ptr - the pointer to add to *
|
||||
* long size - the size to add to it *
|
||||
* *
|
||||
* OUTPUT: void * ptr - the new location it will point to *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size)
|
||||
{
|
||||
return ((void *) ( (char const *) ptr + size));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* AUDIO_MEM_SET -- Quick see routine to set memory to a value *
|
||||
* *
|
||||
* INPUT: void const * - the memory that needs to be set *
|
||||
* unsigned char - the value to set the memory to *
|
||||
* long size - how big an area to set *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/28/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size)
|
||||
{
|
||||
unsigned char *temp = (unsigned char *)ptr;
|
||||
for (int lp = 0; lp < size; lp ++) {
|
||||
*temp++ = value;
|
||||
}
|
||||
}
|
253
WWFLAT32/AUDIO/SOUNDINT.H
Normal file
253
WWFLAT32/AUDIO/SOUNDINT.H
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDINT.H *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 23, 1995 [PWG] *
|
||||
* *
|
||||
* This file is the include file for the Westwood Sound Sytem defines and *
|
||||
* routines that are handled in an interrupt.
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
/*
|
||||
** Defines for true and false. These are included because we do not allow
|
||||
** the sound int to include any of the westwood standard headers. If we
|
||||
** did, there might be too much temptation to call another library function.
|
||||
** this would be bad, because then that function would not be locked.
|
||||
*/
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
** Define the different type of sound compression avaliable to the westwood
|
||||
** library.
|
||||
*/
|
||||
typedef enum {
|
||||
SCOMP_NONE=0, // No compression -- raw data.
|
||||
SCOMP_WESTWOOD=1, // Special sliding window delta compression.
|
||||
SCOMP_SONARC=33, // Sonarc frame compression.
|
||||
SCOMP_SOS=99 // SOS frame compression.
|
||||
} SCompressType;
|
||||
|
||||
/*
|
||||
** This is the safety overrun margin for the sonarc compressed
|
||||
** data frames. This value should be equal the maximum 'order' times
|
||||
** the maximum number of bytes per sample. It should be evenly divisible
|
||||
** by 16 to aid paragraph alignment.
|
||||
*/
|
||||
#define SONARC_MARGIN 32
|
||||
|
||||
|
||||
/*
|
||||
** Define the sample control structure which helps us to handle feeding
|
||||
** data to the sound interrupt.
|
||||
*/
|
||||
#pragma pack(1);
|
||||
typedef struct {
|
||||
/*
|
||||
** This flags whether this sample structure is active or not.
|
||||
*/
|
||||
unsigned Active:1;
|
||||
|
||||
/*
|
||||
** This flags whether the sample is loading or has been started.
|
||||
*/
|
||||
unsigned Loading:1;
|
||||
|
||||
/*
|
||||
** This semaphore ensures that simultaneous update of this structure won't
|
||||
** occur. This is necessary since both interrupt and regular code can modify
|
||||
** this structure.
|
||||
*/
|
||||
unsigned DontTouch:1;
|
||||
|
||||
/*
|
||||
** If this sample is really to be considered a score rather than
|
||||
** a sound effect, then special rules apply. These largely fall into
|
||||
** the area of volume control.
|
||||
*/
|
||||
unsigned IsScore:1;
|
||||
|
||||
/*
|
||||
** This is the original sample pointer. It is used to control the sample based on
|
||||
** pointer rather than handle. The handle method is necessary when more than one
|
||||
** sample could be playing simultaneously. The pointer method is necessary when
|
||||
** the dealing with a sample that may have stopped behind the programmer's back and
|
||||
** this occurance is not otherwise determinable. It is also used in
|
||||
** conjunction with original size to unlock a sample which has been DPMI
|
||||
** locked.
|
||||
*/
|
||||
void const *Original;
|
||||
long OriginalSize;
|
||||
|
||||
/*
|
||||
** These are pointers to the double buffers in low ram.
|
||||
*/
|
||||
VOID *Buffer[2];
|
||||
|
||||
/*
|
||||
** The number of bytes in the buffer that has been filled but is not
|
||||
** yet playing. This value is normally the size of the buffer,
|
||||
** except for the case of the last bit of the sample.
|
||||
*/
|
||||
LONG DataLength;
|
||||
|
||||
/*
|
||||
** This is the buffer index for the low buffer that
|
||||
** has been filled with data but not yet being
|
||||
** played.
|
||||
*/
|
||||
WORD Index;
|
||||
|
||||
/*
|
||||
** Pointer to the sound data that has not yet been copied
|
||||
** to the playback buffers.
|
||||
*/
|
||||
VOID *Source;
|
||||
|
||||
/*
|
||||
** This is the number of bytes remaining in the source data as
|
||||
** pointed to by the "Source" element.
|
||||
*/
|
||||
LONG Remainder;
|
||||
|
||||
/*
|
||||
** Samples maintain a priority which is used to determine
|
||||
** which sounds live or die when the maximum number of
|
||||
** sounds are being played.
|
||||
*/
|
||||
WORD Priority;
|
||||
|
||||
/*
|
||||
** This is the handle as returned by sosDIGIStartSample function.
|
||||
*/
|
||||
WORD Handle;
|
||||
|
||||
/*
|
||||
** This is the current volume of the sample as it is being played.
|
||||
*/
|
||||
WORD Volume;
|
||||
WORD Reducer; // Amount to reduce volume per tick.
|
||||
|
||||
/*
|
||||
** This flags whether the sample is in stereo.
|
||||
*/
|
||||
WORD Stereo;
|
||||
|
||||
/*
|
||||
** This is the compression that the sound data is using.
|
||||
*/
|
||||
SCompressType Compression;
|
||||
WORD TrailerLen; // Number of trailer bytes in buffer.
|
||||
BYTE Trailer[SONARC_MARGIN]; // Maximum number of 'order' samples needed.
|
||||
|
||||
|
||||
DWORD Pitch;
|
||||
WORD Flags;
|
||||
|
||||
/*
|
||||
** This flag indicates whether this sample needs servicing.
|
||||
** Servicing entails filling one of the empty low buffers.
|
||||
*/
|
||||
WORD Service;
|
||||
|
||||
/*
|
||||
** This flag is TRUE when the sample has stopped playing,
|
||||
** BUT there is more data available. The sample must be
|
||||
** restarted upon filling the low buffer.
|
||||
*/
|
||||
BOOL Restart;
|
||||
|
||||
/*
|
||||
** Streaming control handlers.
|
||||
*/
|
||||
BOOL (*Callback)(WORD id, WORD *odd, VOID **buffer, LONG *size);
|
||||
VOID *QueueBuffer; // Pointer to continued sample data.
|
||||
LONG QueueSize; // Size of queue buffer attached.
|
||||
WORD Odd; // Block number tracker (0..StreamBufferCount-1).
|
||||
int FilePending; // Number of buffers already filled ahead.
|
||||
long FilePendingSize; // Number of bytes in last filled buffer.
|
||||
|
||||
/*
|
||||
** The file variables are used when streaming directly off of the
|
||||
** hard drive.
|
||||
*/
|
||||
WORD FileHandle; // Streaming file handle (ERROR = not in use).
|
||||
VOID *FileBuffer; // Temporary streaming buffer (allowed to be freed).
|
||||
/*
|
||||
** The following structure is used if the sample if compressed using
|
||||
** the sos 16 bit compression Codec.
|
||||
*/
|
||||
_SOS_COMPRESS_INFO sosinfo;
|
||||
|
||||
} SampleTrackerType;
|
||||
|
||||
|
||||
typedef struct LockedData {
|
||||
unsigned int DigiHandle; // = -1;
|
||||
BOOL ServiceSomething; // = FALSE;
|
||||
long MagicNumber; // = 0xDEAF;
|
||||
VOID *UncompBuffer; // = NULL;
|
||||
long StreamBufferSize; // = (2*SFX_MINI_STAGE_BUFFER_SIZE)+128;
|
||||
short StreamBufferCount; // = 32;
|
||||
SampleTrackerType SampleTracker[MAX_SFX];
|
||||
unsigned int SoundVolume;
|
||||
unsigned int ScoreVolume;
|
||||
BOOL _int;
|
||||
int MaxSamples;
|
||||
int Rate;
|
||||
} LockedDataType;
|
||||
|
||||
extern LockedDataType LockedData;
|
||||
#pragma pack(4);
|
||||
|
||||
void Init_Locked_Data(void);
|
||||
void Unlock_Locked_Data(void);
|
||||
long Simple_Copy(void ** source, long * ssize, void ** alternate, long * altsize, void **dest, long size);
|
||||
long Sample_Copy(SampleTrackerType *st, void ** source, long * ssize, void ** alternate, long * altsize, void * dest, long size, SCompressType scomp, void * trailer, WORD *trailersize);
|
||||
VOID far cdecl maintenance_callback(VOID);
|
||||
VOID cdecl far DigiCallback(unsigned int driverhandle, unsigned int callsource, unsigned int sampleid);
|
||||
void far HMI_TimerCallback(void);
|
||||
void *Audio_Add_Long_To_Pointer(void const *ptr, long size);
|
||||
void DPMI_Unlock(VOID const *ptr, long const size);
|
||||
extern "C" {
|
||||
void Audio_Mem_Set(void const *ptr, unsigned char value, long size);
|
||||
void Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy);
|
||||
long Decompress_Frame(void * source, void * dest, long size);
|
||||
int Decompress_Frame_Lock(void);
|
||||
int Decompress_Frame_Unlock(void);
|
||||
int sosCODEC_Lock(void);
|
||||
int sosCODEC_Unlock(void);
|
||||
void __GETDS(void);
|
||||
}
|
||||
|
1467
WWFLAT32/AUDIO/SOUNDIO.BAK
Normal file
1467
WWFLAT32/AUDIO/SOUNDIO.BAK
Normal file
File diff suppressed because it is too large
Load Diff
1467
WWFLAT32/AUDIO/SOUNDIO.CPP
Normal file
1467
WWFLAT32/AUDIO/SOUNDIO.CPP
Normal file
File diff suppressed because it is too large
Load Diff
147
WWFLAT32/AUDIO/SOUNDLCK.CPP
Normal file
147
WWFLAT32/AUDIO/SOUNDLCK.CPP
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : SOUNDLCK.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : June 23, 1995 *
|
||||
* *
|
||||
* Last Update : June 23, 1995 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <dos.h>
|
||||
#include <mem.h>
|
||||
#include "soundint.h"
|
||||
#include "wwmem.h"
|
||||
|
||||
LockedDataType LockedData;
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/***************************************************************************
|
||||
* INIT_LOCKED_DATA -- Initializes sound driver locked data *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void Init_Locked_Data(void)
|
||||
{
|
||||
/*
|
||||
** Initialize all of the data elements that need to be locked.
|
||||
*/
|
||||
LockedData.DigiHandle = -1;
|
||||
LockedData.ServiceSomething = FALSE;
|
||||
LockedData.MagicNumber = 0xDEAF;
|
||||
LockedData.UncompBuffer = NULL;
|
||||
LockedData.StreamBufferSize = (2*SFX_MINI_STAGE_BUFFER_SIZE)+128;
|
||||
LockedData.StreamBufferCount = 32;
|
||||
LockedData.SoundVolume = 255;
|
||||
LockedData.ScoreVolume = 255;
|
||||
LockedData._int = FALSE;
|
||||
LockedData.MaxSamples = MAX_SFX;
|
||||
|
||||
/*
|
||||
** Lock the sound specific c functions that will cause us problems if
|
||||
** they are swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Lock(&LockedData, 4096L);
|
||||
DPMI_Lock(Simple_Copy, 4096L);
|
||||
DPMI_Lock(Sample_Copy, 4096L);
|
||||
DPMI_Lock((void *)maintenance_callback, 4096L);
|
||||
DPMI_Lock((void *)DigiCallback, 4096L);
|
||||
DPMI_Lock((void *)HMI_TimerCallback, 4096L);
|
||||
DPMI_Lock(Audio_Add_Long_To_Pointer, 4096L);
|
||||
DPMI_Lock(DPMI_Unlock, 4096L);
|
||||
|
||||
/*
|
||||
** Lock the library functions that will cause us problems if they are
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Lock(Mem_Copy, 4096L);
|
||||
DPMI_Lock(Audio_Mem_Set, 4096L);
|
||||
DPMI_Lock(__GETDS, 4096L);
|
||||
|
||||
/*
|
||||
** Finally lock the two assembly modules that need locking. This can
|
||||
** be handled by calling the lock function that is local to thier module
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
Decompress_Frame_Lock();
|
||||
sosCODEC_Lock();
|
||||
}
|
||||
|
||||
void Unlock_Locked_Data(void)
|
||||
{
|
||||
/*
|
||||
** Lock the sound specific c functions that will cause us problems if
|
||||
** they are swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Unlock(&LockedData, 4096L);
|
||||
DPMI_Unlock(Simple_Copy, 4096L);
|
||||
DPMI_Unlock(Sample_Copy, 4096L);
|
||||
DPMI_Unlock((void *)maintenance_callback, 4096L);
|
||||
DPMI_Unlock((void *)DigiCallback, 4096L);
|
||||
DPMI_Unlock((void *)HMI_TimerCallback, 4096L);
|
||||
DPMI_Unlock(Audio_Add_Long_To_Pointer, 4096L);
|
||||
|
||||
/*
|
||||
** Lock the library functions that will cause us problems if they are
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
DPMI_Unlock(Mem_Copy, 4096L);
|
||||
DPMI_Unlock(Audio_Mem_Set, 4096L);
|
||||
DPMI_Unlock(__GETDS, 4096L);
|
||||
/*
|
||||
** Finally unlock the two assembly modules that need locking. This can
|
||||
** be handled by calling the lock function that is local to thier module
|
||||
** swapped out during an interrupt.
|
||||
*/
|
||||
Decompress_Frame_Unlock();
|
||||
sosCODEC_Unlock();
|
||||
|
||||
/*
|
||||
** As a last step go though all of the sample tracker structures and make
|
||||
** sure all the samples have been properly unlocked.
|
||||
*/
|
||||
for (int id = 0; id < LockedData.MaxSamples; id++) {
|
||||
if (LockedData.SampleTracker[id].Original && !LockedData.SampleTracker[id].IsScore) {
|
||||
DPMI_Unlock(LockedData.SampleTracker[id].Original, LockedData.SampleTracker[id].OriginalSize);
|
||||
LockedData.SampleTracker[id].Original = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user