mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2026-11-03 13:20:15 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
2082 files changed
+797727
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
Binary file not shown.
@@ -0,0 +1,104 @@
|
||||
;Codewright Project File (do not remove or modify this line)
|
||||
[ProjInit]
|
||||
ProjSetConfigFlags=0x00010140
|
||||
|
||||
[State]
|
||||
SysSetCwd='C:\PROJECTS\C&C\CODE\AUDIOMAK'
|
||||
SrchSetFlags=0x20aa
|
||||
FileSortMode=0x13
|
||||
StateWindowFrame=-1,0,1020,690,0x0981f5fa
|
||||
_StateWindow=0,0,1024,657,0x00000108,'c:\projects\c&c\code\audiomak\audiomak.cpp',240,7,244,32,32,0,32,32,32,32,8,65535,65535,1,0,'8514oem',65518,255,49,0,4,243,14,15,241,252,249,560,28,400,0,246,252,245,242,0,0,0,0,0
|
||||
_StateBuffer='c:\projects\c&c\code\audiomak\audiomak.cpp',0x0400048e,560,28,25,'4 7','',0x0,''
|
||||
_StateBuffer='c:\projects\c&c\code\audiomak\scode.asm',0x0400048e,30,64,25,'9 17','',0x0,''
|
||||
WrapEnable=0
|
||||
_StateHistory=SEARCH,'UncompBuffer','saved','orig','FALSE','tasm','TASM','tasm','ASSEMBLER','Decom','.asm.'
|
||||
_StateHistory=REPLACE,'audiomak','desired','long','unsigned','unsigned char','int','source'
|
||||
_StateHistory=FILELIST,'c:\projects\c&c\code\audiomak\cointabl.voc','c:\projects\c&c\code\audiomak\cointabl.wav','c:\projects\c&c\code\audiomak\globals.cpp','c:\projects\c&c\code\audiomak\bfeared.aud','c:\projects\c&c\code\audiomak\audiomak.asm','d:\library\source\soundio.c','c:\projects\c&c\code\audiomak\scode.asm','d:\library\wwlib.i','c:\projects\c&c\code\audiomak\makefile','d:\library\source\makefile'
|
||||
_StateHistory=GOTOMARK,'1','2','1'
|
||||
_StateHistory=GOTOLINE,'364','398','424','431','465'
|
||||
|
||||
[Editor]
|
||||
FilterDeleteList
|
||||
FilterAdd='Source Files','*.c;*.h;*.asm;*.inc',-1
|
||||
FilterAdd='All Files','*.*',-1
|
||||
FilterAdd='C++ Source Files','*.cpp;*.h;*.asm;*.inc',-1
|
||||
StateSetMarkLevel=7
|
||||
ClipboardSetTermStr='\r\n',0
|
||||
ClipboardEnableTermStr=1
|
||||
ClipboardSetSepStr='\r\n',0
|
||||
ClipboardEnableSepStr=1
|
||||
ScrapSetCount=1
|
||||
ExtColorsAssoc='.cpp',1
|
||||
ExtIndentEnableAssoc='.cpp',1
|
||||
ExtSetDelimiters=.cpp,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.h',1
|
||||
ExtIndentEnableAssoc='.h',1
|
||||
ExtSetDelimiters=.h,a-zA-Z_0-9
|
||||
ExtSetDelimiters=.*,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.int',1
|
||||
ExtIndentEnableAssoc='.int',1
|
||||
ExtSetDelimiters=.int,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.lst',1
|
||||
ExtIndentEnableAssoc='.lst',1
|
||||
ExtColorsAssoc='.asm',1
|
||||
ExtSetDelimiters=.asm,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.scr',1
|
||||
ExtIndentEnableAssoc='.scr',1
|
||||
ExtSetDelimiters=.scr,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.c',1
|
||||
ExtIndentEnableAssoc='.c',1
|
||||
ExtSetDelimiters=.c,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.ash',1
|
||||
ExtSetDelimiters=.ash,a-zA-Z_0-9
|
||||
ExtColorsAssoc='.i',1
|
||||
ExtIndentEnableAssoc='.i',1
|
||||
ExtSetDelimiters=.i,a-zA-Z_0-9
|
||||
Autosave=15,15
|
||||
AutosaveDir=''
|
||||
ExtSetUpdateDelay=10
|
||||
ExtDelayedColoring=1
|
||||
ExtCommentSearchLimit=200
|
||||
KeyDelay=635
|
||||
KeyRepeat=190
|
||||
BufSetGlobalBackupSpec='%b.bak'
|
||||
_FontDefault=0,'8514oem',65513,255,49,400,0
|
||||
SysSetDefault=DEFAULT_WINDOW_LEFT_MARGIN,4
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_MARGIN_COL,0
|
||||
SysSetDefault=DEFAULT_WINDOW_HINC,8
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_VIRTSPACES,32
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_VIRTLINES,32
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_TABS,32
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_SPACES,32
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_ELISION,0
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_EOL,32
|
||||
SysSetDefault=DEFAULT_WINDOW_VIS_EOF,32
|
||||
SysSetDefault=DEFAULT_WINDOW_SYSFLAGS,0x118
|
||||
SysSetDefault=DEFAULT_BUFFER_AUTOINDENT_MODE,0x0
|
||||
SysSetDefault=DEFAULT_BUFFER_BACKUP_SPEC,''
|
||||
SysSetDefault=DEFAULT_BUFFER_TABS,'5 9'
|
||||
SysSetDefault=DEFAULT_BUFFER_MAX_TAB,200
|
||||
SysSetDefault=DEFAULT_BUFFER_MAX_VLINES,25
|
||||
SysSetDefault=DEFAULT_BUFFER_SYSFLAGS,0xc800048e
|
||||
_RestoreSysFlags=0x0991f5fa, 0xfffffffc
|
||||
|
||||
[Compiler]
|
||||
BrowseSetFile='c:\projects\c&c\code\audiomak\audiomak.ptg'
|
||||
TagSetFile='c:\projects\c&c\code\audiomak\audiomak.tag'
|
||||
CompilerAddBuild='Microsoft Assembler',1073741880,'ftee masm -w2 -zi %r%e;','','','','','_MicrosoftErrorInfo','','%v%p','','','','','',0
|
||||
CompilerAddBuild='Borland C++',1073742089,'ftee make -DDEBUG=1 %r.obj','','','','','','','','ftee make -DDEBUG=1 %r.obj','','','','',49152
|
||||
CompilerAddBuild='Borland Turbo Assembler',1073741835,'ftee make -B %r.obj','','','','','','','','','','','','',16384
|
||||
CompilerAddBuild='$_cw_proj_hash_$',1073741875,'','ftee maker -B -DDEBUG=1 %r.obj','ftee maker -DDEBUG=1','','','_TasmErrorInfo','proj.err','c:\projects\c&c\code\audiomak','','_BorlandCppErrorInfo','','','',197376
|
||||
CompilerAddBuild='Default Project',1073741880,'','ftee make','ftee make','','','_ErrorInfoDefault','proj.err','%v%p','','','','','',0
|
||||
CompilerAddBuild='Microsoft C',1073741835,'ftee cl -c -AL -Gsw -Ow -Zpe %r%e','','','','','','','','','','','','',0
|
||||
CompilerAddBuild='Script',1073741880,'ftee make %r.inf','ftee make','ftee make','','','_BorlandCppErrorInfo','','','','','','','',0
|
||||
CompilerAddBuild='Zortech C++',1073741880,'ftee ztc -a -b -c -g -ml -W %r%e','','','','','_ZortechCppErrorInfo','','%v%p','','','','','',0
|
||||
CompilerAssign='Borland C++','.scr'
|
||||
CompilerAssign='Borland C++','.int'
|
||||
CompilerAssign='Borland C++','.c'
|
||||
CompilerNewExt=.prg
|
||||
CompilerAssign='Microsoft C','.h'
|
||||
CompilerAssign='Borland C++','.cpp'
|
||||
CompilerAssign='Default Project','.*'
|
||||
CompilerAssign='Zortech C++','.cxx'
|
||||
CompilerAssign='Borland Turbo Assembler','.asm'
|
||||
CompilerAssign='Borland C++','.hpp'
|
||||
@@ -0,0 +1,116 @@
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
.AUTODEPEND
|
||||
|
||||
OBJECTS = audiomak.obj scode.obj
|
||||
|
||||
.cpp.obj:
|
||||
bcc {$*.cpp }
|
||||
|
||||
.asm.obj:
|
||||
tasm $<,$&.obj
|
||||
|
||||
audiomak.exe: turboc.cfg tasm.cfg tlink.cfg $(OBJECTS)
|
||||
tlink @&&!
|
||||
c0l.obj $(OBJECTS)
|
||||
audiomak.exe
|
||||
audiomak.map
|
||||
CL.LIB MATHL.LIB EMU.LIB
|
||||
!
|
||||
|
||||
|
||||
####################################################################
|
||||
# Creates the TURBOC configuration file (also affects CPP.EXE)
|
||||
turboc.cfg: makefile
|
||||
copy &&!
|
||||
-v # Debugging output.
|
||||
-y
|
||||
-Vt # Virtual table pointer comes at end of class members (NEVER CHANGE).
|
||||
-Vb- # Always near pointer to virtual table.
|
||||
-a- # Structures are packed (not byte aligned).
|
||||
-b- # Enums as small as possible.
|
||||
-3 # Enable 386 instructions.
|
||||
-ml # Large model.
|
||||
-C- # Don't allow nested comments (DON'T CHANGE THIS).
|
||||
-c # Just compile -- don't link.
|
||||
-Jg # Template instances are merged to avoid duplicates.
|
||||
-Id:\bc4\include # Header search path.
|
||||
-P- # If extension = .CPP then compile as C++, otherwise treat as C.
|
||||
-w # Enable all warnings.
|
||||
# -w! # Treat all warnings as errors.
|
||||
-X- # Turn on autodependency checking.
|
||||
-RT # Enable run time type itentification.
|
||||
-x # Enable exception handling code.
|
||||
-k- # Optimize: Use abbreviated stack frame.
|
||||
-vi # Turns "inline" expansion on.
|
||||
-Z # Optimize: Supress redundant register loads.
|
||||
-Oi # Optimize: Helper functions expanded inline.
|
||||
-O # Optimize: Jump optimization.
|
||||
-Op # Optimize: Copy propagation to supress reloads.
|
||||
-Ov # Optimize: Speeds array indexing inside of loops.
|
||||
-Og # Optimize: Eliminates common subexpressions (globally).
|
||||
-Oc # Optimize: Eliminates common subexpressions (locally).
|
||||
-Ol # Optimize: Use REP instruction where possible.
|
||||
-d # Optimize: Duplicate strings are merged.
|
||||
-r # Try to put auto variables into registers.
|
||||
-V # Use smart virtual tables (only usable with BCC and TLINK).
|
||||
-dc- # Keep strings in the data segment (DON'T CHANGE THIS).
|
||||
-Ff # Put very very large objects into the far segment.
|
||||
-K2- # Treat "char" different from "signed char" or "unsigned char".
|
||||
-Oa # Optimize: Assumes no pointer aliasing (could cause bugs)!
|
||||
-R- # Don't include browser data (only used by IDE).
|
||||
# -Oe # Optimize: Global register allocation tracking enabled.
|
||||
# -Ob # Optimize: Dead code elimination.
|
||||
# -Om # Optimize: Remove invariant code from loops.
|
||||
# -p # Pascal calling convention default.
|
||||
# -pr # Regiser calling convention default.
|
||||
# -po # Pass "this" in registers when calling member functions.
|
||||
# -f- # Floating point prohibited.
|
||||
# -Yo # Compile as overlay module.
|
||||
# -Ox # Optimize: Execution speed.
|
||||
! turboc.cfg /Q
|
||||
|
||||
####################################################################
|
||||
# Creates TASM config file.
|
||||
tasm.cfg: makefile
|
||||
copy &&!
|
||||
/Zi # Include debug information into object file.
|
||||
/w+ICG
|
||||
/w-PDC
|
||||
/t
|
||||
/w2 # Maximum warning level.
|
||||
/ml # Large model.
|
||||
/w+
|
||||
/v
|
||||
/JIDEAL # Ideal mode.
|
||||
/JP386N # Enable 386 instructions.
|
||||
/UT300 # Force compatibility with old TASM.
|
||||
! tasm.cfg
|
||||
|
||||
####################################################################
|
||||
# Creates the TLINK.CFG file which implicitly controls linking.
|
||||
tlink.cfg: makefile
|
||||
copy &&!
|
||||
/Ld:\bc4\lib
|
||||
/v
|
||||
/c
|
||||
/e
|
||||
/Tde
|
||||
! tlink.cfg /Q
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/Zi
|
||||
/w+ICG
|
||||
/w-PDC
|
||||
/t
|
||||
/w2
|
||||
/ml
|
||||
/w+
|
||||
/v
|
||||
/JIDEAL
|
||||
/JP386N
|
||||
/UT300
|
||||
@@ -0,0 +1,5 @@
|
||||
/Ld:\bc4\lib
|
||||
/v
|
||||
/c
|
||||
/e
|
||||
/Tde
|
||||
@@ -0,0 +1,35 @@
|
||||
-v
|
||||
-y
|
||||
-Vt
|
||||
-Vb-
|
||||
-a-
|
||||
-b-
|
||||
-3
|
||||
-ml
|
||||
-C-
|
||||
-c
|
||||
-Jg
|
||||
-Id:\bc4\include
|
||||
-P-
|
||||
-w
|
||||
-X-
|
||||
-RT
|
||||
-x
|
||||
-k-
|
||||
-vi
|
||||
-Z
|
||||
-Oi
|
||||
-O
|
||||
-Op
|
||||
-Ov
|
||||
-Og
|
||||
-Oc
|
||||
-Ol
|
||||
-d
|
||||
-r
|
||||
-V
|
||||
-dc-
|
||||
-Ff
|
||||
-K2-
|
||||
-Oa
|
||||
-R-
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,675 @@
|
||||
/*
|
||||
** 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 : Data file creator. *
|
||||
* *
|
||||
* File Name : MIXFILE.CPP *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : August 6, 1994 *
|
||||
* *
|
||||
* Last Update : 10/27/94 [JLB] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Calc_CRC -- Calculate the CRC value of a block of data. *
|
||||
* compfunc -- Comparison function used by qsort(). *
|
||||
* DataClass::DataClass -- Constructor for a data file object node. *
|
||||
* DataClass::Process_Input -- Process the input file list and builds linked records. *
|
||||
* DataClass::Process_Output -- Creates the output data file from the component source files.*
|
||||
* DataClass::~DataClass -- Destructor for the data file object. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#pragma inline
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <dir.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
long Calc_CRC(void const *data, long size);
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** This is the data block controlling class. It is used for every data
|
||||
** file as well as processing the entire data file list.
|
||||
*/
|
||||
class DataClass {
|
||||
public:
|
||||
long CRC;
|
||||
static short Count;
|
||||
static long TotalSize;
|
||||
static char *ExtFrom[10];
|
||||
static char *ExtTo[10];
|
||||
static int ExtCount;
|
||||
static char *AltPath[10];
|
||||
static int AltPathCount;
|
||||
|
||||
DataClass(char const *filename);
|
||||
~DataClass(void);
|
||||
static void Process_Input(char const *infile, int quiet, int paths);
|
||||
static void Process_Output(char const *outfile);
|
||||
|
||||
char const * Output_Filename(void);
|
||||
char const * Input_Filename(void);
|
||||
|
||||
private:
|
||||
DataClass *Next; // Pointer to next file in chain.
|
||||
char *Filename; // Raw original filename.
|
||||
long Size; // Size of data element.
|
||||
long Offset; // Offset within mixfile for data start.
|
||||
int Index; // Write order number.
|
||||
|
||||
static DataClass *First;
|
||||
static int Quiet;
|
||||
static int Paths;
|
||||
};
|
||||
|
||||
char *DataClass::AltPath[10];
|
||||
char *DataClass::ExtFrom[10];
|
||||
char *DataClass::ExtTo[10];
|
||||
int DataClass::ExtCount = 0;
|
||||
int DataClass::AltPathCount = 0;
|
||||
short DataClass::Count = 0;
|
||||
DataClass * DataClass::First = 0;
|
||||
int DataClass::Quiet = FALSE;
|
||||
int DataClass::Paths = FALSE;
|
||||
long DataClass::TotalSize = 0;
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
class UsageError{}; // Parameter error or usage display desired.
|
||||
char *infile = 0;
|
||||
char *outfile = 0;
|
||||
int quiet = FALSE;
|
||||
int paths = FALSE;
|
||||
|
||||
/*
|
||||
** Banner message.
|
||||
*/
|
||||
printf("MIXFILE V1.4 (c)\n");
|
||||
|
||||
/*
|
||||
** Process the parameter list and dispatch the packing function.
|
||||
*/
|
||||
try {
|
||||
|
||||
/*
|
||||
** If not enough parameters were specified, then immediately
|
||||
** display the usage instructions.
|
||||
*/
|
||||
if (argc < 2) throw UsageError();
|
||||
|
||||
try {
|
||||
for (int index = 1; index < argc; index++) {
|
||||
char *arg = argv[index];
|
||||
|
||||
switch (*arg) {
|
||||
|
||||
/*
|
||||
** Process any command line switches.
|
||||
*/
|
||||
case '/':
|
||||
case '-':
|
||||
switch (toupper(arg[1])) {
|
||||
case 'Q':
|
||||
quiet = TRUE;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
paths = TRUE;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
if (DataClass::ExtCount >= sizeof(DataClass::ExtFrom)/sizeof(DataClass::ExtFrom[0])) {
|
||||
throw "Too many extensions specified";
|
||||
} else {
|
||||
char * ptr = strupr(strtok(&arg[2], "="));
|
||||
if (*ptr == '.') ptr++;
|
||||
DataClass::ExtFrom[DataClass::ExtCount] = ptr;
|
||||
|
||||
ptr = strupr(strtok(NULL, "=\r\n"));
|
||||
if (*ptr == '.') ptr++;
|
||||
DataClass::ExtTo[DataClass::ExtCount] = ptr;
|
||||
|
||||
DataClass::ExtCount++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
if (DataClass::AltPathCount >= sizeof(DataClass::AltPath)/sizeof(DataClass::AltPath[0])) {
|
||||
throw "Too many paths specified";
|
||||
} else {
|
||||
char dir[MAXDIR];
|
||||
|
||||
strcpy(dir, &arg[2]);
|
||||
if (dir[strlen(dir)-1] != '\\') {
|
||||
strcat(dir, "\\");
|
||||
}
|
||||
DataClass::AltPath[DataClass::AltPathCount++] = strupr(strdup(dir));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Unrecognized option flag";
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
** Process command line filenames for either input or output.
|
||||
*/
|
||||
default:
|
||||
if (outfile) throw "Unrecognized parameter";
|
||||
if (!infile) {
|
||||
FILE *file = fopen(arg, "r");
|
||||
if (!file) throw "Unable to open input file";
|
||||
fclose(file);
|
||||
infile = arg;
|
||||
continue;
|
||||
}
|
||||
if (!outfile) {
|
||||
outfile = arg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform a last minute check to make sure both an input and
|
||||
** output filename was specified. If not, then throw an
|
||||
** error.
|
||||
*/
|
||||
if (!outfile) throw "No output file specified";
|
||||
if (!infile) throw "No input file specified";
|
||||
|
||||
/*
|
||||
** Process the data.
|
||||
*/
|
||||
try {
|
||||
DataClass::Process_Input(infile, quiet, paths);
|
||||
DataClass::Process_Output(outfile);
|
||||
printf("Created mix file '%s'\nEmbedded objects = %d\nTotal file size = %ld\n", outfile, DataClass::Count, DataClass::TotalSize);
|
||||
}
|
||||
catch (char *message) {
|
||||
printf("\nERROR: %s.\n", message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This exception is called for any of the various fatal errors that
|
||||
** can occur while parsing the parameters.
|
||||
*/
|
||||
catch(char *message) {
|
||||
printf("\nERROR: %s.\n", message);
|
||||
throw UsageError();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This exception is thrown when the utility can't proceed and the
|
||||
** utility usage instructions are desired to be displayed.
|
||||
*/
|
||||
catch(UsageError) {
|
||||
printf("\nUSAGE: DATFILE <controlfile> <datafile>\n"
|
||||
"\n"
|
||||
" <controlfile> : list of filenames to pack\n"
|
||||
" <datafile> : output data filename\n"
|
||||
" Options\n"
|
||||
" -q : quiet operation\n"
|
||||
" -i<path> : alternate to find files\n"
|
||||
" -e<ext1>=<ext2> : changes file extensions from <ext1> to <ext2>\n"
|
||||
" -s : record paths in ID\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DataClass::Process_Input -- Process the input file list and builds linked records. *
|
||||
* *
|
||||
* This routine will process the list of files in the input file. It builds a linked *
|
||||
* list of DataClass objects. This routine is the initial process of creating a packed *
|
||||
* data file. * *
|
||||
* *
|
||||
* INPUT: infile -- Pointer to input filename. *
|
||||
* *
|
||||
* quiet -- Process quietly? *
|
||||
* *
|
||||
* paths -- Should the path of the filename be considered as part of its signature?*
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void DataClass::Process_Input(char const *infile, int quiet, int paths)
|
||||
{
|
||||
FILE *file; // Input file.
|
||||
static char buffer[MAXFILE];
|
||||
|
||||
Quiet = quiet;
|
||||
Paths = paths;
|
||||
|
||||
if (!infile) throw "No input file specified";
|
||||
|
||||
file = fopen(infile, "ra");
|
||||
if (!file) throw "Could not open input file";
|
||||
|
||||
if (!Quiet) {
|
||||
printf("Processing '%s'.\n", infile);
|
||||
}
|
||||
|
||||
/*
|
||||
** Process the source file list.
|
||||
*/
|
||||
try {
|
||||
for (;;) {
|
||||
int result = fscanf(file, "%s", buffer);
|
||||
if (result == EOF) break;
|
||||
|
||||
new DataClass(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This error handler is used if there are any errors that occur while
|
||||
** parsing and verifying the data block filenames. Errors can include
|
||||
** source filename errors as well as missing source files themselves.
|
||||
*/
|
||||
catch (char *message) {
|
||||
fclose(file);
|
||||
throw message;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DataClass::DataClass -- Constructor for a data file object node. *
|
||||
* *
|
||||
* This constructs a data file object node and links it into the list of object nodes. *
|
||||
* It performs a preliminary check on the existance of the the source file. *
|
||||
* *
|
||||
* INPUT: filename -- The filename of the object to add. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
* 10/27/94 JLB : Handles multiple data paths. *
|
||||
*=============================================================================================*/
|
||||
DataClass::DataClass(char const *filename)
|
||||
{
|
||||
static char buffer[100];
|
||||
|
||||
if (!filename) throw "NULL filename";
|
||||
|
||||
Filename = strdup(filename);
|
||||
strupr(Filename);
|
||||
|
||||
/*
|
||||
** Try to find the data file.
|
||||
*/
|
||||
FILE *datafile = fopen(Filename, "rb");
|
||||
if (!datafile) {
|
||||
|
||||
/*
|
||||
** If the file couldn't be found in the current directory, check
|
||||
** the alternate paths. If the alternate path is successful, then
|
||||
** alter the pathname to match and continue.
|
||||
*/
|
||||
for (int index = 0; index < AltPathCount; index++) {
|
||||
strcpy(buffer, AltPath[index]);
|
||||
strcat(buffer, Filename);
|
||||
datafile = fopen(buffer, "rb");
|
||||
if (datafile) {
|
||||
free(Filename);
|
||||
Filename = strdup(buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!datafile) {
|
||||
sprintf(buffer, "Could not find source file '%s'", Filename);
|
||||
throw buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine the CRC identifier for the filename, This can be either
|
||||
** the base filename or the complete path (as indicated by the command
|
||||
** line parameter).
|
||||
*/
|
||||
char const * name = Output_Filename();
|
||||
CRC = Calc_CRC(name, strlen(name));
|
||||
|
||||
/*
|
||||
** Find out the size of the source data file.
|
||||
*/
|
||||
fseek(datafile, 0, SEEK_END);
|
||||
long size = ftell(datafile);
|
||||
fclose(datafile);
|
||||
|
||||
if (size == -1) throw "Seek failure";
|
||||
Size = size;
|
||||
|
||||
Index = Count;
|
||||
Count++;
|
||||
Next = First;
|
||||
First = this;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DataClass::~DataClass -- Destructor for the data file object. *
|
||||
* *
|
||||
* This is the destructor for the data file object. It deallocates any memory allocated *
|
||||
* and de-links it from the list of file objects. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
DataClass::~DataClass(void)
|
||||
{
|
||||
if (Filename) {
|
||||
free(Filename);
|
||||
Filename = 0;
|
||||
}
|
||||
|
||||
Count--;
|
||||
DataClass *ptr = First;
|
||||
DataClass *prev = 0;
|
||||
while (ptr) {
|
||||
if (ptr == this) {
|
||||
if (prev) {
|
||||
prev->Next = Next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
prev = ptr;
|
||||
ptr = ptr->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* compfunc -- Comparison function used by qsort(). *
|
||||
* *
|
||||
* This is a support function that compares two file data objects against their CRC *
|
||||
* values. *
|
||||
* *
|
||||
* INPUT: ptr1 -- Pointer to object number 1. *
|
||||
* *
|
||||
* ptr2 -- Pointer to object number 2. *
|
||||
* *
|
||||
* OUTPUT: Returns with a logical comparison of object 1 to object 2. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int compfunc(const void *ptr1, const void *ptr2)
|
||||
{
|
||||
DataClass const *obj1 = *(DataClass const **)ptr1;
|
||||
DataClass const *obj2 = *(DataClass const **)ptr2;
|
||||
|
||||
if (obj1->CRC < obj2->CRC) {
|
||||
return (-1);
|
||||
}
|
||||
if (obj1->CRC > obj2->CRC) {
|
||||
return (1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DataClass::Process_Output -- Creates the output data file from the component source files. *
|
||||
* *
|
||||
* This is the final step in creation of the data output file. It writes the header *
|
||||
* block and then appends the appropriate files to the output file. *
|
||||
* *
|
||||
* INPUT: outname -- Pointer to the filename to use for output. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void DataClass::Process_Output(char const *outname)
|
||||
{
|
||||
FILE *outfile;
|
||||
|
||||
if (Count) {
|
||||
DataClass **array = new DataClass *[Count];
|
||||
|
||||
/*
|
||||
** Open the output file for creation.
|
||||
*/
|
||||
if (!outname) throw "Missing output filename";
|
||||
outfile = fopen(outname, "wb");
|
||||
if (!outfile) {
|
||||
throw "Unable to open output file";
|
||||
}
|
||||
|
||||
/*
|
||||
** Build a working array to the file objects.
|
||||
*/
|
||||
DataClass * ptr = First;
|
||||
for (int index = 0; index < Count; index++) {
|
||||
array[index] = ptr;
|
||||
ptr->Index = index;
|
||||
ptr = ptr->Next;
|
||||
}
|
||||
|
||||
/*
|
||||
** Precalculate the offset value for each data file will be.
|
||||
** This value will be inserted into the header block. This is
|
||||
** performed BEFORE the files are sorted because the data files
|
||||
** are written to disk in the order that they were specified.
|
||||
*/
|
||||
TotalSize = 0;
|
||||
for (index = 0; index < Count; index++) {
|
||||
array[index]->Offset = TotalSize;
|
||||
TotalSize += array[index]->Size;
|
||||
}
|
||||
|
||||
/*
|
||||
** Next, sort the data objects so that a binary search on CRC values
|
||||
** can be used for file retrieval.
|
||||
*/
|
||||
qsort(array, Count, sizeof(array[0]), compfunc);
|
||||
|
||||
/*
|
||||
** Output the header section of the data file. This contains
|
||||
** the count of objects contained, the CRC, and offset for each.
|
||||
*/
|
||||
fwrite(&Count, sizeof(Count), 1, outfile);
|
||||
fwrite(&TotalSize, sizeof(TotalSize), 1, outfile);
|
||||
for (index = 0; index < Count; index++) {
|
||||
fwrite(&array[index]->CRC, sizeof(array[index]->CRC), 1, outfile);
|
||||
fwrite(&array[index]->Offset, sizeof(array[index]->Offset), 1, outfile);
|
||||
fwrite(&array[index]->Size, sizeof(array[index]->Size), 1, outfile);
|
||||
}
|
||||
|
||||
TotalSize += sizeof(Count) + sizeof(TotalSize) + (Count*12);
|
||||
|
||||
if (!Quiet) {
|
||||
printf("size CRC Filename\n");
|
||||
printf("------ -------- -------------------------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** Now write the actual data -- one file at a time in the order that they were
|
||||
** originally specified.
|
||||
*/
|
||||
for (int order = 0; order < Count; order++) {
|
||||
for (index = 0; index < Count; index++) {
|
||||
DataClass * entry = array[index];
|
||||
|
||||
if (entry->Index == order) {
|
||||
FILE *infile;
|
||||
long size;
|
||||
static char buffer[1024*30];
|
||||
|
||||
if (!Quiet) {
|
||||
printf("%-8ld [%08lX] %s\n", entry->Size, entry->CRC, entry->Output_Filename());
|
||||
}
|
||||
|
||||
size = entry->Size;
|
||||
infile = fopen(entry->Input_Filename(), "rb");
|
||||
while (size > 0) {
|
||||
int count;
|
||||
|
||||
count = (size < sizeof(buffer)) ? (int)size : sizeof(buffer);
|
||||
count = fread(buffer, sizeof(buffer[0]), count, infile);
|
||||
fwrite(buffer, sizeof(buffer[0]), count, outfile);
|
||||
size -= count;
|
||||
if (!count) break; // Hmm..
|
||||
}
|
||||
fclose(infile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Calc_CRC -- Calculate the CRC value of a block of data. *
|
||||
* *
|
||||
* This routine is used to create a CRC value from a string of data bytes. *
|
||||
* *
|
||||
* INPUT: data -- Pointer to the data bytes to calculate the CRC value for. *
|
||||
* *
|
||||
* size -- The number of bytes in the data block. *
|
||||
* *
|
||||
* OUTPUT: Returns with the CRC value of the buffer specified. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/06/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
long Calc_CRC(void const *data, long size)
|
||||
{
|
||||
long crc = 0; // Accumulating CRC value.
|
||||
long const *ptr = static_cast<long const *>(data);
|
||||
|
||||
/*
|
||||
** Process the bulk of the data (4 bytes at a time).
|
||||
*/
|
||||
for (; size > sizeof(long); size -= sizeof(long)) {
|
||||
long temp = *ptr++;
|
||||
asm {
|
||||
mov eax,crc
|
||||
rol eax,1
|
||||
add eax,temp
|
||||
mov crc,eax
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If there are any remainder bytes, then process them
|
||||
** as a group of four, but the trailing left over bytes
|
||||
** are forced to be NULL.
|
||||
*/
|
||||
if (size) {
|
||||
long temp = 0;
|
||||
|
||||
memcpy(&temp, ptr, (size_t)size);
|
||||
asm {
|
||||
mov eax,crc
|
||||
rol eax,1
|
||||
add eax,temp
|
||||
mov crc,eax
|
||||
}
|
||||
}
|
||||
|
||||
return (crc);
|
||||
}
|
||||
|
||||
|
||||
char const * DataClass::Output_Filename(void)
|
||||
{
|
||||
char file[MAXFILE];
|
||||
char ext[MAXEXT];
|
||||
char path[MAXPATH];
|
||||
char drive[MAXDRIVE];
|
||||
static char filename[255];
|
||||
|
||||
/*
|
||||
** Break the original filename into its component parts.
|
||||
*/
|
||||
fnsplit(Filename, drive, path, file, ext);
|
||||
|
||||
/*
|
||||
** Substitute the extension if a substitution is called for.
|
||||
*/
|
||||
for (int index = 0; index < ExtCount; index++) {
|
||||
if (stricmp(ExtFrom[index], &ext[1]) == 0) {
|
||||
strcpy(&ext[1], ExtTo[index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Strip the path from the filename if path stripping is enabled.
|
||||
*/
|
||||
if (!Paths) {
|
||||
fnmerge(filename, NULL, NULL, file, ext);
|
||||
} else {
|
||||
fnmerge(filename, drive, path, file, ext);
|
||||
}
|
||||
return(&filename[0]);
|
||||
}
|
||||
|
||||
|
||||
char const * DataClass::Input_Filename(void)
|
||||
{
|
||||
return(Filename);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user