mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-20 18:09:41 +02:00
Grabbed LCW_Comp from Chronoshift to fix editor save bug with compression.
This commit is contained in:
@@ -1,286 +0,0 @@
|
|||||||
;
|
|
||||||
; Copyright 2020 Electronic Arts Inc.
|
|
||||||
;
|
|
||||||
; TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
|
||||||
|
|
||||||
; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
|
||||||
; in the hope that it will be useful, but with permitted additional restrictions
|
|
||||||
; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
|
||||||
; distributed with this program. You should have received a copy of the
|
|
||||||
; GNU General Public License along with permitted additional restrictions
|
|
||||||
; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
|
|
||||||
|
|
||||||
; $Header: F:\projects\c&c0\vcs\code\lcwcomp.asv 5.0 11 Nov 1996 09:40:34 JOE_BOSTIC $
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 routine *
|
|
||||||
;* *
|
|
||||||
;* File Name : COMPRESS.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Louis Castle *
|
|
||||||
;* *
|
|
||||||
;* Last Update : 20 August, 1990 [CY] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
;IDEAL
|
|
||||||
;P386
|
|
||||||
;MODEL USE32 FLAT
|
|
||||||
|
|
||||||
.MODEL FLAT
|
|
||||||
|
|
||||||
;GLOBAL C LCW_Comp :NEAR
|
|
||||||
externdef C LCW_Comp:near
|
|
||||||
|
|
||||||
;CODESEG
|
|
||||||
.code
|
|
||||||
|
|
||||||
; ----------------------------------------------------------------
|
|
||||||
;
|
|
||||||
; Here are prototypes for the routines defined within this module:
|
|
||||||
;
|
|
||||||
; ULONG LCW_Compress(BYTE *source,BYTE *dest, ULONG length);
|
|
||||||
;
|
|
||||||
; ----------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;***********************************************************
|
|
||||||
;
|
|
||||||
; ULONG LCW_Compress(BYTE *source, BYTE *dest, ULONG length)
|
|
||||||
;
|
|
||||||
; returns the size of the compressed data in bytes
|
|
||||||
;
|
|
||||||
;*
|
|
||||||
LCW_Comp proc C source:DWORD, dest:DWORD, datasize:DWORD
|
|
||||||
|
|
||||||
;USES ebx,ecx,edx,edi,esi
|
|
||||||
|
|
||||||
;ARG source:DWORD
|
|
||||||
;ARG dest:DWORD
|
|
||||||
;ARG datasize:DWORD
|
|
||||||
|
|
||||||
LOCAL inlen:DWORD
|
|
||||||
LOCAL a1stdest:DWORD
|
|
||||||
LOCAL a1stsrc:DWORD
|
|
||||||
LOCAL lenoff:DWORD
|
|
||||||
LOCAL ndest:DWORD
|
|
||||||
LOCAL count:DWORD
|
|
||||||
LOCAL matchoff:DWORD
|
|
||||||
LOCAL end_of_data:DWORD
|
|
||||||
|
|
||||||
pushad
|
|
||||||
|
|
||||||
cld
|
|
||||||
mov edi,[dest]
|
|
||||||
mov esi,[source]
|
|
||||||
mov edx,[datasize] ; get length of data to compress
|
|
||||||
|
|
||||||
; mov ax,ds
|
|
||||||
; mov es,ax
|
|
||||||
|
|
||||||
;
|
|
||||||
; compress data to the following codes in the format b = byte, w = word
|
|
||||||
; n = byte code pulled from compressed data
|
|
||||||
; Bit field of n command description
|
|
||||||
; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
|
|
||||||
; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
|
|
||||||
; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
|
|
||||||
; n=11111111,w1,w2 long run run w1 bytes from offset w2
|
|
||||||
; n=10000000 end end of data reached
|
|
||||||
;
|
|
||||||
cld ; make sure all string commands are forward
|
|
||||||
mov ebx,esi
|
|
||||||
add ebx,edx
|
|
||||||
mov [end_of_data],ebx
|
|
||||||
mov [inlen],1 ; set the in-length flag
|
|
||||||
mov [a1stdest],edi ; save original dest offset for size calc
|
|
||||||
mov [a1stsrc],esi ; save offset of first byte of data
|
|
||||||
mov [lenoff],edi ; save the offset of the legth of this len
|
|
||||||
sub eax,eax
|
|
||||||
mov al,081h ; the first byte is always a len
|
|
||||||
stosb ; write out a len of 1
|
|
||||||
lodsb ; get the byte
|
|
||||||
stosb ; save it
|
|
||||||
_loop:
|
|
||||||
mov [ndest],edi ; save offset of compressed data
|
|
||||||
mov edi,[a1stsrc] ; get the offset to the first byte of data
|
|
||||||
mov [count],1 ; set the count of run to 0
|
|
||||||
searchloop:
|
|
||||||
sub eax,eax
|
|
||||||
mov al,[esi] ; get the current byte of data
|
|
||||||
cmp al,[esi+64]
|
|
||||||
jne short notrunlength
|
|
||||||
|
|
||||||
mov ebx,edi
|
|
||||||
|
|
||||||
mov edi,esi
|
|
||||||
mov ecx,[end_of_data]
|
|
||||||
sub ecx,edi
|
|
||||||
repe scasb
|
|
||||||
dec edi
|
|
||||||
mov ecx,edi
|
|
||||||
sub ecx,esi
|
|
||||||
cmp ecx,65
|
|
||||||
jb short notlongenough
|
|
||||||
|
|
||||||
mov [DWORD PTR inlen],0 ; clear the in-length flag
|
|
||||||
mov esi,edi
|
|
||||||
mov edi,[ndest] ; get the offset of our compressed data
|
|
||||||
|
|
||||||
mov ah,al
|
|
||||||
mov al,0FEh
|
|
||||||
stosb
|
|
||||||
xchg ecx,eax
|
|
||||||
stosw
|
|
||||||
mov al,ch
|
|
||||||
stosb
|
|
||||||
|
|
||||||
mov [ndest],edi ; save offset of compressed data
|
|
||||||
mov edi,ebx
|
|
||||||
jmp searchloop
|
|
||||||
notlongenough:
|
|
||||||
mov edi,ebx
|
|
||||||
notrunlength:
|
|
||||||
|
|
||||||
oploop:
|
|
||||||
mov ecx,esi ; get the address of the last byte +1
|
|
||||||
sub ecx,edi ; get the total number of bytes left to comp
|
|
||||||
jz short searchdone
|
|
||||||
|
|
||||||
repne scasb ; look for a match
|
|
||||||
jne short searchdone ; if we don't find one we're done
|
|
||||||
|
|
||||||
mov ebx,[count]
|
|
||||||
mov ah,[esi+ebx-1]
|
|
||||||
cmp ah,[edi+ebx-2]
|
|
||||||
|
|
||||||
jne oploop
|
|
||||||
|
|
||||||
mov edx,esi ; save this spot for the next search
|
|
||||||
mov ebx,edi ; save this spot for the length calc
|
|
||||||
dec edi ; back up one for compare
|
|
||||||
mov ecx,[end_of_data] ; get the end of data
|
|
||||||
sub ecx,esi ; sub current source for max len
|
|
||||||
|
|
||||||
repe cmpsb ; see how many bytes match
|
|
||||||
|
|
||||||
; start of change MH 9-24-91
|
|
||||||
jne short notend ; if found mismatch then di - bx = match count
|
|
||||||
|
|
||||||
inc edi ; else cx = 0 and di + 1 - bx = match count
|
|
||||||
|
|
||||||
notend:
|
|
||||||
; end of change MH 9-24-91
|
|
||||||
|
|
||||||
mov esi,edx ; restore si
|
|
||||||
mov eax,edi ; get the dest
|
|
||||||
sub eax,ebx ; sub the start for total bytes that match
|
|
||||||
mov edi,ebx ; restore dest
|
|
||||||
cmp eax,[count] ; see if its better than before
|
|
||||||
jb searchloop ; if not keep looking
|
|
||||||
|
|
||||||
mov [count],eax ; if so keep the count
|
|
||||||
dec ebx ; back it up for the actual match offset
|
|
||||||
mov [matchoff],ebx ; save the offset for later
|
|
||||||
jmp searchloop ; loop until we searched it all
|
|
||||||
|
|
||||||
searchdone:
|
|
||||||
|
|
||||||
mov ecx,[count] ; get the count of the longest run
|
|
||||||
mov edi,[ndest] ; get the offset of our compressed data
|
|
||||||
cmp ecx,2 ; see if its not enough run to matter
|
|
||||||
jbe short lenin ; if its 0,1, or 2 its too small
|
|
||||||
|
|
||||||
cmp ecx,10 ; if not, see if it would fit in a short
|
|
||||||
ja short medrun ; if not, see if its a medium run
|
|
||||||
|
|
||||||
mov eax,esi ; if its short get the current address
|
|
||||||
sub eax,[matchoff] ; sub the offset of the match
|
|
||||||
cmp eax,0FFFh ; if its less than 12 bits its a short
|
|
||||||
ja short medrun ; if its not, its a medium
|
|
||||||
|
|
||||||
shortrun:
|
|
||||||
sub ebx,ebx
|
|
||||||
mov bl,cl ; get the length (3-10)
|
|
||||||
sub bl,3 ; sub 3 for a 3 bit number 0-7
|
|
||||||
shl bl,4 ; shift it left 4
|
|
||||||
add ah,bl ; add in the length for the high nibble
|
|
||||||
xchg ah,al ; reverse the bytes for a word store
|
|
||||||
jmp short srunnxt ; do the run fixup code
|
|
||||||
|
|
||||||
medrun:
|
|
||||||
cmp ecx,64 ; see if its a short run
|
|
||||||
ja short longrun ; if not, oh well at least its long
|
|
||||||
|
|
||||||
sub cl,3 ; back down 3 to keep it in 6 bits
|
|
||||||
or cl,0C0h ; the highest bits are always on
|
|
||||||
mov al,cl ; put it in al for the stosb
|
|
||||||
stosb ; store it
|
|
||||||
jmp short medrunnxt ; do the run fixup code
|
|
||||||
|
|
||||||
lenin:
|
|
||||||
cmp [DWORD PTR inlen],0 ; is it doing a length?
|
|
||||||
jnz short len ; if so, skip code
|
|
||||||
|
|
||||||
lenin1:
|
|
||||||
mov [lenoff],edi ; save the length code offset
|
|
||||||
mov al,80h ; set the length to 0
|
|
||||||
stosb ; save it
|
|
||||||
|
|
||||||
len:
|
|
||||||
mov ebx,[lenoff] ; get the offset of the length code
|
|
||||||
cmp BYTE PTR [ebx],0BFh ; see if its maxed out
|
|
||||||
je lenin1 ; if so put out a new len code
|
|
||||||
|
|
||||||
stolen:
|
|
||||||
inc BYTE PTR [ebx] ; inc the count code
|
|
||||||
lodsb ; get the byte
|
|
||||||
stosb ; store it
|
|
||||||
mov DWORD PTR [inlen],1 ; we are now in a length so save it
|
|
||||||
jmp short nxt ; do the next code
|
|
||||||
|
|
||||||
longrun:
|
|
||||||
mov al,0ffh ; its a long so set a code of FF
|
|
||||||
stosb ; store it
|
|
||||||
|
|
||||||
mov eax,[count] ; send out the count
|
|
||||||
stosw ; store it
|
|
||||||
medrunnxt:
|
|
||||||
mov eax,[matchoff] ; get the offset
|
|
||||||
sub eax,[a1stsrc] ; make it relative tot he start of data
|
|
||||||
srunnxt:
|
|
||||||
stosw ; store it
|
|
||||||
; this code common to all runs
|
|
||||||
add esi,[count] ; add in the length of the run to the source
|
|
||||||
mov [DWORD PTR inlen],0 ; set the in leght flag to false
|
|
||||||
|
|
||||||
;=======================================================================
|
|
||||||
|
|
||||||
nxt:
|
|
||||||
cmp esi,[end_of_data] ; see if we did the whole pic
|
|
||||||
jae short _out ; if so, cool! were done
|
|
||||||
|
|
||||||
jmp _loop
|
|
||||||
|
|
||||||
_out:
|
|
||||||
mov ax,080h ; remember to send an end of data code
|
|
||||||
stosb ; store it
|
|
||||||
mov eax,edi ; get the last compressed address
|
|
||||||
sub eax,[a1stdest] ; sub the first for the compressed size
|
|
||||||
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
LCW_Comp endp
|
|
||||||
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
* Find_Child_Node -- Find a matching dictionary entry. *
|
* Find_Child_Node -- Find a matching dictionary entry. *
|
||||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -534,3 +535,175 @@ int LZW_Uncompress(Buffer & inbuff, Buffer & outbuff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// jmarshall: This function is from OmniBlade at Chronoshift
|
||||||
|
// https://github.com/TheAssemblyArmada/Chronoshift/blob/develop/src/game/common/lcw.cpp
|
||||||
|
/**
|
||||||
|
* @brief Compresses data to the proprietary LCW format used in many games developed by Westwood Studios.
|
||||||
|
* @warning Worst case can have the compressed data larger than the original.
|
||||||
|
*/
|
||||||
|
extern "C" int LCW_Comp(const void* src, void* dst, unsigned int bytes)
|
||||||
|
{
|
||||||
|
//captainslog_assert(src != nullptr);
|
||||||
|
//captainslog_assert(dst != nullptr);
|
||||||
|
|
||||||
|
if (!bytes) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decide if we are going to do relative offsets for 3 and 5 byte commands
|
||||||
|
bool relative = bytes > UINT16_MAX;
|
||||||
|
|
||||||
|
const uint8_t* getp = static_cast<const uint8_t*>(src);
|
||||||
|
uint8_t* putp = static_cast<uint8_t*>(dst);
|
||||||
|
const uint8_t* getstart = getp;
|
||||||
|
const uint8_t* getend = getp + bytes;
|
||||||
|
uint8_t* putstart = putp;
|
||||||
|
|
||||||
|
// captainslog_debug("LCW Compression... ");
|
||||||
|
|
||||||
|
// relative LCW starts with 0 to flag as relative for decoder
|
||||||
|
if (relative) {
|
||||||
|
// captainslog_debug("LCW Relative compressor.");
|
||||||
|
*putp++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a starting cmd1 and set bool to have cmd1 in progress
|
||||||
|
uint8_t* cmd_onep = putp;
|
||||||
|
*putp++ = 0x81;
|
||||||
|
*putp++ = *getp++;
|
||||||
|
bool cmd_one = true;
|
||||||
|
|
||||||
|
// Compress data
|
||||||
|
while (getp < getend) {
|
||||||
|
// Is RLE encode (4bytes) worth evaluating?
|
||||||
|
if (getend - getp > 64 && *getp == *(getp + 64)) {
|
||||||
|
// RLE run length is encoded as a short so max is UINT16_MAX
|
||||||
|
const uint8_t* rlemax = (getend - getp) < UINT16_MAX ? getend : getp + UINT16_MAX;
|
||||||
|
const uint8_t* rlep;
|
||||||
|
|
||||||
|
for (rlep = getp + 1; *rlep == *getp && rlep < rlemax; ++rlep)
|
||||||
|
;
|
||||||
|
|
||||||
|
uint16_t run_length = rlep - getp;
|
||||||
|
|
||||||
|
// If run length is long enough, write the command and start loop again
|
||||||
|
if (run_length >= 0x41) {
|
||||||
|
// captainslog_debug("0b11111110 Source Pos %ld, Dest Pos %ld, Count %d", getp - getstart, putp - putstart,
|
||||||
|
// run_length); write 4byte command 0b11111110
|
||||||
|
cmd_one = false;
|
||||||
|
*putp++ = 0xFE;
|
||||||
|
*putp++ = run_length;
|
||||||
|
*putp++ = run_length >> 8;
|
||||||
|
*putp++ = *getp;
|
||||||
|
getp = rlep;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// current block size for an offset copy
|
||||||
|
int block_size = 0;
|
||||||
|
const uint8_t* offstart;
|
||||||
|
|
||||||
|
// Set where we start looking for matching runs.
|
||||||
|
if (relative) {
|
||||||
|
offstart = (getp - getstart) < UINT16_MAX ? getstart : getp - UINT16_MAX;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offstart = getstart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for matching runs
|
||||||
|
const uint8_t* offchk = offstart;
|
||||||
|
const uint8_t* offsetp = getp;
|
||||||
|
while (offchk < getp) {
|
||||||
|
// Move offchk to next matching position
|
||||||
|
while (offchk < getp && *offchk != *getp) {
|
||||||
|
++offchk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the checking pointer has reached current pos, break
|
||||||
|
if (offchk >= getp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find out how long the run of matches goes for
|
||||||
|
//<= because it can consider the current pixel as part of a run
|
||||||
|
int i;
|
||||||
|
for (i = 1; &getp[i] < getend; ++i) {
|
||||||
|
if (offchk[i] != getp[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= block_size) {
|
||||||
|
block_size = i;
|
||||||
|
offsetp = offchk;
|
||||||
|
}
|
||||||
|
|
||||||
|
++offchk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decide what encoding to use for current run
|
||||||
|
if (block_size <= 2) {
|
||||||
|
// short copy 0b10??????
|
||||||
|
// check we have an existing 1 byte command and if its value is still
|
||||||
|
// small enough to handle additional bytes
|
||||||
|
// start a new command if current one doesn't have space or we don't
|
||||||
|
// have one to continue
|
||||||
|
if (cmd_one && *cmd_onep < 0xBF) {
|
||||||
|
// increment command value
|
||||||
|
++* cmd_onep;
|
||||||
|
// captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", getp - getstart, cmd_onep - putstart,
|
||||||
|
// *cmd_onep - 0x80);
|
||||||
|
*putp++ = *getp++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmd_onep = putp;
|
||||||
|
// captainslog_debug("0b10?????? Source Pos %ld, Dest Pos %ld, Count %d", getp - getstart, cmd_onep - putstart, 1);
|
||||||
|
*putp++ = 0x81;
|
||||||
|
*putp++ = *getp++;
|
||||||
|
cmd_one = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t offset;
|
||||||
|
uint16_t rel_offset = getp - offsetp;
|
||||||
|
if (block_size > 0xA || (rel_offset > 0xFFF)) {
|
||||||
|
// write 5 byte command 0b11111111
|
||||||
|
if (block_size > 0x40) {
|
||||||
|
// captainslog_debug("0b11111111 Source Pos %ld, Dest Pos %ld, Count %d, ", getp - getstart, putp - putstart,
|
||||||
|
// block_size);
|
||||||
|
*putp++ = 0xFF;
|
||||||
|
*putp++ = block_size;
|
||||||
|
*putp++ = block_size >> 8;
|
||||||
|
// write 3 byte command 0b11??????
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// captainslog_debug("0b11?????? Source Pos %ld, Dest Pos %ld, Count %d, ", getp - getstart, putp - putstart,
|
||||||
|
// block_size);
|
||||||
|
*putp++ = (block_size - 3) | 0xC0;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = relative ? rel_offset : offsetp - getstart;
|
||||||
|
// captainslog_debug("Offset %d", offset);
|
||||||
|
// write 2 byte command? 0b0???????
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// captainslog_debug("0b0??????? Source Pos %ld, Dest Pos %ld, Count %d, ", getp - getstart, putp - putstart,
|
||||||
|
// block_size); uint8_t cmd_two_val = 16 * (block_size - 3) + (rel_offset >> 8); captainslog_debug("Offset %d",
|
||||||
|
// rel_offset);
|
||||||
|
offset = rel_offset << 8 | (16 * (block_size - 3) + (rel_offset >> 8));
|
||||||
|
}
|
||||||
|
*putp++ = offset;
|
||||||
|
*putp++ = offset >> 8;
|
||||||
|
getp += block_size;
|
||||||
|
cmd_one = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write final 0x80, this is why its also known as format80 compression
|
||||||
|
*putp++ = 0x80;
|
||||||
|
return putp - putstart;
|
||||||
|
}
|
||||||
|
// jmarshall end
|
||||||
@@ -793,7 +793,6 @@
|
|||||||
<ClInclude Include="XSTRAW.H" />
|
<ClInclude Include="XSTRAW.H" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<MASM Include="LCWCOMP.ASM" />
|
|
||||||
<MASM Include="MMX.ASM" />
|
<MASM Include="MMX.ASM" />
|
||||||
<MASM Include="TXTPRNT.ASM" />
|
<MASM Include="TXTPRNT.ASM" />
|
||||||
<MASM Include="Win32Lib\LCWCOMP.ASM">
|
<MASM Include="Win32Lib\LCWCOMP.ASM">
|
||||||
|
|||||||
@@ -1947,9 +1947,6 @@
|
|||||||
<MASM Include="Win32Lib\LCWCOMP.ASM">
|
<MASM Include="Win32Lib\LCWCOMP.ASM">
|
||||||
<Filter>Source Files\win32lib</Filter>
|
<Filter>Source Files\win32lib</Filter>
|
||||||
</MASM>
|
</MASM>
|
||||||
<MASM Include="LCWCOMP.ASM">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</MASM>
|
|
||||||
<MASM Include="Win32Lib\TOBUFF.ASM">
|
<MASM Include="Win32Lib\TOBUFF.ASM">
|
||||||
<Filter>Source Files\win32lib</Filter>
|
<Filter>Source Files\win32lib</Filter>
|
||||||
</MASM>
|
</MASM>
|
||||||
|
|||||||
Reference in New Issue
Block a user