mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2025-12-16 07:31:39 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
755
WIN32LIB/AUDIO/OLSOSDEC.ASM
Normal file
755
WIN32LIB/AUDIO/OLSOSDEC.ASM
Normal file
@@ -0,0 +1,755 @@
|
||||
;
|
||||
; 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 DW -1,-1,-1,-1,2,4,6,8
|
||||
DW -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 DW 7, 8, 9, 10, 11, 12, 13,14
|
||||
DW 16, 17, 19, 21, 23, 25, 28, 31
|
||||
DW 34, 37, 41, 45, 50, 55, 60, 66
|
||||
DW 73, 80, 88, 97, 107, 118, 130, 143
|
||||
DW 157, 173, 190, 209, 230, 253, 279, 307
|
||||
DW 337, 371, 408, 449, 494, 544, 598, 658
|
||||
DW 724, 796, 876, 963, 1060, 1166, 1282, 1411
|
||||
DW 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024
|
||||
DW 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484
|
||||
DW 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899
|
||||
DW 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794
|
||||
DW 32767
|
||||
|
||||
;dwCODECByteIndex DD 0 ; this is when to stop compressing
|
||||
;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 C 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 C General_sosCODECDecompressData:NEAR
|
||||
PROC General_sosCODECDecompressData C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
ARG wBytes:DWORD
|
||||
|
||||
local dwCODECBytesProcessed:dword ;bytes to decompress
|
||||
local dwCODECByteIndex:dword ;this is when to stop compressing
|
||||
; these need to be local if the function is to be reenterant
|
||||
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
|
||||
|
||||
;Check for 16 bit decompression
|
||||
|
||||
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
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
??mainloop:
|
||||
test [(sCompInfo ebx).dwSampleIndex],1 ;odd ??
|
||||
je short ??fetchToken ; if so get new token
|
||||
xor eax,eax ;else shift int codebuf
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
jmp short ??calcDifference
|
||||
|
||||
??fetchToken:
|
||||
xor eax,eax ;get a new token
|
||||
mov al,[esi] ;put in codebuf
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
inc esi
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax ;and then code
|
||||
|
||||
??calcDifference:
|
||||
mov [(sCompInfo ebx).dwDifference],0 ;reset diff
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep] ;cx is step value
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4
|
||||
add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
|
||||
|
||||
??no4:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no2:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no1:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8
|
||||
neg [(sCompInfo ebx).dwDifference] ;Negate diff
|
||||
|
||||
??no8:
|
||||
; 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 ??noOverflow
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflow:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflow
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflow:
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bit
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,2
|
||||
jmp short ??adjustIndex
|
||||
|
||||
??output8Bit:
|
||||
; output 8 bit sample
|
||||
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
inc edi
|
||||
|
||||
??adjustIndex:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex],ax ;check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex],8000h
|
||||
jb short ??checkOverflow
|
||||
mov [(sCompInfo ebx).wIndex],0 ;reset index to zero
|
||||
jmp short ??adjustStep
|
||||
|
||||
??checkOverflow:
|
||||
cmp [(sCompInfo ebx).wIndex],88 ;check if wIndex > 88
|
||||
jbe short ??adjustStep
|
||||
mov [(sCompInfo ebx).wIndex],88 ;reset index to 88
|
||||
|
||||
??adjustStep:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex],1
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
dec [dwCODECByteIndex]
|
||||
jne ??mainloop
|
||||
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,1
|
||||
mov ax,[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,1
|
||||
mov ax,[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,1
|
||||
mov ax,[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,1
|
||||
mov ax,[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
|
||||
|
||||
ENDP General_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 C 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 C 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
|
||||
Reference in New Issue
Block a user