Initial commit of Command & Conquer Red Alert source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:15:05 +00:00
parent b685cea758
commit 5e733d5dcc
2082 changed files with 797727 additions and 0 deletions

152
WWFLAT32/AUDIO/AUDIO.BAK Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

47
WWFLAT32/AUDIO/FUNCTION.H Normal file
View 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

File diff suppressed because it is too large Load Diff

191
WWFLAT32/AUDIO/MAKEFILE Normal file
View 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
View 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;

View 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

File diff suppressed because it is too large Load Diff

View 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);

File diff suppressed because it is too large Load Diff

191
WWFLAT32/AUDIO/NEW/MAKEFILE Normal file
View 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 ******************************


View 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
View 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

View 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

View 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


View 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


View 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


Binary file not shown.

View 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
View 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


View 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

View 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

View 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);
}

View 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;
}
}

View 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);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

218
WWFLAT32/AUDIO/SOSFNCT.H Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

1467
WWFLAT32/AUDIO/SOUNDIO.CPP Normal file

File diff suppressed because it is too large Load Diff

147
WWFLAT32/AUDIO/SOUNDLCK.CPP Normal file
View 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;
}
}
}

View File

@@ -0,0 +1,113 @@
/*
** 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 : Descriptor management *
* *
* File Name : DESCMGMT.CPP *
* *
* Programmer : Jeff Wilson *
* *
* Start Date : March 28, 1994 *
* *
* Last Update : March 28, 1994 [] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* MAP_SEGMENT_TO_ADDRESS -- Maps a physical address into a selector *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "descmgmt.h"
#include "misc.h"
/***************************************************************************
* MAP_SEGMENT_TO_ADDRESS -- Maps a physical address into a selector *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: selector UWORD The selector mapped to address. exit on error. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 03/25/1994 jaw: Created. *
*=========================================================================*/
ULONG Map_Segment_To_Address(ULONG address, ULONG length)
{
// this function is not longer needed by RATIONAL SYSTEM DOS4GW
// linear addressing mode.
// a> the first megabyte of memory is mapped to linear adress 0 - 0x10000h
// b> all other addresses are linear offset from either ds: or es:
/*
UWORD segment;
UWORD curDS;
CD_DES desc;
CD_DES cur_desc;
// allocate a selector
if(_dos_allocmem(0, &segment) != 0) {
Exit(1, "Allocation of Descriptor.\n");
}
// get the data for this selector
if(_dx_ldt_rd(segment, (UCHAR *)&desc) != 0) {
Exit(1, "Reading Descriptor.\n");
}
// get the data for current data segment
curDS = GetDs();
if(_dx_ldt_rd(curDS, (UCHAR *)&cur_desc) != 0) {
Exit(1, "Reading Descriptor.\n");
}
// set limit
desc.limit0_15 = (USHORT)(length & 0xffff);
desc.limit16_19 = ((UCHAR)(length >> 16L)) | DOS_32;
// set base address
desc.base0_15 = (USHORT)(address & 0xffff);
desc.base16_23 = (UCHAR)((address >> 16) & 0xff);
desc.base24_31 = (UCHAR)((address >> 24) & 0xff);
// set rights mark as icurrent data segment
desc.arights = cur_desc.arights;
// write to LDT selector
if(_dx_ldt_wr(segment, (UCHAR *)&desc) != 0) {
Exit(1, "Failed writing descriptor.\n");
}
// return selector number
return segment;
*/
if ( address & 0xfff0ffff )
Exit ( 1 , "Error mapping real address to lineal address.\n" ) ;
return address ;
}

View File

@@ -0,0 +1,93 @@
/*
** 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 : WWLIB32 library *
* *
* File Name : DESCMGMT.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DESCMGMT_H
#define DESCMGMT_H
#ifndef WWSTD_H
#include "wwstd.h"
#endif
//=====================================================================
// C type include files
#ifdef __cplusplus
extern "C" {
#endif
#include <dos.h>
#include <bios.h>
#ifdef __cplusplus
}
#endif
// ====================================================================
// types
// These where taken from dos.h
//==========================================
// external functions
// ===================================================
extern ULONG Map_Segment_To_Address(ULONG address, ULONG length);
extern "C" {
// Assemble functions
extern UWORD FixSelector(UWORD sel);
extern UWORD GetDs(void);
extern UWORD GetCs(void);
extern VOID GetDefaultSelectors(VOID);
extern UWORD Get_Standard_Selector(void);
// Assembly data variables
extern UWORD CodeSelector;
extern UWORD DataSelector;
extern UWORD ScreenSelector;
extern UWORD GraphicsSelector;
extern UWORD PspSelector;
extern UWORD EnvSelector;
extern UWORD DosMemSelector;
extern UWORD Fp1167Selector;
extern UWORD FpWeitekSelector;
extern UWORD FpCyrixSelector;
}
#endif // DESCMGMT_H


View File

@@ -0,0 +1,94 @@
;
; 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 : Fix a selector *
;* *
;* File Name : FFIXSEL.ASM *
;* *
;* Programmer : Jeff Wilson *
;* *
;* Start Date : March 28, 1994 *
;* *
;* Last Update : March 28, 1994 [] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* FixSelector -- Fix the Priviledge level of a selector *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
EXTRN exit : near
GLOBAL FixSelector :NEAR
;============================================================================
CODESEG
;***************************************************************************
;* FIXSELECTOR -- Fix the Priviledge level of a selector *
;* *
;* *
;* *
;* INPUT: sel the selector to fix-up *
;* *
;* OUTPUT: UWORD The fixed up selector *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 03/28/1994 jaw Created. *
;*=========================================================================*
PROC FixSelector C near
USES ecx,edx
ARG sel:WORD
; Copy the Table Bit and IOPL from the Current CS
; Something is wrong the program should not be here unthe any circunstance
; movzx ecx,[sel]
; xor eax,eax
; mov ax,cs
; and ax,7
; or ax,cx
push 0
call exit
ret
;====================
ENDP FixSelector
END


View File

@@ -0,0 +1,78 @@
;
; 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 : Get the code selector *
;* *
;* File Name : FGETCS.ASM *
;* *
;* Programmer : Jeff Wilson *
;* *
;* Start Date : March 28, 1994 *
;* *
;* Last Update : March 28, 1994 [] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* GetCs -- Return the current Data selector. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL GetCs :NEAR
;============================================================================
CODESEG
;***************************************************************************
;* GETCS -- Return the current Data selector. *
;* *
;* *
;* *
;* INPUT: NONE *
;* *
;* OUTPUT: UWORD selector of the default code segment *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 03/28/1994 jaw: Created. *
;*=========================================================================*
PROC GetCs C near
xor eax,eax
mov ax,cs
ret
;====================
ENDP GetCs
END


View File

@@ -0,0 +1,77 @@
;
; 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 : Get the data selector *
;* *
;* File Name : FGETDS.ASM *
;* *
;* Programmer : Jeff Wilson *
;* *
;* Start Date : March 28, 1994 *
;* *
;* Last Update : March 28, 1994 [] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* GetDs -- Return the current Data selector. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL GetDs :NEAR
;============================================================================
CODESEG
;***************************************************************************
;* GETDS -- Return the current Data selector. *
;* *
;* *
;* *
;* INPUT: NONE *
;* *
;* OUTPUT: UWORD selector of the default data segment *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 03/28/1994 jaw: Created. *
;*=========================================================================*
PROC GetDs C near
xor eax,eax
mov ax,ds
ret
;====================
ENDP GetDs
END


View File

@@ -0,0 +1,118 @@
;
; 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 : Get the Defines selectors *
;* *
;* File Name : FGETSEL.ASM *
;* *
;* Programmer : Jeff Wilson *
;* *
;* Start Date : March 28, 1994 *
;* *
;* Last Update : March 28, 1994 [] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* GetDefaultSelectors -- Return the current default selectors. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL GetDefaultSelectors :NEAR
GLOBAL DataSelector :WORD
GLOBAL ScreenSelector :WORD
GLOBAL GraphicsSelector :WORD
GLOBAL PspSelector :WORD
GLOBAL EnvSelector :WORD
GLOBAL DosMemSelector :WORD
GLOBAL Fp1167Selector :WORD
GLOBAL FpWeitekSelector :WORD
GLOBAL FpCyrixSelector :WORD
GLOBAL CodeSelector :WORD
DATASEG
; It is very important that this section remain untouch
; is not really needed by Rational System but is here to
; keep compatibility with the TNT dos extender.
DataSelector dw 0
ScreenSelector dw 0
GraphicsSelector dw 0
PspSelector dw 0
EnvSelector dw 0
DosMemSelector dw 0
Fp1167Selector dw 0
FpWeitekSelector dw 0
FpCyrixSelector dw 0
CodeSelector dw 0
;============================================================================
CODESEG
;***************************************************************************
;* GetDefaultSelectors -- Setup the defaults selector values to have the *
;* Correct Descriptor table and IOPL. *
;* *
;* *
;* *
;* INPUT: NONE *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 03/28/1994 jaw: Created. *
;*=========================================================================*
PROC GetDefaultSelectors C near
USES eax,esi,ecx
lea edi,[DataSelector]
lea ecx,[CodeSelector]
sub ecx,edi
shr ecx,1
mov ax,ds
rep stosw
mov ax,cs
mov [word ptr CodeSelector] , ax
ret
;====================
ENDP GetDefaultSelectors
END


183
WWFLAT32/DESCMGMT/MAKEFILE Normal file
View File

@@ -0,0 +1,183 @@
#
# 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 24, 1994 *
#* *
#* *
#*-------------------------------------------------------------------------*
#* *
#* 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 *
#* = 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 = descmgmt
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
LIB_PATH = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
descmgmt.obj &
fgetsel.obj &
fgetcs.obj &
fgetds.obj &
ffixsel.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_PATH)\$(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_PATH)\$(PROJ_NAME).lib: $(OBJECTS) objects.lbc
copy *.h $(%WWFLAT)\include
copy *.inc $(%WWFLAT)\include
copy *.cpp $(%WWFLAT)\srcdebug
copy *.asm $(%WWFLAT)\srcdebug
$(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
#---------------------------------------------------------------------------
# Create the test directory and make it.
#---------------------------------------------------------------------------
test:
mkdir test
cd test
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
update
wmake
cd ..
#**************************** End of makefile ******************************

View File

@@ -0,0 +1,277 @@
/*
** 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/>.
*/
/* $Header: g:/library/source/rcs/./dipthong.c 1.15 1994/05/20 15:35:17 joe_bostic Exp $ */
/***************************************************************************
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : DIPTHONG.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : February 23, 1992 *
* *
* Last Update : February 13, 1995 [BWG] *
* *
* DIGRAM or DIATOMIC encoding is the correct term for this method. *
* This is a fixed dictionary digram encoding optimized for English text. *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Extract_String -- Extracts a string pointer from a string data block. *
* UnDip_Text -- Undipthongs a text string into specified buffer. *
* Dip_Text -- Compresses text by using dipthonging. *
* Fixup_Text -- Converts dipthonged foreign text into normal text. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//#include "function.h"
//#include "ems.h"
#include <keyboard.h>
#include "dipthong.h"
/***************************************************************************
* Fixup_Text -- Converts dipthonged foreign text into normal text. *
* *
* Takes text that has been processed (or undipped) to hold foriegn *
* language character pairs (needed for Window_Print) and converts it *
* so that Text_Print will print it properly. Typically this would be *
* used after text has been undipped but before it will be Text_Printed.*
* Text that is to be Window_Printed doesn't and mustn't have its text *
* processed by this routine. *
* *
* INPUT: source -- Pointer to the source string to process. *
* *
* dest -- Destination buffer to hold the processed string. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine will only reduce the size of the string if it *
* modifies it at all. Because of this it is quite legal to *
* pass the same pointers to this routine so that it will *
* modify the string "in place". *
* *
* HISTORY: *
* 08/13/1993 JLB : Created. *
* 10/06/1994 JLB : Handles source string in EMS. *
*=========================================================================*/
void Fixup_Text(char const *source, char *dest)
{
if (source && dest) {
char const *src;
src = source;
while (*src) {
if (*src == KA_EXTEND) {
src++;
*dest++ = (*src++) + 127;
} else {
*dest++ = *src++;
}
}
*dest = '\0';
}
}
/***************************************************************************
* Dip_Text -- Compresses text by using dipthonging. *
* *
* This routine is used to compress text by using dipthonging. Text *
* that is compressed in this fashion usually is reduced in size by *
* approximately 40%. *
* *
* INPUT: source -- Pointer to the source string to compress. *
* *
* dest -- Pointer to the buffer that will hold the dipthong *
* text output. *
* *
* OUTPUT: Returns the number of bytes output into the output buffer. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1993 JLB : Created. *
*=========================================================================*/
int Dip_Text(char const *source, char *dest)
{
unsigned char first, // First character in pair.
next; // Second character in pair.
int len; // Length of output string.
int common, // Common character index.
dipthong; // Dipthong character index.
len = 0; // No output characters YET.
first = *source++;
next = *source;
while (first) {
if (first > 127) {
/*
** Characters greater than 127 cannot be dipthonged. They must
** be preceeded with an extended character code.
*/
*dest++ = KA_EXTEND;
len++;
first -= 127;
} else {
/*
** Normal characters can be dipthonged. First see if there is a
** match in the Common table.
*/
for (common = 0; common < 16; common++) {
if (Common[common] == first) {
/*
** Common character found. See if there is a matching
** Dipthong character.
*/
for (dipthong = 0; dipthong < 8; dipthong++) {
if (Dipthong[common][dipthong] == next) {
first = (unsigned char)(common << 3) | (unsigned char)dipthong | 0x80;
source++;
}
}
}
}
}
/*
** Output the translated character to the destination buffer.
*/
*dest++ = first;
len++;
first = *source++;
next = *source;
}
*dest = '\0';
return(len);
}
/***************************************************************************
* UnDip_Text -- Undipthongs a text string into specified buffer. *
* *
* This routine is used to undipthong a text string and place the *
* undipped text into the buffer specified. Since dipthonged text is *
* compressed, in order for the text to be used it must be undipped *
* first. *
* *
* INPUT: source -- Pointer to the dipped string. *
* *
* dest -- Pointer to the destination buffer. *
* *
* OUTPUT: Returns the number of bytes placed into the destination *
* buffer. *
* *
* WARNINGS: Be sure the destination buffer is big enough to hold the *
* undipped text. *
* *
* HISTORY: *
* 08/13/1993 JLB : Created. *
* 10/06/1994 JLB : Handles source string in EMS. *
*=========================================================================*/
int UnDip_Text(char const *source, char *dest)
{
int c; // Source input character.
int common; // Common character index.
int len; // Length of output string.
char const *src;
len = 0; // Presume no translation.
/*
** Sweep through the source text and dipthong it.
*/
src = source;
c = *src++;
while (c) {
/*
** Convert a dipthong character into it's component
** ASCII characters.
*/
if (c & 0x80) {
c &= 0x7F;
common = (c & 0x78) >> 3;
*dest++ = Common[common];
len++;
c = Dipthong[common][c & 0x07];
}
*dest++ = (unsigned char)c;
len++;
c = *src++;
}
/*
** End the output text with a '\0'.
*/
*dest++ = '\0';
return(len);
}
/***************************************************************************
* Extract_String -- Extracts a string pointer from a string data block. *
* *
* This routine is used to find a pointer to the specified string *
* inside a string block. String data blocks are created with the *
* TEXTMAKE utility. The data block my reside in XMS or EMS memory, *
* but of course the returned string pointer will also point to *
* such memory. In this case, the string must be placed in real *
* memory before it can be used. *
* *
* INPUT: data -- Pointer to the string data block. *
* *
* string -- The string number to extract (if < 0 then NULL *
* is returned). *
* *
* OUTPUT: Returns with pointer to the string number specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1993 JLB : Created. *
* 08/13/1993 JLB : Handles EMS or XMS data pointer. *
*=========================================================================*/
char *Extract_String(void const *data, int string)
{
unsigned short int const *ptr;
unsigned int offset;
if (!data || string < 0) return(NULL);
ptr = (unsigned short int const *)data;
return (((char*)data) + ptr[string]);
}

View File

@@ -0,0 +1,24 @@
/*
** 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/>.
*/
int Dip_Text(char const *source, char *dest);
int UnDip_Text(char const *source, char *dest);
char *Extract_String(void const *data, int string);
void Fixup_Text(char const *source, char *dest);
extern char Common[];
extern char Dipthong[16][8];

193
WWFLAT32/DIPTHONG/MAKEFILE Normal file
View File

@@ -0,0 +1,193 @@
#
# 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 24, 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 = dipthong
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
LIB_DIR = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
dipthong.obj &
_diptabl.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 *.h $(%WWFLAT)\include
copy *.inc $(%WWFLAT)\include
copy *.cpp $(%WWFLAT)\srcdebug
copy *.asm $(%WWFLAT)\srcdebug
$(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
#---------------------------------------------------------------------------
# Create the test directory and make it.
#---------------------------------------------------------------------------
test:
mkdir test
cd test
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
update
mkdir run
cd run
copy $(%WWVCS)\$(PROJ_NAME)\test\run\vcs.cfg
update
cd..
mkdir art
cd art
copy $(%WWVCS)\$(PROJ_NAME)\test\art\vcs.cfg
update
cd..
wmake
cd ..
#**************************** End of makefile ******************************


View File

@@ -0,0 +1,58 @@
/*
** 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/>.
*/
/* $Header: g:/library/source/rcs/./_diptabl.c 1.11 1994/05/20 15:36:04 joe_bostic Exp $ */
/***************************************************************************
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : _DIPTABL.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 3, 1991 *
* *
* Last Update : July 3, 1991 [JLB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
char Common[16]={' ','e','t','a','i','n','o','s','r','l','h','c','d','u','p','m'};
char Dipthong[16][8]={
{'t','a','s','i','o',' ','w','b'},
{' ','r','n','s','d','a','l','m'},
{'h',' ','i','e','o','r','a','s'},
{'n','r','t','l','c',' ','s','y'},
{'n','s','t','c','l','o','e','r'},
{' ','d','t','g','e','s','i','o'},
{'n','r',' ','u','f','m','s','w'},
{' ','t','e','p','.','i','c','a'},
{'e',' ','o','i','a','d','u','r'},
{' ','l','a','e','i','y','o','d'},
{'e','i','a',' ','o','t','r','u'},
{'e','t','o','a','k','h','l','r'},
{' ','e','i','u',',','.','o','a'},
{'n','s','r','c','t','l','a','i'},
{'l','e','o','i','r','a','t','p'},
{'e','a','o','i','p',' ','b','m'},
};


View File

@@ -0,0 +1,39 @@
/*
** 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 : WWLIB32 Example *
* *
* File Name : DEFINES.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define USER_TIMER_FREQ 60

View File

@@ -0,0 +1,40 @@
/*
** 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 : WWLIB32 Example *
* *
* File Name : EXTERNS.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
extern char NoTimer;
extern char NoKeyBoard;

View File

@@ -0,0 +1,50 @@
/*
** 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 : WWLIB32 Example *
* *
* File Name : FUNCTION.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "wwlib32.h"
#include "defines.h"
#include "structs.h"
#include "externs.h"
/*=========================================================================*/
/* The following prototypes are for the file: MAIN.CPP */
/*=========================================================================*/
extern WORD Main_Program(WORD argc, BYTE *argv[]);
/*=========================================================================*/

View File

@@ -0,0 +1,40 @@
/*
** 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 : WWLIB32 Examples *
* *
* File Name : GLOBALS.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
char NoTimer;
char NoKeyBoard;

62
WWFLAT32/EXAMPLE/MAIN.CPP Normal file
View File

@@ -0,0 +1,62 @@
/*
** 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 : libtest *
* *
* File Name : LIBTEST.CPP *
* *
* Programmer : Jeff Wilson *
* *
* Start Date : April 27, 1994 *
* *
* Last Update : May 3, 1994 [BR] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Main_Program -- user-defined main routine, called from startup.c *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
* Main_Program -- user-defined main routine, called from startup.c *
* *
* INPUT: *
* WORD argc *
* UBYTE *argv[] *
* *
* OUTPUT: *
* Returns: TRUE *
* *
* WARNINGS: *
* *
* HISTORY: *
* 05/03/1994 BR : Created. *
*=========================================================================*/
#pragma argsused
WORD Main_Program(WORD argc, BYTE *argv[])
{
return (TRUE);
}
//////////////////////////////////// End of File /////////////////////////////////////

171
WWFLAT32/EXAMPLE/MAKEFILE Normal file
View File

@@ -0,0 +1,171 @@
#
# 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 .EXE makefile *
#* *
#* File Name : MAKEFILE *
#* *
#* Programmer : Julio R. Jerez *
#* *
#* Start Date : Jan 20, 1995 *
#* *
#* Last Update : *
#* *
#*-------------------------------------------------------------------------*
#* *
#* 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 executable program you're building *
#* PROJ_LIBS = Westwood libraries to link your EXE to *
#* OBJECTS = list of objects in your current working directory *
#* *
#* Optional changes to makefile: *
#* PROJ_DIR = full pathname of your working directory *
#* .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 = library name
# PROJ_DIR = directory containing source & objects
#---------------------------------------------------------------------------
PROJ_NAME = TEST
PROJ_DIR = $(%WWFLAT)\example\TEST
LIB_DIR = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
main.obj &
startup.obj &
globals.obj
PROJ_LIBS = &
wwflat32.lib
#---------------------------------------------------------------------------
# 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)
#---------------------------------------------------------------------------
# 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
#---------------------------------------------------------------------------
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
#---------------------------------------------------------------------------
all: $(PROJ_NAME).exe
#---------------------------------------------------------------------------
# Build the EXE
#---------------------------------------------------------------------------
$(PROJ_NAME).exe: $(OBJECTS) $(PROJ_NAME).lnk $(PROJ_LIBS)
$(LINK_CMD) $(LINK_CFG) system dos4g name $^@ @$(PROJ_NAME).lnk
$(PROJ_LIBS):
echo updating base library $^@
cd ..
wmake
cd $(PROJ_DIR)
$(PROJ_NAME).lnk : $(OBJECTS)
%create $^@
for %index in ($(OBJECTS)) do %append $^@ file %index
for %index in ($(PROJ_LIBS)) do %append $^@ library $(LIB_DIR)\%index
#**************************** End of makefile ******************************

View File

@@ -0,0 +1,194 @@
/*
** 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 : Library startup routine. *
* *
* File Name : STARTUP.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : July 14, 1994 *
* *
* Last Update : August 1, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Prog_End -- Called to shutdown Westood's library. *
* main -- Programs main entry point. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include <stdio.h>
#include <stdlib.h>
#define GRAPHICS TRUE
void *ShapeBuffer = NULL;
/***************************************************************************
* MAIN -- Programs main entry point. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 08/01/1994 SKB : Created. *
*=========================================================================*/
#pragma argsused
WORD main(WORD argc, BYTE *argv[])
{
void *fontptr;
/*======================================================================*/
/* Install page fault handle in case of fatal crash. */
/*======================================================================*/
Install_Page_Fault_Handle ();
/*======================================================================*/
/* Setup the monochrome monitor for testing. */
/*======================================================================*/
MonoEnabled = (Find_Argv("-MONO") ? TRUE : FALSE);
Mono_Clear_Screen();
/*======================================================================*/
/* Initialize the file data table. */
/*======================================================================*/
WWDOS_Init(200, NULL, NULL);
/*======================================================================*/
/* Initialize the system font. */
/*======================================================================*/
#if GRAPHICS
fontptr = Load_Font("STD6P.FNT");
if (!fontptr) {
printf("Unable to load font.");
exit(1);
}
Set_Font(fontptr);
#endif
/*======================================================================*/
/* Setup the timer system. */
/*======================================================================*/
if (Find_Argv("-NOTIME")) {
NoTimer = TRUE;
} else {
Init_Timer_System(USER_TIMER_FREQ);
NoTimer = FALSE;
}
/*======================================================================*/
/* Get the initial graphic mode. */
/*======================================================================*/
#if GRAPHICS
if ( Set_Video_Mode(MCGA_MODE) == FALSE )
{
printf("Unable to Set Graphic Mode\n");
exit ( 0 ) ;
}
#endif
/*======================================================================*/
/* Now we get a keyboard handler. */
/*======================================================================*/
if (Find_Argv("-NOKEY")) {
NoKeyBoard = TRUE;
} else {
NoKeyBoard = FALSE;
Install_Keyboard_Interrupt( Get_RM_Keyboard_Address(), Get_RM_Keyboard_Size());
ShapeBuffer = Alloc(5000, MEM_NORMAL);
Set_Shape_Buffer(ShapeBuffer, 5000);
Install_Mouse(20, 20, 320, 200);
}
/*======================================================================*/
/* Give the game some variance. */
/*======================================================================*/
randomize();
/*======================================================================*/
/* Call the user main program. */
/*======================================================================*/
Main_Program(argc, argv);
/*======================================================================*/
/* Exit gracefully. */
/*======================================================================*/
Prog_End();
return(0);
}
/***************************************************************************
* PROG_END -- Called to shutdown Westood's library. *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: exit() should not be called until this has been called *
* *
* HISTORY: *
* 08/01/1994 SKB : Created. *
*=========================================================================*/
VOID Prog_End(VOID)
{
/*======================================================================*/
/* Get rid of the keyboard handler. */
/*======================================================================*/
if (!NoKeyBoard) {
Remove_Mouse();
Free(ShapeBuffer);
Remove_Keyboard_Interrupt();
}
/*======================================================================*/
/* Get rid of the timer system. */
/*======================================================================*/
if (!NoTimer) {
Remove_Timer_System();
}
/*======================================================================*/
/* Restore the Video mode. */
/*======================================================================*/
#if GRAPHICS
Set_Video_Mode(RESET_MODE);
#endif
/*======================================================================*/
/* Close down the file system. */
/*======================================================================*/
WWDOS_Shutdown();
}

View File

@@ -0,0 +1,37 @@
/*
** 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 : WWLIB32 Examples *
* *
* File Name : STRUCTS.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

View File

@@ -0,0 +1,63 @@
/*
** 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 : WWLIB32 User include file *
* *
* File Name : WWLIB32.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : August 3, 1994 *
* *
* Last Update : August 3, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWLIB32_H
#define WWLIB32_H
#include <wwstd.h>
#include <buffer.h>
#include <descmgmt.h>
#include <file.h>
#include <font.h>
#include <gbuffer.h>
#include <vbuffer.h>
#include <iff.h>
#include <filepcx.h>
#include <keyboard.h>
#include <mcgaprim.h>
#include <misc.h>
#include <mono.h>
#include <palette.h>
#include <playcd.h>
#include <shape.h>
#include <timer.h>
#include <video.h>
#include <wsa.h>
#include <wwmem.h>
#endif // WWLIB32_H

165
WWFLAT32/FILE/DEVICES.ASM Normal file
View File

@@ -0,0 +1,165 @@
;
; 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/>.
;
; $Header: g:/library/wwlib32/system/rcs/devices.asm 1.2 1994/04/28 12:41:41 jeff_wilson Exp $
;***************************************************************************
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : LIBRARY *
;* *
;* File Name : DEVICES.ASM *
;* *
;* Programmer : Christopher Yates *
;* *
;* Last Update : 12 December, 1990 [CY] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* *
; VOID Get_Devices(VOID); *
; WORD Is_Device_Real(WORD drive); *
;* *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
;----------------------------------------------------------------------------
IDEAL
P386
MODEL USE32 FLAT
GLOBAL Get_Devices :NEAR
GLOBAL Is_Device_Real :NEAR
GLOBAL MaxDevice :BYTE
GLOBAL DefaultDrive :BYTE
; ----------------------------------------------------------------
;
; Here are prototypes for the routines defined within this module:
;
; VOID Get_Devices(VOID);
; WORD Is_Device_Real(WORD drive);
;
; ----------------------------------------------------------------
CODESEG
;***********************************************************
;
; GET_DEVICES
;
; VOID Get_Devices(VOID);
;
; This routine establishes the default disk drive and the maximum drive
; available in the current system.
;
;*
DOS equ 21h
PROC Get_Devices C near
USES eax,ebx,edx
sub eax,eax
mov ah,25 ; get current drive service
int DOS ; drive returned in al
mov [DefaultDrive],al ; save it
mov dl,al
mov ah,14 ; set current as current drive
int DOS
dec al ; al = max drives, make it n - 1
xor ah,ah ; clear high byte
mov edx,eax ; use dx to go backward to find out
sub ebx,ebx
??back_loop:
mov bl,dl ; find out about the drive in dl
inc bl
mov eax,0440Eh ; get the physical drive associated
int DOS ; with this letter
jnc short ??later ; if c clear, no error
cmp al,0Fh ; was it invalid? (0Fh = invalid)
jne short ??later ; yes, so LATER
dec edx
jmp ??back_loop ; try, try again
??later:
mov eax,edx ; restore ax
mov [MaxDevice],al ; save the max drive #
ret
ENDP Get_Devices
;***************************************************************
;***************************************************************
;
; IS_DEVICE_REAL
;
; WORD Is_Device_Real(WORD drive);
;
; This routine will tell whether or not a device is a true
; phisical one. Send it the drive # to check.
;
;*
PROC Is_Device_Real C near
USES ebx,edx
ARG drive:WORD
sub edx,edx
mov dx,[drive]
??next_drive:
push ebx
mov bl,dl ; find out about the drive in dl
inc bl
mov eax,0440Eh ; get the physical drive associated
int DOS ; with this letter
pop ebx
jnc short ??it_is_real ; jump if no error
cmp al,01 ; 1 = invalid command,
; 0F = invalid device
je short ??real ; 1? it is ok (RAM device)
jmp short ??invalid ; 0Fh, it was not a device
??it_is_real:
cmp al,0 ; was it a fixed device?
je short ??real ; yes, it's ok
dec al ; make it a drive #
cmp al,dl ; is it a valid drive?
je short ??real
??invalid: ; The device is invalid.
mov eax,0
jmp short ??out
??real: ; Return true, for valid device.
mov eax,1
??out:
ret
ENDP Is_Device_Real
;***************************************************************
END


204
WWFLAT32/FILE/DEVTABLE.ASM Normal file
View File

@@ -0,0 +1,204 @@
;
; 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/>.
;
; $Header: g:/library/wwlib32/system/rcs/devtable.asm 1.2 1994/04/28 12:41:29 jeff_wilson Exp $
;***************************************************************************
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : LIBRARY *
;* *
;* File Name : DEVTABLE.ASM *
;* *
;* Programmer : Christopher Yates *
;* *
;* Last Update : 12 December, 1990 [CY] *
;* *
;* Updated to 32bit protected mode JAW *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* *
; VOID Init_Device_Table(BYTE *table); *
; WORD Max_Device(VOID); *
;* *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
LOCALS ??
DOS equ 21h
GLOBAL Max_Device :NEAR
GLOBAL get_max_device :NEAR
GLOBAL Init_Device_Table :NEAR
CODESEG
; ----------------------------------------------------------------
;
; Here are prototypes for the routines defined within this module:
;
; VOID Init_Device_Table(BYTE *table);
; WORD Max_Device(VOID);
;
; ----------------------------------------------------------------
;----------------------------------------------------------------------------
;
; WORD Max_Device(VOID);
;
PROC Max_Device C NEAR
call get_max_device ; get max devices in ax
ret
ENDP Max_Device
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
;
; returns max devices in AX
PROC get_max_device C NEAR
USES ebx,edx
mov ah,25 ; get current drive service
int DOS ; drive returned in al
mov dl,al
mov ah,14 ; set current as current drive
int DOS
dec al ; al = max drives, make it n - 1
xor ah,ah ; clear high byte
sub edx,edx
mov edx,eax ; use dx to go backward to find out
; if DOS is lying (down)
??back_loop:
push ds
push ebx
mov bl,dl ; find out about the drive in dl
inc bl
mov eax,0440Eh ; get the physical drive associated
int DOS ; with this letter
pop ebx
pop ds
jnc short ??later ; if c clear, no error
cmp al,0Fh ; was it invalid? (0Fh = invalid)
jne short ??later ; yes, so LATER
dec edx
jmp ??back_loop ; try, try again
??later:
mov eax,edx ; restore ax
ret
ENDP get_max_device
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
; VOID Init_Device_Table(BYTE *table);
;
PROC Init_Device_Table C NEAR
USES eax,ebx,edi,edx
ARG table:DWORD ; Pointer to device table.
LOCAL curr_drive:BYTE ; Copy of current drive number.
mov edi,[table]
call get_max_device ; get max devices in ax
add edi,eax
std
mov [curr_drive],al ; save it
??next_drive:
mov dl,[curr_drive] ; copy current drive #
cmp dl,0FFh ; are we done?
je short ??later ; if so, later
dec [curr_drive] ; dec our local drive #
push ds
push ebx
mov bl,dl ; find out about the drive in dl
inc bl
mov eax,0440Eh ; get the physical drive associated
int DOS ; with this letter
pop ebx
pop ds
jnc short ??it_is_real ; jump if no error
cmp al,01 ; 1 = invalid command,
; 0F = invalid device
je short ??set_as_current ; 1? it is ok (RAM device)
jmp short ??invalid ; 0Fh, it was not a device
??it_is_real:
cmp al,0 ; was it a fixed device?
je short ??set_as_current ; yes, it's ok
dec al ; make it a drive #
cmp al,dl ; is it a valid drive?
je short ??set_as_current
;
; Device was logical and not active, so clear the entry
;
??invalid:
xor al,al
stosb
cmp [curr_drive],0 ; are we done checking?
jge ??next_drive ; no, go to next
jmp short ??later
??set_as_current:
mov al,1
stosb
cmp dl,0 ; are we before the A drive (invalid)
jl short ??later ; yes, we are done checking
jmp ??next_drive ; keep processing
??later:
cld
ret
ENDP Init_Device_Table
;----------------------------------------------------------------------------
END


238
WWFLAT32/FILE/FFIRST.ASM Normal file
View File

@@ -0,0 +1,238 @@
;
; 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 : First First *
;* *
;* File Name : FFIRST.ASM *
;* *
;* Programmer : Jeff Wilson *
;* *
;* Start Date : March 28, 1994 *
;* *
;* Last Update : April 15, 1994 [] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Find_First -- Find a file spec *
;* Find_Next -- Find next file in sreach params *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
LOCALS ??
GLOBAL Find_First :NEAR
GLOBAL Find_Next :NEAR
;============================================================================
CODESEG
;***************************************************************************
;* FIND_FIRST -- Find a file spec *
;* *
;* *
;* *
;* INPUT: *
;* file_name File spec to find. Maybe a wildcard name *
;* mode File type *
;* ffblk file data block ptr to write info into *
;* *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 04/15/1994 jaw: Created. *
;*=========================================================================*
PROC Find_First C near
USES ebx,ecx,edx,esi,edi,es,ds
ARG file_name:DWORD,mode:WORD,ffblk:DWORD
mov edx,[file_name]
mov cx,[mode]
mov eax,4e00h ;first firstg function
int 21h
;Find it?
jnc ??found_it ;=>yes
; ax holds the error code
;insure high word of eax is clear
or eax,0ffffffffh
jmp ??exit
??found_it:
; found something
;copy the DTA into the user block
mov eax,2f00h ;get DTA address
int 21h
mov ax,es ;switch selectors
mov dx,ds
mov ds,ax
mov es,dx
mov esi,ebx
mov edi,[ffblk]
add esi,21 ;SKIP RESERVED
add edi,4 ;SKIP RESERVED
sub eax,eax
mov al,[esi] ;get attrib byte
mov [es:edi+4],eax
inc esi
;get time
mov ax,[esi]
add esi,2
mov [es:edi+8],ax
;get date
mov ax,[esi]
add esi,2
mov [es:edi+10],ax
;get file size
mov eax,[esi]
add esi,4
mov [es:edi],eax
add edi,12
mov ecx,13
rep movsb ;copy the DTA name
mov ax,es
mov ds,ax
xor eax,eax
??exit:
ret
;====================
ENDP Find_First
;***************************************************************************
;* FIND_NEXT -- Find next file in sreach params *
;* *
;* *
;* *
;* INPUT: *
;* NONE *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 04/15/1994 jaw: Created. *
;*=========================================================================*
PROC Find_Next C near
USES ebx,ecx,edx,esi,edi,ds,es
ARG ffblk:DWORD
mov eax,04f00h ;Find Next function
int 21h
;Find anything?
jnc ??found_it ;=>no
; ax holds the error code
;insure high word of eax is clear
or eax,0ffffffffh
jmp ??exit
??found_it:
; found something
;copy the DTA into the user block
mov eax,2f00h ;get DTA address
int 21h
mov ax,es ;switch selectors
mov dx,ds
mov ds,ax
mov es,dx
mov esi,ebx
mov edi,[ffblk]
add esi,21 ;SKIP RESERVED
add edi,4 ;SKIP RESERVED
sub eax,eax
mov al,[esi] ;get attrib byte
mov [es:edi+4],eax
inc esi
;get time
mov ax,[esi]
add esi,2
mov [es:edi+8],ax
;get date
mov ax,[esi]
add esi,2
mov [es:edi+10],ax
;get file size
mov eax,[esi]
add esi,4
mov [es:edi],eax
add edi,12
mov ecx,13
rep movsb ;copy the DTA name
mov ax,es
mov ds,ax
xor eax,eax
??exit:
ret
ENDP Find_Next
END





41
WWFLAT32/FILE/FGLOB2.CPP Normal file
View File

@@ -0,0 +1,41 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : FILEIO Library *
* *
* File Name : FILEGLOB.C *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : April 11, 1994 *
* *
* Last Update : April 11, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <wwstd.h>
#include "_file.h"
/* Global varaiables */
WORD Hard_Error_Occured=0;

261
WWFLAT32/FILE/FILE.BAK Normal file
View File

@@ -0,0 +1,261 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - Filio header stuff. *
* *
* File Name : FILE.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : April 11, 1994 *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FILE_H
#define FILE_H
#ifndef ERROR
#define ERROR -1
#endif
#ifndef FILETEMP_H
// This should be removed once the library is all intacked.
#include "filetemp.h"
#endif
/*=========================================================================*/
/* File IO system defines and enumerations */
/*=========================================================================*/
#define XMAXPATH 80
/*
** These are the Open_File, Read_File, and Seek_File constants.
*/
#define READ 1 // Read access.
#define WRITE 2 // Write access.
#ifndef SEEK_SET
#define SEEK_SET 0 // Seek from start of file.
#define SEEK_CUR 1 // Seek relative from current location.
#define SEEK_END 2 // Seek from end of file.
#endif
typedef enum {
FILEB_PROCESSED=8,// Was the packed file header of this file processed?
FILEB_PRELOAD, // Scan for and make file resident at WWDOS_Init time?
FILEB_RESIDENT, // Make resident at Open_File time?
FILEB_FLUSH, // Un-resident at Close_File time?
FILEB_PACKED, // Is this file packed?
FILEB_KEEP, // Don't ever flush this resident file?
FILEB_PRIORITY, // Flush this file last?
FILEB_LAST
} FileFlags_Type;
#define FILEF_NONE 0
#define FILEF_PROCESSED (1<<FILEB_PROCESSED)
#define FILEF_PRELOAD (1<<FILEB_PRELOAD)
#define FILEF_RESIDENT (1<<FILEB_RESIDENT)
#define FILEF_FLUSH (1<<FILEB_FLUSH)
#define FILEF_PACKED (1<<FILEB_PACKED)
#define FILEF_KEEP (1<<FILEB_KEEP)
#define FILEF_PRIORITY (1<<FILEB_PRIORITY)
/*
** These errors are returned by WWDOS_Init(). All errors encountered are
** or'd together so there may be more then one error returned. Not all
** errors are fatal, such as the cache errors.
*/
typedef enum {
FI_SUCCESS = 0x00,
FI_CACHE_TOO_BIG = 0x01,
FI_CACHE_ALREADY_INIT = 0x02,
FI_FILEDATA_FILE_NOT_FOUND = 0x04,
FI_FILEDATA_TOO_BIG = 0x08,
FI_SEARCH_PATH_NOT_FOUND = 0x10,
FI_STARTUP_PATH_NOT_FOUND = 0x20,
FI_NO_CACHE_FOR_PRELOAD = 0x40,
FI_FILETABLE_NOT_INIT = 0x80,
} FileInitErrorType;
/*
** These are the errors that are detected by the File I/O system and
** passed to the io error routine.
*/
//lint -strong(AJX,FileErrorType)
typedef enum {
CANT_CREATE_FILE,
BAD_OPEN_MODE,
COULD_NOT_OPEN,
TOO_MANY_FILES,
CLOSING_NON_HANDLE,
READING_NON_HANDLE,
WRITING_NON_HANDLE,
SEEKING_NON_HANDLE,
SEEKING_BAD_OFFSET,
WRITING_RESIDENT,
UNKNOWN_INDEX,
DID_NOT_CLOSE,
FATAL_ERROR,
FILE_NOT_LISTED,
FILE_LENGTH_MISMATCH,
INTERNAL_ERROR,
MAKE_RESIDENT_ZERO_SIZE,
RESIDENT_SORT_FAILURE,
NUMBER_OF_ERRORS /* MAKE SURE THIS IS THE LAST ENTRY */
} FileErrorType;
// This is here tempararaly until library is put together.
//extern WORD cdecl (*cdecl IO_Error)(FileErrorType error, BYTE const *filename);
extern short (*Open_Error)(FileErrorType, BYTE const *);
/*=========================================================================*/
/* File IO system structures */
/*=========================================================================*/
//lint -strong(AJX,FileDataType)
typedef struct {
char *Name; // File name (include sub-directory but not volume).
long Size; // File size (0=indeterminate).
void *Ptr; // Resident file pointer.
long Start; // Starting offset in DOS handle file.
unsigned char Disk; // Disk number location.
unsigned char OpenCount; // Count of open locks on resident file.
unsigned short Flag; // File control flags.
} FileDataType;
/*=========================================================================*/
/* FIle IO system globals. */
/*=========================================================================*/
// These are cpp errors in funtions declarations JULIO JEREZ
// extern FileDataType cdecl FileData[];
// extern BYTE cdecl ExecPath[XMAXPATH + 1];
// extern BYTE cdecl DataPath[XMAXPATH + 1];
// extern BYTE cdecl StartPath[XMAXPATH + 1];
// extern BOOL cdecl UseCD;
// The correct syntax is NO TYPE MODIFIER APPLY TO DATA DECLARATIONS
extern FileDataType FileData[];
extern char ExecPath[XMAXPATH + 1];
extern char DataPath[XMAXPATH + 1];
extern char StartPath[XMAXPATH + 1];
extern BOOL UseCD;
/*=========================================================================*/
/* The following prototypes are for the file: FILEINIT.CPP */
/*=========================================================================*/
void cdecl WWDOS_Shutdown(void);
FileInitErrorType cdecl WWDOS_Init(unsigned long cachesize, char *filedata, char *cdpath);
/*=========================================================================*/
/* The following prototypes are for the file: FILE.CPP */
/*=========================================================================*/
int cdecl Open_File(char const *file_name, short mode);
void cdecl Close_File(short handle);
long cdecl Read_File(short handle, void *buf, unsigned long bytes);
long cdecl Write_File(short handle, void const *buf, unsigned long bytes);
unsigned long cdecl Seek_File(short handle, long offset, short starting);
int cdecl File_Exists(char const *file_name);
unsigned long cdecl File_Size(short handle);
BOOL cdecl Is_Handle_Valid(short handle, FileErrorType error, char const *name);
short cdecl Open_File_With_Recovery( char const *file_name, unsigned short mode );
/*=========================================================================*/
/* The following prototypes are for the file: FILECACH.CPP */
/*=========================================================================*/
void Unfragment_File_Cache(void);
BOOL cdecl Make_File_Resident(char const *filename);
short cdecl Flush_Unused_File_Cache(short flush_keeps);
BOOL cdecl Free_Resident_File(char const *file);
/*=========================================================================*/
/* The following prototypes are for the file: FILECHNG.CPP */
/*=========================================================================*/
short cdecl Create_File(char const *file_name);
short cdecl Delete_File(char const *file_name);
BOOL cdecl Change_File_Size(short handle, unsigned long new_size);
/*=========================================================================*/
/* The following prototypes are for the file: FILEINFO.CPP */
/*=========================================================================*/
short cdecl Get_DOS_Handle(short fh);
short cdecl Free_Handles(void);
short cdecl Find_Disk_Number(char const *file_name);
short cdecl Set_File_Flags(char const *filename, short flags);
short cdecl Clear_File_Flags(char const *filename, short flags);
short cdecl Get_File_Flags(char const *filename);
BOOL cdecl Multi_Drive_Search(BOOL on);
/*=========================================================================*/
/* The following prototypes are for the file: FINDFILE.CPP */
/*=========================================================================*/
short cdecl Find_File(char const *file_name);
short cdecl Find_File_Index(char const *filename);
/*=========================================================================*/
/* The following prototypes are for the file: FFIRST.ASM */
/*=========================================================================*/
#include <dos.h>
#ifdef __cplusplus
extern "C" {
#endif
extern short Find_First(unsigned char *fname, unsigned short mode, struct find_t *ffblk);
extern short Find_Next(struct find_t *ffblk);
#ifdef __cplusplus
}
#endif
#endif // FILE_H


1070
WWFLAT32/FILE/FILE.CPP Normal file

File diff suppressed because it is too large Load Diff

261
WWFLAT32/FILE/FILE.H Normal file
View File

@@ -0,0 +1,261 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - Filio header stuff. *
* *
* File Name : FILE.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : April 11, 1994 *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FILE_H
#define FILE_H
#ifndef ERROR
#define ERROR -1
#endif
#ifndef FILETEMP_H
// This should be removed once the library is all intacked.
#include "filetemp.h"
#endif
/*=========================================================================*/
/* File IO system defines and enumerations */
/*=========================================================================*/
#define XMAXPATH 80
/*
** These are the Open_File, Read_File, and Seek_File constants.
*/
#define READ 1 // Read access.
#define WRITE 2 // Write access.
#ifndef SEEK_SET
#define SEEK_SET 0 // Seek from start of file.
#define SEEK_CUR 1 // Seek relative from current location.
#define SEEK_END 2 // Seek from end of file.
#endif
typedef enum {
FILEB_PROCESSED=8,// Was the packed file header of this file processed?
FILEB_PRELOAD, // Scan for and make file resident at WWDOS_Init time?
FILEB_RESIDENT, // Make resident at Open_File time?
FILEB_FLUSH, // Un-resident at Close_File time?
FILEB_PACKED, // Is this file packed?
FILEB_KEEP, // Don't ever flush this resident file?
FILEB_PRIORITY, // Flush this file last?
FILEB_LAST
} FileFlags_Type;
#define FILEF_NONE 0
#define FILEF_PROCESSED (1<<FILEB_PROCESSED)
#define FILEF_PRELOAD (1<<FILEB_PRELOAD)
#define FILEF_RESIDENT (1<<FILEB_RESIDENT)
#define FILEF_FLUSH (1<<FILEB_FLUSH)
#define FILEF_PACKED (1<<FILEB_PACKED)
#define FILEF_KEEP (1<<FILEB_KEEP)
#define FILEF_PRIORITY (1<<FILEB_PRIORITY)
/*
** These errors are returned by WWDOS_Init(). All errors encountered are
** or'd together so there may be more then one error returned. Not all
** errors are fatal, such as the cache errors.
*/
typedef enum {
FI_SUCCESS = 0x00,
FI_CACHE_TOO_BIG = 0x01,
FI_CACHE_ALREADY_INIT = 0x02,
FI_FILEDATA_FILE_NOT_FOUND = 0x04,
FI_FILEDATA_TOO_BIG = 0x08,
FI_SEARCH_PATH_NOT_FOUND = 0x10,
FI_STARTUP_PATH_NOT_FOUND = 0x20,
FI_NO_CACHE_FOR_PRELOAD = 0x40,
FI_FILETABLE_NOT_INIT = 0x80,
} FileInitErrorType;
/*
** These are the errors that are detected by the File I/O system and
** passed to the io error routine.
*/
//lint -strong(AJX,FileErrorType)
typedef enum {
CANT_CREATE_FILE,
BAD_OPEN_MODE,
COULD_NOT_OPEN,
TOO_MANY_FILES,
CLOSING_NON_HANDLE,
READING_NON_HANDLE,
WRITING_NON_HANDLE,
SEEKING_NON_HANDLE,
SEEKING_BAD_OFFSET,
WRITING_RESIDENT,
UNKNOWN_INDEX,
DID_NOT_CLOSE,
FATAL_ERROR,
FILE_NOT_LISTED,
FILE_LENGTH_MISMATCH,
INTERNAL_ERROR,
MAKE_RESIDENT_ZERO_SIZE,
RESIDENT_SORT_FAILURE,
NUMBER_OF_ERRORS /* MAKE SURE THIS IS THE LAST ENTRY */
} FileErrorType;
// This is here tempararaly until library is put together.
//extern WORD cdecl (*cdecl IO_Error)(FileErrorType error, BYTE const *filename);
extern short (*Open_Error)(FileErrorType, BYTE const *);
/*=========================================================================*/
/* File IO system structures */
/*=========================================================================*/
//lint -strong(AJX,FileDataType)
typedef struct {
char *Name; // File name (include sub-directory but not volume).
long Size; // File size (0=indeterminate).
void *Ptr; // Resident file pointer.
long Start; // Starting offset in DOS handle file.
unsigned char Disk; // Disk number location.
unsigned char OpenCount; // Count of open locks on resident file.
unsigned short Flag; // File control flags.
} FileDataType;
/*=========================================================================*/
/* FIle IO system globals. */
/*=========================================================================*/
// These are cpp errors in funtions declarations JULIO JEREZ
// extern FileDataType cdecl FileData[];
// extern BYTE cdecl ExecPath[XMAXPATH + 1];
// extern BYTE cdecl DataPath[XMAXPATH + 1];
// extern BYTE cdecl StartPath[XMAXPATH + 1];
// extern BOOL cdecl UseCD;
// The correct syntax is NO TYPE MODIFIER APPLY TO DATA DECLARATIONS
extern FileDataType FileData[];
extern char ExecPath[XMAXPATH + 1];
extern char DataPath[XMAXPATH + 1];
extern char StartPath[XMAXPATH + 1];
extern BOOL UseCD;
/*=========================================================================*/
/* The following prototypes are for the file: FILEINIT.CPP */
/*=========================================================================*/
void cdecl WWDOS_Shutdown(void);
FileInitErrorType cdecl WWDOS_Init(unsigned long cachesize, char *filedata, char *cdpath);
/*=========================================================================*/
/* The following prototypes are for the file: FILE.CPP */
/*=========================================================================*/
int cdecl Open_File(char const *file_name, int mode);
void cdecl Close_File(int handle);
long cdecl Read_File(int handle, void *buf, unsigned long bytes);
long cdecl Write_File(int handle, void const *buf, unsigned long bytes);
unsigned long cdecl Seek_File(int handle, long offset, int starting);
int cdecl File_Exists(char const *file_name);
unsigned long cdecl File_Size(int handle);
BOOL cdecl Is_Handle_Valid(int handle, FileErrorType error, char const *name);
int cdecl Open_File_With_Recovery( char const *file_name, unsigned int mode );
/*=========================================================================*/
/* The following prototypes are for the file: FILECACH.CPP */
/*=========================================================================*/
void Unfragment_File_Cache(void);
BOOL cdecl Make_File_Resident(char const *filename);
short cdecl Flush_Unused_File_Cache(short flush_keeps);
BOOL cdecl Free_Resident_File(char const *file);
/*=========================================================================*/
/* The following prototypes are for the file: FILECHNG.CPP */
/*=========================================================================*/
short cdecl Create_File(char const *file_name);
short cdecl Delete_File(char const *file_name);
BOOL cdecl Change_File_Size(short handle, unsigned long new_size);
/*=========================================================================*/
/* The following prototypes are for the file: FILEINFO.CPP */
/*=========================================================================*/
short cdecl Get_DOS_Handle(short fh);
short cdecl Free_Handles(void);
short cdecl Find_Disk_Number(char const *file_name);
short cdecl Set_File_Flags(char const *filename, short flags);
short cdecl Clear_File_Flags(char const *filename, short flags);
short cdecl Get_File_Flags(char const *filename);
BOOL cdecl Multi_Drive_Search(BOOL on);
/*=========================================================================*/
/* The following prototypes are for the file: FINDFILE.CPP */
/*=========================================================================*/
int cdecl Find_File(char const *file_name);
int cdecl Find_File_Index(char const *filename);
/*=========================================================================*/
/* The following prototypes are for the file: FFIRST.ASM */
/*=========================================================================*/
#include <dos.h>
#ifdef __cplusplus
extern "C" {
#endif
extern short Find_First(unsigned char *fname, unsigned short mode, struct find_t *ffblk);
extern short Find_Next(struct find_t *ffblk);
#ifdef __cplusplus
}
#endif
#endif // FILE_H


250
WWFLAT32/FILE/FILECACH.CPP Normal file
View File

@@ -0,0 +1,250 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - File Caching routines *
* *
* File Name : FILECACH.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : April 18, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Make_File_Resident -- Makes a file resident even if not flaged so. *
* Flush_Unused_File_Cache -- Flushes the file cache of any non opened fi*
* Free_Resident_File -- Free the given file if it is resident. *
* Unfragment_File_Cache -- Does a garbage collection on the file heap. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include <wwstd.h>
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#ifndef WWMEM_H
#include <wwmem.h>
#endif
#include <string.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* UNFRAGMENT_FILE_CACHE -- Does a garbage collection on the file heap. *
* *
* INPUT: NONE. *
* *
* OUTPUT: NONE. *
* *
* WARNINGS: Can be a lengthy process. *
* *
* HISTORY: *
* 04/18/1994 SKB : Created. *
*=========================================================================*/
VOID Unfragment_File_Cache(VOID)
{
FileDataType *filedata;
FileDataType *parent;
UWORD idx;
// Let the memory system clean up the file heap.
Mem_Cleanup(FileCacheHeap);
// Now get our pointers back.
// Start after the parent PAK files since we will need to check our pointers
// with them.
filedata = &FileDataPtr[NumPAKFiles];
for (idx = NumPAKFiles; idx < NumPAKFiles; idx++, filedata++) {
while (filedata->Name) {
// Only process files that are in the file cache.
if (filedata->Ptr) {
// Is a inner PAK file?
if (filedata->Flag & FILEF_PACKED) {
parent = &FileDataPtr[filedata->Disk];
// Is it just a copied pointer of the parent?
if (parent->Ptr == filedata->Ptr) {
filedata->Ptr = Mem_Find(FileCacheHeap, filedata->Disk);
}
else
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
}
}
else {
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
}
}
}
// Now that the children have been taken care of, let us do the parents.
for (filedata = FileDataPtr, idx = 0; idx < NumPAKFiles; idx++, filedata++) {
// Only process files that are in the file cache.
if (filedata->Ptr) {
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
}
}
}
/***************************************************************************
* MAKE_FILE_RESIDENT -- Makes a file resident even if not flaged so. *
* *
* INPUT: BYTE *filename - name of file to be made resident. *
* *
* OUTPUT: BOOL if successful. could fail in not enouph RAM or not found. *
* *
* WARNINGS: File must be in FileData table. *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
BOOL Make_File_Resident(BYTE const *filename)
{
FileDataType *filedata; // Pointer to the current FileData.
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
WORD fileindex;
WORD oldflag;
WORD handle;
fileindex = Find_File_Index(filename);
// if the file is not in the table, we can't make it resident
if (fileindex == ERROR) return(FALSE);
// Get a pointer for quicker pointer action.
filedata = &FileDataPtr[fileindex];
// Change the flags for a moment.
oldflag = filedata->Flag;
filedata->Flag |= FILEF_RESIDENT;
filedata->Flag &= ~FILEF_FLUSH;
// Make the file resident.
handle = Open_File(filename, READ);
Close_File(handle);
// Set flags back to normal.
filedata->Flag = oldflag;
return(TRUE);
}
/***************************************************************************
* Flush_Unused_File_Cache -- Flushes the file cache of any non opened files. *
* *
* INPUT: WORD flush_keep - TRUE to flush even files marked FILEF_KEEP.*
* *
* OUTPUT: WORD Number of file flushed. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/23/1993 SB : Created. *
*=========================================================================*/
WORD Flush_Unused_File_Cache(WORD flush_keeps)
{
WORD index;
WORD freed = 0;
FileDataType *filedata = NULL;
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
// Loop throuph the file table looking for files that could be freed.
index = 0;
filedata = &FileDataPtr[index];;
while (filedata->Name && strlen(filedata->Name)) {
if (filedata->Ptr && !filedata->OpenCount &&
(flush_keeps || !(filedata->Flag & FILEF_KEEP)) ) {
Mem_Free(FileCacheHeap, filedata->Ptr);
filedata->Ptr = NULL;
freed++;
}
index++;
filedata = &FileDataPtr[index];;
}
return (freed);
}
/***************************************************************************
* FREE_RESIDENT_FILE -- Free the given file if it is resident. *
* *
* INPUT: BYTE *file to free *
* *
* OUTPUT: TRUE if file was free'd, FALSE otherwise *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/22/1992 CY : Created. *
*=========================================================================*/
BOOL cdecl Free_Resident_File(BYTE const *file)
{
WORD fileindex;
BOOL oldflag; // Previous file flag.
FileDataType *filedata; // Pointer to the current FileData.
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
// if the file is not in the table, we can't free it
if ((fileindex = Find_File_Index(file)) == ERROR) {
return(FALSE);
}
// get a pointer for quicker calculations.
filedata = &FileDataPtr[fileindex];
// If it isn't resident, don't try to Free it
if (filedata->Ptr == NULL) {
return(TRUE);
}
// Change the flags for a moment.
oldflag = filedata->Flag;
filedata->Flag &= ~(FILEF_RESIDENT|FILEF_KEEP);
filedata->Flag |= FILEF_FLUSH;
// Get the file out of Memory if it was there.
Close_File(Open_File(file, READ));
// Set flags back to original.
filedata->Flag = oldflag;
return(TRUE);
}

154
WWFLAT32/FILE/FILECHNG.CPP Normal file
View File

@@ -0,0 +1,154 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - File functions. *
* *
* File Name : FILECHNG.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : September 13, 1993 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Delete_File -- Deletes the file from the disk. *
* Create_File -- Creates an empty file on disk. *
* Change_File_Size -- Change the size of a writting file. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#ifndef WWMEM_H
#include <wwmem.h>
#endif
#include <io.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* CREATE_FILE -- Creates an empty file on disk. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 05/24/1992 JLB : Created. *
*=========================================================================*/
WORD cdecl Create_File(BYTE const *file_name)
{
WORD fd;
if (!file_name) return(FALSE);
fd = Open_File(file_name, WRITE);
if (fd != ERROR) {
Close_File(fd);
return(TRUE);
}
return(FALSE);
}
/***************************************************************************
* DELETE_FILE -- Deletes the file from the disk. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 05/24/1992 JLB : Created. *
*=========================================================================*/
WORD cdecl Delete_File(BYTE const *file_name)
{
WORD index;
FileDataType *filedata; // Pointer to the current FileData.
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
if (!file_name) return(FALSE);
CallingDOSInt++;
ibm_setdisk(*StartPath - 'A');
index = Find_File_Index(file_name);
filedata = &FileDataPtr[index];
if (index != ERROR && filedata->Ptr) {
Mem_Free(FileCacheHeap, filedata->Ptr);
filedata->Ptr = NULL;
}
index = !FILEDELETE(file_name);
CallingDOSInt--;
return(index);
}
/***************************************************************************
* CHANGE_FILE_SIZE -- Change the size of a writting file. *
* *
* INPUT: WORD handle - handle of file. *
* ULONG new_size - size of new handle. *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
BOOL cdecl Change_File_Size(WORD handle, ULONG new_size)
{
WORD entry;
if (Is_Handle_Valid(handle, WRITING_NON_HANDLE, NULL)) {
entry = Get_DOS_Handle(handle);
if (entry != ERROR) {
return(chsize(entry, new_size) != ERROR);
}
}
return(FALSE);
}

View File

@@ -0,0 +1,72 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : File IO System LIbrary *
* *
* File Name : FILEDATA.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : April 11, 1994 *
* *
* Last Update : April 11, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/*
structure for FileDataType is:
BYTE *filename: initialize to actual file name on disk.
LONG size: initialize to actual file size on disk.
BYTE *ptr: initialize to a 0L below.
WORD disk: which floppy disk number (1+) file resides on.
LONG pos: initialize to a 0L below.
UBYTE priority: file priorities can be from 0 to 127. (127 = highest)
if you want the file to be attempted to be made
resident at runtime, add 128 to the file priority
to set the high bit. even though the files
priority will appear to be 128 to 255, it will
still remain 0 to 127.
*/
FileDataType FileData[] = {
{ "", 0L, 0L, 0, 0L, 0 }
/* Must have an empty entry!!! */
};

View File

@@ -0,0 +1,74 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : FILEIO Library *
* *
* File Name : FILEGLOB.C *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : April 11, 1994 *
* *
* Last Update : April 11, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include <wwstd.h>
#endif
#ifndef FILE_H
#include "_file.h"
#endif
#include <process.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/* Global varaiables */
BYTE ExecPath[XMAXPATH + 1];
BYTE DataPath[XMAXPATH + 1];
BYTE StartPath[XMAXPATH + 1];
BOOL UseCD;
/* File System only Global varaiables */
BYTE CallingDOSInt; // Indicate we are performing a DOS function
BYTE MaxDevice,DefaultDrive;
BYTE MultiDriveSearch = TRUE; // Multiple drive search flag
FileDataType *FileDataPtr = NULL;
FileHandleType FileHandleTable[TABLE_MAX];
UWORD NumFiles; // Number of files, except PAK, in file table.
UWORD NumPAKFiles; // Number of PAK files in filetable.
VOID *FileCacheHeap = NULL; // Pointer to the cache in memory.
WORD DiskNumber; // Where file was found (-1 == current directory).
WORD MaxDirNum = 0;
WORD (*Open_Error)(FileErrorType, BYTE const *) = NULL;

276
WWFLAT32/FILE/FILEINFO.CPP Normal file
View File

@@ -0,0 +1,276 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - Fileio information functions. *
* *
* File Name : FILE.CPP *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : April 19, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Get_DOS_Handle -- Fetches system specific DOS file handle. *
* Find_Disk_Number -- Determine disk a file resides upon. *
* Set_File_Flags -- Sets flags for file if FileData table. *
* Get_File_Flags -- Gets the flags on a file in the FileData table. *
* Free_Handles -- Returns number of free file handles in WW system. *
* Multi_Drive_Search -- Turns Multi search drive on and off. *
* Clear_File_Flags -- Clears flags specified for file. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* GET_DOS_HANDLE -- Fetches system specific DOS file handle. *
* *
* This routine will return with the system specific DOS file handle. *
* On the IBM, this is a WORD, on the Amiga, it is a LONG (BPTR). Use *
* this routine with caution, because the value returned is NOT *
* portable. *
* *
* INPUT: fh -- Westwood file system handle. *
* *
* OUTPUT: Returns with the system DOS file handle (WORD or LONG). *
* *
* WARNINGS: If you pass in an invalid file handle, or a file handle *
* that references a resident file, then the ERROR code is *
* returned. Be SURE to check for this. *
* *
* HISTORY: *
* 08/21/1991 JLB : Created. *
* 11/09/1991 JLB : Checks for illegal file handle passed in. *
*=========================================================================*/
WORD cdecl Get_DOS_Handle(WORD fh)
{
/*
** If an illegal file handle is passed in then always abort.
*/
if (fh >= 0 && fh < TABLE_MAX) {
if (!FileHandleTable[fh].Empty || FileHandleTable[fh].Handle) {
return(FileHandleTable[fh].Handle);
}
/*
** If it falls through here, then the file must be resident. It is
** illegal to get a DOS handle to a resident file.
*/
}
return(FILEOPENERROR);
}
/***************************************************************************
* FREE_HANDLES -- Returns number of free file handles in WW system. *
* *
* INPUT: NONE. *
* *
* OUTPUT: NONE. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
WORD cdecl Free_Handles(VOID)
{
WORD count; // Count of the number of free file handles.
WORD index; // Working file handle index var.
count = 0;
for (index = 0; index < TABLE_MAX; index++) {
if (FileHandleTable[index].Empty) count++;
}
return(count);
}
/***************************************************************************
* FIND_DISK_NUMBER -- Determine disk a file resides upon. *
* *
* This routine will determine the disk number that the specified *
* file resides upon. It determines this by scanning through the *
* FileData table. If the specified file is a packed file, then it *
* will reference the parent packed file to determine the disk number. *
* *
* INPUT: file_name -- Pointer to the file name to check. *
* *
* OUTPUT: Returns with the disk number that the file resides upon. If *
* ERROR is returned, then the file does not exist in the *
* FileTable. The number returned is 0=A, 1=B, etc. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/22/1991 JLB : Created. *
*=========================================================================*/
WORD cdecl Find_Disk_Number(BYTE const *file_name)
{
FileDataType *filedata; // Pointer to the current FileData.
WORD index; // FileTable index.
index = Find_File_Index(file_name);
if (index != ERROR) {
filedata = &FileDataPtr[index];
if (filedata->Flag & FILEF_PACKED) {
return (Find_Disk_Number(FileDataPtr[filedata->Disk].Name));
}
return(filedata->Disk);
}
return (index);
}
/***************************************************************************
* SET_FILE_FLAGS -- Sets flags for file if FileData table. *
* *
* INPUT: BYTE *filename - file to modify. *
* WORD flags - flags to set in file. *
* *
* OUTPUT: WORD - if file found in FileData table. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/04/1993 SKB : Created. *
*=========================================================================*/
WORD cdecl Set_File_Flags(BYTE const *filename, WORD flags)
{
FileDataType *filedata; // Pointer to the current FileData.
WORD index; // FileTable index.
index = Find_File_Index(filename);
if (index != ERROR) {
filedata = &FileDataPtr[index];
filedata->Flag |= flags;
return (TRUE);
}
return (FALSE);
}
/***************************************************************************
* CLEAR_FILE_FLAGS -- Clears flags specified for file. *
* *
* INPUT: BYTE *filename - file to modify. *
* WORD flags - flags to set in file. *
* *
* OUTPUT: WORD - if file found in FileData table. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/19/1994 SKB : Created. *
*=========================================================================*/
WORD cdecl Clear_File_Flags(BYTE const *filename, WORD flags)
{
FileDataType *filedata; // Pointer to the current FileData.
WORD index; // FileTable index.
index = Find_File_Index(filename);
if (index != ERROR) {
filedata = &FileDataPtr[index];
filedata->Flag &= ~flags;
return (TRUE);
}
return (FALSE);
}
/***************************************************************************
* GET_FILE_FLAGS -- Gets the flags on a file in the FileData table. *
* *
* *
* INPUT: BYTE *filename - file to modify. *
* *
* OUTPUT: *
* *
* OUTPUT: WORD - if file found in FileData table. *
* *
* HISTORY: *
* 10/04/1993 SKB : Created. *
*=========================================================================*/
WORD cdecl Get_File_Flags(BYTE const *filename)
{
FileDataType *filedata; // Pointer to the current FileData.
WORD index; // FileTable index.
index = Find_File_Index(filename);
if (index != ERROR) {
filedata = &FileDataPtr[index];
return (filedata->Flag);
}
return (FALSE);
}
/***************************************************************************
* MULTI_DRIVE_SEARCH -- Turns Multi search drive on and off. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
BOOL cdecl Multi_Drive_Search(BOOL on)
{
BOOL old;
Hard_Error_Occured = 0;
old = MultiDriveSearch;
MultiDriveSearch = on;
return(old);
}

511
WWFLAT32/FILE/FILEINIT.CPP Normal file
View File

@@ -0,0 +1,511 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Library - Fileio init routines. *
* *
* File Name : FILEINIT.C *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : September 13, 1993 *
* *
* Last Update : April 19, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* WWDOS_Init -- Initialize the fileio WWS fileio system. *
* WWDOS_Shutdown -- Clean up any things that needs to be to exit game. *
* Init_FileData_Table -- Initializes or reads in FileData Table. *
* Sort_FileData_Table -- Sorts the FileData table that is in memory. *
* Preload_Files -- Loads files marked with FILEF_PRELOAD into cache. *
* Init_File_Cache -- Initializes and allocs the file cache heap. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#ifndef WWMEM_H
#include <wwmem.h>
#endif
#ifndef MISC_H
#include <misc.h>
#endif
#include <direct.h>
#include <search.h>
#include <string.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
PRIVATE FileInitErrorType cdecl Init_File_Cache(ULONG cachesize);
PRIVATE FileInitErrorType cdecl Init_FileData_Table(BYTE const *filename);
PRIVATE FileInitErrorType cdecl Set_Search_Drives( BYTE *cdpath );
PRIVATE FileInitErrorType cdecl Preload_Files(VOID);
PRIVATE int QSort_Comp_Func(const void *p1, const void *p2);
PRIVATE VOID Sort_FileData_Table(VOID);
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* WWDOS_INIT -- Initialize the fileio WWS fileio system. *
* *
* *
* INPUT: ULONG cachesize - size wanted for the cache. *
* BYTE *filedat - NULL or name of filedata table file. *
* BYTE *cdpath - NULL or secondary search path on a CD. *
* *
* OUTPUT: Returns all errors encountered or'd together. *
* *
* WARNINGS: User should call the WWDOS_Init function for all file *
* initialization. *
* *
* HISTORY: *
* 04/19/1994 SKB : Created. *
*=========================================================================*/
FileInitErrorType cdecl WWDOS_Init(ULONG cachesize, BYTE *filedata, BYTE *cdpath)
{
// FileInitErrorType errors;
unsigned errors ;
// This has not been completed yet, when it is, uncomment it and add errors.
Install_Hard_Error_Handler () ;
Get_Devices();
if (cachesize) {
errors = Init_File_Cache(cachesize);
} else {
errors = FI_SUCCESS;
}
errors = errors | Init_FileData_Table(filedata);
errors = errors | Set_Search_Drives(cdpath);
errors = errors | Preload_Files();
return ( FileInitErrorType ) errors ;
}
/***************************************************************************
* WWDOS_SHUTDOWN -- Clean up any things that needs to be in file syste to *
* exit game. *
* One could shut down the file system and open it back *
* up with a different size cache or filetable. *
* *
* INPUT: NONE. *
* *
* OUTPUT: NONE. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/19/1994 SKB : Created. *
*=========================================================================*/
VOID cdecl WWDOS_Shutdown(VOID)
{
FileDataType *filedata; // Pointer to the current FileData.
WORD file_handle;
FileHandleType *filehandletable; // Pointer to the current file handle.
// Close all open files.
filehandletable = FileHandleTable;
for (file_handle = 0; file_handle < TABLE_MAX; file_handle++, filehandletable++) {
if (!filehandletable->Empty) {
Close_File(file_handle);
}
}
// Free the file cache heap.
if (FileCacheHeap) {
// Get a pointer to the current filedata.
if (FileDataPtr) {
filedata = FileDataPtr;
} else {
filedata = FileData;
}
while(filedata->Name && filedata->Name[0]) {
filedata->Ptr = NULL;
filedata++;
}
Free(FileCacheHeap);
FileCacheHeap = NULL;
}
// Free up the file data.
if (FileDataPtr != FileData) {
Free(FileDataPtr);
}
FileDataPtr = NULL;
chdir(StartPath);
ibm_setdisk(*StartPath - 'A');
// This has not been completed yet, when it is, uncomment it and add errors.
Remove_Hard_Error_Handler();
}
/***************************************************************************
* INIT_FILE_CACHE -- Initializes and allocs the file cache heap. *
* *
* INPUT: ULONG cachesize - size of heap cache.. *
* *
* OUTPUT: FileInitErrorType error code. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/19/1994 SKB : Created. *
*=========================================================================*/
PRIVATE FileInitErrorType cdecl Init_File_Cache(ULONG cachesize)
{
// Allocate and initialize the file cache heap.
if (FileCacheHeap) {
return (FI_CACHE_ALREADY_INIT);
}
if ((Ram_Free(MEM_NORMAL) >= cachesize)) {
FileCacheHeap = Alloc(cachesize, MEM_NORMAL);
Mem_Init(FileCacheHeap, cachesize);
}
if (!FileCacheHeap) {
return (FI_CACHE_TOO_BIG);
}
return (FI_SUCCESS);
}
/***************************************************************************
* INIT_FILEDATA_TABLE -- Initializes or reads in FileData Table. *
* *
* INPUT: *
* *
* OUTPUT: FileInitErrorType error code. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
PRIVATE FileInitErrorType cdecl Init_FileData_Table(BYTE const *filename)
{
WORD fd;
ULONG fsize;
FileDataType *ptr;
WORD index;
BYTE fname[13];
/*
** Inialize the file handle table to reflect no files open.
*/
for (index = 0; index < TABLE_MAX; index++) {
FileHandleTable[index].Empty = TRUE;
}
// Set up our FileData ptr to be the initial FileData table.
FileDataPtr = FileData;
// Sort the filedata table.
// This needs to be done even if we load it off disk since the initial file data
// table might contain a filename.
Sort_FileData_Table();
// If there is a file name, then the filedata table will be loaded from disk.
if (filename) {
if (!Find_File(filename)) {
return (FI_FILEDATA_FILE_NOT_FOUND);
}
fd = Open_File(filename, READ);
fsize = File_Size(fd);
if ((Ram_Free(MEM_NORMAL) < fsize)) {
Close_File(fd);
return (FI_FILEDATA_TOO_BIG);
}
// Allocate some system memory.
// Setup the new FileDataPtr and this time.
FileDataPtr = ptr = (FileDataType *) Alloc(fsize, MEM_NORMAL);
// Load the file up into memory.
Read_File(fd, FileDataPtr, fsize);
Close_File(fd);
// Process the filetable. The filenames need their pointers adjusted.
// At this time we will also count the number of files and number of PAK files.
NumPAKFiles = NumFiles = 0;
// Make sure that the file name will have a NUL at the end.
fname[12] = 0;
while(TRUE) {
// Have we reached the end of the list?
if (!ptr->Name) break;
// Adjust the name pointer to point the the correct area.
ptr->Name = (BYTE *)FileDataPtr + (LONG) ptr->Name;
// Count up weather it is a PAK file or a normal file.
if (!NumFiles && strstr((char *) ptr->Name, (char *) ".PAK")) {
NumPAKFiles++;
// Mark that it has been processed so that Open_File() will not do it.
ptr->Flag |= FILEF_PROCESSED;
} else {
NumFiles++;
}
// Next record.
ptr++;
}
}
return (FI_SUCCESS);
}
/***************************************************************************
* Set_Search_Drives -- Sets up the CDRom and HardDrive paths. *
* *
* INPUT: BYTE *cdpath - path of data files on a CD. *
* Should pass in NULL for non CD products. *
* *
* OUTPUT: FileInitErrorType error code. *
* Varibable defined: *
* ExecPath = Full path of EXE file. *
* StartPath = Directory user started in. *
* DataPath = secondary search path (typically CD-ROM). *
* Note: format of paths is "C:\PATH" *
* *
* WARNINGS: The cdpath may be overiden by a "-CD<path>" command line *
* arguement that specifies another drive (HARD or CD) and path *
* where the data resides. Whenever a file is opened, it checks *
* the startup drive first, then the CD search path if the first *
* search was unsuccessful. *
* *
* HISTORY: *
* 01/14/1993 SB : Created. *
* 04/19/1994 SKB : Mods for 32 bit library. *
*=========================================================================*/
PRIVATE FileInitErrorType cdecl Set_Search_Drives( BYTE *cdpath )
{
BYTE *ptr;
#if LIB_EXTERNS_RESOLVED
// NOTE: THIS IS WRONG, THIS IS NOT THE WAY TO GET THE EXE's PATH.
// Locate the executable.
strcpy(ExecPath, _argv[0]);
// Find the very last '\' on the path.
ptr = strrchr((char *) ExecPath, (int) '\\');
#else
ptr = NULL;
#endif
// Remove the exe name to just have the path.
if (ptr == NULL) {
*ExecPath = 0;
}
else {
*ptr = 0;
}
// Did the user specify a second path?
ptr = Find_Argv("-CD");
// If so, set the data path to that.
if (ptr) {
strcpy(DataPath, ptr + 3);
}
// Otherwise check to see if there is a CD-Rom drive.
else {
if (cdpath && *cdpath) {
#if LIB_EXTERNS_RESOLVED
UseCD = GetCDDrive();
#else
UseCD = FALSE;
#endif
}
else {
UseCD = FALSE;
}
// If so, set the Drive to it and find out if any directories.
if ( UseCD ) {
strcpy( DataPath, "A:" );
strcat( DataPath, cdpath);
*DataPath = 'A'+UseCD;
}
// If not, set the Data path to the execacutable path.
else {
strcpy(DataPath, ExecPath);
}
}
// Finnally, set the starting path.
getcwd(StartPath, XMAXPATH);
// Make sure they are all uppercase.
strupr(StartPath);
strupr(DataPath);
strupr(ExecPath);
// Change directories to the secondary search path (DataPath).
if (*DataPath && chdir(DataPath)) {
return (FI_SEARCH_PATH_NOT_FOUND);
}
// Lastley, Make sure we are in the startup directory. This will overide
// the secondary data path if they are on the same drive.
if (chdir(StartPath)) {
return (FI_STARTUP_PATH_NOT_FOUND);
}
return (FI_SUCCESS);
}
/***************************************************************************
* PRELOAD_FILES -- Loads files marked with FILEF_PRELOAD into cache. *
* *
* *
* INPUT: none. *
* *
* OUTPUT: FileInitErrorType error code. *
* *
* WARNINGS: The FileData must be initialized and the file heap initialized*
* in order for this to work. *
* *
* HISTORY: *
* 04/19/1994 SKB : Created. *
*=========================================================================*/
PRIVATE FileInitErrorType cdecl Preload_Files(VOID)
{
FileDataType *filedata; // Working file data table pointer.
BOOL oldflag; // Previous file flag.
if (!FileDataPtr) {
return (FI_FILETABLE_NOT_INIT);
}
if (!FileCacheHeap) {
return (FI_NO_CACHE_FOR_PRELOAD);
}
/*
** Make all files flagged to be made resident at startup, resident.
*/
filedata = FileDataPtr;
while (filedata->Name && strlen(filedata->Name)) {
if (filedata->Flag & FILEF_PRELOAD) {
oldflag = filedata->Flag;
filedata->Flag |= FILEF_RESIDENT; // Make it resident.
filedata->Flag &= ~FILEF_FLUSH; // Don't purge on Close_File.
Close_File(Open_File(filedata->Name, READ));
filedata->Flag &= ~(FILEF_RESIDENT|FILEF_FLUSH); // Clear bits.
filedata->Flag |= oldflag & (FILEF_RESIDENT|FILEF_FLUSH); // Restore bits.
}
filedata++;
}
return (FI_SUCCESS);
}
/***************************************************************************
* SORT_FILEDATA_TABLE -- Sorts the FileData table that is in memory. *
* *
* INPUT: NONE *
* *
* OUTPUT: NONE. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 09/13/1993 SKB : Created. *
*=========================================================================*/
PRIVATE int QSort_Comp_Func(const void *p1, const void *p2)
{
return(strcmp(((FileDataType*)p1)->Name, ((FileDataType*)p2)->Name));
}
PRIVATE VOID Sort_FileData_Table(VOID)
{
/*
** Sort the filetable it but keep the pack file indexes correct.
*/
/*
** The number of pak files in the file table.
*/
NumPAKFiles = 0;
strupr(FileData[NumPAKFiles].Name);
while (strstr((char *) FileData[NumPAKFiles].Name, (char *) ".PAK")) {
strupr(FileData[NumPAKFiles].Name);
NumPAKFiles++;
}
/*
** Count the remaining files within the file table.
*/
NumFiles = 0;
while(FileData[NumFiles+NumPAKFiles].Name && FileData[NumFiles+NumPAKFiles].Name[0]) {
strupr(FileData[NumFiles+NumPAKFiles].Name);
NumFiles++;
}
/*
** Sort the file entries (past the pak files).
*/
if (NumFiles) {
qsort(&FileData[NumPAKFiles], NumFiles, sizeof(FileDataType), QSort_Comp_Func);
}
}


151
WWFLAT32/FILE/FILEIO.CPP Normal file
View File

@@ -0,0 +1,151 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : FILEIO.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 21, 1991 *
* *
* Last Update : September 13, 1993 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#include <dos.h>
#include <direct.h>
#include <io.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
WORD ibm_getdisk(VOID)
{
unsigned disk;
CallingDOSInt++;
// disk = getdisk();
_dos_getdrive ( & disk ) ;
CallingDOSInt--;
return(disk-1);
}
WORD ibm_setdisk(WORD drive)
{
// WORD disk;
unsigned disk ;
CallingDOSInt++;
// disk = setdisk(drive);
_dos_setdrive ( drive+1 , & disk ) ;
CallingDOSInt--;
return(disk);
}
WORD ibm_close(WORD handle)
{
WORD success;
CallingDOSInt++;
success = close(handle);
CallingDOSInt--;
return(success);
}
WORD ibm_unlink(BYTE const *name)
{
WORD success;
CallingDOSInt++;
success = unlink(name);
CallingDOSInt--;
return(success);
}
LONG ibm_lseek(WORD handle, LONG offset, WORD where)
{
LONG new_offset;
CallingDOSInt++;
new_offset = lseek(handle, offset, where);
CallingDOSInt--;
return(new_offset);
}
UWORD ibm_read(WORD handle, VOID *ptr, UWORD bytes)
{
UWORD bytes_read;
CallingDOSInt++;
bytes_read = read(handle, ptr, bytes);
CallingDOSInt--;
return(bytes_read);
}
UWORD ibm_write(WORD handle, VOID *ptr, UWORD bytes)
{
UWORD bytes_written;
CallingDOSInt++;
bytes_written = write(handle, ptr, bytes);
CallingDOSInt--;
return(bytes_written);
}
WORD ibm_open(BYTE const *name, UWORD mode, WORD attrib)
{
WORD handle;
CallingDOSInt++;
handle = open(name, mode, attrib);
CallingDOSInt--;
return(handle);
}
WORD ibm_chdir(BYTE const *path)
{
WORD retval;
CallingDOSInt++;
retval = chdir(path);
CallingDOSInt--;
return(retval);
}


388
WWFLAT32/FILE/FILELIB.CPP Normal file
View File

@@ -0,0 +1,388 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : FILEIO Library support routines. *
* *
* File Name : FILELIB.C *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : April 11, 1994 *
* *
* Last Update : April 11, 1994 [SKB] *
* *
* *
* *
*-------------------------------------------------------------------------*
* Notes: This file contains private functions to the fileio system. *
* While these functions may be used by any module in the fileio *
* system, they cannot be used by a user program. For this reason *
* they are put into this module. *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Cache_File -- Attempts to cache file in XMS if flags set. *
* Do_IO_Error -- Performs a non-recoverable error message display. *
* Do_Open_Error -- Does an error message that could return. *
* Is_Handle_Valid -- Determines validity of the specified file handle. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#ifndef WWMEM_H
#include <wwmem.h>
#endif
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <sys\stat.h>
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
/***************************************************************************
* DO_ERROR -- Does an error message that could return. *
* *
* This routine displays a file error message and unless the player *
* presses <ESC>, it will return. If the player presses <ESC>, then *
* it will terminate the program. *
* *
* INPUT: error -- Error message number. *
* *
* filename -- File name that the error occured on. *
* *
* OUTPUT: TRUE/FALSE; Should the process be repeated? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/09/1991 JLB : Created. *
*=========================================================================*/
#pragma argsused
WORD cdecl Do_Open_Error(FileErrorType errormsgnum, BYTE const *file_name)
{
BYTE *ptr=NULL; // Working file name pointer (just name and extension).
/*
** Since the file name may include a path, we must extract the true
** file name from the given string.
*/
if (file_name) {
#if LIB_EXTERNS_RESOLVED
ptr = strrchr((char *) file_name, (int) '\\');
#else
ptr = NULL;
#endif
if (ptr) {
ptr++;
} else {
ptr = (BYTE *) file_name;
}
}
#if LIB_EXTERNS_RESOLVED
strupr(ptr);
return (IO_Error(errormsgnum, ptr));
#else
return(0);
#endif
}
/***************************************************************************
* DO_IO_ERROR -- Performs a non-recoverable error message display. *
* *
* This routine will perform a non-recoverable file error message *
* display. It is called when an error is detected that has no *
* recovery or retry process defined. *
* *
* INPUT: errornum -- Error number detected. *
* *
* filename -- Name of the file that caused the error. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/09/1991 JLB : Created. *
*=========================================================================*/
#pragma argsused
VOID cdecl Do_IO_Error(FileErrorType errormsgnum, BYTE const *filename)
{
#if LIB_EXTERNS_RESOLVED
(VOID)IO_Error(errormsgnum, filename);
#endif
#if(TRUE)
Prog_End();
exit((int)errormsgnum);
#else
Program_End();
#endif
}
/***************************************************************************
* Read_File_With_Recovery -- read the same file on another directory if an error *
* occurs. *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/16/1993 QY : Created. *
*=========================================================================*/
LONG cdecl Read_File_With_Recovery( WORD handle, VOID *buf, UWORD bytes )
{
WORD newhandle;
LONG bytes_read;
do {
Hard_Error_Occured = 0;
// Make sure we are in the right path.
CHANGEDIR( DataPath );
// open the same file
newhandle = Open_File( FileHandleTable[ handle ].Name, FileHandleTable[ handle ].Mode );
Seek_File( newhandle, FileHandleTable[ handle ].Pos, SEEK_SET );
// dos close the old file
FILECLOSE( FileHandleTable[ handle ].Handle );
// copy FileHandleTable[ newhandle ] to FileHandleTable[ handle ]
Mem_Copy( &FileHandleTable[ newhandle ], &FileHandleTable[ handle ],
( ULONG ) sizeof( FileHandleTable[ newhandle ] ) );
// delete FileHandleTable[newhandle]
FileHandleTable[ newhandle ].Empty = TRUE;
// continue reading file
bytes_read = ( LONG ) FILEREAD( FileHandleTable[ handle ].Handle, buf, bytes );
// if still error, do it again; else return the number of bytes read
if ( !Hard_Error_Occured ) {
return( bytes_read );
}
if (!Do_Open_Error(COULD_NOT_OPEN, FileHandleTable[ handle ].Name)) {
return(FALSE);
}
} while (CHANGEDIR( DataPath ));
return (NULL);
}
/***************************************************************************
* Open_File_With_Recovery -- open the same file on another directory *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 02/16/1993 QY : Created. *
*=========================================================================*/
WORD cdecl Open_File_With_Recovery( BYTE const *file_name, UWORD mode )
{
WORD handle;
Hard_Error_Occured = FALSE;
handle = FILEOPEN(file_name, mode);
// Do not return if there was a HardError and Using a CD and we are looking at
// the CD.
if (!Hard_Error_Occured || !UseCD || (ibm_getdisk() != (*DataPath - 'A'))) {
return (handle);
}
#if DEBUGPRINT
Mono_Print(file_name); Mono_Print(":OPENERROR ");
#endif
Hard_Error_Occured = 0;
// It is possible that the CD has been poped out and put back in, let us
// change there and then try again.
ibm_setdisk(*DataPath - 'A');
CHANGEDIR( DataPath );
// open the same file
handle = FILEOPEN( file_name, mode );
// if still error, do it again; else return the dos handle
if ( !Hard_Error_Occured ) {
return( handle );
}
Hard_Error_Occured = 0;
return (FILEOPENERROR);
}
/***************************************************************************
* CACHE_FILE -- Attempts to cache file in XMS if flags set. *
* *
* *
* INPUT: WORD index - the index of the file in the FileData table. *
* WORD file_handle - WWS file handle of file. *
* *
* OUTPUT: BOOL : was it cached? *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1993 SKB : Created. *
*=========================================================================*/
BOOL cdecl Cache_File(WORD index, WORD file_handle)
{
LONG filesize; // Size of the memory block needed.
LONG freecache; // Amount of free XMS.
FileDataType *filedata = NULL;
FileDataType hold;
FileHandleType *filehandletable;
WORD flag; // Type of system memory to cache file.
WORD file;
// Only files in the file table can be cached.
if (index == ERROR) {
return FALSE;
}
// Setup our pointer to the file we may want to cache.
filedata = &FileDataPtr[index];
// Should this be cached, and is it not yet cached?
if ((filedata->Flag & (FILEF_RESIDENT|FILEF_PRELOAD)) && !filedata->Ptr) {
filesize = filedata->Size;
/*
** If there is o room to cache the file, then turn off its cache file.
*/
if (filesize > Mem_Pool_Size(FileCacheHeap)) {
// Remove resident flags so that it will not keep trying to cache itself
// since there will never be enough room for it.
filedata->Flag &= ~(FILEF_PRELOAD|FILEF_KEEP|FILEF_RESIDENT|FILEF_FLUSH);
return FALSE;
}
// Go through freeing files until there is enouph space in the
// memory pool.
while (filesize > Mem_Avail(FileCacheHeap)) {
VOID *node;
// Get the oldest non used file pointer.
node = Mem_Find_Oldest(FileCacheHeap);
// If non was found, sorry no room for the new file.
if (!node) {
return (FALSE);
}
// Get a pointer to the structure for convenience.
filedata = &FileDataPtr[Mem_Get_ID(node)];
// Free it from the heap and update the file system so it knows that
// the file is no longer in memory.
Mem_Free(FileCacheHeap, filedata->Ptr);
filedata->Ptr = NULL;
}
// If there is not a big enough space we will have to take garbage
// collection hit. (OUCH!!!!!!)
if (filesize > Mem_Largest_Avail(FileCacheHeap)) {
Unfragment_File_Cache();
}
// Make sure we have a big enough space and if so, put the file into memory.
if (filesize < Mem_Largest_Avail(FileCacheHeap)) {
// Get some pointers to save code space and time.
filehandletable = &FileHandleTable[file_handle];
filedata = &FileDataPtr[index];
// Alloc the buffer in our file cache, then read the file in.
filedata->Ptr = Mem_Alloc(FileCacheHeap, filesize, index);
// Extra check - it should not fail.
if (!filedata->Ptr) return(FALSE);
// Mark it so that it never comes back as Oldest used.
Mem_In_Use(filedata->Ptr);
// Get the file into memory.
Read_File(file_handle, filedata->Ptr, filesize);
// reset the read index from the above read.
filehandletable->Pos = 0L;
// This makes caching inner pak file possible. No longer is the
// PAK'd file based off the parent file.
filehandletable->Start = 0;
// Close the parent file. Remove it's open count.
if (filedata->Flag & FILEF_PACKED) {
FileDataType p_hold;
FileDataType *parent;
parent = &FileDataPtr[filedata->Disk];
parent->OpenCount--;
}
FILECLOSE(filehandletable->Handle);
filehandletable->Handle = 0;
return (TRUE);
}
}
// The file was not cached, let the caller know.
return (FALSE);
}

View File

@@ -0,0 +1,41 @@
/*
** 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 : wwlib32 *
* *
* File Name : FILESTUB.CPP *
* *
* Programmer : Bill Randolph *
* *
* Start Date : May 3, 1994 *
* *
* Last Update : May 3, 1994 [BR] *
* *
* This module is a temorary stub that contains IO_Error. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "wwstd.h"
#include "file.h"
WORD Text_IO_Error(FileErrorType, BYTE const *){return FALSE;}
WORD (*IO_Error)(FileErrorType, BYTE const *) = Text_IO_Error;
/************************* End of filestub.cpp *****************************/

60
WWFLAT32/FILE/FILETEMP.H Normal file
View File

@@ -0,0 +1,60 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Temp header for file routines. *
* *
* File Name : FILETEMP.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : April 20, 1994 *
* *
* Last Update : April 20, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FILETEMP_H
#define FILETEMP_H
/////////////////////////////////////////////////////////////////////
// THIS DOES NOT BELONG HERE. IT WAS PUT HERE JUST TO GET THE THING
// TO COMPILE. ONCE THE BUFFER AND PAGE SYSTEMS ARE PUT IN, THESE
// WILL NEED TO BE TAKEN OUT AND MODS MADE TO ANY FUNCTION USING BuffType.
// SKB 4/20/94.
/*=========================================================================*/
/* Defines and such that must go into wwstd.h */
/*=========================================================================*/
// Look at FileErrorType below for the IO_Error function.
//extern WORD cdecl (*cdecl IO_Error)(FileErrorType error, BYTE const *filename);
VOID cdecl Prog_End(VOID);
extern WORD Hard_Error_Occured;
//////////////////////// END OF DON'T BELONG //////////////////////////////////
#endif //FILETEMP_H

312
WWFLAT32/FILE/FINDFILE.BAK Normal file
View File

@@ -0,0 +1,312 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : FINDFILE.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 21, 1991 *
* *
* Last Update : September 29, 1993 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Find_File_Index -- Finds the FileTable index number for a given file. *
* Find_File -- Checks if a file is immediatly available. *
* Get_FileData -- Gets a pointer back to the correct file. *
* Find_File -- Checks if a file is immediatly available. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#include <direct.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <search.h>
#include <sys\stat.h>
/***************************************************************************
* FIND_FILE -- Checks if a file is immediatly available. *
* *
* Use this function to determine if a file is immediatly available. *
* This routine will NOT request for the proper disk to be inserted *
* if the file could not be found. Use File_Exists for that feature. *
* The Westwood file I/O system does NOT have to be initialized as *
* a prerequisit to using this function. *
* *
* INPUT: file_name -- Name of the file to check. *
* *
* OUTPUT: Returns the disk number that the file exits on (A=1, B=2, etc) *
* *
* WARNINGS: This sets the current drive to the drive that contains the *
* specified file (if it is found). *
* *
* HISTORY: *
* 11/14/1991 JLB : Created. *
* 03/14/1992 JLB : Modified for Amiga compatability. *
* 01/11/1993 SKB : Modified for CD-ROM searches. *
*=========================================================================*/
int cdecl Find_File(char const *file_name)
{
FileDataType *filedata = NULL;
WORD index; // File index (if any).
WORD disk; // Disk number of file (if in filetable).
/*
** If the filename is invalid then it errors out as if the file wasn't
** found (naturally).
*/
if (!file_name) return(FALSE);
/*
** Determine if the file has a file table entry. If it does, then
** special checks and processing must occur.
** Also, if it is in memory, return with it.
*/
index = Find_File_Index(file_name);
filedata = &FileDataPtr[index];
if (index != ERROR) {
// If the file is currently cached, return TRUE that it was found.
if (filedata->Ptr) {
return (TRUE);
}
}
/*
** Always check the current directory for the file. Only if it can't
** be found are furthur measures required.
*/
DiskNumber = ERROR; // This indicates file exists in current directory.
#if (LIB_CDROM)
ibm_setdisk(*StartPath - 'A');
#endif
/*
** Check the current directory by attempting to open with READ access.
*/
{
WORD handle;
CallingDOSInt++;
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
CallingDOSInt--;
if (handle != ERROR)
{
// WORD d;
unsigned d ;
CallingDOSInt++;
close(handle);
// d = getdisk();
_dos_getdrive ( & d) ;
CallingDOSInt--;
return(d);
}
}
if (index != ERROR) {
disk = filedata->Disk;
/*
** If the file is in a packed file, then search for the packed file
** instead of the specified one.
*/
if (index != ERROR && (filedata->Flag & FILEF_PACKED)) {
filedata = &FileDataPtr[disk];
return (Find_File(filedata->Name));
}
}
/*
** It could not be found on the current drive, so search the other
** drives if allowed to do so.
*/
if (!MultiDriveSearch) {
return(FALSE);
}
#if (LIB_CDROM)
// If we were unable to find the file on the hard drive, change
// drives to the CD rom drive and see if it is there.
ibm_setdisk(*DataPath - 'A');
{
WORD handle;
Hard_Error_Occured = 0;
handle = Open_File_With_Recovery( file_name, MODE_OLDFILE );
if (handle != FILEOPENERROR) {
FILECLOSE(handle);
return(ibm_getdisk() + 1);
}
}
ibm_setdisk(*StartPath - 'A');
return (FALSE);
#else
{
WORD start_drive; // Original current drive number.
/*
** Record the current drive for restoring later in case of failure.
*/
CallingDOSInt++;
start_drive = getdisk();
CallingDOSInt--;
/*
** Sweep backward from the last real drive to the first, looking for the
** file on each in turn.
*/
for (index = MaxDevice; index != -1; index--) {
if (Is_Device_Real(index)) {
CallingDOSInt++;
setdisk(index);
CallingDOSInt--;
{
WORD handle;
CallingDOSInt++;
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
CallingDOSInt--;
if (handle != ERROR) {
CallingDOSInt++;
close(handle);
CallingDOSInt--;
DiskNumber = index+1;
return (DiskNumber);
}
}
}
}
CallingDOSInt++;
setdisk(start_drive);
CallingDOSInt--;
}
return(FALSE);
#endif
}
/***************************************************************************
* FIND_FILE_INDEX -- Finds the FileTable index number for a given file. *
* *
* This function searches the FileTable and returns with the index of *
* the matching file. If the file doesn't exist in the table, then *
* ERROR is returned. It does not care about case. *
* *
* INPUT: filename -- Pointer to the filename to check. *
* *
* OUTPUT: Returns with the index into the FileTable. If the file does *
* not exist in the file table, then ERROR is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/09/1991 JLB : Created. *
* 06/11/1993 JLB : Sorts and binary searches the file table. *
*=========================================================================*/
PRIVATE int Comp_Func(const void *p1, const void *p2)
{
return(strcmp((char *) ((FileDataType*)p1)->Name, (char *) ((FileDataType*)p2)->Name));
}
WORD cdecl Find_File_Index(BYTE const *filename)
{
FileDataType *filedata; // File entry pointer.
FileDataType key; // Working file data type var.
/*
** Perform a binary search on the presorted filetable.
*/
if (filename) {
filedata = NULL;
key.Name = (BYTE *) strupr((char *)filename);
if (strstr((char *)key.Name, (char *)".PAK")) {
/*
** If the FileData table was not loaded from the disk then the PAK files are
** not sorted so Perform a linear search for the pak files.
** Otherwise the files are sorted so speed things up by doing a bsearch.
*/
if (FileData == FileDataPtr) {
filedata = (FileDataType *) lfind(&key, FileDataPtr, (size_t *) &NumPAKFiles, sizeof(FileDataType), Comp_Func);
}
else {
filedata = (FileDataType *)bsearch(&key, FileDataPtr, NumPAKFiles, sizeof(FileDataType), Comp_Func);
}
} else {
/*
** Perform a binary search for the regular files.
*/
filedata = (FileDataType *)bsearch(&key, &FileDataPtr[NumPAKFiles], NumFiles, sizeof(FileDataType), Comp_Func);
}
// Return the element in the array if file was found in table.
if (filedata) {
return (filedata - FileDataPtr);
//return ((WORD)((((LONG)filedata) - ((LONG)FileDataPtr)) / sizeof(FileDataType)));
}
}
return(ERROR);
}


312
WWFLAT32/FILE/FINDFILE.CPP Normal file
View File

@@ -0,0 +1,312 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : FINDFILE.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 21, 1991 *
* *
* Last Update : September 29, 1993 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Find_File_Index -- Finds the FileTable index number for a given file. *
* Find_File -- Checks if a file is immediatly available. *
* Get_FileData -- Gets a pointer back to the correct file. *
* Find_File -- Checks if a file is immediatly available. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
#ifndef WWSTD_H
#include "wwstd.h"
#endif
#ifndef _FILE_H
#include "_file.h"
#endif
#include <direct.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <search.h>
#include <sys\stat.h>
/***************************************************************************
* FIND_FILE -- Checks if a file is immediatly available. *
* *
* Use this function to determine if a file is immediatly available. *
* This routine will NOT request for the proper disk to be inserted *
* if the file could not be found. Use File_Exists for that feature. *
* The Westwood file I/O system does NOT have to be initialized as *
* a prerequisit to using this function. *
* *
* INPUT: file_name -- Name of the file to check. *
* *
* OUTPUT: Returns the disk number that the file exits on (A=1, B=2, etc) *
* *
* WARNINGS: This sets the current drive to the drive that contains the *
* specified file (if it is found). *
* *
* HISTORY: *
* 11/14/1991 JLB : Created. *
* 03/14/1992 JLB : Modified for Amiga compatability. *
* 01/11/1993 SKB : Modified for CD-ROM searches. *
*=========================================================================*/
int cdecl Find_File(char const *file_name)
{
FileDataType *filedata = NULL;
WORD index; // File index (if any).
WORD disk; // Disk number of file (if in filetable).
/*
** If the filename is invalid then it errors out as if the file wasn't
** found (naturally).
*/
if (!file_name) return(FALSE);
/*
** Determine if the file has a file table entry. If it does, then
** special checks and processing must occur.
** Also, if it is in memory, return with it.
*/
index = Find_File_Index(file_name);
filedata = &FileDataPtr[index];
if (index != ERROR) {
// If the file is currently cached, return TRUE that it was found.
if (filedata->Ptr) {
return (TRUE);
}
}
/*
** Always check the current directory for the file. Only if it can't
** be found are furthur measures required.
*/
DiskNumber = ERROR; // This indicates file exists in current directory.
#if (LIB_CDROM)
ibm_setdisk(*StartPath - 'A');
#endif
/*
** Check the current directory by attempting to open with READ access.
*/
{
WORD handle;
CallingDOSInt++;
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
CallingDOSInt--;
if (handle != ERROR)
{
// WORD d;
unsigned d ;
CallingDOSInt++;
close(handle);
// d = getdisk();
_dos_getdrive ( & d) ;
CallingDOSInt--;
return(d);
}
}
if (index != ERROR) {
disk = filedata->Disk;
/*
** If the file is in a packed file, then search for the packed file
** instead of the specified one.
*/
if (index != ERROR && (filedata->Flag & FILEF_PACKED)) {
filedata = &FileDataPtr[disk];
return (Find_File(filedata->Name));
}
}
/*
** It could not be found on the current drive, so search the other
** drives if allowed to do so.
*/
if (!MultiDriveSearch) {
return(FALSE);
}
#if (LIB_CDROM)
// If we were unable to find the file on the hard drive, change
// drives to the CD rom drive and see if it is there.
ibm_setdisk(*DataPath - 'A');
{
WORD handle;
Hard_Error_Occured = 0;
handle = Open_File_With_Recovery( file_name, MODE_OLDFILE );
if (handle != FILEOPENERROR) {
FILECLOSE(handle);
return(ibm_getdisk() + 1);
}
}
ibm_setdisk(*StartPath - 'A');
return (FALSE);
#else
{
WORD start_drive; // Original current drive number.
/*
** Record the current drive for restoring later in case of failure.
*/
CallingDOSInt++;
start_drive = getdisk();
CallingDOSInt--;
/*
** Sweep backward from the last real drive to the first, looking for the
** file on each in turn.
*/
for (index = MaxDevice; index != -1; index--) {
if (Is_Device_Real(index)) {
CallingDOSInt++;
setdisk(index);
CallingDOSInt--;
{
WORD handle;
CallingDOSInt++;
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
CallingDOSInt--;
if (handle != ERROR) {
CallingDOSInt++;
close(handle);
CallingDOSInt--;
DiskNumber = index+1;
return (DiskNumber);
}
}
}
}
CallingDOSInt++;
setdisk(start_drive);
CallingDOSInt--;
}
return(FALSE);
#endif
}
/***************************************************************************
* FIND_FILE_INDEX -- Finds the FileTable index number for a given file. *
* *
* This function searches the FileTable and returns with the index of *
* the matching file. If the file doesn't exist in the table, then *
* ERROR is returned. It does not care about case. *
* *
* INPUT: filename -- Pointer to the filename to check. *
* *
* OUTPUT: Returns with the index into the FileTable. If the file does *
* not exist in the file table, then ERROR is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/09/1991 JLB : Created. *
* 06/11/1993 JLB : Sorts and binary searches the file table. *
*=========================================================================*/
PRIVATE int Comp_Func(const void *p1, const void *p2)
{
return(strcmp((char *) ((FileDataType*)p1)->Name, (char *) ((FileDataType*)p2)->Name));
}
int cdecl Find_File_Index(char const *filename)
{
FileDataType *filedata; // File entry pointer.
FileDataType key; // Working file data type var.
/*
** Perform a binary search on the presorted filetable.
*/
if (filename) {
filedata = NULL;
key.Name = (BYTE *) strupr((char *)filename);
if (strstr((char *)key.Name, (char *)".PAK")) {
/*
** If the FileData table was not loaded from the disk then the PAK files are
** not sorted so Perform a linear search for the pak files.
** Otherwise the files are sorted so speed things up by doing a bsearch.
*/
if (FileData == FileDataPtr) {
filedata = (FileDataType *) lfind(&key, FileDataPtr, (size_t *) &NumPAKFiles, sizeof(FileDataType), Comp_Func);
}
else {
filedata = (FileDataType *)bsearch(&key, FileDataPtr, NumPAKFiles, sizeof(FileDataType), Comp_Func);
}
} else {
/*
** Perform a binary search for the regular files.
*/
filedata = (FileDataType *)bsearch(&key, &FileDataPtr[NumPAKFiles], NumFiles, sizeof(FileDataType), Comp_Func);
}
// Return the element in the array if file was found in table.
if (filedata) {
return (filedata - FileDataPtr);
//return ((WORD)((((LONG)filedata) - ((LONG)FileDataPtr)) / sizeof(FileDataType)));
}
}
return(ERROR);
}


216
WWFLAT32/FILE/HARDERR.ASM Normal file
View File

@@ -0,0 +1,216 @@
;
; 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 : Hard/Critical Error Handler *
;* *
;* File Name : harderr.asm *
;* *
;* Programmer : Scott K. Bowen. *
;* *
;* Start Date : July 18, 1994 *
;* *
;* Last Update : July 26, 1994 [SKB] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Install_Hard_Error_Handler -- Setup for handling critical errors *
;* Remove_Hard_Erroror_Handler -- Remove the critical error handler stuff*
;* Critical_Error_Handler -- Catch critical error interrupt. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
LOCALS ??
;INCLUDE "tntdos.inc"
;//////////////////////////////////////////////////////////////////////////////////////
;///////////////////////////////////// Equates ////////////////////////////////////////
DOS_SYS_CALL EQU 21h ; to do TNT DOS-XNDR system calls.
LOCK_PAGES EQU 5 ; Lock pages subfunction using DX_MEM_MGT
UNLOCK_PAGES EQU 6 ; Unlock pages subfunction using DX_MEM_MGT
CRITERR_INT_NUM EQU 24h
DISK_ERROR_BIT EQU 01000000000000000b ; bit 7 of dh.
DISK_ERROR EQU 1 ; Value of Hard_Error_Occured if disk/floppy error.
OTHER_ERROR EQU 2 ; Value of Hard_Error_Occured if other type of error.
;
; Interrupt handler stack frame
;
_FLGS equ [DWORD PTR ebp+52] ; 386|DOS-Extender flags
_GS equ [WORD PTR ebp+48] ; original GS
_FS equ [WORD PTR ebp+44] ; original FS
_DS equ [WORD PTR ebp+40] ; original DS
_ES equ [WORD PTR ebp+36] ; original ES
_SS equ [WORD PTR ebp+32] ; original SS
_ESP equ [DWORD PTR ebp+28] ; original ESP
_EFLAGS equ [DWORD PTR ebp+24] ; original EFLAGS
_CS equ [DWORD PTR ebp+20] ; original CS
_EIP equ [DWORD PTR ebp+16] ; original EIP
_EBP equ [DWORD PTR ebp] ; original EBP
;
; DOS critical error stack frame
;
_DOS_FLAGS equ [WORD PTR es:ebx+22] ; interrupt stack frame from real
_DOS_CS equ [WORD PTR es:ebx+20] ; mode INT 21h
_DOS_IP equ [WORD PTR es:ebx+18] ;
_DOS_ES equ [WORD PTR es:ebx+16] ; regs at time INT 21h was issued
_DOS_DS equ [WORD PTR es:ebx+14] ; in real mode
_DOS_BP equ [WORD PTR es:ebx+12] ;
_DOS_DI equ [WORD PTR es:ebx+10] ;
_DOS_SI equ [WORD PTR es:ebx+8] ;
_DOS_DX equ [WORD PTR es:ebx+6] ;
_DOS_CX equ [WORD PTR es:ebx+4] ;
_DOS_BX equ [WORD PTR es:ebx+2] ;
_DOS_AX equ [WORD PTR es:ebx] ;
;
; Error codes put into Hard_Error_Code
;
DISK_WRITE_PROTECTED equ 00h
UNKOWN_DEVICE equ 01h
DRIVE_NOT_READY equ 02h
UNKOWN_COMMAND equ 03h
CRC_ERROR equ 04h
WRONG_DATA_LENGTH equ 05h
SEEK_ERROR equ 06h
UNKOWN_DEVICE_TYPE equ 07h
SECTOR_NOT_FOUND equ 08h
OUT_OF_PAPER equ 09h
WRITE_ERROR equ 0Ah
READ_ERROR equ 0Bh
GENERAL_ERROR equ 0Ch
;//////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////// Prototypes ///////////////////////////////////////
GLOBAL Install_Hard_Error_Handler :NEAR
GLOBAL Remove_Hard_Error_Handler :NEAR
;//////////////////////////////////////////////////////////////////////////////////////
;///////////////////////////////// Global/Local Data //////////////////////////////////
DATASEG
LABEL LockedDataStart BYTE
Hard_Error_Occured DB 0 ; Hard disk error or other error.
Hard_Error_Code DB 0 ; Error Code.
LABEL LockedDataEnd BYTE
OldRMI DD ? ; original real mode critical err vector
OldPMIOffset DD ? ; original protected mode critical err vector
OldPMISelector DD ? ; original PM crit error selector.
InitFlags DD 0 ; Flags to indicate what has been initialized.
; InitFlags that are set to have a fully functional interrupt.
IF_SET_VECTORS equ 1 ; Vectors have been set.
IF_LOCKED_PM_CODE equ 2 ; Locked PM code for DPMI.
IF_LOCKED_PM_DATA equ 4 ; Locked PM data for DPMI.
IF_FUNCTIONAL equ 8 ; crit error is in and functional.
;//////////////////////////////////////////////////////////////////////////////////////
;///////////////////////////////////// Code //////////////////////////////////////////
CODESEG
;***************************************************************************
;* INSTALL_HARD_ERROR_HANDLER -- Setup for handling critical errors. *
;* *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 07/26/1994 SKB : Created. *
;*=========================================================================*
PROC Install_Hard_Error_Handler C near
USES eax,ebx,ecx,ds,es
ret
ENDP Install_Hard_Error_Handler
;***************************************************************************
;* REMOVE_HARD_ERROROR_HANDLER -- Remove the critical error handler stuff *
;* *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 07/26/1994 SKB : Created. *
;*=========================================================================*
PROC Remove_Hard_Error_Handler C near
USES ebx,ecx,edx,ds,es
;
; Restore the original interrupt vectors and exit
;
ret
ENDP Remove_Hard_Error_Handler
;***************************************************************************
;* Critical_Error_Handler -- Catch critical error interrupt. *
;* *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 07/26/1994 SKB : Created. *
;*=========================================================================*
LABEL LockedCodeStart BYTE
PROC Critical_Error_Handler NEAR
ENDP Critical_Error_Handler
LABEL LockedCodeEnd BYTE
END


194
WWFLAT32/FILE/MAKEFILE Normal file
View File

@@ -0,0 +1,194 @@
#
# 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 = file
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
LIB_DIR = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
file.obj &
filecach.obj &
filechng.obj &
filedata.obj &
fileglob.obj &
fglob2.obj &
fileinfo.obj &
fileinit.obj &
fileio.obj &
filelib.obj &
filestub.obj &
findfile.obj &
devices.obj &
devtable.obj &
ffirst.obj &
harderr.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: $(WWLIB)\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 *.h $(%WWFLAT)\include
copy *.inc $(%WWFLAT)\include
copy *.cpp $(%WWFLAT)\srcdebug
copy *.asm $(%WWFLAT)\srcdebug
$(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
#---------------------------------------------------------------------------
# Create the test directory and make it.
#---------------------------------------------------------------------------
test:
mkdir test
cd test
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
update
wmake
cd ..
#**************************** End of makefile ******************************

183
WWFLAT32/FILE/_FILE.BAK Normal file
View File

@@ -0,0 +1,183 @@
/*
** 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 A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : Library - Filio header stuff. *
;* *
;* File Name : FILE.H *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : September 13, 1993 *
;* *
;* Last Update : April 11, 1994 *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FILE_H
#include "file.h"
#endif
#ifndef _FILE_H
#define _FILE_H
/*=========================================================================*/
/* Fileio defines */
/*=========================================================================*/
#define LIB_CDROM TRUE
#define MODE_OLDFILE (O_RDONLY | O_BINARY)
#define MODE_NEWFILE (O_WRONLY | O_BINARY | O_CREAT | O_TRUNC)
#define MODE_READWRITE (O_RDWR | O_BINARY)
#define FILEOPENERROR -1
#define FILEOPEN(f,m) ibm_open(f, m, (((UWORD) m) == MODE_OLDFILE) ? S_IREAD : (S_IREAD | S_IWRITE))
#define FILECLOSE(fd) ibm_close(fd)
#define FILEREAD(f,b,n) ibm_read(f,b,(WORD)(n))
#define FILEWRITE(f,b,n) ibm_write(f,b,(WORD)(n))
#define FILESEEK(f,b,n) ibm_lseek(f, b, n)
#define FILEDELETE(f) ibm_unlink(f)
#define CHANGEDIR(p) ibm_chdir(p)
#define FILENAMESIZE 13
#define IO_CHUNK_SIZE 0xfff0UL
/*
** Maximum number of file handles
*/
#define TABLE_MAX 20
/*=========================================================================*/
/* The file handle table */
/*=========================================================================*/
typedef struct {
BOOL Empty; // Is this handle empty?
WORD Handle; // DOS file handle (0 = resident).
LONG Pos; // Current file position.
LONG Start; // Offset of file from pointer.
WORD Index; // FileData[] index.
WORD Mode; // Access mode (WW).
BYTE *Name; // File name pointer.
} FileHandleType;
/*=========================================================================*/
/* The following prototypes are for the file: FILEIO.CPP */
/*=========================================================================*/
WORD ibm_getdisk(VOID);
WORD ibm_setdisk(WORD drive);
WORD ibm_close(WORD handle);
WORD ibm_unlink(BYTE const *name);
LONG ibm_lseek(WORD handle, LONG offset, WORD where);
UWORD ibm_read(WORD handle, VOID *ptr, UWORD bytes);
UWORD ibm_write(WORD handle, VOID *ptr, UWORD bytes);
WORD ibm_open(BYTE const *name, UWORD mode, WORD attrib);
WORD ibm_chdir(BYTE const *path);
/*=========================================================================*/
/* The following prototypes are for the file: FILELIB.CPP */
/*=========================================================================*/
WORD cdecl Do_Open_Error(FileErrorType errormsgnum, BYTE const *file_name);
VOID cdecl Do_IO_Error(FileErrorType errormsgnum, BYTE const *filename);
LONG cdecl Read_File_With_Recovery( WORD handle, VOID *buf, UWORD bytes );
WORD cdecl Open_File_With_Recovery( BYTE const *file_name, UWORD mode );
BOOL cdecl Cache_File(WORD index, WORD file_handle);
/*=========================================================================*/
/* The following prototypes are for the file: DEVICES.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Get_Devices(VOID);
extern WORD Is_Device_Real(WORD device);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* The following prototypes are for the file: DEVTABLE.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Init_Device_Table(BYTE *table);
extern WORD Max_Device(VOID);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* The following prototypes are for the file: HARDERR.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Install_Hard_Error_Handler(VOID);
extern VOID Remove_Hard_Error_Handler(VOID);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* Globale variables in the fileio system. */
/*=========================================================================*/
extern BYTE CallingDOSInt;
extern "C" extern BYTE MaxDevice,DefaultDrive;
extern BYTE MultiDriveSearch;
extern FileDataType *FileDataPtr;
extern FileHandleType FileHandleTable[TABLE_MAX];
extern UWORD NumFiles; // Number of files, except PAK, in file table.
extern UWORD NumPAKFiles; // Number of PAK files in filetable.
extern VOID *FileCacheHeap; // Pointer to the cache in memory.
extern WORD DiskNumber;
extern WORD MaxDirNum;
/*=========================================================================*/
#endif // _FILE_H

183
WWFLAT32/FILE/_FILE.H Normal file
View File

@@ -0,0 +1,183 @@
/*
** 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 A S S O C I A T E S **
;***************************************************************************
;* *
;* Project Name : Library - Filio header stuff. *
;* *
;* File Name : FILE.H *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : September 13, 1993 *
;* *
;* Last Update : April 11, 1994 *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FILE_H
#include "file.h"
#endif
#ifndef _FILE_H
#define _FILE_H
/*=========================================================================*/
/* Fileio defines */
/*=========================================================================*/
#define LIB_CDROM TRUE
#define MODE_OLDFILE (O_RDONLY | O_BINARY)
#define MODE_NEWFILE (O_WRONLY | O_BINARY | O_CREAT | O_TRUNC)
#define MODE_READWRITE (O_RDWR | O_BINARY)
#define FILEOPENERROR -1
#define FILEOPEN(f,m) ibm_open(f, m, (((UWORD) m) == MODE_OLDFILE) ? S_IREAD : (S_IREAD | S_IWRITE))
#define FILECLOSE(fd) ibm_close(fd)
#define FILEREAD(f,b,n) ibm_read(f,b,(WORD)(n))
#define FILEWRITE(f,b,n) ibm_write(f,b,(WORD)(n))
#define FILESEEK(f,b,n) ibm_lseek(f, b, n)
#define FILEDELETE(f) ibm_unlink(f)
#define CHANGEDIR(p) ibm_chdir(p)
#define FILENAMESIZE 13
#define IO_CHUNK_SIZE 0xfff0UL
/*
** Maximum number of file handles
*/
#define TABLE_MAX 20
/*=========================================================================*/
/* The file handle table */
/*=========================================================================*/
typedef struct {
BOOL Empty; // Is this handle empty?
WORD Handle; // DOS file handle (0 = resident).
LONG Pos; // Current file position.
LONG Start; // Offset of file from pointer.
WORD Index; // FileData[] index.
WORD Mode; // Access mode (WW).
BYTE *Name; // File name pointer.
} FileHandleType;
/*=========================================================================*/
/* The following prototypes are for the file: FILEIO.CPP */
/*=========================================================================*/
WORD ibm_getdisk(VOID);
WORD ibm_setdisk(WORD drive);
WORD ibm_close(WORD handle);
WORD ibm_unlink(BYTE const *name);
LONG ibm_lseek(WORD handle, LONG offset, WORD where);
UWORD ibm_read(WORD handle, VOID *ptr, UWORD bytes);
UWORD ibm_write(WORD handle, VOID *ptr, UWORD bytes);
WORD ibm_open(BYTE const *name, UWORD mode, WORD attrib);
WORD ibm_chdir(BYTE const *path);
/*=========================================================================*/
/* The following prototypes are for the file: FILELIB.CPP */
/*=========================================================================*/
WORD cdecl Do_Open_Error(FileErrorType errormsgnum, BYTE const *file_name);
VOID cdecl Do_IO_Error(FileErrorType errormsgnum, BYTE const *filename);
LONG cdecl Read_File_With_Recovery( WORD handle, VOID *buf, UWORD bytes );
int cdecl Open_File_With_Recovery( BYTE const *file_name, unsigned int mode );
BOOL cdecl Cache_File(WORD index, WORD file_handle);
/*=========================================================================*/
/* The following prototypes are for the file: DEVICES.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Get_Devices(VOID);
extern WORD Is_Device_Real(WORD device);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* The following prototypes are for the file: DEVTABLE.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Init_Device_Table(BYTE *table);
extern WORD Max_Device(VOID);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* The following prototypes are for the file: HARDERR.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Install_Hard_Error_Handler(VOID);
extern VOID Remove_Hard_Error_Handler(VOID);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
/* Globale variables in the fileio system. */
/*=========================================================================*/
extern BYTE CallingDOSInt;
extern "C" extern BYTE MaxDevice,DefaultDrive;
extern BYTE MultiDriveSearch;
extern FileDataType *FileDataPtr;
extern FileHandleType FileHandleTable[TABLE_MAX];
extern UWORD NumFiles; // Number of files, except PAK, in file table.
extern UWORD NumPAKFiles; // Number of PAK files in filetable.
extern VOID *FileCacheHeap; // Pointer to the cache in memory.
extern WORD DiskNumber;
extern WORD MaxDirNum;
/*=========================================================================*/
#endif // _FILE_H

122
WWFLAT32/FONT/FONT.BAK Normal file
View File

@@ -0,0 +1,122 @@
/*
** 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 : Font and text print 32 bit library *
* *
* File Name : FONT.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : June 27, 1994 *
* *
* Last Update : June 29, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* VVPC::Text_Print -- Text print into a virtual viewport. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FONT_H
#define FONT_H
#ifndef GBUFFER_H
#include <gbuffer.h>
#endif
#ifndef VBUFFER_H
#include <vbuffer.h>
#endif
//////////////////////////////////////// Defines //////////////////////////////////////////
// defines for font header, offsets to block offsets
#define FONTINFOBLOCK 4
#define FONTOFFSETBLOCK 6
#define FONTWIDTHBLOCK 8
#define FONTDATABLOCK 10
#define FONTHEIGHTBLOCK 12
// defines for font info block
#define FONTINFOMAXHEIGHT 4
#define FONTINFOMAXWIDTH 5
//////////////////////////////////////// Prototypes //////////////////////////////////////////
/*=========================================================================*/
/* The following prototypes are for the file: SET_FONT.CPP */
/*=========================================================================*/
VOID *cdecl Set_Font(VOID const *fontptr);
/*=========================================================================*/
/* The following prototypes are for the file: FONT.CPP */
/*=========================================================================*/
WORD cdecl Char_Pixel_Width(BYTE chr);
UWORD cdecl String_Pixel_Width(BYTE const *string);
VOID cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& vp, ULONG offset, INT *x, INT *y);
VOID cdecl Get_Next_Text_Print_XY(VideoViewPortClass& vp, ULONG offset, INT *x, INT *y);
/*=========================================================================*/
/* The following prototypes are for the file: LOADFONT.CPP */
/*=========================================================================*/
VOID *cdecl Load_Font(BYTE const *name);
/*=========================================================================*/
/* The following prototypes are for the file: TEXTPRNT.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
VOID Set_Font_Palette_Range(VOID const *palette, INT start_idx, INT end_idx);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
//////////////////////////////////////// External varables ///////////////////////////////////////
extern "C" int FontXSpacing;
extern "C" int FontYSpacing;
extern BYTE FontWidth ;
extern BYTE FontHeight;
extern BYTE *FontWidthBlockPtr;
extern "C" VOID const *FontPtr;
#endif // FONT_H

170
WWFLAT32/FONT/FONT.CPP Normal file
View File

@@ -0,0 +1,170 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : LIBRARY *
* *
* File Name : FONT.C *
* *
* Programmer : David Dettmer *
* *
* Last Update : July 20, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Char_Pixel_Width -- Return pixel width of a character. *
* String_Pixel_Width -- Return pixel width of a string of characters. *
* Get_Next_Text_Print_XY -- Calculates X and Y given ret value from Text_P*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <wwstd.h>
#include "font.h"
#include <malloc.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys\stat.h>
#include <string.h>
/***************************************************************************
* CHAR_PIXEL_WIDTH -- Return pixel width of a character. *
* *
* Retreives the pixel width of a character from the font width block. *
* *
* INPUT: Character. *
* *
* OUTPUT: Pixel width of a string of characters. *
* *
* WARNINGS: Set_Font must have been called first. *
* *
* HISTORY: *
* 01/31/1992 DRD : Created. *
* 06/30/1994 SKB : Converted to 32 bit library. *
*=========================================================================*/
WORD cdecl Char_Pixel_Width(BYTE chr)
{
WORD width;
width = (UBYTE)*(FontWidthBlockPtr + (UBYTE)chr) + FontXSpacing;
return(width);
}
/***************************************************************************
* STRING_PIXEL_WIDTH -- Return pixel width of a string of characters. *
* *
* Calculates the pixel width of a string of characters. This uses *
* the font width block for the widths. *
* *
* INPUT: Pointer to string of characters. *
* *
* OUTPUT: Pixel width of a string of characters. *
* *
* WARNINGS: Set_Font must have been called first. *
* *
* HISTORY: *
* 01/30/1992 DRD : Created. *
* 01/31/1992 DRD : Use Char_Pixel_Width. *
* 06/30/1994 SKB : Converted to 32 bit library. *
*=========================================================================*/
UWORD cdecl String_Pixel_Width(BYTE const *string)
{
WORD width; // Working accumulator of string width.
WORD largest = 0; // Largest recorded width of the string.
if (!string) return(0);
width = 0;
while (*string) {
if (*string == '\r') {
string++;
largest = MAX(largest, width);
width = 0;
} else {
width += Char_Pixel_Width(*string++); // add each char's width
}
}
largest = MAX(largest, width);
return(largest);
}
/***************************************************************************
* GET_NEXT_TEXT_PRINT_XY -- Calculates X and Y given ret value from Text_P*
* *
* *
* INPUT: VVPC& vp - viewport that was printed to. *
* ULONG offset - offset that Text_Print returned. *
* INT *x - x return value. *
* INT *y - y return value. *
* *
* OUTPUT: x and y are set. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/20/1994 SKB : Created. *
*=========================================================================*/
VOID cdecl Get_Next_Text_Print_XY(VideoViewPortClass& vp, ULONG offset, INT *x, INT *y)
{
INT buffwidth;
if (offset) {
buffwidth = vp.Get_Width() + vp.Get_XAdd();
offset -= vp.Get_Offset();
*x = offset % buffwidth;
*y = offset / buffwidth;
} else {
*x = *y = 0;
}
}
/***************************************************************************
* GET_NEXT_TEXT_PRINT_XY -- Calculates X and Y given ret value from Text_P*
* *
* *
* INPUT: VVPC& vp - viewport that was printed to. *
* ULONG offset - offset that Text_Print returned. *
* INT *x - x return value. *
* INT *y - y return value. *
* *
* OUTPUT: x and y are set. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/20/1994 SKB : Created. *
*=========================================================================*/
VOID cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& vp, ULONG offset, INT *x, INT *y)
{
INT buffwidth;
if (offset) {
buffwidth = vp.Get_Width() + vp.Get_XAdd();
offset -= vp.Get_Offset();
*x = offset % buffwidth;
*y = offset / buffwidth;
} else {
*x = *y = 0;
}
}

122
WWFLAT32/FONT/FONT.H Normal file
View File

@@ -0,0 +1,122 @@
/*
** 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 : Font and text print 32 bit library *
* *
* File Name : FONT.H *
* *
* Programmer : Scott K. Bowen *
* *
* Start Date : June 27, 1994 *
* *
* Last Update : June 29, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* VVPC::Text_Print -- Text print into a virtual viewport. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FONT_H
#define FONT_H
#ifndef GBUFFER_H
#include <gbuffer.h>
#endif
#ifndef VBUFFER_H
#include <vbuffer.h>
#endif
//////////////////////////////////////// Defines //////////////////////////////////////////
// defines for font header, offsets to block offsets
#define FONTINFOBLOCK 4
#define FONTOFFSETBLOCK 6
#define FONTWIDTHBLOCK 8
#define FONTDATABLOCK 10
#define FONTHEIGHTBLOCK 12
// defines for font info block
#define FONTINFOMAXHEIGHT 4
#define FONTINFOMAXWIDTH 5
//////////////////////////////////////// Prototypes //////////////////////////////////////////
/*=========================================================================*/
/* The following prototypes are for the file: SET_FONT.CPP */
/*=========================================================================*/
VOID *cdecl Set_Font(VOID const *fontptr);
/*=========================================================================*/
/* The following prototypes are for the file: FONT.CPP */
/*=========================================================================*/
WORD cdecl Char_Pixel_Width(BYTE chr);
UWORD cdecl String_Pixel_Width(BYTE const *string);
VOID cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& vp, ULONG offset, INT *x, INT *y);
VOID cdecl Get_Next_Text_Print_XY(VideoViewPortClass& vp, ULONG offset, INT *x, INT *y);
/*=========================================================================*/
/* The following prototypes are for the file: LOADFONT.CPP */
/*=========================================================================*/
VOID *cdecl Load_Font(BYTE const *name);
/*=========================================================================*/
/* The following prototypes are for the file: TEXTPRNT.ASM */
/*=========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
VOID Set_Font_Palette_Range(VOID const *palette, INT start_idx, INT end_idx);
#ifdef __cplusplus
}
#endif
/*=========================================================================*/
//////////////////////////////////////// External varables ///////////////////////////////////////
extern "C" int FontXSpacing;
extern "C" int FontYSpacing;
extern BYTE FontWidth ;
extern BYTE FontHeight;
extern BYTE *FontWidthBlockPtr;
extern "C" void const *FontPtr;
#endif // FONT_H

122
WWFLAT32/FONT/LOADFONT.BAK Normal file
View File

@@ -0,0 +1,122 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : LOADFONT.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 6, 1991 *
* *
* Last Update : June 27, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Load_Font -- Loads a font from disk. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <wwstd.h>
#include "font.h"
#include <file.h>
#include <wwmem.h>
#if(IBM)
#include <fcntl.h>
#include <io.h>
#endif
extern "C" {
int FontXSpacing = 0;
int FontYSpacing = 0;
void const *FontPtr = NULL;
}
BYTE FontWidth = 8;
BYTE FontHeight = 8;
// only font.c and set_font.c use the following
BYTE *FontWidthBlockPtr = NULL;
/***************************************************************************
* LOAD_FONT -- Loads a font from disk. *
* *
* This loads a font from disk. This function must be called as a *
* precursor to calling Set_Font(). You need only call this function *
* once per desired font at the beginning of your code, but AFTER *
* Prog_Init() is called. *
* *
* INPUT: name - Pointer to font name to use (eg. "topaz.font") *
* *
* fontsize - Size in points of the font loaded. *
* *
* OUTPUT: Pointer to font data or NULL if unable to load. *
* *
* WARNINGS: Some system memory is grabbed by this routine. *
* *
* HISTORY: *
* 4/10/91 BS : 2.0 compatibily *
* 6/09/91 JLB : IBM and Amiga compatability. *
* 11/27/1991 JLB : Uses file I/O routines for disk access. *
* 01/29/1992 DRD : Modified to use new font format. *
* 02/01/1992 DRD : Added font file verification. *
* 06/29/1994 SKB : modified for 32 bit library *
*=========================================================================*/
VOID *cdecl Load_Font(BYTE const *name)
{
BYTE valid;
WORD fh; // DOS file handle for font file.
UWORD size; // Size of the data in the file (-2);
BYTE *ptr = NULL; // Pointer to newly loaded font.
if (Find_File(name)) {
fh = Open_File(name, READ);
if (Read_File(fh, (BYTE *) &size, 2) != 2) return(NULL);
ptr = (BYTE *) Alloc(size, MEM_NORMAL);
*(WORD *)ptr = size;
Read_File(fh, ptr + 2, size - 2);
Close_File(fh);
} else {
return (NULL);
}
//
// verify that the file loaded is a valid font file.
//
valid = FALSE;
if (*(ptr + 2) == 0) { // no compression
if (*(ptr + 3) == 5) { // currently only 5 data blocks are used.
valid = TRUE;
}
}
if ( !valid ) {
return (NULL);
}
return(ptr);
}

120
WWFLAT32/FONT/LOADFONT.CPP Normal file
View File

@@ -0,0 +1,120 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : LOADFONT.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 6, 1991 *
* *
* Last Update : June 27, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Load_Font -- Loads a font from disk. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <wwstd.h>
#include "font.h"
#include <file.h>
#include <wwmem.h>
#if(IBM)
#include <fcntl.h>
#include <io.h>
#endif
int FontXSpacing = 0;
int FontYSpacing = 0;
void const *FontPtr = NULL;
BYTE FontWidth = 8;
BYTE FontHeight = 8;
// only font.c and set_font.c use the following
BYTE *FontWidthBlockPtr = NULL;
/***************************************************************************
* LOAD_FONT -- Loads a font from disk. *
* *
* This loads a font from disk. This function must be called as a *
* precursor to calling Set_Font(). You need only call this function *
* once per desired font at the beginning of your code, but AFTER *
* Prog_Init() is called. *
* *
* INPUT: name - Pointer to font name to use (eg. "topaz.font") *
* *
* fontsize - Size in points of the font loaded. *
* *
* OUTPUT: Pointer to font data or NULL if unable to load. *
* *
* WARNINGS: Some system memory is grabbed by this routine. *
* *
* HISTORY: *
* 4/10/91 BS : 2.0 compatibily *
* 6/09/91 JLB : IBM and Amiga compatability. *
* 11/27/1991 JLB : Uses file I/O routines for disk access. *
* 01/29/1992 DRD : Modified to use new font format. *
* 02/01/1992 DRD : Added font file verification. *
* 06/29/1994 SKB : modified for 32 bit library *
*=========================================================================*/
VOID *cdecl Load_Font(BYTE const *name)
{
BYTE valid;
WORD fh; // DOS file handle for font file.
UWORD size; // Size of the data in the file (-2);
BYTE *ptr = NULL; // Pointer to newly loaded font.
if (Find_File(name)) {
fh = Open_File(name, READ);
if (Read_File(fh, (BYTE *) &size, 2) != 2) return(NULL);
ptr = (BYTE *) Alloc(size, MEM_NORMAL);
*(WORD *)ptr = size;
Read_File(fh, ptr + 2, size - 2);
Close_File(fh);
} else {
return (NULL);
}
//
// verify that the file loaded is a valid font file.
//
valid = FALSE;
if (*(ptr + 2) == 0) { // no compression
if (*(ptr + 3) == 5) { // currently only 5 data blocks are used.
valid = TRUE;
}
}
if ( !valid ) {
return (NULL);
}
return(ptr);
}

195
WWFLAT32/FONT/MAKEFILE Normal file
View File

@@ -0,0 +1,195 @@
#
# 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 24, 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 = font
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
LIB_DIR = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
font.obj &
loadfont.obj &
set_font.obj &
setfpal.obj &
textprnt.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 *.h $(%WWFLAT)\include
copy *.inc $(%WWFLAT)\include
copy *.cpp $(%WWFLAT)\srcdebug
copy *.asm $(%WWFLAT)\srcdebug
$(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
#---------------------------------------------------------------------------
# Create the test directory and make it.
#---------------------------------------------------------------------------
test:
mkdir test
cd test
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
update
mkdir run
cd run
copy $(%WWVCS)\$(PROJ_NAME)\test\run\vcs.cfg
update
cd..
mkdir art
cd art
copy $(%WWVCS)\$(PROJ_NAME)\test\art\vcs.cfg
update
cd..
wmake
cd ..
#**************************** End of makefile ******************************

106
WWFLAT32/FONT/SETFPAL.ASM Normal file
View File

@@ -0,0 +1,106 @@
;
; 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 : 32 bit library Text Print *
;* *
;* File Name : TEXTPRNT.ASM *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : July 2, 1994 *
;* *
;* Last Update : July 2, 1994 [SKB] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Text_Print -- Assembly text print routine. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL ColorXlat:BYTE
GLOBAL Set_Font_Palette_Range:NEAR
CODESEG
;***********************************************************
; SET_FONT_PALETTE_RANGE
;
; VOID Set_Font_Palette_Range(VOID *palette, WORD start, WORD end);
;
; This routine changes the local Draw_Char color translation table
; with the color numbers in palette.
;
; Bounds Checking: forces start and end to a range of 0-15
;*
PROC Set_Font_Palette_Range C near
USES eax, ebx, ecx,edi,esi
ARG palette:DWORD
ARG start:DWORD
ARG endval:DWORD
cld
mov esi,[palette]
mov ebx,[start]
and ebx,0FH ; value 0-15
mov ecx,[endval]
and ecx,0FH ; value 0-15
cmp ecx,ebx ; if end < start then exit
jl short ??exit
sub ecx,ebx ; number of colors = end - start + 1
inc ecx
mov edi,OFFSET ColorXlat ; get start of xlat table
add edi,ebx ; add starting offset
shl ebx,4 ; multiply start offset by 16
add ebx,OFFSET ColorXlat ; add start of xlat table
; updates 0-15 for lonibble xlat
; updates 0,16,32,...,240 for hinibble xlat
??setpal:
lodsb ; get color number
stosb ; save color number for lonibble xlat
mov [ebx],al ; save color number for hinibble xlat
add ebx,010H ; add 16 to index for hinibble offset
dec ecx
jnz ??setpal
??exit:
ret
ENDP Set_Font_Palette_Range
;***********************************************************
;***********************************************************
END

View File

@@ -0,0 +1,89 @@
/*
** 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : SET_FONT.C *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 6, 1991 *
* *
* Last Update : June 29, 1994 [SKB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Set_Font -- Changes the default text printing font. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <wwstd.h>
#include "font.h"
/***************************************************************************
* SET_FONT -- Changes the default text printing font. *
* *
* This routine will change the default text printing font for all *
* text output. It handles updating the system where necessary. *
* *
* INPUT: fontptr -- Pointer to the font to change to. *
* *
* OUTPUT: Returns with a pointer to the previous font. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/06/1991 JLB : Created. *
* 09/17/1991 JLB : Fixed return value bug. *
* 01/31/1992 DRD : Modified to use new font format. *
* 06/29/1994 SKB : modified for 32 bit library *
*=========================================================================*/
VOID *cdecl Set_Font(VOID const *fontptr)
{
VOID *oldfont;
BYTE const *blockptr;
oldfont = (VOID *) FontPtr;
if (fontptr) {
FontPtr = (VOID *) fontptr;
/*
** Inform the system about the new font.
*/
FontWidthBlockPtr = (BYTE*)fontptr + *(UWORD *)((BYTE*)fontptr + FONTWIDTHBLOCK);
blockptr = (BYTE*)fontptr + *(UWORD *)((BYTE*)fontptr + FONTINFOBLOCK);
FontHeight = *(blockptr + FONTINFOMAXHEIGHT);
FontWidth = *(blockptr + FONTINFOMAXWIDTH);
//Draw_Char_Setup();
#if FALSE
WindowLines = WinH / FontHeight;
WindowWidth = WinW << 3;
WindowColumns = WindowWidth / FontWidth;
#endif
}
return(oldfont);
}

436
WWFLAT32/FONT/TEXTPRNT.ASM Normal file
View File

@@ -0,0 +1,436 @@
;
; 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 : 32 bit library Text Print *
;* *
;* File Name : TEXTPRNT.ASM *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : July 2, 1994 *
;* *
;* Last Update : July 2, 1994 [SKB] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Text_Print -- Assembly text print routine. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL C FontPtr:DWORD
GLOBAL Text_Print:NEAR
; The header of the font file looks like this:
; UWORD FontLength; 0
; BYTE FontCompress; 2
; BYTE FontDataBlocks; 3
; UWORD InfoBlockOffset; 4
; UWORD OffsetBlockOffset; 6
; UWORD WidthBlockOffset; 8
; UWORD DataBlockOffset; 10
; UWORD HeightOffset; 12
; For this reason the following equates have these values:
FONTINFOBLOCK EQU 4
FONTOFFSETBLOCK EQU 6
FONTWIDTHBLOCK EQU 8
FONTDATABLOCK EQU 10
FONTHEIGHTBLOCK EQU 12
FONTINFOMAXHEIGHT EQU 4
FONTINFOMAXWIDTH EQU 5
LOCALS ??
DATASEG
ColorXlat DB 000H,001H,002H,003H,004H,005H,006H,007H
DB 008H,009H,00AH,00BH,00CH,00DH,00EH,00FH
DB 001H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 002H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 003H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 004H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 005H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 006H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 007H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 008H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 009H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00AH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00BH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00CH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00DH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00EH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00FH
CODESEG
;***************************************************************************
;* TEXT_PRINT -- Assembly text print routine. *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 06/28/1994 SKB : Created. *
;*=========================================================================*
PROC Text_Print C near
USES ebx,ecx,edx,esi,edi
ARG vpselector:WORD
ARG vpoffset:DWORD
ARG vpwidth:DWORD
ARG vpheight:DWORD
ARG vpxadd:DWORD
ARG string:DWORD
ARG x_pixel:DWORD
ARG y_pixel:DWORD
ARG fcolor:DWORD
ARG bcolor:DWORD
LOCAL infoblock:DWORD ; pointer to info block
LOCAL offsetblock:DWORD ; pointer to offset block (UWORD *)
LOCAL widthblock:DWORD ; pointer to width block (BYTE *)
LOCAL heightblock:DWORD ; pointer to height block (UWORD *)
LOCAL curline:DWORD ; pointer to first column of current row.
LOCAL bufferwidth:DWORD ; width of buffer (vpwidth + Xadd)
LOCAL nextdraw:DWORD ; bufferwidth - width of cur character.
LOCAL startdraw:DWORD ; where next character will start being drawn.
LOCAL char:DWORD ; current character value.
LOCAL maxheight:BYTE ; max height of characters in font.
LOCAL bottomblank:BYTE ; amount of empty space below current character.
LOCAL charheight:BYTE ; true height of current character.
;-------------------------------- Where to draw -----------------------------------------------
; Set up memory location to start drawing.
movzx eax,[vpselector]
mov es,ax ; Set up selector to write to.
mov eax,[vpwidth] ; get the width of the viewport
add eax,[vpxadd] ; add amount to add to get to left edge of next line.
mov [bufferwidth],eax ; save it off for later use.
mul [y_pixel] ; multiply rowsize * y_pixel start.
mov edi,[vpoffset] ; get start of the viewport
add edi,eax ; add x,y position to start of vp to get starting row address.
mov [curline],edi ; save 0,y address for line feed stuff.
add edi,[x_pixel] ; add to get starting column in starting row.
mov [startdraw],edi ; save it off.
;-------------------------------- Create block pointers ----------------------------------------
; Get the pointer to the font.
; We could check for NULL but why waste the time.
; It is up to programmer to make sure it is set.
mov esi,[FontPtr] ; Get the font pointer
; Set up some pointers to the different memory blocks.
; esi (FontPtr) is added to each to get the true address of each block.
; Many registers are used for P5 optimizations.
; ebx is used for InfoBlock which is then used in the next section.
movzx eax,[WORD PTR esi+FONTOFFSETBLOCK] ; get offset to offset block
movzx ebx,[WORD PTR esi+FONTINFOBLOCK] ; get offset to info block (must be ebx for height test)
movzx ecx,[WORD PTR esi+FONTWIDTHBLOCK] ; get offset to width block
movzx edx,[WORD PTR esi+FONTHEIGHTBLOCK] ; get offset to height block
add eax,esi ; add offset of FontPtr to offset block
add ebx,esi ; add offset of FontPtr to info block
add ecx,esi ; add offset of FontPtr to width block
add edx,esi ; add offset of FontPtr to height block
mov [offsetblock],eax ; save offset to offset block
mov [infoblock],ebx ; save offset to info block
mov [widthblock],ecx ; save offset to width block
mov [heightblock],edx ; save offset to height block
;------------------------------------------ Test for fit ----------------------------------------------
; Test to make sure the height of the max character will fit on this line
; and and not fall out of the viewport.
; remember we set ebx to FONTINFOBLOCK above.
movzx eax,[BYTE PTR ebx + FONTINFOMAXHEIGHT]; get the max height in font.
mov [maxheight],al ; save it for later use.
add eax,[y_pixel] ; add current y_value.
cmp eax,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we're outa here.
mov [y_pixel],eax ; save for next line feed. y value for next line.
cld ; Make sure we are always forward copying.
;------------------------ Set palette foreground and background ----------------------------------
mov eax,[fcolor] ; foreground color
mov [ColorXlat+1],al
mov [ColorXlat+16],al
mov eax,[bcolor] ; background color
mov [ColorXlat],al
;-------------------------------------------------------------------------------------------------
;----------------------------------------- Main loop ----------------------------------------------
; Now we go into the main loop of reading each character in the string and doing
; something with it.
??next_char:
; while (*string++)
xor eax,eax ; zero out since we will just load al.
mov esi,[string] ; get address on next character.
lodsb ; load the character into al.
test eax,0FFH ; test to see if character is a NULL
jz ??done ; character is NULL, get outa here.
mov edi,[startdraw] ; Load the starting address.
mov [string],esi ; save index into string. (incremented by lodsb)
cmp eax,13 ; is the character a line feed?
je ??line_feed ; if so, go to special case.
mov [char],eax ; save the character off for later reference.
mov ebx,eax ; save it in ebx for later use also.
add eax,[widthblock] ; figure address of width of character.
mov ecx,[x_pixel] ; get current x_pixel.
movzx edx,[BYTE PTR eax] ; get the width of the character in dl.
add ecx,edx ; add width of char to current x_pixel.
add [startdraw],edx ; save start draw for next character.
cmp ecx,[vpwidth] ; is the pixel greater then the vp width?
jg ??force_line_feed ; if so, force a line feed.
mov [x_pixel],ecx ; save value of start of next character.
mov ecx,[bufferwidth] ; get amount to next y same x (one row down)
sub ecx,edx ; take the current width off.
mov [nextdraw],ecx ; save it to add to edi when done with a row.
; At this point we got the character. It is now time to find out specifics
; about drawing the darn thing.
; ebx = char so they can be used as an indexes.
; edx = width of character for loop later.
; get offset of data for character into esi.
shl ebx,1 ; mult by 2 to later use as a WORD index.
mov esi,[offsetblock] ; get pointer to begining of offset block.
add esi,ebx ; index into offset block.
movzx esi,[WORD PTR esi] ; get true offset into data block from FontPtr.
add esi,[FontPtr] ; Now add FontPtr address to get true address.
; Get top and bottom blank sizes and the true height of the character.
add ebx,[heightblock] ; point ebx to element in height array.
mov al,[ebx+1] ; load the data height into dl.
mov cl,[ebx] ; load the first data row into cl.
mov bl,[maxheight] ; get the max height of characters.
mov [charheight],al ; get number of rows with data.
add al,cl ; add the two heights.
sub bl,al ; subract topblank + char height from maxheight.
mov [bottomblank],bl ; save off the number of blank rows on the bottom.
; leaving this section:
; dl is still the width of the character.
; cl is the height of the top blank area.
mov ebx,OFFSET ColorXlat ; setup ebx for xlat commands.
mov dh,dl ; save the width of the character to restore each loop.
cmp cl,0 ; is there any blank rows on top?
jz ??draw_char ; if not go and draw the real character.
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jnz ??loop_top ; if not go and write the color
;----------------------------------------- skip Top blank area ----------------------------------------
; this case, the top is transparrent, but we need to increase our dest pointer to correct row.
movzx eax,cl ; get number of rows into eax;
mov ecx,edx ; save width since edx will be destroyed by mul.
mul [bufferwidth] ; multiply that by the width of the buffer.
mov edx,ecx ; restore the width
add edi,eax ; update the pointer.
jmp short ??draw_char ; now go draw the character.
;----------------------------------------- fill Top blank area ----------------------------------------
; edi was set a long time ago.
; al is the translated color
??loop_top:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_top ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
dec cl ; decrement or row count
mov dh,dl ; restore width in dh for loop.
jz ??draw_char ; we are done here, go draw the character.
jmp short ??loop_top ; go back to top of loop.
;----------------------------------------- Draw character ----------------------------------------------
??draw_char:
movzx ecx,[charheight] ; get the height of character to count down rows.
test ecx,ecx ; is there any data? (blank would not have any)
jz ??next_char ; if no data, go on to next character.
??while_data:
lodsb ; get byte value from font data
mov ah,al ; save hinibble
and eax,0F00FH ; mask of low nibble in al hi nibble in ah.
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiplo ; skip over write
mov [es:edi],al ; write it out
??skiplo:
inc edi
dec dh ; decrement our width.
jz short ??nextrow ; check if done with width of char
mov al,ah ; restore to get
; test the time difference between looking up in a large table when shr al,4 is not done as
; compared to using only a 16 byte table when using the shr al,4
;shr al,4 ; shift the hi nibble down to low nibble
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiphi ; skip over write
mov [es:edi],al ; write it out
??skiphi:
inc edi
dec dh ; decrement our width.
jnz short ??while_data ; check if done with width of char
??nextrow:
add edi,[nextdraw] ; go to next line.
dec ecx ; decrement the number of rows to go
mov dh,dl ; restore our column count for row.
jnz ??while_data ; more data for character.
; Now it is time to setup for clearing out the bottom of the character.
movzx ecx,[bottomblank] ; get amount on bottom that is blank
cmp ecx,0 ; if there is no blank bottom...
jz ??next_char ; then skip to go to next character
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jz ??next_char ; skip the top black section to let the background through
mov dh,dl ; restore width in dh for loop.
;----------------------------------------- Blank below character -----------------------------------
??loop_bottom:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_bottom ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
mov dh,dl ; restore width in dh for loop.
dec cl ; decrement or row count
jz ??next_char ; we are done here, go to the next character.
jmp short ??loop_bottom ; go back to top of loop.
;----------------------------------- end of next_char (main) loop ------------------------------------
;-------------------------------------------------------------------------------------------------
;----------------------------------- special case line feeds ----------------------------------------
??force_line_feed:
; decrement pointer *string so that it will be back at same character
; when it goes through the loop.
mov eax,[string] ; get string pointer.
dec eax ; decrement it to point to previos char
mov [string],eax ; save it back off.
; Now go into the line feed code.....
??line_feed:
mov edx,[y_pixel] ; get the current y pixel value.
movzx ecx,[maxheight] ; get max height for later use.
add edx,ecx ; add max height to y_pixel
cmp edx,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we are outa here.
mov eax,[bufferwidth] ; get bytes to next line.
mov edi,[curline] ; get start of current line.
mul ecx ; mult max height * next line.
add edi,eax ; add adjustment to current line.
add [y_pixel],ecx ; increment to our next y position.
mov [curline],edi ; save it off for next line_feed.
mov [startdraw],edi ; save it off so we know where to draw next char.w
mov [x_pixel],0 ; zero out x_pixel
jmp ??next_char
??overflow:
mov [startdraw],0 ; Indicate that there is no valid next pos.
??done:
mov eax,[startdraw] ; return this so calling routine
ret ; can figure out where to draw next.
ENDP Text_Print
;***********************************************************
END

436
WWFLAT32/FONT/TEXTPRNT.BAK Normal file
View File

@@ -0,0 +1,436 @@
;
; 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 : 32 bit library Text Print *
;* *
;* File Name : TEXTPRNT.ASM *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : July 2, 1994 *
;* *
;* Last Update : July 2, 1994 [SKB] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Text_Print -- Assembly text print routine. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
GLOBAL FontPtr:DWORD
GLOBAL Text_Print:NEAR
; The header of the font file looks like this:
; UWORD FontLength; 0
; BYTE FontCompress; 2
; BYTE FontDataBlocks; 3
; UWORD InfoBlockOffset; 4
; UWORD OffsetBlockOffset; 6
; UWORD WidthBlockOffset; 8
; UWORD DataBlockOffset; 10
; UWORD HeightOffset; 12
; For this reason the following equates have these values:
FONTINFOBLOCK EQU 4
FONTOFFSETBLOCK EQU 6
FONTWIDTHBLOCK EQU 8
FONTDATABLOCK EQU 10
FONTHEIGHTBLOCK EQU 12
FONTINFOMAXHEIGHT EQU 4
FONTINFOMAXWIDTH EQU 5
LOCALS ??
DATASEG
ColorXlat DB 000H,001H,002H,003H,004H,005H,006H,007H
DB 008H,009H,00AH,00BH,00CH,00DH,00EH,00FH
DB 001H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 002H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 003H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 004H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 005H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 006H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 007H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 008H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 009H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00AH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00BH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00CH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00DH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00EH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00FH
CODESEG
;***************************************************************************
;* TEXT_PRINT -- Assembly text print routine. *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 06/28/1994 SKB : Created. *
;*=========================================================================*
PROC Text_Print C near
USES ebx,ecx,edx,esi,edi
ARG vpselector:WORD
ARG vpoffset:DWORD
ARG vpwidth:DWORD
ARG vpheight:DWORD
ARG vpxadd:DWORD
ARG string:DWORD
ARG x_pixel:DWORD
ARG y_pixel:DWORD
ARG fcolor:DWORD
ARG bcolor:DWORD
LOCAL infoblock:DWORD ; pointer to info block
LOCAL offsetblock:DWORD ; pointer to offset block (UWORD *)
LOCAL widthblock:DWORD ; pointer to width block (BYTE *)
LOCAL heightblock:DWORD ; pointer to height block (UWORD *)
LOCAL curline:DWORD ; pointer to first column of current row.
LOCAL bufferwidth:DWORD ; width of buffer (vpwidth + Xadd)
LOCAL nextdraw:DWORD ; bufferwidth - width of cur character.
LOCAL startdraw:DWORD ; where next character will start being drawn.
LOCAL char:DWORD ; current character value.
LOCAL maxheight:BYTE ; max height of characters in font.
LOCAL bottomblank:BYTE ; amount of empty space below current character.
LOCAL charheight:BYTE ; true height of current character.
;-------------------------------- Where to draw -----------------------------------------------
; Set up memory location to start drawing.
movzx eax,[vpselector]
mov es,ax ; Set up selector to write to.
mov eax,[vpwidth] ; get the width of the viewport
add eax,[vpxadd] ; add amount to add to get to left edge of next line.
mov [bufferwidth],eax ; save it off for later use.
mul [y_pixel] ; multiply rowsize * y_pixel start.
mov edi,[vpoffset] ; get start of the viewport
add edi,eax ; add x,y position to start of vp to get starting row address.
mov [curline],edi ; save 0,y address for line feed stuff.
add edi,[x_pixel] ; add to get starting column in starting row.
mov [startdraw],edi ; save it off.
;-------------------------------- Create block pointers ----------------------------------------
; Get the pointer to the font.
; We could check for NULL but why waste the time.
; It is up to programmer to make sure it is set.
mov esi,[FontPtr] ; Get the font pointer
; Set up some pointers to the different memory blocks.
; esi (FontPtr) is added to each to get the true address of each block.
; Many registers are used for P5 optimizations.
; ebx is used for InfoBlock which is then used in the next section.
movzx eax,[WORD PTR esi+FONTOFFSETBLOCK] ; get offset to offset block
movzx ebx,[WORD PTR esi+FONTINFOBLOCK] ; get offset to info block (must be ebx for height test)
movzx ecx,[WORD PTR esi+FONTWIDTHBLOCK] ; get offset to width block
movzx edx,[WORD PTR esi+FONTHEIGHTBLOCK] ; get offset to height block
add eax,esi ; add offset of FontPtr to offset block
add ebx,esi ; add offset of FontPtr to info block
add ecx,esi ; add offset of FontPtr to width block
add edx,esi ; add offset of FontPtr to height block
mov [offsetblock],eax ; save offset to offset block
mov [infoblock],ebx ; save offset to info block
mov [widthblock],ecx ; save offset to width block
mov [heightblock],edx ; save offset to height block
;------------------------------------------ Test for fit ----------------------------------------------
; Test to make sure the height of the max character will fit on this line
; and and not fall out of the viewport.
; remember we set ebx to FONTINFOBLOCK above.
movzx eax,[BYTE PTR ebx + FONTINFOMAXHEIGHT]; get the max height in font.
mov [maxheight],al ; save it for later use.
add eax,[y_pixel] ; add current y_value.
cmp eax,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we're outa here.
mov [y_pixel],eax ; save for next line feed. y value for next line.
cld ; Make sure we are always forward copying.
;------------------------ Set palette foreground and background ----------------------------------
mov eax,[fcolor] ; foreground color
mov [ColorXlat+1],al
mov [ColorXlat+16],al
mov eax,[bcolor] ; background color
mov [ColorXlat],al
;-------------------------------------------------------------------------------------------------
;----------------------------------------- Main loop ----------------------------------------------
; Now we go into the main loop of reading each character in the string and doing
; something with it.
??next_char:
; while (*string++)
xor eax,eax ; zero out since we will just load al.
mov esi,[string] ; get address on next character.
lodsb ; load the character into al.
test eax,0FFH ; test to see if character is a NULL
jz ??done ; character is NULL, get outa here.
mov edi,[startdraw] ; Load the starting address.
mov [string],esi ; save index into string. (incremented by lodsb)
cmp eax,13 ; is the character a line feed?
je ??line_feed ; if so, go to special case.
mov [char],eax ; save the character off for later reference.
mov ebx,eax ; save it in ebx for later use also.
add eax,[widthblock] ; figure address of width of character.
mov ecx,[x_pixel] ; get current x_pixel.
movzx edx,[BYTE PTR eax] ; get the width of the character in dl.
add ecx,edx ; add width of char to current x_pixel.
add [startdraw],edx ; save start draw for next character.
cmp ecx,[vpwidth] ; is the pixel greater then the vp width?
jg ??force_line_feed ; if so, force a line feed.
mov [x_pixel],ecx ; save value of start of next character.
mov ecx,[bufferwidth] ; get amount to next y same x (one row down)
sub ecx,edx ; take the current width off.
mov [nextdraw],ecx ; save it to add to edi when done with a row.
; At this point we got the character. It is now time to find out specifics
; about drawing the darn thing.
; ebx = char so they can be used as an indexes.
; edx = width of character for loop later.
; get offset of data for character into esi.
shl ebx,1 ; mult by 2 to later use as a WORD index.
mov esi,[offsetblock] ; get pointer to begining of offset block.
add esi,ebx ; index into offset block.
movzx esi,[WORD PTR esi] ; get true offset into data block from FontPtr.
add esi,[FontPtr] ; Now add FontPtr address to get true address.
; Get top and bottom blank sizes and the true height of the character.
add ebx,[heightblock] ; point ebx to element in height array.
mov al,[ebx+1] ; load the data height into dl.
mov cl,[ebx] ; load the first data row into cl.
mov bl,[maxheight] ; get the max height of characters.
mov [charheight],al ; get number of rows with data.
add al,cl ; add the two heights.
sub bl,al ; subract topblank + char height from maxheight.
mov [bottomblank],bl ; save off the number of blank rows on the bottom.
; leaving this section:
; dl is still the width of the character.
; cl is the height of the top blank area.
mov ebx,OFFSET ColorXlat ; setup ebx for xlat commands.
mov dh,dl ; save the width of the character to restore each loop.
cmp cl,0 ; is there any blank rows on top?
jz ??draw_char ; if not go and draw the real character.
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jnz ??loop_top ; if not go and write the color
;----------------------------------------- skip Top blank area ----------------------------------------
; this case, the top is transparrent, but we need to increase our dest pointer to correct row.
movzx eax,cl ; get number of rows into eax;
mov ecx,edx ; save width since edx will be destroyed by mul.
mul [bufferwidth] ; multiply that by the width of the buffer.
mov edx,ecx ; restore the width
add edi,eax ; update the pointer.
jmp short ??draw_char ; now go draw the character.
;----------------------------------------- fill Top blank area ----------------------------------------
; edi was set a long time ago.
; al is the translated color
??loop_top:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_top ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
dec cl ; decrement or row count
mov dh,dl ; restore width in dh for loop.
jz ??draw_char ; we are done here, go draw the character.
jmp short ??loop_top ; go back to top of loop.
;----------------------------------------- Draw character ----------------------------------------------
??draw_char:
movzx ecx,[charheight] ; get the height of character to count down rows.
test ecx,ecx ; is there any data? (blank would not have any)
jz ??next_char ; if no data, go on to next character.
??while_data:
lodsb ; get byte value from font data
mov ah,al ; save hinibble
and eax,0F00FH ; mask of low nibble in al hi nibble in ah.
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiplo ; skip over write
mov [es:edi],al ; write it out
??skiplo:
inc edi
dec dh ; decrement our width.
jz short ??nextrow ; check if done with width of char
mov al,ah ; restore to get
; test the time difference between looking up in a large table when shr al,4 is not done as
; compared to using only a 16 byte table when using the shr al,4
;shr al,4 ; shift the hi nibble down to low nibble
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiphi ; skip over write
mov [es:edi],al ; write it out
??skiphi:
inc edi
dec dh ; decrement our width.
jnz short ??while_data ; check if done with width of char
??nextrow:
add edi,[nextdraw] ; go to next line.
dec ecx ; decrement the number of rows to go
mov dh,dl ; restore our column count for row.
jnz ??while_data ; more data for character.
; Now it is time to setup for clearing out the bottom of the character.
movzx ecx,[bottomblank] ; get amount on bottom that is blank
cmp ecx,0 ; if there is no blank bottom...
jz ??next_char ; then skip to go to next character
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jz ??next_char ; skip the top black section to let the background through
mov dh,dl ; restore width in dh for loop.
;----------------------------------------- Blank below character -----------------------------------
??loop_bottom:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_bottom ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
mov dh,dl ; restore width in dh for loop.
dec cl ; decrement or row count
jz ??next_char ; we are done here, go to the next character.
jmp short ??loop_bottom ; go back to top of loop.
;----------------------------------- end of next_char (main) loop ------------------------------------
;-------------------------------------------------------------------------------------------------
;----------------------------------- special case line feeds ----------------------------------------
??force_line_feed:
; decrement pointer *string so that it will be back at same character
; when it goes through the loop.
mov eax,[string] ; get string pointer.
dec eax ; decrement it to point to previos char
mov [string],eax ; save it back off.
; Now go into the line feed code.....
??line_feed:
mov edx,[y_pixel] ; get the current y pixel value.
movzx ecx,[maxheight] ; get max height for later use.
add edx,ecx ; add max height to y_pixel
cmp edx,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we are outa here.
mov eax,[bufferwidth] ; get bytes to next line.
mov edi,[curline] ; get start of current line.
mul ecx ; mult max height * next line.
add edi,eax ; add adjustment to current line.
add [y_pixel],ecx ; increment to our next y position.
mov [curline],edi ; save it off for next line_feed.
mov [startdraw],edi ; save it off so we know where to draw next char.w
mov [x_pixel],0 ; zero out x_pixel
jmp ??next_char
??overflow:
mov [startdraw],0 ; Indicate that there is no valid next pos.
??done:
mov eax,[startdraw] ; return this so calling routine
ret ; can figure out where to draw next.
ENDP Text_Print
;***********************************************************
END

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