| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- ;
- ; 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 <http://www.gnu.org/licenses/>.
- ;
- ;***************************************************************************
- ;** 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 : BITBLIT.ASM *
- ;* *
- ;* Programmer : Phil W. Gorrow *
- ;* *
- ;* Start Date : June 8, 1994 *
- ;* *
- ;* Last Update : December 13, 1994 [PWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- LOCALS ??
- INCLUDE "svgaprim.inc"
- INCLUDE "gbuffer.inc"
- TRANSP equ 0
- CODESEG
- ;***************************************************************************
- ;* GVC::BLIT -- Copies a buffer to a graphic page non-linearly *
- ;* *
- ;* NOTE: All coordinate values are expressed in pixels *
- ;* *
- ;* INPUT: VideoViewPortClass *dest - Video View Port to copy to *
- ;* WORD src_x - Src x position to copy from *
- ;* WORD src_y - Src y position to copy from *
- ;* WORD dst_x - Dest x position to copy to *
- ;* WORD dst_y - Dest y position to copy to *
- ;* WORD w - Width of region to copy *
- ;* WORD h - Height of region to copy *
- ;* *
- ;* 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. *
- ;* *
- ;* HISTORY: *
- ;* 05/11/1994 PWG : Created. *
- ;* 08/05/1994 PWG : Fixed clipping problem *
- ;*=========================================================================*
- PROC Linear_Blit_To_Vesa C near
- USES ebx,ecx,edx,esi,edi
- ;*===================================================================
- ;* define the arguements that our function takes.
- ;*===================================================================
- ARG this :DWORD ; this is a member function
- ARG dest :DWORD ; what are we blitting to
- ARG x_pixel :DWORD ; x pixel position in source
- ARG y_pixel :DWORD ; y pixel position in source
- ARG dest_x0 :dword
- ARG dest_y0 :dword
- ARG pixel_width :DWORD ; width of rectangle to blit
- ARG pixel_height:DWORD ; height of rectangle to blit
- ARG trans :DWORD ; do we deal with transparents?
- ;*===================================================================
- ; 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 scr_ajust_width:DWORD
- LOCAL dest_ajust_width:DWORD
- LOCAL source_area : dword
- LOCAL dest_area : dword
- ; Clip Source Rectangle against source Window boundaries.
- mov esi , [ this ] ; get ptr to src
- xor ecx , ecx
- xor edx , edx
- mov edi , [ (VideoViewPort esi) . VIVPWidth ] ; 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,[ ( VideoViewPort esi) . VIVPHeight ] ; 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 ??clip_against_dest
- test cl , 1000b
- jz ??scr_left_ok
- mov [ x_pixel ] , 0
- ??scr_left_ok:
- test cl , 0010b
- jz ??scr_bottom_ok
- mov [ y_pixel ] , 0
- ??scr_bottom_ok:
- test dl , 0100b
- jz ??scr_right_ok
- mov eax , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
- mov [ x1_pixel ] , eax
- ??scr_right_ok:
- test dl , 0001b
- jz ??clip_against_dest
- mov eax , [ (VideoViewPort esi) . VIVPHeight ] ; get width into register
- mov [ y1_pixel ] , eax
- ; Clip Source Rectangle against destination Window boundaries.
- ??clip_against_dest:
- mov eax , [ dest_x0 ]
- mov ebx , [ dest_y0 ]
- sub eax , [ x_pixel ]
- sub ebx , [ y_pixel ]
- add eax , [ x1_pixel ]
- add ebx , [ y1_pixel ]
- mov [ dest_x1 ] , eax
- mov [ dest_y1 ] , ebx
- mov esi , [ dest ] ; get ptr to src
- xor ecx , ecx
- xor edx , edx
- mov edi , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
- mov eax , [ dest_x0 ]
- mov ebx , [ dest_x1 ]
- shld ecx , eax , 1
- inc edi
- shld edx , ebx , 1
- sub eax , edi
- sub ebx , edi
- shld ecx , eax , 1
- shld edx , ebx , 1
- mov edi,[ ( VideoViewPort esi) . VIVPHeight ] ; get height into register
- mov eax , [ dest_y0 ]
- mov ebx , [ dest_y1 ]
- shld ecx , eax , 1
- 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 ??dest_left_ok
- mov eax , [ dest_x0 ]
- mov [ dest_x0 ] , 0
- sub [ x_pixel ] , eax
- ??dest_left_ok:
- test cl , 0010b
- jz ??dest_bottom_ok
- mov eax , [ dest_y0 ]
- mov [ dest_y0 ] , 0
- sub [ y_pixel ] , eax
- ??dest_bottom_ok:
- test dl , 0100b
- jz ??dest_right_ok
- mov ebx , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
- mov eax , [ dest_x1 ]
- mov [ dest_x1 ] , ebx
- sub eax , ebx
- sub [ x1_pixel ] , eax
- ??dest_right_ok:
- test dl , 0001b
- jz ??do_blit
- mov ebx , [ (VideoViewPort esi) . VIVPHeight ] ; get width into register
- mov eax , [ dest_y1 ]
- mov [ dest_y1 ] , ebx
- sub eax , ebx
- sub [ y1_pixel ] , eax
- ??do_blit:
- cld
- mov ebx , [ this ]
- mov esi , [ (VideoViewPort ebx) . VIVPOffset ]
- mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
- add eax , [ (VideoViewPort ebx) . VIVPWidth ]
- mov ecx , eax
- mul [ y_pixel ]
- add esi , [ x_pixel ]
- mov [ source_area ] , ecx
- add esi , eax
- add ecx , [ x_pixel ]
- sub ecx , [ x1_pixel ]
- mov [ scr_ajust_width ] , ecx
- mov ebx , [ dest ]
- mov edi , [ (VideoViewPort ebx) . VIVPOffset ]
- mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
- add eax , [ (VideoViewPort ebx) . VIVPWidth ]
- mov ecx , eax
- mul [ dest_y0 ]
- add edi , [ dest_x0 ]
- mov [ dest_area ] , ecx
- add edi , eax
- Call Vesa_Asm_Set_Win ; set the window
- mov eax , [ dest_x1 ]
- sub eax , [ dest_x0 ]
- jz ??real_out
- sub ecx , eax
- mov [ dest_ajust_width ] , ecx
- mov edx , [ dest_y1 ]
- sub edx , [ dest_y0 ]
- jz ??real_out
- ; ********************************************************************
- ; Forward bitblit only
- IF TRANSP
- test [ trans ] , 1
- 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:
- lea ebx , [ edi + eax ]
- add ebx , [ cpu_video_page ]
- cmp ebx , [ cpu_page_limit ]
- jl ??in_range
- xor ecx , ecx
- mov ebx , eax
- cmp edi , 0b0000h
- jge ??no_trailing
- mov ecx , 0b0000h
- sub ecx , edi
- sub ebx , ecx
- rep movsb
- ??no_trailing:
- add edi , [ cpu_video_page ]
- Call Vesa_Asm_Set_Win ; set the window
- mov ecx , ebx
- rep movsb
- add esi , [ scr_ajust_width ]
- add edi , [ dest_ajust_width ]
- dec edx ; decrement the height
- jnz ??forward_loop_dword
- ret
- ??in_range:
- 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:
- lea ebx , [ edi + eax ]
- add ebx , [ cpu_video_page ]
- cmp ebx , [ cpu_page_limit ]
- mov ebx , eax
- jl ??in_range_bytes
- xor ecx , ecx
- cmp edi , 0b0000h
- jge ??no_trailing_bytes
- mov ecx , 0b0000h
- sub ecx , edi
- sub ebx , ecx
- rep movsb
- ??no_trailing_bytes:
- add edi , [ cpu_video_page ]
- Call Vesa_Asm_Set_Win ; set the window
- ??in_range_bytes:
- mov ecx , ebx
- 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 Linear_Blit_To_Vesa
- END
|