FILLRECT.ASM 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. ;***************************************************************************
  19. ;** 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 **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : GraphicViewPortClass *
  23. ;* *
  24. ;* File Name : CLEAR.ASM *
  25. ;* *
  26. ;* Programmer : Phil Gorrow *
  27. ;* *
  28. ;* Start Date : June 7, 1994 *
  29. ;* *
  30. ;* Last Update : June 7, 1994 [PWG] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* GVPC::Fill_Rect -- draws a filled rectangle to a graphics buffer *
  35. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  36. IDEAL
  37. P386
  38. MODEL USE32 FLAT
  39. INCLUDE ".\drawbuff.inc"
  40. INCLUDE ".\gbuffer.inc"
  41. CODESEG
  42. ;***************************************************************************
  43. ;* GVPC::FILL_RECT -- Fills a rectangular region of a graphic view port *
  44. ;* *
  45. ;* INPUT: WORD the left hand x pixel position of region *
  46. ;* WORD the upper x pixel position of region *
  47. ;* WORD the right hand x pixel position of region *
  48. ;* WORD the lower x pixel position of region *
  49. ;* UBYTE the color (optional) to clear the view port to *
  50. ;* *
  51. ;* OUTPUT: none *
  52. ;* *
  53. ;* NOTE: This function is optimized to handle viewport with no XAdd *
  54. ;* value. It also handles DWORD aligning the destination *
  55. ;* when speed can be gained by doing it. *
  56. ;* HISTORY: *
  57. ;* 06/07/1994 PWG : Created. *
  58. ;*=========================================================================*
  59. PROC Buffer_Fill_Rect C near
  60. USES eax,ebx,ecx,edx,esi,edi,ebp
  61. ;*===================================================================
  62. ;* define the arguements that our function takes.
  63. ;*===================================================================
  64. ARG this_object:DWORD ; this is a member function
  65. ARG x1_pixel:WORD
  66. ARG y1_pixel:WORD
  67. ARG x2_pixel:WORD
  68. ARG y2_pixel:WORD
  69. ARG color:BYTE ; what color should we clear to
  70. ;*===================================================================
  71. ; Define some locals so that we can handle things quickly
  72. ;*===================================================================
  73. LOCAL VPwidth:DWORD ; the width of the viewport
  74. LOCAL VPheight:DWORD ; the height of the viewport
  75. LOCAL VPxadd:DWORD ; the additional x offset of viewport
  76. LOCAL VPbpr:DWORD ; the number of bytes per row of viewport
  77. ;*===================================================================
  78. ;* save off the viewport characteristics on the stack
  79. ;*===================================================================
  80. mov ebx,[this_object] ; get a pointer to viewport
  81. mov eax,[(GraphicViewPort ebx).GVPWidth] ; get width from viewport
  82. mov ecx,[(GraphicViewPort ebx).GVPHeight] ; get height from viewport
  83. mov edx,[(GraphicViewPort ebx).GVPXAdd] ; get xadd from viewport
  84. add edx,[(GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface
  85. mov [VPwidth],eax ; store the width of locally
  86. mov [VPheight],ecx
  87. mov [VPxadd],edx
  88. add eax,edx
  89. mov [VPbpr],eax
  90. ;*===================================================================
  91. ;* move the important parameters into local registers
  92. ;*===================================================================
  93. movsx eax,[x1_pixel]
  94. movsx ebx,[y1_pixel]
  95. movsx ecx,[x2_pixel]
  96. movsx edx,[y2_pixel]
  97. ;*===================================================================
  98. ;* Convert the x2 and y2 pixel to a width and height
  99. ;*===================================================================
  100. cmp eax,ecx
  101. jl ??no_swap_x
  102. xchg eax,ecx
  103. ??no_swap_x:
  104. sub ecx,eax
  105. cmp ebx,edx
  106. jl ??no_swap_y
  107. xchg ebx,edx
  108. ??no_swap_y:
  109. sub edx,ebx
  110. inc ecx
  111. inc edx
  112. ;*===================================================================
  113. ;* Bounds check source X.
  114. ;*===================================================================
  115. cmp eax, [VPwidth] ; compare with the max
  116. jge ??out ; starts off screen, then later
  117. jb short ??sx_done ; if it's not negative, it's ok
  118. ;------ Clip source X to left edge of screen.
  119. add ecx, eax ; Reduce width (add in negative src X).
  120. xor eax, eax ; Clip to left of screen.
  121. ??sx_done:
  122. ;*===================================================================
  123. ;* Bounds check source Y.
  124. ;*===================================================================
  125. cmp ebx, [VPheight] ; compare with the max
  126. jge ??out ; starts off screen, then later
  127. jb short ??sy_done ; if it's not negative, it's ok
  128. ;------ Clip source Y to top edge of screen.
  129. add edx, ebx ; Reduce height (add in negative src Y).
  130. xor ebx, ebx ; Clip to top of screen.
  131. ??sy_done:
  132. ;*===================================================================
  133. ;* Bounds check width versus width of source and dest view ports
  134. ;*===================================================================
  135. push ebx ; save off ebx for later use
  136. mov ebx,[VPwidth] ; get the source width
  137. sub ebx, eax ; Maximum allowed pixel width (given coordinates).
  138. sub ebx, ecx ; Pixel width undershoot.
  139. jns short ??width_ok ; if not signed no adjustment necessary
  140. add ecx, ebx ; Reduce width to screen limits.
  141. ??width_ok:
  142. pop ebx ; restore ebx to old value
  143. ;*===================================================================
  144. ;* Bounds check height versus height of source view port
  145. ;*===================================================================
  146. push eax ; save of eax for later use
  147. mov eax, [VPheight] ; get the source height
  148. sub eax, ebx ; Maximum allowed pixel height (given coordinates).
  149. sub eax, edx ; Pixel height undershoot.
  150. jns short ??height_ok ; if not signed no adjustment necessary
  151. add edx, eax ; Reduce height to screen limits.
  152. ??height_ok:
  153. pop eax ; restore eax to old value
  154. ;*===================================================================
  155. ;* Perform the last minute checks on the width and height
  156. ;*===================================================================
  157. or ecx,ecx
  158. jz ??out
  159. or edx,edx
  160. jz ??out
  161. cmp ecx,[VPwidth]
  162. ja ??out
  163. cmp edx,[VPheight]
  164. ja ??out
  165. ;*===================================================================
  166. ;* Get the offset into the virtual viewport.
  167. ;*===================================================================
  168. xchg edi,eax ; save off the contents of eax
  169. xchg esi,edx ; and edx for size test
  170. mov eax,ebx ; move the y pixel into eax
  171. mul [VPbpr] ; multiply by bytes per row
  172. add edi,eax ; add the result into the x position
  173. mov ebx,[this_object]
  174. add edi,[(GraphicViewPort ebx).GVPOffset]
  175. mov edx,esi ; restore edx back to real value
  176. mov eax,ecx ; store total width in ecx
  177. sub eax,[VPwidth] ; modify xadd value to include clipped
  178. sub [VPxadd],eax ; width bytes (subtract a negative number)
  179. ;*===================================================================
  180. ; Convert the color byte to a DWORD for fast storing
  181. ;*===================================================================
  182. mov al,[color] ; get color to clear to
  183. mov ah,al ; extend across WORD
  184. mov ebx,eax ; extend across DWORD in
  185. shl eax,16 ; several steps
  186. mov ax,bx
  187. ;*===================================================================
  188. ; If there is no row offset then adjust the width to be the size of
  189. ; the entire viewport and adjust the height to be 1
  190. ;*===================================================================
  191. mov esi,[VPxadd]
  192. or esi,esi ; set the flags for esi
  193. jnz ??row_by_row_aligned ; and act on them
  194. xchg eax,ecx ; switch bit pattern and width
  195. mul edx ; multiply by edx to get size
  196. xchg eax,ecx ; switch size and bit pattern
  197. mov edx,1 ; only 1 line off view port size to do
  198. ;*===================================================================
  199. ; Find out if we should bother to align the row.
  200. ;*===================================================================
  201. ??row_by_row_aligned:
  202. mov ebp,ecx ; width saved in ebp
  203. cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them?
  204. jl ??row_by_row ; if not then skip
  205. ;*===================================================================
  206. ; Figure out the alignment offset if there is any
  207. ;*===================================================================
  208. mov ebx,edi ; get output position
  209. and ebx,3 ; is there a remainder?
  210. jz ??aligned_loop ; if not we are aligned
  211. xor ebx,3 ; find number of align bytes
  212. inc ebx ; this number is off by one
  213. sub ebp,ebx ; subtract from width
  214. ;*===================================================================
  215. ; Now that we have the alignment offset copy each row
  216. ;*===================================================================
  217. ??aligned_loop:
  218. mov ecx,ebx ; get number of bytes to align
  219. rep stosb ; and move them over
  220. mov ecx,ebp ; get number of aligned bytes
  221. shr ecx,2 ; convert to DWORDS
  222. rep stosd ; and move them over
  223. mov ecx,ebp ; get number of aligned bytes
  224. and ecx,3 ; find the remainder
  225. rep stosb ; and move it over
  226. add edi,esi ; fix the line offset
  227. dec edx ; decrement the height
  228. jnz ??aligned_loop ; if more to do than do it
  229. jmp ??exit ; we are all done
  230. ;*===================================================================
  231. ; If not enough bytes to bother aligning copy each line across a byte
  232. ; at a time.
  233. ;*===================================================================
  234. ??row_by_row:
  235. mov ecx,ebp ; get total width in bytes
  236. rep stosb ; store the width
  237. add edi,esi ; handle the xadd
  238. dec edx ; decrement the height
  239. jnz ??row_by_row ; if any left then next line
  240. ??out:
  241. ??exit:
  242. ret
  243. ENDP Buffer_Fill_Rect
  244. END