CLIPRECT.ASM 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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 A S S O C I A T E S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Support Library *
  23. ;* *
  24. ;* File Name : cliprect.asm *
  25. ;* *
  26. ;* Programmer : Julio R Jerez *
  27. ;* *
  28. ;* Start Date : Mar, 2 1995 *
  29. ;* *
  30. ;* *
  31. ;*-------------------------------------------------------------------------*
  32. ;* Functions: *
  33. ;* int Clip_Rect ( int * x , int * y , int * dw , int * dh , *
  34. ;* int width , int height ) ; *
  35. ;* int Confine_Rect ( int * x , int * y , int * dw , int * dh , *
  36. ;* int width , int height ) ; *
  37. ;* *
  38. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  39. IDEAL
  40. P386
  41. MODEL USE32 FLAT
  42. GLOBAL C Clip_Rect :NEAR
  43. GLOBAL C Confine_Rect :NEAR
  44. CODESEG
  45. ;***************************************************************************
  46. ;* Clip_Rect -- clip a given rectangle against a given window *
  47. ;* *
  48. ;* INPUT: &x , &y , &w , &h -> Pointer to rectangle being clipped *
  49. ;* width , height -> dimension of clipping window *
  50. ;* *
  51. ;* OUTPUT: a) Zero if the rectangle is totally contained by the *
  52. ;* clipping window. *
  53. ;* b) A negative value if the rectangle is totally outside the *
  54. ;* the clipping window *
  55. ;* c) A positive value if the rectangle was clipped against the *
  56. ;* clipping window, also the values pointed by x, y, w, h will *
  57. ;* be modified to new clipped values *
  58. ;* *
  59. ;* 05/03/1995 JRJ : added comment *
  60. ;*=========================================================================*
  61. ; int Clip_Rect (int* x, int* y, int* dw, int* dh, int width, int height); *
  62. PROC Clip_Rect C near
  63. uses ebx,ecx,edx,esi,edi
  64. arg x:dword
  65. arg y:dword
  66. arg w:dword
  67. arg h:dword
  68. arg width:dword
  69. arg height:dword
  70. ;This Clipping algorithm is a derivation of the very well known
  71. ;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency
  72. ;it is probably the most commontly implemented algorithm both in software
  73. ;and hardware for clipping lines, rectangles, and convex polygons against
  74. ;a rectagular clipping window. For reference see
  75. ;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes
  76. ; pages 113 to 177".
  77. ; Briefly consist in computing the Sutherland code for both end point of
  78. ; the rectangle to find out if the rectangle is:
  79. ; - trivially accepted (no further clipping test, return the oroginal data)
  80. ; - trivially rejected (return with no action, return error code)
  81. ; - retangle must be iteratively clipped again edges of the clipping window
  82. ; and return the clipped rectangle
  83. ; get all four pointer into regisnters
  84. mov esi,[x] ; esi = pointer to x
  85. mov edi,[y] ; edi = pointer to x
  86. mov eax,[w] ; eax = pointer to dw
  87. mov ebx,[h] ; ebx = pointer to dh
  88. ; load the actual data into reg
  89. mov esi,[esi] ; esi = x0
  90. mov edi,[edi] ; edi = y0
  91. mov eax,[eax] ; eax = dw
  92. mov ebx,[ebx] ; ebx = dh
  93. ; create a wire frame of the type [x0,y0] , [x1,y1]
  94. add eax,esi ; eax = x1 = x0 + dw
  95. add ebx,edi ; ebx = y1 = y0 + dh
  96. ; we start we suthenland code0 and code1 set to zero
  97. xor ecx,ecx ; cl = sutherland boolean code0
  98. xor edx,edx ; dl = sutherland boolean code0
  99. ; now we start computing the to suthenland boolean code for x0 , x1
  100. shld ecx,esi,1 ; bit3 of code0 = sign bit of (x0 - 0)
  101. shld edx,eax,1 ; bit3 of code1 = sign bit of (x1 - 0)
  102. sub esi,[width] ; get the difference (x0 - (width + 1))
  103. sub eax,[width] ; get the difference (x1 - (width + 1))
  104. dec esi
  105. dec eax
  106. shld ecx,esi,1 ; bit2 of code0 = sign bit of (x0 - (width + 1))
  107. shld edx,eax,1 ; bit2 of code1 = sign bit of (x0 - (width + 1))
  108. ; now we start computing the to suthenland boolean code for y0 , y1
  109. shld ecx,edi,1 ; bit1 of code0 = sign bit of (y0 - 0)
  110. shld edx,ebx,1 ; bit1 of code1 = sign bit of (y0 - 0)
  111. sub edi,[height] ; get the difference (y0 - (height + 1))
  112. sub ebx,[height] ; get the difference (y1 - (height + 1))
  113. dec edi
  114. dec ebx
  115. shld ecx,edi,1 ; bit0 of code0 = sign bit of (y0 - (height + 1))
  116. shld edx,ebx,1 ; bit0 of code1 = sign bit of (y1 - (height + 1))
  117. ; Bit 2 and 0 of cl and bl are complemented
  118. xor cl,5 ; reverse bit2 and bit0 in code0
  119. xor dl,5 ; reverse bit2 and bit0 in code1
  120. ; now perform the rejection test
  121. mov eax,-1 ; set return code to false
  122. mov bl,cl ; save code0 for future use
  123. test dl,cl ; if any two pair of bit in code0 and code1 is set
  124. jnz ??clip_out ; then rectangle is outside the window
  125. ; now perform the aceptance test
  126. xor eax,eax ; set return code to true
  127. or bl,dl ; if all pair of bits in code0 and code1 are reset
  128. jz ??clip_out ; then rectangle is insize the window. '
  129. ; we need to clip the rectangle iteratively
  130. mov eax,-1 ; set return code to false
  131. test cl,1000b ; if bit3 of code0 is set then the rectangle
  132. jz ??left_ok ; spill out the left edge of the window
  133. mov edi,[x] ; edi = a pointer to x0
  134. mov ebx,[w] ; ebx = a pointer to dw
  135. mov esi,[edi] ; esi = x0
  136. mov [dword ptr edi],0 ; set x0 to 0 "this the left edge value"
  137. add [ebx],esi ; adjust dw by x0, since x0 must be negative
  138. ??left_ok:
  139. test cl,0010b ; if bit1 of code0 is set then the rectangle
  140. jz ??bottom_ok ; spill out the bottom edge of the window
  141. mov edi,[y] ; edi = a pointer to y0
  142. mov ebx,[h] ; ebx = a pointer to dh
  143. mov esi,[edi] ; esi = y0
  144. mov [dword ptr edi],0 ; set y0 to 0 "this the bottom edge value"
  145. add [ebx],esi ; adjust dh by y0, since y0 must be negative
  146. ??bottom_ok:
  147. test dl,0100b ; if bit2 of code1 is set then the rectangle
  148. jz ??right_ok ; spill out the right edge of the window
  149. mov edi,[w] ; edi = a pointer to dw
  150. mov esi,[x] ; esi = a pointer to x
  151. mov ebx,[width] ; ebx = the width of the window
  152. sub ebx,[esi] ; the new dw is the difference (width-x0)
  153. mov [edi],ebx ; adjust dw to (width - x0)
  154. jle ??clip_out ; if (width-x0) = 0 then the clipped retangle
  155. ; has no width we are done
  156. ??right_ok:
  157. test dl,0001b ; if bit0 of code1 is set then the rectangle
  158. jz ??clip_ok ; spill out the top edge of the window
  159. mov edi,[h] ; edi = a pointer to dh
  160. mov esi,[y] ; esi = a pointer to y0
  161. mov ebx,[height] ; ebx = the height of the window
  162. sub ebx,[esi] ; the new dh is the difference (height-y0)
  163. mov [edi],ebx ; adjust dh to (height-y0)
  164. jle ??clip_out ; if (width-x0) = 0 then the clipped retangle
  165. ; has no width we are done
  166. ??clip_ok:
  167. mov eax,1 ; signal the calling program that the rectangle was modify
  168. ??clip_out:
  169. ret
  170. ENDP Clip_Rect
  171. ;***************************************************************************
  172. ;* Confine_Rect -- clip a given rectangle against a given window *
  173. ;* *
  174. ;* INPUT: &x,&y,w,h -> Pointer to rectangle being clipped *
  175. ;* width,height -> dimension of clipping window *
  176. ;* *
  177. ;* OUTPUT: a) Zero if the rectangle is totally contained by the *
  178. ;* clipping window. *
  179. ;* c) A positive value if the rectangle was shifted in position *
  180. ;* to fix inside the clipping window, also the values pointed *
  181. ;* by x, y, will adjusted to a new values *
  182. ;* *
  183. ;* NOTE: this function make not attempt to verify if the rectangle is *
  184. ;* bigger than the clipping window and at the same time wrap around*
  185. ;* it. If that is the case the result is meaningless *
  186. ;*=========================================================================*
  187. ; int Confine_Rect (int* x, int* y, int dw, int dh, int width, int height); *
  188. PROC Confine_Rect C near
  189. uses ebx, esi,edi
  190. arg x:dword
  191. arg y:dword
  192. arg w:dword
  193. arg h:dword
  194. arg width :dword
  195. arg height:dword
  196. xor eax,eax
  197. mov ebx,[x]
  198. mov edi,[w]
  199. mov esi,[ebx]
  200. add edi,[ebx]
  201. sub edi,[width]
  202. neg esi
  203. dec edi
  204. test esi,edi
  205. jl ??x_axix_ok
  206. mov eax,1
  207. test esi,esi
  208. jl ??shift_right
  209. mov [dword ptr ebx],0
  210. jmp ??x_axix_ok
  211. ??shift_right:
  212. inc edi
  213. sub [ebx],edi
  214. ??x_axix_ok:
  215. mov ebx,[y]
  216. mov edi,[h]
  217. mov esi,[ebx]
  218. add edi,[ebx]
  219. sub edi,[height]
  220. neg esi
  221. dec edi
  222. test esi,edi
  223. jl ??confi_out
  224. mov eax,1
  225. test esi,esi
  226. jl ??shift_top
  227. mov [dword ptr ebx],0
  228. ret
  229. ??shift_top:
  230. inc edi
  231. sub [ebx],edi
  232. ??confi_out:
  233. ret
  234. ENDP Confine_Rect
  235. END