2SUPPORT.ASM 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  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\2support.asv 5.0 11 Nov 1996 09:40:36 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. mov ecx,[(GraphicViewPort ebx).GVPWidth]
  87. add ecx,[(GraphicViewPort ebx).GVPXAdd]
  88. add ecx,[(GraphicViewPort ebx).GVPPitch]
  89. mul ecx
  90. add edi,eax
  91. ; Verify the the X pixel offset is legal.
  92. mov edx,[(GraphicViewPort ebx).GVPWidth]
  93. cmp edx,[x]
  94. mov edx,ecx
  95. jbe short ??exit
  96. add edi,[x]
  97. ; Write the pixel to the screen.
  98. mov ebx,[siz] ; Copy of pixel size.
  99. sub edx,ebx ; Modulo to reach start of next row.
  100. mov eax,[color]
  101. ??again:
  102. mov ecx,ebx
  103. rep stosb
  104. add edi,edx ; EDI points to start of next row.
  105. dec [siz]
  106. jnz short ??again
  107. ??exit:
  108. ret
  109. ENDP Fat_Put_Pixel
  110. if 0
  111. ;***************************************************************************
  112. ;* strtrim -- Remove the trailing white space from a string. *
  113. ;* *
  114. ;* Use this routine to remove white space characters from the beginning *
  115. ;* and end of the string. The string is modified in place by *
  116. ;* this routine. *
  117. ;* *
  118. ;* INPUT: buffer -- Pointer to the string to modify. *
  119. ;* *
  120. ;* OUTPUT: none *
  121. ;* *
  122. ;* WARNINGS: none *
  123. ;* *
  124. ;* HISTORY: *
  125. ;* 10/07/1992 JLB : Created. *
  126. ;*=========================================================================*
  127. ; VOID cdecl strtrim(BYTE *buffer);
  128. GLOBAL C strtrim :NEAR
  129. PROC strtrim C near
  130. USES ax, edi, esi
  131. ARG buffer:DWORD ; Pointer to string to modify.
  132. cmp [buffer],0
  133. je short ??fini
  134. ; Prepare for string scanning by loading pointers.
  135. cld
  136. mov esi,[buffer]
  137. mov edi,esi
  138. ; Strip white space from the start of the string.
  139. ??looper:
  140. lodsb
  141. cmp al,20h ; Space
  142. je short ??looper
  143. cmp al,9 ; TAB
  144. je short ??looper
  145. stosb
  146. ; Copy the rest of the string.
  147. ??gruntloop:
  148. lodsb
  149. stosb
  150. or al,al
  151. jnz short ??gruntloop
  152. dec edi
  153. ; Strip the white space from the end of the string.
  154. ??looper2:
  155. mov [edi],al
  156. dec edi
  157. mov ah,[edi]
  158. cmp ah,20h
  159. je short ??looper2
  160. cmp ah,9
  161. je short ??looper2
  162. ??fini:
  163. ret
  164. ENDP strtrim
  165. ;***************************************************************************
  166. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
  167. ;* *
  168. ;* This routine is used to build a special fading table for C&C. There *
  169. ;* are certain colors that get faded to and cannot be faded again. *
  170. ;* With this rule, it is possible to draw a shadow multiple times and *
  171. ;* not have it get any lighter or darker. *
  172. ;* *
  173. ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
  174. ;* *
  175. ;* dest -- Pointer to the 256 byte remap table. *
  176. ;* *
  177. ;* color -- Color index of the color to "fade to". *
  178. ;* *
  179. ;* frac -- The fraction to fade to the specified color *
  180. ;* *
  181. ;* OUTPUT: Returns with pointer to the remap table. *
  182. ;* *
  183. ;* WARNINGS: none *
  184. ;* *
  185. ;* HISTORY: *
  186. ;* 10/07/1992 JLB : Created. *
  187. ;*=========================================================================*/
  188. ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
  189. GLOBAL C Conquer_Build_Fading_Table : NEAR
  190. PROC Conquer_Build_Fading_Table C near
  191. USES ebx, ecx, edi, esi
  192. ARG palette:DWORD
  193. ARG dest:DWORD
  194. ARG color:DWORD
  195. ARG frac:DWORD
  196. LOCAL matchvalue:DWORD ; Last recorded match value.
  197. LOCAL targetred:BYTE ; Target gun red.
  198. LOCAL targetgreen:BYTE ; Target gun green.
  199. LOCAL targetblue:BYTE ; Target gun blue.
  200. LOCAL idealred:BYTE
  201. LOCAL idealgreen:BYTE
  202. LOCAL idealblue:BYTE
  203. LOCAL matchcolor:BYTE ; Tentative match color.
  204. ALLOWED_COUNT EQU 16
  205. ALLOWED_START EQU 256-ALLOWED_COUNT
  206. cld
  207. ; If the source palette is NULL, then just return with current fading table pointer.
  208. cmp [palette],0
  209. je ??fini1
  210. cmp [dest],0
  211. je ??fini1
  212. ; Fractions above 255 become 255.
  213. mov eax,[frac]
  214. cmp eax,0100h
  215. jb short ??ok
  216. mov [frac],0FFh
  217. ??ok:
  218. ; Record the target gun values.
  219. mov esi,[palette]
  220. mov ebx,[color]
  221. add esi,ebx
  222. add esi,ebx
  223. add esi,ebx
  224. lodsb
  225. mov [targetred],al
  226. lodsb
  227. mov [targetgreen],al
  228. lodsb
  229. mov [targetblue],al
  230. ; Main loop.
  231. xor ebx,ebx ; Remap table index.
  232. ; Transparent black never gets remapped.
  233. mov edi,[dest]
  234. mov [edi],bl
  235. inc edi
  236. ; EBX = source palette logical number (1..255).
  237. ; EDI = running pointer into dest remap table.
  238. ??mainloop:
  239. inc ebx
  240. mov esi,[palette]
  241. add esi,ebx
  242. add esi,ebx
  243. add esi,ebx
  244. mov edx,[frac]
  245. shr edx,1
  246. ; new = orig - ((orig-target) * fraction);
  247. lodsb ; orig
  248. mov dh,al ; preserve it for later.
  249. sub al,[targetred] ; al = (orig-target)
  250. imul dl ; ax = (orig-target)*fraction
  251. shl eax,1
  252. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  253. mov [idealred],dh ; preserve ideal color gun value.
  254. lodsb ; orig
  255. mov dh,al ; preserve it for later.
  256. sub al,[targetgreen] ; al = (orig-target)
  257. imul dl ; ax = (orig-target)*fraction
  258. shl eax,1
  259. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  260. mov [idealgreen],dh ; preserve ideal color gun value.
  261. lodsb ; orig
  262. mov dh,al ; preserve it for later.
  263. sub al,[targetblue] ; al = (orig-target)
  264. imul dl ; ax = (orig-target)*fraction
  265. shl eax,1
  266. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  267. mov [idealblue],dh ; preserve ideal color gun value.
  268. ; Sweep through a limited set of existing colors to find the closest
  269. ; matching color.
  270. mov eax,[color]
  271. mov [matchcolor],al ; Default color (self).
  272. mov [matchvalue],-1 ; Ridiculous match value init.
  273. mov ecx,ALLOWED_COUNT
  274. mov esi,[palette] ; Pointer to original palette.
  275. add esi,(ALLOWED_START)*3
  276. ; BH = color index.
  277. mov bh,ALLOWED_START
  278. ??innerloop:
  279. xor edx,edx ; Comparison value starts null.
  280. ; Build the comparison value based on the sum of the differences of the color
  281. ; guns squared.
  282. lodsb
  283. sub al,[idealred]
  284. mov ah,al
  285. imul ah
  286. add edx,eax
  287. lodsb
  288. sub al,[idealgreen]
  289. mov ah,al
  290. imul ah
  291. add edx,eax
  292. lodsb
  293. sub al,[idealblue]
  294. mov ah,al
  295. imul ah
  296. add edx,eax
  297. jz short ??perfect ; If perfect match found then quit early.
  298. cmp edx,[matchvalue]
  299. jae short ??notclose
  300. mov [matchvalue],edx ; Record new possible color.
  301. mov [matchcolor],bh
  302. ??notclose:
  303. inc bh ; Checking color index.
  304. loop ??innerloop
  305. mov bh,[matchcolor]
  306. ??perfect:
  307. mov [matchcolor],bh
  308. xor bh,bh ; Make BX valid main index again.
  309. ; When the loop exits, we have found the closest match.
  310. mov al,[matchcolor]
  311. stosb
  312. cmp ebx,ALLOWED_START-1
  313. jne ??mainloop
  314. ; Fill the remainder of the remap table with values
  315. ; that will remap the color to itself.
  316. mov ecx,ALLOWED_COUNT
  317. ??fillerloop:
  318. inc bl
  319. mov al,bl
  320. stosb
  321. loop ??fillerloop
  322. ??fini1:
  323. mov esi,[dest]
  324. mov eax,esi
  325. ret
  326. ENDP Conquer_Build_Fading_Table
  327. ;***************************************************************************
  328. ;* Remove_From_List -- Removes a pointer from a list of pointers. *
  329. ;* *
  330. ;* This low level routine is used to remove a pointer from a list of *
  331. ;* pointers. The trailing pointers are moved downward to fill the *
  332. ;* hole. *
  333. ;* *
  334. ;* INPUT: list -- Pointer to list of pointer. *
  335. ;* *
  336. ;* index -- Pointer to length of pointer list. *
  337. ;* *
  338. ;* ptr -- The pointer value to search for and remove. *
  339. ;* *
  340. ;* OUTPUT: none *
  341. ;* *
  342. ;* WARNINGS: none *
  343. ;* *
  344. ;* HISTORY: *
  345. ;* 04/11/1994 JLB : Created. *
  346. ;* 04/22/1994 JLB : Convert to assembly language. *
  347. ;* 05/10/1994 JLB : Short pointers now. *
  348. ;*=========================================================================*/
  349. ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
  350. GLOBAL C Remove_From_List:NEAR
  351. PROC Remove_From_List C near
  352. USES edi, esi, ecx, eax
  353. ARG list:DWORD ; Pointer to list.
  354. ARG index:DWORD ; Pointer to count.
  355. ARG element:DWORD ; Element to remove.
  356. ; Fetch the number of elements in the list. If there are no
  357. ; elements, then just exit quickly.
  358. mov edi,[index]
  359. mov ecx,[edi]
  360. jcxz short ??fini2
  361. ; Fetch pointer to list.
  362. cmp [list],0
  363. je short ??fini2
  364. mov edi,[list]
  365. ; Loop through all elements searching for a match.
  366. mov eax,[element]
  367. repne scasd
  368. jne short ??fini2 ; No match found.
  369. ; Copy all remaining elements down. If this is the
  370. ; last element in the list then nothing needs to be
  371. ; copied -- just decrement the list size.
  372. jcxz short ??nocopy ; No copy necessary.
  373. mov esi,edi
  374. sub edi,4
  375. rep movsd
  376. ; Reduce the list count by one.
  377. ??nocopy:
  378. mov edi,[index]
  379. dec [DWORD PTR edi]
  380. ??fini2:
  381. ret
  382. ENDP Remove_From_List
  383. ; long cdecl Get_EAX();
  384. GLOBAL C Get_EAX :NEAR
  385. PROC Get_EAX C near
  386. ret
  387. ENDP Get_EAX
  388. endif
  389. DATASEG
  390. TabA DD 6949350
  391. DD 4913933
  392. DD 3474675
  393. DD 2456966
  394. DD 1737338
  395. DD 1228483
  396. DD 868669
  397. DD 614242
  398. DD 434334
  399. DD 307121
  400. DD 217167
  401. DD 153560
  402. DD 108584
  403. DD 76780
  404. DD 54292
  405. DD 38390
  406. DD 27146
  407. DD 19195
  408. DD 13573
  409. DD 9598
  410. DD 6786
  411. DD 4799
  412. DD 3393
  413. DD 2399
  414. DD 1697
  415. DD 1200
  416. DD 848
  417. DD 600
  418. DD 424
  419. DD 300
  420. DD 212
  421. DD 150
  422. DD 106
  423. TabB DD 154
  424. DD 218
  425. DD 309
  426. DD 437
  427. DD 618
  428. DD 874
  429. DD 1236
  430. DD 1748
  431. DD 2472
  432. DD 3496
  433. DD 4944
  434. DD 6992
  435. DD 9888
  436. DD 13983
  437. DD 19775
  438. DD 27967
  439. DD 39551
  440. DD 55933
  441. DD 79101
  442. DD 111866
  443. DD 158203
  444. DD 223732
  445. DD 316405
  446. DD 447465
  447. DD 632811
  448. DD 894929
  449. DD 1265621
  450. DD 1789859
  451. DD 2531243
  452. DD 3579718
  453. DD 5062486
  454. DD 7159436
  455. DD 10124971
  456. CODESEG
  457. ;***********************************************************************************************
  458. ;* Square_Root -- Finds the square root of the fixed pointer parameter. *
  459. ;* *
  460. ;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
  461. ;* *
  462. ;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
  463. ;* *
  464. ;* WARNINGS: none *
  465. ;* *
  466. ;* HISTORY: *
  467. ;* 10/04/1995 JLB : Adapted. *
  468. ;*=============================================================================================*/
  469. ;unsigned Square_Root(unsigned val);
  470. GLOBAL C Square_Root :NEAR
  471. PROC Square_Root C near
  472. USES ebx,edx
  473. bsr ebx,eax
  474. jz ??zero
  475. mul [DWORD 4*ebx + OFFSET TabA]
  476. shrd eax,edx,10h
  477. add eax, [4*ebx + OFFSET TabB]
  478. ??zero:
  479. ret
  480. ENDP Square_Root
  481. ;----------------------------------------------------------------------------
  482. END