ASM files removed, functions replaced with bits from Chronoshift.

This commit is contained in:
Justin Marshall
2020-06-11 13:28:41 -07:00
parent 04b14ea4a2
commit a7fdd19b5a
20 changed files with 1911 additions and 9169 deletions
+2 -19
View File
@@ -9,6 +9,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
set(src_win32lib set(src_win32lib
./REDALERT/WIN32LIB/TOBUFF.cpp
./RedAlert/WIN32LIB/ALLOC.CPP ./RedAlert/WIN32LIB/ALLOC.CPP
./RedAlert/WIN32LIB/AUDIO.H ./RedAlert/WIN32LIB/AUDIO.H
./RedAlert/WIN32LIB/BUFFER.CPP ./RedAlert/WIN32LIB/BUFFER.CPP
@@ -711,27 +712,9 @@ set(src_external
) )
ADD_CUSTOM_COMMAND(OUTPUT TOBUFF.obj
COMMAND ml -c
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/WIN32LIB/TOBUFF.ASM
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/WIN32LIB/TOBUFF.ASM
COMMENT "generate TOBUFF.obj")
ADD_CUSTOM_COMMAND(OUTPUT KEYFBUFF.obj
COMMAND ml.exe /c /nolog /Zi /Zm /Cx
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/KEYFBUFF.ASM /Fl"" /Cp /W3 /errorReport:prompt
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/KEYFBUFF.ASM
COMMENT "generate KEYFBUFF.obj")
ADD_CUSTOM_COMMAND(OUTPUT MMX.obj
COMMAND ml.exe /c /nolog /Zi
${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/MMX.ASM /Fl"" /Cp /W3 /errorReport:prompt
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/MMX.ASM
COMMENT "generate MMX.obj")
add_definitions(-DCHEAT_KEYS -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS) add_definitions(-DCHEAT_KEYS -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS)
add_compile_options(/permissive+ /Zc:forScope- /Zp1) add_compile_options(/permissive+ /Zc:forScope- /Zp1)
add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external} TOBUFF.obj KEYFBUFF.obj MMX.obj "REDALERT/TXTPRNT.CPP") add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external})
+317 -317
View File
@@ -96,59 +96,59 @@ typedef struct tShapeHeaderType{
static int Length; static int Length;
void *Get_Shape_Header_Data(void *ptr) //void *Get_Shape_Header_Data(void *ptr)
{ //{
if (UseBigShapeBuffer) { // if (UseBigShapeBuffer) {
//
ShapeHeaderType *header = (ShapeHeaderType*) ptr; // ShapeHeaderType *header = (ShapeHeaderType*) ptr;
return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) ); // return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
//
} else { // } else {
return (ptr); // return (ptr);
} // }
} //}
//
int Get_Last_Frame_Length(void) //int Get_Last_Frame_Length(void)
{ //{
return(Length); // return(Length);
} //}
void Reset_Theater_Shapes (void) //void Reset_Theater_Shapes (void)
{ //{
/* // /*
** Delete any previously allocated slots // ** Delete any previously allocated slots
*/ // */
for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) { // for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
delete [] KeyFrameSlots [i]; // delete [] KeyFrameSlots [i];
} // }
//
TheaterShapeBufferPtr = TheaterShapeBufferStart; // TheaterShapeBufferPtr = TheaterShapeBufferStart;
TotalTheaterShapes = 0; // TotalTheaterShapes = 0;
TheaterSlotsUsed = THEATER_SLOT_START; // TheaterSlotsUsed = THEATER_SLOT_START;
} //}
void Reallocate_Big_Shape_Buffer(void) //void Reallocate_Big_Shape_Buffer(void)
{ //{
if (ReallocShapeBufferFlag) { // if (ReallocShapeBufferFlag) {
BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space // BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
BigShapeBufferPtr -= (unsigned)BigShapeBufferStart; // BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
Memory_Error = NULL; // Memory_Error = NULL;
BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength); // BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
Memory_Error = &Memory_Error_Handler; // Memory_Error = &Memory_Error_Handler;
/* // /*
** If we have run out of memory then disable the uncompressed shapes // ** If we have run out of memory then disable the uncompressed shapes
** It may still be possible to continue with compressed shapes // ** It may still be possible to continue with compressed shapes
*/ // */
if (!BigShapeBufferStart) { // if (!BigShapeBufferStart) {
UseBigShapeBuffer = false; // UseBigShapeBuffer = false;
return; // return;
} // }
BigShapeBufferPtr += (unsigned)BigShapeBufferStart; // BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
ReallocShapeBufferFlag = FALSE; // ReallocShapeBufferFlag = FALSE;
} // }
} //}
//#ifdef FIXIT_SCORE_CRASH //#ifdef FIXIT_SCORE_CRASH
@@ -166,10 +166,10 @@ void Reallocate_Big_Shape_Buffer(void)
* HISTORY: * * HISTORY: *
* 11/19/96 2:37PM ST : Created * * 11/19/96 2:37PM ST : Created *
*=============================================================================================*/ *=============================================================================================*/
void Disable_Uncompressed_Shapes (void) //void Disable_Uncompressed_Shapes (void)
{ //{
UseBigShapeBuffer = false; // UseBigShapeBuffer = false;
} //}
@@ -187,10 +187,10 @@ void Disable_Uncompressed_Shapes (void)
* HISTORY: * * HISTORY: *
* 11/19/96 2:37PM ST : Created * * 11/19/96 2:37PM ST : Created *
*=============================================================================================*/ *=============================================================================================*/
void Enable_Uncompressed_Shapes (void) //void Enable_Uncompressed_Shapes (void)
{ //{
UseBigShapeBuffer = OriginalUseBigShapeBuffer; // UseBigShapeBuffer = OriginalUseBigShapeBuffer;
} //}
//#endif //FIXIT //#endif //FIXIT
void Check_Use_Compressed_Shapes (void) void Check_Use_Compressed_Shapes (void)
@@ -222,266 +222,266 @@ void Check_Use_Compressed_Shapes (void)
unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr) //unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr)
{ //{
#ifdef FIXIT_SCORE_CRASH //#ifdef FIXIT_SCORE_CRASH
char *ptr; // char *ptr;
unsigned long offcurr, offdiff; // unsigned long offcurr, offdiff;
#else //#else
char *ptr, *lockptr;//, *uncomp_ptr; // char *ptr, *lockptr;//, *uncomp_ptr;
unsigned long offcurr, off16, offdiff; // unsigned long offcurr, off16, offdiff;
#endif //#endif
unsigned long offset[SUBFRAMEOFFS]; // unsigned long offset[SUBFRAMEOFFS];
KeyFrameHeaderType *keyfr; // KeyFrameHeaderType *keyfr;
unsigned short buffsize, currframe, subframe; // unsigned short buffsize, currframe, subframe;
unsigned long length = 0; // unsigned long length = 0;
char frameflags; // char frameflags;
unsigned long return_value; // unsigned long return_value;
char *temp_shape_ptr; // char *temp_shape_ptr;
//
// // //
// valid pointer?? // // valid pointer??
// // //
Length = 0; // Length = 0;
if ( !dataptr || !buffptr ) { // if ( !dataptr || !buffptr ) {
return(0); // return(0);
} // }
//
// // //
// look at header then check that frame to build is not greater // // look at header then check that frame to build is not greater
// than total frames // // than total frames
// // //
keyfr = (KeyFrameHeaderType *) dataptr; // keyfr = (KeyFrameHeaderType *) dataptr;
//
if ( framenumber >= keyfr->frames ) { // if ( framenumber >= keyfr->frames ) {
return(0); // return(0);
} // }
//
//
if (UseBigShapeBuffer) { // if (UseBigShapeBuffer) {
/* // /*
** If we havnt yet allocated memory for uncompressed shapes then do so now. // ** If we havnt yet allocated memory for uncompressed shapes then do so now.
** // **
*/ // */
if (!BigShapeBufferStart) { // if (!BigShapeBufferStart) {
BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL); // BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
BigShapeBufferPtr = BigShapeBufferStart; // BigShapeBufferPtr = BigShapeBufferStart;
//
/* // /*
** Allocate memory for theater specific uncompressed shapes // ** Allocate memory for theater specific uncompressed shapes
*/ // */
TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL); // TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
TheaterShapeBufferPtr = TheaterShapeBufferStart; // TheaterShapeBufferPtr = TheaterShapeBufferStart;
} // }
//
/* // /*
** If we are running out of memory (<10k left) for uncompressed shapes // ** If we are running out of memory (<10k left) for uncompressed shapes
** then allocate some more. // ** then allocate some more.
*/ // */
if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) { // if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
ReallocShapeBufferFlag = TRUE; // ReallocShapeBufferFlag = TRUE;
} // }
//
/* // /*
** If this animation was not previously uncompressed then // ** If this animation was not previously uncompressed then
** allocate memory to keep the pointers to the uncompressed data // ** allocate memory to keep the pointers to the uncompressed data
** for these animation frames // ** for these animation frames
*/ // */
if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) { // if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
keyfr->x = UNCOMPRESS_MAGIC_NUMBER; // keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
if (IsTheaterShape) { // if (IsTheaterShape) {
keyfr->y = TheaterSlotsUsed; // keyfr->y = TheaterSlotsUsed;
TheaterSlotsUsed++; // TheaterSlotsUsed++;
} else { // } else {
keyfr->y = TotalSlotsUsed; // keyfr->y = TotalSlotsUsed;
TotalSlotsUsed++; // TotalSlotsUsed++;
} // }
/* // /*
** Allocate and clear the memory for the shape info // ** Allocate and clear the memory for the shape info
*/ // */
KeyFrameSlots[keyfr->y]= new char *[keyfr->frames]; // KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4); // memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
} // }
//
/* // /*
** If this frame was previously uncompressed then just return // ** If this frame was previously uncompressed then just return
** a pointer to the raw data // ** a pointer to the raw data
*/ // */
if (*(KeyFrameSlots[keyfr->y]+framenumber)) { // if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
if (IsTheaterShape) { // if (IsTheaterShape) {
return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); // return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
} else { // } else {
return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); // return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
} // }
} // }
} // }
//
// calc buff size // // calc buff size
buffsize = keyfr->width * keyfr->height; // buffsize = keyfr->width * keyfr->height;
//
// get offset into data // // get offset into data
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) ); // ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
Mem_Copy( ptr, &offset[0], 12L ); // Mem_Copy( ptr, &offset[0], 12L );
frameflags = (char)(offset[0] >> 24); // frameflags = (char)(offset[0] >> 24);
//
//
if ( (frameflags & KF_KEYFRAME) ) { // if ( (frameflags & KF_KEYFRAME) ) {
//
ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) ); // ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
//
if (keyfr->flags & 1 ) { // if (keyfr->flags & 1 ) {
ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); // ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
} // }
length = LCW_Uncompress( ptr, buffptr, buffsize ); // length = LCW_Uncompress( ptr, buffptr, buffsize );
} else { // key delta or delta // } else { // key delta or delta
//
if ( (frameflags & KF_DELTA) ) { // if ( (frameflags & KF_DELTA) ) {
currframe = (unsigned short)offset[1]; // currframe = (unsigned short)offset[1];
//
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) ); // ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); // Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
} // }
//
// key frame // // key frame
offcurr = offset[1] & 0x00FFFFFFL; // offcurr = offset[1] & 0x00FFFFFFL;
//
// key delta // // key delta
offdiff = (offset[0] & 0x00FFFFFFL) - offcurr; // offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
//
ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr ); // ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
//
if (keyfr->flags & 1 ) { // if (keyfr->flags & 1 ) {
ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); // ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
} // }
//
#ifndef FIXIT_SCORE_CRASH //#ifndef FIXIT_SCORE_CRASH
off16 = (unsigned long)lockptr & 0x00003FFFL; // off16 = (unsigned long)lockptr & 0x00003FFFL;
#endif //#endif
//
length = LCW_Uncompress( ptr, buffptr, buffsize ); // length = LCW_Uncompress( ptr, buffptr, buffsize );
//
if (length > buffsize) { // if (length > buffsize) {
return(0); // return(0);
} // }
//
#ifndef FIXIT_SCORE_CRASH //#ifndef FIXIT_SCORE_CRASH
if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { // if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
//
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); // ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
off16 = (unsigned long)ptr & 0x00003FFFL; // off16 = (unsigned long)ptr & 0x00003FFFL;
//
offcurr += offdiff; // offcurr += offdiff;
offdiff = 0; // offdiff = 0;
} // }
#endif //#endif
//
length = buffsize; // length = buffsize;
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); // Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
//
if ( (frameflags & KF_DELTA) ) { // if ( (frameflags & KF_DELTA) ) {
// adjust to delta after the keydelta // // adjust to delta after the keydelta
//
currframe++; // currframe++;
subframe = 2; // subframe = 2;
//
while (currframe <= framenumber) { // while (currframe <= framenumber) {
offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr; // offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
//
#ifndef FIXIT_SCORE_CRASH //#ifndef FIXIT_SCORE_CRASH
if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { // if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
//
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); // ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
off16 = (unsigned long)lockptr & 0x00003FFFL; // off16 = (unsigned long)lockptr & 0x00003FFFL;
//
offcurr += offdiff; // offcurr += offdiff;
offdiff = 0; // offdiff = 0;
} // }
#endif //#endif
//
length = buffsize; // length = buffsize;
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); // Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
//
currframe++; // currframe++;
subframe += 2; // subframe += 2;
//
if ( subframe >= (SUBFRAMEOFFS - 1) && // if ( subframe >= (SUBFRAMEOFFS - 1) &&
currframe <= framenumber ) { // currframe <= framenumber ) {
Mem_Copy( Add_Long_To_Pointer( dataptr, // Mem_Copy( Add_Long_To_Pointer( dataptr,
(((unsigned long)currframe << 3) + // (((unsigned long)currframe << 3) +
sizeof(KeyFrameHeaderType)) ), // sizeof(KeyFrameHeaderType)) ),
&offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); // &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
subframe = 0; // subframe = 0;
} // }
} // }
} // }
} // }
//
//
if (UseBigShapeBuffer) { // if (UseBigShapeBuffer) {
/* // /*
** Save the uncompressed shape data so we dont have to uncompress it // ** Save the uncompressed shape data so we dont have to uncompress it
** again next time its drawn. // ** again next time its drawn.
** We keep a space free before the raw shape data so we can add line // ** We keep a space free before the raw shape data so we can add line
** header info before the shape is drawn for the first time // ** header info before the shape is drawn for the first time
*/ // */
//
if (IsTheaterShape) { // if (IsTheaterShape) {
/* // /*
** Shape is a theater specific shape // ** Shape is a theater specific shape
*/ // */
return_value = (unsigned long) TheaterShapeBufferPtr; // return_value = (unsigned long) TheaterShapeBufferPtr;
temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); // temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
/* // /*
** align the actual shape data // ** align the actual shape data
*/ // */
if (3 & (unsigned)temp_shape_ptr) { // if (3 & (unsigned)temp_shape_ptr) {
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); // temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
} // }
//
memcpy (temp_shape_ptr , buffptr , length); // memcpy (temp_shape_ptr , buffptr , length);
((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated // ((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data // ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer // ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer
*(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart; // *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); // TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
/* // /*
** Align the next shape // ** Align the next shape
*/ // */
if (3 & (unsigned)TheaterShapeBufferPtr) { // if (3 & (unsigned)TheaterShapeBufferPtr) {
TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc); // TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
} // }
Length = length; // Length = length;
return (return_value); // return (return_value);
//
} else { // } else {
//
//
return_value=(unsigned long)BigShapeBufferPtr; // return_value=(unsigned long)BigShapeBufferPtr;
temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); // temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
/* // /*
** align the actual shape data // ** align the actual shape data
*/ // */
if (3 & (unsigned)temp_shape_ptr) { // if (3 & (unsigned)temp_shape_ptr) {
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); // temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
} // }
memcpy (temp_shape_ptr , buffptr , length); // memcpy (temp_shape_ptr , buffptr , length);
((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated // ((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data // ((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data
((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer // ((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer
*(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart; // *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); // BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
// Align the next shape // // Align the next shape
if (3 & (unsigned)BigShapeBufferPtr) { // if (3 & (unsigned)BigShapeBufferPtr) {
BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc); // BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
} // }
Length = length; // Length = length;
return (return_value); // return (return_value);
} // }
//
} else { // } else {
return ((unsigned long)buffptr); // return ((unsigned long)buffptr);
} // }
} //}
/*********************************************************************************************** /***********************************************************************************************
-561
View File
@@ -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
-504
View File
@@ -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
-5
View File
@@ -2169,11 +2169,6 @@ Mono_Set_Cursor(0,0);
** Call the focus loss handler ** Call the focus loss handler
*/ */
Check_For_Focus_Loss(); Check_For_Focus_Loss();
/*
** Allocate extra memory for uncompressed shapes as needed
*/
Reallocate_Big_Shape_Buffer();
#endif #endif
/* /*
-126
View File
@@ -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
-182
View File
@@ -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
View File
@@ -51,13 +51,13 @@
** Prototypes for linkage to assembly module ** Prototypes for linkage to assembly module
*/ */
extern "C" { //extern "C" {
bool __cdecl Detect_MMX_Availability(void); // bool __cdecl Detect_MMX_Availability(void);
void __cdecl Init_MMX(void); // void __cdecl Init_MMX(void);
//
extern char CPUType; // extern char CPUType;
extern char VendorID; // extern char VendorID;
} //}
/*********************************************************************************************** /***********************************************************************************************
@@ -82,13 +82,13 @@ void Get_CPU_Type(int & cpu_type, bool & mmx, char * vendor_id, int vendor_id_le
/* /*
** Call the asm CPU detection code ** Call the asm CPU detection code
*/ */
mmx = Detect_MMX_Availability(); mmx = 1; //Detect_MMX_Availability();
/* /*
** Return the promised results ** Return the promised results
*/ */
cpu_type = (int)CPUType; cpu_type = 1; //(int)CPUType;
char * vendor_ptr = &VendorID; char* vendor_ptr = "Fake CPU"; //&VendorID;
strncpy(vendor_id, vendor_ptr, vendor_id_length); strncpy(vendor_id, vendor_ptr, vendor_id_length);
} }
-110
View File
@@ -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 *****************************
-316
View File
@@ -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
-299
View File
@@ -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
+2 -1
View File
@@ -176,6 +176,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, unsigned int fdwReason, void *lpvReserve
* HISTORY: * * HISTORY: *
* 03/20/1995 JLB : Created. * * 03/20/1995 JLB : Created. *
*=============================================================================================*/ *=============================================================================================*/
void Reallocate_Big_Shape_Buffer(void);
int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show ) int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show )
{ {
#ifdef WIN32 #ifdef WIN32
@@ -186,7 +187,7 @@ int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int
//char command_line[1024]; //char command_line[1024];
//strcpy(command_line, command_line_in); //strcpy(command_line, command_line_in);
Reallocate_Big_Shape_Buffer();
#ifndef MPEGMOVIE // Denzil 6/10/98 #ifndef MPEGMOVIE // Denzil 6/10/98
//PG DDSCAPS surface_capabilities; //PG DDSCAPS surface_capabilities;
-556
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -28,6 +28,8 @@ class GraphicBufferClass;
/* Define functions which have not under-gone name mangling */ /* Define functions which have not under-gone name mangling */
/*=========================================================================*/ /*=========================================================================*/
long __cdecl Buffer_To_Buffer(GraphicViewPortClass* vp, int x, int y, int w, int h, void* buffer, int length);
extern "C" { extern "C" {
/*======================================================================*/ /*======================================================================*/
/* Externs for all of the common functions between the video buffer */ /* Externs for all of the common functions between the video buffer */
@@ -38,7 +40,6 @@ extern "C" {
void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color); void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color);
int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y); int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y);
void __cdecl Buffer_Clear(void *thisptr, unsigned char color); void __cdecl Buffer_Clear(void *thisptr, unsigned char color);
long __cdecl Buffer_To_Buffer(void *thisptr, int x, int y, int w, int h, void *buff, long size);
long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view); long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view);
BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel, BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel,
int dy_pixel, int pixel_width, int pixel_height, BOOL trans); int dy_pixel, int pixel_width, int pixel_height, BOOL trans);
-288
View File
@@ -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
-294
View File
@@ -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
-294
View File
@@ -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
+70
View File
@@ -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;
}