mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-17 08:50:29 +02:00
ASM files removed, functions replaced with bits from Chronoshift.
This commit is contained in:
+2
-19
@@ -9,6 +9,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../)
|
|||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
set(src_win32lib
|
set(src_win32lib
|
||||||
|
./REDALERT/WIN32LIB/TOBUFF.cpp
|
||||||
./RedAlert/WIN32LIB/ALLOC.CPP
|
./RedAlert/WIN32LIB/ALLOC.CPP
|
||||||
./RedAlert/WIN32LIB/AUDIO.H
|
./RedAlert/WIN32LIB/AUDIO.H
|
||||||
./RedAlert/WIN32LIB/BUFFER.CPP
|
./RedAlert/WIN32LIB/BUFFER.CPP
|
||||||
@@ -711,27 +712,9 @@ set(src_external
|
|||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT TOBUFF.obj
|
|
||||||
COMMAND ml -c
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/WIN32LIB/TOBUFF.ASM
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/WIN32LIB/TOBUFF.ASM
|
|
||||||
COMMENT "generate TOBUFF.obj")
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT KEYFBUFF.obj
|
|
||||||
COMMAND ml.exe /c /nolog /Zi /Zm /Cx
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/KEYFBUFF.ASM /Fl"" /Cp /W3 /errorReport:prompt
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/KEYFBUFF.ASM
|
|
||||||
COMMENT "generate KEYFBUFF.obj")
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT MMX.obj
|
|
||||||
COMMAND ml.exe /c /nolog /Zi
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/MMX.ASM /Fl"" /Cp /W3 /errorReport:prompt
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/MMX.ASM
|
|
||||||
COMMENT "generate MMX.obj")
|
|
||||||
|
|
||||||
add_definitions(-DCHEAT_KEYS -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS)
|
add_definitions(-DCHEAT_KEYS -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS)
|
||||||
add_compile_options(/permissive+ /Zc:forScope- /Zp1)
|
add_compile_options(/permissive+ /Zc:forScope- /Zp1)
|
||||||
add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external} TOBUFF.obj KEYFBUFF.obj MMX.obj "REDALERT/TXTPRNT.CPP")
|
add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+317
-317
@@ -96,59 +96,59 @@ typedef struct tShapeHeaderType{
|
|||||||
|
|
||||||
static int Length;
|
static int Length;
|
||||||
|
|
||||||
void *Get_Shape_Header_Data(void *ptr)
|
//void *Get_Shape_Header_Data(void *ptr)
|
||||||
{
|
//{
|
||||||
if (UseBigShapeBuffer) {
|
// if (UseBigShapeBuffer) {
|
||||||
|
//
|
||||||
ShapeHeaderType *header = (ShapeHeaderType*) ptr;
|
// ShapeHeaderType *header = (ShapeHeaderType*) ptr;
|
||||||
return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
|
// return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
|
||||||
|
//
|
||||||
} else {
|
// } else {
|
||||||
return (ptr);
|
// return (ptr);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
int Get_Last_Frame_Length(void)
|
//int Get_Last_Frame_Length(void)
|
||||||
{
|
//{
|
||||||
return(Length);
|
// return(Length);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
void Reset_Theater_Shapes (void)
|
//void Reset_Theater_Shapes (void)
|
||||||
{
|
//{
|
||||||
/*
|
// /*
|
||||||
** Delete any previously allocated slots
|
// ** Delete any previously allocated slots
|
||||||
*/
|
// */
|
||||||
for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
|
// for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
|
||||||
delete [] KeyFrameSlots [i];
|
// delete [] KeyFrameSlots [i];
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
// TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||||
TotalTheaterShapes = 0;
|
// TotalTheaterShapes = 0;
|
||||||
TheaterSlotsUsed = THEATER_SLOT_START;
|
// TheaterSlotsUsed = THEATER_SLOT_START;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
void Reallocate_Big_Shape_Buffer(void)
|
//void Reallocate_Big_Shape_Buffer(void)
|
||||||
{
|
//{
|
||||||
if (ReallocShapeBufferFlag) {
|
// if (ReallocShapeBufferFlag) {
|
||||||
BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
|
// BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
|
||||||
BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
|
// BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
|
||||||
Memory_Error = NULL;
|
// Memory_Error = NULL;
|
||||||
BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
|
// BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
|
||||||
Memory_Error = &Memory_Error_Handler;
|
// Memory_Error = &Memory_Error_Handler;
|
||||||
/*
|
// /*
|
||||||
** If we have run out of memory then disable the uncompressed shapes
|
// ** If we have run out of memory then disable the uncompressed shapes
|
||||||
** It may still be possible to continue with compressed shapes
|
// ** It may still be possible to continue with compressed shapes
|
||||||
*/
|
// */
|
||||||
if (!BigShapeBufferStart) {
|
// if (!BigShapeBufferStart) {
|
||||||
UseBigShapeBuffer = false;
|
// UseBigShapeBuffer = false;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
|
// BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
|
||||||
ReallocShapeBufferFlag = FALSE;
|
// ReallocShapeBufferFlag = FALSE;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
//#ifdef FIXIT_SCORE_CRASH
|
//#ifdef FIXIT_SCORE_CRASH
|
||||||
@@ -166,10 +166,10 @@ void Reallocate_Big_Shape_Buffer(void)
|
|||||||
* HISTORY: *
|
* HISTORY: *
|
||||||
* 11/19/96 2:37PM ST : Created *
|
* 11/19/96 2:37PM ST : Created *
|
||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
void Disable_Uncompressed_Shapes (void)
|
//void Disable_Uncompressed_Shapes (void)
|
||||||
{
|
//{
|
||||||
UseBigShapeBuffer = false;
|
// UseBigShapeBuffer = false;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -187,10 +187,10 @@ void Disable_Uncompressed_Shapes (void)
|
|||||||
* HISTORY: *
|
* HISTORY: *
|
||||||
* 11/19/96 2:37PM ST : Created *
|
* 11/19/96 2:37PM ST : Created *
|
||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
void Enable_Uncompressed_Shapes (void)
|
//void Enable_Uncompressed_Shapes (void)
|
||||||
{
|
//{
|
||||||
UseBigShapeBuffer = OriginalUseBigShapeBuffer;
|
// UseBigShapeBuffer = OriginalUseBigShapeBuffer;
|
||||||
}
|
//}
|
||||||
//#endif //FIXIT
|
//#endif //FIXIT
|
||||||
|
|
||||||
void Check_Use_Compressed_Shapes (void)
|
void Check_Use_Compressed_Shapes (void)
|
||||||
@@ -222,266 +222,266 @@ void Check_Use_Compressed_Shapes (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr)
|
//unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr)
|
||||||
{
|
//{
|
||||||
#ifdef FIXIT_SCORE_CRASH
|
//#ifdef FIXIT_SCORE_CRASH
|
||||||
char *ptr;
|
// char *ptr;
|
||||||
unsigned long offcurr, offdiff;
|
// unsigned long offcurr, offdiff;
|
||||||
#else
|
//#else
|
||||||
char *ptr, *lockptr;//, *uncomp_ptr;
|
// char *ptr, *lockptr;//, *uncomp_ptr;
|
||||||
unsigned long offcurr, off16, offdiff;
|
// unsigned long offcurr, off16, offdiff;
|
||||||
#endif
|
//#endif
|
||||||
unsigned long offset[SUBFRAMEOFFS];
|
// unsigned long offset[SUBFRAMEOFFS];
|
||||||
KeyFrameHeaderType *keyfr;
|
// KeyFrameHeaderType *keyfr;
|
||||||
unsigned short buffsize, currframe, subframe;
|
// unsigned short buffsize, currframe, subframe;
|
||||||
unsigned long length = 0;
|
// unsigned long length = 0;
|
||||||
char frameflags;
|
// char frameflags;
|
||||||
unsigned long return_value;
|
// unsigned long return_value;
|
||||||
char *temp_shape_ptr;
|
// char *temp_shape_ptr;
|
||||||
|
//
|
||||||
//
|
// //
|
||||||
// valid pointer??
|
// // valid pointer??
|
||||||
//
|
// //
|
||||||
Length = 0;
|
// Length = 0;
|
||||||
if ( !dataptr || !buffptr ) {
|
// if ( !dataptr || !buffptr ) {
|
||||||
return(0);
|
// return(0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
//
|
// //
|
||||||
// look at header then check that frame to build is not greater
|
// // look at header then check that frame to build is not greater
|
||||||
// than total frames
|
// // than total frames
|
||||||
//
|
// //
|
||||||
keyfr = (KeyFrameHeaderType *) dataptr;
|
// keyfr = (KeyFrameHeaderType *) dataptr;
|
||||||
|
//
|
||||||
if ( framenumber >= keyfr->frames ) {
|
// if ( framenumber >= keyfr->frames ) {
|
||||||
return(0);
|
// return(0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
if (UseBigShapeBuffer) {
|
// if (UseBigShapeBuffer) {
|
||||||
/*
|
// /*
|
||||||
** If we havnt yet allocated memory for uncompressed shapes then do so now.
|
// ** If we havnt yet allocated memory for uncompressed shapes then do so now.
|
||||||
**
|
// **
|
||||||
*/
|
// */
|
||||||
if (!BigShapeBufferStart) {
|
// if (!BigShapeBufferStart) {
|
||||||
BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
|
// BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
|
||||||
BigShapeBufferPtr = BigShapeBufferStart;
|
// BigShapeBufferPtr = BigShapeBufferStart;
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
** Allocate memory for theater specific uncompressed shapes
|
// ** Allocate memory for theater specific uncompressed shapes
|
||||||
*/
|
// */
|
||||||
TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
|
// TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
|
||||||
TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
// TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
** If we are running out of memory (<10k left) for uncompressed shapes
|
// ** If we are running out of memory (<10k left) for uncompressed shapes
|
||||||
** then allocate some more.
|
// ** then allocate some more.
|
||||||
*/
|
// */
|
||||||
if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
|
// if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
|
||||||
ReallocShapeBufferFlag = TRUE;
|
// ReallocShapeBufferFlag = TRUE;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
** If this animation was not previously uncompressed then
|
// ** If this animation was not previously uncompressed then
|
||||||
** allocate memory to keep the pointers to the uncompressed data
|
// ** allocate memory to keep the pointers to the uncompressed data
|
||||||
** for these animation frames
|
// ** for these animation frames
|
||||||
*/
|
// */
|
||||||
if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
|
// if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
|
||||||
keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
|
// keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
|
||||||
if (IsTheaterShape) {
|
// if (IsTheaterShape) {
|
||||||
keyfr->y = TheaterSlotsUsed;
|
// keyfr->y = TheaterSlotsUsed;
|
||||||
TheaterSlotsUsed++;
|
// TheaterSlotsUsed++;
|
||||||
} else {
|
// } else {
|
||||||
keyfr->y = TotalSlotsUsed;
|
// keyfr->y = TotalSlotsUsed;
|
||||||
TotalSlotsUsed++;
|
// TotalSlotsUsed++;
|
||||||
}
|
// }
|
||||||
/*
|
// /*
|
||||||
** Allocate and clear the memory for the shape info
|
// ** Allocate and clear the memory for the shape info
|
||||||
*/
|
// */
|
||||||
KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
|
// KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
|
||||||
memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
|
// memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
** If this frame was previously uncompressed then just return
|
// ** If this frame was previously uncompressed then just return
|
||||||
** a pointer to the raw data
|
// ** a pointer to the raw data
|
||||||
*/
|
// */
|
||||||
if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
|
// if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
|
||||||
if (IsTheaterShape) {
|
// if (IsTheaterShape) {
|
||||||
return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
// return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||||
} else {
|
// } else {
|
||||||
return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
// return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// calc buff size
|
// // calc buff size
|
||||||
buffsize = keyfr->width * keyfr->height;
|
// buffsize = keyfr->width * keyfr->height;
|
||||||
|
//
|
||||||
// get offset into data
|
// // get offset into data
|
||||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
|
// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
|
||||||
Mem_Copy( ptr, &offset[0], 12L );
|
// Mem_Copy( ptr, &offset[0], 12L );
|
||||||
frameflags = (char)(offset[0] >> 24);
|
// frameflags = (char)(offset[0] >> 24);
|
||||||
|
//
|
||||||
|
//
|
||||||
if ( (frameflags & KF_KEYFRAME) ) {
|
// if ( (frameflags & KF_KEYFRAME) ) {
|
||||||
|
//
|
||||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
|
// ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
|
||||||
|
//
|
||||||
if (keyfr->flags & 1 ) {
|
// if (keyfr->flags & 1 ) {
|
||||||
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
// ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||||
}
|
// }
|
||||||
length = LCW_Uncompress( ptr, buffptr, buffsize );
|
// length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||||
} else { // key delta or delta
|
// } else { // key delta or delta
|
||||||
|
//
|
||||||
if ( (frameflags & KF_DELTA) ) {
|
// if ( (frameflags & KF_DELTA) ) {
|
||||||
currframe = (unsigned short)offset[1];
|
// currframe = (unsigned short)offset[1];
|
||||||
|
//
|
||||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
|
// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
|
||||||
Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
// Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// key frame
|
// // key frame
|
||||||
offcurr = offset[1] & 0x00FFFFFFL;
|
// offcurr = offset[1] & 0x00FFFFFFL;
|
||||||
|
//
|
||||||
// key delta
|
// // key delta
|
||||||
offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
|
// offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
|
||||||
|
//
|
||||||
ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
|
// ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
|
||||||
|
//
|
||||||
if (keyfr->flags & 1 ) {
|
// if (keyfr->flags & 1 ) {
|
||||||
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
// ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
#ifndef FIXIT_SCORE_CRASH
|
//#ifndef FIXIT_SCORE_CRASH
|
||||||
off16 = (unsigned long)lockptr & 0x00003FFFL;
|
// off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||||
#endif
|
//#endif
|
||||||
|
//
|
||||||
length = LCW_Uncompress( ptr, buffptr, buffsize );
|
// length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||||
|
//
|
||||||
if (length > buffsize) {
|
// if (length > buffsize) {
|
||||||
return(0);
|
// return(0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
#ifndef FIXIT_SCORE_CRASH
|
//#ifndef FIXIT_SCORE_CRASH
|
||||||
if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
// if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||||
|
//
|
||||||
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||||
off16 = (unsigned long)ptr & 0x00003FFFL;
|
// off16 = (unsigned long)ptr & 0x00003FFFL;
|
||||||
|
//
|
||||||
offcurr += offdiff;
|
// offcurr += offdiff;
|
||||||
offdiff = 0;
|
// offdiff = 0;
|
||||||
}
|
// }
|
||||||
#endif
|
//#endif
|
||||||
|
//
|
||||||
length = buffsize;
|
// length = buffsize;
|
||||||
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||||
|
//
|
||||||
if ( (frameflags & KF_DELTA) ) {
|
// if ( (frameflags & KF_DELTA) ) {
|
||||||
// adjust to delta after the keydelta
|
// // adjust to delta after the keydelta
|
||||||
|
//
|
||||||
currframe++;
|
// currframe++;
|
||||||
subframe = 2;
|
// subframe = 2;
|
||||||
|
//
|
||||||
while (currframe <= framenumber) {
|
// while (currframe <= framenumber) {
|
||||||
offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
|
// offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
|
||||||
|
//
|
||||||
#ifndef FIXIT_SCORE_CRASH
|
//#ifndef FIXIT_SCORE_CRASH
|
||||||
if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
// if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||||
|
//
|
||||||
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||||
off16 = (unsigned long)lockptr & 0x00003FFFL;
|
// off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||||
|
//
|
||||||
offcurr += offdiff;
|
// offcurr += offdiff;
|
||||||
offdiff = 0;
|
// offdiff = 0;
|
||||||
}
|
// }
|
||||||
#endif
|
//#endif
|
||||||
|
//
|
||||||
length = buffsize;
|
// length = buffsize;
|
||||||
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||||
|
//
|
||||||
currframe++;
|
// currframe++;
|
||||||
subframe += 2;
|
// subframe += 2;
|
||||||
|
//
|
||||||
if ( subframe >= (SUBFRAMEOFFS - 1) &&
|
// if ( subframe >= (SUBFRAMEOFFS - 1) &&
|
||||||
currframe <= framenumber ) {
|
// currframe <= framenumber ) {
|
||||||
Mem_Copy( Add_Long_To_Pointer( dataptr,
|
// Mem_Copy( Add_Long_To_Pointer( dataptr,
|
||||||
(((unsigned long)currframe << 3) +
|
// (((unsigned long)currframe << 3) +
|
||||||
sizeof(KeyFrameHeaderType)) ),
|
// sizeof(KeyFrameHeaderType)) ),
|
||||||
&offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
// &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||||
subframe = 0;
|
// subframe = 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
if (UseBigShapeBuffer) {
|
// if (UseBigShapeBuffer) {
|
||||||
/*
|
// /*
|
||||||
** Save the uncompressed shape data so we dont have to uncompress it
|
// ** Save the uncompressed shape data so we dont have to uncompress it
|
||||||
** again next time its drawn.
|
// ** again next time its drawn.
|
||||||
** We keep a space free before the raw shape data so we can add line
|
// ** We keep a space free before the raw shape data so we can add line
|
||||||
** header info before the shape is drawn for the first time
|
// ** header info before the shape is drawn for the first time
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
if (IsTheaterShape) {
|
// if (IsTheaterShape) {
|
||||||
/*
|
// /*
|
||||||
** Shape is a theater specific shape
|
// ** Shape is a theater specific shape
|
||||||
*/
|
// */
|
||||||
return_value = (unsigned long) TheaterShapeBufferPtr;
|
// return_value = (unsigned long) TheaterShapeBufferPtr;
|
||||||
temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
// temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||||
/*
|
// /*
|
||||||
** align the actual shape data
|
// ** align the actual shape data
|
||||||
*/
|
// */
|
||||||
if (3 & (unsigned)temp_shape_ptr) {
|
// if (3 & (unsigned)temp_shape_ptr) {
|
||||||
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
memcpy (temp_shape_ptr , buffptr , length);
|
// memcpy (temp_shape_ptr , buffptr , length);
|
||||||
((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
|
// ((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
|
||||||
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data
|
// ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data
|
||||||
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer
|
// ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer
|
||||||
*(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
|
// *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
|
||||||
TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
// TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||||
/*
|
// /*
|
||||||
** Align the next shape
|
// ** Align the next shape
|
||||||
*/
|
// */
|
||||||
if (3 & (unsigned)TheaterShapeBufferPtr) {
|
// if (3 & (unsigned)TheaterShapeBufferPtr) {
|
||||||
TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
|
// TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
|
||||||
}
|
// }
|
||||||
Length = length;
|
// Length = length;
|
||||||
return (return_value);
|
// return (return_value);
|
||||||
|
//
|
||||||
} else {
|
// } else {
|
||||||
|
//
|
||||||
|
//
|
||||||
return_value=(unsigned long)BigShapeBufferPtr;
|
// return_value=(unsigned long)BigShapeBufferPtr;
|
||||||
temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
// temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||||
/*
|
// /*
|
||||||
** align the actual shape data
|
// ** align the actual shape data
|
||||||
*/
|
// */
|
||||||
if (3 & (unsigned)temp_shape_ptr) {
|
// if (3 & (unsigned)temp_shape_ptr) {
|
||||||
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||||
}
|
// }
|
||||||
memcpy (temp_shape_ptr , buffptr , length);
|
// memcpy (temp_shape_ptr , buffptr , length);
|
||||||
((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
|
// ((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
|
||||||
((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data
|
// ((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data
|
||||||
((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer
|
// ((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer
|
||||||
*(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
|
// *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
|
||||||
BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
// BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||||
// Align the next shape
|
// // Align the next shape
|
||||||
if (3 & (unsigned)BigShapeBufferPtr) {
|
// if (3 & (unsigned)BigShapeBufferPtr) {
|
||||||
BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
|
// BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
|
||||||
}
|
// }
|
||||||
Length = length;
|
// Length = length;
|
||||||
return (return_value);
|
// return (return_value);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
} else {
|
// } else {
|
||||||
return ((unsigned long)buffptr);
|
// return ((unsigned long)buffptr);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
|
|||||||
@@ -1,561 +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\2support.asv 5.0 11 Nov 1996 09:40:36 JOE_BOSTIC $
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 : Command & Conquer *
|
|
||||||
;* *
|
|
||||||
;* File Name : SUPPORT.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Joe L. Bostic *
|
|
||||||
;* *
|
|
||||||
;* Start Date : September 23, 1993 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : May 10, 1994 [JLB] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* strtrim -- Remove the trailing white space from a string. *
|
|
||||||
;* Fat_Put_Pixel -- Draws a fat pixel. *
|
|
||||||
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
|
|
||||||
;* Remove_From_List -- Removes a pointer from a list of pointers. *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
IDEAL
|
|
||||||
P386
|
|
||||||
MODEL USE32 FLAT
|
|
||||||
|
|
||||||
INCLUDE "gbuffer.inc"
|
|
||||||
DISPLAY "Command & Conquer assembly support routines."
|
|
||||||
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Fat_Put_Pixel -- Draws a fat pixel. *
|
|
||||||
;* *
|
|
||||||
;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
|
|
||||||
;* across. This routine is faster than drawing a similar small shape *
|
|
||||||
;* and faster than calling Fill_Rect. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
|
|
||||||
;* left corner. *
|
|
||||||
;* *
|
|
||||||
;* color -- The color to render the pixel in. *
|
|
||||||
;* *
|
|
||||||
;* size -- The number of pixels width of the big "pixel". *
|
|
||||||
;* *
|
|
||||||
;* page -- The pointer to a GraphicBuffer class or something *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 03/17/1994 JLB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
|
|
||||||
GLOBAL C Fat_Put_Pixel:NEAR
|
|
||||||
PROC Fat_Put_Pixel C near
|
|
||||||
USES eax, ebx, ecx, edx, edi, esi
|
|
||||||
|
|
||||||
ARG x:DWORD ; X coordinate of upper left pixel corner.
|
|
||||||
ARG y:DWORD ; Y coordinate of upper left pixel corner.
|
|
||||||
ARG color:DWORD ; Color to use for the "pixel".
|
|
||||||
ARG siz:DWORD ; Size of "pixel" to plot (square).
|
|
||||||
ARG gpage:DWORD ; graphic page address to plot onto
|
|
||||||
|
|
||||||
cmp [siz],0
|
|
||||||
je short ??exit
|
|
||||||
|
|
||||||
; Set EDI to point to start of logical page memory.
|
|
||||||
;*===================================================================
|
|
||||||
; Get the viewport information and put bytes per row in ecx
|
|
||||||
;*===================================================================
|
|
||||||
mov ebx,[gpage] ; get a pointer to viewport
|
|
||||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
|
|
||||||
|
|
||||||
; Verify the the Y pixel offset is legal.
|
|
||||||
mov eax,[y]
|
|
||||||
cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
|
|
||||||
jae short ??exit
|
|
||||||
mov ecx,[(GraphicViewPort ebx).GVPWidth]
|
|
||||||
add ecx,[(GraphicViewPort ebx).GVPXAdd]
|
|
||||||
add ecx,[(GraphicViewPort ebx).GVPPitch]
|
|
||||||
mul ecx
|
|
||||||
add edi,eax
|
|
||||||
|
|
||||||
; Verify the the X pixel offset is legal.
|
|
||||||
|
|
||||||
mov edx,[(GraphicViewPort ebx).GVPWidth]
|
|
||||||
cmp edx,[x]
|
|
||||||
mov edx,ecx
|
|
||||||
jbe short ??exit
|
|
||||||
add edi,[x]
|
|
||||||
|
|
||||||
; Write the pixel to the screen.
|
|
||||||
mov ebx,[siz] ; Copy of pixel size.
|
|
||||||
sub edx,ebx ; Modulo to reach start of next row.
|
|
||||||
mov eax,[color]
|
|
||||||
??again:
|
|
||||||
mov ecx,ebx
|
|
||||||
rep stosb
|
|
||||||
add edi,edx ; EDI points to start of next row.
|
|
||||||
dec [siz]
|
|
||||||
jnz short ??again
|
|
||||||
|
|
||||||
??exit:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Fat_Put_Pixel
|
|
||||||
|
|
||||||
|
|
||||||
if 0
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* strtrim -- Remove the trailing white space from a string. *
|
|
||||||
;* *
|
|
||||||
;* Use this routine to remove white space characters from the beginning *
|
|
||||||
;* and end of the string. The string is modified in place by *
|
|
||||||
;* this routine. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: buffer -- Pointer to the string to modify. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/07/1992 JLB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
; VOID cdecl strtrim(BYTE *buffer);
|
|
||||||
GLOBAL C strtrim :NEAR
|
|
||||||
PROC strtrim C near
|
|
||||||
USES ax, edi, esi
|
|
||||||
|
|
||||||
ARG buffer:DWORD ; Pointer to string to modify.
|
|
||||||
|
|
||||||
cmp [buffer],0
|
|
||||||
je short ??fini
|
|
||||||
|
|
||||||
; Prepare for string scanning by loading pointers.
|
|
||||||
cld
|
|
||||||
mov esi,[buffer]
|
|
||||||
mov edi,esi
|
|
||||||
|
|
||||||
; Strip white space from the start of the string.
|
|
||||||
??looper:
|
|
||||||
lodsb
|
|
||||||
cmp al,20h ; Space
|
|
||||||
je short ??looper
|
|
||||||
cmp al,9 ; TAB
|
|
||||||
je short ??looper
|
|
||||||
stosb
|
|
||||||
|
|
||||||
; Copy the rest of the string.
|
|
||||||
??gruntloop:
|
|
||||||
lodsb
|
|
||||||
stosb
|
|
||||||
or al,al
|
|
||||||
jnz short ??gruntloop
|
|
||||||
dec edi
|
|
||||||
; Strip the white space from the end of the string.
|
|
||||||
??looper2:
|
|
||||||
mov [edi],al
|
|
||||||
dec edi
|
|
||||||
mov ah,[edi]
|
|
||||||
cmp ah,20h
|
|
||||||
je short ??looper2
|
|
||||||
cmp ah,9
|
|
||||||
je short ??looper2
|
|
||||||
|
|
||||||
??fini:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP strtrim
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
|
|
||||||
;* *
|
|
||||||
;* This routine is used to build a special fading table for C&C. There *
|
|
||||||
;* are certain colors that get faded to and cannot be faded again. *
|
|
||||||
;* With this rule, it is possible to draw a shadow multiple times and *
|
|
||||||
;* not have it get any lighter or darker. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
|
|
||||||
;* *
|
|
||||||
;* dest -- Pointer to the 256 byte remap table. *
|
|
||||||
;* *
|
|
||||||
;* color -- Color index of the color to "fade to". *
|
|
||||||
;* *
|
|
||||||
;* frac -- The fraction to fade to the specified color *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with pointer to the remap table. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/07/1992 JLB : Created. *
|
|
||||||
;*=========================================================================*/
|
|
||||||
;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
|
|
||||||
GLOBAL C Conquer_Build_Fading_Table : NEAR
|
|
||||||
PROC Conquer_Build_Fading_Table C near
|
|
||||||
USES ebx, ecx, edi, esi
|
|
||||||
|
|
||||||
ARG palette:DWORD
|
|
||||||
ARG dest:DWORD
|
|
||||||
ARG color:DWORD
|
|
||||||
ARG frac:DWORD
|
|
||||||
|
|
||||||
LOCAL matchvalue:DWORD ; Last recorded match value.
|
|
||||||
LOCAL targetred:BYTE ; Target gun red.
|
|
||||||
LOCAL targetgreen:BYTE ; Target gun green.
|
|
||||||
LOCAL targetblue:BYTE ; Target gun blue.
|
|
||||||
LOCAL idealred:BYTE
|
|
||||||
LOCAL idealgreen:BYTE
|
|
||||||
LOCAL idealblue:BYTE
|
|
||||||
LOCAL matchcolor:BYTE ; Tentative match color.
|
|
||||||
|
|
||||||
ALLOWED_COUNT EQU 16
|
|
||||||
ALLOWED_START EQU 256-ALLOWED_COUNT
|
|
||||||
|
|
||||||
cld
|
|
||||||
|
|
||||||
; If the source palette is NULL, then just return with current fading table pointer.
|
|
||||||
cmp [palette],0
|
|
||||||
je ??fini1
|
|
||||||
cmp [dest],0
|
|
||||||
je ??fini1
|
|
||||||
|
|
||||||
; Fractions above 255 become 255.
|
|
||||||
mov eax,[frac]
|
|
||||||
cmp eax,0100h
|
|
||||||
jb short ??ok
|
|
||||||
mov [frac],0FFh
|
|
||||||
??ok:
|
|
||||||
|
|
||||||
; Record the target gun values.
|
|
||||||
mov esi,[palette]
|
|
||||||
mov ebx,[color]
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
lodsb
|
|
||||||
mov [targetred],al
|
|
||||||
lodsb
|
|
||||||
mov [targetgreen],al
|
|
||||||
lodsb
|
|
||||||
mov [targetblue],al
|
|
||||||
|
|
||||||
; Main loop.
|
|
||||||
xor ebx,ebx ; Remap table index.
|
|
||||||
|
|
||||||
; Transparent black never gets remapped.
|
|
||||||
mov edi,[dest]
|
|
||||||
mov [edi],bl
|
|
||||||
inc edi
|
|
||||||
|
|
||||||
; EBX = source palette logical number (1..255).
|
|
||||||
; EDI = running pointer into dest remap table.
|
|
||||||
??mainloop:
|
|
||||||
inc ebx
|
|
||||||
mov esi,[palette]
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
|
|
||||||
mov edx,[frac]
|
|
||||||
shr edx,1
|
|
||||||
; new = orig - ((orig-target) * fraction);
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetred] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealred],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetgreen] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealgreen],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetblue] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealblue],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
; Sweep through a limited set of existing colors to find the closest
|
|
||||||
; matching color.
|
|
||||||
|
|
||||||
mov eax,[color]
|
|
||||||
mov [matchcolor],al ; Default color (self).
|
|
||||||
mov [matchvalue],-1 ; Ridiculous match value init.
|
|
||||||
mov ecx,ALLOWED_COUNT
|
|
||||||
|
|
||||||
mov esi,[palette] ; Pointer to original palette.
|
|
||||||
add esi,(ALLOWED_START)*3
|
|
||||||
|
|
||||||
; BH = color index.
|
|
||||||
mov bh,ALLOWED_START
|
|
||||||
??innerloop:
|
|
||||||
|
|
||||||
xor edx,edx ; Comparison value starts null.
|
|
||||||
|
|
||||||
; Build the comparison value based on the sum of the differences of the color
|
|
||||||
; guns squared.
|
|
||||||
lodsb
|
|
||||||
sub al,[idealred]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
|
|
||||||
lodsb
|
|
||||||
sub al,[idealgreen]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
|
|
||||||
lodsb
|
|
||||||
sub al,[idealblue]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
jz short ??perfect ; If perfect match found then quit early.
|
|
||||||
|
|
||||||
cmp edx,[matchvalue]
|
|
||||||
jae short ??notclose
|
|
||||||
mov [matchvalue],edx ; Record new possible color.
|
|
||||||
mov [matchcolor],bh
|
|
||||||
??notclose:
|
|
||||||
inc bh ; Checking color index.
|
|
||||||
loop ??innerloop
|
|
||||||
mov bh,[matchcolor]
|
|
||||||
??perfect:
|
|
||||||
mov [matchcolor],bh
|
|
||||||
xor bh,bh ; Make BX valid main index again.
|
|
||||||
|
|
||||||
; When the loop exits, we have found the closest match.
|
|
||||||
mov al,[matchcolor]
|
|
||||||
stosb
|
|
||||||
cmp ebx,ALLOWED_START-1
|
|
||||||
jne ??mainloop
|
|
||||||
|
|
||||||
; Fill the remainder of the remap table with values
|
|
||||||
; that will remap the color to itself.
|
|
||||||
mov ecx,ALLOWED_COUNT
|
|
||||||
??fillerloop:
|
|
||||||
inc bl
|
|
||||||
mov al,bl
|
|
||||||
stosb
|
|
||||||
loop ??fillerloop
|
|
||||||
|
|
||||||
??fini1:
|
|
||||||
mov esi,[dest]
|
|
||||||
mov eax,esi
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Conquer_Build_Fading_Table
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Remove_From_List -- Removes a pointer from a list of pointers. *
|
|
||||||
;* *
|
|
||||||
;* This low level routine is used to remove a pointer from a list of *
|
|
||||||
;* pointers. The trailing pointers are moved downward to fill the *
|
|
||||||
;* hole. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: list -- Pointer to list of pointer. *
|
|
||||||
;* *
|
|
||||||
;* index -- Pointer to length of pointer list. *
|
|
||||||
;* *
|
|
||||||
;* ptr -- The pointer value to search for and remove. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 04/11/1994 JLB : Created. *
|
|
||||||
;* 04/22/1994 JLB : Convert to assembly language. *
|
|
||||||
;* 05/10/1994 JLB : Short pointers now. *
|
|
||||||
;*=========================================================================*/
|
|
||||||
;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
|
|
||||||
GLOBAL C Remove_From_List:NEAR
|
|
||||||
PROC Remove_From_List C near
|
|
||||||
USES edi, esi, ecx, eax
|
|
||||||
ARG list:DWORD ; Pointer to list.
|
|
||||||
ARG index:DWORD ; Pointer to count.
|
|
||||||
ARG element:DWORD ; Element to remove.
|
|
||||||
|
|
||||||
; Fetch the number of elements in the list. If there are no
|
|
||||||
; elements, then just exit quickly.
|
|
||||||
mov edi,[index]
|
|
||||||
mov ecx,[edi]
|
|
||||||
jcxz short ??fini2
|
|
||||||
|
|
||||||
; Fetch pointer to list.
|
|
||||||
cmp [list],0
|
|
||||||
je short ??fini2
|
|
||||||
mov edi,[list]
|
|
||||||
|
|
||||||
; Loop through all elements searching for a match.
|
|
||||||
mov eax,[element]
|
|
||||||
repne scasd
|
|
||||||
jne short ??fini2 ; No match found.
|
|
||||||
|
|
||||||
; Copy all remaining elements down. If this is the
|
|
||||||
; last element in the list then nothing needs to be
|
|
||||||
; copied -- just decrement the list size.
|
|
||||||
jcxz short ??nocopy ; No copy necessary.
|
|
||||||
mov esi,edi
|
|
||||||
sub edi,4
|
|
||||||
rep movsd
|
|
||||||
|
|
||||||
; Reduce the list count by one.
|
|
||||||
??nocopy:
|
|
||||||
mov edi,[index]
|
|
||||||
dec [DWORD PTR edi]
|
|
||||||
|
|
||||||
??fini2:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Remove_From_List
|
|
||||||
|
|
||||||
|
|
||||||
; long cdecl Get_EAX();
|
|
||||||
GLOBAL C Get_EAX :NEAR
|
|
||||||
PROC Get_EAX C near
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Get_EAX
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
DATASEG
|
|
||||||
|
|
||||||
TabA DD 6949350
|
|
||||||
DD 4913933
|
|
||||||
DD 3474675
|
|
||||||
DD 2456966
|
|
||||||
DD 1737338
|
|
||||||
DD 1228483
|
|
||||||
DD 868669
|
|
||||||
DD 614242
|
|
||||||
DD 434334
|
|
||||||
DD 307121
|
|
||||||
DD 217167
|
|
||||||
DD 153560
|
|
||||||
DD 108584
|
|
||||||
DD 76780
|
|
||||||
DD 54292
|
|
||||||
DD 38390
|
|
||||||
DD 27146
|
|
||||||
DD 19195
|
|
||||||
DD 13573
|
|
||||||
DD 9598
|
|
||||||
DD 6786
|
|
||||||
DD 4799
|
|
||||||
DD 3393
|
|
||||||
DD 2399
|
|
||||||
DD 1697
|
|
||||||
DD 1200
|
|
||||||
DD 848
|
|
||||||
DD 600
|
|
||||||
DD 424
|
|
||||||
DD 300
|
|
||||||
DD 212
|
|
||||||
DD 150
|
|
||||||
DD 106
|
|
||||||
|
|
||||||
TabB DD 154
|
|
||||||
DD 218
|
|
||||||
DD 309
|
|
||||||
DD 437
|
|
||||||
DD 618
|
|
||||||
DD 874
|
|
||||||
DD 1236
|
|
||||||
DD 1748
|
|
||||||
DD 2472
|
|
||||||
DD 3496
|
|
||||||
DD 4944
|
|
||||||
DD 6992
|
|
||||||
DD 9888
|
|
||||||
DD 13983
|
|
||||||
DD 19775
|
|
||||||
DD 27967
|
|
||||||
DD 39551
|
|
||||||
DD 55933
|
|
||||||
DD 79101
|
|
||||||
DD 111866
|
|
||||||
DD 158203
|
|
||||||
DD 223732
|
|
||||||
DD 316405
|
|
||||||
DD 447465
|
|
||||||
DD 632811
|
|
||||||
DD 894929
|
|
||||||
DD 1265621
|
|
||||||
DD 1789859
|
|
||||||
DD 2531243
|
|
||||||
DD 3579718
|
|
||||||
DD 5062486
|
|
||||||
DD 7159436
|
|
||||||
DD 10124971
|
|
||||||
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
;***********************************************************************************************
|
|
||||||
;* Square_Root -- Finds the square root of the fixed pointer parameter. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/04/1995 JLB : Adapted. *
|
|
||||||
;*=============================================================================================*/
|
|
||||||
;unsigned Square_Root(unsigned val);
|
|
||||||
GLOBAL C Square_Root :NEAR
|
|
||||||
PROC Square_Root C near
|
|
||||||
USES ebx,edx
|
|
||||||
|
|
||||||
bsr ebx,eax
|
|
||||||
jz ??zero
|
|
||||||
|
|
||||||
mul [DWORD 4*ebx + OFFSET TabA]
|
|
||||||
shrd eax,edx,10h
|
|
||||||
add eax, [4*ebx + OFFSET TabB]
|
|
||||||
??zero:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Square_Root
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
@@ -1,504 +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]>.
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 : TXTPRNT.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Phil W. Gorrow *
|
|
||||||
;* *
|
|
||||||
;* Start Date : January 17, 1995 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : January 17, 1995 [PWG] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* MCGA_Print -- Assembly MCGA text print routine *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
IDEAL
|
|
||||||
P386
|
|
||||||
MODEL USE32 FLAT
|
|
||||||
|
|
||||||
;INCLUDE "mcgaprim.inc"
|
|
||||||
;INCLUDE ".\gbuffer.inc"
|
|
||||||
|
|
||||||
GLOBAL C Buffer_Print : NEAR
|
|
||||||
|
|
||||||
STRUC GraphicViewPort
|
|
||||||
GVPOffset DD ? ; offset to virtual viewport
|
|
||||||
GVPWidth DD ? ; width of virtual viewport
|
|
||||||
GVPHeight DD ? ; height of virtual viewport
|
|
||||||
GVPXAdd DD ? ; x mod to get to next line
|
|
||||||
GVPXPos DD ? ; x pos relative to Graphic Buff
|
|
||||||
GVPYPos DD ? ; y pos relative to Graphic Buff
|
|
||||||
GVPPitch dd ? ; modulo of graphic view port
|
|
||||||
GVPBuffPtr DD ? ; ptr to associated Graphic Buff
|
|
||||||
ENDS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;*=========================================================================*
|
|
||||||
;* Extern the font pointer which is defined by the font class *
|
|
||||||
;*=========================================================================*
|
|
||||||
GLOBAL C FontPtr:DWORD
|
|
||||||
GLOBAL C FontXSpacing:DWORD
|
|
||||||
GLOBAL C FontYSpacing:DWORD
|
|
||||||
GLOBAL C ColorXlat:BYTE
|
|
||||||
|
|
||||||
;*=========================================================================*
|
|
||||||
;* Define the necessary equates for structures and bounds checking *
|
|
||||||
;*=========================================================================*
|
|
||||||
; 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 ??
|
|
||||||
;*=========================================================================*
|
|
||||||
;* Define the color xlate table in the data segment *
|
|
||||||
;*=========================================================================*
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* MCGA_PRINT -- Assembly MCGA text print routine *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: *
|
|
||||||
;* *
|
|
||||||
;* PROTO: *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 01/17/1995 PWG : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
PROC Buffer_Print C near
|
|
||||||
USES ebx,ecx,edx,esi,edi
|
|
||||||
|
|
||||||
ARG this: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.
|
|
||||||
LOCAL vpwidth:DWORD
|
|
||||||
LOCAL vpheight:DWORD
|
|
||||||
LOCAL original_x:DWORD ; Starting X position.
|
|
||||||
|
|
||||||
|
|
||||||
;-------------------------------- Where to draw -----------------------------------------------
|
|
||||||
; Set up memory location to start drawing.
|
|
||||||
mov ebx,[this] ; get a pointer to dest
|
|
||||||
mov eax,[(GraphicViewPort ebx).GVPHeight] ; get height of viewport
|
|
||||||
mov [vpheight],eax ; save off height of viewport
|
|
||||||
mov eax,[(GraphicViewPort ebx).GVPWidth] ; get width of viewport
|
|
||||||
mov [vpwidth],eax ; save it off for later
|
|
||||||
add eax,[(GraphicViewPort ebx).GVPXAdd] ; add in xadd for bytes_per_line
|
|
||||||
add eax,[(GraphicViewPort ebx).GVPPitch] ; add in pitch of direct draw surface
|
|
||||||
mov [bufferwidth],eax ; save it off for later use.
|
|
||||||
|
|
||||||
mul [y_pixel] ; multiply rowsize * y_pixel start.
|
|
||||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get start of the viewport
|
|
||||||
add edi,eax ; add y position to start of vp
|
|
||||||
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.
|
|
||||||
|
|
||||||
mov eax,[x_pixel]
|
|
||||||
mov [original_x],eax
|
|
||||||
|
|
||||||
;-------------------------------- 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
|
|
||||||
or esi,esi
|
|
||||||
jz ??overflow
|
|
||||||
|
|
||||||
; 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 al,10 ; is the character a line feed?
|
|
||||||
je ??line_feed ; if so, go to special case.
|
|
||||||
|
|
||||||
cmp al,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.
|
|
||||||
mov eax,[FontXSpacing]
|
|
||||||
add ecx,eax
|
|
||||||
add [startdraw],edx ; save start draw for next character.
|
|
||||||
add [startdraw],eax ; adjust for the font spacing value
|
|
||||||
|
|
||||||
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.
|
|
||||||
xor eax,eax
|
|
||||||
; Now go into the line feed code.....
|
|
||||||
|
|
||||||
??line_feed:
|
|
||||||
mov bl,al
|
|
||||||
mov edx,[y_pixel] ; get the current y pixel value.
|
|
||||||
movzx ecx,[maxheight] ; get max height for later use.
|
|
||||||
add ecx,[FontYSpacing]
|
|
||||||
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.
|
|
||||||
;;; DRD
|
|
||||||
mov [curline],edi ; save it off for next line_feed.
|
|
||||||
|
|
||||||
; Move the cursor to either the left edge of the screen
|
|
||||||
; or the left margin of the print position depending
|
|
||||||
; on whether <CR> or <LF> was specified. <CR> = left margin
|
|
||||||
; <LF> = left edge of screen
|
|
||||||
xor eax,eax
|
|
||||||
cmp bl,10
|
|
||||||
je ??lfeed
|
|
||||||
mov eax,[original_x]
|
|
||||||
??lfeed:
|
|
||||||
mov [x_pixel],eax ; zero out x_pixel
|
|
||||||
|
|
||||||
add edi,eax
|
|
||||||
;;; DRD 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
|
|
||||||
|
|
||||||
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 Buffer_Print
|
|
||||||
;***************************************************************************
|
|
||||||
;* GET_FONT_PALETTE_PTR -- Returns a pointer to the 256 byte font palette *
|
|
||||||
;* *
|
|
||||||
;* INPUT: none *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* PROTO: void *Get_Font_Palette_Ptr(void); *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 08/18/1995 PWG : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
|
|
||||||
GLOBAL C Get_Font_Palette_Ptr:NEAR
|
|
||||||
PROC Get_Font_Palette_Ptr C near
|
|
||||||
mov eax, OFFSET ColorXlat
|
|
||||||
ret
|
|
||||||
ENDP Get_Font_Palette_Ptr
|
|
||||||
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -2169,11 +2169,6 @@ Mono_Set_Cursor(0,0);
|
|||||||
** Call the focus loss handler
|
** Call the focus loss handler
|
||||||
*/
|
*/
|
||||||
Check_For_Focus_Loss();
|
Check_For_Focus_Loss();
|
||||||
|
|
||||||
/*
|
|
||||||
** Allocate extra memory for uncompressed shapes as needed
|
|
||||||
*/
|
|
||||||
Reallocate_Big_Shape_Buffer();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,126 +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]>.
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 I N C **
|
|
||||||
;***************************************************************************
|
|
||||||
;* *
|
|
||||||
;* Project Name : Command & Conquer *
|
|
||||||
;* *
|
|
||||||
;* File Name : COORDA.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Barry W. Green *
|
|
||||||
;* *
|
|
||||||
;* Start Date : February 17, 1995 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : February 17, 1995 [BWG] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
|
|
||||||
IDEAL
|
|
||||||
P386
|
|
||||||
MODEL USE32 FLAT
|
|
||||||
|
|
||||||
global C Cardinal_To_Fixed :NEAR
|
|
||||||
global C Fixed_To_Cardinal :NEAR
|
|
||||||
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
;***********************************************************************************************
|
|
||||||
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
|
|
||||||
;* *
|
|
||||||
;* This utility function will convert cardinal numbers into a fixed point fraction. The *
|
|
||||||
;* use of fixed point numbers occurs throughout the product -- since it is a convenient *
|
|
||||||
;* tool. The fixed point number is based on the formula: *
|
|
||||||
;* *
|
|
||||||
;* result = cardinal / base *
|
|
||||||
;* *
|
|
||||||
;* The accuracy of the fixed point number is limited to 1/65536 as the lowest and up to *
|
|
||||||
;* 65536 as the largest. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: base -- The key number to base the fraction about. *
|
|
||||||
;* *
|
|
||||||
;* cardinal -- The other number (hey -- what do you call it?) *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates *
|
|
||||||
;* to the "base" parameter. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 02/17/1995 BWG : Created. *
|
|
||||||
;*=============================================================================================*/
|
|
||||||
;unsigned int Cardinal_To_Fixed(unsigned base, unsigned cardinal);
|
|
||||||
|
|
||||||
PROC Cardinal_To_Fixed C near
|
|
||||||
USES ebx, edx
|
|
||||||
|
|
||||||
ARG base:DWORD
|
|
||||||
ARG cardinal:DWORD
|
|
||||||
|
|
||||||
mov eax,0FFFFFFFFh ; establish default return value
|
|
||||||
|
|
||||||
mov ebx,[base]
|
|
||||||
or ebx,ebx
|
|
||||||
jz near ??retneg1 ; if base==0, return 4294967295
|
|
||||||
|
|
||||||
mov eax,[cardinal] ; otherwise, return (cardinal*65536)/base
|
|
||||||
shl eax,16
|
|
||||||
xor edx,edx
|
|
||||||
div ebx
|
|
||||||
|
|
||||||
??retneg1:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Cardinal_To_Fixed
|
|
||||||
|
|
||||||
|
|
||||||
;***********************************************************************************************
|
|
||||||
;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
|
|
||||||
;* *
|
|
||||||
;* Use this routine to convert a fixed point number into a cardinal number. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: base -- The base number that the original fixed point number was created from. *
|
|
||||||
;* *
|
|
||||||
;* fixed -- The fixed point number to convert. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with the reconverted number. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 02/17/1995 BWG : Created. *
|
|
||||||
;*=============================================================================================*/
|
|
||||||
;unsigned int Fixed_To_Cardinal(unsigned base, unsigned fixed);
|
|
||||||
PROC Fixed_To_Cardinal C near
|
|
||||||
USES edx
|
|
||||||
|
|
||||||
ARG base:DWORD
|
|
||||||
ARG fixed:DWORD
|
|
||||||
|
|
||||||
mov eax,[base]
|
|
||||||
mul [fixed]
|
|
||||||
add eax,08000h ; eax = (base * fixed) + 0x8000
|
|
||||||
|
|
||||||
shr eax,16 ; return eax/65536
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Fixed_To_Cardinal
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -1,182 +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\cpuid.asv 5.0 11 Nov 1996 09:40:28 JOE_BOSTIC $
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 I N C **
|
|
||||||
;***************************************************************************
|
|
||||||
;* *
|
|
||||||
;* Project Name : Command & Conquer *
|
|
||||||
;* *
|
|
||||||
;* File Name : MMX.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Steve Tall *
|
|
||||||
;* *
|
|
||||||
;* Start Date : May 19th, 1996 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : May 19th 1996 [ST] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
|
|
||||||
.586
|
|
||||||
.model flat
|
|
||||||
|
|
||||||
;
|
|
||||||
; Variables externs
|
|
||||||
;
|
|
||||||
GLOBAL C CPUType:byte
|
|
||||||
;externdef C CPUType:byte
|
|
||||||
GLOBAL C VendorID:byte
|
|
||||||
;externdef C VendorID:byte
|
|
||||||
|
|
||||||
;
|
|
||||||
; Function externs
|
|
||||||
;
|
|
||||||
GLOBAL C Detect_MMX_Availability:near
|
|
||||||
;externdef C Detect_MMX_Availability:near
|
|
||||||
|
|
||||||
|
|
||||||
.code
|
|
||||||
|
|
||||||
|
|
||||||
;*********************************************************************************************
|
|
||||||
;* Detect_MMX_Availability -- Detect the presence of MMX technology. *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: Nothing *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: True if MMX technology is available. *
|
|
||||||
;* *
|
|
||||||
;* Warnings: *
|
|
||||||
;* *
|
|
||||||
;* Note: Based in part on CPUID32.ASM by Intel *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 05/19/96 ST : Created. *
|
|
||||||
;*===========================================================================================*
|
|
||||||
|
|
||||||
Detect_MMX_Availability proc C
|
|
||||||
|
|
||||||
local idflag:byte
|
|
||||||
local cputype:byte
|
|
||||||
|
|
||||||
;assume processor is at least 386
|
|
||||||
;
|
|
||||||
;check whether AC bit in eflags can be toggled.
|
|
||||||
;If not then processor is 386
|
|
||||||
|
|
||||||
mov [idflag],0
|
|
||||||
|
|
||||||
pushfd ;get Eflags in EAX
|
|
||||||
pop eax
|
|
||||||
mov ecx,eax ;save eflags
|
|
||||||
xor eax,40000h ;toggle AC bit in eflags
|
|
||||||
push eax ;new eflags on stack
|
|
||||||
popfd ;move new value into eflags
|
|
||||||
pushfd ;get new eflags back into eax
|
|
||||||
pop eax
|
|
||||||
xor eax,ecx ;if AC bit not toggled then CPU=386
|
|
||||||
mov [cputype],3
|
|
||||||
jz @@end_get_cpu ;cpu is 386
|
|
||||||
|
|
||||||
push ecx
|
|
||||||
popfd ;restore AC bit in eflags
|
|
||||||
|
|
||||||
|
|
||||||
;processor is at least 486
|
|
||||||
;
|
|
||||||
;Check for ability to set/clear ID flag in EFLAGS
|
|
||||||
;ID flag indicates ability of processor to execute the CPUID instruction.
|
|
||||||
;486 not guaranteed to have CPUID inst?
|
|
||||||
;
|
|
||||||
mov [cputype],4
|
|
||||||
mov eax,ecx ;original EFLAGS
|
|
||||||
xor eax,200000h ;toggle ID bit
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
xor eax,ecx ;check if still toggled
|
|
||||||
jz @@end_get_cpu
|
|
||||||
|
|
||||||
|
|
||||||
; Execute CPUID instruction to determine vendor, family,
|
|
||||||
; model and stepping.
|
|
||||||
;
|
|
||||||
|
|
||||||
mov [idflag],1 ;flag ID is available
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov dword ptr [VendorID],ebx
|
|
||||||
mov dword ptr [VendorID+4],edx
|
|
||||||
mov dword ptr [VendorID+8],ecx
|
|
||||||
mov dword ptr [VendorID+12]," "
|
|
||||||
|
|
||||||
cmp eax,1 ;check if 1 is valid
|
|
||||||
jl @@end_get_cpu ;inp for cpuid inst.
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
inc eax
|
|
||||||
|
|
||||||
cpuid ;get stepping, model and family
|
|
||||||
|
|
||||||
and ax,0f00H
|
|
||||||
shr ax,08H
|
|
||||||
|
|
||||||
mov [cputype],al
|
|
||||||
|
|
||||||
@@end_get_cpu: mov al,[cputype]
|
|
||||||
mov [CPUType],al
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; We have the CPU type in al now.
|
|
||||||
; If we arent on at least a pentium then we can assume there is no MMX
|
|
||||||
;
|
|
||||||
cmp al,5
|
|
||||||
jl @@no_mmx
|
|
||||||
|
|
||||||
mov eax,1
|
|
||||||
cpuid
|
|
||||||
test edx,00800000h
|
|
||||||
jz @@no_mmx
|
|
||||||
|
|
||||||
;
|
|
||||||
; MMX detected - return true
|
|
||||||
;
|
|
||||||
mov eax,1
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
@@no_mmx: xor eax,eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
Detect_MMX_Availability endp
|
|
||||||
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
CPUType db 0
|
|
||||||
VendorID db "Not available",0,0,0,0,0,0
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
+10
-10
@@ -51,13 +51,13 @@
|
|||||||
** Prototypes for linkage to assembly module
|
** Prototypes for linkage to assembly module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" {
|
//extern "C" {
|
||||||
bool __cdecl Detect_MMX_Availability(void);
|
// bool __cdecl Detect_MMX_Availability(void);
|
||||||
void __cdecl Init_MMX(void);
|
// void __cdecl Init_MMX(void);
|
||||||
|
//
|
||||||
extern char CPUType;
|
// extern char CPUType;
|
||||||
extern char VendorID;
|
// extern char VendorID;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
@@ -82,13 +82,13 @@ void Get_CPU_Type(int & cpu_type, bool & mmx, char * vendor_id, int vendor_id_le
|
|||||||
/*
|
/*
|
||||||
** Call the asm CPU detection code
|
** Call the asm CPU detection code
|
||||||
*/
|
*/
|
||||||
mmx = Detect_MMX_Availability();
|
mmx = 1; //Detect_MMX_Availability();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the promised results
|
** Return the promised results
|
||||||
*/
|
*/
|
||||||
cpu_type = (int)CPUType;
|
cpu_type = 1; //(int)CPUType;
|
||||||
char * vendor_ptr = &VendorID;
|
char* vendor_ptr = "Fake CPU"; //&VendorID;
|
||||||
strncpy(vendor_id, vendor_ptr, vendor_id_length);
|
strncpy(vendor_id, vendor_ptr, vendor_id_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,110 +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]>.
|
|
||||||
|
|
||||||
|
|
||||||
;!!!!!!!!!!!!!!!!!!! lock the allocation
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 : VQLIB *
|
|
||||||
;* *
|
|
||||||
;* File Name : HANDLER.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Bill Randolph *
|
|
||||||
;* *
|
|
||||||
;* Start Date : April 7, 1995 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : April 7, 1995 [BRR] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* IPXHandler -- callback routine for IPX *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
;********************* Model & Processor Directives ************************
|
|
||||||
IDEAL
|
|
||||||
P386
|
|
||||||
MODEL USE32 FLAT
|
|
||||||
LOCALS ??
|
|
||||||
|
|
||||||
|
|
||||||
;******************************** Includes *********************************
|
|
||||||
|
|
||||||
|
|
||||||
;******************************** Defines ***********************************
|
|
||||||
|
|
||||||
|
|
||||||
;****************************** Declarations ********************************
|
|
||||||
GLOBAL C Get_RM_IPX_Address:NEAR
|
|
||||||
GLOBAL C Get_RM_IPX_Size:NEAR
|
|
||||||
|
|
||||||
;********************************* Data ************************************
|
|
||||||
DATASEG
|
|
||||||
|
|
||||||
LABEL RealBinStart BYTE
|
|
||||||
include "obj\win32\ipxreal.ibn"
|
|
||||||
LABEL RealBinEnd BYTE
|
|
||||||
|
|
||||||
;********************************* Data ************************************
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Get_RM_IPX_Address -- Return address of real mode code for copy. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: *
|
|
||||||
;* none *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: *
|
|
||||||
;* VOID * to the address of the real mode IPX code *
|
|
||||||
;* *
|
|
||||||
;* PROTO: *
|
|
||||||
;* VOID *Get_RM_IPX_Address(VOID); *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 07/06/1994 SKB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
PROC Get_RM_IPX_Address C Near
|
|
||||||
|
|
||||||
mov eax, OFFSET RealBinStart
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Get_RM_IPX_Size -- return size of real mode IPX code. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: *
|
|
||||||
;* none *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: *
|
|
||||||
;* LONG size of the real mode IPX code *
|
|
||||||
;* *
|
|
||||||
;* PROTO: *
|
|
||||||
;* LONG Get_RM_IPX_Size(VOID); *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 07/06/1994 SKB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
PROC Get_RM_IPX_Size C Near
|
|
||||||
|
|
||||||
mov eax, OFFSET RealBinEnd - OFFSET RealBinStart
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
;************************** End of handler.asm *****************************
|
|
||||||
@@ -1,316 +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]>.
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 : VQLIB *
|
|
||||||
;* *
|
|
||||||
;* File Name : HANDLER.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Bill Randolph *
|
|
||||||
;* *
|
|
||||||
;* Start Date : April 7, 1995 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : April 7, 1995 [BRR] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* IPXHandler -- callback routine for IPX *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
;********************* Model & Processor Directives ************************
|
|
||||||
IDEAL
|
|
||||||
MODEL LARGE
|
|
||||||
P386N
|
|
||||||
LOCALS ??
|
|
||||||
|
|
||||||
|
|
||||||
;******************************** Includes *********************************
|
|
||||||
|
|
||||||
|
|
||||||
;******************************** Defines ***********************************
|
|
||||||
|
|
||||||
|
|
||||||
;****************************** Declarations ********************************
|
|
||||||
GLOBAL IPXHandler:FAR
|
|
||||||
|
|
||||||
|
|
||||||
;********************************* Code ************************************
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; The markers let the application verify that it's mapping this memory
|
|
||||||
; correctly.
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
Marker1 DW 1111h ; placeholder to find data start
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; This is the IPX Event Control Block:
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
ECB_LinkAddress DD ?
|
|
||||||
ECB_EventServiceRoutine DD ? ; Event Handler ptr
|
|
||||||
ECB_InUse DB ? ; 0 = event is complete
|
|
||||||
ECB_CompletionCode DB ? ; 0 = OK, IPX error otherwise
|
|
||||||
ECB_SocketNumber DW ? ; socket to listen/send on
|
|
||||||
ECB_ConnectionID DW ?
|
|
||||||
ECB_RestOfWorkspace DW ?
|
|
||||||
ECB_DriverWorkSpace DB 12 DUP (?)
|
|
||||||
ECB_ImmediateAddress DB 6 DUP (?) ; bridge address
|
|
||||||
ECB_PacketCount DW ? ; # data areas (2)
|
|
||||||
ECB_HeaderAddress DD ? ; ptr to IPX header buffer
|
|
||||||
ECB_HeaderLength DW ? ; length of IPX header buffer
|
|
||||||
ECB_PacketAddress DD ? ; ptr to packet buffer
|
|
||||||
ECB_PacketLength DW ? ; length of packet buffer
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; The rest of the variables are for telling IPX which buffer to store the
|
|
||||||
; next incoming packet in. They must be initialized by the application.
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
NumBufs DW 0 ; # buffers provided by app
|
|
||||||
BufferFlags DD 0 ; array of in-use flags (1 = in use)
|
|
||||||
PacketSize DW 0 ; total size of 1 buf (incl IPX hdr)
|
|
||||||
FirstPacketBuf DD 0 ; ptr to 1st packet buffer
|
|
||||||
CurIndex DW 0 ; current packet/flag index
|
|
||||||
CurPacketBuf DD 0 ; ptr to current packet buf
|
|
||||||
FuncOffset DW StartLabel ; offset of our routine
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; These values are for preventing re-entrancy; they're currently not used.
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
Semaphore DB 0 ; prevents re-entrancy
|
|
||||||
ReEntrantCount DW 0 ; times we've been called re-entrantly
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; Local stack space
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
StackPtr DW 0 ; saved copy of stack ptr
|
|
||||||
StackSeg DW 0 ; saved copy of stack seg
|
|
||||||
StackPtr_int DW 0 ; our internal stack ptr
|
|
||||||
StackSeg_int DW 0 ; our internal stack seg
|
|
||||||
StackCheck DW 1234h ; check for stack overflow
|
|
||||||
DW 256 DUP (0) ; stack storage space
|
|
||||||
StackSpace DW 0 ; label for our stack space
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
; These bytes mark the end of the real-mode data area
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
Marker2 DW 2222h ; placeholder to find data end
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* IPXHandler -- IPX callback routine *
|
|
||||||
;* *
|
|
||||||
;* This routine is assembled as a stand-alone executable, then loaded *
|
|
||||||
;* into low DOS memory by a protected-mode application. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: *
|
|
||||||
;* none. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: *
|
|
||||||
;* none. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: *
|
|
||||||
;* none. *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 04/07/1995 BRR : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
label StartLabel
|
|
||||||
PROC IPXHandler C FAR USES
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Turn off interrupts; make sure memory copies go forward
|
|
||||||
;...................................................................
|
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
cld
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Set up segment registers to point DS to CS
|
|
||||||
;...................................................................
|
|
||||||
push ds
|
|
||||||
push ax
|
|
||||||
mov ax,cs
|
|
||||||
mov ds,ax
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Set up our local stack; save SS & SP first.
|
|
||||||
;...................................................................
|
|
||||||
mov [StackSeg],ss
|
|
||||||
mov [StackPtr],sp
|
|
||||||
mov [StackPtr_int], OFFSET StackSpace
|
|
||||||
mov [StackSeg_int], SEG StackSpace
|
|
||||||
lss sp, [DWORD PTR StackPtr_int]
|
|
||||||
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Save all registers
|
|
||||||
;...................................................................
|
|
||||||
pushad
|
|
||||||
push es
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; If we've been called re-entrantly, just exit
|
|
||||||
;...................................................................
|
|
||||||
cmp [Semaphore],0
|
|
||||||
jz ??Start_Handler
|
|
||||||
add [ReEntrantCount],1
|
|
||||||
jmp ??Exit_Handler
|
|
||||||
|
|
||||||
??Start_Handler:
|
|
||||||
;...................................................................
|
|
||||||
; Set our semaphore
|
|
||||||
;...................................................................
|
|
||||||
mov [Semaphore],1
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
; Set 'CurIndex' to the index of the next-available receive buffer,
|
|
||||||
; and 'CurPacketBuf to the next-available packet buffer
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
;...................................................................
|
|
||||||
; Get 'CurIndex' & increment it. Wrap to 0 if we reach 'NumBufs'
|
|
||||||
; Since I'm treating 'CurPacketBuf' as a long integer (and not as
|
|
||||||
; a segment:offset), the entire data area can't be larger than 64K.
|
|
||||||
;...................................................................
|
|
||||||
mov dx,[CurIndex] ; DX = CurIndex
|
|
||||||
mov eax,[CurPacketBuf] ; EAX = current packet buffer addr
|
|
||||||
inc dx ; DX = next index
|
|
||||||
add ax,[PacketSize] ; EAX = next buffer ptr
|
|
||||||
cmp dx,[NumBufs] ; see if DX is past # buffers
|
|
||||||
jb ??Get_Flag
|
|
||||||
mov dx,0 ; wrap to 1st index
|
|
||||||
mov eax,[FirstPacketBuf] ; wrap to 1st packet buffer
|
|
||||||
|
|
||||||
??Get_Flag:
|
|
||||||
;...................................................................
|
|
||||||
; Get the next buffer-in-use flag; if it's 0, load [CurIndex] with
|
|
||||||
; the value of SI (the next index). If it's 1, skip the updating of
|
|
||||||
; the index, flag & buffer ptr.
|
|
||||||
; DX = new CurIndex
|
|
||||||
; EAX = new CurPacketBuf
|
|
||||||
;...................................................................
|
|
||||||
les di,[BufferFlags] ; ES:DI = BufferFlags address
|
|
||||||
mov bx,di ; BX = DI + new CurIndex
|
|
||||||
add bx,dx
|
|
||||||
|
|
||||||
cmp [BYTE PTR es:bx],0 ; compare next flag to 0 (avail)
|
|
||||||
jne ??Set_ECB ; if not avail, skip setting new values
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; The next buffer is available; so, set this buffer's In-Use flag
|
|
||||||
; to 1, and move on to the next buffer. Do not set this buffer's
|
|
||||||
; flag to 1 until we move on to the next buffer, to prevent the
|
|
||||||
; application from reading the currently-in-use packet buffer.
|
|
||||||
; DX = new CurIndex
|
|
||||||
; EAX = new CurPacketBuf
|
|
||||||
; ES:DI = BufferFlags address
|
|
||||||
;...................................................................
|
|
||||||
mov bx,di ; BX = DI + old CurIndex
|
|
||||||
add bx,[CurIndex]
|
|
||||||
mov [BYTE PTR es:bx],1 ; set old BufferFlags value to in-use
|
|
||||||
|
|
||||||
mov [CurIndex],dx ; save new index
|
|
||||||
mov [CurPacketBuf],eax ; save new packet address
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
; Set up the Event Control Block to tell IPX to start listening.
|
|
||||||
; The following entries are filled in by the app, and should be left
|
|
||||||
; alone:
|
|
||||||
; - EventServiceRoutine
|
|
||||||
; - SocketNumber
|
|
||||||
; The rest should be re-initialized. Note that EBX is now pointing
|
|
||||||
; to an unavailable buffer if the next buffer was already in use;
|
|
||||||
; so it must be reloaded with the correct buffer address from
|
|
||||||
; [CurPacketBuf].
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
??Set_ECB:
|
|
||||||
mov [ECB_LinkAddress],0 ; default
|
|
||||||
mov [ECB_InUse],0 ; default
|
|
||||||
mov [ECB_CompletionCode],0 ; default
|
|
||||||
mov [ECB_ConnectionID],0 ; default
|
|
||||||
mov [ECB_RestOfWorkspace],0 ; default
|
|
||||||
mov [ECB_DriverWorkSpace],0 ; default
|
|
||||||
mov [ECB_ImmediateAddress],0 ; default
|
|
||||||
mov [ECB_PacketCount],2 ; use 2 data areas
|
|
||||||
mov ebx,[CurPacketBuf] ; get current buffer address
|
|
||||||
mov [ECB_HeaderAddress],ebx ; set header address
|
|
||||||
mov [ECB_HeaderLength],30 ; size of IPX header
|
|
||||||
add ebx,30 ; point to past the header
|
|
||||||
mov [ECB_PacketAddress],ebx ; set packet data address
|
|
||||||
mov ax,[PacketSize] ; get size of one buffer
|
|
||||||
sub ax,30 ; remove size of IPX header
|
|
||||||
mov [ECB_PacketLength],ax ; set size of packet data
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
; Clear the IPX header for this packet
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
les di,[ECB_HeaderAddress] ; ES:DI = IPX Listen Header
|
|
||||||
mov cx,30 ; (30 bytes = size of header)
|
|
||||||
mov al,0
|
|
||||||
rep stosb ; clear to 0's
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
; Command IPX to start listening again.
|
|
||||||
;-------------------------------------------------------------------
|
|
||||||
mov bx,4 ; IPX code for Listen
|
|
||||||
mov ax,ds ; ES = segment of ListenECB
|
|
||||||
mov es,ax
|
|
||||||
mov ax,OFFSET ECB_LinkAddress
|
|
||||||
mov si,ax ; ES:SI = address of ECB
|
|
||||||
int 07ah ; call IPX interrupt
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Clear our semaphore
|
|
||||||
;...................................................................
|
|
||||||
mov [Semaphore],0
|
|
||||||
|
|
||||||
??Exit_Handler:
|
|
||||||
;...................................................................
|
|
||||||
; Pop values from our local stack
|
|
||||||
;...................................................................
|
|
||||||
pop es
|
|
||||||
popad
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Check our stack-check value; if the stack has overflowed, generate
|
|
||||||
; a debugger break.
|
|
||||||
;...................................................................
|
|
||||||
cmp [StackCheck],1234h
|
|
||||||
je ??Restore_Stack
|
|
||||||
int 3
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Restore the stack to its previous value
|
|
||||||
;...................................................................
|
|
||||||
??Restore_Stack:
|
|
||||||
lss sp, [DWORD PTR StackPtr]
|
|
||||||
|
|
||||||
;...................................................................
|
|
||||||
; Pop the rest of the registers
|
|
||||||
;...................................................................
|
|
||||||
pop ax
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
popf
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP IPXHandler
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
;************************** End of handler.asm *****************************
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,299 +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]>.
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 I N C **
|
|
||||||
;***************************************************************************
|
|
||||||
;* *
|
|
||||||
;* Project Name : Command & Conquer *
|
|
||||||
;* *
|
|
||||||
;* File Name : MMX.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Steve Tall *
|
|
||||||
;* *
|
|
||||||
;* Start Date : May 19th, 1996 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : May 19th 1996 [ST] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
|
|
||||||
; include <mmx.inc>
|
|
||||||
|
|
||||||
|
|
||||||
.model flat
|
|
||||||
;.686
|
|
||||||
|
|
||||||
|
|
||||||
externdef C Detect_MMX_Availability:near
|
|
||||||
externdef C Single_Line_Trans_Entry:near
|
|
||||||
externdef C Next_Line:near
|
|
||||||
externdef C Init_MMX:near
|
|
||||||
externdef C MMX_Done:near
|
|
||||||
|
|
||||||
externdef EndNewShapeJumpTable:byte
|
|
||||||
externdef NewShapeJumpTable:dword
|
|
||||||
externdef C Single_Line_Trans:near
|
|
||||||
externdef MMX_Single_Line_Trans:near
|
|
||||||
|
|
||||||
|
|
||||||
.code
|
|
||||||
|
|
||||||
externdef C CPUType:byte
|
|
||||||
externdef C VendorID:byte
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;*********************************************************************************************
|
|
||||||
;* Detect_MMX_Availability -- Detect the presence of MMX technology. *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: Nothing *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: True if MMX technology is available. *
|
|
||||||
;* *
|
|
||||||
;* Warnings: *
|
|
||||||
;* *
|
|
||||||
;* Note: Based in part on CPUID32.ASM by Intel *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 05/19/96 ST : Created. *
|
|
||||||
;*===========================================================================================*
|
|
||||||
|
|
||||||
Detect_MMX_Availability proc C
|
|
||||||
|
|
||||||
local idflag:byte
|
|
||||||
local local_cputype:byte
|
|
||||||
|
|
||||||
; MMX always available now. ST - 1/3/2019 1:31PM
|
|
||||||
mov [CPUType], 5
|
|
||||||
mov eax, 1
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
;assume processor is at least 386
|
|
||||||
;
|
|
||||||
;check whether AC bit in eflags can be toggled.
|
|
||||||
;If not then processor is 386
|
|
||||||
|
|
||||||
mov [idflag],0
|
|
||||||
|
|
||||||
pushfd ;get Eflags in EAX
|
|
||||||
pop eax
|
|
||||||
mov ecx,eax ;save eflags
|
|
||||||
xor eax,40000h ;toggle AC bit in eflags
|
|
||||||
push eax ;new eflags on stack
|
|
||||||
popfd ;move new value into eflags
|
|
||||||
pushfd ;get new eflags back into eax
|
|
||||||
pop eax
|
|
||||||
xor eax,ecx ;if AC bit not toggled then CPU=386
|
|
||||||
mov [local_cputype],3
|
|
||||||
jz @@end_get_cpu ;cpu is 386
|
|
||||||
|
|
||||||
push ecx
|
|
||||||
popfd ;restore AC bit in eflags
|
|
||||||
|
|
||||||
|
|
||||||
;processor is at least 486
|
|
||||||
;
|
|
||||||
;Check for ability to set/clear ID flag in EFLAGS
|
|
||||||
;ID flag indicates ability of processor to execute the CPUID instruction.
|
|
||||||
;486 not guaranteed to have CPUID inst?
|
|
||||||
;
|
|
||||||
mov [local_cputype],4
|
|
||||||
mov eax,ecx ;original EFLAGS
|
|
||||||
xor eax,200000h ;toggle ID bit
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
xor eax,ecx ;check if still toggled
|
|
||||||
jz @@end_get_cpu
|
|
||||||
|
|
||||||
|
|
||||||
; Execute CPUID instruction to determine vendor, family,
|
|
||||||
; model and stepping.
|
|
||||||
;
|
|
||||||
|
|
||||||
mov [idflag],1 ;flag ID is available
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
cpuid
|
|
||||||
|
|
||||||
mov dword ptr [VendorID],ebx
|
|
||||||
mov dword ptr [VendorID+4],edx
|
|
||||||
mov dword ptr [VendorID+8],ecx
|
|
||||||
mov dword ptr [VendorID+12]," "
|
|
||||||
|
|
||||||
cmp eax,1 ;check if 1 is valid
|
|
||||||
jl @@end_get_cpu ;inp for cpuid inst.
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
inc eax
|
|
||||||
|
|
||||||
cpuid ;get stepping, model and family
|
|
||||||
|
|
||||||
and ax,0f00H
|
|
||||||
shr ax,08H
|
|
||||||
|
|
||||||
mov [local_cputype],al
|
|
||||||
|
|
||||||
@@end_get_cpu: mov al,[local_cputype]
|
|
||||||
mov [CPUType],al
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; We have the CPU type in al now.
|
|
||||||
; If we arent on at least a pentium then we can assume there is no MMX
|
|
||||||
;
|
|
||||||
cmp al,5
|
|
||||||
jl @@no_mmx
|
|
||||||
|
|
||||||
mov eax,1
|
|
||||||
cpuid
|
|
||||||
test edx,00800000h
|
|
||||||
jz @@no_mmx
|
|
||||||
|
|
||||||
;
|
|
||||||
; MMX detected - return true
|
|
||||||
;
|
|
||||||
mov eax,1
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
@@no_mmx: xor eax,eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
Detect_MMX_Availability endp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;*********************************************************************************************
|
|
||||||
;* Init_MMX -- Do any special inits required for MMX support *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: Nothing *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: None *
|
|
||||||
;* *
|
|
||||||
;* Warnings: *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 05/19/96 ST : Created. *
|
|
||||||
;*===========================================================================================*
|
|
||||||
|
|
||||||
Init_MMX proc C
|
|
||||||
|
|
||||||
mov edi,offset NewShapeJumpTable
|
|
||||||
mov ecx,offset EndNewShapeJumpTable
|
|
||||||
sub ecx,edi
|
|
||||||
shr ecx,2
|
|
||||||
mov eax,offset Single_Line_Trans
|
|
||||||
mov ebx,offset MMX_Single_Line_Trans
|
|
||||||
cld
|
|
||||||
|
|
||||||
|
|
||||||
@@patch_loop: repnz scasd
|
|
||||||
jnz @@done
|
|
||||||
mov [edi-4],ebx
|
|
||||||
test ecx,ecx
|
|
||||||
jnz @@patch_loop
|
|
||||||
|
|
||||||
@@done: ret
|
|
||||||
|
|
||||||
Init_MMX endp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;*********************************************************************************************
|
|
||||||
;* MMX_Done -- Restores floating point capability after MMX usage *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: Nothing *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: None *
|
|
||||||
;* *
|
|
||||||
;* Warnings: *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 05/19/96 ST : Created. *
|
|
||||||
;*===========================================================================================*
|
|
||||||
|
|
||||||
MMX_Done proc C
|
|
||||||
|
|
||||||
emms
|
|
||||||
ret
|
|
||||||
|
|
||||||
MMX_Done endp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
code segment page public use32 'code' ; Need stricter segment alignment
|
|
||||||
; for pentium optimisations
|
|
||||||
|
|
||||||
|
|
||||||
;*********************************************************************************************
|
|
||||||
;* MMX_Single_Line_Trans -- draw a single line of transparent pixels using MMX technology *
|
|
||||||
;* *
|
|
||||||
;* *
|
|
||||||
;* INPUT: Esi - ptr to source data *
|
|
||||||
;* Edi - ptr to destination data *
|
|
||||||
;* Ecx - width to draw in bytes *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: None *
|
|
||||||
;* *
|
|
||||||
;* Warnings: *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 05/19/96 ST : Created. *
|
|
||||||
;*===========================================================================================*
|
|
||||||
|
|
||||||
align 16
|
|
||||||
|
|
||||||
MMX_Single_Line_Trans proc near
|
|
||||||
|
|
||||||
;
|
|
||||||
; If we are doing less than 8 bytes then dont use MMX
|
|
||||||
;
|
|
||||||
push offset Single_Line_Trans_Entry
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
@@next_line: ret
|
|
||||||
|
|
||||||
|
|
||||||
MMX_Single_Line_Trans endp
|
|
||||||
|
|
||||||
|
|
||||||
code ends
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
CPUType db 0
|
|
||||||
VendorID db "Not available",0,0,0,0,0,0
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -176,6 +176,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, unsigned int fdwReason, void *lpvReserve
|
|||||||
* HISTORY: *
|
* HISTORY: *
|
||||||
* 03/20/1995 JLB : Created. *
|
* 03/20/1995 JLB : Created. *
|
||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
|
void Reallocate_Big_Shape_Buffer(void);
|
||||||
int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
|
int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -186,7 +187,7 @@ int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int
|
|||||||
//char command_line[1024];
|
//char command_line[1024];
|
||||||
//strcpy(command_line, command_line_in);
|
//strcpy(command_line, command_line_in);
|
||||||
|
|
||||||
|
Reallocate_Big_Shape_Buffer();
|
||||||
|
|
||||||
#ifndef MPEGMOVIE // Denzil 6/10/98
|
#ifndef MPEGMOVIE // Denzil 6/10/98
|
||||||
//PG DDSCAPS surface_capabilities;
|
//PG DDSCAPS surface_capabilities;
|
||||||
|
|||||||
@@ -1,556 +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\support.asv 5.0 11 Nov 1996 09:40:30 JOE_BOSTIC $
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 : Command & Conquer *
|
|
||||||
;* *
|
|
||||||
;* File Name : SUPPORT.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Joe L. Bostic *
|
|
||||||
;* *
|
|
||||||
;* Start Date : September 23, 1993 *
|
|
||||||
;* *
|
|
||||||
;* Last Update : May 10, 1994 [JLB] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* strtrim -- Remove the trailing white space from a string. *
|
|
||||||
;* Fat_Put_Pixel -- Draws a fat pixel. *
|
|
||||||
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
|
|
||||||
;* Remove_From_List -- Removes a pointer from a list of pointers. *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
IDEAL
|
|
||||||
P386
|
|
||||||
MODEL USE32 FLAT
|
|
||||||
|
|
||||||
INCLUDE "gbuffer.inc"
|
|
||||||
DISPLAY "Command & Conquer assembly support routines."
|
|
||||||
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Fat_Put_Pixel -- Draws a fat pixel. *
|
|
||||||
;* *
|
|
||||||
;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
|
|
||||||
;* across. This routine is faster than drawing a similar small shape *
|
|
||||||
;* and faster than calling Fill_Rect. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
|
|
||||||
;* left corner. *
|
|
||||||
;* *
|
|
||||||
;* color -- The color to render the pixel in. *
|
|
||||||
;* *
|
|
||||||
;* size -- The number of pixels width of the big "pixel". *
|
|
||||||
;* *
|
|
||||||
;* page -- The pointer to a GraphicBuffer class or something *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 03/17/1994 JLB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
|
|
||||||
GLOBAL C Fat_Put_Pixel:NEAR
|
|
||||||
PROC Fat_Put_Pixel C near
|
|
||||||
USES eax, ebx, ecx, edx, edi, esi
|
|
||||||
|
|
||||||
ARG x:DWORD ; X coordinate of upper left pixel corner.
|
|
||||||
ARG y:DWORD ; Y coordinate of upper left pixel corner.
|
|
||||||
ARG color:DWORD ; Color to use for the "pixel".
|
|
||||||
ARG siz:DWORD ; Size of "pixel" to plot (square).
|
|
||||||
ARG gpage:DWORD ; graphic page address to plot onto
|
|
||||||
|
|
||||||
cmp [siz],0
|
|
||||||
je short ??exit
|
|
||||||
|
|
||||||
; Set EDI to point to start of logical page memory.
|
|
||||||
;*===================================================================
|
|
||||||
; Get the viewport information and put bytes per row in ecx
|
|
||||||
;*===================================================================
|
|
||||||
mov ebx,[gpage] ; get a pointer to viewport
|
|
||||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
|
|
||||||
|
|
||||||
; Verify the the Y pixel offset is legal.
|
|
||||||
mov eax,[y]
|
|
||||||
cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
|
|
||||||
jae short ??exit
|
|
||||||
mul [(GraphicViewPort ebx).GVPWidth]
|
|
||||||
add edi,eax
|
|
||||||
|
|
||||||
; Verify the the X pixel offset is legal.
|
|
||||||
mov edx,[(GraphicViewPort ebx).GVPWidth]
|
|
||||||
cmp edx,[x]
|
|
||||||
jbe short ??exit
|
|
||||||
add edi,[x]
|
|
||||||
|
|
||||||
; Write the pixel to the screen.
|
|
||||||
mov ebx,[siz] ; Copy of pixel size.
|
|
||||||
sub edx,ebx ; Modulo to reach start of next row.
|
|
||||||
mov eax,[color]
|
|
||||||
??again:
|
|
||||||
mov ecx,ebx
|
|
||||||
rep stosb
|
|
||||||
add edi,edx ; EDI points to start of next row.
|
|
||||||
dec [siz]
|
|
||||||
jnz short ??again
|
|
||||||
|
|
||||||
??exit:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Fat_Put_Pixel
|
|
||||||
|
|
||||||
|
|
||||||
if 0
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* strtrim -- Remove the trailing white space from a string. *
|
|
||||||
;* *
|
|
||||||
;* Use this routine to remove white space characters from the beginning *
|
|
||||||
;* and end of the string. The string is modified in place by *
|
|
||||||
;* this routine. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: buffer -- Pointer to the string to modify. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/07/1992 JLB : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
; VOID cdecl strtrim(BYTE *buffer);
|
|
||||||
GLOBAL C strtrim :NEAR
|
|
||||||
PROC strtrim C near
|
|
||||||
USES ax, edi, esi
|
|
||||||
|
|
||||||
ARG buffer:DWORD ; Pointer to string to modify.
|
|
||||||
|
|
||||||
cmp [buffer],0
|
|
||||||
je short ??fini
|
|
||||||
|
|
||||||
; Prepare for string scanning by loading pointers.
|
|
||||||
cld
|
|
||||||
mov esi,[buffer]
|
|
||||||
mov edi,esi
|
|
||||||
|
|
||||||
; Strip white space from the start of the string.
|
|
||||||
??looper:
|
|
||||||
lodsb
|
|
||||||
cmp al,20h ; Space
|
|
||||||
je short ??looper
|
|
||||||
cmp al,9 ; TAB
|
|
||||||
je short ??looper
|
|
||||||
stosb
|
|
||||||
|
|
||||||
; Copy the rest of the string.
|
|
||||||
??gruntloop:
|
|
||||||
lodsb
|
|
||||||
stosb
|
|
||||||
or al,al
|
|
||||||
jnz short ??gruntloop
|
|
||||||
dec edi
|
|
||||||
; Strip the white space from the end of the string.
|
|
||||||
??looper2:
|
|
||||||
mov [edi],al
|
|
||||||
dec edi
|
|
||||||
mov ah,[edi]
|
|
||||||
cmp ah,20h
|
|
||||||
je short ??looper2
|
|
||||||
cmp ah,9
|
|
||||||
je short ??looper2
|
|
||||||
|
|
||||||
??fini:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP strtrim
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
|
|
||||||
;* *
|
|
||||||
;* This routine is used to build a special fading table for C&C. There *
|
|
||||||
;* are certain colors that get faded to and cannot be faded again. *
|
|
||||||
;* With this rule, it is possible to draw a shadow multiple times and *
|
|
||||||
;* not have it get any lighter or darker. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
|
|
||||||
;* *
|
|
||||||
;* dest -- Pointer to the 256 byte remap table. *
|
|
||||||
;* *
|
|
||||||
;* color -- Color index of the color to "fade to". *
|
|
||||||
;* *
|
|
||||||
;* frac -- The fraction to fade to the specified color *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with pointer to the remap table. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/07/1992 JLB : Created. *
|
|
||||||
;*=========================================================================*/
|
|
||||||
;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
|
|
||||||
GLOBAL C Conquer_Build_Fading_Table : NEAR
|
|
||||||
PROC Conquer_Build_Fading_Table C near
|
|
||||||
USES ebx, ecx, edi, esi
|
|
||||||
|
|
||||||
ARG palette:DWORD
|
|
||||||
ARG dest:DWORD
|
|
||||||
ARG color:DWORD
|
|
||||||
ARG frac:DWORD
|
|
||||||
|
|
||||||
LOCAL matchvalue:DWORD ; Last recorded match value.
|
|
||||||
LOCAL targetred:BYTE ; Target gun red.
|
|
||||||
LOCAL targetgreen:BYTE ; Target gun green.
|
|
||||||
LOCAL targetblue:BYTE ; Target gun blue.
|
|
||||||
LOCAL idealred:BYTE
|
|
||||||
LOCAL idealgreen:BYTE
|
|
||||||
LOCAL idealblue:BYTE
|
|
||||||
LOCAL matchcolor:BYTE ; Tentative match color.
|
|
||||||
|
|
||||||
ALLOWED_COUNT EQU 16
|
|
||||||
ALLOWED_START EQU 256-ALLOWED_COUNT
|
|
||||||
|
|
||||||
cld
|
|
||||||
|
|
||||||
; If the source palette is NULL, then just return with current fading table pointer.
|
|
||||||
cmp [palette],0
|
|
||||||
je ??fini1
|
|
||||||
cmp [dest],0
|
|
||||||
je ??fini1
|
|
||||||
|
|
||||||
; Fractions above 255 become 255.
|
|
||||||
mov eax,[frac]
|
|
||||||
cmp eax,0100h
|
|
||||||
jb short ??ok
|
|
||||||
mov [frac],0FFh
|
|
||||||
??ok:
|
|
||||||
|
|
||||||
; Record the target gun values.
|
|
||||||
mov esi,[palette]
|
|
||||||
mov ebx,[color]
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
lodsb
|
|
||||||
mov [targetred],al
|
|
||||||
lodsb
|
|
||||||
mov [targetgreen],al
|
|
||||||
lodsb
|
|
||||||
mov [targetblue],al
|
|
||||||
|
|
||||||
; Main loop.
|
|
||||||
xor ebx,ebx ; Remap table index.
|
|
||||||
|
|
||||||
; Transparent black never gets remapped.
|
|
||||||
mov edi,[dest]
|
|
||||||
mov [edi],bl
|
|
||||||
inc edi
|
|
||||||
|
|
||||||
; EBX = source palette logical number (1..255).
|
|
||||||
; EDI = running pointer into dest remap table.
|
|
||||||
??mainloop:
|
|
||||||
inc ebx
|
|
||||||
mov esi,[palette]
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
add esi,ebx
|
|
||||||
|
|
||||||
mov edx,[frac]
|
|
||||||
shr edx,1
|
|
||||||
; new = orig - ((orig-target) * fraction);
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetred] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealred],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetgreen] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealgreen],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
lodsb ; orig
|
|
||||||
mov dh,al ; preserve it for later.
|
|
||||||
sub al,[targetblue] ; al = (orig-target)
|
|
||||||
imul dl ; ax = (orig-target)*fraction
|
|
||||||
shl eax,1
|
|
||||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
|
||||||
mov [idealblue],dh ; preserve ideal color gun value.
|
|
||||||
|
|
||||||
; Sweep through a limited set of existing colors to find the closest
|
|
||||||
; matching color.
|
|
||||||
|
|
||||||
mov eax,[color]
|
|
||||||
mov [matchcolor],al ; Default color (self).
|
|
||||||
mov [matchvalue],-1 ; Ridiculous match value init.
|
|
||||||
mov ecx,ALLOWED_COUNT
|
|
||||||
|
|
||||||
mov esi,[palette] ; Pointer to original palette.
|
|
||||||
add esi,(ALLOWED_START)*3
|
|
||||||
|
|
||||||
; BH = color index.
|
|
||||||
mov bh,ALLOWED_START
|
|
||||||
??innerloop:
|
|
||||||
|
|
||||||
xor edx,edx ; Comparison value starts null.
|
|
||||||
|
|
||||||
; Build the comparison value based on the sum of the differences of the color
|
|
||||||
; guns squared.
|
|
||||||
lodsb
|
|
||||||
sub al,[idealred]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
|
|
||||||
lodsb
|
|
||||||
sub al,[idealgreen]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
|
|
||||||
lodsb
|
|
||||||
sub al,[idealblue]
|
|
||||||
mov ah,al
|
|
||||||
imul ah
|
|
||||||
add edx,eax
|
|
||||||
jz short ??perfect ; If perfect match found then quit early.
|
|
||||||
|
|
||||||
cmp edx,[matchvalue]
|
|
||||||
jae short ??notclose
|
|
||||||
mov [matchvalue],edx ; Record new possible color.
|
|
||||||
mov [matchcolor],bh
|
|
||||||
??notclose:
|
|
||||||
inc bh ; Checking color index.
|
|
||||||
loop ??innerloop
|
|
||||||
mov bh,[matchcolor]
|
|
||||||
??perfect:
|
|
||||||
mov [matchcolor],bh
|
|
||||||
xor bh,bh ; Make BX valid main index again.
|
|
||||||
|
|
||||||
; When the loop exits, we have found the closest match.
|
|
||||||
mov al,[matchcolor]
|
|
||||||
stosb
|
|
||||||
cmp ebx,ALLOWED_START-1
|
|
||||||
jne ??mainloop
|
|
||||||
|
|
||||||
; Fill the remainder of the remap table with values
|
|
||||||
; that will remap the color to itself.
|
|
||||||
mov ecx,ALLOWED_COUNT
|
|
||||||
??fillerloop:
|
|
||||||
inc bl
|
|
||||||
mov al,bl
|
|
||||||
stosb
|
|
||||||
loop ??fillerloop
|
|
||||||
|
|
||||||
??fini1:
|
|
||||||
mov esi,[dest]
|
|
||||||
mov eax,esi
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Conquer_Build_Fading_Table
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* Remove_From_List -- Removes a pointer from a list of pointers. *
|
|
||||||
;* *
|
|
||||||
;* This low level routine is used to remove a pointer from a list of *
|
|
||||||
;* pointers. The trailing pointers are moved downward to fill the *
|
|
||||||
;* hole. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: list -- Pointer to list of pointer. *
|
|
||||||
;* *
|
|
||||||
;* index -- Pointer to length of pointer list. *
|
|
||||||
;* *
|
|
||||||
;* ptr -- The pointer value to search for and remove. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 04/11/1994 JLB : Created. *
|
|
||||||
;* 04/22/1994 JLB : Convert to assembly language. *
|
|
||||||
;* 05/10/1994 JLB : Short pointers now. *
|
|
||||||
;*=========================================================================*/
|
|
||||||
;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
|
|
||||||
GLOBAL C Remove_From_List:NEAR
|
|
||||||
PROC Remove_From_List C near
|
|
||||||
USES edi, esi, ecx, eax
|
|
||||||
ARG list:DWORD ; Pointer to list.
|
|
||||||
ARG index:DWORD ; Pointer to count.
|
|
||||||
ARG element:DWORD ; Element to remove.
|
|
||||||
|
|
||||||
; Fetch the number of elements in the list. If there are no
|
|
||||||
; elements, then just exit quickly.
|
|
||||||
mov edi,[index]
|
|
||||||
mov ecx,[edi]
|
|
||||||
jcxz short ??fini2
|
|
||||||
|
|
||||||
; Fetch pointer to list.
|
|
||||||
cmp [list],0
|
|
||||||
je short ??fini2
|
|
||||||
mov edi,[list]
|
|
||||||
|
|
||||||
; Loop through all elements searching for a match.
|
|
||||||
mov eax,[element]
|
|
||||||
repne scasd
|
|
||||||
jne short ??fini2 ; No match found.
|
|
||||||
|
|
||||||
; Copy all remaining elements down. If this is the
|
|
||||||
; last element in the list then nothing needs to be
|
|
||||||
; copied -- just decrement the list size.
|
|
||||||
jcxz short ??nocopy ; No copy necessary.
|
|
||||||
mov esi,edi
|
|
||||||
sub edi,4
|
|
||||||
rep movsd
|
|
||||||
|
|
||||||
; Reduce the list count by one.
|
|
||||||
??nocopy:
|
|
||||||
mov edi,[index]
|
|
||||||
dec [DWORD PTR edi]
|
|
||||||
|
|
||||||
??fini2:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Remove_From_List
|
|
||||||
|
|
||||||
|
|
||||||
; long cdecl Get_EAX();
|
|
||||||
GLOBAL C Get_EAX :NEAR
|
|
||||||
PROC Get_EAX C near
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Get_EAX
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
DATASEG
|
|
||||||
|
|
||||||
TabA DD 6949350
|
|
||||||
DD 4913933
|
|
||||||
DD 3474675
|
|
||||||
DD 2456966
|
|
||||||
DD 1737338
|
|
||||||
DD 1228483
|
|
||||||
DD 868669
|
|
||||||
DD 614242
|
|
||||||
DD 434334
|
|
||||||
DD 307121
|
|
||||||
DD 217167
|
|
||||||
DD 153560
|
|
||||||
DD 108584
|
|
||||||
DD 76780
|
|
||||||
DD 54292
|
|
||||||
DD 38390
|
|
||||||
DD 27146
|
|
||||||
DD 19195
|
|
||||||
DD 13573
|
|
||||||
DD 9598
|
|
||||||
DD 6786
|
|
||||||
DD 4799
|
|
||||||
DD 3393
|
|
||||||
DD 2399
|
|
||||||
DD 1697
|
|
||||||
DD 1200
|
|
||||||
DD 848
|
|
||||||
DD 600
|
|
||||||
DD 424
|
|
||||||
DD 300
|
|
||||||
DD 212
|
|
||||||
DD 150
|
|
||||||
DD 106
|
|
||||||
|
|
||||||
TabB DD 154
|
|
||||||
DD 218
|
|
||||||
DD 309
|
|
||||||
DD 437
|
|
||||||
DD 618
|
|
||||||
DD 874
|
|
||||||
DD 1236
|
|
||||||
DD 1748
|
|
||||||
DD 2472
|
|
||||||
DD 3496
|
|
||||||
DD 4944
|
|
||||||
DD 6992
|
|
||||||
DD 9888
|
|
||||||
DD 13983
|
|
||||||
DD 19775
|
|
||||||
DD 27967
|
|
||||||
DD 39551
|
|
||||||
DD 55933
|
|
||||||
DD 79101
|
|
||||||
DD 111866
|
|
||||||
DD 158203
|
|
||||||
DD 223732
|
|
||||||
DD 316405
|
|
||||||
DD 447465
|
|
||||||
DD 632811
|
|
||||||
DD 894929
|
|
||||||
DD 1265621
|
|
||||||
DD 1789859
|
|
||||||
DD 2531243
|
|
||||||
DD 3579718
|
|
||||||
DD 5062486
|
|
||||||
DD 7159436
|
|
||||||
DD 10124971
|
|
||||||
|
|
||||||
CODESEG
|
|
||||||
|
|
||||||
;***********************************************************************************************
|
|
||||||
;* Square_Root -- Finds the square root of the fixed pointer parameter. *
|
|
||||||
;* *
|
|
||||||
;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: none *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 10/04/1995 JLB : Adapted. *
|
|
||||||
;*=============================================================================================*/
|
|
||||||
;unsigned Square_Root(unsigned val);
|
|
||||||
GLOBAL C Square_Root :NEAR
|
|
||||||
PROC Square_Root C near
|
|
||||||
USES ebx,edx
|
|
||||||
|
|
||||||
bsr ebx,eax
|
|
||||||
jz ??zero
|
|
||||||
|
|
||||||
mul [DWORD 4*ebx + OFFSET TabA]
|
|
||||||
shrd eax,edx,10h
|
|
||||||
add eax, [4*ebx + OFFSET TabB]
|
|
||||||
??zero:
|
|
||||||
ret
|
|
||||||
|
|
||||||
ENDP Square_Root
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
+1508
-76
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@ class GraphicBufferClass;
|
|||||||
/* Define functions which have not under-gone name mangling */
|
/* Define functions which have not under-gone name mangling */
|
||||||
/*=========================================================================*/
|
/*=========================================================================*/
|
||||||
|
|
||||||
|
long __cdecl Buffer_To_Buffer(GraphicViewPortClass* vp, int x, int y, int w, int h, void* buffer, int length);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/*======================================================================*/
|
/*======================================================================*/
|
||||||
/* Externs for all of the common functions between the video buffer */
|
/* Externs for all of the common functions between the video buffer */
|
||||||
@@ -38,7 +40,6 @@ extern "C" {
|
|||||||
void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color);
|
void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color);
|
||||||
int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y);
|
int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y);
|
||||||
void __cdecl Buffer_Clear(void *thisptr, unsigned char color);
|
void __cdecl Buffer_Clear(void *thisptr, unsigned char color);
|
||||||
long __cdecl Buffer_To_Buffer(void *thisptr, int x, int y, int w, int h, void *buff, long size);
|
|
||||||
long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view);
|
long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view);
|
||||||
BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel,
|
BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel,
|
||||||
int dy_pixel, int pixel_width, int pixel_height, BOOL trans);
|
int dy_pixel, int pixel_width, int pixel_height, BOOL trans);
|
||||||
|
|||||||
@@ -1,288 +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: g:/library/wwlib32/misc/rcs/lcwcomp.asm 1.1 1994/04/11 15:31:10 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 routine *
|
|
||||||
;* *
|
|
||||||
;* File Name : COMPRESS.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Louis Castle *
|
|
||||||
;* *
|
|
||||||
;* Last Update : 20 August, 1990 [CY] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* *
|
|
||||||
; ULONG LCW_Compress(BYTE *source,BYTE *dest, ULONG length); *
|
|
||||||
;* *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
;IDEAL
|
|
||||||
;P386
|
|
||||||
;MODEL USE32 FLAT
|
|
||||||
|
|
||||||
.MODEL FLAT
|
|
||||||
|
|
||||||
;GLOBAL LCW_Compress :NEAR
|
|
||||||
externdef C LCW_Compress: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_Compress 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_Compress endp
|
|
||||||
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -1,294 +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: g:/library/wwlib32/misc/rcs/lcwuncmp.asm 1.1 1994/04/11 15:31:21 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 routine *
|
|
||||||
;* *
|
|
||||||
;* File Name : UNCOMP.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Christopher Yates *
|
|
||||||
;* *
|
|
||||||
;* Last Update : 20 August, 1990 [CY] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* *
|
|
||||||
; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); *
|
|
||||||
;* *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
;IDEAL
|
|
||||||
;P386
|
|
||||||
;MODEL USE32 FLAT
|
|
||||||
.MODEL FLAT
|
|
||||||
|
|
||||||
;GLOBAL C LCW_Uncompress :NEAR
|
|
||||||
externdef C LCW_Uncompress:NEAR
|
|
||||||
|
|
||||||
;CODESEG
|
|
||||||
.code
|
|
||||||
|
|
||||||
; ----------------------------------------------------------------
|
|
||||||
;
|
|
||||||
; Here are prototypes for the routines defined within this module:
|
|
||||||
;
|
|
||||||
; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length);
|
|
||||||
;
|
|
||||||
; ----------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LCW_Uncompress proc C source:DWORD, dest:DWORD, _length:DWORD
|
|
||||||
|
|
||||||
;USES ebx,ecx,edx,edi,esi
|
|
||||||
|
|
||||||
;ARG source:DWORD
|
|
||||||
;ARG dest:DWORD
|
|
||||||
;ARG length:DWORD
|
|
||||||
;LOCALS
|
|
||||||
LOCAL a1stdest:DWORD
|
|
||||||
LOCAL maxlen:DWORD
|
|
||||||
LOCAL lastbyte:DWORD
|
|
||||||
;LOCAL lastcom:DWORD
|
|
||||||
;LOCAL lastcom1:DWORD
|
|
||||||
|
|
||||||
|
|
||||||
pushad
|
|
||||||
|
|
||||||
mov edi,[dest]
|
|
||||||
mov esi,[source]
|
|
||||||
mov edx,[_length]
|
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; uncompress 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 copy copy w1 bytes from offset w2
|
|
||||||
; n=11111110,w1,b1 long run run byte b1 for w1 bytes
|
|
||||||
; n=10000000 end end of data reached
|
|
||||||
;
|
|
||||||
|
|
||||||
mov [a1stdest],edi
|
|
||||||
add edx,edi
|
|
||||||
mov [lastbyte],edx
|
|
||||||
cld ; make sure all lod and sto are forward
|
|
||||||
mov ebx,esi ; save the source offset
|
|
||||||
|
|
||||||
??loop:
|
|
||||||
mov eax,[lastbyte]
|
|
||||||
sub eax,edi ; get the remaining byte to uncomp
|
|
||||||
jz short ??out ; were done
|
|
||||||
|
|
||||||
mov [maxlen],eax ; save for string commands
|
|
||||||
mov esi,ebx ; mov in the source index
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
mov al,[esi]
|
|
||||||
inc esi
|
|
||||||
test al,al ; see if its a short run
|
|
||||||
js short ??notshort
|
|
||||||
|
|
||||||
mov ecx,eax ;put count nibble in cl
|
|
||||||
|
|
||||||
mov ah,al ; put rel offset high nibble in ah
|
|
||||||
and ah,0Fh ; only 4 bits count
|
|
||||||
|
|
||||||
shr cl,4 ; get run -3
|
|
||||||
add ecx,3 ; get actual run length
|
|
||||||
|
|
||||||
cmp ecx,[maxlen] ; is it too big to fit?
|
|
||||||
jbe short ??rsok ; if not, its ok
|
|
||||||
|
|
||||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
|
||||||
|
|
||||||
??rsok:
|
|
||||||
mov al,[esi] ; get rel offset low byte
|
|
||||||
lea ebx,[esi+1] ; save the source offset
|
|
||||||
mov esi,edi ; get the current dest
|
|
||||||
sub esi,eax ; get relative offset
|
|
||||||
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
??notshort:
|
|
||||||
test al,40h ; is it a length?
|
|
||||||
jne short ??notlength ; if not it could be med or long run
|
|
||||||
|
|
||||||
cmp al,80h ; is it the end?
|
|
||||||
je short ??out ; if so its over
|
|
||||||
|
|
||||||
mov cl,al ; put the byte in count register
|
|
||||||
and ecx,3Fh ; and off the extra bits
|
|
||||||
|
|
||||||
cmp ecx,[maxlen] ; is it too big to fit?
|
|
||||||
jbe short ??lenok ; if not, its ok
|
|
||||||
|
|
||||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
|
||||||
|
|
||||||
??lenok:
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
mov ebx,esi ; save the source offset
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
??out:
|
|
||||||
mov eax,edi
|
|
||||||
sub eax,[a1stdest]
|
|
||||||
jmp ??exit
|
|
||||||
|
|
||||||
??notlength:
|
|
||||||
mov cl,al ; get the entire code
|
|
||||||
and ecx,3Fh ; and off all but the size -3
|
|
||||||
add ecx,3 ; add 3 for byte count
|
|
||||||
|
|
||||||
cmp al,0FEh
|
|
||||||
jne short ??notrunlength
|
|
||||||
|
|
||||||
xor ecx,ecx
|
|
||||||
mov cx,[esi]
|
|
||||||
|
|
||||||
xor eax,eax
|
|
||||||
mov al,[esi+2]
|
|
||||||
lea ebx,[esi+3] ;save the source offset
|
|
||||||
|
|
||||||
cmp ecx,[maxlen] ; is it too big to fit?
|
|
||||||
jbe short ??runlenok ; if not, its ok
|
|
||||||
|
|
||||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
|
||||||
|
|
||||||
??runlenok:
|
|
||||||
test ecx,0ffe0h
|
|
||||||
jnz ??dont_use_stosb
|
|
||||||
rep stosb
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
|
|
||||||
??dont_use_stosb:
|
|
||||||
mov ah,al
|
|
||||||
mov edx,eax
|
|
||||||
shl eax,16
|
|
||||||
or eax,edx
|
|
||||||
|
|
||||||
test edi,3
|
|
||||||
jz ??aligned
|
|
||||||
|
|
||||||
mov [edi],eax
|
|
||||||
mov edx,edi
|
|
||||||
and edi,0fffffffch
|
|
||||||
lea edi,[edi+4]
|
|
||||||
and edx,3
|
|
||||||
dec dl
|
|
||||||
xor dl,3
|
|
||||||
sub ecx,edx
|
|
||||||
|
|
||||||
??aligned:
|
|
||||||
mov edx,ecx
|
|
||||||
shr ecx,2
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
and edx,3
|
|
||||||
jz ??loop
|
|
||||||
mov ecx,edx
|
|
||||||
rep stosb
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
??notrunlength:
|
|
||||||
cmp al,0FFh ; is it a long run?
|
|
||||||
jne short ??notlong ; if not use the code as the size
|
|
||||||
|
|
||||||
xor ecx,ecx
|
|
||||||
xor eax,eax
|
|
||||||
mov cx,[esi] ; if so, get the size
|
|
||||||
lea esi,[esi+2]
|
|
||||||
|
|
||||||
??notlong:
|
|
||||||
mov ax,[esi] ;get the real index
|
|
||||||
add eax,[a1stdest] ;add in the 1st index
|
|
||||||
lea ebx,[esi+2] ;save the source offset
|
|
||||||
cmp ecx,[maxlen] ;compare for overrun
|
|
||||||
mov esi,eax ;use eax as new source
|
|
||||||
jbe short ??runok ; if not, its ok
|
|
||||||
|
|
||||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
|
||||||
|
|
||||||
??runok:
|
|
||||||
test ecx,0ffe0h
|
|
||||||
jnz ??dont_use_movsb
|
|
||||||
rep movsb
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
??dont_use_movsb:
|
|
||||||
lea edx,[edi+0fffffffch]
|
|
||||||
cmp esi,edx
|
|
||||||
ja ??use_movsb
|
|
||||||
|
|
||||||
test edi,3
|
|
||||||
jz ??aligned2
|
|
||||||
|
|
||||||
mov eax,[esi]
|
|
||||||
mov [edi],eax
|
|
||||||
mov edx,edi
|
|
||||||
and edi,0fffffffch
|
|
||||||
lea edi,[edi+4]
|
|
||||||
and edx,3
|
|
||||||
dec dl
|
|
||||||
xor dl,3
|
|
||||||
sub ecx,edx
|
|
||||||
add esi,edx
|
|
||||||
|
|
||||||
??aligned2:
|
|
||||||
mov edx,ecx
|
|
||||||
shr ecx,2
|
|
||||||
and edx,3
|
|
||||||
rep movsd
|
|
||||||
mov ecx,edx
|
|
||||||
??use_movsb:
|
|
||||||
rep movsb
|
|
||||||
jmp ??loop
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
??exit:
|
|
||||||
mov eax,edi
|
|
||||||
mov ebx,[dest]
|
|
||||||
sub eax,ebx
|
|
||||||
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
LCW_Uncompress endp
|
|
||||||
|
|
||||||
;***********************************************************
|
|
||||||
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -1,294 +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]>.
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;** 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 32 bit Library *
|
|
||||||
;* *
|
|
||||||
;* File Name : TOBUFFER.ASM *
|
|
||||||
;* *
|
|
||||||
;* Programmer : Phil W. Gorrow *
|
|
||||||
;* *
|
|
||||||
;* Start Date : June 8, 1994 *
|
|
||||||
;* Last Update : Feb 10, 1995 [jrj] *
|
|
||||||
;* *
|
|
||||||
;*-------------------------------------------------------------------------*
|
|
||||||
;* Functions: *
|
|
||||||
;* VVC::TOBUFFER -- Copies a virtual viewport to a linear buffer *
|
|
||||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|
||||||
|
|
||||||
;IDEAL
|
|
||||||
;P386
|
|
||||||
;MODEL USE32 FLAT
|
|
||||||
;LOCALS ??
|
|
||||||
.model flat
|
|
||||||
|
|
||||||
|
|
||||||
TRANSP equ 0
|
|
||||||
|
|
||||||
|
|
||||||
;INCLUDE "drawbuff.inc"
|
|
||||||
INCLUDE gbuffer.inc
|
|
||||||
|
|
||||||
|
|
||||||
;CODESEG
|
|
||||||
.code
|
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
|
||||||
;* VIVC::TOBUFFER -- Copies a virtual viewport to a linear buffer *
|
|
||||||
;* *
|
|
||||||
;* INPUT: BYTE * dest - buffer to copy to *
|
|
||||||
;* size - size of the buffer to copy to *
|
|
||||||
;* x_pixel - x pixel on viewport to copy from *
|
|
||||||
;* y_pixel - y pixel on viewport to copy from *
|
|
||||||
;* pixel_width - the width of copy region *
|
|
||||||
;* pixel_height - the height of copy region *
|
|
||||||
;* *
|
|
||||||
;* OUTPUT: none *
|
|
||||||
;* *
|
|
||||||
;* WARNINGS: Coordinates and dimensions will be adjusted if they exceed *
|
|
||||||
;* the boundaries. In the event that no adjustment is *
|
|
||||||
;* possible this routine will abort. If the size of the *
|
|
||||||
;* region to copy exceeds the size passed in for the buffer *
|
|
||||||
;* the routine will automatically abort. *
|
|
||||||
;* *
|
|
||||||
;* HISTORY: *
|
|
||||||
;* 06/15/1994 PWG : Created. *
|
|
||||||
;*=========================================================================*
|
|
||||||
Buffer_To_Buffer proc C public USES ebx ecx edx esi edi this_object:DWORD, x_pixel:DWORD, y_pixel:DWORD, pixel_width:DWORD, pixel_height:DWORD, dest:DWORD, buffer_size:DWORD
|
|
||||||
|
|
||||||
;PROC Buffer_To_Buffer C near
|
|
||||||
;USES ebx,ecx,edx,esi,edi
|
|
||||||
|
|
||||||
;*===================================================================
|
|
||||||
;* define the arguements that our function takes.
|
|
||||||
;*===================================================================
|
|
||||||
;ARG this_object:DWORD ; this is a class member function
|
|
||||||
;ARG x_pixel:DWORD ; Page X pixel coordinate.
|
|
||||||
;ARG y_pixel:DWORD ; Page Y pixel coordinate.
|
|
||||||
;ARG pixel_width:DWORD ; Width of region in pixels.
|
|
||||||
;ARG pixel_height:DWORD ; Height of region in pixels.
|
|
||||||
;ARG dest:DWORD ; the buffer to copy to
|
|
||||||
;ARG buffer_size:DWORD ; the size of the buffer
|
|
||||||
|
|
||||||
;*===================================================================
|
|
||||||
; Define some locals so that we can handle things quickly
|
|
||||||
;*===================================================================
|
|
||||||
LOCAL x1_pixel :dword
|
|
||||||
LOCAL y1_pixel :dword
|
|
||||||
LOCAL dest_x1 : dword
|
|
||||||
LOCAL dest_y1 : dword
|
|
||||||
LOCAL dest_ajust_width:DWORD
|
|
||||||
LOCAL scr_ajust_width:DWORD
|
|
||||||
;LOCAL dest_area : dword
|
|
||||||
|
|
||||||
; Clip dest Rectangle against source Window boundaries.
|
|
||||||
|
|
||||||
mov [ dest_x1 ] , 0
|
|
||||||
mov [ dest_y1 ] , 0
|
|
||||||
|
|
||||||
mov esi , [ this_object ] ; get ptr to dest
|
|
||||||
xor ecx , ecx
|
|
||||||
xor edx , edx
|
|
||||||
mov edi , [esi].GraphicViewPort.GVPWidth ; get width into register
|
|
||||||
mov ebx , [ x_pixel ]
|
|
||||||
mov eax , [ x_pixel ]
|
|
||||||
add ebx , [ pixel_width ]
|
|
||||||
shld ecx , eax , 1
|
|
||||||
mov [ x1_pixel ] , ebx
|
|
||||||
inc edi
|
|
||||||
shld edx , ebx , 1
|
|
||||||
sub eax , edi
|
|
||||||
sub ebx , edi
|
|
||||||
shld ecx , eax , 1
|
|
||||||
shld edx , ebx , 1
|
|
||||||
|
|
||||||
mov edi,[esi].GraphicViewPort.GVPHeight ; get height into register
|
|
||||||
mov ebx , [ y_pixel ]
|
|
||||||
mov eax , [ y_pixel ]
|
|
||||||
add ebx , [ pixel_height ]
|
|
||||||
shld ecx , eax , 1
|
|
||||||
mov [ y1_pixel ] , ebx
|
|
||||||
inc edi
|
|
||||||
shld edx , ebx , 1
|
|
||||||
sub eax , edi
|
|
||||||
sub ebx , edi
|
|
||||||
shld ecx , eax , 1
|
|
||||||
shld edx , ebx , 1
|
|
||||||
|
|
||||||
xor cl , 5
|
|
||||||
xor dl , 5
|
|
||||||
mov al , cl
|
|
||||||
test dl , cl
|
|
||||||
jnz real_out
|
|
||||||
or al , dl
|
|
||||||
jz do_blit
|
|
||||||
|
|
||||||
test cl , 1000b
|
|
||||||
jz scr_left_ok
|
|
||||||
mov eax , [ x_pixel ]
|
|
||||||
neg eax
|
|
||||||
mov [ x_pixel ] , 0
|
|
||||||
mov [ dest_x1 ] , eax
|
|
||||||
|
|
||||||
scr_left_ok:
|
|
||||||
test cl , 0010b
|
|
||||||
jz scr_bottom_ok
|
|
||||||
mov eax , [ y_pixel ]
|
|
||||||
neg eax
|
|
||||||
mov [ y_pixel ] , 0
|
|
||||||
mov [ dest_y1 ] , eax
|
|
||||||
|
|
||||||
scr_bottom_ok:
|
|
||||||
test dl , 0100b
|
|
||||||
jz scr_right_ok
|
|
||||||
mov eax , [esi].GraphicViewPort.GVPWidth ; get width into register
|
|
||||||
mov [ x1_pixel ] , eax
|
|
||||||
scr_right_ok:
|
|
||||||
test dl , 0001b
|
|
||||||
jz do_blit
|
|
||||||
mov eax , [esi].GraphicViewPort.GVPHeight ; get width into register
|
|
||||||
mov [ y1_pixel ] , eax
|
|
||||||
|
|
||||||
do_blit:
|
|
||||||
|
|
||||||
cld
|
|
||||||
|
|
||||||
mov eax , [esi].GraphicViewPort.GVPXAdd
|
|
||||||
add eax , [esi].GraphicViewPort.GVPWidth
|
|
||||||
add eax , [esi].GraphicViewPort.GVPPitch
|
|
||||||
mov esi , [esi].GraphicViewPort.GVPOffset
|
|
||||||
|
|
||||||
mov ecx , eax
|
|
||||||
mul [ y_pixel ]
|
|
||||||
add esi , [ x_pixel ]
|
|
||||||
add esi , eax
|
|
||||||
|
|
||||||
add ecx , [ x_pixel ]
|
|
||||||
sub ecx , [ x1_pixel ]
|
|
||||||
mov [ scr_ajust_width ] , ecx
|
|
||||||
|
|
||||||
mov edi , [ dest ]
|
|
||||||
mov eax , [ pixel_width ]
|
|
||||||
sub eax , [ x1_pixel ]
|
|
||||||
add eax , [ x_pixel ]
|
|
||||||
mov [ dest_ajust_width ] , eax
|
|
||||||
|
|
||||||
mov eax , [ dest_y1 ]
|
|
||||||
mul [ pixel_width ]
|
|
||||||
add eax , [ dest_x1 ]
|
|
||||||
add edi , eax
|
|
||||||
|
|
||||||
mov edx , [ y1_pixel ]
|
|
||||||
mov eax , [ x1_pixel ]
|
|
||||||
sub edx , [ y_pixel ]
|
|
||||||
jle real_out
|
|
||||||
sub eax , [ x_pixel ]
|
|
||||||
jle real_out
|
|
||||||
|
|
||||||
mov ebx , [ pixel_width ]
|
|
||||||
imul ebx , edx
|
|
||||||
cmp ebx , [ buffer_size ]
|
|
||||||
jg real_out
|
|
||||||
|
|
||||||
|
|
||||||
; ********************************************************************
|
|
||||||
; Forward bitblit only
|
|
||||||
|
|
||||||
IF TRANSP
|
|
||||||
cmp [ transp ] , 0
|
|
||||||
jnz forward_Blit_trans
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
; the inner loop is so efficient that
|
|
||||||
; the optimal consept no longer apply because
|
|
||||||
; the optimal byte have to by a number greather than 9 bytes
|
|
||||||
cmp eax , 10
|
|
||||||
jl forward_loop_bytes
|
|
||||||
|
|
||||||
forward_loop_dword:
|
|
||||||
mov ecx , edi
|
|
||||||
mov ebx , eax
|
|
||||||
neg ecx
|
|
||||||
and ecx , 3
|
|
||||||
sub ebx , ecx
|
|
||||||
rep movsb
|
|
||||||
mov ecx , ebx
|
|
||||||
shr ecx , 2
|
|
||||||
rep movsd
|
|
||||||
mov ecx , ebx
|
|
||||||
and ecx , 3
|
|
||||||
rep movsb
|
|
||||||
add esi , [ scr_ajust_width ]
|
|
||||||
add edi , [ dest_ajust_width ]
|
|
||||||
dec edx
|
|
||||||
jnz forward_loop_dword
|
|
||||||
ret
|
|
||||||
|
|
||||||
forward_loop_bytes:
|
|
||||||
mov ecx , eax
|
|
||||||
rep movsb
|
|
||||||
add esi , [ scr_ajust_width ]
|
|
||||||
add edi , [ dest_ajust_width ]
|
|
||||||
dec edx ; decrement the height
|
|
||||||
jnz forward_loop_bytes
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
IF TRANSP
|
|
||||||
|
|
||||||
forward_Blit_trans:
|
|
||||||
mov ecx , eax
|
|
||||||
and ecx , 01fh
|
|
||||||
lea ecx , [ ecx + ecx * 4 ]
|
|
||||||
neg ecx
|
|
||||||
shr eax , 5
|
|
||||||
lea ecx , [ transp_reference + ecx * 2 ]
|
|
||||||
mov [ y1_pixel ] , ecx
|
|
||||||
|
|
||||||
forward_loop_trans:
|
|
||||||
mov ecx , eax
|
|
||||||
jmp [ y1_pixel ]
|
|
||||||
forward_trans_line:
|
|
||||||
REPT 32
|
|
||||||
local transp_pixel
|
|
||||||
mov bl , [ esi ]
|
|
||||||
test bl , bl
|
|
||||||
jz transp_pixel
|
|
||||||
mov [ edi ] , bl
|
|
||||||
transp_pixel:
|
|
||||||
inc esi
|
|
||||||
inc edi
|
|
||||||
ENDM
|
|
||||||
transp_reference:
|
|
||||||
dec ecx
|
|
||||||
jge forward_trans_line
|
|
||||||
add esi , [ scr_ajust_width ]
|
|
||||||
add edi , [ dest_ajust_width ]
|
|
||||||
dec edx
|
|
||||||
jnz forward_loop_trans
|
|
||||||
ret
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
real_out:
|
|
||||||
ret
|
|
||||||
|
|
||||||
;ENDP Buffer_To_Buffer
|
|
||||||
Buffer_To_Buffer endp
|
|
||||||
|
|
||||||
END
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author CCHyper
|
||||||
|
* @author OmniBlade
|
||||||
|
*
|
||||||
|
* @brief Low level software blitters.
|
||||||
|
*
|
||||||
|
* @copyright Chronoshift 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
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
* A full copy of the GNU General Public License can be found in
|
||||||
|
* LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "gbuffer.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
long __cdecl Buffer_To_Buffer(GraphicViewPortClass* vp, int x, int y, int w, int h, void* buffer, int length)
|
||||||
|
{
|
||||||
|
int xstart = x;
|
||||||
|
int ystart = y;
|
||||||
|
int xend = x + w - 1;
|
||||||
|
int yend = y + h - 1;
|
||||||
|
|
||||||
|
int xoffset = 0;
|
||||||
|
int yoffset = 0;
|
||||||
|
|
||||||
|
// If we aren't drawing within the viewport, return
|
||||||
|
if (!buffer || length <= 0 || xstart >= vp->Get_Width() || ystart >= vp->Get_Height() || xend < 0 || yend < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clipping
|
||||||
|
if (xstart < 0) {
|
||||||
|
xoffset = -xstart;
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ystart < 0) {
|
||||||
|
yoffset += h * (-ystart);
|
||||||
|
ystart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xend = min(xend, (int)vp->Get_Width() - 1);
|
||||||
|
yend = min(yend, (int)vp->Get_Height() - 1);
|
||||||
|
|
||||||
|
// Setup parameters for blit
|
||||||
|
int pitch = vp->Get_Pitch() + vp->Get_Width() + vp->Get_XAdd();
|
||||||
|
uint8_t* src = y * pitch + x + (uint8_t*)(vp->Get_Offset());
|
||||||
|
uint8_t* dst = xoffset + w * yoffset + (uint8_t*)(buffer);
|
||||||
|
// int src_pitch = x_pos + pitch - xend + 1;
|
||||||
|
// int dst_pitch = x_pos + width - xend + 1;
|
||||||
|
int lines = yend - ystart + 1;
|
||||||
|
int blit_width = xend - xstart + 1;
|
||||||
|
|
||||||
|
// Is our buffer large enough?
|
||||||
|
if (lines * w <= length) {
|
||||||
|
// blit
|
||||||
|
while (lines--) {
|
||||||
|
memcpy(dst, src, blit_width);
|
||||||
|
src += pitch;
|
||||||
|
dst += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user