MiscAsm.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  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. /*
  15. **
  16. ** Misc. assembly code moved from headers
  17. **
  18. **
  19. **
  20. **
  21. **
  22. */
  23. #include "FUNCTION.H"
  24. extern "C" void __cdecl Mem_Copy(void const *source, void *dest, unsigned long bytes_to_copy)
  25. {
  26. memcpy(dest, source, bytes_to_copy);
  27. }
  28. /***********************************************************************************************
  29. * Distance -- Determines the lepton distance between two coordinates. *
  30. * *
  31. * This routine is used to determine the distance between two coordinates. It uses the *
  32. * Dragon Strike method of distance determination and thus it is very fast. *
  33. * *
  34. * INPUT: coord1 -- First coordinate. *
  35. * *
  36. * coord2 -- Second coordinate. *
  37. * *
  38. * OUTPUT: Returns the lepton distance between the two coordinates. *
  39. * *
  40. * WARNINGS: none *
  41. * *
  42. * HISTORY: *
  43. * 05/27/1994 JLB : Created. *
  44. *=============================================================================================*/
  45. int Distance_Coord(COORDINATE coord1, COORDINATE coord2)
  46. {
  47. __asm {
  48. mov eax,[coord1]
  49. mov ebx,[coord2]
  50. mov dx,ax
  51. sub dx,bx
  52. jg okx
  53. neg dx
  54. okx:
  55. shr eax,16
  56. shr ebx,16
  57. sub ax,bx
  58. jg oky
  59. neg ax
  60. oky:
  61. cmp ax,dx
  62. jg ok
  63. xchg ax,dx
  64. ok:
  65. shr dx,1
  66. add ax,dx
  67. }
  68. }
  69. /*
  70. ;***************************************************************************
  71. ;* DESIRED_FACING16 -- Converts coordinates into a facing number. *
  72. ;* *
  73. ;* This converts coordinates into a desired facing number that ranges *
  74. ;* from 0 to 15 (0 equals North and going clockwise). *
  75. ;* *
  76. ;* INPUT: x1,y1 -- Position of origin point. *
  77. ;* *
  78. ;* x2,y2 -- Position of target. *
  79. ;* *
  80. ;* OUTPUT: Returns desired facing as a number from 0 to 255 but *
  81. ;* accurate to 22.5 degree increments. *
  82. ;* *
  83. ;* WARNINGS: If the two coordinates are the same, then -1 will be *
  84. ;* returned. It is up to you to handle this case. *
  85. ;* *
  86. ;* HISTORY: *
  87. ;* 08/14/1991 JLB : Created. *
  88. ;*=========================================================================*
  89. */
  90. long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2)
  91. {
  92. static const char _new_facing16[] = {
  93. 3, 2, 4,-1, 1, 2,0,-1,
  94. 13,14,12,-1,15,14,0,-1,
  95. 5, 6, 4,-1, 7, 6,8,-1,
  96. 11,10,12,-1, 9,10,8,-1
  97. };
  98. __asm {
  99. xor ebx,ebx //; Index byte (built).
  100. //; Determine Y axis difference.
  101. mov edx,[y1]
  102. mov ecx,[y2]
  103. sub edx,ecx //; DX = Y axis (signed).
  104. jns short absy
  105. inc ebx //; Set the signed bit.
  106. neg edx //; ABS(y)
  107. absy:
  108. //; Determine X axis difference.
  109. shl ebx,1
  110. mov eax,[x1]
  111. mov ecx,[x2]
  112. sub ecx,eax //; CX = X axis (signed).
  113. jns short absx
  114. inc ebx //; Set the signed bit.
  115. neg ecx //; ABS(x)
  116. absx:
  117. //; Determine the greater axis.
  118. cmp ecx,edx
  119. jb short dxisbig
  120. xchg ecx,edx
  121. dxisbig:
  122. rcl ebx,1 //; Y > X flag bit.
  123. //; Determine the closeness or farness of lesser axis.
  124. mov eax,edx
  125. inc eax //; Round up.
  126. shr eax,1
  127. inc eax //; Round up.
  128. shr eax,1 //; 1/4 of greater axis.
  129. cmp ecx,eax
  130. rcl ebx,1 //; Very close to major axis bit.
  131. sub edx,eax
  132. cmp edx,ecx
  133. rcl ebx,1 //; Very far from major axis bit.
  134. xor eax,eax
  135. mov al,[_new_facing16+ebx]
  136. //; Normalize to 0..FF range.
  137. shl eax,4
  138. // ret
  139. }
  140. }
  141. /*
  142. ;***************************************************************************
  143. ;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. *
  144. ;* *
  145. ;* This is a desired facing algorithm that has a resolution of 0 *
  146. ;* through 255. *
  147. ;* *
  148. ;* INPUT: srcx,srcy -- Source coordinate. *
  149. ;* *
  150. ;* dstx,dsty -- Destination coordinate. *
  151. ;* *
  152. ;* OUTPUT: Returns with the desired facing to face the destination *
  153. ;* coordinate from the position of the source coordinate. North *
  154. ;* is 0, East is 64, etc. *
  155. ;* *
  156. ;* WARNINGS: This routine is slower than the other forms of desired *
  157. ;* facing calculation. Use this routine when accuracy is *
  158. ;* required. *
  159. ;* *
  160. ;* HISTORY: *
  161. ;* 12/24/1991 JLB : Adapted. *
  162. ;*=========================================================================*/
  163. int __cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty)
  164. {
  165. __asm {
  166. xor ebx,ebx //; Facing number.
  167. ////; Determine absolute X delta and left/right direction.
  168. mov ecx,[dstx]
  169. sub ecx,[srcx]
  170. jge short xnotneg
  171. neg ecx
  172. mov ebx,11000000b //; Set bit 7 and 6 for leftward.
  173. xnotneg:
  174. //; Determine absolute Y delta and top/bottom direction.
  175. mov eax,[srcy]
  176. sub eax,[dsty]
  177. jge short ynotneg
  178. xor ebx,01000000b //; Complement bit 6 for downward.
  179. neg eax
  180. ynotneg:
  181. //; Set DX=64 for quadrants 0 and 2.
  182. mov edx,ebx
  183. and edx,01000000b
  184. xor edx,01000000b
  185. //; Determine if the direction is closer to the Y axis and make sure that
  186. //; CX holds the larger of the two deltas. This is in preparation for the
  187. //; divide.
  188. cmp eax,ecx
  189. jb short gotaxis
  190. xchg eax,ecx
  191. xor edx,01000000b //; Closer to Y axis so make DX=64 for quad 0 and 2.
  192. gotaxis:
  193. //; If closer to the X axis then add 64 for quadrants 0 and 2. If
  194. //; closer to the Y axis then add 64 for quadrants 1 and 3. Determined
  195. //; add value is in DX and save on stack.
  196. push edx
  197. //; Make sure that the division won't overflow. Reduce precision until
  198. //; the larger number is less than 256 if it appears that an overflow
  199. //; will occur. If the high byte of the divisor is not zero, then this
  200. //; guarantees no overflow, so just abort shift operation.
  201. test eax,0FFFFFF00h
  202. jnz short nooverflow
  203. again:
  204. test ecx,0FFFFFF00h
  205. jz short nooverflow
  206. shr ecx,1
  207. shr eax,1
  208. jmp short again
  209. nooverflow:
  210. //; Make sure that the division won't underflow (divide by zero). If
  211. //; this would occur, then set the quotient to $FF and skip divide.
  212. or ecx,ecx
  213. jnz short nounderflow
  214. mov eax,0FFFFFFFFh
  215. jmp short divcomplete
  216. //; Derive a pseudo angle number for the octant. The angle is based
  217. //; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
  218. nounderflow:
  219. xor edx,edx
  220. shld edx,eax,8 //; shift high byte of eax into dl
  221. shl eax,8
  222. div ecx
  223. divcomplete:
  224. //; Integrate the 5 most significant bits into the angle index. If DX
  225. //; is not zero, then it is 64. This means that the dividend must be negated
  226. //; before it is added into the final angle value.
  227. shr eax,3
  228. pop edx
  229. or edx,edx
  230. je short noneg
  231. dec edx
  232. neg eax
  233. noneg:
  234. add eax,edx
  235. add eax,ebx
  236. and eax,0FFH
  237. // ret
  238. }
  239. }
  240. /*
  241. ;***************************************************************************
  242. ;** 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 **
  243. ;***************************************************************************
  244. ;* *
  245. ;* Project Name : Support Library *
  246. ;* *
  247. ;* File Name : FACING8.ASM *
  248. ;* *
  249. ;* Programmer : Joe L. Bostic *
  250. ;* *
  251. ;* Start Date : May 8, 1991 *
  252. ;* *
  253. ;* Last Update : February 6, 1995 [BWG] *
  254. ;* *
  255. ;*-------------------------------------------------------------------------*
  256. ;* Functions: *
  257. ;* Desired_Facing8 -- Determines facing to reach a position. *
  258. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  259. IDEAL
  260. P386
  261. MODEL USE32 FLAT
  262. GLOBAL C Desired_Facing8 :NEAR
  263. ; INCLUDE "wwlib.i"
  264. DATASEG
  265. ; 8 direction desired facing lookup table. Build the index according
  266. ; to the following bits:
  267. ;
  268. ; bit 3 = Is y2 < y1?
  269. ; bit 2 = Is x2 < x1?
  270. ; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)?
  271. ; bit 0 = Is the facing closer to a major axis?
  272. //NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4
  273. // CODESEG
  274. */
  275. /*
  276. ;***************************************************************************
  277. ;* DESIRED_FACING8 -- Determines facing to reach a position. *
  278. ;* *
  279. ;* This routine will return with the most desirable facing to reach *
  280. ;* one position from another. It is accurate to a resolution of 0 to *
  281. ;* 7. *
  282. ;* *
  283. ;* INPUT: x1,y1 -- Position of origin point. *
  284. ;* *
  285. ;* x2,y2 -- Position of target. *
  286. ;* *
  287. ;* OUTPUT: Returns desired facing as a number from 0..255 with an *
  288. ;* accuracy of 32 degree increments. *
  289. ;* *
  290. ;* WARNINGS: If the two coordinates are the same, then -1 will be *
  291. ;* returned. It is up to you to handle this case. *
  292. ;* *
  293. ;* HISTORY: *
  294. ;* 07/15/1991 JLB : Documented. *
  295. ;* 08/08/1991 JLB : Same position check. *
  296. ;* 08/14/1991 JLB : New algorithm *
  297. ;* 02/06/1995 BWG : Convert to 32-bit *
  298. ;*=========================================================================*
  299. */
  300. int __cdecl Desired_Facing8(long x1, long y1, long x2, long y2)
  301. {
  302. static const char _new_facing8[] = {1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4};
  303. __asm {
  304. xor ebx,ebx //; Index byte (built).
  305. //; Determine Y axis difference.
  306. mov edx,[y1]
  307. mov ecx,[y2]
  308. sub edx,ecx //; DX = Y axis (signed).
  309. jns short absy
  310. inc ebx //; Set the signed bit.
  311. neg edx //; ABS(y)
  312. absy:
  313. //; Determine X axis difference.
  314. shl ebx,1
  315. mov eax,[x1]
  316. mov ecx,[x2]
  317. sub ecx,eax //; CX = X axis (signed).
  318. jns short absx
  319. inc ebx //; Set the signed bit.
  320. neg ecx //; ABS(x)
  321. absx:
  322. //; Determine the greater axis.
  323. cmp ecx,edx
  324. jb short dxisbig
  325. xchg ecx,edx
  326. dxisbig:
  327. rcl ebx,1 //; Y > X flag bit.
  328. //; Determine the closeness or farness of lesser axis.
  329. mov eax,edx
  330. inc eax //; Round up.
  331. shr eax,1
  332. cmp ecx,eax
  333. rcl ebx,1 //; Close to major axis bit.
  334. xor eax,eax
  335. mov al,[_new_facing8+ebx]
  336. //; Normalize to 0..FF range.
  337. shl eax,5
  338. // ret
  339. }
  340. }
  341. #if (0)
  342. /*
  343. ; $Header: //depot/Projects/Mobius/QA/Project/Run/SOURCECODE/TIBERIANDAWN/MiscAsm.cpp#139 $
  344. ;***************************************************************************
  345. ;** 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 **
  346. ;***************************************************************************
  347. ;* *
  348. ;* Project Name : Support Library *
  349. ;* *
  350. ;* File Name : FACING16.ASM *
  351. ;* *
  352. ;* Programmer : Joe L. Bostic *
  353. ;* *
  354. ;* Start Date : May 8, 1991 *
  355. ;* *
  356. ;* Last Update : February 6, 1995 [BWG] *
  357. ;* *
  358. ;*-------------------------------------------------------------------------*
  359. ;* Functions: *
  360. ;* Desired_Facing16 -- Converts coordinates into a facing number. *
  361. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  362. IDEAL
  363. P386
  364. MODEL USE32 FLAT
  365. GLOBAL C Desired_Facing16 :NEAR
  366. ; INCLUDE "wwlib.i"
  367. DATASEG
  368. ; 16 direction desired facing lookup table. Build the index according
  369. ; to the following bits:
  370. ;
  371. ; bit 4 = Is y2 < y1?
  372. ; bit 3 = Is x2 < x1?
  373. ; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)?
  374. ; bit 1 = Is the lesser absolute difference very close to zero?
  375. ; bit 0 = Is the lesser absolute difference very close to the greater dist?
  376. NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1
  377. DB 13,14,12,-1,15,14,0,-1
  378. DB 5, 6, 4,-1, 7, 6,8,-1
  379. DB 11,10,12,-1, 9,10,8,-1
  380. CODESEG
  381. ;***************************************************************************
  382. ;* DESIRED_FACING16 -- Converts coordinates into a facing number. *
  383. ;* *
  384. ;* This converts coordinates into a desired facing number that ranges *
  385. ;* from 0 to 15 (0 equals North and going clockwise). *
  386. ;* *
  387. ;* INPUT: x1,y1 -- Position of origin point. *
  388. ;* *
  389. ;* x2,y2 -- Position of target. *
  390. ;* *
  391. ;* OUTPUT: Returns desired facing as a number from 0 to 255 but *
  392. ;* accurate to 22.5 degree increments. *
  393. ;* *
  394. ;* WARNINGS: If the two coordinates are the same, then -1 will be *
  395. ;* returned. It is up to you to handle this case. *
  396. ;* *
  397. ;* HISTORY: *
  398. ;* 08/14/1991 JLB : Created. *
  399. ;*=========================================================================*
  400. */
  401. long __cdecl Desired_Facing16(long x1, long y1, long x2, long y2)
  402. {
  403. __asm {
  404. xor ebx,ebx ; Index byte (built).
  405. ; Determine Y axis difference.
  406. mov edx,[y1]
  407. mov ecx,[y2]
  408. sub edx,ecx //; DX = Y axis (signed).
  409. jns short absy
  410. inc ebx //; Set the signed bit.
  411. neg edx //; ABS(y)
  412. absy:
  413. //; Determine X axis difference.
  414. shl ebx,1
  415. mov eax,[x1]
  416. mov ecx,[x2]
  417. sub ecx,eax //; CX = X axis (signed).
  418. jns short absx
  419. inc ebx //; Set the signed bit.
  420. neg ecx //; ABS(x)
  421. absx:
  422. //; Determine the greater axis.
  423. cmp ecx,edx
  424. jb short dxisbig
  425. xchg ecx,edx
  426. dxisbig:
  427. rcl ebx,1 //; Y > X flag bit.
  428. //; Determine the closeness or farness of lesser axis.
  429. mov eax,edx
  430. inc eax //; Round up.
  431. shr eax,1
  432. inc eax //; Round up.
  433. shr eax,1 //; 1/4 of greater axis.
  434. cmp ecx,eax
  435. rcl ebx,1 //; Very close to major axis bit.
  436. sub edx,eax
  437. cmp edx,ecx
  438. rcl ebx,1 //; Very far from major axis bit.
  439. xor eax,eax
  440. mov al,[NewFacing16+ebx]
  441. //; Normalize to 0..FF range.
  442. shl eax,4
  443. // ret
  444. }
  445. }
  446. #if (0)
  447. PROC Desired_Facing16 C near
  448. USES ebx, ecx, edx
  449. ARG x1:DWORD
  450. ARG y1:DWORD
  451. ARG x2:DWORD
  452. ARG y2:DWORD
  453. xor ebx,ebx ; Index byte (built).
  454. ; Determine Y axis difference.
  455. mov edx,[y1]
  456. mov ecx,[y2]
  457. sub edx,ecx ; DX = Y axis (signed).
  458. jns short ??absy
  459. inc ebx ; Set the signed bit.
  460. neg edx ; ABS(y)
  461. ??absy:
  462. ; Determine X axis difference.
  463. shl ebx,1
  464. mov eax,[x1]
  465. mov ecx,[x2]
  466. sub ecx,eax ; CX = X axis (signed).
  467. jns short ??absx
  468. inc ebx ; Set the signed bit.
  469. neg ecx ; ABS(x)
  470. ??absx:
  471. ; Determine the greater axis.
  472. cmp ecx,edx
  473. jb short ??dxisbig
  474. xchg ecx,edx
  475. ??dxisbig:
  476. rcl ebx,1 ; Y > X flag bit.
  477. ; Determine the closeness or farness of lesser axis.
  478. mov eax,edx
  479. inc eax ; Round up.
  480. shr eax,1
  481. inc eax ; Round up.
  482. shr eax,1 ; 1/4 of greater axis.
  483. cmp ecx,eax
  484. rcl ebx,1 ; Very close to major axis bit.
  485. sub edx,eax
  486. cmp edx,ecx
  487. rcl ebx,1 ; Very far from major axis bit.
  488. xor eax,eax
  489. mov al,[NewFacing16+ebx]
  490. ; Normalize to 0..FF range.
  491. shl eax,4
  492. ret
  493. ENDP Desired_Facing16
  494. END
  495. #endif
  496. #endif
  497. /*
  498. ;***********************************************************************************************
  499. ;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
  500. ;* *
  501. ;* This utility function will convert cardinal numbers into a fixed point fraction. The *
  502. ;* use of fixed point numbers occurs throughout the product -- since it is a convenient *
  503. ;* tool. The fixed point number is based on the formula: *
  504. ;* *
  505. ;* result = cardinal / base *
  506. ;* *
  507. ;* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to *
  508. ;* 256 as the largest. *
  509. ;* *
  510. ;* INPUT: base -- The key number to base the fraction about. *
  511. ;* *
  512. ;* cardinal -- The other number (hey -- what do you call it?) *
  513. ;* *
  514. ;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates *
  515. ;* to the "base" parameter. *
  516. ;* *
  517. ;* WARNINGS: none *
  518. ;* *
  519. ;* HISTORY: *
  520. ;* 02/17/1995 BWG : Created. *
  521. ;*=============================================================================================*/
  522. unsigned int __cdecl Cardinal_To_Fixed(unsigned base, unsigned cardinal)
  523. {
  524. __asm {
  525. mov eax,0FFFFh //; establish default return value
  526. mov ebx,[base]
  527. or ebx, ebx
  528. jz retneg1 //; if base==0, return 65535
  529. mov eax,[cardinal] //; otherwise, return (cardinal*256)/base
  530. shl eax,8
  531. xor edx,edx
  532. div ebx
  533. retneg1:
  534. //ret
  535. }
  536. }
  537. #if (0)
  538. PROC Cardinal_To_Fixed C near
  539. USES ebx, edx
  540. ARG base:DWORD
  541. ARG cardinal:DWORD
  542. mov eax,0FFFFh ; establish default return value
  543. mov ebx,[base]
  544. or ebx,ebx
  545. jz near ??retneg1 ; if base==0, return 65535
  546. mov eax,[cardinal] ; otherwise, return (cardinal*256)/base
  547. shl eax,8
  548. xor edx,edx
  549. div ebx
  550. ??retneg1:
  551. ret
  552. ENDP Cardinal_To_Fixed
  553. #endif
  554. /*
  555. ;***********************************************************************************************
  556. ;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
  557. ;* *
  558. ;* Use this routine to convert a fixed point number into a cardinal number. *
  559. ;* *
  560. ;* INPUT: base -- The base number that the original fixed point number was created from. *
  561. ;* *
  562. ;* fixed -- The fixed point number to convert. *
  563. ;* *
  564. ;* OUTPUT: Returns with the reconverted number. *
  565. ;* *
  566. ;* WARNINGS: none *
  567. ;* *
  568. ;* HISTORY: *
  569. ;* 02/17/1995 BWG : Created. *
  570. ;*=============================================================================================*/
  571. unsigned int __cdecl Fixed_To_Cardinal(unsigned base, unsigned fixed)
  572. {
  573. // PROC Fixed_To_Cardinal C near
  574. // USES edx
  575. // ARG base:DWORD
  576. // ARG fixed:DWORD
  577. __asm {
  578. mov eax,[base]
  579. mul [fixed]
  580. add eax,080h //; eax = (base * fixed) + 0x80
  581. test eax,0FF000000h //; if high byte set, return FFFF
  582. jnz rneg1
  583. shr eax,8 //; else, return eax/256
  584. jmp all_done
  585. rneg1:
  586. mov eax,0FFFFh //; establish default return value
  587. all_done:
  588. //ret
  589. }
  590. #if (0)
  591. mov eax,[base]
  592. mul [fixed]
  593. add eax,080h ; eax = (base * fixed) + 0x80
  594. test eax,0FF000000h ; if high byte set, return FFFF
  595. jnz ??rneg1
  596. shr eax,8 ; else, return eax/256
  597. ret
  598. ??rneg1 :
  599. mov eax,0FFFFh ; establish default return value
  600. ret
  601. ENDP Fixed_To_Cardinal
  602. END
  603. #endif
  604. }
  605. void __cdecl Set_Bit(void * array, int bit, int value)
  606. {
  607. __asm {
  608. mov ecx, [bit]
  609. mov eax, [value]
  610. mov esi, [array]
  611. mov ebx,ecx
  612. shr ebx,5
  613. and ecx,01Fh
  614. btr [esi+ebx*4],ecx
  615. or eax,eax
  616. jz ok
  617. bts [esi+ebx*4],ecx
  618. ok:
  619. }
  620. }
  621. int __cdecl Get_Bit(void const * array, int bit)
  622. {
  623. __asm {
  624. mov eax, [bit]
  625. mov esi, [array]
  626. mov ebx,eax
  627. shr ebx,5
  628. and eax,01Fh
  629. bt [esi+ebx*4],eax
  630. setc al
  631. }
  632. }
  633. int __cdecl First_True_Bit(void const * array)
  634. {
  635. __asm {
  636. mov esi, [array]
  637. mov eax,-32
  638. again:
  639. add eax,32
  640. mov ebx,[esi]
  641. add esi,4
  642. bsf ebx,ebx
  643. jz again
  644. add eax,ebx
  645. }
  646. }
  647. int __cdecl First_False_Bit(void const * array)
  648. {
  649. __asm {
  650. mov esi, [array]
  651. mov eax,-32
  652. again:
  653. add eax,32
  654. mov ebx,[esi]
  655. not ebx
  656. add esi,4
  657. bsf ebx,ebx
  658. jz again
  659. add eax,ebx
  660. }
  661. }
  662. int __cdecl Bound(int original, int min, int max)
  663. {
  664. __asm {
  665. mov eax,[original]
  666. mov ebx,[min]
  667. mov ecx,[max]
  668. cmp ebx,ecx
  669. jl okorder
  670. xchg ebx,ecx
  671. okorder: cmp eax,ebx
  672. jg okmin
  673. mov eax,ebx
  674. okmin: cmp eax,ecx
  675. jl okmax
  676. mov eax,ecx
  677. okmax:
  678. }
  679. }
  680. CELL __cdecl Coord_Cell(COORDINATE coord)
  681. {
  682. __asm {
  683. mov eax, coord
  684. mov ebx,eax
  685. shr eax,010h
  686. xor al,al
  687. shr eax,2
  688. or al,bh
  689. }
  690. }
  691. /*
  692. ;***********************************************************
  693. ; SHAKE_SCREEN
  694. ;
  695. ; VOID Shake_Screen(int shakes);
  696. ;
  697. ; This routine shakes the screen the number of times indicated.
  698. ;
  699. ; Bounds Checking: None
  700. ;
  701. ;*
  702. */
  703. void __cdecl Shake_Screen(int shakes)
  704. {
  705. // PG_TO_FIX
  706. // Need a different solution for shaking the screen
  707. shakes;
  708. }
  709. #if (0)
  710. GLOBAL C Shake_Screen :NEAR
  711. CODESEG
  712. ;***********************************************************
  713. ; SHAKE_SCREEN
  714. ;
  715. ; VOID Shake_Screen(int shakes);
  716. ;
  717. ; This routine shakes the screen the number of times indicated.
  718. ;
  719. ; Bounds Checking: None
  720. ;
  721. ;*
  722. PROC Shake_Screen C near
  723. USES ecx, edx
  724. ARG shakes:DWORD
  725. ret
  726. mov ecx,[shakes]
  727. ;;; push es
  728. ;;; mov ax,40h
  729. ;;; mov es,ax
  730. ;;; mov dx,[es:63h]
  731. ;;; pop es
  732. mov eax,[0463h] ; get CRTC I/O port
  733. mov dx,ax
  734. add dl,6 ; video status port
  735. ??top_loop:
  736. ??start_retrace:
  737. in al,dx
  738. test al,8
  739. jz ??start_retrace
  740. ??end_retrace:
  741. in al,dx
  742. test al,8
  743. jnz ??end_retrace
  744. cli
  745. sub dl,6 ; dx = 3B4H or 3D4H
  746. mov ah,01 ; top word of start address
  747. mov al,0Ch
  748. out dx,al
  749. xchg ah,al
  750. inc dx
  751. out dx,al
  752. xchg ah,al
  753. dec dx
  754. mov ah,040h ; bottom word = 40 (140h)
  755. inc al
  756. out dx,al
  757. xchg ah,al
  758. inc dx
  759. out dx,al
  760. xchg ah,al
  761. sti
  762. add dl,5
  763. ??start_retrace2:
  764. in al,dx
  765. test al,8
  766. jz ??start_retrace2
  767. ??end_retrace2:
  768. in al,dx
  769. test al,8
  770. jnz ??end_retrace2
  771. ??start_retrace3:
  772. in al,dx
  773. test al,8
  774. jz ??start_retrace3
  775. ??end_retrace3:
  776. in al,dx
  777. test al,8
  778. jnz ??end_retrace3
  779. cli
  780. sub dl,6 ; dx = 3B4H or 3D4H
  781. mov ah,0
  782. mov al,0Ch
  783. out dx,al
  784. xchg ah,al
  785. inc dx
  786. out dx,al
  787. xchg ah,al
  788. dec dx
  789. mov ah,0
  790. inc al
  791. out dx,al
  792. xchg ah,al
  793. inc dx
  794. out dx,al
  795. xchg ah,al
  796. sti
  797. add dl,5
  798. loop ??top_loop
  799. ret
  800. ENDP Shake_Screen
  801. ;***********************************************************
  802. END
  803. #endif
  804. /*
  805. ;***************************************************************************
  806. ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
  807. ;* *
  808. ;* This routine is used to build a special fading table for C&C. There *
  809. ;* are certain colors that get faded to and cannot be faded again. *
  810. ;* With this rule, it is possible to draw a shadow multiple times and *
  811. ;* not have it get any lighter or darker. *
  812. ;* *
  813. ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
  814. ;* *
  815. ;* dest -- Pointer to the 256 byte remap table. *
  816. ;* *
  817. ;* color -- Color index of the color to "fade to". *
  818. ;* *
  819. ;* frac -- The fraction to fade to the specified color *
  820. ;* *
  821. ;* OUTPUT: Returns with pointer to the remap table. *
  822. ;* *
  823. ;* WARNINGS: none *
  824. ;* *
  825. ;* HISTORY: *
  826. ;* 10/07/1992 JLB : Created. *
  827. ;*=========================================================================*/
  828. void * __cdecl Conquer_Build_Fading_Table(void const *palette, void *dest, int color, int frac)
  829. {
  830. /*
  831. global C Conquer_Build_Fading_Table : NEAR
  832. PROC Conquer_Build_Fading_Table C near
  833. USES ebx, ecx, edi, esi
  834. ARG palette:DWORD
  835. ARG dest:DWORD
  836. ARG color:DWORD
  837. ARG frac:DWORD
  838. LOCAL matchvalue:DWORD ; Last recorded match value.
  839. LOCAL targetred:BYTE ; Target gun red.
  840. LOCAL targetgreen:BYTE ; Target gun green.
  841. LOCAL targetblue:BYTE ; Target gun blue.
  842. LOCAL idealred:BYTE
  843. LOCAL idealgreen:BYTE
  844. LOCAL idealblue:BYTE
  845. LOCAL matchcolor:BYTE ; Tentative match color.
  846. ALLOWED_COUNT EQU 16
  847. ALLOWED_START EQU 256-ALLOWED_COUNT
  848. */
  849. #define ALLOWED_COUNT 16
  850. #define ALLOWED_START 256-ALLOWED_COUNT
  851. int matchvalue = 0; //:DWORD ; Last recorded match value.
  852. unsigned char targetred = 0; //BYTE ; Target gun red.
  853. unsigned char targetgreen = 0; //BYTE ; Target gun green.
  854. unsigned char targetblue = 0; //BYTE ; Target gun blue.
  855. unsigned char idealred = 0; //BYTE
  856. unsigned char idealgreen = 0; //BYTE
  857. unsigned char idealblue = 0; //BYTE
  858. unsigned char matchcolor = 0; //:BYTE ; Tentative match color.
  859. __asm {
  860. cld
  861. ; If the source palette is NULL, then just return with current fading table pointer.
  862. cmp [palette],0
  863. je fini1
  864. cmp [dest],0
  865. je fini1
  866. ; Fractions above 255 become 255.
  867. mov eax,[frac]
  868. cmp eax,0100h
  869. jb short ok
  870. mov [frac],0FFh
  871. ok:
  872. ; Record the target gun values.
  873. mov esi,[palette]
  874. mov ebx,[color]
  875. add esi,ebx
  876. add esi,ebx
  877. add esi,ebx
  878. lodsb
  879. mov [targetred],al
  880. lodsb
  881. mov [targetgreen],al
  882. lodsb
  883. mov [targetblue],al
  884. ; Main loop.
  885. xor ebx,ebx ; Remap table index.
  886. ; Transparent black never gets remapped.
  887. mov edi,[dest]
  888. mov [edi],bl
  889. inc edi
  890. ; EBX = source palette logical number (1..255).
  891. ; EDI = running pointer into dest remap table.
  892. mainloop:
  893. inc ebx
  894. mov esi,[palette]
  895. add esi,ebx
  896. add esi,ebx
  897. add esi,ebx
  898. mov edx,[frac]
  899. shr edx,1
  900. ; new = orig - ((orig-target) * fraction);
  901. lodsb ; orig
  902. mov dh,al ; preserve it for later.
  903. sub al,[targetred] ; al = (orig-target)
  904. imul dl ; ax = (orig-target)*fraction
  905. shl eax,1
  906. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  907. mov [idealred],dh ; preserve ideal color gun value.
  908. lodsb ; orig
  909. mov dh,al ; preserve it for later.
  910. sub al,[targetgreen] ; al = (orig-target)
  911. imul dl ; ax = (orig-target)*fraction
  912. shl eax,1
  913. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  914. mov [idealgreen],dh ; preserve ideal color gun value.
  915. lodsb ; orig
  916. mov dh,al ; preserve it for later.
  917. sub al,[targetblue] ; al = (orig-target)
  918. imul dl ; ax = (orig-target)*fraction
  919. shl eax,1
  920. sub dh,ah ; dh = orig - ((orig-target) * fraction)
  921. mov [idealblue],dh ; preserve ideal color gun value.
  922. ; Sweep through a limited set of existing colors to find the closest
  923. ; matching color.
  924. mov eax,[color]
  925. mov [matchcolor],al ; Default color (self).
  926. mov [matchvalue],-1 ; Ridiculous match value init.
  927. mov ecx,ALLOWED_COUNT
  928. mov esi,[palette] ; Pointer to original palette.
  929. add esi,(ALLOWED_START)*3
  930. ; BH = color index.
  931. mov bh,ALLOWED_START
  932. innerloop:
  933. xor edx,edx ; Comparison value starts null.
  934. ; Build the comparison value based on the sum of the differences of the color
  935. ; guns squared.
  936. lodsb
  937. sub al,[idealred]
  938. mov ah,al
  939. imul ah
  940. add edx,eax
  941. lodsb
  942. sub al,[idealgreen]
  943. mov ah,al
  944. imul ah
  945. add edx,eax
  946. lodsb
  947. sub al,[idealblue]
  948. mov ah,al
  949. imul ah
  950. add edx,eax
  951. jz short perfect ; If perfect match found then quit early.
  952. cmp edx,[matchvalue]
  953. jae short notclose
  954. mov [matchvalue],edx ; Record new possible color.
  955. mov [matchcolor],bh
  956. notclose:
  957. inc bh ; Checking color index.
  958. loop innerloop
  959. mov bh,[matchcolor]
  960. perfect:
  961. mov [matchcolor],bh
  962. xor bh,bh ; Make BX valid main index again.
  963. ; When the loop exits, we have found the closest match.
  964. mov al,[matchcolor]
  965. stosb
  966. cmp ebx,ALLOWED_START-1
  967. jne mainloop
  968. ; Fill the remainder of the remap table with values
  969. ; that will remap the color to itself.
  970. mov ecx,ALLOWED_COUNT
  971. fillerloop:
  972. inc bl
  973. mov al,bl
  974. stosb
  975. loop fillerloop
  976. fini1:
  977. mov esi,[dest]
  978. mov eax,esi
  979. //ret
  980. }
  981. }
  982. extern "C" long __cdecl Reverse_Long(long number)
  983. {
  984. __asm {
  985. mov eax,dword ptr [number]
  986. xchg al,ah
  987. ror eax,16
  988. xchg al,ah
  989. }
  990. }
  991. extern "C" short __cdecl Reverse_Short(short number)
  992. {
  993. __asm {
  994. mov ax,[number]
  995. xchg ah,al
  996. }
  997. }
  998. extern "C" long __cdecl Swap_Long(long number)
  999. {
  1000. __asm {
  1001. mov eax,dword ptr [number]
  1002. ror eax,16
  1003. }
  1004. }
  1005. /*
  1006. ;***************************************************************************
  1007. ;* strtrim -- Remove the trailing white space from a string. *
  1008. ;* *
  1009. ;* Use this routine to remove white space characters from the beginning *
  1010. ;* and end of the string. The string is modified in place by *
  1011. ;* this routine. *
  1012. ;* *
  1013. ;* INPUT: buffer -- Pointer to the string to modify. *
  1014. ;* *
  1015. ;* OUTPUT: none *
  1016. ;* *
  1017. ;* WARNINGS: none *
  1018. ;* *
  1019. ;* HISTORY: *
  1020. ;* 10/07/1992 JLB : Created. *
  1021. ;*=========================================================================*
  1022. ; VOID cdecl strtrim(BYTE *buffer);
  1023. global C strtrim :NEAR
  1024. PROC strtrim C near
  1025. USES ax, edi, esi
  1026. ARG buffer:DWORD ; Pointer to string to modify.
  1027. */
  1028. void __cdecl strtrim(char *buffer)
  1029. {
  1030. __asm {
  1031. cmp [buffer],0
  1032. je short fini
  1033. ; Prepare for string scanning by loading pointers.
  1034. cld
  1035. mov esi,[buffer]
  1036. mov edi,esi
  1037. ; Strip white space from the start of the string.
  1038. looper:
  1039. lodsb
  1040. cmp al,20h ; Space
  1041. je short looper
  1042. cmp al,9 ; TAB
  1043. je short looper
  1044. stosb
  1045. ; Copy the rest of the string.
  1046. gruntloop:
  1047. lodsb
  1048. stosb
  1049. or al,al
  1050. jnz short gruntloop
  1051. dec edi
  1052. ; Strip the white space from the end of the string.
  1053. looper2:
  1054. mov [edi],al
  1055. dec edi
  1056. mov ah,[edi]
  1057. cmp ah,20h
  1058. je short looper2
  1059. cmp ah,9
  1060. je short looper2
  1061. fini:
  1062. //ret
  1063. }
  1064. }
  1065. /*
  1066. ;***************************************************************************
  1067. ;* Fat_Put_Pixel -- Draws a fat pixel. *
  1068. ;* *
  1069. ;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
  1070. ;* across. This routine is faster than drawing a similar small shape *
  1071. ;* and faster than calling Fill_Rect. *
  1072. ;* *
  1073. ;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
  1074. ;* left corner. *
  1075. ;* *
  1076. ;* color -- The color to render the pixel in. *
  1077. ;* *
  1078. ;* size -- The number of pixels width of the big "pixel". *
  1079. ;* *
  1080. ;* page -- The pointer to a GraphicBuffer class or something *
  1081. ;* *
  1082. ;* OUTPUT: none *
  1083. ;* *
  1084. ;* WARNINGS: none *
  1085. ;* *
  1086. ;* HISTORY: *
  1087. ;* 03/17/1994 JLB : Created. *
  1088. ;*=========================================================================*
  1089. ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
  1090. global C Fat_Put_Pixel:NEAR
  1091. PROC Fat_Put_Pixel C near
  1092. USES eax, ebx, ecx, edx, edi, esi
  1093. ARG x:DWORD ; X coordinate of upper left pixel corner.
  1094. ARG y:DWORD ; Y coordinate of upper left pixel corner.
  1095. ARG color:DWORD ; Color to use for the "pixel".
  1096. ARG siz:DWORD ; Size of "pixel" to plot (square).
  1097. ARG gpage:DWORD ; graphic page address to plot onto
  1098. */
  1099. void __cdecl Fat_Put_Pixel(int x, int y, int color, int siz, GraphicViewPortClass &gpage)
  1100. {
  1101. __asm {
  1102. cmp [siz],0
  1103. je short exit_label
  1104. ; Set EDI to point to start of logical page memory.
  1105. ;*===================================================================
  1106. ; Get the viewport information and put bytes per row in ecx
  1107. ;*===================================================================
  1108. mov ebx,[gpage] ; get a pointer to viewport
  1109. mov edi,[ebx]GraphicViewPortClass.Offset ; get the correct offset
  1110. ; Verify the the Y pixel offset is legal.
  1111. mov eax,[y]
  1112. cmp eax,[ebx]GraphicViewPortClass.Height ;YPIXEL_MAX
  1113. jae short exit_label
  1114. mov ecx,[ebx]GraphicViewPortClass.Width
  1115. add ecx,[ebx]GraphicViewPortClass.XAdd
  1116. add ecx,[ebx]GraphicViewPortClass.Pitch
  1117. mul ecx
  1118. add edi,eax
  1119. ; Verify the the X pixel offset is legal.
  1120. mov edx,[ebx]GraphicViewPortClass.Width
  1121. cmp edx,[x]
  1122. mov edx,ecx
  1123. jbe short exit_label
  1124. add edi,[x]
  1125. ; Write the pixel to the screen.
  1126. mov ebx,[siz] ; Copy of pixel size.
  1127. sub edx,ebx ; Modulo to reach start of next row.
  1128. mov eax,[color]
  1129. again:
  1130. mov ecx,ebx
  1131. rep stosb
  1132. add edi,edx ; EDI points to start of next row.
  1133. dec [siz]
  1134. jnz short again
  1135. exit_label:
  1136. //ret
  1137. }
  1138. }
  1139. /*
  1140. ;***************************************************************************
  1141. ;** 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 **
  1142. ;***************************************************************************
  1143. ;* *
  1144. ;* Project Name : Westwood Library *
  1145. ;* *
  1146. ;* File Name : CRC.ASM *
  1147. ;* *
  1148. ;* Programmer : Joe L. Bostic *
  1149. ;* *
  1150. ;* Start Date : June 12, 1992 *
  1151. ;* *
  1152. ;* Last Update : February 10, 1995 [BWG] *
  1153. ;* *
  1154. ;*-------------------------------------------------------------------------*
  1155. ;* Functions: *
  1156. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  1157. IDEAL
  1158. P386
  1159. MODEL USE32 FLAT
  1160. GLOBAL C Calculate_CRC :NEAR
  1161. CODESEG
  1162. */
  1163. extern "C" long __cdecl Calculate_CRC(void *buffer, long length)
  1164. {
  1165. unsigned long crc;
  1166. unsigned long local_length = (unsigned long) length;
  1167. __asm {
  1168. ; Load pointer to data block.
  1169. mov [crc],0
  1170. pushad
  1171. mov esi,[buffer]
  1172. cld
  1173. ; Clear CRC to default (NULL) value.
  1174. xor ebx,ebx
  1175. //; Fetch the length of the data block to CRC.
  1176. mov ecx,[local_length]
  1177. jecxz short fini
  1178. ; Prepare the length counters.
  1179. mov edx,ecx
  1180. and dl,011b
  1181. shr ecx,2
  1182. ; Perform the bulk of the CRC scanning.
  1183. jecxz short remainder2
  1184. accumloop:
  1185. lodsd
  1186. rol ebx,1
  1187. add ebx,eax
  1188. loop accumloop
  1189. ; Handle the remainder bytes.
  1190. remainder2:
  1191. or dl,dl
  1192. jz short fini
  1193. mov ecx,edx
  1194. xor eax,eax
  1195. and ecx,0FFFFh
  1196. push ecx
  1197. nextbyte:
  1198. lodsb
  1199. ror eax,8
  1200. loop nextbyte
  1201. pop ecx
  1202. neg ecx
  1203. add ecx,4
  1204. shl ecx,3
  1205. ror eax,cl
  1206. ;nextbyte:
  1207. ; shl eax,8
  1208. ; lodsb
  1209. ; loop nextbyte
  1210. rol ebx,1
  1211. add ebx,eax
  1212. fini:
  1213. mov [crc],ebx
  1214. popad
  1215. mov eax,[crc]
  1216. //ret
  1217. }
  1218. }
  1219. extern "C" void __cdecl Set_Palette_Range(void *palette)
  1220. {
  1221. if (palette == NULL) {
  1222. return;
  1223. }
  1224. memcpy(CurrentPalette, palette, 768);
  1225. Set_DD_Palette(palette);
  1226. }