SUPPORT.ASM 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. ;
  2. ; Copyright 2020 Electronic Arts Inc.
  3. ;
  4. ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. ; software: you can redistribute it and/or modify it under the terms of
  6. ; the GNU General Public License as published by the Free Software Foundation,
  7. ; either version 3 of the License, or (at your option) any later version.
  8. ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. ; in the hope that it will be useful, but with permitted additional restrictions
  10. ; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. ; distributed with this program. You should have received a copy of the
  12. ; GNU General Public License along with permitted additional restrictions
  13. ; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
  14. ; $Header: F:\projects\c&c0\vcs\code\support.asv 5.0 11 Nov 1996 09:40:30 JOE_BOSTIC $
  15. ;***************************************************************************
  16. ;** 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 **
  17. ;***************************************************************************
  18. ;* *
  19. ;* Project Name : Command & Conquer *
  20. ;* *
  21. ;* File Name : SUPPORT.ASM *
  22. ;* *
  23. ;* Programmer : Joe L. Bostic *
  24. ;* *
  25. ;* Start Date : September 23, 1993 *
  26. ;* *
  27. ;* Last Update : May 10, 1994 [JLB] *
  28. ;* *
  29. ;*-------------------------------------------------------------------------*
  30. ;* Functions: *
  31. ;* strtrim -- Remove the trailing white space from a string. *
  32. ;* Fat_Put_Pixel -- Draws a fat pixel. *
  33. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
  34. ;* Remove_From_List -- Removes a pointer from a list of pointers. *
  35. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  36. IDEAL
  37. P386
  38. MODEL USE32 FLAT
  39. INCLUDE "gbuffer.inc"
  40. DISPLAY "Command & Conquer assembly support routines."
  41. CODESEG
  42. ;***************************************************************************
  43. ;* Fat_Put_Pixel -- Draws a fat pixel. *
  44. ;* *
  45. ;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
  46. ;* across. This routine is faster than drawing a similar small shape *
  47. ;* and faster than calling Fill_Rect. *
  48. ;* *
  49. ;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
  50. ;* left corner. *
  51. ;* *
  52. ;* color -- The color to render the pixel in. *
  53. ;* *
  54. ;* size -- The number of pixels width of the big "pixel". *
  55. ;* *
  56. ;* page -- The pointer to a GraphicBuffer class or something *
  57. ;* *
  58. ;* OUTPUT: none *
  59. ;* *
  60. ;* WARNINGS: none *
  61. ;* *
  62. ;* HISTORY: *
  63. ;* 03/17/1994 JLB : Created. *
  64. ;*=========================================================================*
  65. ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
  66. GLOBAL C Fat_Put_Pixel:NEAR
  67. PROC Fat_Put_Pixel C near
  68. USES eax, ebx, ecx, edx, edi, esi
  69. ARG x:DWORD ; X coordinate of upper left pixel corner.
  70. ARG y:DWORD ; Y coordinate of upper left pixel corner.
  71. ARG color:DWORD ; Color to use for the "pixel".
  72. ARG siz:DWORD ; Size of "pixel" to plot (square).
  73. ARG gpage:DWORD ; graphic page address to plot onto
  74. cmp [siz],0
  75. je short ??exit
  76. ; Set EDI to point to start of logical page memory.
  77. ;*===================================================================
  78. ; Get the viewport information and put bytes per row in ecx
  79. ;*===================================================================
  80. mov ebx,[gpage] ; get a pointer to viewport
  81. mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
  82. ; Verify the the Y pixel offset is legal.
  83. mov eax,[y]
  84. cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
  85. jae short ??exit
  86. mul [(GraphicViewPort ebx).GVPWidth]
  87. add edi,eax
  88. ; Verify the the X pixel offset is legal.
  89. mov edx,[(GraphicViewPort ebx).GVPWidth]
  90. cmp edx,[x]
  91. jbe short ??exit
  92. add edi,[x]
  93. ; Write the pixel to the screen.
  94. mov ebx,[siz] ; Copy of pixel size.
  95. sub edx,ebx ; Modulo to reach start of next row.
  96. mov eax,[color]
  97. ??again:
  98. mov ecx,ebx
  99. rep stosb
  100. add edi,edx ; EDI points to start of next row.
  101. dec [siz]
  102. jnz short ??again
  103. ??exit:
  104. ret
  105. ENDP Fat_Put_Pixel
  106. if 0
  107. ;***************************************************************************
  108. ;* strtrim -- Remove the trailing white space from a string. *
  109. ;* *
  110. ;* Use this routine to remove white space characters from the beginning *
  111. ;* and end of the string. The string is modified in place by *
  112. ;* this routine. *
  113. ;* *
  114. ;* INPUT: buffer -- Pointer to the string to modify. *
  115. ;* *
  116. ;* OUTPUT: none *
  117. ;* *
  118. ;* WARNINGS: none *
  119. ;* *
  120. ;* HISTORY: *
  121. ;* 10/07/1992 JLB : Created. *
  122. ;*=========================================================================*
  123. ; VOID cdecl strtrim(BYTE *buffer);
  124. GLOBAL C strtrim :NEAR
  125. PROC strtrim C near
  126. USES ax, edi, esi
  127. ARG buffer:DWORD ; Pointer to string to modify.
  128. cmp [buffer],0
  129. je short ??fini
  130. ; Prepare for string scanning by loading pointers.
  131. cld
  132. mov esi,[buffer]
  133. mov edi,esi
  134. ; Strip white space from the start of the string.
  135. ??looper:
  136. lodsb
  137. cmp al,20h ; Space
  138. je short ??looper
  139. cmp al,9 ; TAB
  140. je short ??looper
  141. stosb
  142. ; Copy the rest of the string.
  143. ??gruntloop:
  144. lodsb
  145. stosb
  146. or al,al
  147. jnz short ??gruntloop
  148. dec edi
  149. ; Strip the white space from the end of the string.
  150. ??looper2:
  151. mov [edi],al
  152. dec edi
  153. mov ah,[edi]
  154. cmp ah,20h
  155. je short ??looper2
  156. cmp ah,9
  157. je short ??looper2
  158. ??fini:
  159. ret
  160. ENDP strtrim
  161. ;***************************************************************************
  162. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
  163. ;* *
  164. ;* This routine is used to build a special fading table for C&C. There *
  165. ;* are certain colors that get faded to and cannot be faded again. *
  166. ;* With this rule, it is possible to draw a shadow multiple times and *
  167. ;* not have it get any lighter or darker. *
  168. ;* *
  169. ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
  170. ;* *
  171. ;* dest -- Pointer to the 256 byte remap table. *
  172. ;* *
  173. ;* color -- Color index of the color to "fade to". *
  174. ;* *
  175. ;* frac -- The fraction to fade to the specified color *
  176. ;* *
  177. ;* OUTPUT: Returns with pointer to the remap table. *
  178. ;* *
  179. ;* WARNINGS: none *
  180. ;* *
  181. ;* HISTORY: *
  182. ;* 10/07/1992 JLB : Created. *
  183. ;*=========================================================================*/
  184. ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
  185. GLOBAL C Conquer_Build_Fading_Table : NEAR
  186. PROC Conquer_Build_Fading_Table C near
  187. USES ebx, ecx, edi, esi
  188. ARG palette:DWORD
  189. ARG dest:DWORD
  190. ARG color:DWORD
  191. ARG frac:DWORD
  192. LOCAL matchvalue:DWORD ; Last recorded match value.
  193. LOCAL targetred:BYTE ; Target gun red.
  194. LOCAL targetgreen:BYTE ; Target gun green.
  195. LOCAL targetblue:BYTE ; Target gun blue.
  196. LOCAL idealred:BYTE
  197. LOCAL idealgreen:BYTE
  198. LOCAL idealblue:BYTE
  199. LOCAL matchcolor:BYTE ; Tentative match color.
  200. ALLOWED_COUNT EQU 16
  201. ALLOWED_START EQU 256-ALLOWED_COUNT
  202. cld
  203. ; If the source palette is NULL, then just return with current fading table pointer.
  204. cmp [palette],0
  205. je ??fini1
  206. cmp [dest],0
  207. je ??fini1
  208. ; Fractions above 255 become 255.
  209. mov eax,[frac]
  210. cmp eax,0100h
  211. jb short ??ok
  212. mov [frac],0FFh
  213. ??ok:
  214. ; Record the target gun values.
  215. mov esi,[palette]
  216. mov ebx,[color]
  217. add esi,ebx
  218. add esi,ebx
  219. add esi,ebx
  220. lodsb
  221. mov [targetred],al
  222. lodsb
  223. mov [targetgreen],al
  224. lodsb
  225. mov [targetblue],al
  226. ; Main loop.
  227. xor ebx,ebx ; Remap table index.
  228. ; Transparent black never gets remapped.
  229. mov edi,[dest]
  230. mov [edi],bl
  231. inc edi
  232. ; EBX = source palette logical number (1..255).
  233. ; EDI = running pointer into dest remap table.
  234. ??mainloop:
  235. inc ebx
  236. mov esi,[palette]
  237. add esi,ebx
  238. add esi,ebx
  239. add esi,ebx
  240. mov edx,[frac]
  241. shr edx,1
  242. ; new = orig - ((orig-target) * fraction);
  243. lodsb ; orig
  244. mov dh,al ; preserve it for later.
  245. sub al,[targetred] ; al = (orig-target)
  246. imul dl ; ax = (orig-target)*fraction
  247. shl eax,1
  248. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  249. mov [idealred],dh ; preserve ideal color gun value.
  250. lodsb ; orig
  251. mov dh,al ; preserve it for later.
  252. sub al,[targetgreen] ; 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 [idealgreen],dh ; preserve ideal color gun value.
  257. lodsb ; orig
  258. mov dh,al ; preserve it for later.
  259. sub al,[targetblue] ; 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 [idealblue],dh ; preserve ideal color gun value.
  264. ; Sweep through a limited set of existing colors to find the closest
  265. ; matching color.
  266. mov eax,[color]
  267. mov [matchcolor],al ; Default color (self).
  268. mov [matchvalue],-1 ; Ridiculous match value init.
  269. mov ecx,ALLOWED_COUNT
  270. mov esi,[palette] ; Pointer to original palette.
  271. add esi,(ALLOWED_START)*3
  272. ; BH = color index.
  273. mov bh,ALLOWED_START
  274. ??innerloop:
  275. xor edx,edx ; Comparison value starts null.
  276. ; Build the comparison value based on the sum of the differences of the color
  277. ; guns squared.
  278. lodsb
  279. sub al,[idealred]
  280. mov ah,al
  281. imul ah
  282. add edx,eax
  283. lodsb
  284. sub al,[idealgreen]
  285. mov ah,al
  286. imul ah
  287. add edx,eax
  288. lodsb
  289. sub al,[idealblue]
  290. mov ah,al
  291. imul ah
  292. add edx,eax
  293. jz short ??perfect ; If perfect match found then quit early.
  294. cmp edx,[matchvalue]
  295. jae short ??notclose
  296. mov [matchvalue],edx ; Record new possible color.
  297. mov [matchcolor],bh
  298. ??notclose:
  299. inc bh ; Checking color index.
  300. loop ??innerloop
  301. mov bh,[matchcolor]
  302. ??perfect:
  303. mov [matchcolor],bh
  304. xor bh,bh ; Make BX valid main index again.
  305. ; When the loop exits, we have found the closest match.
  306. mov al,[matchcolor]
  307. stosb
  308. cmp ebx,ALLOWED_START-1
  309. jne ??mainloop
  310. ; Fill the remainder of the remap table with values
  311. ; that will remap the color to itself.
  312. mov ecx,ALLOWED_COUNT
  313. ??fillerloop:
  314. inc bl
  315. mov al,bl
  316. stosb
  317. loop ??fillerloop
  318. ??fini1:
  319. mov esi,[dest]
  320. mov eax,esi
  321. ret
  322. ENDP Conquer_Build_Fading_Table
  323. ;***************************************************************************
  324. ;* Remove_From_List -- Removes a pointer from a list of pointers. *
  325. ;* *
  326. ;* This low level routine is used to remove a pointer from a list of *
  327. ;* pointers. The trailing pointers are moved downward to fill the *
  328. ;* hole. *
  329. ;* *
  330. ;* INPUT: list -- Pointer to list of pointer. *
  331. ;* *
  332. ;* index -- Pointer to length of pointer list. *
  333. ;* *
  334. ;* ptr -- The pointer value to search for and remove. *
  335. ;* *
  336. ;* OUTPUT: none *
  337. ;* *
  338. ;* WARNINGS: none *
  339. ;* *
  340. ;* HISTORY: *
  341. ;* 04/11/1994 JLB : Created. *
  342. ;* 04/22/1994 JLB : Convert to assembly language. *
  343. ;* 05/10/1994 JLB : Short pointers now. *
  344. ;*=========================================================================*/
  345. ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
  346. GLOBAL C Remove_From_List:NEAR
  347. PROC Remove_From_List C near
  348. USES edi, esi, ecx, eax
  349. ARG list:DWORD ; Pointer to list.
  350. ARG index:DWORD ; Pointer to count.
  351. ARG element:DWORD ; Element to remove.
  352. ; Fetch the number of elements in the list. If there are no
  353. ; elements, then just exit quickly.
  354. mov edi,[index]
  355. mov ecx,[edi]
  356. jcxz short ??fini2
  357. ; Fetch pointer to list.
  358. cmp [list],0
  359. je short ??fini2
  360. mov edi,[list]
  361. ; Loop through all elements searching for a match.
  362. mov eax,[element]
  363. repne scasd
  364. jne short ??fini2 ; No match found.
  365. ; Copy all remaining elements down. If this is the
  366. ; last element in the list then nothing needs to be
  367. ; copied -- just decrement the list size.
  368. jcxz short ??nocopy ; No copy necessary.
  369. mov esi,edi
  370. sub edi,4
  371. rep movsd
  372. ; Reduce the list count by one.
  373. ??nocopy:
  374. mov edi,[index]
  375. dec [DWORD PTR edi]
  376. ??fini2:
  377. ret
  378. ENDP Remove_From_List
  379. ; long cdecl Get_EAX();
  380. GLOBAL C Get_EAX :NEAR
  381. PROC Get_EAX C near
  382. ret
  383. ENDP Get_EAX
  384. endif
  385. DATASEG
  386. TabA DD 6949350
  387. DD 4913933
  388. DD 3474675
  389. DD 2456966
  390. DD 1737338
  391. DD 1228483
  392. DD 868669
  393. DD 614242
  394. DD 434334
  395. DD 307121
  396. DD 217167
  397. DD 153560
  398. DD 108584
  399. DD 76780
  400. DD 54292
  401. DD 38390
  402. DD 27146
  403. DD 19195
  404. DD 13573
  405. DD 9598
  406. DD 6786
  407. DD 4799
  408. DD 3393
  409. DD 2399
  410. DD 1697
  411. DD 1200
  412. DD 848
  413. DD 600
  414. DD 424
  415. DD 300
  416. DD 212
  417. DD 150
  418. DD 106
  419. TabB DD 154
  420. DD 218
  421. DD 309
  422. DD 437
  423. DD 618
  424. DD 874
  425. DD 1236
  426. DD 1748
  427. DD 2472
  428. DD 3496
  429. DD 4944
  430. DD 6992
  431. DD 9888
  432. DD 13983
  433. DD 19775
  434. DD 27967
  435. DD 39551
  436. DD 55933
  437. DD 79101
  438. DD 111866
  439. DD 158203
  440. DD 223732
  441. DD 316405
  442. DD 447465
  443. DD 632811
  444. DD 894929
  445. DD 1265621
  446. DD 1789859
  447. DD 2531243
  448. DD 3579718
  449. DD 5062486
  450. DD 7159436
  451. DD 10124971
  452. CODESEG
  453. ;***********************************************************************************************
  454. ;* Square_Root -- Finds the square root of the fixed pointer parameter. *
  455. ;* *
  456. ;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
  457. ;* *
  458. ;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
  459. ;* *
  460. ;* WARNINGS: none *
  461. ;* *
  462. ;* HISTORY: *
  463. ;* 10/04/1995 JLB : Adapted. *
  464. ;*=============================================================================================*/
  465. ;unsigned Square_Root(unsigned val);
  466. GLOBAL C Square_Root :NEAR
  467. PROC Square_Root C near
  468. USES ebx,edx
  469. bsr ebx,eax
  470. jz ??zero
  471. mul [DWORD 4*ebx + OFFSET TabA]
  472. shrd eax,edx,10h
  473. add eax, [4*ebx + OFFSET TabB]
  474. ??zero:
  475. ret
  476. ENDP Square_Root
  477. ;----------------------------------------------------------------------------
  478. END