SHADOW.ASM 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ; $Header: g:/library/source/rcs/./shadow.asm 1.9 1994/05/20 15:30:49 joe_bostic Exp $
  19. ;***************************************************************************
  20. ;** 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 **
  21. ;***************************************************************************
  22. ;* *
  23. ;* Project Name : LIBRARY *
  24. ;* *
  25. ;* File Name : SHADOW.ASM *
  26. ;* *
  27. ;* Programmer : Christopher Yates *
  28. ;* *
  29. ;* Last Update : February 28, 1995 [BG] *
  30. ;* *
  31. ;*-------------------------------------------------------------------------*
  32. ;* Functions: *
  33. ;* *
  34. ;* void Shadow_Blit(int xpix, int ypix, int width, int height, GVPC src, GVPC dst, void *shadowbuff);
  35. ;* *
  36. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  37. IDEAL
  38. P386
  39. MODEL USE32 FLAT
  40. INCLUDE ".\drawbuff.inc"
  41. INCLUDE ".\gbuffer.inc"
  42. INCLUDE ".\keystruc.inc"
  43. GLOBAL C Shadow_Blit : NEAR
  44. GLOBAL C RealModePtr : DWORD
  45. GLOBAL C Hide_Mouse : NEAR
  46. GLOBAL C Show_Mouse : NEAR
  47. CODESEG
  48. ; void Shadow_Blit(int xpix, int ypix, int width, int height, GVPC src, VBC dst, void *shadowbuff);
  49. ; Warning: Shadow_Blit appears to be relatively stupid, in that while it is
  50. ; optimized to perform word or dword blits, it only does so if the
  51. ; entire region is word or dword-sized. In other words, if you blit
  52. ; a region that is 200 pixels wide (clearly dword-sized), then it
  53. ; will use the dword loop. However, if you blit a region that is
  54. ; 201 pixels wide, the dumb thing will use the byte loop for the
  55. ; entire blit.
  56. PROC Shadow_Blit C near
  57. USES eax,ebx,ecx,edx,esi,edi
  58. ARG x:DWORD
  59. ARG y:DWORD
  60. ARG region_width:DWORD
  61. ARG region_height:DWORD
  62. ARG srcpage:DWORD
  63. ARG dstpage:DWORD
  64. ARG shadow:DWORD
  65. LOCAL modulo:DWORD ; Row modulo
  66. LOCAL hidemouse:DWORD ; Was the mouse hidden?
  67. LOCAL dwordwidth:DWORD
  68. LOCAL bytewidth:DWORD
  69. cld ; Always move forward.
  70. mov [hidemouse],0 ; Presume mouse hasn't been hidden.
  71. ; Fetch the segment of the seenpage.
  72. mov ebx,[dstpage]
  73. mov ebx,[(GraphicViewPort ebx).GVPOffset]
  74. ; Determine if the mouse needs to be hidden at all. If this happens to be
  75. ; a shadow blit to non visible page (who knows why!?) then don't bother to
  76. ; hide the mouse since it isn't necessary.
  77. ; cmp ebx,0A0000h
  78. ; setne [BYTE PTR hidemouse] ; Flag that mouse need not be hidden.
  79. ; jne short ??itsok
  80. mov esi,[RealModePtr]
  81. cmp [(KeyboardType esi).MState],0
  82. je short ??itsok
  83. mov [hidemouse],1
  84. call Hide_Mouse C ; Hides mouse again (just to be sure).
  85. ??itsok:
  86. mov edi,[srcpage]
  87. mov esi,[(GraphicViewPort edi).GVPOffset]
  88. mov eax,[(GraphicViewPort edi).GVPWidth]
  89. add eax,[(GraphicViewPort edi).GVPXAdd]
  90. add eax,[(GraphicViewPort edi).GVPPitch]
  91. push eax ; save width+xadd for later calc
  92. mov edx,[y]
  93. mul edx
  94. add eax,[x]
  95. add esi,eax
  96. ; At this point, esi points to the source page and ebx points to the dest page
  97. sub ebx,esi ; esi+ebx == dest page pointer
  98. mov edi,[shadow] ; EDI points to shadow buffer.
  99. mov ecx,[region_height] ; get the height of the window in cx
  100. mov edx,[RealModePtr]
  101. ; Calculate the row add module.
  102. pop eax ; restore width+xadd
  103. sub eax,[region_width]
  104. mov [modulo],eax
  105. mov eax,[region_width]
  106. shr eax,2
  107. mov [dwordwidth],eax
  108. mov eax,[region_width]
  109. and eax,3
  110. mov [bytewidth],eax
  111. ;---------------------------------------
  112. ; DOUBLE WORD shadow blit if possible.
  113. ;---------------------------------------
  114. ??dloop_top:
  115. push ecx
  116. mov ecx,[dwordwidth]
  117. ??lcontinue:
  118. repe cmpsd ; check the entire row for changed longs
  119. je short ??loop_top
  120. ; If this row would interfere with the mouse image, then hide it.
  121. cmp [hidemouse],0
  122. jnz short ??dok
  123. mov eax,[(KeyboardType edx).MouseY]
  124. sub eax,[(KeyboardType edx).MouseYHot]
  125. cmp eax,[y]
  126. jg short ??dok
  127. add eax,[(KeyboardType edx).MouseHeight]
  128. cmp eax,[y]
  129. jb short ??dok
  130. mov [hidemouse],1 ; Manual hide of the mouse.
  131. call Hide_Mouse C
  132. ??dok:
  133. mov eax,[esi-4]
  134. mov [ebx+esi-4],eax ; Update destination page.
  135. mov [edi-4],eax ; Update shadow buffer.
  136. or ecx,ecx
  137. jne short ??lcontinue
  138. ;---------------------------------------
  139. ; Row loop start for BYTES.
  140. ;---------------------------------------
  141. ??loop_top:
  142. mov ecx,[bytewidth]
  143. ; Column loop start -- by bytes.
  144. ??continue:
  145. repe cmpsb ; check the entire row for changed longs
  146. je short ??done_x
  147. ; If this row would interfere with the mouse image, then hide it.
  148. cmp [hidemouse],0
  149. jnz short ??bok
  150. mov eax,[(KeyboardType edx).MouseY]
  151. sub eax,[(KeyboardType edx).MouseYHot]
  152. cmp eax,[y]
  153. jg short ??bok
  154. add eax,[(KeyboardType edx).MouseHeight]
  155. cmp eax,[y]
  156. jl short ??bok
  157. mov [hidemouse],1 ; Manual hide of the mouse.
  158. call Hide_Mouse C
  159. ??bok:
  160. mov al,[esi-1]
  161. mov [ebx+esi-1],al ; Update destination page.
  162. mov [edi-1],al ; Update shadow buffer.
  163. or ecx,ecx
  164. jne short ??continue
  165. ??done_x:
  166. inc [y]
  167. add esi,[modulo]
  168. pop ecx
  169. dec ecx
  170. jnz ??dloop_top
  171. ??fini:
  172. ; Re show the mouse if it was hidden by this routine.
  173. cmp [hidemouse],0
  174. je short ??reallyfini
  175. call Show_Mouse C
  176. ??reallyfini:
  177. ret
  178. ENDP Shadow_Blit
  179. END