; ; Command & Conquer Red Alert(tm) ; Copyright 2025 Electronic Arts Inc. ; ; This program 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. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . ; ;*************************************************************************** ;** 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 ?? TRANSP equ 0 INCLUDE ".\drawbuff.inc" INCLUDE ".\gbuffer.inc" CODESEG ;*************************************************************************** ;* 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. * ;*=========================================================================* 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 , [ (GraphicViewPort esi) . 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,[ ( GraphicViewPort esi) . 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 , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register mov [ x1_pixel ] , eax ??scr_right_ok: test dl , 0001b jz ??do_blit mov eax , [ (GraphicViewPort esi) . GVPHeight ] ; get width into register mov [ y1_pixel ] , eax ??do_blit: cld mov eax , [ (GraphicViewPort esi) . GVPXAdd ] add eax , [ (GraphicViewPort esi) . GVPWidth ] add eax , [ (GraphicViewPort esi) . GVPPitch ] mov esi , [ (GraphicViewPort esi) . 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 END