SUPPORT.ASM 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. ;
  2. ; Command & Conquer(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: F:\projects\c&c\vcs\code\support.asv 2.13 16 Oct 1995 16:52:36 JOE_BOSTIC $
  19. ;***************************************************************************
  20. ;** 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 **
  21. ;***************************************************************************
  22. ;* *
  23. ;* Project Name : Command & Conquer *
  24. ;* *
  25. ;* File Name : SUPPORT.ASM *
  26. ;* *
  27. ;* Programmer : Joe L. Bostic *
  28. ;* *
  29. ;* Start Date : September 23, 1993 *
  30. ;* *
  31. ;* Last Update : May 10, 1994 [JLB] *
  32. ;* *
  33. ;*-------------------------------------------------------------------------*
  34. ;* Functions: *
  35. ;* strtrim -- Remove the trailing white space from a string. *
  36. ;* Fat_Put_Pixel -- Draws a fat pixel. *
  37. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
  38. ;* Remove_From_List -- Removes a pointer from a list of pointers. *
  39. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  40. IDEAL
  41. P386
  42. MODEL USE32 FLAT
  43. INCLUDE "gbuffer.inc"
  44. DISPLAY "Command & Conquer assembly support routines."
  45. CODESEG
  46. ;***************************************************************************
  47. ;* strtrim -- Remove the trailing white space from a string. *
  48. ;* *
  49. ;* Use this routine to remove white space characters from the beginning *
  50. ;* and end of the string. The string is modified in place by *
  51. ;* this routine. *
  52. ;* *
  53. ;* INPUT: buffer -- Pointer to the string to modify. *
  54. ;* *
  55. ;* OUTPUT: none *
  56. ;* *
  57. ;* WARNINGS: none *
  58. ;* *
  59. ;* HISTORY: *
  60. ;* 10/07/1992 JLB : Created. *
  61. ;*=========================================================================*
  62. ; VOID cdecl strtrim(BYTE *buffer);
  63. global C strtrim :NEAR
  64. PROC strtrim C near
  65. USES ax, edi, esi
  66. ARG buffer:DWORD ; Pointer to string to modify.
  67. cmp [buffer],0
  68. je short ??fini
  69. ; Prepare for string scanning by loading pointers.
  70. cld
  71. mov esi,[buffer]
  72. mov edi,esi
  73. ; Strip white space from the start of the string.
  74. ??looper:
  75. lodsb
  76. cmp al,20h ; Space
  77. je short ??looper
  78. cmp al,9 ; TAB
  79. je short ??looper
  80. stosb
  81. ; Copy the rest of the string.
  82. ??gruntloop:
  83. lodsb
  84. stosb
  85. or al,al
  86. jnz short ??gruntloop
  87. dec edi
  88. ; Strip the white space from the end of the string.
  89. ??looper2:
  90. mov [edi],al
  91. dec edi
  92. mov ah,[edi]
  93. cmp ah,20h
  94. je short ??looper2
  95. cmp ah,9
  96. je short ??looper2
  97. ??fini:
  98. ret
  99. ENDP strtrim
  100. ;***************************************************************************
  101. ;* Fat_Put_Pixel -- Draws a fat pixel. *
  102. ;* *
  103. ;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
  104. ;* across. This routine is faster than drawing a similar small shape *
  105. ;* and faster than calling Fill_Rect. *
  106. ;* *
  107. ;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
  108. ;* left corner. *
  109. ;* *
  110. ;* color -- The color to render the pixel in. *
  111. ;* *
  112. ;* size -- The number of pixels width of the big "pixel". *
  113. ;* *
  114. ;* page -- The pointer to a GraphicBuffer class or something *
  115. ;* *
  116. ;* OUTPUT: none *
  117. ;* *
  118. ;* WARNINGS: none *
  119. ;* *
  120. ;* HISTORY: *
  121. ;* 03/17/1994 JLB : Created. *
  122. ;*=========================================================================*
  123. ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
  124. global C Fat_Put_Pixel:NEAR
  125. PROC Fat_Put_Pixel C near
  126. USES eax, ebx, ecx, edx, edi, esi
  127. ARG x:DWORD ; X coordinate of upper left pixel corner.
  128. ARG y:DWORD ; Y coordinate of upper left pixel corner.
  129. ARG color:DWORD ; Color to use for the "pixel".
  130. ARG siz:DWORD ; Size of "pixel" to plot (square).
  131. ARG gpage:DWORD ; graphic page address to plot onto
  132. cmp [siz],0
  133. je short ??exit
  134. ; Set EDI to point to start of logical page memory.
  135. ;*===================================================================
  136. ; Get the viewport information and put bytes per row in ecx
  137. ;*===================================================================
  138. mov ebx,[gpage] ; get a pointer to viewport
  139. mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
  140. ; Verify the the Y pixel offset is legal.
  141. mov eax,[y]
  142. cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
  143. jae short ??exit
  144. mov ecx,[(GraphicViewPort ebx).GVPWidth]
  145. add ecx,[(GraphicViewPort ebx).GVPXAdd]
  146. add ecx,[(GraphicViewPort ebx).GVPPitch]
  147. mul ecx
  148. add edi,eax
  149. ; Verify the the X pixel offset is legal.
  150. mov edx,[(GraphicViewPort ebx).GVPWidth]
  151. cmp edx,[x]
  152. mov edx,ecx
  153. jbe short ??exit
  154. add edi,[x]
  155. ; Write the pixel to the screen.
  156. mov ebx,[siz] ; Copy of pixel size.
  157. sub edx,ebx ; Modulo to reach start of next row.
  158. mov eax,[color]
  159. ??again:
  160. mov ecx,ebx
  161. rep stosb
  162. add edi,edx ; EDI points to start of next row.
  163. dec [siz]
  164. jnz short ??again
  165. ??exit:
  166. ret
  167. ENDP Fat_Put_Pixel
  168. ;***************************************************************************
  169. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
  170. ;* *
  171. ;* This routine is used to build a special fading table for C&C. There *
  172. ;* are certain colors that get faded to and cannot be faded again. *
  173. ;* With this rule, it is possible to draw a shadow multiple times and *
  174. ;* not have it get any lighter or darker. *
  175. ;* *
  176. ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
  177. ;* *
  178. ;* dest -- Pointer to the 256 byte remap table. *
  179. ;* *
  180. ;* color -- Color index of the color to "fade to". *
  181. ;* *
  182. ;* frac -- The fraction to fade to the specified color *
  183. ;* *
  184. ;* OUTPUT: Returns with pointer to the remap table. *
  185. ;* *
  186. ;* WARNINGS: none *
  187. ;* *
  188. ;* HISTORY: *
  189. ;* 10/07/1992 JLB : Created. *
  190. ;*=========================================================================*/
  191. ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
  192. global C Conquer_Build_Fading_Table : NEAR
  193. PROC Conquer_Build_Fading_Table C near
  194. USES ebx, ecx, edi, esi
  195. ARG palette:DWORD
  196. ARG dest:DWORD
  197. ARG color:DWORD
  198. ARG frac:DWORD
  199. LOCAL matchvalue:DWORD ; Last recorded match value.
  200. LOCAL targetred:BYTE ; Target gun red.
  201. LOCAL targetgreen:BYTE ; Target gun green.
  202. LOCAL targetblue:BYTE ; Target gun blue.
  203. LOCAL idealred:BYTE
  204. LOCAL idealgreen:BYTE
  205. LOCAL idealblue:BYTE
  206. LOCAL matchcolor:BYTE ; Tentative match color.
  207. ALLOWED_COUNT EQU 16
  208. ALLOWED_START EQU 256-ALLOWED_COUNT
  209. cld
  210. ; If the source palette is NULL, then just return with current fading table pointer.
  211. cmp [palette],0
  212. je ??fini1
  213. cmp [dest],0
  214. je ??fini1
  215. ; Fractions above 255 become 255.
  216. mov eax,[frac]
  217. cmp eax,0100h
  218. jb short ??ok
  219. mov [frac],0FFh
  220. ??ok:
  221. ; Record the target gun values.
  222. mov esi,[palette]
  223. mov ebx,[color]
  224. add esi,ebx
  225. add esi,ebx
  226. add esi,ebx
  227. lodsb
  228. mov [targetred],al
  229. lodsb
  230. mov [targetgreen],al
  231. lodsb
  232. mov [targetblue],al
  233. ; Main loop.
  234. xor ebx,ebx ; Remap table index.
  235. ; Transparent black never gets remapped.
  236. mov edi,[dest]
  237. mov [edi],bl
  238. inc edi
  239. ; EBX = source palette logical number (1..255).
  240. ; EDI = running pointer into dest remap table.
  241. ??mainloop:
  242. inc ebx
  243. mov esi,[palette]
  244. add esi,ebx
  245. add esi,ebx
  246. add esi,ebx
  247. mov edx,[frac]
  248. shr edx,1
  249. ; new = orig - ((orig-target) * fraction);
  250. lodsb ; orig
  251. mov dh,al ; preserve it for later.
  252. sub al,[targetred] ; al = (orig-target)
  253. imul dl ; ax = (orig-target)*fraction
  254. shl eax,1
  255. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  256. mov [idealred],dh ; preserve ideal color gun value.
  257. lodsb ; orig
  258. mov dh,al ; preserve it for later.
  259. sub al,[targetgreen] ; al = (orig-target)
  260. imul dl ; ax = (orig-target)*fraction
  261. shl eax,1
  262. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  263. mov [idealgreen],dh ; preserve ideal color gun value.
  264. lodsb ; orig
  265. mov dh,al ; preserve it for later.
  266. sub al,[targetblue] ; al = (orig-target)
  267. imul dl ; ax = (orig-target)*fraction
  268. shl eax,1
  269. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  270. mov [idealblue],dh ; preserve ideal color gun value.
  271. ; Sweep through a limited set of existing colors to find the closest
  272. ; matching color.
  273. mov eax,[color]
  274. mov [matchcolor],al ; Default color (self).
  275. mov [matchvalue],-1 ; Ridiculous match value init.
  276. mov ecx,ALLOWED_COUNT
  277. mov esi,[palette] ; Pointer to original palette.
  278. add esi,(ALLOWED_START)*3
  279. ; BH = color index.
  280. mov bh,ALLOWED_START
  281. ??innerloop:
  282. xor edx,edx ; Comparison value starts null.
  283. ; Build the comparison value based on the sum of the differences of the color
  284. ; guns squared.
  285. lodsb
  286. sub al,[idealred]
  287. mov ah,al
  288. imul ah
  289. add edx,eax
  290. lodsb
  291. sub al,[idealgreen]
  292. mov ah,al
  293. imul ah
  294. add edx,eax
  295. lodsb
  296. sub al,[idealblue]
  297. mov ah,al
  298. imul ah
  299. add edx,eax
  300. jz short ??perfect ; If perfect match found then quit early.
  301. cmp edx,[matchvalue]
  302. jae short ??notclose
  303. mov [matchvalue],edx ; Record new possible color.
  304. mov [matchcolor],bh
  305. ??notclose:
  306. inc bh ; Checking color index.
  307. loop ??innerloop
  308. mov bh,[matchcolor]
  309. ??perfect:
  310. mov [matchcolor],bh
  311. xor bh,bh ; Make BX valid main index again.
  312. ; When the loop exits, we have found the closest match.
  313. mov al,[matchcolor]
  314. stosb
  315. cmp ebx,ALLOWED_START-1
  316. jne ??mainloop
  317. ; Fill the remainder of the remap table with values
  318. ; that will remap the color to itself.
  319. mov ecx,ALLOWED_COUNT
  320. ??fillerloop:
  321. inc bl
  322. mov al,bl
  323. stosb
  324. loop ??fillerloop
  325. ??fini1:
  326. mov esi,[dest]
  327. mov eax,esi
  328. ret
  329. ENDP Conquer_Build_Fading_Table
  330. ;***************************************************************************
  331. ;* Remove_From_List -- Removes a pointer from a list of pointers. *
  332. ;* *
  333. ;* This low level routine is used to remove a pointer from a list of *
  334. ;* pointers. The trailing pointers are moved downward to fill the *
  335. ;* hole. *
  336. ;* *
  337. ;* INPUT: list -- Pointer to list of pointer. *
  338. ;* *
  339. ;* index -- Pointer to length of pointer list. *
  340. ;* *
  341. ;* ptr -- The pointer value to search for and remove. *
  342. ;* *
  343. ;* OUTPUT: none *
  344. ;* *
  345. ;* WARNINGS: none *
  346. ;* *
  347. ;* HISTORY: *
  348. ;* 04/11/1994 JLB : Created. *
  349. ;* 04/22/1994 JLB : Convert to assembly language. *
  350. ;* 05/10/1994 JLB : Short pointers now. *
  351. ;*=========================================================================*/
  352. ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
  353. global C Remove_From_List:NEAR
  354. PROC Remove_From_List C near
  355. USES edi, esi, ecx, eax
  356. ARG list:DWORD ; Pointer to list.
  357. ARG index:DWORD ; Pointer to count.
  358. ARG element:DWORD ; Element to remove.
  359. ; Fetch the number of elements in the list. If there are no
  360. ; elements, then just exit quickly.
  361. mov edi,[index]
  362. mov ecx,[edi]
  363. jcxz short ??fini2
  364. ; Fetch pointer to list.
  365. cmp [list],0
  366. je short ??fini2
  367. mov edi,[list]
  368. ; Loop through all elements searching for a match.
  369. mov eax,[element]
  370. repne scasd
  371. jne short ??fini2 ; No match found.
  372. ; Copy all remaining elements down. If this is the
  373. ; last element in the list then nothing needs to be
  374. ; copied -- just decrement the list size.
  375. jcxz short ??nocopy ; No copy necessary.
  376. mov esi,edi
  377. sub edi,4
  378. rep movsd
  379. ; Reduce the list count by one.
  380. ??nocopy:
  381. mov edi,[index]
  382. dec [DWORD PTR edi]
  383. ??fini2:
  384. ret
  385. ENDP Remove_From_List
  386. ; long cdecl Get_EAX();
  387. global C Get_EAX :NEAR
  388. PROC Get_EAX C near
  389. ret
  390. ENDP Get_EAX
  391. ;----------------------------------------------------------------------------
  392. END