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:
322
TOOLS/AUDIOMAK/SCODE.ASM
Normal file
322
TOOLS/AUDIOMAK/SCODE.ASM
Normal file
@@ -0,0 +1,322 @@
|
||||
;
|
||||
; 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/>.
|
||||
;
|
||||
|
||||
|
||||
IDEAL
|
||||
IDEAL_MODE EQU 1
|
||||
VERSION T300 ; Code written for V3.0 TASM version.
|
||||
IDEAL
|
||||
P386N ; target machine.
|
||||
SMART ; Enable optimizations.
|
||||
WARN ; Full warnings.
|
||||
LOCALS ??
|
||||
MODEL LARGE @filename
|
||||
; INCLUDE "d:\library\wwlib.i"
|
||||
|
||||
CODE_2BIT EQU 0
|
||||
CODE_4BIT EQU 1
|
||||
CODE_RAW EQU 2
|
||||
CODE_SILENCE EQU 3
|
||||
MAGICNUMBER EQU 00000DEAFh
|
||||
MAGICNUMBER2 EQU 0BABEBABEh
|
||||
|
||||
; VERSION T300 ; Code written for V3.0 TASM version.
|
||||
; P386N ; target machine.
|
||||
; MODEL LARGE @filename
|
||||
; WARN ; Full warnings.
|
||||
; LOCALS ??
|
||||
|
||||
CODESEG
|
||||
|
||||
_2bitdecode DB -2, -1, 0, 1
|
||||
;_2bitdecode DB -2, -1, 1, 2
|
||||
_4bitdecode DB -9,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8
|
||||
;_4bitdecode DB -16,-13,-10,-8,-6,-4,-2,-1,1,2,4,6,8,10,13,16
|
||||
|
||||
GLOBAL C Decompress_Frame:FAR
|
||||
PROC C Decompress_Frame FAR USES bx cx edx ds si es di bp
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG count:WORD
|
||||
|
||||
LOCAL previous:BYTE
|
||||
LOCAL incount:WORD
|
||||
|
||||
; Initialize counter for number of bytes read from source.
|
||||
mov [incount],0
|
||||
|
||||
; Verify parameters for legality.
|
||||
cmp [source],0
|
||||
je ??fini
|
||||
cmp [dest],0
|
||||
je ??fini
|
||||
cmp [count],0
|
||||
je ??fini
|
||||
|
||||
; Fetch parameter values into working registers.
|
||||
lds si,[source] ; Pointer to source data.
|
||||
les di,[dest] ; Pointer to destination data.
|
||||
mov cx,[count] ; Number of bytes to fill dest buffer.
|
||||
mov dl,080h ; Previous sample (starting value).
|
||||
|
||||
??mainloop:
|
||||
; Check to see if the destination is full. Exit if so.
|
||||
cmp cx,0
|
||||
jle ??fini
|
||||
|
||||
; Fetch code byte from input stream.
|
||||
xor ah,ah
|
||||
mov al,[ds:si]
|
||||
inc [incount]
|
||||
inc si
|
||||
shl ax,2 ; AH contains code.
|
||||
shr al,2 ; AL contains sub-code data.
|
||||
|
||||
; Check to see if a raw sequence follows.
|
||||
cmp ah,CODE_RAW
|
||||
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 [es:di],dl
|
||||
dec cx
|
||||
inc di
|
||||
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 bx,cx
|
||||
xor ah,ah
|
||||
inc al
|
||||
mov cx,ax
|
||||
shr cx,1
|
||||
rep movsw
|
||||
adc cx,cx
|
||||
rep movsb
|
||||
mov cx,bx
|
||||
add [incount],ax
|
||||
sub cx,ax
|
||||
dec di
|
||||
mov dl,[es:di] ; Set "previous" value.
|
||||
inc di
|
||||
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:
|
||||
; Fetch nibble packed delta codes.
|
||||
mov ah,[ds:si]
|
||||
mov bl,ah
|
||||
inc [incount]
|
||||
inc si
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
and bx,00001111b
|
||||
|
||||
add dl,[cs:_4bitdecode+bx] ; Add in delta
|
||||
pushf
|
||||
cmp [cs:_4bitdecode+bx],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,[cs:_4bitdecode+bx] ; Add in delta
|
||||
pushf
|
||||
cmp [cs:_4bitdecode+bx],0
|
||||
jl short ??neg2
|
||||
popf
|
||||
jnc short ??ok2
|
||||
mov dh,0FFh
|
||||
jmp short ??ok2
|
||||
??neg2:
|
||||
popf
|
||||
jc short ??ok2
|
||||
xor dh,dh
|
||||
??ok2:
|
||||
|
||||
; Output the two sample bytes.
|
||||
mov [es:di],dx
|
||||
sub cx,2
|
||||
add di,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:
|
||||
; Fetch packed delta codes.
|
||||
mov ah,[ds:si]
|
||||
inc [incount]
|
||||
inc si
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
mov bl,ah
|
||||
and bx,000011b
|
||||
add dl,[cs:_2bitdecode+bx] ; Add in delta
|
||||
|
||||
pushf
|
||||
cmp [cs:_2bitdecode+bx],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 bx,2
|
||||
and bl,00000011b
|
||||
add dl,[cs:_2bitdecode+bx] ; Add in delta
|
||||
|
||||
pushf
|
||||
cmp [cs:_2bitdecode+bx],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 bx,4
|
||||
and bl,00000011b
|
||||
add dl,[cs:_2bitdecode+bx] ; Add in delta
|
||||
|
||||
pushf
|
||||
cmp [cs:_2bitdecode+bx],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 bx,6
|
||||
and bl,00000011b
|
||||
add dl,[cs:_2bitdecode+bx] ; Add in delta
|
||||
|
||||
pushf
|
||||
cmp [cs:_2bitdecode+bx],0
|
||||
jl short ??neg6
|
||||
popf
|
||||
jnc short ??ok6
|
||||
mov dl,0FFh
|
||||
jmp short ??ok6
|
||||
??neg6:
|
||||
popf
|
||||
jc short ??ok6
|
||||
xor dl,dl
|
||||
??ok6:
|
||||
|
||||
;mov dh,dl
|
||||
ror edx,8
|
||||
|
||||
; Output the two sample bytes.
|
||||
mov [es:di],edx
|
||||
sub cx,4
|
||||
add di,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 bh,bh
|
||||
mov bl,al
|
||||
mov al,dl
|
||||
sub cx,bx
|
||||
xchg cx,bx
|
||||
rep stosb
|
||||
mov cx,bx
|
||||
jmp ??mainloop
|
||||
|
||||
; Final cleanup and exit.
|
||||
??fini:
|
||||
mov ax,[incount]
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user