DS_DS.ASM 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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 : Draw Shape Routines for library. *
  23. ;* *
  24. ;* File Name : DS_DS.ASM *
  25. ;* *
  26. ;* Programmer : Scott K. Bowen *
  27. ;* *
  28. ;* Start Date : August 24, 1993 *
  29. ;* *
  30. ;* Last Update : September 6, 1994 [IML] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* Draw_Scale -- Draws a scaled row of pixels to the viewport *
  35. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  36. IDEAL
  37. P386
  38. MODEL USE32 FLAT
  39. ;******************************** Includes *********************************
  40. INCLUDE "shape.inc"
  41. ;********************************* Code ************************************
  42. CODESEG
  43. ;***************************************************************************
  44. ;* Draw_Scale -- Draws a scaled row of pixels to the viewport *
  45. ;* *
  46. ;* INPUT: *
  47. ;* ECX = number of pixels (not bytes) to draw *
  48. ;* EDX = XTotal initializer value *
  49. ;* ESI = shape (source) buffer address *
  50. ;* EDI = viewport (destination) address *
  51. ;* [WidthCount] = remaining bytes on the line *
  52. ;* *
  53. ;* OUTPUT: *
  54. ;* ESI - updated to current location in the shape data *
  55. ;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
  56. ;* [WidthCount] - bytes remaining on the line *
  57. ;* *
  58. ;* WARNINGS: none *
  59. ;* *
  60. ;* HISTORY: *
  61. ;* 04/14/1992 PWG : Created. *
  62. ;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
  63. ;* 06/02/1994 BR : Converted to 32-bit. *
  64. ;* 08/09/1994 IML : Optimized for 32-bit. *
  65. ;* 09/06/1994 IML : Integrated p_* and ds_* routines. *
  66. ;*=========================================================================*
  67. PROC Draw_Scale NOLANGUAGE NEAR
  68. mov eax,0 ; init to 0
  69. test [Flags],SHAPE_EFFECTS
  70. jnz short ??general_draw_continue
  71. jmp short ??fast_draw_continue
  72. ;--------------------------------------------------------------------
  73. ; Extra fast draw loop for shapes with no flags set.
  74. ;--------------------------------------------------------------------
  75. ;--------------------------------------------------------------------
  76. ; Load a new byte:
  77. ; - read the byte into AL
  78. ; - if it's a run, deal with it
  79. ; - otherwise,
  80. ; - decrement [WidthCount]
  81. ; - update EDX with [ScaleX]
  82. ; - see if it's drawable (upon proc entry, it won't be)
  83. ; - yes: draw a pixel
  84. ; - no : load a new byte
  85. ;--------------------------------------------------------------------
  86. ??fast_draw_loop:
  87. mov al,[esi] ; get the next pixel from the source
  88. inc esi
  89. or eax,eax
  90. jz short ??fast_is_run ; deal with a run
  91. dec [WidthCount] ; count down # bytes processed
  92. add edx,[ScaleX] ; add in the scale value
  93. ??fast_draw_continue:
  94. or dh,dh ; are there any pixels to draw?
  95. jz short ??fast_draw_loop
  96. ;--------------------------------------------------------------------
  97. ; Draw one pixel:
  98. ; - draw the pixel
  99. ; - increment destination pointer
  100. ; - decrement high byte of EDX (X-scale accumulator)
  101. ; - loop (while ECX>0) to see if it's drawable
  102. ;--------------------------------------------------------------------
  103. mov [edi],al ; store color value to viewport
  104. inc edi ; increment the destination index
  105. dec dh ; decrement the pixels to write
  106. dec ecx
  107. jnz short ??fast_draw_continue
  108. jmp ??out ; get the heck outta here
  109. ;--------------------------------------------------------------------
  110. ; Handle a run:
  111. ; - Get the run repetition value
  112. ; - subract it from [WidthCount]
  113. ; - multiply it by [ScaleX]
  114. ; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
  115. ; - add high bytes (# pixels) to EDI
  116. ; - subtract them from ECX
  117. ; - clear EAX
  118. ; - if ECX>0, go get next byte
  119. ;--------------------------------------------------------------------
  120. ??fast_is_run:
  121. mov al,[esi] ; get number of repeated values
  122. inc esi
  123. sub [WidthCount],eax ; adjust the remaining byte width
  124. mov ebx,edx ; preserve dx for the multiply
  125. mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
  126. add eax,ebx ; add in the current x-total
  127. mov edx,eax ; (assume EDX is empty)
  128. shr eax,8 ; EAX = # pixels skipped
  129. and edx,00FFh ; keep only low byte
  130. add edi,eax ; add to EDI
  131. sub ecx,eax ; subtract it from ECX
  132. mov eax,0 ; clear EAX
  133. or ecx,ecx
  134. jg short ??fast_draw_loop ; if more to draw, process new byte
  135. jmp ??out
  136. ;--------------------------------------------------------------------
  137. ; General purpose draw loop for shapes with one or more flags set.
  138. ;--------------------------------------------------------------------
  139. ;--------------------------------------------------------------------
  140. ; Load a new byte:
  141. ; - read the byte into AL
  142. ; - if it's a run, deal with it
  143. ; - otherwise,
  144. ; - decrement [WidthCount]
  145. ; - update EDX with [ScaleX]
  146. ; - see if it's drawable (upon proc entry, it won't be)
  147. ; - yes: draw a pixel
  148. ; - no : load a new byte
  149. ;--------------------------------------------------------------------
  150. ??general_draw_loop:
  151. mov al,[esi] ; get the next pixel from the source
  152. inc esi
  153. or eax,eax
  154. jz ??general_is_run ; deal with a run
  155. dec [WidthCount] ; count down # bytes processed
  156. add edx,[ScaleX] ; add in the scale value
  157. ??general_draw_continue:
  158. or dh,dh ; are there any pixels to draw?
  159. jz short ??general_draw_loop
  160. ;--------------------------------------------------------------------
  161. ; Draw one pixel:
  162. ; - draw the pixel
  163. ; - increment destination pointer
  164. ; - decrement high byte of EDX (X-scale accumulator)
  165. ; - loop (while ECX>0) to see if it's drawable
  166. ;--------------------------------------------------------------------
  167. ??draw:
  168. mov [StashReg],eax ; save eax
  169. mov [StashEDX],edx ; save edx
  170. mov edx,[Flags]
  171. ??test_priority:
  172. test edx,SHAPE_PRIORITY
  173. jnz short ??priority
  174. ??test_predator:
  175. test edx,SHAPE_PREDATOR
  176. jnz short ??predator
  177. ??test_compact:
  178. test edx,SHAPE_COMPACT
  179. jnz ??compact
  180. ??test_shadow:
  181. test edx,SHAPE_SHADOW
  182. jnz ??shadow
  183. ??test_translucency:
  184. test edx,SHAPE_GHOST
  185. jnz ??translucency
  186. ??test_fading:
  187. test edx,SHAPE_FADING
  188. jnz ??fading
  189. ??test_transparency:
  190. test edx,SHAPE_FADING ; if fading is enabled test for
  191. jz short ??no_fading_draw_loop ; transparency
  192. or eax,eax
  193. jz short ??is_transparent
  194. ??no_fading_draw_loop:
  195. mov [edi],al ; store color value to viewport
  196. ??is_transparent:
  197. mov eax,[StashReg] ; restore eax
  198. mov edx,[StashEDX] ; restore edx
  199. inc edi ; increment the destination index
  200. dec dh ; decrement the pixels to write
  201. dec ecx
  202. jnz ??general_draw_continue
  203. jmp ??out ; get the heck outta here
  204. ??priority:
  205. mov ebx,[MaskAdjust] ; get mask page offset
  206. mov bl,[BYTE PTR ebx + edi] ; get mask value
  207. and bl,CLEAR_UNUSED_BITS ; clear unused bits
  208. cmp [PriLevel],bl ; are we in front of
  209. jge short ??test_predator ; background?
  210. mov ebx,[BackAdjust] ; get background page offset
  211. mov al,[BYTE PTR ebx + edi] ; get background pixel
  212. jmp short ??test_transparency
  213. ??predator:
  214. mov ebx,[PartialCount]
  215. add ebx,[PartialPred]
  216. or bh,bh
  217. jnz short ??draw_pred ; is this a predator pixel?
  218. mov [PartialCount],ebx
  219. jmp ??test_compact
  220. ??draw_pred:
  221. xor bh,bh
  222. mov [PartialCount],ebx
  223. mov ebx,[PredValue] ; pick up a color offset a pseudo-
  224. ; random amount from the current
  225. mov al,[edi + ebx] ; viewport address
  226. jmp short ??test_transparency
  227. ??compact:
  228. mov ebx,[ColorTable] ; get the address of the color table
  229. mov al,[BYTE PTR ebx + eax] ; convert it into the proper byte
  230. jmp ??test_shadow
  231. ??shadow:
  232. cmp al,SHADOW_COL
  233. jne ??test_translucency ; is the table value a magic number?
  234. mov al,[edi] ; get the destination color and
  235. mov ebx,[ShadowingTable] ; index into the shadow table
  236. mov al,[BYTE PTR ebx + eax]
  237. jmp ??test_transparency
  238. ??fading:
  239. mov [StashECX],ecx ; preserve ecx for later
  240. mov ebx,[FadingTable] ; run color through fading table
  241. mov ecx,[FadingNum]
  242. ??fade_loop:
  243. mov al, [BYTE PTR ebx + eax]
  244. dec ecx
  245. jnz short ??fade_loop
  246. mov ecx,[StashECX] ; restore ecx for main draw loop
  247. jmp ??test_transparency
  248. ??translucency:
  249. mov ebx,[IsTranslucent] ; is it a translucent color?
  250. mov bh,[BYTE PTR ebx + eax]
  251. or bh,bh
  252. js ??test_fading
  253. and ebx,0FF00h ; clear all of ebx except bh
  254. ; we have the index to the translation table
  255. ; ((trans_colour * 256) + dest colour)
  256. mov al,[edi] ; mov pixel at destination to al
  257. add ebx,[Translucent] ; get the ptr to it!
  258. ; Add the (trans_color * 256) of the translation equ.
  259. mov al,[BYTE PTR ebx + eax] ; get new pixel in al
  260. jmp ??test_fading
  261. ;--------------------------------------------------------------------
  262. ; Handle a run:
  263. ; - Get the run repetition value
  264. ; - subract it from [WidthCount]
  265. ; - multiply it by [ScaleX]
  266. ; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
  267. ; - add high bytes (# pixels) to EDI
  268. ; - subtract them from ECX
  269. ; - clear EAX
  270. ; - if ECX>0, go get next byte
  271. ;--------------------------------------------------------------------
  272. ??general_is_run:
  273. mov al,[esi] ; get number of repeated values
  274. inc esi
  275. sub [WidthCount],eax ; adjust the remaining byte width
  276. mov ebx,edx ; preserve dx for the multiply
  277. mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
  278. add eax,ebx ; add in the current x-total
  279. mov edx,eax ; (assume EDX is empty)
  280. shr eax,8 ; EAX = # pixels skipped
  281. and edx,00FFh ; keep only low byte
  282. add edi,eax ; add to EDI
  283. sub ecx,eax ; subtract it from ECX
  284. mov eax,0 ; clear EAX
  285. or ecx,ecx
  286. jg ??general_draw_loop ; if more to draw, process new byte
  287. ??out:
  288. ret ; lets get out of here
  289. ENDP Draw_Scale
  290. END
  291. ;**************************** End of ds_ds.asm ******************************