mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-18 09:04:12 +02:00
ASM files removed, functions replaced with bits from Chronoshift.
This commit is contained in:
+317
-317
@@ -96,59 +96,59 @@ typedef struct tShapeHeaderType{
|
||||
|
||||
static int Length;
|
||||
|
||||
void *Get_Shape_Header_Data(void *ptr)
|
||||
{
|
||||
if (UseBigShapeBuffer) {
|
||||
|
||||
ShapeHeaderType *header = (ShapeHeaderType*) ptr;
|
||||
return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
|
||||
|
||||
} else {
|
||||
return (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
int Get_Last_Frame_Length(void)
|
||||
{
|
||||
return(Length);
|
||||
}
|
||||
//void *Get_Shape_Header_Data(void *ptr)
|
||||
//{
|
||||
// if (UseBigShapeBuffer) {
|
||||
//
|
||||
// ShapeHeaderType *header = (ShapeHeaderType*) ptr;
|
||||
// return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
|
||||
//
|
||||
// } else {
|
||||
// return (ptr);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//int Get_Last_Frame_Length(void)
|
||||
//{
|
||||
// return(Length);
|
||||
//}
|
||||
|
||||
|
||||
void Reset_Theater_Shapes (void)
|
||||
{
|
||||
/*
|
||||
** Delete any previously allocated slots
|
||||
*/
|
||||
for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
|
||||
delete [] KeyFrameSlots [i];
|
||||
}
|
||||
|
||||
TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||
TotalTheaterShapes = 0;
|
||||
TheaterSlotsUsed = THEATER_SLOT_START;
|
||||
}
|
||||
//void Reset_Theater_Shapes (void)
|
||||
//{
|
||||
// /*
|
||||
// ** Delete any previously allocated slots
|
||||
// */
|
||||
// for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
|
||||
// delete [] KeyFrameSlots [i];
|
||||
// }
|
||||
//
|
||||
// TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||
// TotalTheaterShapes = 0;
|
||||
// TheaterSlotsUsed = THEATER_SLOT_START;
|
||||
//}
|
||||
|
||||
|
||||
void Reallocate_Big_Shape_Buffer(void)
|
||||
{
|
||||
if (ReallocShapeBufferFlag) {
|
||||
BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
|
||||
BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
|
||||
Memory_Error = NULL;
|
||||
BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
|
||||
Memory_Error = &Memory_Error_Handler;
|
||||
/*
|
||||
** If we have run out of memory then disable the uncompressed shapes
|
||||
** It may still be possible to continue with compressed shapes
|
||||
*/
|
||||
if (!BigShapeBufferStart) {
|
||||
UseBigShapeBuffer = false;
|
||||
return;
|
||||
}
|
||||
BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
|
||||
ReallocShapeBufferFlag = FALSE;
|
||||
}
|
||||
}
|
||||
//void Reallocate_Big_Shape_Buffer(void)
|
||||
//{
|
||||
// if (ReallocShapeBufferFlag) {
|
||||
// BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
|
||||
// BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
|
||||
// Memory_Error = NULL;
|
||||
// BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
|
||||
// Memory_Error = &Memory_Error_Handler;
|
||||
// /*
|
||||
// ** If we have run out of memory then disable the uncompressed shapes
|
||||
// ** It may still be possible to continue with compressed shapes
|
||||
// */
|
||||
// if (!BigShapeBufferStart) {
|
||||
// UseBigShapeBuffer = false;
|
||||
// return;
|
||||
// }
|
||||
// BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
|
||||
// ReallocShapeBufferFlag = FALSE;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//#ifdef FIXIT_SCORE_CRASH
|
||||
@@ -166,10 +166,10 @@ void Reallocate_Big_Shape_Buffer(void)
|
||||
* HISTORY: *
|
||||
* 11/19/96 2:37PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Disable_Uncompressed_Shapes (void)
|
||||
{
|
||||
UseBigShapeBuffer = false;
|
||||
}
|
||||
//void Disable_Uncompressed_Shapes (void)
|
||||
//{
|
||||
// UseBigShapeBuffer = false;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@@ -187,10 +187,10 @@ void Disable_Uncompressed_Shapes (void)
|
||||
* HISTORY: *
|
||||
* 11/19/96 2:37PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Enable_Uncompressed_Shapes (void)
|
||||
{
|
||||
UseBigShapeBuffer = OriginalUseBigShapeBuffer;
|
||||
}
|
||||
//void Enable_Uncompressed_Shapes (void)
|
||||
//{
|
||||
// UseBigShapeBuffer = OriginalUseBigShapeBuffer;
|
||||
//}
|
||||
//#endif //FIXIT
|
||||
|
||||
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)
|
||||
{
|
||||
#ifdef FIXIT_SCORE_CRASH
|
||||
char *ptr;
|
||||
unsigned long offcurr, offdiff;
|
||||
#else
|
||||
char *ptr, *lockptr;//, *uncomp_ptr;
|
||||
unsigned long offcurr, off16, offdiff;
|
||||
#endif
|
||||
unsigned long offset[SUBFRAMEOFFS];
|
||||
KeyFrameHeaderType *keyfr;
|
||||
unsigned short buffsize, currframe, subframe;
|
||||
unsigned long length = 0;
|
||||
char frameflags;
|
||||
unsigned long return_value;
|
||||
char *temp_shape_ptr;
|
||||
|
||||
//
|
||||
// valid pointer??
|
||||
//
|
||||
Length = 0;
|
||||
if ( !dataptr || !buffptr ) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
//
|
||||
// look at header then check that frame to build is not greater
|
||||
// than total frames
|
||||
//
|
||||
keyfr = (KeyFrameHeaderType *) dataptr;
|
||||
|
||||
if ( framenumber >= keyfr->frames ) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
if (UseBigShapeBuffer) {
|
||||
/*
|
||||
** If we havnt yet allocated memory for uncompressed shapes then do so now.
|
||||
**
|
||||
*/
|
||||
if (!BigShapeBufferStart) {
|
||||
BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
|
||||
BigShapeBufferPtr = BigShapeBufferStart;
|
||||
|
||||
/*
|
||||
** Allocate memory for theater specific uncompressed shapes
|
||||
*/
|
||||
TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
|
||||
TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||
}
|
||||
|
||||
/*
|
||||
** If we are running out of memory (<10k left) for uncompressed shapes
|
||||
** then allocate some more.
|
||||
*/
|
||||
if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
|
||||
ReallocShapeBufferFlag = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
** If this animation was not previously uncompressed then
|
||||
** allocate memory to keep the pointers to the uncompressed data
|
||||
** for these animation frames
|
||||
*/
|
||||
if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
|
||||
keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
|
||||
if (IsTheaterShape) {
|
||||
keyfr->y = TheaterSlotsUsed;
|
||||
TheaterSlotsUsed++;
|
||||
} else {
|
||||
keyfr->y = TotalSlotsUsed;
|
||||
TotalSlotsUsed++;
|
||||
}
|
||||
/*
|
||||
** Allocate and clear the memory for the shape info
|
||||
*/
|
||||
KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
|
||||
memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
|
||||
}
|
||||
|
||||
/*
|
||||
** If this frame was previously uncompressed then just return
|
||||
** a pointer to the raw data
|
||||
*/
|
||||
if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
|
||||
if (IsTheaterShape) {
|
||||
return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||
} else {
|
||||
return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calc buff size
|
||||
buffsize = keyfr->width * keyfr->height;
|
||||
|
||||
// get offset into data
|
||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
|
||||
Mem_Copy( ptr, &offset[0], 12L );
|
||||
frameflags = (char)(offset[0] >> 24);
|
||||
|
||||
|
||||
if ( (frameflags & KF_KEYFRAME) ) {
|
||||
|
||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
|
||||
|
||||
if (keyfr->flags & 1 ) {
|
||||
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||
}
|
||||
length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||
} else { // key delta or delta
|
||||
|
||||
if ( (frameflags & KF_DELTA) ) {
|
||||
currframe = (unsigned short)offset[1];
|
||||
|
||||
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
|
||||
Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||
}
|
||||
|
||||
// key frame
|
||||
offcurr = offset[1] & 0x00FFFFFFL;
|
||||
|
||||
// key delta
|
||||
offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
|
||||
|
||||
ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
|
||||
|
||||
if (keyfr->flags & 1 ) {
|
||||
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||
}
|
||||
|
||||
#ifndef FIXIT_SCORE_CRASH
|
||||
off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||
#endif
|
||||
|
||||
length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||
|
||||
if (length > buffsize) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifndef FIXIT_SCORE_CRASH
|
||||
if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||
|
||||
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||
off16 = (unsigned long)ptr & 0x00003FFFL;
|
||||
|
||||
offcurr += offdiff;
|
||||
offdiff = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
length = buffsize;
|
||||
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||
|
||||
if ( (frameflags & KF_DELTA) ) {
|
||||
// adjust to delta after the keydelta
|
||||
|
||||
currframe++;
|
||||
subframe = 2;
|
||||
|
||||
while (currframe <= framenumber) {
|
||||
offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
|
||||
|
||||
#ifndef FIXIT_SCORE_CRASH
|
||||
if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||
|
||||
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||
off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||
|
||||
offcurr += offdiff;
|
||||
offdiff = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
length = buffsize;
|
||||
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||
|
||||
currframe++;
|
||||
subframe += 2;
|
||||
|
||||
if ( subframe >= (SUBFRAMEOFFS - 1) &&
|
||||
currframe <= framenumber ) {
|
||||
Mem_Copy( Add_Long_To_Pointer( dataptr,
|
||||
(((unsigned long)currframe << 3) +
|
||||
sizeof(KeyFrameHeaderType)) ),
|
||||
&offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||
subframe = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (UseBigShapeBuffer) {
|
||||
/*
|
||||
** Save the uncompressed shape data so we dont have to uncompress it
|
||||
** again next time its drawn.
|
||||
** 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
|
||||
*/
|
||||
|
||||
if (IsTheaterShape) {
|
||||
/*
|
||||
** Shape is a theater specific shape
|
||||
*/
|
||||
return_value = (unsigned long) TheaterShapeBufferPtr;
|
||||
temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||
/*
|
||||
** align the actual shape data
|
||||
*/
|
||||
if (3 & (unsigned)temp_shape_ptr) {
|
||||
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||
}
|
||||
|
||||
memcpy (temp_shape_ptr , buffptr , length);
|
||||
((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_buffer = 1; //Theater buffer
|
||||
*(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
|
||||
TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||
/*
|
||||
** Align the next shape
|
||||
*/
|
||||
if (3 & (unsigned)TheaterShapeBufferPtr) {
|
||||
TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
|
||||
}
|
||||
Length = length;
|
||||
return (return_value);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
return_value=(unsigned long)BigShapeBufferPtr;
|
||||
temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||
/*
|
||||
** align the actual shape data
|
||||
*/
|
||||
if (3 & (unsigned)temp_shape_ptr) {
|
||||
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||
}
|
||||
memcpy (temp_shape_ptr , buffptr , length);
|
||||
((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_buffer = 0; //Normal Big Shape Buffer
|
||||
*(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
|
||||
BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||
// Align the next shape
|
||||
if (3 & (unsigned)BigShapeBufferPtr) {
|
||||
BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
|
||||
}
|
||||
Length = length;
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
} else {
|
||||
return ((unsigned long)buffptr);
|
||||
}
|
||||
}
|
||||
//unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr)
|
||||
//{
|
||||
//#ifdef FIXIT_SCORE_CRASH
|
||||
// char *ptr;
|
||||
// unsigned long offcurr, offdiff;
|
||||
//#else
|
||||
// char *ptr, *lockptr;//, *uncomp_ptr;
|
||||
// unsigned long offcurr, off16, offdiff;
|
||||
//#endif
|
||||
// unsigned long offset[SUBFRAMEOFFS];
|
||||
// KeyFrameHeaderType *keyfr;
|
||||
// unsigned short buffsize, currframe, subframe;
|
||||
// unsigned long length = 0;
|
||||
// char frameflags;
|
||||
// unsigned long return_value;
|
||||
// char *temp_shape_ptr;
|
||||
//
|
||||
// //
|
||||
// // valid pointer??
|
||||
// //
|
||||
// Length = 0;
|
||||
// if ( !dataptr || !buffptr ) {
|
||||
// return(0);
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// // look at header then check that frame to build is not greater
|
||||
// // than total frames
|
||||
// //
|
||||
// keyfr = (KeyFrameHeaderType *) dataptr;
|
||||
//
|
||||
// if ( framenumber >= keyfr->frames ) {
|
||||
// return(0);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (UseBigShapeBuffer) {
|
||||
// /*
|
||||
// ** If we havnt yet allocated memory for uncompressed shapes then do so now.
|
||||
// **
|
||||
// */
|
||||
// if (!BigShapeBufferStart) {
|
||||
// BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
|
||||
// BigShapeBufferPtr = BigShapeBufferStart;
|
||||
//
|
||||
// /*
|
||||
// ** Allocate memory for theater specific uncompressed shapes
|
||||
// */
|
||||
// TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
|
||||
// TheaterShapeBufferPtr = TheaterShapeBufferStart;
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// ** If we are running out of memory (<10k left) for uncompressed shapes
|
||||
// ** then allocate some more.
|
||||
// */
|
||||
// if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
|
||||
// ReallocShapeBufferFlag = TRUE;
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// ** If this animation was not previously uncompressed then
|
||||
// ** allocate memory to keep the pointers to the uncompressed data
|
||||
// ** for these animation frames
|
||||
// */
|
||||
// if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
|
||||
// keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
|
||||
// if (IsTheaterShape) {
|
||||
// keyfr->y = TheaterSlotsUsed;
|
||||
// TheaterSlotsUsed++;
|
||||
// } else {
|
||||
// keyfr->y = TotalSlotsUsed;
|
||||
// TotalSlotsUsed++;
|
||||
// }
|
||||
// /*
|
||||
// ** Allocate and clear the memory for the shape info
|
||||
// */
|
||||
// KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
|
||||
// memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// ** If this frame was previously uncompressed then just return
|
||||
// ** a pointer to the raw data
|
||||
// */
|
||||
// if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
|
||||
// if (IsTheaterShape) {
|
||||
// return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||
// } else {
|
||||
// return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // calc buff size
|
||||
// buffsize = keyfr->width * keyfr->height;
|
||||
//
|
||||
// // get offset into data
|
||||
// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
|
||||
// Mem_Copy( ptr, &offset[0], 12L );
|
||||
// frameflags = (char)(offset[0] >> 24);
|
||||
//
|
||||
//
|
||||
// if ( (frameflags & KF_KEYFRAME) ) {
|
||||
//
|
||||
// ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
|
||||
//
|
||||
// if (keyfr->flags & 1 ) {
|
||||
// ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||
// }
|
||||
// length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||
// } else { // key delta or delta
|
||||
//
|
||||
// if ( (frameflags & KF_DELTA) ) {
|
||||
// currframe = (unsigned short)offset[1];
|
||||
//
|
||||
// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
|
||||
// Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||
// }
|
||||
//
|
||||
// // key frame
|
||||
// offcurr = offset[1] & 0x00FFFFFFL;
|
||||
//
|
||||
// // key delta
|
||||
// offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
|
||||
//
|
||||
// ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
|
||||
//
|
||||
// if (keyfr->flags & 1 ) {
|
||||
// ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
|
||||
// }
|
||||
//
|
||||
//#ifndef FIXIT_SCORE_CRASH
|
||||
// off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||
//#endif
|
||||
//
|
||||
// length = LCW_Uncompress( ptr, buffptr, buffsize );
|
||||
//
|
||||
// if (length > buffsize) {
|
||||
// return(0);
|
||||
// }
|
||||
//
|
||||
//#ifndef FIXIT_SCORE_CRASH
|
||||
// if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||
//
|
||||
// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||
// off16 = (unsigned long)ptr & 0x00003FFFL;
|
||||
//
|
||||
// offcurr += offdiff;
|
||||
// offdiff = 0;
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
// length = buffsize;
|
||||
// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||
//
|
||||
// if ( (frameflags & KF_DELTA) ) {
|
||||
// // adjust to delta after the keydelta
|
||||
//
|
||||
// currframe++;
|
||||
// subframe = 2;
|
||||
//
|
||||
// while (currframe <= framenumber) {
|
||||
// offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
|
||||
//
|
||||
//#ifndef FIXIT_SCORE_CRASH
|
||||
// if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
|
||||
//
|
||||
// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
|
||||
// off16 = (unsigned long)lockptr & 0x00003FFFL;
|
||||
//
|
||||
// offcurr += offdiff;
|
||||
// offdiff = 0;
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
// length = buffsize;
|
||||
// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
|
||||
//
|
||||
// currframe++;
|
||||
// subframe += 2;
|
||||
//
|
||||
// if ( subframe >= (SUBFRAMEOFFS - 1) &&
|
||||
// currframe <= framenumber ) {
|
||||
// Mem_Copy( Add_Long_To_Pointer( dataptr,
|
||||
// (((unsigned long)currframe << 3) +
|
||||
// sizeof(KeyFrameHeaderType)) ),
|
||||
// &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
|
||||
// subframe = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (UseBigShapeBuffer) {
|
||||
// /*
|
||||
// ** Save the uncompressed shape data so we dont have to uncompress it
|
||||
// ** again next time its drawn.
|
||||
// ** 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
|
||||
// */
|
||||
//
|
||||
// if (IsTheaterShape) {
|
||||
// /*
|
||||
// ** Shape is a theater specific shape
|
||||
// */
|
||||
// return_value = (unsigned long) TheaterShapeBufferPtr;
|
||||
// temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||
// /*
|
||||
// ** align the actual shape data
|
||||
// */
|
||||
// if (3 & (unsigned)temp_shape_ptr) {
|
||||
// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||
// }
|
||||
//
|
||||
// memcpy (temp_shape_ptr , buffptr , length);
|
||||
// ((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_buffer = 1; //Theater buffer
|
||||
// *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
|
||||
// TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||
// /*
|
||||
// ** Align the next shape
|
||||
// */
|
||||
// if (3 & (unsigned)TheaterShapeBufferPtr) {
|
||||
// TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
|
||||
// }
|
||||
// Length = length;
|
||||
// return (return_value);
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
//
|
||||
// return_value=(unsigned long)BigShapeBufferPtr;
|
||||
// temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
|
||||
// /*
|
||||
// ** align the actual shape data
|
||||
// */
|
||||
// if (3 & (unsigned)temp_shape_ptr) {
|
||||
// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
|
||||
// }
|
||||
// memcpy (temp_shape_ptr , buffptr , length);
|
||||
// ((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_buffer = 0; //Normal Big Shape Buffer
|
||||
// *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
|
||||
// BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
|
||||
// // Align the next shape
|
||||
// if (3 & (unsigned)BigShapeBufferPtr) {
|
||||
// BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
|
||||
// }
|
||||
// Length = length;
|
||||
// return (return_value);
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// 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
|
||||
*/
|
||||
Check_For_Focus_Loss();
|
||||
|
||||
/*
|
||||
** Allocate extra memory for uncompressed shapes as needed
|
||||
*/
|
||||
Reallocate_Big_Shape_Buffer();
|
||||
#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
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
bool __cdecl Detect_MMX_Availability(void);
|
||||
void __cdecl Init_MMX(void);
|
||||
|
||||
extern char CPUType;
|
||||
extern char VendorID;
|
||||
}
|
||||
//extern "C" {
|
||||
// bool __cdecl Detect_MMX_Availability(void);
|
||||
// void __cdecl Init_MMX(void);
|
||||
//
|
||||
// extern char CPUType;
|
||||
// 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
|
||||
*/
|
||||
mmx = Detect_MMX_Availability();
|
||||
mmx = 1; //Detect_MMX_Availability();
|
||||
|
||||
/*
|
||||
** Return the promised results
|
||||
*/
|
||||
cpu_type = (int)CPUType;
|
||||
char * vendor_ptr = &VendorID;
|
||||
cpu_type = 1; //(int)CPUType;
|
||||
char* vendor_ptr = "Fake CPU"; //&VendorID;
|
||||
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: *
|
||||
* 03/20/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void Reallocate_Big_Shape_Buffer(void);
|
||||
int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
|
||||
{
|
||||
#ifdef WIN32
|
||||
@@ -186,7 +187,7 @@ int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int
|
||||
//char command_line[1024];
|
||||
//strcpy(command_line, command_line_in);
|
||||
|
||||
|
||||
Reallocate_Big_Shape_Buffer();
|
||||
|
||||
#ifndef MPEGMOVIE // Denzil 6/10/98
|
||||
//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 */
|
||||
/*=========================================================================*/
|
||||
|
||||
long __cdecl Buffer_To_Buffer(GraphicViewPortClass* vp, int x, int y, int w, int h, void* buffer, int length);
|
||||
|
||||
extern "C" {
|
||||
/*======================================================================*/
|
||||
/* 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);
|
||||
int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y);
|
||||
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);
|
||||
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);
|
||||
|
||||
@@ -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