From a7fdd19b5a611b81070bf49b423af613d225e4e8 Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Thu, 11 Jun 2020 13:28:41 -0700 Subject: [PATCH] ASM files removed, functions replaced with bits from Chronoshift. --- CMakeLists.txt | 21 +- REDALERT/2KEYFRAM.CPP | 634 ++-- REDALERT/2SUPPORT.ASM | 561 ---- REDALERT/2TXTPRNT.ASM | 504 --- REDALERT/CONQUER.CPP | 5 - REDALERT/COORDA.ASM | 126 - REDALERT/CPUID.ASM | 182 -- REDALERT/GETCPU.CPP | 20 +- REDALERT/IPXPROT.ASM | 110 - REDALERT/IPXREAL.ASM | 316 -- REDALERT/KEYFBUFF.ASM | 5210 -------------------------------- REDALERT/MMX.ASM | 299 -- REDALERT/STARTUP.CPP | 3 +- REDALERT/SUPPORT.ASM | 556 ---- REDALERT/Shape.cpp | 1584 +++++++++- REDALERT/WIN32LIB/DRAWBUFF.H | 3 +- REDALERT/WIN32LIB/LCWCOMP.ASM | 288 -- REDALERT/WIN32LIB/LCWUNCMP.ASM | 294 -- REDALERT/WIN32LIB/TOBUFF.ASM | 294 -- REDALERT/WIN32LIB/TOBUFF.CPP | 70 + 20 files changed, 1911 insertions(+), 9169 deletions(-) delete mode 100644 REDALERT/2SUPPORT.ASM delete mode 100644 REDALERT/2TXTPRNT.ASM delete mode 100644 REDALERT/COORDA.ASM delete mode 100644 REDALERT/CPUID.ASM delete mode 100644 REDALERT/IPXPROT.ASM delete mode 100644 REDALERT/IPXREAL.ASM delete mode 100644 REDALERT/KEYFBUFF.ASM delete mode 100644 REDALERT/MMX.ASM delete mode 100644 REDALERT/SUPPORT.ASM delete mode 100644 REDALERT/WIN32LIB/LCWCOMP.ASM delete mode 100644 REDALERT/WIN32LIB/LCWUNCMP.ASM delete mode 100644 REDALERT/WIN32LIB/TOBUFF.ASM create mode 100644 REDALERT/WIN32LIB/TOBUFF.CPP diff --git a/CMakeLists.txt b/CMakeLists.txt index d4971f3..f8ec233 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../) set(CMAKE_VERBOSE_MAKEFILE ON) set(src_win32lib + ./REDALERT/WIN32LIB/TOBUFF.cpp ./RedAlert/WIN32LIB/ALLOC.CPP ./RedAlert/WIN32LIB/AUDIO.H ./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_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}) diff --git a/REDALERT/2KEYFRAM.CPP b/REDALERT/2KEYFRAM.CPP index 1d9d511..18af0a5 100644 --- a/REDALERT/2KEYFRAM.CPP +++ b/REDALERT/2KEYFRAM.CPP @@ -96,59 +96,59 @@ typedef struct tShapeHeaderType{ static int Length; -void *Get_Shape_Header_Data(void *ptr) -{ - if (UseBigShapeBuffer) { - - ShapeHeaderType *header = (ShapeHeaderType*) ptr; - return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) ); - - } else { - return (ptr); - } -} - -int Get_Last_Frame_Length(void) -{ - return(Length); -} +//void *Get_Shape_Header_Data(void *ptr) +//{ +// if (UseBigShapeBuffer) { +// +// ShapeHeaderType *header = (ShapeHeaderType*) ptr; +// return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) ); +// +// } else { +// return (ptr); +// } +//} +// +//int Get_Last_Frame_Length(void) +//{ +// return(Length); +//} -void Reset_Theater_Shapes (void) -{ - /* - ** Delete any previously allocated slots - */ - for (int i=THEATER_SLOT_START ; i= keyfr->frames ) { - return(0); - } - - - if (UseBigShapeBuffer) { - /* - ** If we havnt yet allocated memory for uncompressed shapes then do so now. - ** - */ - if (!BigShapeBufferStart) { - BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL); - BigShapeBufferPtr = BigShapeBufferStart; - - /* - ** Allocate memory for theater specific uncompressed shapes - */ - TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL); - TheaterShapeBufferPtr = TheaterShapeBufferStart; - } - - /* - ** If we are running out of memory (<10k left) for uncompressed shapes - ** then allocate some more. - */ - if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) { - ReallocShapeBufferFlag = TRUE; - } - - /* - ** If this animation was not previously uncompressed then - ** allocate memory to keep the pointers to the uncompressed data - ** for these animation frames - */ - if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) { - keyfr->x = UNCOMPRESS_MAGIC_NUMBER; - if (IsTheaterShape) { - keyfr->y = TheaterSlotsUsed; - TheaterSlotsUsed++; - } else { - keyfr->y = TotalSlotsUsed; - TotalSlotsUsed++; - } - /* - ** Allocate and clear the memory for the shape info - */ - KeyFrameSlots[keyfr->y]= new char *[keyfr->frames]; - memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4); - } - - /* - ** If this frame was previously uncompressed then just return - ** a pointer to the raw data - */ - if (*(KeyFrameSlots[keyfr->y]+framenumber)) { - if (IsTheaterShape) { - return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); - } else { - return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); - } - } - } - - // calc buff size - buffsize = keyfr->width * keyfr->height; - - // get offset into data - ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) ); - Mem_Copy( ptr, &offset[0], 12L ); - frameflags = (char)(offset[0] >> 24); - - - if ( (frameflags & KF_KEYFRAME) ) { - - ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) ); - - if (keyfr->flags & 1 ) { - ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); - } - length = LCW_Uncompress( ptr, buffptr, buffsize ); - } else { // key delta or delta - - if ( (frameflags & KF_DELTA) ) { - currframe = (unsigned short)offset[1]; - - ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) ); - Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); - } - - // key frame - offcurr = offset[1] & 0x00FFFFFFL; - - // key delta - offdiff = (offset[0] & 0x00FFFFFFL) - offcurr; - - ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr ); - - if (keyfr->flags & 1 ) { - ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); - } - -#ifndef FIXIT_SCORE_CRASH - off16 = (unsigned long)lockptr & 0x00003FFFL; -#endif - - length = LCW_Uncompress( ptr, buffptr, buffsize ); - - if (length > buffsize) { - return(0); - } - -#ifndef FIXIT_SCORE_CRASH - if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { - - ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); - off16 = (unsigned long)ptr & 0x00003FFFL; - - offcurr += offdiff; - offdiff = 0; - } -#endif - - length = buffsize; - Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); - - if ( (frameflags & KF_DELTA) ) { - // adjust to delta after the keydelta - - currframe++; - subframe = 2; - - while (currframe <= framenumber) { - offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr; - -#ifndef FIXIT_SCORE_CRASH - if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { - - ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); - off16 = (unsigned long)lockptr & 0x00003FFFL; - - offcurr += offdiff; - offdiff = 0; - } -#endif - - length = buffsize; - Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); - - currframe++; - subframe += 2; - - if ( subframe >= (SUBFRAMEOFFS - 1) && - currframe <= framenumber ) { - Mem_Copy( Add_Long_To_Pointer( dataptr, - (((unsigned long)currframe << 3) + - sizeof(KeyFrameHeaderType)) ), - &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); - subframe = 0; - } - } - } - } - - - if (UseBigShapeBuffer) { - /* - ** Save the uncompressed shape data so we dont have to uncompress it - ** again next time its drawn. - ** We keep a space free before the raw shape data so we can add line - ** header info before the shape is drawn for the first time - */ - - if (IsTheaterShape) { - /* - ** Shape is a theater specific shape - */ - return_value = (unsigned long) TheaterShapeBufferPtr; - temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); - /* - ** align the actual shape data - */ - if (3 & (unsigned)temp_shape_ptr) { - temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); - } - - memcpy (temp_shape_ptr , buffptr , length); - ((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated - ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data - ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer - *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart; - TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); - /* - ** Align the next shape - */ - if (3 & (unsigned)TheaterShapeBufferPtr) { - TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc); - } - Length = length; - return (return_value); - - } else { - - - return_value=(unsigned long)BigShapeBufferPtr; - temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); - /* - ** align the actual shape data - */ - if (3 & (unsigned)temp_shape_ptr) { - temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); - } - memcpy (temp_shape_ptr , buffptr , length); - ((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated - ((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data - ((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer - *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart; - BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); - // Align the next shape - if (3 & (unsigned)BigShapeBufferPtr) { - BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc); - } - Length = length; - return (return_value); - } - - } else { - return ((unsigned long)buffptr); - } -} +//unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr) +//{ +//#ifdef FIXIT_SCORE_CRASH +// char *ptr; +// unsigned long offcurr, offdiff; +//#else +// char *ptr, *lockptr;//, *uncomp_ptr; +// unsigned long offcurr, off16, offdiff; +//#endif +// unsigned long offset[SUBFRAMEOFFS]; +// KeyFrameHeaderType *keyfr; +// unsigned short buffsize, currframe, subframe; +// unsigned long length = 0; +// char frameflags; +// unsigned long return_value; +// char *temp_shape_ptr; +// +// // +// // valid pointer?? +// // +// Length = 0; +// if ( !dataptr || !buffptr ) { +// return(0); +// } +// +// // +// // look at header then check that frame to build is not greater +// // than total frames +// // +// keyfr = (KeyFrameHeaderType *) dataptr; +// +// if ( framenumber >= keyfr->frames ) { +// return(0); +// } +// +// +// if (UseBigShapeBuffer) { +// /* +// ** If we havnt yet allocated memory for uncompressed shapes then do so now. +// ** +// */ +// if (!BigShapeBufferStart) { +// BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL); +// BigShapeBufferPtr = BigShapeBufferStart; +// +// /* +// ** Allocate memory for theater specific uncompressed shapes +// */ +// TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL); +// TheaterShapeBufferPtr = TheaterShapeBufferStart; +// } +// +// /* +// ** If we are running out of memory (<10k left) for uncompressed shapes +// ** then allocate some more. +// */ +// if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) { +// ReallocShapeBufferFlag = TRUE; +// } +// +// /* +// ** If this animation was not previously uncompressed then +// ** allocate memory to keep the pointers to the uncompressed data +// ** for these animation frames +// */ +// if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) { +// keyfr->x = UNCOMPRESS_MAGIC_NUMBER; +// if (IsTheaterShape) { +// keyfr->y = TheaterSlotsUsed; +// TheaterSlotsUsed++; +// } else { +// keyfr->y = TotalSlotsUsed; +// TotalSlotsUsed++; +// } +// /* +// ** Allocate and clear the memory for the shape info +// */ +// KeyFrameSlots[keyfr->y]= new char *[keyfr->frames]; +// memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4); +// } +// +// /* +// ** If this frame was previously uncompressed then just return +// ** a pointer to the raw data +// */ +// if (*(KeyFrameSlots[keyfr->y]+framenumber)) { +// if (IsTheaterShape) { +// return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); +// } else { +// return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber)); +// } +// } +// } +// +// // calc buff size +// buffsize = keyfr->width * keyfr->height; +// +// // get offset into data +// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) ); +// Mem_Copy( ptr, &offset[0], 12L ); +// frameflags = (char)(offset[0] >> 24); +// +// +// if ( (frameflags & KF_KEYFRAME) ) { +// +// ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) ); +// +// if (keyfr->flags & 1 ) { +// ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); +// } +// length = LCW_Uncompress( ptr, buffptr, buffsize ); +// } else { // key delta or delta +// +// if ( (frameflags & KF_DELTA) ) { +// currframe = (unsigned short)offset[1]; +// +// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) ); +// Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); +// } +// +// // key frame +// offcurr = offset[1] & 0x00FFFFFFL; +// +// // key delta +// offdiff = (offset[0] & 0x00FFFFFFL) - offcurr; +// +// ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr ); +// +// if (keyfr->flags & 1 ) { +// ptr = (char *)Add_Long_To_Pointer( ptr, 768L ); +// } +// +//#ifndef FIXIT_SCORE_CRASH +// off16 = (unsigned long)lockptr & 0x00003FFFL; +//#endif +// +// length = LCW_Uncompress( ptr, buffptr, buffsize ); +// +// if (length > buffsize) { +// return(0); +// } +// +//#ifndef FIXIT_SCORE_CRASH +// if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { +// +// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); +// off16 = (unsigned long)ptr & 0x00003FFFL; +// +// offcurr += offdiff; +// offdiff = 0; +// } +//#endif +// +// length = buffsize; +// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); +// +// if ( (frameflags & KF_DELTA) ) { +// // adjust to delta after the keydelta +// +// currframe++; +// subframe = 2; +// +// while (currframe <= framenumber) { +// offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr; +// +//#ifndef FIXIT_SCORE_CRASH +// if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) { +// +// ptr = (char *)Add_Long_To_Pointer( ptr, offdiff ); +// off16 = (unsigned long)lockptr & 0x00003FFFL; +// +// offcurr += offdiff; +// offdiff = 0; +// } +//#endif +// +// length = buffsize; +// Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff)); +// +// currframe++; +// subframe += 2; +// +// if ( subframe >= (SUBFRAMEOFFS - 1) && +// currframe <= framenumber ) { +// Mem_Copy( Add_Long_To_Pointer( dataptr, +// (((unsigned long)currframe << 3) + +// sizeof(KeyFrameHeaderType)) ), +// &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); +// subframe = 0; +// } +// } +// } +// } +// +// +// if (UseBigShapeBuffer) { +// /* +// ** Save the uncompressed shape data so we dont have to uncompress it +// ** again next time its drawn. +// ** We keep a space free before the raw shape data so we can add line +// ** header info before the shape is drawn for the first time +// */ +// +// if (IsTheaterShape) { +// /* +// ** Shape is a theater specific shape +// */ +// return_value = (unsigned long) TheaterShapeBufferPtr; +// temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); +// /* +// ** align the actual shape data +// */ +// if (3 & (unsigned)temp_shape_ptr) { +// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); +// } +// +// memcpy (temp_shape_ptr , buffptr , length); +// ((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated +// ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data +// ((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer +// *(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart; +// TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); +// /* +// ** Align the next shape +// */ +// if (3 & (unsigned)TheaterShapeBufferPtr) { +// TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc); +// } +// Length = length; +// return (return_value); +// +// } else { +// +// +// return_value=(unsigned long)BigShapeBufferPtr; +// temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType); +// /* +// ** align the actual shape data +// */ +// if (3 & (unsigned)temp_shape_ptr) { +// temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc); +// } +// memcpy (temp_shape_ptr , buffptr , length); +// ((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated +// ((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data +// ((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer +// *(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart; +// BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr); +// // Align the next shape +// if (3 & (unsigned)BigShapeBufferPtr) { +// BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc); +// } +// Length = length; +// return (return_value); +// } +// +// } else { +// return ((unsigned long)buffptr); +// } +//} /*********************************************************************************************** diff --git a/REDALERT/2SUPPORT.ASM b/REDALERT/2SUPPORT.ASM deleted file mode 100644 index d3f0e3a..0000000 --- a/REDALERT/2SUPPORT.ASM +++ /dev/null @@ -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 - diff --git a/REDALERT/2TXTPRNT.ASM b/REDALERT/2TXTPRNT.ASM deleted file mode 100644 index b5467ef..0000000 --- a/REDALERT/2TXTPRNT.ASM +++ /dev/null @@ -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 or was specified. = left margin - ; = 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 diff --git a/REDALERT/CONQUER.CPP b/REDALERT/CONQUER.CPP index a3e4eb5..a0ae38f 100644 --- a/REDALERT/CONQUER.CPP +++ b/REDALERT/CONQUER.CPP @@ -2169,11 +2169,6 @@ Mono_Set_Cursor(0,0); ** Call the focus loss handler */ Check_For_Focus_Loss(); - - /* - ** Allocate extra memory for uncompressed shapes as needed - */ - Reallocate_Big_Shape_Buffer(); #endif /* diff --git a/REDALERT/COORDA.ASM b/REDALERT/COORDA.ASM deleted file mode 100644 index d9510b7..0000000 --- a/REDALERT/COORDA.ASM +++ /dev/null @@ -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 diff --git a/REDALERT/CPUID.ASM b/REDALERT/CPUID.ASM deleted file mode 100644 index fabcf6c..0000000 --- a/REDALERT/CPUID.ASM +++ /dev/null @@ -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 - diff --git a/REDALERT/GETCPU.CPP b/REDALERT/GETCPU.CPP index 8e5456b..d2571a8 100644 --- a/REDALERT/GETCPU.CPP +++ b/REDALERT/GETCPU.CPP @@ -51,13 +51,13 @@ ** Prototypes for linkage to assembly module */ -extern "C" { - bool __cdecl Detect_MMX_Availability(void); - void __cdecl Init_MMX(void); - - extern char CPUType; - extern char VendorID; -} +//extern "C" { +// bool __cdecl Detect_MMX_Availability(void); +// void __cdecl Init_MMX(void); +// +// extern char CPUType; +// extern char VendorID; +//} /*********************************************************************************************** @@ -82,13 +82,13 @@ void Get_CPU_Type(int & cpu_type, bool & mmx, char * vendor_id, int vendor_id_le /* ** Call the asm CPU detection code */ - mmx = Detect_MMX_Availability(); + mmx = 1; //Detect_MMX_Availability(); /* ** Return the promised results */ - cpu_type = (int)CPUType; - char * vendor_ptr = &VendorID; + cpu_type = 1; //(int)CPUType; + char* vendor_ptr = "Fake CPU"; //&VendorID; strncpy(vendor_id, vendor_ptr, vendor_id_length); } diff --git a/REDALERT/IPXPROT.ASM b/REDALERT/IPXPROT.ASM deleted file mode 100644 index ab95251..0000000 --- a/REDALERT/IPXPROT.ASM +++ /dev/null @@ -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 ***************************** diff --git a/REDALERT/IPXREAL.ASM b/REDALERT/IPXREAL.ASM deleted file mode 100644 index 657c113..0000000 --- a/REDALERT/IPXREAL.ASM +++ /dev/null @@ -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 ***************************** diff --git a/REDALERT/KEYFBUFF.ASM b/REDALERT/KEYFBUFF.ASM deleted file mode 100644 index 002a2bf..0000000 --- a/REDALERT/KEYFBUFF.ASM +++ /dev/null @@ -1,5210 +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 : Command & Conquer * -;* * -;* File Name : KEYFBUFF.ASM * -;* * -;* Programmer : David R. Dettmer * -;* * -;* Start Date : March 3, 1995 * -;* * -;* Last Update : * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* Buffer_Frame_To_Page -- Copies a linear buffer to a virtual viewport * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -;********************** Model & Processor Directives *********************** -;IDEAL -;P386 -;MODEL USE32 FLAT -;jumps - -.MODEL FLAT -;.386 - -;******************************** Includes ********************************* -;INCLUDE "gbuffer.inc" -;include "profile.inc" - -OPTIMAL_BYTE_COPY equ 14 - -GraphicViewPort STRUCT -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 -GraphicViewPort ENDS - -;******************************** Equates ********************************** - -TRUE equ 1 ; Boolean 'true' value -FALSE equ 0 ; Boolean 'false' value - -;*=========================================================================*/ -;* The following are defines used to control what functions are linked * -;* in for Buffer_Frame_To_Page. * -;*=========================================================================*/ -;USE_NORMAL EQU TRUE -;USE_HORZ_REV EQU TRUE -;USE_VERT_REV EQU TRUE -;USE_SCALING EQU TRUE - - -FLAG_NORMAL EQU 0 -FLAG_TRANS EQU 1 -FLAG_GHOST EQU 2 -FLAG_FADING EQU 4 -FLAG_PREDATOR EQU 8 - -FLAG_MASK EQU 0Fh - - -SHAPE_NORMAL EQU 0000h ; Standard shape -;SHAPE_HORZ_REV EQU 0001h ; Flipped horizontally -;SHAPE_VERT_REV EQU 0002h ; Flipped vertically -;SHAPE_SCALING EQU 0004h ; Scaled (WORD scale_x, WORD scale_y) -;SHAPE_VIEWPORT_REL EQU 0010h ; Coords are window-relative -;SHAPE_WIN_REL EQU 0010h ; Coordinates are window relative instead of absolute. -SHAPE_CENTER EQU 0020h ; Coords are based on shape's center pt -SHAPE_TRANS EQU 0040h ; has transparency - -SHAPE_FADING EQU 0100h ; Fading effect (VOID * fading_table, - ; WORD fading_num) -SHAPE_PREDATOR EQU 0200h ; Transparent warping effect -;SHAPE_COMPACT EQU 0400h ; Never use this bit -;SHAPE_PRIORITY EQU 0800h ; Use priority system when drawing -SHAPE_GHOST EQU 1000h ; Shape is drawn ghosted -;SHAPE_SHADOW EQU 2000h -SHAPE_PARTIAL EQU 4000h -;SHAPE_COLOR EQU 8000h ; Remap the shape's colors - ; (VOID * color_table) - - -; -;.......................... Shadow Effect .................................. -; -SHADOW_COL EQU 00FFh ; magic number for shadows - -;......................... Priority System ................................. -; -CLEAR_UNUSED_BITS EQU 0007h ; and with 0000-0111 to clear - ; non-walkable high bit and - ; scaling id bits -NON_WALKABLE_BIT EQU 0080h ; and with 1000-0000 to clear all - ; but non-walkable bit -; -;......................... Predator Effect ................................. -; -;PRED_MASK EQU 0007h ; mask used for predator pixel puts -PRED_MASK EQU 000Eh ; mask used for predator pixel puts - - -;--------------------------------------------------------------------------- -; -; Use a macro to make code a little cleaner. -; The parameter varname is optional. -; Syntax to use macro is : -; WANT equ expression -; USE func [,varname] -; If the 'varname' is defined, a table declaration is created like: -; GLOBAL TableName:DWORD -; Then, the table entry is created: -; If WANT is true, the table entry is created for the given function: -; varname DD func -; If WANT is not TRUE, a Not_Supported entry is put in the table: -; varname DD Not_Supported -; The resulting tables look like: -; -; GLOBAL ExampTable:DWORD -; ExampTable DD routine1 -; DD routine2 -; DD routine3 -; ... -; Thus, each table is an array of function pointers. -; -;--------------------------------------------------------------------------- -USE MACRO func, varname - IF WANT - varname DD func - ELSE - varname DD Not_Supported - ENDIF -ENDM - -prologue macro -endm - - - -epilogue macro -endm - - -; IFNB -; GLOBAL varname:DWORD -; ENDIF - -;--------------------------------------------------------------------------- - - -.DATA - -;--------------------------------------------------------------------------- -; Predator effect variables -;--------------------------------------------------------------------------- -; make table for negative offset and use the used space for other variables - -BFPredNegTable DW -1, -3, -2, -5, -2, -4, -3, -1 - ; 8 words below calculated - DW 0, 0, 0, 0, 0, 0, 0, 0 ; index ffffff00 - DD 0, 0, 0, 0 ; index ffffff10 -BFPredOffset DD 0, 0, 0, 0 ; index ffffff20 - DD 0, 0, 0, 0 ; index ffffff30 - ; partially faded predator effect value -BFPartialPred DD 0, 0, 0, 0 ; index ffffff40 -BFPartialCount DD 0, 0, 0, 0 ; index ffffff50 - DD 0, 0, 0, 0 ; index ffffff60 - DD 0, 0, 0, 0 ; index ffffff70 - DD 0, 0, 0, 0 ; index ffffff80 - DD 0, 0, 0, 0 ; index ffffff90 - DD 0, 0, 0, 0 ; index ffffffa0 - DD 0, 0, 0, 0 ; index ffffffb0 - DD 0, 0, 0, 0 ; index ffffffc0 - DD 0, 0, 0, 0 ; index ffffffd0 - DD 0, 0, 0, 0 ; index ffffffe0 - DD 0, 0, 0, 0 ; index fffffff0 -BFPredTable DW 1, 3, 2, 5, 2, 3, 4, 1 -;BFPredTable DB 1, 3, 2, 5, 4, 3, 2, 1 - - - - - - - extern C BigShapeBufferStart:dword - extern C UseBigShapeBuffer:dword - extern C TheaterShapeBufferStart:dword - extern C IsTheaterShape:dword - ;extern C Single_Line_Trans_Entry:near - ;extern C Next_Line:near - extern C MMX_Done:near - extern C MMXAvailable:dword - ;extern C EndNewShapeJumpTable:byte - ;extern C NewShapeJumpTable:dword - - -;********************************************************************************** -; -; Jump tables for new line header system -; -; Each line of shape data now has a header byte which describes the data on the line. -; - -; -; Header byte control bits -; -BLIT_TRANSPARENT =1 -BLIT_GHOST =2 -BLIT_FADING =4 -BLIT_PREDATOR =8 -BLIT_SKIP =16 -BLIT_ALL =BLIT_TRANSPARENT or BLIT_GHOST or BLIT_FADING or BLIT_PREDATOR or BLIT_SKIP - - -ShapeHeaderType STRUCT - - draw_flags dd ? - shape_data dd ? - shape_buffer dd ? - -ShapeHeaderType ENDS - - - -; -; Global definitions for routines that draw a single line of a shape -; - ;extern Short_Single_Line_Copy:near - ;extern Single_Line_Trans:near - ;extern Single_Line_Ghost:near - ;extern Single_Line_Ghost_Trans:near - ;extern Single_Line_Fading:near - ;extern Single_Line_Fading_Trans:near - ;extern Single_Line_Ghost_Fading:near - ;extern Single_Line_Ghost_Fading_Trans:near - ;extern Single_Line_Predator:near - ;extern Single_Line_Predator_Trans:near - ;extern Single_Line_Predator_Ghost:near - ;extern Single_Line_Predator_Ghost_Trans:near - ;extern Single_Line_Predator_Fading:near - ;extern Single_Line_Predator_Fading_Trans:near - ;extern Single_Line_Predator_Ghost_Fading:near - ;extern Single_Line_Predator_Ghost_Fading_Trans:near - ;extern Single_Line_Skip:near - - ;extern Single_Line_Single_Fade:near - ;extern Single_Line_Single_Fade_Trans:near - -;externdef AllFlagsJumpTable:dword -; -externdef NewShapeJumpTable:dword -externdef EndNewShapeJumpTable:byte -externdef CriticalFadeRedirections:dword -;externdef BufferFrameTable:dword - -;externdef CriticalFadeRedirections:dword -;externdef CriticalFadeRedirections:dword -;externdef CriticalFadeRedirections:dword -;externdef BF_Copy:far ptr -;externdef BF_Trans:dword -;externdef BF_Ghost:dword -;externdef BF_Ghost_Trans:dword -;externdef BF_Fading:dword -;externdef BF_Fading_Trans:dword -;externdef BF_Ghost_Fading:dword -;externdef BF_Ghost_Fading_Trans:dword -;externdef BF_Predator:dword -;externdef BF_Predator_Trans:dword -;externdef BF_Predator_Ghost:dword -;externdef BF_Predator_Ghost_Trans:dword -;externdef BF_Predator_Fading:dword -;externdef BF_Predator_Fading_Trans:dword -;externdef BF_Predator_Ghost_Fading:dword -;externdef BF_Predator_Ghost_Fading_Trans:dword - -externdef C Single_Line_Trans:near -externdef C Single_Line_Trans_Entry:near -;externdef C Next_Line:near - - -.CODE - - -;--------------------------------------------------------------------------- -; Code Segment Tables: -; This code uses the USE macro to set up tables of function addresses. -; The tables have the following format: -; Tables defined are: -; BufferFrameTable -;--------------------------------------------------------------------------- - -WANT equ -USE BF_Copy, BufferFrameTable - -WANT equ -USE BF_Trans - -WANT equ -USE BF_Ghost - -WANT equ -USE BF_Ghost_Trans - -WANT equ -USE BF_Fading - -WANT equ -USE BF_Fading_Trans - -WANT equ -USE BF_Ghost_Fading - -WANT equ -USE BF_Ghost_Fading_Trans - -WANT equ -USE BF_Predator - -WANT equ -USE BF_Predator_Trans - -WANT equ -USE BF_Predator_Ghost - -WANT equ -USE BF_Predator_Ghost_Trans - -WANT equ -USE BF_Predator_Fading - -WANT equ -USE BF_Predator_Fading_Trans - -WANT equ -USE BF_Predator_Ghost_Fading - -WANT equ -USE BF_Predator_Ghost_Fading_Trans - - - -.DATA - -;NewShapeJumpTable label near ptr dword - -; -; Jumptable for shape line drawing with no flags set -; - -NewShapeJumpTable dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy -;CriticalFadeRedirections label dword -CriticalFadeRedirections dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with transparent flags set -; - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and transparent flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - -; -; Jumptable for shape line drawing routines with fading flag set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Fading - dd Single_Line_Fading - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and transparent flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and ghost flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - -; -; Jumptable for shape line drawing routines with fading, transparent and ghost flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - - -; -; Jumptable for shape line drawing with predator flag set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with transparent and predator flags set -; - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with ghost and transparent and predator flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - -; -; Jumptable for shape line drawing routines with fading and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Fading - dd Single_Line_Fading - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and transparent and predator flags set -; - - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Fading - dd Single_Line_Fading_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -; -; Jumptable for shape line drawing routines with fading and ghost and predator flags set -; - - dd Short_Single_Line_Copy - dd Short_Single_Line_Copy - dd Single_Line_Ghost - dd Single_Line_Ghost - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading - dd Single_Line_Predator - dd Single_Line_Predator - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - - - - - - -; -; Jumptable for shape line drawing routines with all flags set -; - -AllFlagsJumpTable label dword - dd Short_Single_Line_Copy - dd Single_Line_Trans - dd Single_Line_Ghost - dd Single_Line_Ghost_Trans - dd Single_Line_Single_Fade - dd Single_Line_Single_Fade_Trans - dd Single_Line_Ghost_Fading - dd Single_Line_Ghost_Fading_Trans - dd Single_Line_Predator - dd Single_Line_Predator_Trans - dd Single_Line_Predator_Ghost - dd Single_Line_Predator_Ghost_Trans - dd Single_Line_Predator_Fading - dd Single_Line_Predator_Fading_Trans - dd Single_Line_Predator_Ghost_Fading - dd Single_Line_Predator_Ghost_Fading_Trans - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - dd Single_Line_Skip - - -EndNewShapeJumpTable db 0 - -.CODE - - - -;--------------------------------------------------------------------------- - - - - -;********************************************************************************************* -;* Set_Shape_Header -- create the line header bytes for a shape * -;* * -;* INPUT: Shape width * -;* Shape height * -;* ptr to raw shape data * -;* ptr to shape headers * -;* shape flags * -;* ptr to translucency table * -;* IsTranslucent * -;* * -;* OUTPUT: none * -;* * -;* Warnings: * -;* * -;* HISTORY: * -;* 11/29/95 10:09AM ST : Created. * -;*===========================================================================================* - - Setup_Shape_Header proc C pixel_width:DWORD, pixel_height:DWORD, src:DWORD, headers:DWORD, flags:DWORD, Translucent:DWORD, IsTranslucent:DWORD - - ;ARG pixel_width :DWORD ; width of rectangle to blit - ;ARG pixel_height :DWORD ; height of rectangle to blit - ;ARG src :DWORD ; this is a member function - ;ARG headers :DWORD - ;ARG flags :DWORD - ;ARG Translucent :DWORD - ;ARG IsTranslucent :DWORD - LOCAL trans_count :DWORD - - pushad - - - mov esi,[src] ;ptr to raw shape data - mov edi,[headers] ;ptr to headers we are going to set up - mov eax,[flags] - and eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST - mov [edi].ShapeHeaderType.draw_flags,eax ;save old flags in header - add edi,size ShapeHeaderType - mov edx,[pixel_height] ;number of shape lines to scan - -outer_loop: mov ecx,[pixel_width] ;number of pixels in shape line - xor bl,bl ;flag the we dont know anything about this line yet - mov [trans_count],0 ;we havnt scanned any transparent pixels yet - -; -; Scan one shape line to see what kind of data it contains -; -inner_loop: xor eax,eax - mov al,[esi] - inc esi - -; -; Check for transparent pixel -; - test al,al - jnz not_transp - test [flags],SHAPE_TRANS - jz not_transp - or bl,BLIT_TRANSPARENT ;flag that pixel is transparent - inc [trans_count] ;keep count of the number of transparent pixels on the line - jmp end_lp - -; -; Check for predator effect on this line -; -not_transp: test [flags],SHAPE_PREDATOR - jz not_pred - or bl,BLIT_PREDATOR - -; -; Check for ghost effects -; -not_pred: test [flags],SHAPE_GHOST - jz not_ghost - push edi - mov edi,[IsTranslucent] - cmp byte ptr [edi+eax],-1 - pop edi - jz not_ghost - or bl,BLIT_GHOST - -; -; Check if fading is required -; -not_ghost: test [flags],SHAPE_FADING - jz end_lp - or bl,BLIT_FADING - -end_lp: dec ecx - jnz inner_loop - - -; -; Interpret the info we have collected and decide which routine will be -; used to draw this line -; - xor bh,bh - - test bl,BLIT_TRANSPARENT - jz no_transparencies - or bh,BLIT_TRANSPARENT - mov ecx,[pixel_width] - cmp ecx,[trans_count] - jnz not_all_trans - -; all pixels in the line were transparent so we dont need to draw it at all - mov bh,BLIT_SKIP - jmp got_line_type - -not_all_trans: -no_transparencies: - mov al,bl - and al,BLIT_PREDATOR - or bh,al - mov al,bl - and al,BLIT_GHOST - or bh,al - mov al,bl - and al,BLIT_FADING - or bh,al - -; -; Save the line header and do the next line -; -got_line_type:mov [edi],bh - inc edi - - dec edx - jnz outer_loop - - - popad - ret - -Setup_Shape_Header endp - - - - -;************************************************************** -; -; Macro to fetch the header of the next line and jump to the appropriate routine -; -next_line macro - - add edi , [ dest_adjust_width ] ;add in dest modulo - dec edx ;line counter - jz real_out ;return - mov ecx,[save_ecx] ;ecx is pixel count - mov eax,[header_pointer] ;ptr to next header byte - mov al,[eax] - inc [header_pointer] - and eax,BLIT_ALL ;Make sure we dont jump to some spurious address - ; if the header is wrong then its better to draw with the wrong - ; shape routine than to die - shl eax,2 - add eax,[ShapeJumpTableAddress] ;get the address to jump to - jmp dword ptr [eax] ;do the jump - - endm - - - - - - -;*************************************************************************** -;* VVC::TOPAGE -- Copies a linear buffer to a virtual viewport * -;* * -;* INPUT: WORD x_pixel - x pixel on viewport to copy from * -;* WORD y_pixel - y pixel on viewport to copy from * -;* WORD pixel_width - the width of copy region * -;* WORD pixel_height - the height of copy region * -;* BYTE * src - buffer to copy from * -;* VVPC * dest - virtual viewport to copy to * -;* * -;* 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_Frame_To_Page proc C public USES eax ebx ecx edx esi edi x_pixel:DWORD, y_pixel:DWORD, pixel_width:DWORD, pixel_height:DWORD, src:DWORD, dest:DWORD, flags:DWORD - - ;USES eax,ebx,ecx,edx,esi,edi - - ;*=================================================================== - ;* define the arguements that our function takes. - ;*=================================================================== - ;ARG x_pixel :DWORD ; x pixel position in source - ;ARG y_pixel :DWORD ; y pixel position in source - ;ARG pixel_width :DWORD ; width of rectangle to blit - ;ARG pixel_height:DWORD ; height of rectangle to blit - ;ARG src :DWORD ; this is a member function - ;ARG dest :DWORD ; what are we blitting to - - ;ARG flags :DWORD ; flags passed - - ;*=================================================================== - ; Define some locals so that we can handle things quickly - ;*=================================================================== - LOCAL IsTranslucent :DWORD ; ptr to the is_translucent table - LOCAL Translucent :DWORD ; ptr to the actual translucent table - LOCAL FadingTable :DWORD ; extracted fading table pointer - LOCAL FadingNum :DWORD ; get the number of times to fade - - LOCAL StashECX :DWORD ; temp variable for ECX register - - LOCAL jflags :DWORD ; flags used to goto correct buff frame routine - LOCAL BufferFrameRout :DWORD ; ptr to the buffer frame routine - - LOCAL jmp_loc :DWORD ; calculated jump location - LOCAL loop_cnt :DWORD - - LOCAL x1_pixel :DWORD - LOCAL y1_pixel :DWORD - LOCAL scr_x :DWORD - LOCAL scr_y :DWORD - LOCAL dest_adjust_width :DWORD - LOCAL scr_adjust_width :DWORD - LOCAL header_pointer :DWORD - LOCAL use_old_draw :DWORD - LOCAL save_ecx :DWORD - LOCAL ShapeJumpTableAddress :DWORD - LOCAL shape_buffer_start :DWORD - - prologue - cmp [ src ] , 0 - jz real_out - - ; - ; Save the line attributes pointers and - ; Modify the src pointer to point to the actual image - ; - cmp [UseBigShapeBuffer],0 - jz do_args ;just use the old shape drawing system - - mov edi,[src] - mov [header_pointer],edi - - mov eax,[BigShapeBufferStart] - cmp [edi].ShapeHeaderType.shape_buffer,0 - jz is_ordinary_shape - mov eax,[TheaterShapeBufferStart] -is_ordinary_shape: - mov [shape_buffer_start],eax - - mov edi,[edi].ShapeHeaderType.shape_data - add edi,[shape_buffer_start] - mov [src],edi - mov [use_old_draw],0 - - - ;==================================================================== - ; Pull off optional arguments: - ; EDI is used as an offset from the 'flags' parameter, to point - ; to the optional argument currently being processed. - ;==================================================================== -do_args: - mov edi , 4 ; optional params start past flags - mov [ jflags ] , 0 ; clear jump flags - -check_centering: - ;------------------------------------------------------------------- - ; See if we need to center the frame - ;------------------------------------------------------------------- - test [ flags ] , SHAPE_CENTER ; does this need to be centered? - je check_trans ; if not the skip over this stuff - - mov eax , [ pixel_width ] - mov ebx , [ pixel_height ] - sar eax , 1 - sar ebx , 1 - sub [ x_pixel ] , eax - sub [ y_pixel ] , ebx - -check_trans: - test [ flags ] , SHAPE_TRANS - jz check_ghost - - or [ jflags ] , FLAG_TRANS - - ;-------------------------------------------------------------------- - ; SHAPE_GHOST: DWORD is_translucent tbl - ;-------------------------------------------------------------------- -check_ghost: - test [ flags ] , SHAPE_GHOST ; are we ghosting this shape - jz check_fading - - mov eax , [ flags + edi ] - or [ jflags ] , FLAG_GHOST - mov [ IsTranslucent ] , eax ; save ptr to is_trans. tbl - add eax , 0100h ; add 256 for first table - add edi , 4 ; next argument - mov [ Translucent ] , eax ; save ptr to translucent tbl - - - -check_fading: - ;______________________________________________________________________ - ; If this is the first time through for this shape then - ; set up the shape header - ;______________________________________________________________________ - pushad - - cmp [UseBigShapeBuffer],0 - jz new_shape - - mov edi,[header_pointer] - cmp [edi].ShapeHeaderType.draw_flags,-1 - jz setup_headers - mov eax,[flags] ;Redo the shape headers if this shape was - and eax,SHAPE_TRANS or SHAPE_FADING or SHAPE_PREDATOR or SHAPE_GHOST ;initially set up with different flags - cmp eax,[edi].ShapeHeaderType.draw_flags - jz no_header_setup -new_shape: - mov [use_old_draw],1 - jmp no_header_setup - -setup_headers: - push [IsTranslucent] - push [Translucent] - push [flags] - push [header_pointer] - push [src] - push [pixel_height] - push [pixel_width] - call Setup_Shape_Header - add esp,7*4 - mov [ShapeJumpTableAddress], offset AllFlagsJumpTable - jmp headers_set -no_header_setup: - - xor eax,eax - test [flags],SHAPE_PREDATOR - jz not_shape_predator - or al,BLIT_PREDATOR - -not_shape_predator: - test [flags],SHAPE_FADING - jz not_shape_fading - or al,BLIT_FADING - -not_shape_fading: - - test [flags],SHAPE_TRANS - jz not_shape_transparent - or al,BLIT_TRANSPARENT - -not_shape_transparent: - - test [flags],SHAPE_GHOST - jz not_shape_ghost - or al,BLIT_GHOST - -not_shape_ghost: - - - shl eax,7 - add eax, offset NewShapeJumpTable - mov [ShapeJumpTableAddress],eax - ;call Init_New_Shape_Jump_Table_Address - - -headers_set: - popad - - ;-------------------------------------------------------------------- - ; SHAPE_FADING: DWORD fade_table[256], DWORD fade_count - ;-------------------------------------------------------------------- - test [ flags ] , SHAPE_FADING ; are we fading this shape - jz check_predator - - mov eax , [ flags + edi ] - mov [ FadingTable ] , eax ; save address of fading tbl - mov eax , [ flags + edi + 4 ] ; get fade num - or [ jflags ] , FLAG_FADING - and eax , 03fh ; no need for more than 63 - add edi , 8 ; next argument - cmp eax , 0 ; check if it's 0 - jnz set_fading ; if not, store fade num - - and [ flags ] , NOT SHAPE_FADING ; otherwise, don't fade - -set_fading: - mov [ FadingNum ] , eax - - mov ebx,[ShapeJumpTableAddress] - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Single_Fade - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Single_Fade_Trans - cmp eax,1 - jz single_fade - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx],offset Single_Line_Fading - mov dword ptr [CriticalFadeRedirections-NewShapeJumpTable+ebx+4],offset Single_Line_Fading_Trans - -single_fade: - - ;-------------------------------------------------------------------- - ; SHAPE_PREDATOR: DWORD init_pred_lookup_offset (0-7) - ;-------------------------------------------------------------------- -check_predator: - test [ flags ] , SHAPE_PREDATOR ; is predator effect on - jz check_partial - - mov eax , [ flags + edi ] ; pull the partial value - or [ jflags ] , FLAG_PREDATOR - shl eax , 1 - cmp eax , 0 - jge check_range - - neg eax - mov ebx , -1 - and eax , PRED_MASK ; keep entries within bounds - mov bl , al - mov eax , ebx ; will be ffffff00-ffffff07 - jmp pred_cont - -check_range: - and eax , PRED_MASK ; keep entries within bounds - -pred_cont: - add edi , 4 ; next argument - mov [ BFPredOffset ] , eax - mov [ BFPartialCount ] , 0 ; clear the partial count - mov [ BFPartialPred ] , 100h ; init partial to off - -pred_neg_init: - mov esi , [ dest ] ; get ptr to dest - mov ebx, 7 * 2 - -pred_loop: - movzx eax , [ WORD PTR BFPredNegTable + ebx ] - add eax , [esi].GraphicViewPort.GVPWidth ; add width - add eax , [esi].GraphicViewPort.GVPXAdd ; add x add - add eax , [esi].GraphicViewPort.GVPPitch ; extra pitch of DD surface ST - 9/29/95 1:08PM - mov [ WORD PTR BFPredNegTable + 16 + ebx ] , ax - dec ebx - dec ebx - jge pred_loop - - ;-------------------------------------------------------------------- - ; SHAPE_PARTIAL: DWORD partial_pred_value (0-255) - ;-------------------------------------------------------------------- -check_partial: - test [ flags ] , SHAPE_PARTIAL ; is this a partial pred? - jz setupfunc - - mov eax , [ flags + edi ] ; pull the partial value - add edi , 4 ; next argument - and eax , 0ffh ; make sure 0-255 - mov [ BFPartialPred ] , eax ; store it off - -setupfunc: - mov ebx , [ jflags ] ; load flags value - and ebx , FLAG_MASK ; clip high bits - add ebx , ebx ; mult by 4 to get DWORD offset - add ebx , ebx - mov ebx , dword ptr [ BufferFrameTable + ebx ] ; get table value - mov dword ptr [ BufferFrameRout ] , ebx ; store it in the function pointer - -; Clip dest Rectangle against source Window boundaries. - - mov [ scr_x ] , 0 - mov [ scr_y ] , 0 - mov esi , [ dest ] ; 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 - - mov [use_old_draw],1 - test cl , 1000b - jz dest_left_ok - - mov eax , [ x_pixel ] - neg eax - mov [ x_pixel ] , 0 - mov [ scr_x ] , eax - -dest_left_ok: - test cl , 0010b - jz dest_bottom_ok - - mov eax , [ y_pixel ] - neg eax - mov [ y_pixel ] , 0 - mov [ scr_y ] , eax - -dest_bottom_ok: - test dl , 0100b - jz dest_right_ok - - mov eax , [esi].GraphicViewPort.GVPWidth ; get width into register - mov [ x1_pixel ] , eax - -dest_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.GVPPitch - add eax , [esi].GraphicViewPort.GVPWidth - mov edi , [esi].GraphicViewPort.GVPOffset - - mov ecx , eax - mul [ y_pixel ] - add edi , [ x_pixel ] - add edi , eax - - add ecx , [ x_pixel ] - sub ecx , [ x1_pixel ] - mov [ dest_adjust_width ] , ecx - - mov esi , [ src ] - mov eax , [ pixel_width ] - sub eax , [ x1_pixel ] - add eax , [ x_pixel ] - mov [ scr_adjust_width ] , eax - - mov eax , [ scr_y ] - mul [ pixel_width ] - add eax , [ scr_x ] - add esi , eax - -; -; If the shape needs to be clipped then we cant handle it with the new header systen -; so draw it with the old shape drawer -; - cmp [use_old_draw],0 - jnz use_old_stuff - - add [header_pointer],size ShapeHeaderType - mov edx,[pixel_height] - mov ecx,[pixel_width] - mov eax,[header_pointer] - mov al,[eax] - mov [save_ecx],ecx - inc [header_pointer] - and eax,BLIT_ALL - shl eax,2 - add eax,[ShapeJumpTableAddress] - jmp dword ptr [eax] - - -use_old_stuff: - mov edx , [ y1_pixel ] - mov eax , [ x1_pixel ] - - sub edx , [ y_pixel ] - jle real_out - - sub eax , [ x_pixel ] - jle real_out - - jmp [ BufferFrameRout ] ; buffer frame to viewport routine - -real_out: - - cmp [MMXAvailable],0 - jz no_mmx_cleanup - call MMX_Done - -no_mmx_cleanup: - epilogue - - ret - - -; ******************************************************************** -; Forward bitblit only -; 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 -; ******************************************************************** -;extern BF_Copy:near - -BF_Copy: - prologue - - 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_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz forward_loop_dword - - ret - -forward_loop_bytes: - mov ecx , eax - rep movsb - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx ; decrement the height - jnz forward_loop_bytes - - epilogue - - ret - - -;******************************************************************** -;******************************************************************** - -; segment code page public use32 'code' ; Need stricter segment alignment - ; for pentium optimisations - - -; -; Expand the 'next_line' macro so we can jump to it -; -; -; ST - 12/20/2018 3:48PM -Next_Line:: next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Trans:: - prologue - -Single_Line_Trans_Entry:: - -slt_mask_map_lp: ; Pentium pipeline usage - ;Pipe Cycles - mov al,[esi] ;U 1 - inc esi ;Vee 1 - - test al,al ;U 1 - jz slt_skip ;Vee 1/5 - -slt_not_trans:mov [edi],al ;u 1 - - inc edi ;vee 1 - dec ecx ;u 1 - - jnz slt_mask_map_lp ;vee (maybe) 1 - -slt_end_line: epilogue - next_line - - ;align 32 - -slt_skip: inc edi - dec ecx - jz slt_skip_end_line - - mov al,[esi] - inc esi - test al,al - jz slt_skip2 - mov [edi],al - inc edi - dec ecx - jnz slt_mask_map_lp - - epilogue - next_line - - ;align 32 - -slt_skip2: inc edi - dec ecx - jz slt_end_line - -; -; If we have hit two transparent pixels in a row then we go into -; the transparent optimised bit -; -slt_round_again: - rept 64 - mov al,[esi] ; ;pipe 1 - inc esi ;1 ;pipe 2 - test al,al ; ;pipe 1 - jnz slt_not_trans;pipe 2 (not pairable in 1) - ;2 - inc edi ; ;pipe 1 - dec ecx ;3 ;pipe 2 - jz slt_end_line ;4 ;pipe 1 (not pairable) - endm ; best case is 4 cycles per iteration - jmp slt_round_again - - - -slt_skip_end_line: - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with no transparent pixels -; -; 11/29/95 10:21AM - ST -; -; We have to align the destination for cards that dont bankswitch correctly -; when you write non-aligned data. -; - ;align 32 -Long_Single_Line_Copy: - prologue - - rept 3 - test edi,3 - jz LSLC_aligned - movsb - dec ecx - endm - -LSLC_aligned: - mov ebx,ecx - - shr ecx,2 - rep movsd - and ebx,3 - jz proc_out - movsb - dec bl - jz proc_out - movsb - dec bl - jz proc_out - movsb -proc_out: epilogue - next_line - - - -;***************************************************************************** -; Draw a single short line with no transparent pixels -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Short_Single_Line_Copy: - prologue - cmp ecx,16 - jge Long_Single_Line_Copy - mov ebx,ecx - rep movsb - mov ecx,ebx - epilogue - next_line - - -;***************************************************************************** -; Skip a line of source that is all transparent -; -; 11/29/95 10:21AM - ST -; - - ;align 32 -Single_Line_Skip: - prologue - add esi,ecx - add edi,ecx - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Single_Line_Ghost: - - prologue - xor eax,eax -slg_loop: mov al,[esi] - mov ebx,[IsTranslucent] - inc esi - mov bh,[eax+ebx] - cmp bh,-1 - jz slg_store_pixel - - and ebx,0ff00h - mov al,[edi] - add ebx,[Translucent] - mov al,[eax+ebx] - -slg_store_pixel: - mov [edi],al - - inc edi - dec ecx - jnz slg_loop - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 -Single_Line_Ghost_Trans: - prologue - xor eax,eax -; cmp ecx,3 -; ja slgt4 - -slgt_loop: mov al,[esi] - inc esi - test al,al - jz slgt_transparent - -slgt_not_transparent: - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgt_store_pixel - - and ebx,0ff00h - mov al,[edi] - add ebx,[Translucent] - mov al,[eax+ebx] - -slgt_store_pixel: - mov [edi],al - inc edi - dec ecx - jnz slgt_loop - epilogue - next_line - - - ;align 32 - -slgt_transparent: - inc edi ;1 - dec ecx ;2 - jz slgt_out ;1 (not pairable) - -slgt_round_again: - rept 64 - mov al,[esi] ; ;pipe 1 - inc esi ;1 ;pipe 2 - test al,al ; ;pipe 1 - jnz slgt_not_transparent ;pipe 2 (not pairable in 1) - ;2 - inc edi ; ;pipe 1 - dec ecx ;3 ;pipe 2 - jz slgt_out ;4 ;pipe 1 (not pairable) - endm ; best case is 4 cycles per iteration - jmp slgt_round_again - -slgt_out: epilogue - next_line - - - -; -; Optimised video memory access version -; - ;align 32 - -slgt4: push edx - mov edx,[edi] - - rept 4 - local slgt4_store1 - local slgt4_trans1 - mov al,[esi] - inc esi - test al,al - jz slgt4_trans1 - - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgt4_store1 - - and ebx,0ff00h - mov al,dl - add ebx,[Translucent] - mov al,[eax+ebx] - -slgt4_store1: mov dl,al - -slgt4_trans1: ror edx,8 - endm - mov [edi],edx - pop edx - lea edi,[edi+4] - lea ecx,[ecx+0fffffffch] - cmp ecx,3 - ja slgt4 - test ecx,ecx - jnz slgt_loop - - epilogue - next_line - - - - - - - - - - -;***************************************************************************** -; Draw a single line with fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Fading: - prologue - xor eax,eax - mov ebx,[FadingTable] - push ebp - mov ebp,[FadingNum] - push ebp - -slf_loop: mov al,[esi] - inc esi - - mov ebp,[esp] - -slf_fade_loop:mov al,[ebx+eax] - dec ebp - jnz slf_fade_loop - - mov [edi],al - inc edi - - dec ecx - jnz slf_loop - add esp,4 - pop ebp - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with transparent pixels and fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Fading_Trans: - prologue - xor eax,eax - mov ebx,[FadingTable] - push ebp - mov ebp,[FadingNum] - push ebp - -slft_loop: mov al,[esi] - inc esi - test al,al - jz slft_transparent - - mov ebp,[esp] - -slft_fade_loop: - mov al,[ebx+eax] - dec ebp - jnz slft_fade_loop - - mov [edi],al -slft_transparent: - inc edi - - dec ecx - jnz slft_loop - add esp,4 - pop ebp - epilogue - next_line - - - - - -;***************************************************************************** -; Draw a single line with a single fade level (colour remap) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Single_Fade: - prologue - xor eax,eax - mov ebx,[FadingTable] - -slsf_loop: mov al,[esi] - mov al,[ebx+eax] - mov [edi],al - inc esi - inc edi - - dec ecx - jnz slsf_loop - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels and a single fade level (colour remap) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Single_Fade_Trans: - prologue - xor eax,eax - mov ebx,[FadingTable] - -slsft_loop: mov al,[esi] - inc esi - test al,al - jz slsft_transparent - mov al,[ebx+eax] - mov [edi],al - inc edi - dec ecx - jnz slsft_loop - epilogue - next_line - - ;align 32 - -slsft_transparent: - inc edi - - dec ecx - jz slsft_next_line - mov al,[esi] - inc esi - test al,al - jz slsft_transparent - mov al,[ebx+eax] - mov [edi],al - inc edi - dec ecx - jnz slsft_loop - -slsft_next_line: - epilogue - next_line - - - - - -;***************************************************************************** -; Draw a single line with ghosting and fading (colour remapping) -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Ghost_Fading: - - prologue - mov [StashECX],ecx - -SLGF_loop: xor eax,eax - mov al,[esi] - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgf_do_fading - - and ebx,0ff00h - - mov al,[edi] - add ebx,[Translucent] - mov al,[ebx+eax] - -slgf_do_fading: - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgf_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slgf_fade_loop - - mov [edi],al - inc esi - inc edi - - dec [StashECX] - jnz SLGF_loop - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with transparent pixels, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Ghost_Fading_Trans: - prologue - mov [StashECX],ecx - xor eax,eax - -; cmp ecx,3 -; ja slgft4 - -SLGFT_loop: mov al,[esi] - inc esi - test al,al - jz slgft_trans_pixel - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgft_do_fading - - and ebx,0ff00h - - mov al,[edi] - add ebx,[Translucent] - mov al,[ebx+eax] - -slgft_do_fading: - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgft_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slgft_fade_loop - - mov [edi],al -slgft_trans_pixel: - inc edi - - dec [StashECX] - jnz SLGFT_loop - epilogue - next_line - - - ;align 32 - -slgft4: push edx - mov edx,[edi] - - rept 4 - local slgft4_fade - local slgft4_fade_lp - local slgft4_trans - mov al,[esi] - inc esi - test al,al - jz slgft4_trans - mov ebx,[IsTranslucent] - mov bh,[eax+ebx] - cmp bh,-1 - jz slgft4_fade - - and ebx,0ff00h - - mov al,dl - add ebx,[Translucent] - mov al,[ebx+eax] - -slgft4_fade: mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slgft4_fade_lp: mov al,[eax+ebx] - dec ecx - jnz slgft4_fade_lp - - mov dl,al - -slgft4_trans: ror edx,8 - endm - mov [edi],edx - pop edx - lea edi,[edi+4] - sub [StashECX],4 - jz slgft4_out - cmp [StashECX],3 - ja slgft4 - jmp SLGFT_loop - -slgft4_out: epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator effect -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator: - - prologue - -slp_loop: mov al,[esi] - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - or bh,bh - jnz slp_get_pred - - mov [BFPartialCount] , ebx - jmp slp_skip_pixel - -slp_get_pred: xor bh , bh - mov eax,[BFPredOffset] - mov [BFPartialCount] , ebx - add byte ptr [BFPredOffset],2 - mov eax, dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - mov [edi],al - -slp_skip_pixel: - inc esi - inc edi - - dec ecx - jnz slp_loop - - epilogue - next_line - - - - -;***************************************************************************** -; Draw a single line with transparent pixels and predator effect -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Trans: - - prologue - -slpt_loop: mov al,[esi] - inc esi - test al,al - jz slpt_skip_pixel - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - or bh,bh - jnz slpt_get_pred - - mov [BFPartialCount] , ebx - jmp slpt_skip_pixel - -slpt_get_pred:xor bh , bh - mov eax,[BFPredOffset] - mov [BFPartialCount] , ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset ] , PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - mov [edi],al - -slpt_skip_pixel: - inc edi - - dec ecx - jnz slpt_loop - - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost: - - prologue - -slpg_loop: mov al,[esi] - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpg_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpg_check_ghost - -slpg_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax ] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - mov al,[edi+eax] - -slpg_check_ghost: - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpg_store_pixel - - xor eax,eax - and ebx,0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpg_store_pixel: - mov [edi],al - inc esi - inc edi - - dec ecx - jnz slpg_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, predator and ghosting -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Trans: - prologue - -slpgt_loop: mov al,[esi] - inc esi - test al,al - jz slpgt_transparent - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpgt_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgt_check_ghost - -slpgt_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax ] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - mov al,[edi+eax] - -slpgt_check_ghost: - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgt_store_pixel - - xor eax,eax - and ebx,0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgt_store_pixel: - mov [edi],al -slpgt_transparent: - inc edi - - dec ecx - jnz slpgt_loop - - pop ecx - epilogue - next_line - - -;***************************************************************************** -; Draw a single line with predator and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Fading: - - prologue - mov [StashECX],ecx - -slpf_loop: mov al,[esi] - mov ebx,[BFPartialCount] - inc esi - add ebx,[BFPartialPred] - test bh,bh - jnz slpf_get_pred - - mov [BFPartialCount],ebx - jmp slpf_do_fading - -slpf_get_pred:xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - and byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - - and eax,0ffffh - mov al,[eax+edi] - -slpf_do_fading: - and eax,255 - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpf_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slpf_fade_loop - - mov [edi],al - inc edi - - dec [StashECX] - jnz slpf_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, fading and predator -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Fading_Trans: - prologue - mov [StashECX],ecx - -slpft_loop: mov al,[esi] - inc esi - test al,al - jz slpft_transparent - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh,bh - jnz slpft_get_pred - - mov [BFPartialCount],ebx - jmp slpft_do_fading - -slpft_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - and byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - - and eax,0ffffh - mov al,[eax+edi] - -slpft_do_fading: - and eax,255 - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpft_fade_loop: - mov al,[eax+ebx] - dec ecx - jnz slpft_fade_loop - - mov [edi],al -slpft_transparent: - inc edi - - dec [StashECX] - jnz slpft_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with predator, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Fading: - - prologue - mov [StashECX],ecx - -slpgf_loop: mov al,[esi] - mov ebx,[BFPartialCount] - inc esi - add ebx,[BFPartialPred] - test bh , bh - jnz slpgf_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgf_check_ghost - -slpgf_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - -slpgf_check_ghost: - and eax,255 - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgf_do_fading - - and ebx , 0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgf_do_fading: - xor eax,eax - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpgf_fade_loop: - mov al,[ebx+eax] - dec ecx - jnz slpgf_fade_loop - -slpgf_store_pixel: - mov [edi],al - inc edi - - dec [StashECX] - jnz slpgf_loop - - epilogue - next_line - - - -;***************************************************************************** -; Draw a single line with transparent pixels, predator, ghosting and fading -; -; 11/29/95 10:21AM - ST -; - ;align 32 - -Single_Line_Predator_Ghost_Fading_Trans: - - prologue - mov [StashECX],ecx - -slpgft_loop: mov al,[esi] - inc esi - test al,al - jz slpgft_transparent - - mov ebx,[BFPartialCount] - add ebx,[BFPartialPred] - test bh , bh - jnz slpgft_get_pred ; is this a predator pixel? - - mov [BFPartialCount],ebx - jmp slpgft_check_ghost - -slpgft_get_pred: - xor bh,bh - mov eax,[BFPredOffset] - mov [BFPartialCount],ebx - add byte ptr [BFPredOffset],2 - mov eax,dword ptr [BFPredTable+eax] - and byte ptr [BFPredOffset],PRED_MASK - and eax,0ffffh - - mov al,[edi+eax] - -slpgft_check_ghost: - and eax,255 - mov ebx,[IsTranslucent] - mov bh,[ebx+eax] - cmp bh,0ffh - je slpgft_do_fading - - and ebx , 0FF00h - - mov al,[edi] - add ebx,[Translucent] - - mov al,[ebx+eax] - -slpgft_do_fading: - xor eax,eax - mov ebx,[FadingTable] - mov ecx,[FadingNum] - -slpgft_fade_loop: - mov al,[ebx+eax] - dec ecx - jnz slpgft_fade_loop - -slpgft_store_pixel: - mov [edi],al -slpgft_transparent: - inc edi - - dec [StashECX] - jnz slpgft_loop - - epilogue - next_line - - - - -; ends ;end of strict alignment segment - -; codeseg - - - -;extern BF_Trans:near - -BF_Trans: - - prologue -; calc the code location to skip to 10 bytes per REPT below!!!! - mov ecx , eax - and ecx , 01fh - lea ecx , [ ecx + ecx * 4 ] ; quick multiply by 5 - neg ecx - shr eax , 5 - lea ecx , [ trans_reference + ecx * 2 ] ; next multiply by 2 - mov [ loop_cnt ] , eax - mov [ jmp_loc ] , ecx - -trans_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -; the following code should NOT be changed without changing the calculation -; above!!!!!! - -trans_line: - - REPT 32 - local trans_pixel - mov bl , [ esi ] - inc esi - test bl , bl - jz trans_pixel - - mov [ edi ] , bl - - trans_pixel: - inc edi - ENDM - -trans_reference: - dec ecx - jge trans_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz trans_loop - epilogue - - ret - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost:near -BF_Ghost: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx, [offset ghost_reference] - sub ecx, [offset ghost_line] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -ghost_line: - - REPT 32 - local store_pixel - mov al , [ esi ] - inc esi - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -ghost_reference: - dec ecx - jge ghost_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Trans:near -BF_Ghost_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_t_reference ] - sub ecx, [ offset ghost_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -ghost_t_line: - - REPT 32 - local transp_pixel - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -ghost_t_reference: - dec ecx - jge ghost_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Fading:near -BF_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset fading_reference ] - sub ecx, [ offset fading_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ fading_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -fading_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - mov ebx , [ FadingTable ] ; run color through fading table - jmp [ jmp_loc ] - -fading_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -fading_line: - - REPT 32 - local fade_loop - mov al , [ esi ] - inc esi - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - inc edi - - ENDM - -fading_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge fading_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz fading_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Fading_Trans:near -BF_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset fading_t_reference ] - sub ecx, [ offset fading_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ fading_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -fading_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - mov ebx , [ FadingTable ] ; run color through fading table - jmp [ jmp_loc ] - -fading_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -fading_t_line: - - REPT 32 - local transp_pixel - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -fading_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge fading_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz fading_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Fading:near -BF_Ghost_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_f_reference ] - sub ecx, [ offset ghost_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -ghost_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -ghost_f_line: - - REPT 32 - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - mov ebx , [ IsTranslucent ] ; is it a lucent color? - mov bh , byte ptr [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the lation table - ; ((_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (_color * 256) of the lation equ. - mov al , byte ptr [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -ghost_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge ghost_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Ghost_Fading_Trans:near -BF_Ghost_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset ghost_f_t_reference ] - sub ecx, [ offset ghost_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ ghost_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -ghost_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -ghost_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -ghost_f_t_line: - - REPT 32 - local transp_pixel - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz transp_pixel - - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , byte ptr [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , byte ptr [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - - transp_pixel: - inc edi - - ENDM - -ghost_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge ghost_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz ghost_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator:near -BF_Predator: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_reference ] - sub ecx, [offset predator_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_line: - - REPT 32 - local get_pred - local skip_pixel - mov al , [ esi ] - inc esi - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp skip_pixel - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - -; xor bh , bh -; mov eax , [ BFPredValue ] ; pick up a color offset a pseudo- -; ; random amount from the current -; mov [ BFPartialCount ] , ebx -; mov al , [ edi + eax ] ; viewport address - - mov [ edi ] , al - - skip_pixel: - inc edi - - ENDM - -predator_reference: - dec ecx - jge predator_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Trans:near -BF_Predator_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_t_reference ] - sub ecx, [ offset predator_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_t_line: - - REPT 32 - local trans_pixel - local get_pred - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp store_pixel - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_t_reference: - dec ecx - jge predator_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost:near -BF_Predator_Ghost: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_reference ] - sub ecx, [ offset predator_g_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_g_line: - - REPT 32 - local get_pred - local check_ghost - local store_pixel - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -predator_g_reference: - dec ecx - jge predator_g_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Trans:near -BF_Predator_Ghost_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_t_reference ] - sub ecx, [ offset predator_g_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_t_loop: - mov ecx , [ loop_cnt ] - jmp [ jmp_loc ] - -predator_g_t_line: - - REPT 32 - local trans_pixel - local get_pred - local check_ghost - local store_pixel - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je store_pixel - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_g_t_reference: - dec ecx - jge predator_g_t_line - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Fading:near -BF_Predator_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_f_reference ] - sub ecx, [ offset predator_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_f_line: - - REPT 32 - local get_pred - local do_fading - local fade_loop - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp do_fading - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - inc edi - - ENDM - -predator_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Fading_Trans:near -BF_Predator_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_f_t_reference ] - sub ecx, [ offset predator_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_f_t_line: - - REPT 32 - local trans_pixel - local get_pred - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp do_fading - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Fading:near -BF_Predator_Ghost_Fading: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_f_reference ] - sub ecx, [ offset predator_g_f_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_f_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_f_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_g_f_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_g_f_line: - - REPT 32 - local get_pred - local check_ghost - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - mov ebx , [ BFPartialCount ] - inc esi - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - inc edi - - ENDM - -predator_g_f_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_g_f_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_f_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -;extern BF_Predator_Ghost_Fading_Trans:near -BF_Predator_Ghost_Fading_Trans: - - prologue - mov ebx , eax ; width - - ; NOTE: the below calculation assumes a group of instructions is - ; less than 256 bytes - - ; get length of the 32 groups of instructions - - lea ecx , [ offset predator_g_f_t_reference ] - sub ecx, [ offset predator_g_f_t_line ] - - shr ebx , 5 ; width / 32 - shr ecx , 5 ; length of instructions / 32 - and eax , 01fh ; mod of width / 32 - mul cl ; calc offset to start of group - neg eax ; inverse of width - mov [ loop_cnt ] , ebx ; save width / 32 - lea ecx , [ predator_g_f_t_reference + eax ] - mov eax , 0 - mov [ jmp_loc ] , ecx - -predator_g_f_t_loop: - mov ecx , [ loop_cnt ] - mov [ StashECX ] , ecx ; preserve ecx for later - jmp [ jmp_loc ] - -predator_g_f_t_line_begin: - mov [ StashECX ] , ecx ; preserve ecx for later - -predator_g_f_t_line: - - REPT 32 - local trans_pixel - local get_pred - local check_ghost - local store_pixel - local do_fading - local fade_loop - mov al , [ esi ] - inc esi - test al , al - jz trans_pixel - - mov ebx , [ BFPartialCount ] - add ebx , [ BFPartialPred ] - or bh , bh - jnz get_pred ; is this a predator pixel? - - mov [ BFPartialCount ] , ebx - jmp check_ghost - - get_pred: - xor bh , bh - mov eax, [ BFPredOffset ] - mov [ BFPartialCount ] , ebx - add BYTE PTR [ BFPredOffset ] , 2 - movzx eax , WORD PTR [ BFPredTable + eax ] - and BYTE PTR [ BFPredOffset ] , PRED_MASK - ; pick up a color offset a pseudo- - ; random amount from the current - movzx eax , BYTE PTR [ edi + eax ] ; viewport address - - check_ghost: - mov ebx , [ IsTranslucent ] ; is it a translucent color? - mov bh , BYTE PTR [ ebx + eax ] - cmp bh , 0ffh - je do_fading - - and ebx , 0FF00h ; clear all of ebx except bh - ; we have the index to the translation table - ; ((trans_colour * 256) + dest colour) - mov al , [ edi ] ; mov pixel at destination to al - add ebx , [ Translucent ] ; get the ptr to it! - ; Add the (trans_color * 256) of the translation equ. - mov al , BYTE PTR [ ebx + eax ] ; get new pixel in al -; DRD jmp store_pixel - - do_fading: - mov ebx , [ FadingTable ] ; run color through fading table - mov ecx , [ FadingNum ] - - fade_loop: - mov al, byte ptr [ebx + eax] - dec ecx - jnz fade_loop - - store_pixel: - mov [ edi ] , al - - trans_pixel: - inc edi - - ENDM - -predator_g_f_t_reference: - mov ecx , [ StashECX ] ; restore ecx for main draw loop - dec ecx - jge predator_g_f_t_line_begin - - add esi , [ scr_adjust_width ] - add edi , [ dest_adjust_width ] - dec edx - jnz predator_g_f_t_loop - - epilogue - ret - - -;******************************************************************** -;******************************************************************** - -Not_Supported: - ret - -Buffer_Frame_To_Page ENDP - - -end - -externdef C CPUType: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 - -;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 -; - cmp ecx,8 - jge @@mmx_loop - push offset Single_Line_Trans_Entry - ret - -; -; Use MMX instructions to mask 8 bytes at once -; -; Creates a bitmask based on the source bytes equality with zero and then uses this to mask -; out the source bytes in the destination data. The advatage that MMX gives us is that there is -; no 'test for zero then jump' required to mask. -; - align 64 ;MMX instructions like 64 byte alignment! - -@@mmx_loop: - movq mm0,[esi] ; move 8 bytes of source into mm0 - pxor mm1,mm1 ; zero out mm1 - pcmpeqb mm1,mm0 ; compare mm0 with 0. Bits get set in mm1 - lea esi,[esi+8] ; adjust the source data pointer - pand mm1,[edi] ; and in the destination data to throw away the bytes which arent zero in the source - sub ecx,8 ; adjust the byte counter - por mm1,mm0 ; or in the source with the destination data - movq [edi],mm1 ; write back the destination data - lea edi,[edi+8] ; adjust the destination pointer - - cmp ecx,8 - jg @@mmx_loop - -; -; Jump to the approprite code for drawing the end of this line or going to the next one -; - push offset Next_Line - jcxz @@next_line - push offset Single_Line_Trans_Entry -@@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 - -;*************************************************************************** -;** 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 Library * -;* * -;* File Name : KEYFBUFF.ASM * -;* * -;* Programmer : Phil W. Gorrow * -;* * -;* Start Date : July 16, 1992 * -;* * -;* Last Update : October 2, 1994 [JLB] * -;* * -;*-------------------------------------------------------------------------* -;* Functions: * -;* BUFFER_FRAME_TO_LOGICPAGE -- * -;* Normal_Draw -- Function that writes a normal pixel line * -;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - -; IDEAL -; P386 -;IDEAL_MODE EQU 1 -; INCLUDE "wwlib.i" - - ;------------------------------------------------------------------- - ; Extern all the library variables that this module requires - ;------------------------------------------------------------------- - - EXTRN C MaskPage:WORD - EXTRN C BackGroundPage:WORD - - ;------------------------------------------------------------------- - ; Define all the equates that this module requires - ;------------------------------------------------------------------- - -WIN_X EQU 0 ; offset for the x coordinate -WIN_Y EQU 2 ; offset for the y coordinate -WIN_WIDTH EQU 4 ; offset for the window width -WIN_HEIGHT EQU 6 ; offset for the window height -BYTESPERROW EQU 320 ; number of bytes per row - -FLAG_NORMAL EQU 0 ; flag for normal draw - -FLAG_GHOST EQU 1 ; This flag enables the ghost -FLAG_PRIORITY_TRANS EQU 2 ; flag for priority and transparent -FLAG_TRANS EQU 4 ; flag for transparent draw -FLAG_PRIORITY EQU 8 ; flag for priority draw - - ; fx on the above flags - -FLAG_MASK EQU 15 ; used to and of uneeded bits - -SHAPE_NORMAL EQU 0000h ; Standard shape. -;SHAPE_HORZ_REV EQU 0001h ; Flipped horizontally. -;SHAPE_VERT_REV EQU 0002h ; Flipped vertically. -;SHAPE_SCALING EQU 0004h ; Scaled (WORD scale_x, WORD scale_y) - -SHAPE_WIN_REL EQU 0010h ; Coordinates are window relative instead of absolute. -SHAPE_CENTER EQU 0020h ; Coordinates are based on shape's center point. -SHAPE_TRANS EQU 0040h ; has transparency - - -;SHAPE_FADING EQU 0100h ; Fading effect active (VOID * fading_table, WORD fading_num). -;SHAPE_PREDATOR EQU 0200h ; Transparent warping effect. -;SHAPE_COMPACT EQU 0400h ; Never use this bit. -SHAPE_PRIORITY EQU 0800h ; Use priority system when drawing. - -SHAPE_GHOST EQU 1000h ; Transluscent table process. -;SHAPE_SHADOW EQU 2000h ; -;SHAPE_PARTIAL EQU 4000h ; -;SHAPE_COLOR EQU 8000h ; Remap the shape's colors (VOID * color_table). - - -; MBL MOD 12.1.92 - -CLEAR_NON_WALK_BIT_AND_SCALE_BITS EQU 7 ; Makes it one AND per pixel in Priority_Trans display -CLEAR_NON_WALK_BIT EQU 7fh ; and with 0111-1111 to clear non-walkable high bit -CLEAR_SCALE_BITS EQU 87h ; and with 1000-0111 to clear scaling id bits -NON_WALKABLE_BIT EQU 80h ; and with 1000-0000 to clear all but non-walkable bit - -; END MBL MOD - - - CODESEG - - ; 1 = GHOST (all odd entrys are prefixed with Ghost_) - ; 2 = BLAAAH - ; 4 = Trans (prfx) - ; 8 = Prior (prfx) - - -;--------------------------------------------------------------------------- -; Define the table of different line draw types -;--------------------------------------------------------------------------- - -LineTable DW WSA_Normal_Draw ;0 - DW Ghost_Normal_Draw ;1 - DW 0 ;2 - DW 0 ;3 - - DW Transparent_Draw ;4 - DW Ghost_Transparent_Draw ;5 - DW 0 ;6 - DW 0 ;7 - - DW Priority_Draw ;8 - DW Ghost_Priority_Draw ;9 - DW 0 ;10 - DW 0 ;11 - - DW Priority_Transparent_Draw ;12 - DW Ghost_Priority_Transparent_Draw ;13 - DW 0 ;14 - DW 0 ;15 - - - -;*************************************************************************** -;* BUFFER_FRAME_TO_LOGICPAGE -- * -;* * -;* * -;* * -;* INPUT: * -;* * -;* OUTPUT: * -;* * -;* WARNINGS: * -;* * -;* HISTORY: * -;* 07/16/1992 PWG : Created. * -;*=========================================================================* - PUBLIC C Buffer_Frame_To_LogicPage - PROC C Buffer_Frame_To_LogicPage FAR USES ax bx ecx dx ds esi es edi - - ;------------------------------------------------------------------- - ; Define the arguements that our program takes. - ;------------------------------------------------------------------- - - ARG x_pixel:WORD ; x pixel position to draw at - ARG y_pixel:WORD ; y pixel position to draw at - ARG pixel_w:WORD ; pixel width of draw region - ARG pixel_h:WORD ; pixel height of draw region - ARG win:WORD ; window to clip around - ARG flags:WORD ; flags that this routine will take - ARG buffer:DWORD ; pointer to the buffer with data - ARG args:WORD - - ;------------------------------------------------------------------- - ; Define the local variables that our program uses - ;------------------------------------------------------------------- - - LOCAL IsTranslucent:DWORD ; ptr to the is_translucent table - LOCAL Translucent:DWORD ; ptr to the actual translucent table - - LOCAL win_x1:WORD ; clip window left x pixel position - LOCAL win_x2:WORD ; clip window right x pixel position - LOCAL win_y1:WORD ; clip window top y pixel position - LOCAL win_y2:WORD ; clip window bottom y pixel position - LOCAL clipleft:WORD ; number of pixels to clip on left - LOCAL clipright:WORD ; number of pixels to clip on right - LOCAL nextline:WORD ; offset to the next line - LOCAL putmiddle:WORD ; routine to call to put the middle - LOCAL maskpage:WORD ; location of the depth masks - LOCAL background:WORD ; location of the background data - LOCAL jflags:WORD ; location of the background data - - LOCAL priority:BYTE ; the priority level of the back - - push fs - - xor ecx,ecx - - ;-------------------------------------------------------------------- - ; Check to see if we have supplied any GHOST tables. - ;-------------------------------------------------------------------- - push di - - mov di,6 - mov [jflags],0 - -ghost: - test [flags],SHAPE_GHOST ; are we ghosting this shape - jz short no_ghost ; if not then skip and do more - - or [jflags],FLAG_GHOST - - les ax,dword ptr [buffer + di] - - ; get the "are we really translucent?" table - mov [WORD PTR IsTranslucent],ax - mov [WORD PTR IsTranslucent + 2],es - add ax,0100h ; add to offset for tables - - ; get the "ok we are translucent!!" table - mov [WORD PTR Translucent],ax - mov [WORD PTR Translucent + 2],es - - add di,4 - -no_ghost: - - pop di - - ;------------------------------------------------------------------- - ; See if we need to center the frame - ;------------------------------------------------------------------- - test [flags],SHAPE_CENTER ; does this need to be centered? - je short no_centering ; if not the skip over this stuff - - mov ax,[pixel_w] - mov bx,[pixel_h] - sar ax,1 - sar bx,1 - sub [x_pixel],ax - sub [y_pixel],bx - -no_centering: - mov ax,[flags] - and ax,SHAPE_PRIORITY+SHAPE_TRANS - cmp ax,SHAPE_PRIORITY+SHAPE_TRANS - jne short test_trans - - or [jflags],FLAG_PRIORITY_TRANS - jmp short priority - - ;------------------------------------------------------------------- - ; Get the trans information if we need to get it - ;------------------------------------------------------------------- -test_trans: - test [flags],SHAPE_TRANS ; does this draw use transparencies? - je short test_priority ; if not the skip over this junk - - or [jflags],FLAG_TRANS - -test_priority: - ;------------------------------------------------------------------- - ; Get the priority information if we need to get it - ;------------------------------------------------------------------- - test [flags],SHAPE_PRIORITY ; does this draw use priorities? - je short no_priority ; if not the skip over this junk - - or [jflags],FLAG_PRIORITY - -priority: - mov ax,[BackGroundPage] ; get the background page from ds - mov [background],ax ; and store it on the stack - mov ax,[MaskPage] ; get the mask page from ds - mov [maskpage],ax ; and store it on the stack - mov ax,[WORD PTR buffer + 4]; get the priority level from args - mov [priority],al ; and store it in a local - - ;------------------------------------------------------------------- - ; Get the draw routine that we are going to draw with - ;------------------------------------------------------------------- -no_priority: -; mov bx,[flags] ; load in the current flags byte -; and bx,FLAG_MASK ; prevent lockup on bad value - mov bx,[jflags] ; load in the jump table flags - shl bx,1 - mov ax,[WORD PTR LineTable + bx] ; get the offset of the skip table - mov [putmiddle],ax ; store off the new offset - - ;------------------------------------------------------------------- - ; Get a pointer to the logic page to where we will draw our buffer - ;------------------------------------------------------------------- - push [LogicPage] ; push the current logic page - call FAR PTR Get_Page ; get the physical page address - add sp,2 ; pull the parameter from the stack - mov es,dx ; store the address in the dest - - ;-------------------------------------------------------------------- - ; Point DI to the beginning of the window that we need to look at. - ; that way we can access all of the info through di. - ;-------------------------------------------------------------------- - mov si,OFFSET WindowList ; get the offset of the window list - mov cl,4 ; shift 3 times = multiply by 16 - mov ax,[win] ; get the window number we are using - shl ax,cl ; each window is 8 words long - add si,ax ; add that into the offset of window - - ;-------------------------------------------------------------------- - ; Place all the clipping values on the stack so our function will - ; be truly re-entrant and will not need to shadow these values. - ;-------------------------------------------------------------------- - mov cl,3 ; to convert x to pixel mult by 8 - mov ax,[si + WIN_X] ; get the left clip position - shl ax,cl ; convert to a pixel x position - mov [win_x1],ax ; store the left edge of window - mov [win_x2],ax - - mov ax,[si + WIN_WIDTH] ; get the width of the window - shl ax,cl ; convert to a pixel width - add [win_x2],ax ; add to get the right window edge - - mov ax,[si + WIN_Y] ; get the win y coordinate to clip - mov [win_y1],ax ; and save it onto the stack - - add ax,[si + WIN_HEIGHT] ; calculate the bottom win y coord - mov [win_y2],ax ; and save it onto the stack - - test [flags],SHAPE_WIN_REL ; is this window relative? - je short get_buffer ; if not the skip over - - mov ax,[win_x1] ; get left edge of window - add [x_pixel],ax ; add to x pixel position - mov ax,[win_y1] ; get top edge of window - add [y_pixel],ax ; add to y pixel position - - ;-------------------------------------------------------------------- - ; Get a pointer to the source buffer so we can handle the clipping - ;-------------------------------------------------------------------- -get_buffer: - lds si,[buffer] ; get a pointer to the buffer - - ;-------------------------------------------------------------------- - ; Check the top of our shape and clip any lines that are necessary - ;-------------------------------------------------------------------- - mov ax,[y_pixel] ; get the y_pixel draw position - sub ax,[win_y1] ; subtract out the window y top - jns short check_bottom ; skip if y below window top - add ax,[pixel_h] ; add in the height of the region - jg short clip_top ; if positive then clip top lines - -jump_exit: - jmp proc_exit ; otherwise completely clipped - -clip_top: - xchg [pixel_h],ax - sub ax,[pixel_h] - add [y_pixel],ax - mul [pixel_w] ; convert to number of bytes to skip - add si,ax ; skip past the necessary bytes - - ;-------------------------------------------------------------------- - ; Check the bottom of our shape and clip it if necessary - ;-------------------------------------------------------------------- -check_bottom: - mov ax,[win_y2] ; get the bottom y of the window - sub ax,[y_pixel] ; subtract of the y to draw at - js jump_exit ; if its signed then nothing to draw - jz jump_exit ; if its zero then nothing to draw - - cmp ax,[pixel_h] ; if more room to draw then height - jae short clip_x_left ; then go check the left clip - mov [pixel_h],ax ; clip all but amount that will fit - -clip_x_left: - mov [clipleft],0 ; clear clip on left of region - mov ax,[x_pixel] ; get the pixel x of draw region - sub ax,[win_x1] ; pull out the window coordinate - jns short clip_x_right - neg ax ; negate to get amnt to skip in buf - mov [clipleft],ax ; store it in the left clip info - add [x_pixel],ax ; move to the edge of the window - sub [pixel_w],ax ; pull it out of the pixel width - -clip_x_right: - mov [clipright],0 ; clear clip on right of region - mov ax,[win_x2] ; get the window x of clip region - sub ax,[x_pixel] ; subtract the draw edge of region - js jump_exit ; if its negative then get out - jz jump_exit ; if its zero then get out - - cmp ax,[pixel_w] ; is space available larger than w - jae short draw_prep ; if so then go get drawing - - - xchg [pixel_w],ax ; amt to draw in pixel_w (wid in ax) - sub ax,[pixel_w] ; pull out the amount to draw - mov [clipright],ax ; this is the amount to clip on right - -draw_prep: - push si ; save off source pos in buffer - push ds ; both offset and segment - mov ax,@data - mov ds,ax - mov bx,[y_pixel] - shl bx,1 ; shift left by 1 for word table look - lds si,[YTable] ; get the address of the ytable - mov di,[ds:si+bx] ; look up the multiplied value - pop ds ; restore source pos in buffer - pop si ; both offset and segment - - add di,[x_pixel] ; add in the x pixel position - mov [nextline],di ; save it off in the next line - - ;-------------------------------------------------------------------- - ; Now determine the type of the shape and process it in the proper - ; way. - ;-------------------------------------------------------------------- - mov dx,[pixel_h] - - ; Check to see if the WSA is the screen width and there is no - ; clipping. In this case, then a special single call to the - ; line processing routine is possible. - mov ax,[clipleft] - add ax,[clipright] - jne short top_of_loop - cmp [pixel_w],BYTESPERROW - jne short top_of_loop - - ;------------------------------------ - ; The width of the WSA is the screen width, so just process as - ; one large WSA line. - mov ax,BYTESPERROW - imul dx - mov cx,ax - call [putmiddle] - jmp short proc_exit - - ;------------------------------------ - ; Process line by line. -top_of_loop: - add si,[clipleft] ; skip whats necessary on left edge - mov cx,[pixel_w] ; get the width we need to draw - - ; Copy the source to the destination as appropriate. This routine can - ; trash AX, BX, CX, and DI. It must properly modify SI to point one byte past - ; the end of the data. - call [putmiddle] - - add si,[clipright] ; skip past the left clip - add [nextline],BYTESPERROW - mov di,[nextline] - - dec dx - jnz top_of_loop - -proc_exit: - pop fs - ret - ENDP - - -;*************************************************************************** -;* NORMAL_DRAW -- Function that writes a normal pixel line * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;*=========================================================================* - - PROC NOLANGUAGE WSA_Normal_Draw NEAR - - IF 1 - ; This version is marginally faster than the later version. - mov ax,cx - shr cx,2 - rep movsd - and ax,011b - mov cx,ax - shr cx,1 - rep movsw - adc cx,cx - rep movsb - ret - - ELSE - - shr cx,1 ; convert to words (odd pix in carry) - rep movsw ; write out the needed words - adc cx,0 ; add the carry into cx - rep movsb ; write out the odd byte if any - ret - ENDIF - - ENDP - - -;*************************************************************************** -;* TRANSPARENT_DRAW -- Function that writes a transparent pixel line * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;* 10/02/1994 JLB : Optimized for 250% speed improvement. * -;*=========================================================================* - PROC NOLANGUAGE Transparent_Draw NEAR - - IF 1 - ; Preserve DX since it is used as a scratch register. - push dx - -loop: - ; Swap DS:SI and ES:DI back in preparation for the REP SCASB - ; instruction. - xchg di,si - mov dx,es - mov ax,ds - mov ds,dx - mov es,ax - - ; Remember the bytes remaining in order to calculate the position - ; of the scan when it stops. - mov bx,cx - - ; Scan looking for a non-zero value in the source buffer. - xor al,al - repe scasb - - ; When the loop ends, if the EQ flag is set then the scanning is - ; complete. Jump to the end of the routine in order to fixup the - ; pointers. - je short fini - - ; Advance the destination pointer by the amount necessary to match - ; the source movement. DS:SI points to where data should be written. - add si,bx - inc cx ; SCASB leaves CX one too low, fix it. - dec di ; SCASB leaves DI one byte too far, fix it. - sub si,cx - - ; Scan for the duration of non-zero pixels. This yields a count which - ; is used to copy the source data to the destination. Preserve DI. - mov dx,di - mov bx,cx - repne scasb - mov di,dx - - ; Set BX to equal the number of bytes to copy from source to dest. - inc cx ; SCASB leaves CX one too low, fix it. - sub bx,cx - - ; Move the data from ES:DI to DS:SI for BX bytes. - xchg cx,bx ; Make CX=bytes to move, BX=bytes remaining. - - ; Swap DS:SI and ES:DI in preparation for the REP MOV instruction. - xchg di,si - mov dx,es - mov ax,ds - mov ds,dx - mov es,ax - - ; Move the data from source to dest. First try to move double - ; words. Then copy the remainder bytes (if any). Putting jumps in - ; this section doesn't result in any savings -- oh well. - mov ax,cx - shr cx,2 - rep movsd - and ax,0011b - mov cx,ax - shr cx,1 - rep movsw - adc cx,cx - rep movsb - - ; Restore CX with the remaining bytes to process. - mov cx,bx - - ; If there are more bytes to process, then loop back. - or cx,cx - jne short loop - -fini: - ; Swap ES:DI and DS:SI back to original orientation. - mov ax,ds - mov bx,es - mov es,ax - mov ds,bx - xchg di,si - - ; Restore DX and return. - pop dx - ret - - ELSE - -loop_top: - lodsb - or al,al - jz short skip - - mov [es:di],al ; store the pixel to the screen -skip: - inc di - loop loop_top - ret - - ENDIF - - ENDP - - -;*************************************************************************** -;* PRIORITY_DRAW -- Function that writes a pixels if they are in front of * -;* the given plate. * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;* 12/01/1992 MBL : Updated to work with latest mask data encoding. * -;* 17/01/1993 MCC : Updated for 386, and optimized * -;*=========================================================================* - - PROC NOLANGUAGE Priority_Draw NEAR - - mov fs,[background] ; get the SEG of the background page - mov gs,[maskpage] ; get the SEG of the mask info - mov ah,[priority] ; keep a copy of priority varible for faster cmp - - -loop_top: - lodsb ; get the pixel to draw on the screen - - ; get the mask byte for our pixel - mov bl,[ds:di] - ; get rid of non-walkable bit and - ; get rid of scaling id bits - and bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS - - cmp ah,bl ; are we more toward the front? - jge short out_pixel ; if so then write the pixel - - mov al,[fs:di] ; get the pixel to write -out_pixel: - stosb ; write the pixel and inc the DI - loop loop_top - ret - - ENDP - - -;*************************************************************************** -;* PRIORITY_TRANSPARENT_DRAW -- Function that writes a pixels if they are * -;* in front of the given plate. It also deals with * -;* transparent pixels. * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;* 12/01/1992 MBL : Updated to work with latest mask data encoding. * -;* 17/01/1993 MCC : Updated for 386, and optimized * -;*=========================================================================* - - PROC NOLANGUAGE Priority_Transparent_Draw NEAR - - mov fs,[background] ; get the SEG of the background page - mov gs,[maskpage] ; get the SEG of the mask info - mov ah,[priority] ; keep a copy of priority varible for faster cmp - -loop_top: - lodsb ; get the pixel on the screen - or al,al ; check to see if al is transparent - je short write_back ; if it is go write background - - mov bl,[gs:di] ; get the mask byte for our pixel - - ; get rid of non-walkable bit and - ; get rid of scaling id bits - and bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS - - cmp ah,bl ; are we more toward the front? - jge short out_pixel ; if so then write the pixel - -write_back: - mov al,[fs:di] ; get the pixel to write -out_pixel: - stosb ; write the pixel - loop loop_top - ret - - ENDP - - -;*************************************************************************** -;* GHOST_NORMAL_DRAW -- Function that writes a normal pixel line * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 05/27/1993 MCC : Created. * -;*=========================================================================* - - PROC NOLANGUAGE Ghost_Normal_Draw NEAR - -loop_top: - lodsb - -;--- - ; Ok, find out if the colour is a Translucent colour - push ax - push ds - - lds bx,[IsTranslucent] - mov ah,al ; preserve real pixel - xlat ; get new al (transluecent pixel - xchg ah,al ; get real pixel back into AL just in case - cmp ah,255 - je short normal_pixel ; is it a translucent ? - ; if we get passed here value in - ; AH should be 0-15 - - ; yes, it is a translucent colour so goto our translucent translation - ; table and set up a ptr to the correct table - - mov al,[es:di] - ; mov pixel at destination to al and we have - ; the index to the translation table - ; ((trans_colour * 256) + dest colour) - lds bx,[Translucent] ; get the ptr to it! - add bh,ah ; Add the (trans_color * 256) of the translation equ. - ; XLAT only uses AL so no need to clear AH - xlat ; get new pixel in AL - -normal_pixel: - pop ds - pop bx - mov ah,bh -;--- - - mov [es:di],al ; store the pixel to the screen - -skip: - inc di - loop loop_top - - ret - - ENDP - - -;*************************************************************************** -;* GHOST_TRANSPARENT_DRAW -- Function that writes a transparent pixel line * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 05/27/1993 MCC : Created. * -;*=========================================================================* - PROC NOLANGUAGE Ghost_Transparent_Draw NEAR - -loop_top: - lodsb - or al,al - jz short skip - -;--- - ; Ok, find out if the colour is a Translucent colour - push ax - push ds - - lds bx,[IsTranslucent] - mov ah,al ; preserve real pixel - xlat ; get new al (transluecent pixel - xchg ah,al ; get real pixel back into AL just in case - cmp ah,255 - je short normal_pixel ; is it a translucent ? - ; if we get passed here value in - ; AH should be 0-15 - - ; yes, it is a translucent colour so goto our translucent translation - ; table and set up a ptr to the correct table - - mov al,[es:di] - ; mov pixel at destination to al and we have - ; the index to the translation table - ; ((trans_colour * 256) + dest colour) - lds bx,[Translucent] ; get the ptr to it! - add bh,ah ; Add the (trans_color * 256) of the translation equ. - ; XLAT only uses AL so no need to clear AH - xlat ; get new pixel in AL - -normal_pixel: - pop ds - pop bx - mov ah,bh -;--- - - mov [es:di],al ; store the pixel to the screen - -skip: - inc di - loop loop_top - ret - - ENDP - - -;*************************************************************************** -;* GHOST_PRIORITY_DRAW -- Function that writes a pixels if they are in fron* -;* the given plate. * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;* 12/01/1992 MBL : Updated to work with latest mask data encoding. * -;* 05/27/1993 MCC : Updated to use the new Ghosting fx * -;* 17/01/1993 MCC : Updated for 386, and optimized * -;*=========================================================================* - PROC NOLANGUAGE Ghost_Priority_Draw NEAR - - mov fs,[background] ; get the SEG of the background page - mov gs,[maskpage] ; get the SEG of the mask info - mov ah,[priority] ; keep a copy of priority varible for faster cmp - - -loop_top: - lodsb ; get the pixel to draw on the screen - ; get the mask byte for our pixel - mov bl,[ds:di] - ; get rid of non-walkable bit and - ; get rid of scaling id bits - and bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS - cmp ah,bl ; are we more toward the front? - jge short out_pixel ; if so then write the pixel - - mov al,[fs:di] ; get the pixel to write -out_pixel: - stosb ; write the pixel and inc the DI - loop loop_top - - ret - - ENDP - - -;*************************************************************************** -;* GHOST_PRIORITY_TRANSPARENT_DRAW -- Function that writes a pixels if they* -;* in front of the given plate. It also deals with * -;* transparent pixels. * -;* * -;* INPUT: cx - number of pixels to write * -;* ds:si - buffer which holds the pixels to write * -;* es:di - place to put the pixels we are writing * -;* * -;* OUTPUT: ds:si - points to next pixel past last pixel read * -;* es:di - points to next pixel past last pixel written * -;* * -;* WARNINGS: none * -;* * -;* HISTORY: * -;* 07/17/1992 PWG : Created. * -;* 12/01/1992 MBL : Updated to work with latest mask data encoding. * -;* 05/27/1993 MCC : Updated to use the new Ghosting fx * -;* 17/01/1993 MCC : Updated for 386, and optimized * -;*=========================================================================* - PROC NOLANGUAGE Ghost_Priority_Transparent_Draw NEAR - - mov fs,[background] ; get the SEG of the background page - mov gs,[maskpage] ; get the SEG of the mask info - mov ah,[priority] ; keep a copy of priority varible for faster cmp - -loop_top: - lodsb ; get the pixel on the screen - or al,al ; check to see if al is transparent - je short write_back ; if it is go write background - mov bl,[gs:di] ; get the mask byte for our pixel - ; get rid of non-walkable bit and - ; get rid of scaling id bits - and bl,CLEAR_NON_WALK_BIT_AND_SCALE_BITS - cmp ah,bl ; are we more toward the front? - jge short out_pixel ; if so then write the pixel -write_back: - mov al,[fs:di] ; get the pixel to write -out_pixel: - stosb ; write the pixel - loop loop_top - - ret - - ENDP - - END - diff --git a/REDALERT/MMX.ASM b/REDALERT/MMX.ASM deleted file mode 100644 index 5294429..0000000 --- a/REDALERT/MMX.ASM +++ /dev/null @@ -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 - - - .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 \ No newline at end of file diff --git a/REDALERT/STARTUP.CPP b/REDALERT/STARTUP.CPP index afb0545..82bd7d9 100644 --- a/REDALERT/STARTUP.CPP +++ b/REDALERT/STARTUP.CPP @@ -176,6 +176,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, unsigned int fdwReason, void *lpvReserve * HISTORY: * * 03/20/1995 JLB : Created. * *=============================================================================================*/ +void Reallocate_Big_Shape_Buffer(void); int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int command_show ) { #ifdef WIN32 @@ -186,7 +187,7 @@ int PASCAL WinMain ( HINSTANCE instance , HINSTANCE , char * command_line , int //char command_line[1024]; //strcpy(command_line, command_line_in); - + Reallocate_Big_Shape_Buffer(); #ifndef MPEGMOVIE // Denzil 6/10/98 //PG DDSCAPS surface_capabilities; diff --git a/REDALERT/SUPPORT.ASM b/REDALERT/SUPPORT.ASM deleted file mode 100644 index 561f148..0000000 --- a/REDALERT/SUPPORT.ASM +++ /dev/null @@ -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 - diff --git a/REDALERT/Shape.cpp b/REDALERT/Shape.cpp index cca1b42..c97d4a6 100644 --- a/REDALERT/Shape.cpp +++ b/REDALERT/Shape.cpp @@ -13,99 +13,1531 @@ // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection +/** + * @file + * + * @author CCHyper + * @author OmniBlade + * + * @brief Low level functions for loading and rendering C&C sprite files. + * + * @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 "FUNCTION.H" +#include +#include -/* -** -** Replacement for Shape asm files -** -** ST - 12/19/2018 10:15AM -** -** -** -*/ +#define le16toh(x) x +#define le32toh(x) x +using std::memcpy; -extern "C" unsigned char *_ShapeBuffer = 0; -extern "C" long _ShapeBufferSize = 0; +#define SHP_HAS_PAL 0x0001 +#define SHP_LCW_FRAME 0x80 +#define SHP_XOR_FAR_FRAME 0x40 +#define SHP_XOR_PREV_FRAME 0x20 +#define BIGSHP_BUFFER_MIN_FREE 128000 +#define BIGSHP_BUFFER_GROW 2000000 - +#define SHAPE_TRANSPARENT 0x40 -/* -;*************************************************************************** -;* SET_SHAPE_BUFFER -- Sets the shape buffer to the given pointer * -;* * -;* This routine will set the shape buffer to the given value and make sure * -;* that the system does not try to compress any shapes that will be larger * -;* than the shape buffer. * -;* * -;* INPUT: void * - pointer to the shape buffer * -;* int - size of the buffer which has been passed in * -;* * -;* OUTPUT: none * -;* * -;* PROTO: VOID *Set_Shape_Bufer(void *buffer, int size); * -;* * -;* HISTORY: * -;* 10/26/1994 PWG : Created. * -;*=========================================================================* -*/ -extern "C" void __cdecl Set_Shape_Buffer(void const *buffer, int size) +struct ShapeHeaderStruct { - _ShapeBuffer = (unsigned char *)buffer; - _ShapeBufferSize = size; + uint16_t m_FrameCount; + uint16_t m_XPos; // In memory 0xDDD5 here indicates we have a keyframe slot allocated + uint16_t m_YPos; // Used in memory to hold keyframe slot + uint16_t m_Width; + uint16_t m_Height; + uint16_t m_LargestFrameSize; + uint16_t m_Flags; +}; + +struct ShapeBufferHeader +{ + uint32_t m_DrawFlags; + uint32_t m_FrameOffset; + BOOL m_IsTheaterShape; +}; + +extern "C" BOOL UseBigShapeBuffer; +extern unsigned BigShapeBufferLength; +extern unsigned TheaterShapeBufferLength; +extern bool OriginalUseBigShapeBuffer; + +extern "C" extern char* BigShapeBufferStart; +extern char* BigShapeBufferPtr; +// int TotalBigShapes = 0; +BOOL g_ReallocShapeBufferFlag; +extern "C" extern char* TheaterShapeBufferStart; +extern char* TheaterShapeBufferPtr; +int g_TotalTheaterShapes = 0; +uint32_t* g_KeyFrameSlots[1500]; +int g_TotalSlotsUsed = 0; +// int BuildFrameLength = 0; +extern "C" extern bool UseOldShapeDraw; +extern "C" char* _ShapeBuffer = nullptr; +long _ShapeBufferSize = 0; +int g_TheaterSlotsUsed = 1000; +int g_ShapeLength; + +// The predator effect basically just takes a destination pixel and replaces it +// with the value g_PredTable[g_PredFrame] pixels away if g_PartialCount +// is greater than or equal to 256. After every pixel, it is increased by +// g_PartialPred and reset to % 256 after reaching 256 or greater. +static const int16_t g_PredTable[8] = { 1, 3, 2, 5, 2, 3, 4, 1 }; +static uint32_t g_PredFrame; +static uint32_t g_PartialCount; +static uint32_t g_PartialPred; +static uint8_t* g_PredatorLimit = nullptr; + +// Buffer Frame to Page function pointer type defs +typedef void (*BF_Function)(int, int, uint8_t*, uint8_t*, int, int, uint8_t*, uint8_t*, uint8_t*, int); +typedef void (*Single_Line_Function)(int, uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*, int); + +// Just copy source to dest as is. +void BF_Copy(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + memcpy(dst, src, width); + dst = dst + dst_pitch + width; + src = src + src_pitch + width; + } } +// Index 0 transparency +void BF_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + *dst = sbyte; + } -#if (0) -global C ShapeBuffer :dword -global C ShapeBufferSize :dword -global C _ShapeBuffer :dword -global C _ShapeBufferSize :dword -global C Set_Shape_Buffer :near + ++dst; + } -DATASEG -label ShapeBuffer dword -_ShapeBuffer dd 0 + src += src_pitch; + dst += dst_pitch; + } +} -label ShapeBufferSize dword -_ShapeBufferSize dd 0 +// Fading table based shadow and transparency +void BF_Ghost(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + uint8_t fbyte = ghost_lookup[sbyte]; -CODESEG + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } -;*************************************************************************** -;* SET_SHAPE_BUFFER -- Sets the shape buffer to the given pointer * -;* * -;* This routine will set the shape buffer to the given value and make sure * -;* that the system does not try to compress any shapes that will be larger * -;* than the shape buffer. * -;* * -;* INPUT: void * - pointer to the shape buffer * -;* int - size of the buffer which has been passed in * -;* * -;* OUTPUT: none * -;* * -;* PROTO: VOID *Set_Shape_Bufer(void *buffer, int size); * -;* * -;* HISTORY: * -;* 10/26/1994 PWG : Created. * -;*=========================================================================* -GLOBAL C Set_Shape_Buffer:NEAR + *dst++ = sbyte; + } -PROC Set_Shape_Buffer C near - USES eax + src += src_pitch; + dst += dst_pitch; + } +} - ARG buff:DWORD - ARG size:DWORD +// Fading table based shadow and transparency with index 0 ignored +void BF_Ghost_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; - mov eax,[size] - mov [_ShapeBufferSize],eax + if (sbyte) { + uint8_t fbyte = ghost_lookup[sbyte]; - mov eax,[buff] - mov [_ShapeBuffer],eax - ret + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } - ENDP Set_Shape_Buffer -END + *dst = sbyte; + } -#endif \ No newline at end of file + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Fading(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src; + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } + } +} + +void BF_Fading_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Ghost_Fading(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Ghost_Fading_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, uint8_t* ghost_lookup, + uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + g_PartialCount += g_PartialPred; + + // if ( g_PartialCount & 0xFF00 ) { + // g_PartialCount &= 0xFFFF00FF; + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + *dst = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + ++dst; + } + + src += src_pitch + width; + dst += dst_pitch; + } +} + +void BF_Predator_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator_Ghost(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst++ = sbyte; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator_Ghost_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator_Fading(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } + } +} + +void BF_Predator_Fading_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator_Ghost_Fading(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +void BF_Predator_Ghost_Fading_Trans(int width, int height, uint8_t* dst, uint8_t* src, int dst_pitch, int src_pitch, + uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + while (height--) { + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } + + src += src_pitch; + dst += dst_pitch; + } +} + +// Jump table for BF_* functions +static const BF_Function OldShapeJumpTable[16] = { BF_Copy, + BF_Trans, + BF_Ghost, + BF_Ghost_Trans, + BF_Fading, + BF_Fading_Trans, + BF_Ghost_Fading, + BF_Ghost_Fading_Trans, + BF_Predator, + BF_Predator_Trans, + BF_Predator_Ghost, + BF_Predator_Ghost_Trans, + BF_Predator_Fading, + BF_Predator_Fading_Trans, + BF_Predator_Ghost_Fading, + BF_Predator_Ghost_Fading_Trans }; + +// Single line versions +void Single_Line_Skip( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ +} + +// This was Short_Single_Line_Copy, renamed for consistency +void Single_Line_Copy( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + memcpy(dst, src, width); +} + +void Single_Line_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Ghost( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Ghost_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Fading( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Fading_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Single_Fade( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + *dst++ = fade_tab[*src++]; + } +} + +void Single_Line_Single_Fade_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + *dst = fade_tab[sbyte]; + } + + ++dst; + } +} + +void Single_Line_Ghost_Fading( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Ghost_Fading_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Predator( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + g_PartialCount += g_PartialPred; + + // captainslog_dbgassert(g_PredFrame < 8, "Predator frame %u.\n", g_PredFrame); + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + *dst = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + ++dst; + } +} + +void Single_Line_Predator_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + // captainslog_dbgassert(g_PredFrame < 8, "Predator frame %u.\n", g_PredFrame); + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Predator_Ghost( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Predator_Ghost_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Predator_Fading( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Predator_Fading_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +void Single_Line_Predator_Ghost_Fading( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst++ = sbyte; + } +} + +void Single_Line_Predator_Ghost_Fading_Trans( + int width, uint8_t* dst, uint8_t* src, uint8_t* ghost_lookup, uint8_t* ghost_tab, uint8_t* fade_tab, int count) +{ + for (int i = width; i > 0; --i) { + uint8_t sbyte = *src++; + + if (sbyte) { + g_PartialCount += g_PartialPred; + + if (g_PartialCount >= 256) { + g_PartialCount %= 256; + + if (&dst[g_PredTable[g_PredFrame]] < g_PredatorLimit) { + sbyte = dst[g_PredTable[g_PredFrame]]; + } + + g_PredFrame = (g_PredFrame + 2) % 8; + } + + uint8_t fbyte = ghost_lookup[sbyte]; + + if (fbyte != 0xFF) { + sbyte = ghost_tab[*dst + fbyte * 256]; + } + + for (int i = 0; i < count; ++i) { + sbyte = fade_tab[sbyte]; + } + + *dst = sbyte; + } + + ++dst; + } +} + +// Jump table for Single_Line_* functions +static Single_Line_Function NewShapeJumpTable[32] = { Single_Line_Copy, + Single_Line_Trans, + Single_Line_Ghost, + Single_Line_Ghost_Trans, + Single_Line_Fading, + Single_Line_Fading_Trans, + Single_Line_Ghost_Fading, + Single_Line_Ghost_Fading_Trans, + Single_Line_Predator, + Single_Line_Predator_Trans, + Single_Line_Predator_Ghost, + Single_Line_Predator_Ghost_Trans, + Single_Line_Predator_Fading, + Single_Line_Predator_Fading_Trans, + Single_Line_Predator_Ghost_Fading, + Single_Line_Predator_Ghost_Fading_Trans, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip, + Single_Line_Skip }; + +// This one appears to deal with the buffered shape data +void* Get_Shape_Header_Data(void* shape) +{ + ShapeBufferHeader* header = static_cast(shape); + if (UseBigShapeBuffer) { + if (header->m_IsTheaterShape) { + return header->m_FrameOffset + TheaterShapeBufferStart; + } + else { + return header->m_FrameOffset + BigShapeBufferStart; + } + } + + return shape; +} + +int Get_Last_Frame_Length() +{ + return g_ShapeLength; +} + +void Reset_Theater_Shapes() +{ + // I think this loops through and deletes any slot that is > 1000 + if (g_TheaterSlotsUsed > 1000) { + for (int i = 1000; i < g_TheaterSlotsUsed; ++i) { + delete[] g_KeyFrameSlots[i]; + } + } + + TheaterShapeBufferPtr = TheaterShapeBufferStart; + g_TotalTheaterShapes = 0; + g_TheaterSlotsUsed = 1000; +} + +void Reallocate_Big_Shape_Buffer() +{ + { + // g_MemoryError = nullptr; + BigShapeBufferLength += BIGSHP_BUFFER_GROW; + BigShapeBufferPtr -= (intptr_t)BigShapeBufferStart; + BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength); + // captainslog_debug("Reallocating Big Shape Buffer, size is now %d.", BigShapeBufferLength); + // TODO + // g_MemoryError = Memory_Error_Handler; + if (BigShapeBufferStart) { + g_ReallocShapeBufferFlag = false; + BigShapeBufferPtr += (intptr_t)BigShapeBufferStart; + } + else { + UseBigShapeBuffer = false; + } + } +} + +void Disable_Uncompressed_Shapes() +{ + UseBigShapeBuffer = false; +} + +void Enable_Uncompressed_Shapes() +{ + UseBigShapeBuffer = OriginalUseBigShapeBuffer; +} + +void* Build_Frame2(void* shape, uint16_t frame, void* buffer) +{ + uint8_t* shape_data = static_cast(shape); + // frame = frame; + g_ShapeLength = 0; + + if (shape == nullptr || buffer == nullptr) { + return nullptr; + } + + ShapeHeaderStruct* header = static_cast(shape); + if (frame >= le16toh(header->m_FrameCount)) { + // captainslog_debug( + // "Requested frame %d is greater than total frames %d in this shape file.\n", frame, + // le16toh(header->m_FrameCount)); + + return nullptr; + } + + // If we are using a cache + if (UseBigShapeBuffer) { + if (!BigShapeBufferStart) { + // captainslog_debug("Allocating buffers for UseBigShapeBuffer."); + BigShapeBufferStart = static_cast(Alloc(BigShapeBufferLength, MEM_NORMAL)); + BigShapeBufferPtr = BigShapeBufferStart; + TheaterShapeBufferStart = static_cast(Alloc(TheaterShapeBufferLength, MEM_NORMAL)); + TheaterShapeBufferPtr = TheaterShapeBufferStart; + } + + if (BigShapeBufferLength + (uintptr_t)BigShapeBufferStart - (uintptr_t)BigShapeBufferPtr + < BIGSHP_BUFFER_MIN_FREE) { + g_ReallocShapeBufferFlag = true; + } + + // Do we have a keyframe slot allocated already? + if (header->m_XPos != 0xDDD5) { + header->m_XPos = 0xDDD5; + if (IsTheaterShape) { + header->m_YPos = g_TheaterSlotsUsed++; + } + else { + header->m_YPos = g_TotalSlotsUsed++; + } + + g_KeyFrameSlots[header->m_YPos] = new uint32_t[header->m_FrameCount]; + memset(g_KeyFrameSlots[header->m_YPos], 0, sizeof(uint32_t) * header->m_FrameCount); + } + + // Do we have anything in our keyframe slot yet? If so, return it. + uint32_t shp_buff_offset = g_KeyFrameSlots[header->m_YPos][frame]; + if (shp_buff_offset != 0) { + // captainslog_debug("Using Cached frame."); + + if (IsTheaterShape) { + return shp_buff_offset + TheaterShapeBufferStart; + } + else { + return shp_buff_offset + BigShapeBufferStart; + } + } + } + + // If we don't have a cache or failed to find a cached image for this frame, we need to decode the frame we want. + uint32_t offset_buff[7]; + int frame_size = le16toh(header->m_Height) * le16toh(header->m_Width); + memcpy(offset_buff, &shape_data[8 * frame + sizeof(ShapeHeaderStruct)], 12); + uint8_t frame_type = (le32toh(offset_buff[0]) & 0xFF000000) >> 24; + + if (frame_type & SHP_LCW_FRAME) { + // captainslog_debug("Decoding key frame."); + uint8_t* frame_data = &shape_data[le32toh(offset_buff[0]) & 0xFFFFFF]; + + // Amazingly it seems that shp files actually do support having a pal, just none do. + if (header->m_Flags & SHP_HAS_PAL) { + frame_data = &shape_data[(le32toh(offset_buff[0]) & 0xFFFFFF) + 768]; + } + + frame_size = LCW_Uncomp(frame_data, buffer, frame_size); + } + else { + // captainslog_debug("Decoding XOR frame."); + int ref_frame = 0; + // If we have an Xor chain, load first delta address into buffer + if (frame_type & SHP_XOR_PREV_FRAME) { + ref_frame = le32toh(offset_buff[1]) & 0xFFFF; + memcpy(offset_buff, &shape_data[8 * ref_frame + sizeof(ShapeHeaderStruct)], 28); + } + + // Get the base LCW data and the offset from it to the Xor data + int base_m_FrameOffset = offset_buff[1] & 0xFFFFFF; + int xor_data_offset = (le32toh(offset_buff[0]) & 0xFFFFFF) - (le32toh(offset_buff[1]) & 0xFFFFFF); + char* lcw_data = (char *)&shape_data[le32toh(offset_buff[1]) & 0xFFFFFF]; + + if (header->m_Flags & SHP_HAS_PAL) { + lcw_data = (char*)&shape_data[(le32toh(offset_buff[1]) & 0xFFFFFF) + 768]; + } + + if (LCW_Uncomp(lcw_data, buffer, frame_size) > frame_size) { + // captainslog_debug("LCW decompressed more data than expected."); + return nullptr; + } + + Apply_XOR_Delta((char*)buffer, lcw_data + xor_data_offset); + + if (frame_type & SHP_XOR_PREV_FRAME) { + // captainslog_debug("Decoding delta sequence."); + ++ref_frame; + int offset_index = 2; + + while (ref_frame <= frame) { + Apply_XOR_Delta((char *)buffer, &lcw_data[(le32toh(offset_buff[offset_index]) & 0xFFFFFF) - base_m_FrameOffset]); + ++ref_frame; + offset_index += 2; + + if (offset_index >= 6 && ref_frame <= frame) { + offset_index = 0; + memcpy(offset_buff, &shape_data[8 * ref_frame + sizeof(ShapeHeaderStruct)], 28); + } + } + } + } + + // This bit handles if we have a shape buffer to cache the decompressed frames + ShapeBufferHeader* buff_header = nullptr; + + if (UseBigShapeBuffer) { + if (IsTheaterShape) { + char* saved_tsbp = TheaterShapeBufferPtr; + // Why height? I don't get it? Anyhow, this bit is aligning the memory + // Ahh, Buffer_Frame_To_Page writes flags into the extra area + // for how each line is to be processed. + char* aligned_tsbp = TheaterShapeBufferPtr + header->m_Height + sizeof(ShapeBufferHeader); + + // Align memory pointer + uintptr_t align = (uintptr_t)aligned_tsbp; + + if ((align % sizeof(void*)) != 0) { + align += sizeof(void*) - (align % sizeof(void*)); + } + + aligned_tsbp = (char*)align; + + memcpy(aligned_tsbp, buffer, frame_size); + buff_header = reinterpret_cast(TheaterShapeBufferPtr); + buff_header->m_DrawFlags = -1; + buff_header->m_IsTheaterShape = true; + buff_header->m_FrameOffset = aligned_tsbp - TheaterShapeBufferStart; + g_KeyFrameSlots[header->m_YPos][frame] = TheaterShapeBufferPtr - TheaterShapeBufferStart; + TheaterShapeBufferPtr = aligned_tsbp + frame_size; + + // Align memory pointer + align = (uintptr_t)TheaterShapeBufferPtr; + if ((align % sizeof(void*)) != 0) { + align += sizeof(void*) - (align % sizeof(void*)); + } + TheaterShapeBufferPtr = (char*)align; + + g_ShapeLength = frame_size; + + return saved_tsbp; + } + else { + char* saved_bsbp = BigShapeBufferPtr; + char* aligned_bsbp = BigShapeBufferPtr + header->m_Height + sizeof(ShapeBufferHeader); + + // Align memory pointer + uintptr_t align = (uintptr_t)aligned_bsbp; + + if ((align % sizeof(void*)) != 0) { + align += sizeof(void*) - (align % sizeof(void*)); + } + + aligned_bsbp = (char*)align; + + memcpy(aligned_bsbp, buffer, frame_size); + buff_header = reinterpret_cast(BigShapeBufferPtr); + buff_header->m_DrawFlags = -1; + buff_header->m_IsTheaterShape = false; + buff_header->m_FrameOffset = aligned_bsbp - BigShapeBufferStart; + g_KeyFrameSlots[header->m_YPos][frame] = BigShapeBufferPtr - BigShapeBufferStart; + BigShapeBufferPtr = aligned_bsbp + frame_size; + + // Align memory pointer + align = (uintptr_t)BigShapeBufferPtr; + + if ((align % sizeof(void*)) != 0) { + align += sizeof(void*) - (align % sizeof(void*)); + } + + BigShapeBufferPtr = (char*)align; + + g_ShapeLength = frame_size; + return saved_bsbp; + } + } + + return buffer; +} + +unsigned long Build_Frame(void const* dataptr, unsigned short framenumber, void* buffptr) { + UseBigShapeBuffer = false; + return (unsigned long)Build_Frame2((void *)dataptr, framenumber, buffptr); // 32 bit to 64 bit issue +} + +unsigned short Get_Build_Frame_Count(void* shape) +{ + if (shape != nullptr) { + return static_cast(shape)->m_FrameCount; + } + + return 0; +} + +unsigned short Get_Build_Frame_X(void* shape) +{ + if (shape != nullptr) { + return static_cast(shape)->m_XPos; + } + + return 0; +} + +unsigned short Get_Build_Frame_Y(void* shape) +{ + if (shape != nullptr) { + return static_cast(shape)->m_YPos; + } + + return 0; +} + +unsigned short Get_Build_Frame_Width(void* shape) +{ + if (shape != nullptr) { + return static_cast(shape)->m_Width; + } + + return 0; +} + +unsigned short Get_Build_Frame_Height(void* shape) +{ + if (shape != nullptr) { + return static_cast(shape)->m_Height; + } + + return 0; +} + +// This would handle a shp file with a palette, RA doesn't actually have any that +// have this though. +BOOL Get_Build_Frame_Palette(void* shape, void* pal) +{ + ShapeHeaderStruct* header = static_cast(shape); + + if (shape && header->m_Flags & SHP_HAS_PAL) { + // calc offset to palette + memcpy(pal, static_cast(shape) + 8 * header->m_FrameCount + sizeof(ShapeHeaderStruct), 768); + + return true; + } + + return false; +} + +extern "C" void Set_Shape_Buffer(const void* buffer, int size) +{ + _ShapeBuffer = (char *)(buffer); + _ShapeBufferSize = size; +} + +int Set_Shape_Height(void* shape, unsigned short new_height) +{ + int oldheight = static_cast(shape)->m_Height; + static_cast(shape)->m_Height = new_height; + return oldheight; +} + +// Used by Buffer_Frame_To_Page to flag which blit function to use for each line +// Results are cached for subsequent draw calls. +static void Single_Line_Flagger( + int width, int height, void* frame, void* draw_header, int flags, void* ghost_tab, void* ghost_lookup) +{ + uint8_t* shape_src; + uint8_t* flag_dst; + uint8_t tmp_flags; + int current_byte; + uint8_t has_skipped; + uint8_t row_flags; + int skipped; + + shape_src = static_cast(frame); + ShapeBufferHeader* header = static_cast(draw_header); + header->m_DrawFlags = flags & 0x1340; + flag_dst = static_cast(draw_header) + sizeof(ShapeBufferHeader); + uint8_t* ghost = static_cast(ghost_lookup); + + for (int i = height; i > 0; --i) { + tmp_flags = 0; + skipped = 0; + for (int j = width; j > 0; --j) { + current_byte = *shape_src++; + + if (current_byte || !(flags & SHAPE_TRANSPARENT)) { + if (flags & SHAPE_PREDATOR) { + tmp_flags |= 8; + } + + if (flags & SHAPE_GHOST && ghost[current_byte] != 0xFF) { + tmp_flags |= 2; + } + + if (flags & SHAPE_FADING) { + tmp_flags |= 4; + } + } + else { + tmp_flags |= 1; + ++skipped; + } + } + + has_skipped = 0; + + if (tmp_flags & 1 && (has_skipped = 1, width == skipped)) { + row_flags = 0x10; + } + else { + row_flags = (tmp_flags & 4) | (tmp_flags & 2) | (tmp_flags & 8) | has_skipped; + } + + *flag_dst++ = row_flags; + } +} + +long Buffer_Frame_To_Page(int x, int y, int width, int height, void* shape, GraphicViewPortClass& viewport, int flags, ...) +{ + BOOL use_old_drawer = false; + int fade_count = 0; + ShapeBufferHeader* draw_header = nullptr; + uint8_t* fade_table = nullptr; + uint8_t* ghost_table = nullptr; + uint8_t* ghost_lookup = nullptr; + + if (!shape) { + return 0; + } + + uint8_t* frame_data = static_cast(shape); + + if (UseOldShapeDraw) { + use_old_drawer = true; + } + else if (UseBigShapeBuffer) { + draw_header = static_cast(shape); + uint8_t* shape_buff = reinterpret_cast(BigShapeBufferStart); + + if (draw_header->m_IsTheaterShape) { + shape_buff = reinterpret_cast(TheaterShapeBufferStart); + } + + frame_data = shape_buff + draw_header->m_FrameOffset; + use_old_drawer = false; + } + + va_list ap; + va_start(ap, flags); + + int blit_style = 0; + + if (flags & SHAPE_CENTER) { + x -= width / 2; + y -= height / 2; + } + + // Sets for BF_Trans functions + if (flags & SHAPE_TRANSPARENT) { + blit_style |= 1; + } + + // Sets for BF_Ghost functions + if (flags & SHAPE_GHOST) { + blit_style |= 2; + ghost_lookup = va_arg(ap, uint8_t*); + ghost_table = ghost_lookup + 256; + } + + if (!UseBigShapeBuffer || UseOldShapeDraw) { + use_old_drawer = true; + } + + if (use_old_drawer != true && (draw_header->m_DrawFlags == 0xFFFFFFFF || draw_header->m_DrawFlags != (flags & 0x1340))) { + Single_Line_Flagger(width, height, frame_data, draw_header, flags, ghost_table, ghost_lookup); + } + + // Sets for BF_Fading functions + if (flags & SHAPE_FADING) { + fade_table = va_arg(ap, uint8_t*); + fade_count = va_arg(ap, int) & 0x3F; + blit_style |= 4; + + if (!fade_count) { + flags &= ~SHAPE_FADING; + } + + // s_Special blitters for if fade step count is only 1 + NewShapeJumpTable[4] = Single_Line_Single_Fade; + NewShapeJumpTable[5] = Single_Line_Single_Fade_Trans; + + if (fade_count != 1) { + NewShapeJumpTable[4] = Single_Line_Fading; + NewShapeJumpTable[5] = Single_Line_Fading_Trans; + } + } + + // Sets for BF_Predator functions + if (flags & SHAPE_PREDATOR) { + int current_frame = va_arg(ap, uint32_t); + blit_style |= 8; + + g_PredFrame = ((unsigned)current_frame) % 8; + g_PartialCount = 0; + g_PartialPred = 256; + + // Calculates the end of the visible display buffer, hopefully prevent crashes from predator effect. + // Unused by default in RA, but would be nice on the phase tank in Aftermath. + g_PredatorLimit = (uint8_t*)(viewport.Get_Offset()) + viewport.Get_Full_Pitch() * viewport.Get_Height(); + } + + if (flags & SHAPE_PARTIAL) { + g_PartialPred = va_arg(ap, int) & 0xFF; + } + + va_end(ap); + + int xstart = x; + int ystart = y; + int yend = y + height - 1; + int xend = x + width - 1; + int ms_img_offset = 0; + + // If we aren't drawing within the viewport, return. + if (xstart >= viewport.Get_Width() || ystart >= viewport.Get_Height() || xend <= 0 || yend <= 0) { + return 0; + } + + // Do any needed clipping. + if (xstart < 0) { + ms_img_offset = -xstart; + xstart = 0; + use_old_drawer = true; + } + + if (ystart < 0) { + frame_data += width * (-ystart); + ystart = 0; + use_old_drawer = true; + } + + if (xend >= viewport.Get_Width() - 1) { + xend = viewport.Get_Width() - 1; + use_old_drawer = true; + } + + if (yend >= viewport.Get_Height() - 1) { + yend = viewport.Get_Height() - 1; + use_old_drawer = true; + } + + int blit_width = xend - xstart + 1; + int blit_height = yend - ystart + 1; + + int pitch = viewport.Get_Full_Pitch(); + uint8_t* dst = ystart * pitch + xstart + (uint8_t*)(viewport.Get_Offset()); + uint8_t* src = frame_data + ms_img_offset; + int dst_pitch = pitch - blit_width; + int src_pitch = width - blit_width; + + // Use "new" line drawing routines that appear to have been added during the windows port. + if (use_old_drawer != true) { + // DEBUG_SAY("Drawing with Single_Line draw functions\n"); + + // Here we can use the individual line drawing routines + // Means we can skip drawing some lines all together or avoid using + // more expensive routines on some lines. + uint8_t* line_flags = reinterpret_cast(draw_header + 1); + + for (int i = 0; i < blit_height; ++i) { + NewShapeJumpTable[line_flags[i] & 0x1F](blit_width, dst, src, ghost_lookup, ghost_table, fade_table, fade_count); + src += width; + dst += pitch; + } + + return 0; + } + + // Here we just use the function that will blit the entire frame + // using the appropriate effects. + if (blit_height > 0 && blit_width > 0) { + // DEBUG_SAY("Drawing with BF draw functions\n"); + OldShapeJumpTable[blit_style & 0xF]( + blit_width, blit_height, dst, src, dst_pitch, src_pitch, ghost_lookup, ghost_table, fade_table, fade_count); + } + + return 0; +} diff --git a/REDALERT/WIN32LIB/DRAWBUFF.H b/REDALERT/WIN32LIB/DRAWBUFF.H index 1b08216..f30e477 100644 --- a/REDALERT/WIN32LIB/DRAWBUFF.H +++ b/REDALERT/WIN32LIB/DRAWBUFF.H @@ -28,6 +28,8 @@ class GraphicBufferClass; /* Define functions which have not under-gone name mangling */ /*=========================================================================*/ +long __cdecl Buffer_To_Buffer(GraphicViewPortClass* vp, int x, int y, int w, int h, void* buffer, int length); + extern "C" { /*======================================================================*/ /* Externs for all of the common functions between the video buffer */ @@ -38,7 +40,6 @@ extern "C" { void __cdecl Buffer_Put_Pixel(void * thisptr, int x, int y, unsigned char color); int __cdecl Buffer_Get_Pixel(void * thisptr, int x, int y); void __cdecl Buffer_Clear(void *thisptr, unsigned char color); - long __cdecl Buffer_To_Buffer(void *thisptr, int x, int y, int w, int h, void *buff, long size); long __cdecl Buffer_To_Page(int x, int y, int w, int h, void *Buffer, void *view); BOOL __cdecl Linear_Blit_To_Linear( void *thisptr, void * dest, int x_pixel, int y_pixel, int dx_pixel, int dy_pixel, int pixel_width, int pixel_height, BOOL trans); diff --git a/REDALERT/WIN32LIB/LCWCOMP.ASM b/REDALERT/WIN32LIB/LCWCOMP.ASM deleted file mode 100644 index 1c3e639..0000000 --- a/REDALERT/WIN32LIB/LCWCOMP.ASM +++ /dev/null @@ -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 diff --git a/REDALERT/WIN32LIB/LCWUNCMP.ASM b/REDALERT/WIN32LIB/LCWUNCMP.ASM deleted file mode 100644 index d7a7298..0000000 --- a/REDALERT/WIN32LIB/LCWUNCMP.ASM +++ /dev/null @@ -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 diff --git a/REDALERT/WIN32LIB/TOBUFF.ASM b/REDALERT/WIN32LIB/TOBUFF.ASM deleted file mode 100644 index b210cf3..0000000 --- a/REDALERT/WIN32LIB/TOBUFF.ASM +++ /dev/null @@ -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 \ No newline at end of file diff --git a/REDALERT/WIN32LIB/TOBUFF.CPP b/REDALERT/WIN32LIB/TOBUFF.CPP new file mode 100644 index 0000000..ff729e8 --- /dev/null +++ b/REDALERT/WIN32LIB/TOBUFF.CPP @@ -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 +#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; +}