LINEAR.ASM 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/2d/rcs/linear.asm $
  13. ; $Revision: 1.20 $
  14. ; $Author: john $
  15. ; $Date: 1994/11/28 17:08:30 $
  16. ;
  17. ; Routines to access linear VGA memory
  18. ;
  19. ; $Log: linear.asm $
  20. ; Revision 1.20 1994/11/28 17:08:30 john
  21. ; Took out some unused functions in linear.asm, moved
  22. ; gr_linear_movsd from linear.asm to bitblt.c, made sure that
  23. ; the code in ibiblt.c sets the direction flags before rep movsing.
  24. ;
  25. ; Revision 1.19 1994/11/27 22:57:56 john
  26. ; Took out some code that was never called.
  27. ;
  28. ; Revision 1.18 1994/09/12 14:40:16 john
  29. ; Neatend.
  30. ;
  31. ; Revision 1.17 1994/07/27 18:30:30 john
  32. ; Took away the blending table.
  33. ;
  34. ; Revision 1.16 1994/04/08 16:59:28 john
  35. ; Add fading poly's; Made palette fade 32 instead of 16.
  36. ;
  37. ; Revision 1.15 1993/12/21 20:10:03 john
  38. ; *** empty log message ***
  39. ;
  40. ; Revision 1.14 1993/12/21 19:58:31 john
  41. ; added selector stuff
  42. ;
  43. ; Revision 1.13 1993/12/21 11:40:51 john
  44. ; *** empty log message ***
  45. ;
  46. ; Revision 1.12 1993/12/09 15:01:52 john
  47. ; Changed palette stuff majorly
  48. ;
  49. ; Revision 1.11 1993/12/08 16:41:02 john
  50. ; *** empty log message ***
  51. ;
  52. ; Revision 1.10 1993/12/08 11:50:17 john
  53. ; Fixed bug with gr_init
  54. ;
  55. ; Revision 1.9 1993/12/07 12:32:12 john
  56. ; moved bmd_palette to gr_palette
  57. ;
  58. ; Revision 1.8 1993/12/03 12:11:25 john
  59. ; *** empty log message ***
  60. ;
  61. ; Revision 1.7 1993/11/16 11:29:08 john
  62. ; *** empty log message ***
  63. ;
  64. ; Revision 1.6 1993/10/15 16:22:13 john
  65. ; *** empty log message ***
  66. ;
  67. ; Revision 1.5 1993/09/29 16:15:28 john
  68. ; added assembler linear_line
  69. ;
  70. ; Revision 1.4 1993/09/26 18:59:27 john
  71. ; fade stuff
  72. ;
  73. ; Revision 1.3 1993/09/21 14:00:59 john
  74. ; added code to save 43/50 line text modes.
  75. ;
  76. ; Revision 1.2 1993/09/16 17:28:06 john
  77. ; added code to save/restore video mode
  78. ;
  79. ; Revision 1.1 1993/09/08 11:41:30 john
  80. ; Initial revision
  81. ;
  82. ;
  83. ;
  84. .386
  85. _DATA SEGMENT BYTE PUBLIC USE32 'DATA'
  86. INCLUDE VGAREGS.INC
  87. ; Put data here
  88. PUBLIC _gr_var_color
  89. PUBLIC _gr_var_bitmap
  90. PUBLIC _gr_var_bwidth
  91. _gr_var_color dd ?
  92. _gr_var_bitmap dd ?
  93. _gr_var_bwidth dd ?
  94. ; Local variables for gr_linear_line_
  95. AdjUp dd ? ;error term adjust up on each advance
  96. AdjDown dd ? ;error term adjust down when error term turns over
  97. WholeStep dd ? ;minimum run length
  98. XAdvance dd ? ;1 or -1, for direction in which X advances
  99. XStart dd ?
  100. YStart dd ?
  101. XEnd dd ?
  102. YEnd dd ?
  103. _DATA ENDS
  104. DGROUP GROUP _DATA
  105. _TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
  106. ASSUME DS:_DATA
  107. ASSUME CS:_TEXT
  108. include psmacros.inc
  109. ; Args passed in EAX, EDX, EBX, ECX
  110. ; Fast run length slice line drawing implementation for mode 0x13, the VGA's
  111. ; 320x200 256-color mode.
  112. ; Draws a line between the specified endpoints in color Color.
  113. PUBLIC gr_linear_line_
  114. gr_linear_line_:
  115. cld
  116. push esi ;preserve C register variables
  117. push edi
  118. push ebp
  119. mov XStart, eax
  120. mov YStart, edx
  121. mov XEnd, ebx
  122. mov YEnd, ecx
  123. mov ebp, _gr_var_bwidth
  124. ; We'll draw top to bottom, to reduce the number of cases we have to handle,
  125. ; and to make lines between the same endpoints always draw the same pixels.
  126. mov eax,YStart
  127. cmp eax,YEnd
  128. jle LineIsTopToBottom
  129. xchg YEnd, eax ;swap endpoints
  130. mov YStart, eax
  131. mov ebx, XStart
  132. xchg XEnd, ebx
  133. mov XStart, ebx
  134. LineIsTopToBottom:
  135. ; Point EDI to the first pixel to draw.
  136. mov edx,ebp
  137. mul edx ;YStart * ebp
  138. mov esi, XStart
  139. mov edi, esi
  140. add edi, _gr_var_bitmap
  141. add edi, eax ;EDI = YStart * ebp + XStart
  142. ; = offset of initial pixel
  143. ; Figure out how far we're going vertically (guaranteed to be positive).
  144. mov ecx, YEnd
  145. sub ecx, YStart ;ECX = YDelta
  146. ; Figure out whether we're going left or right, and how far we're going
  147. ; horizontally. In the process, special-case vertical lines, for speed and
  148. ; to avoid nasty boundary conditions and division by 0.
  149. mov edx, XEnd
  150. sub edx, esi ;XDelta
  151. jnz NotVerticalLine ;XDelta == 0 means vertical line
  152. ;it is a vertical line
  153. ;yes, special case vertical line
  154. mov eax, _gr_var_color
  155. VLoop:
  156. mov [edi],al
  157. add edi,ebp
  158. dec ecx
  159. jns VLoop
  160. jmp Done
  161. ; Special-case code for horizontal lines.
  162. IsHorizontalLine:
  163. mov eax, _gr_var_color
  164. mov ah,al ;duplicate in high byte for word access
  165. and ebx,ebx ;left to right?
  166. jns DirSet ;yes
  167. sub edi, edx ;currently right to left, point to left end so we
  168. ; can go left to right (avoids unpleasantness with
  169. ; right to left REP STOSW)
  170. DirSet:
  171. mov ecx, edx
  172. inc ecx ;# of pixels to draw
  173. shr ecx, 1 ;# of words to draw
  174. rep stosw ;do as many words as possible
  175. adc ecx, ecx
  176. rep stosb ;do the odd byte, if there is one
  177. jmp Done
  178. ; Special-case code for diagonal lines.
  179. IsDiagonalLine:
  180. mov eax, _gr_var_color
  181. add ebx, ebp ;advance distance from one pixel to next
  182. DLoop:
  183. mov [edi],al
  184. add edi, ebx
  185. dec ecx
  186. jns DLoop
  187. jmp Done
  188. NotVerticalLine:
  189. mov ebx,1 ;assume left to right, so XAdvance = 1
  190. ;***leaves flags unchanged***
  191. jns LeftToRight ;left to right, all set
  192. neg ebx ;right to left, so XAdvance = -1
  193. neg edx ;|XDelta|
  194. LeftToRight:
  195. ; Special-case horizontal lines.
  196. and ecx, ecx ;YDelta == 0?
  197. jz IsHorizontalLine ;yes
  198. ; Special-case diagonal lines.
  199. cmp ecx, edx ;YDelta == XDelta?
  200. jz IsDiagonalLine ;yes
  201. ; Determine whether the line is X or Y major, and handle accordingly.
  202. cmp edx, ecx
  203. jae XMajor
  204. jmp YMajor
  205. ; X-major (more horizontal than vertical) line.
  206. XMajor:
  207. and ebx,ebx ;left to right?
  208. jns DFSet ;yes, CLD is already set
  209. std ;right to left, so draw backwards
  210. DFSet:
  211. mov eax,edx ;XDelta
  212. sub edx,edx ;prepare for division
  213. div ecx ;EAX = XDelta/YDelta
  214. ; (minimum # of pixels in a run in this line)
  215. ;EDX = XDelta % YDelta
  216. mov ebx,edx ;error term adjust each time Y steps by 1;
  217. add ebx,ebx ; used to tell when one extra pixel should be
  218. mov AdjUp, ebx ; drawn as part of a run, to account for
  219. ; fractional steps along the X axis per
  220. ; 1-pixel steps along Y
  221. mov esi, ecx ;error term adjust when the error term turns
  222. add esi, esi ; over, used to factor out the X step made at
  223. mov AdjDown, esi ; that time
  224. ; Initial error term; reflects an initial step of 0.5 along the Y axis.
  225. sub edx, esi ;(XDelta % YDelta) - (YDelta * 2)
  226. ;DX = initial error term
  227. ; The initial and last runs are partial, because Y advances only 0.5 for
  228. ; these runs, rather than 1. Divide one full run, plus the initial pixel,
  229. ; between the initial and last runs.
  230. mov esi, ecx ;SI = YDelta
  231. mov ecx, eax ;whole step (minimum run length)
  232. shr ecx,1
  233. inc ecx ;initial pixel count = (whole step / 2) + 1;
  234. ; (may be adjusted later). This is also the
  235. ; final run pixel count
  236. push ecx ;remember final run pixel count for later
  237. ; If the basic run length is even and there's no fractional advance, we have
  238. ; one pixel that could go to either the initial or last partial run, which
  239. ; we'll arbitrarily allocate to the last run.
  240. ; If there is an odd number of pixels per run, we have one pixel that can't
  241. ; be allocated to either the initial or last partial run, so we'll add 0.5 to
  242. ; the error term so this pixel will be handled by the normal full-run loop.
  243. add edx,esi ;assume odd length, add YDelta to error term
  244. ; (add 0.5 of a pixel to the error term)
  245. test al,1 ;is run length even?
  246. jnz XMajorAdjustDone ;no, already did work for odd case, all set
  247. sub edx,esi ;length is even, undo odd stuff we just did
  248. and ebx,ebx ;is the adjust up equal to 0?
  249. jnz XMajorAdjustDone ;no (don't need to check for odd length,
  250. ; because of the above test)
  251. dec ecx ;both conditions met; make initial run 1
  252. ; shorter
  253. XMajorAdjustDone:
  254. mov WholeStep,eax ;whole step (minimum run length)
  255. mov eax, _gr_var_color ;AL = drawing color
  256. ; Draw the first, partial run of pixels.
  257. rep stosb ;draw the final run
  258. add edi,ebp ;advance along the minor axis (Y)
  259. ; Draw all full runs.
  260. cmp esi,1 ;are there more than 2 scans, so there are
  261. ; some full runs? (SI = # scans - 1)
  262. jna XMajorDrawLast ;no, no full runs
  263. dec edx ;adjust error term by -1 so we can use
  264. ; carry test
  265. shr esi,1 ;convert from scan to scan-pair count
  266. jnc XMajorFullRunsOddEntry ;if there is an odd number of scans,
  267. ; do the odd scan now
  268. XMajorFullRunsLoop:
  269. mov ecx, WholeStep ;run is at least this long
  270. add edx,ebx ;advance the error term and add an extra
  271. jnc XMajorNoExtra ; pixel if the error term so indicates
  272. inc ecx ;one extra pixel in run
  273. sub edx,AdjDown ;reset the error term
  274. XMajorNoExtra:
  275. rep stosb ;draw this scan line's run
  276. add edi,ebp ;advance along the minor axis (Y)
  277. XMajorFullRunsOddEntry: ;enter loop here if there is an odd number
  278. ; of full runs
  279. mov ecx,WholeStep ;run is at least this long
  280. add edx,ebx ;advance the error term and add an extra
  281. jnc XMajorNoExtra2 ; pixel if the error term so indicates
  282. inc ecx ;one extra pixel in run
  283. sub edx,AdjDown ;reset the error term
  284. XMajorNoExtra2:
  285. rep stosb ;draw this scan line's run
  286. add edi,ebp ;advance along the minor axis (Y)
  287. dec esi
  288. jnz XMajorFullRunsLoop
  289. ; Draw the final run of pixels.
  290. XMajorDrawLast:
  291. pop ecx ;get back the final run pixel length
  292. rep stosb ;draw the final run
  293. cld ;restore normal direction flag
  294. jmp Done
  295. ; Y-major (more vertical than horizontal) line.
  296. YMajor:
  297. mov XAdvance,ebx ;remember which way X advances
  298. mov eax,ecx ;YDelta
  299. mov ecx,edx ;XDelta
  300. sub edx,edx ;prepare for division
  301. div ecx ;EAX = YDelta/XDelta
  302. ; (minimum # of pixels in a run in this line)
  303. ;EDX = YDelta % XDelta
  304. mov ebx,edx ;error term adjust each time X steps by 1;
  305. add ebx,ebx ; used to tell when one extra pixel should be
  306. mov AdjUp,ebx ; drawn as part of a run, to account for
  307. ; fractional steps along the Y axis per
  308. ; 1-pixel steps along X
  309. mov esi,ecx ;error term adjust when the error term turns
  310. add esi,esi ; over, used to factor out the Y step made at
  311. mov AdjDown, esi ; that time
  312. ; Initial error term; reflects an initial step of 0.5 along the X axis.
  313. sub edx,esi ;(YDelta % XDelta) - (XDelta * 2)
  314. ;DX = initial error term
  315. ; The initial and last runs are partial, because X advances only 0.5 for
  316. ; these runs, rather than 1. Divide one full run, plus the initial pixel,
  317. ; between the initial and last runs.
  318. mov esi,ecx ;SI = XDelta
  319. mov ecx,eax ;whole step (minimum run length)
  320. shr ecx,1
  321. inc ecx ;initial pixel count = (whole step / 2) + 1;
  322. ; (may be adjusted later)
  323. push ecx ;remember final run pixel count for later
  324. ; If the basic run length is even and there's no fractional advance, we have
  325. ; one pixel that could go to either the initial or last partial run, which
  326. ; we'll arbitrarily allocate to the last run.
  327. ; If there is an odd number of pixels per run, we have one pixel that can't
  328. ; be allocated to either the initial or last partial run, so we'll add 0.5 to
  329. ; the error term so this pixel will be handled by the normal full-run loop.
  330. add edx,esi ;assume odd length, add XDelta to error term
  331. test al,1 ;is run length even?
  332. jnz YMajorAdjustDone ;no, already did work for odd case, all set
  333. sub edx,esi ;length is even, undo odd stuff we just did
  334. and ebx,ebx ;is the adjust up equal to 0?
  335. jnz YMajorAdjustDone ;no (don't need to check for odd length,
  336. ; because of the above test)
  337. dec ecx ;both conditions met; make initial run 1
  338. ; shorter
  339. YMajorAdjustDone:
  340. mov WholeStep,eax ;whole step (minimum run length)
  341. mov eax,_gr_var_color ;AL = drawing color
  342. mov ebx, XAdvance ;which way X advances
  343. ; Draw the first, partial run of pixels.
  344. YMajorFirstLoop:
  345. mov [edi],al ;draw the pixel
  346. add edi,ebp ;advance along the major axis (Y)
  347. dec ecx
  348. jnz YMajorFirstLoop
  349. add edi,ebx ;advance along the minor axis (X)
  350. ; Draw all full runs.
  351. cmp esi,1 ;# of full runs. Are there more than 2
  352. ; columns, so there are some full runs?
  353. ; (SI = # columns - 1)
  354. jna YMajorDrawLast ;no, no full runs
  355. dec edx ;adjust error term by -1 so we can use
  356. ; carry test
  357. shr esi,1 ;convert from column to column-pair count
  358. jnc YMajorFullRunsOddEntry ;if there is an odd number of
  359. ; columns, do the odd column now
  360. YMajorFullRunsLoop:
  361. mov ecx,WholeStep ;run is at least this long
  362. add edx,AdjUp ;advance the error term and add an extra
  363. jnc YMajorNoExtra ; pixel if the error term so indicates
  364. inc ecx ;one extra pixel in run
  365. sub edx,AdjDown ;reset the error term
  366. YMajorNoExtra:
  367. ;draw the run
  368. YMajorRunLoop:
  369. mov [edi],al ;draw the pixel
  370. add edi,ebp ;advance along the major axis (Y)
  371. dec ecx
  372. jnz YMajorRunLoop
  373. add edi,ebx ;advance along the minor axis (X)
  374. YMajorFullRunsOddEntry: ;enter loop here if there is an odd number
  375. ; of full runs
  376. mov ecx,WholeStep ;run is at least this long
  377. add edx,AdjUp ;advance the error term and add an extra
  378. jnc YMajorNoExtra2 ; pixel if the error term so indicates
  379. inc ecx ;one extra pixel in run
  380. sub edx, AdjDown ;reset the error term
  381. YMajorNoExtra2:
  382. ;draw the run
  383. YMajorRunLoop2:
  384. mov [edi],al ;draw the pixel
  385. add edi,ebp ;advance along the major axis (Y)
  386. dec ecx
  387. jnz YMajorRunLoop2
  388. add edi,ebx ;advance along the minor axis (X)
  389. dec esi
  390. jnz YMajorFullRunsLoop
  391. ; Draw the final run of pixels.
  392. YMajorDrawLast:
  393. pop ecx ;get back the final run pixel length
  394. YMajorLastLoop:
  395. mov [edi],al ;draw the pixel
  396. add edi,ebp ;advance along the major axis (Y)
  397. dec ecx
  398. jnz YMajorLastLoop
  399. Done:
  400. pop ebp
  401. pop edi
  402. pop esi ;restore C register variables
  403. ret
  404. PUBLIC gr_linear_stosd_
  405. gr_linear_stosd_:
  406. ; EAX -> Destination buffer
  407. ; EDX -> Byte to store
  408. ; EBX -> Number of bytes to move
  409. push ecx
  410. push edi
  411. mov edi, eax
  412. mov dh, dl
  413. mov ax, dx
  414. shl eax, 16
  415. mov ax, dx
  416. cld
  417. mov ecx, ebx
  418. shr ecx, 2
  419. rep stosd
  420. mov ecx, ebx
  421. and ecx, 011b
  422. rep stosb
  423. pop edi
  424. pop ecx
  425. ret
  426. PUBLIC gr_update_buffer_
  427. gr_update_buffer_:
  428. ; EAX = Latest source buffer
  429. ; EDX = Earlier source buffer
  430. ; EBX = Dest source buffer
  431. ; ECX = Size of buffer
  432. push esi
  433. push edi
  434. push ebp
  435. cld
  436. mov esi, eax
  437. mov edi, edx
  438. mov ebp, esi
  439. shr ecx, 2
  440. FindNextMismatch:
  441. repe cmpsd
  442. mov eax, [esi-4]
  443. mov edx, ebx
  444. add edx, esi
  445. sub edx, ebp
  446. mov [edx], eax ; EDX = dest + size - bytes to end
  447. cmp ecx, 0
  448. jne FindNextMismatch
  449. Done11:
  450. pop ebp
  451. pop edi
  452. pop esi
  453. ret
  454. ;--NOT USED!!-- X0 dd ? ;X coordinate of line start point
  455. ;--NOT USED!!-- Y0 dd ? ;Y coordinate of line start point
  456. ;--NOT USED!!-- X1 dd ? ;X coordinate of line end point
  457. ;--NOT USED!!-- Y1 dd ? ;Y coordinate of line end point
  458. ;--NOT USED!!-- BaseColor db ? ;color # of first color in block used for
  459. ;--NOT USED!!-- ; antialiasing, the 100% intensity version of the
  460. ;--NOT USED!!-- ; drawing color
  461. ;--NOT USED!!-- NumLevels db 16 ;size of color block, with BaseColor+NumLevels-1
  462. ;--NOT USED!!-- ; being the 0% intensity version of the drawing color
  463. ;--NOT USED!!-- ; (maximum NumLevels = 256)
  464. ;--NOT USED!!-- IntensityBits db 4 ;log base 2 of NumLevels; the # of bits used to
  465. ;--NOT USED!!-- ; describe the intensity of the drawing color.
  466. ;--NOT USED!!-- ; 2**IntensityBits==NumLevels
  467. ;--NOT USED!!-- ; (maximum IntensityBits = 8)
  468. ;--NOT USED!!-- ; C near-callable function to draw an antialiased line from
  469. ;--NOT USED!!-- ; (X0,Y0) to (X1,Y1), in mode 13h, the VGA's standard 320x200 256-color
  470. ;--NOT USED!!-- ; mode. Uses an antialiasing approach published by Xiaolin Wu in the July
  471. ;--NOT USED!!-- ; 1991 issue of Computer Graphics. Requires that the palette be set up so
  472. ;--NOT USED!!-- ; that there are NumLevels intensity levels of the desired drawing color,
  473. ;--NOT USED!!-- ; starting at color BaseColor (100% intensity) and followed by (NumLevels-1)
  474. ;--NOT USED!!-- ; levels of evenly decreasing intensity, with color (BaseColor+NumLevels-1)
  475. ;--NOT USED!!-- ; being 0% intensity of the desired drawing color (black). No clipping is
  476. ;--NOT USED!!-- ; performed in DrawWuLine. Handles a maximum of 256 intensity levels per
  477. ;--NOT USED!!-- ; antialiased color. This code is suitable for use at screen resolutions,
  478. ;--NOT USED!!-- ; with lines typically no more than 1K long; for longer lines, 32-bit error
  479. ;--NOT USED!!-- ; arithmetic must be used to avoid problems with fixed-point inaccuracy.
  480. ;--NOT USED!!-- ; Tested with TASM 3.0.
  481. ;--NOT USED!!-- ;
  482. ;--NOT USED!!-- ; C near-callable as:
  483. ;--NOT USED!!-- ; void DrawWuLine(int X0, int Y0, int X1, int Y1, int BaseColor,
  484. ;--NOT USED!!-- ; int NumLevels, unsigned int IntensityBits);
  485. ;--NOT USED!!--
  486. ;--NOT USED!!-- SCREEN_WIDTH_IN_BYTES equ 320 ;# of bytes from the start of one scan line
  487. ;--NOT USED!!-- ; to the start of the next
  488. ;--NOT USED!!-- SCREEN_SEGMENT equ 0a000h ;segment in which screen memory resides
  489. ;--NOT USED!!--
  490. ;--NOT USED!!-- ; Parameters passed in stack frame.
  491. ;--NOT USED!!--
  492. ;--NOT USED!!--
  493. ;--NOT USED!!-- ;_gr_var_color, _gr_var_bitmap, _gr_var_bwidth
  494. ;--NOT USED!!--
  495. ;--NOT USED!!-- public gr_linear_aaline_
  496. ;--NOT USED!!-- gr_linear_aaline_:
  497. ;--NOT USED!!--
  498. ;--NOT USED!!-- push ebp
  499. ;--NOT USED!!-- push esi ;preserve C's register variables
  500. ;--NOT USED!!-- push edi
  501. ;--NOT USED!!-- cld ;make string instructions increment their pointers
  502. ;--NOT USED!!--
  503. ;--NOT USED!!-- mov X0, eax
  504. ;--NOT USED!!-- mov Y0, edx
  505. ;--NOT USED!!-- mov X1, ebx
  506. ;--NOT USED!!-- mov Y1, ecx
  507. ;--NOT USED!!--
  508. ;--NOT USED!!-- mov eax, _gr_var_color
  509. ;--NOT USED!!-- mov BaseColor, al
  510. ;--NOT USED!!--
  511. ;--NOT USED!!-- ; Make sure the line runs top to bottom.
  512. ;--NOT USED!!-- mov esi,X0
  513. ;--NOT USED!!-- mov eax,Y0
  514. ;--NOT USED!!-- cmp eax,Y1 ;swap endpoints if necessary to ensure that
  515. ;--NOT USED!!-- jna NoSwap ; Y0 <= Y1
  516. ;--NOT USED!!-- xchg Y1,eax
  517. ;--NOT USED!!-- mov Y0,eax
  518. ;--NOT USED!!-- xchg X1,esi
  519. ;--NOT USED!!-- mov X0,esi
  520. ;--NOT USED!!-- NoSwap:
  521. ;--NOT USED!!--
  522. ;--NOT USED!!-- ; Draw the initial pixel, which is always exactly intersected by the line
  523. ;--NOT USED!!-- ; and so needs no weighting.
  524. ;--NOT USED!!--
  525. ;--NOT USED!!-- mov edx,_gr_var_bwidth
  526. ;--NOT USED!!-- mul edx ;Y0 * SCREEN_WIDTH_IN_BYTES yields the offset
  527. ;--NOT USED!!-- ; of the start of the row start the initial
  528. ;--NOT USED!!-- ; pixel is on
  529. ;--NOT USED!!-- add esi,eax ;point DS:SI to the initial pixel
  530. ;--NOT USED!!-- add esi,_gr_var_bitmap
  531. ;--NOT USED!!-- mov al, BaseColor ;color with which to draw
  532. ;--NOT USED!!-- mov [esi],al ;draw the initial pixel
  533. ;--NOT USED!!--
  534. ;--NOT USED!!-- mov ebx,1 ;XDir = 1; assume DeltaX >= 0
  535. ;--NOT USED!!-- mov ecx,X1
  536. ;--NOT USED!!-- sub ecx,X0 ;DeltaX; is it >= 1?
  537. ;--NOT USED!!-- jns DeltaXSet ;yes, move left->right, all set
  538. ;--NOT USED!!-- ;no, move right->left
  539. ;--NOT USED!!-- neg ecx ;make DeltaX positive
  540. ;--NOT USED!!-- neg ebx ;XDir = -1
  541. ;--NOT USED!!-- DeltaXSet:
  542. ;--NOT USED!!--
  543. ;--NOT USED!!-- ; Special-case horizontal, vertical, and diagonal lines, which require no
  544. ;--NOT USED!!-- ; weighting because they go right through the center of every pixel.
  545. ;--NOT USED!!-- mov edx,Y1
  546. ;--NOT USED!!-- sub edx,Y0 ;DeltaY; is it 0?
  547. ;--NOT USED!!-- jnz NotHorz ;no, not horizontal
  548. ;--NOT USED!!-- ;yes, is horizontal, special case
  549. ;--NOT USED!!-- and ebx,ebx ;draw from left->right?
  550. ;--NOT USED!!-- jns DoHorz ;yes, all set
  551. ;--NOT USED!!-- std ;no, draw right->left
  552. ;--NOT USED!!-- DoHorz:
  553. ;--NOT USED!!-- lea edi,[ebx+esi] ;point DI to next pixel to draw
  554. ;--NOT USED!!-- ;point ES:DI to next pixel to draw
  555. ;--NOT USED!!-- mov al,BaseColor ;color with which to draw
  556. ;--NOT USED!!-- ;CX = DeltaX at this point
  557. ;--NOT USED!!-- rep stosb ;draw the rest of the horizontal line
  558. ;--NOT USED!!-- cld ;restore default direction flag
  559. ;--NOT USED!!-- jmp DoneAA ;and we're done
  560. ;--NOT USED!!--
  561. ;--NOT USED!!-- NotHorz:
  562. ;--NOT USED!!-- and ecx,ecx ;is DeltaX 0?
  563. ;--NOT USED!!-- jnz NotVert ;no, not a vertical line
  564. ;--NOT USED!!-- ;yes, is vertical, special case
  565. ;--NOT USED!!-- mov al,BaseColor ;color with which to draw
  566. ;--NOT USED!!-- VertLoop:
  567. ;--NOT USED!!-- add esi,_gr_var_bwidth ;point to next pixel to draw
  568. ;--NOT USED!!-- mov [esi], al ;draw the next pixel
  569. ;--NOT USED!!-- dec edx ;--DeltaY
  570. ;--NOT USED!!-- jnz VertLoop
  571. ;--NOT USED!!-- jmp DoneAA ;and we're done
  572. ;--NOT USED!!--
  573. ;--NOT USED!!-- NotVert:
  574. ;--NOT USED!!-- cmp ecx,edx ;DeltaX == DeltaY?
  575. ;--NOT USED!!-- jnz NotDiag ;no, not diagonal
  576. ;--NOT USED!!-- ;yes, is diagonal, special case
  577. ;--NOT USED!!-- mov al,BaseColor ;color with which to draw
  578. ;--NOT USED!!-- DiagLoop:
  579. ;--NOT USED!!-- lea esi,[esi+ebx]
  580. ;--NOT USED!!-- add esi,_gr_var_bwidth
  581. ;--NOT USED!!-- ;advance to next pixel to draw by
  582. ;--NOT USED!!-- ; incrementing Y and adding XDir to X
  583. ;--NOT USED!!-- mov [esi],al ;draw the next pixel
  584. ;--NOT USED!!-- dec edx ;--DeltaY
  585. ;--NOT USED!!-- jnz DiagLoop
  586. ;--NOT USED!!-- jmp DoneAA ;and we're done
  587. ;--NOT USED!!--
  588. ;--NOT USED!!-- ; Line is not horizontal, diagonal, or vertical.
  589. ;--NOT USED!!-- NotDiag:
  590. ;--NOT USED!!-- ; Is this an X-major or Y-major line?
  591. ;--NOT USED!!-- cmp edx,ecx
  592. ;--NOT USED!!-- jb XMajorAA ;it's X-major
  593. ;--NOT USED!!--
  594. ;--NOT USED!!-- ; It's a Y-major line. Calculate the 16-bit fixed-point fractional part of a
  595. ;--NOT USED!!-- ; pixel that X advances each time Y advances 1 pixel, truncating the result
  596. ;--NOT USED!!-- ; to avoid overrunning the endpoint along the X axis.
  597. ;--NOT USED!!-- xchg edx,ecx ;DX = DeltaX, CX = DeltaY
  598. ;--NOT USED!!-- sub ax,ax ;make DeltaX 16.16 fixed-point value in DX:AX
  599. ;--NOT USED!!-- div cx ;AX = (DeltaX << 16) / DeltaY. Won't overflow
  600. ;--NOT USED!!-- ; because DeltaX < DeltaY
  601. ;--NOT USED!!-- mov di,cx ;DI = DeltaY (loop count)
  602. ;--NOT USED!!-- sub esi,ebx ;back up the start X by 1, as explained below
  603. ;--NOT USED!!-- mov dx,-1 ;initialize the line error accumulator to -1,
  604. ;--NOT USED!!-- ; so that it will turn over immediately and
  605. ;--NOT USED!!-- ; advance X to the start X. This is necessary
  606. ;--NOT USED!!-- ; properly to bias error sums of 0 to mean
  607. ;--NOT USED!!-- ; "advance next time" rather than "advance
  608. ;--NOT USED!!-- ; this time," so that the final error sum can
  609. ;--NOT USED!!-- ; never cause drawing to overrun the final X
  610. ;--NOT USED!!-- ; coordinate (works in conjunction with
  611. ;--NOT USED!!-- ; truncating ErrorAdj, to make sure X can't
  612. ;--NOT USED!!-- ; overrun)
  613. ;--NOT USED!!-- mov cl,8 ;CL = # of bits by which to shift
  614. ;--NOT USED!!-- sub cl,IntensityBits ; ErrorAcc to get intensity level (8
  615. ;--NOT USED!!-- ; instead of 16 because we work only
  616. ;--NOT USED!!-- ; with the high byte of ErrorAcc)
  617. ;--NOT USED!!-- mov ch,NumLevels ;mask used to flip all bits in an
  618. ;--NOT USED!!-- dec ch ; intensity weighting, producing
  619. ;--NOT USED!!-- ; result (1 - intensity weighting)
  620. ;--NOT USED!!-- mov bp, ax
  621. ;--NOT USED!!-- mov al, BaseColor
  622. ;--NOT USED!!-- ;BP = ErrorAdj, AL = BaseColor,
  623. ;--NOT USED!!-- ; AH = scratch register
  624. ;--NOT USED!!--
  625. ;--NOT USED!!--
  626. ;--NOT USED!!--
  627. ;--NOT USED!!-- ; Draw all remaining pixels.
  628. ;--NOT USED!!-- YMajorLoop:
  629. ;--NOT USED!!-- add dx,bp ;calculate error for next pixel
  630. ;--NOT USED!!-- jnc NoXAdvance ;not time to step in X yet
  631. ;--NOT USED!!-- ;the error accumulator turned over,
  632. ;--NOT USED!!-- ; so advance the X coord
  633. ;--NOT USED!!-- add esi,ebx ;add XDir to the pixel pointer
  634. ;--NOT USED!!-- NoXAdvance:
  635. ;--NOT USED!!-- add esi,_gr_var_bwidth ;Y-major, so always advance Y
  636. ;--NOT USED!!--
  637. ;--NOT USED!!-- ; The IntensityBits most significant bits of ErrorAcc give us the intensity
  638. ;--NOT USED!!-- ; weighting for this pixel, and the complement of the weighting for the
  639. ;--NOT USED!!-- ; paired pixel.
  640. ;--NOT USED!!-- mov ah,dh ;msb of ErrorAcc
  641. ;--NOT USED!!-- shr ah,cl ;Weighting = ErrorAcc >> IntensityShift;
  642. ;--NOT USED!!-- ;add ah,al ;BaseColor + Weighting
  643. ;--NOT USED!!--
  644. ;--NOT USED!!-- ; Make ah = _gr_fade_table + BaseColor+(15-ah)*256
  645. ;--NOT USED!!-- push ecx
  646. ;--NOT USED!!-- push ebx
  647. ;--NOT USED!!-- mov ebx, 15
  648. ;--NOT USED!!-- sub bl, ah
  649. ;--NOT USED!!-- shl ebx, 8
  650. ;--NOT USED!!-- movzx ecx, BaseColor
  651. ;--NOT USED!!-- add ebx, ecx
  652. ;--NOT USED!!-- add ebx, offset _gr_fade_table
  653. ;--NOT USED!!-- mov ah, [ebx]
  654. ;--NOT USED!!-- pop ebx
  655. ;--NOT USED!!-- pop ecx
  656. ;--NOT USED!!--
  657. ;--NOT USED!!-- mov [esi],ah ;DrawPixel(X, Y, BaseColor + Weighting);
  658. ;--NOT USED!!--
  659. ;--NOT USED!!-- mov ah,dh ;msb of ErrorAcc
  660. ;--NOT USED!!-- shr ah,cl ;Weighting = ErrorAcc >> IntensityShift;
  661. ;--NOT USED!!-- xor ah,ch ;Weighting ^ WeightingComplementMask
  662. ;--NOT USED!!-- ;add ah,al ;BaseColor + (Weighting ^ WeightingComplementMask)
  663. ;--NOT USED!!--
  664. ;--NOT USED!!-- ; Make ah = _gr_fade_table + BaseColor+(15-ah)*256
  665. ;--NOT USED!!-- push ecx
  666. ;--NOT USED!!-- push ebx
  667. ;--NOT USED!!-- mov ebx, 15
  668. ;--NOT USED!!-- sub bl, 0
  669. ;--NOT USED!!-- shl ebx, 8
  670. ;--NOT USED!!-- movzx ecx, BaseColor
  671. ;--NOT USED!!-- add ebx, ecx
  672. ;--NOT USED!!-- add ebx, offset _gr_fade_table
  673. ;--NOT USED!!-- mov ah, [ebx]
  674. ;--NOT USED!!-- pop ebx
  675. ;--NOT USED!!-- pop ecx
  676. ;--NOT USED!!--
  677. ;--NOT USED!!--
  678. ;--NOT USED!!-- mov [esi+ebx],ah ;DrawPixel(X+XDir, Y,
  679. ;--NOT USED!!-- ; BaseColor + (Weighting ^ WeightingComplementMask));
  680. ;--NOT USED!!-- dec di ;--DeltaY
  681. ;--NOT USED!!-- jnz YMajorLoop
  682. ;--NOT USED!!-- jmp DoneAA ;we're done with this line
  683. ;--NOT USED!!--
  684. ;--NOT USED!!-- ; It's an X-major line.
  685. ;--NOT USED!!-- XMajorAA:
  686. ;--NOT USED!!-- ; Calculate the 16-bit fixed-point fractional part of a pixel that Y advances
  687. ;--NOT USED!!-- ; each time X advances 1 pixel, truncating the result to avoid overrunning
  688. ;--NOT USED!!-- ; the endpoint along the X axis.
  689. ;--NOT USED!!-- sub eax,eax ;make DeltaY 16.16 fixed-point value in DX:AX
  690. ;--NOT USED!!-- div ecx ;AX = (DeltaY << 16) / Deltax. Won't overflow
  691. ;--NOT USED!!-- ; because DeltaY < DeltaX
  692. ;--NOT USED!!-- mov edi,ecx ;DI = DeltaX (loop count)
  693. ;--NOT USED!!-- sub esi,_gr_var_bwidth ;back up the start X by 1, as
  694. ;--NOT USED!!-- ; explained below
  695. ;--NOT USED!!-- mov edx,-1 ;initialize the line error accumulator to -1,
  696. ;--NOT USED!!-- ; so that it will turn over immediately and
  697. ;--NOT USED!!-- ; advance Y to the start Y. This is necessary
  698. ;--NOT USED!!-- ; properly to bias error sums of 0 to mean
  699. ;--NOT USED!!-- ; "advance next time" rather than "advance
  700. ;--NOT USED!!-- ; this time," so that the final error sum can
  701. ;--NOT USED!!-- ; never cause drawing to overrun the final Y
  702. ;--NOT USED!!-- ; coordinate (works in conjunction with
  703. ;--NOT USED!!-- ; truncating ErrorAdj, to make sure Y can't
  704. ;--NOT USED!!-- ; overrun)
  705. ;--NOT USED!!-- mov cl,8 ;CL = # of bits by which to shift
  706. ;--NOT USED!!-- sub cl,IntensityBits ; ErrorAcc to get intensity level (8
  707. ;--NOT USED!!-- ; instead of 16 because we work only
  708. ;--NOT USED!!-- ; with the high byte of ErrorAcc)
  709. ;--NOT USED!!-- mov ch,NumLevels ;mask used to flip all bits in an
  710. ;--NOT USED!!-- dec ch ; intensity weighting, producing
  711. ;--NOT USED!!-- ; result (1 - intensity weighting)
  712. ;--NOT USED!!--
  713. ;--NOT USED!!-- mov ebp, eax
  714. ;--NOT USED!!-- mov al, BaseColor
  715. ;--NOT USED!!--
  716. ;--NOT USED!!-- ; Draw all remaining pixels.
  717. ;--NOT USED!!-- XMajorLoop:
  718. ;--NOT USED!!-- add edx,ebp ;calculate error for next pixel
  719. ;--NOT USED!!-- jnc NoYAdvance ;not time to step in Y yet
  720. ;--NOT USED!!-- ;the error accumulator turned over,
  721. ;--NOT USED!!-- ; so advance the Y coord
  722. ;--NOT USED!!-- add esi,_gr_var_bwidth ;advance Y
  723. ;--NOT USED!!-- NoYAdvance:
  724. ;--NOT USED!!-- add esi,ebx ;X-major, so add XDir to the pixel pointer
  725. ;--NOT USED!!--
  726. ;--NOT USED!!-- ; The IntensityBits most significant bits of ErrorAcc give us the intensity
  727. ;--NOT USED!!-- ; weighting for this pixel, and the complement of the weighting for the
  728. ;--NOT USED!!-- ; paired pixel.
  729. ;--NOT USED!!-- mov ah,dh ;msb of ErrorAcc
  730. ;--NOT USED!!-- shr ah,cl ;Weighting = ErrorAcc >> IntensityShift;
  731. ;--NOT USED!!-- ;add ah,al ;BaseColor + Weighting
  732. ;--NOT USED!!--
  733. ;--NOT USED!!-- ; Make ah = _gr_fade_table + BaseColor+(15-ah)*256
  734. ;--NOT USED!!-- push ecx
  735. ;--NOT USED!!-- push ebx
  736. ;--NOT USED!!-- mov ebx, 15
  737. ;--NOT USED!!-- sub bl, ah
  738. ;--NOT USED!!-- shl ebx, 8
  739. ;--NOT USED!!-- movzx ecx, BaseColor
  740. ;--NOT USED!!-- add ebx, ecx
  741. ;--NOT USED!!-- add ebx, offset _gr_fade_table
  742. ;--NOT USED!!-- mov ah, [ebx]
  743. ;--NOT USED!!-- pop ebx
  744. ;--NOT USED!!-- pop ecx
  745. ;--NOT USED!!--
  746. ;--NOT USED!!--
  747. ;--NOT USED!!-- mov [esi],ah ;DrawPixel(X, Y, BaseColor + Weighting);
  748. ;--NOT USED!!-- mov ah,dh ;msb of ErrorAcc
  749. ;--NOT USED!!-- shr ah,cl ;Weighting = ErrorAcc >> IntensityShift;
  750. ;--NOT USED!!-- xor ah,ch ;Weighting ^ WeightingComplementMask
  751. ;--NOT USED!!-- ;add ah,al ;BaseColor + (Weighting ^ WeightingComplementMask)
  752. ;--NOT USED!!-- add esi, _gr_var_bwidth
  753. ;--NOT USED!!--
  754. ;--NOT USED!!-- ; Make ah = _gr_fade_table + BaseColor+(15-ah)*256
  755. ;--NOT USED!!-- push ecx
  756. ;--NOT USED!!-- push ebx
  757. ;--NOT USED!!-- mov ebx, 15
  758. ;--NOT USED!!-- sub bl, ah
  759. ;--NOT USED!!-- shl ebx, 8
  760. ;--NOT USED!!-- movzx ecx, BaseColor
  761. ;--NOT USED!!-- add ebx, ecx
  762. ;--NOT USED!!-- add ebx, offset _gr_fade_table
  763. ;--NOT USED!!-- mov ah, [ebx]
  764. ;--NOT USED!!-- pop ebx
  765. ;--NOT USED!!-- pop ecx
  766. ;--NOT USED!!--
  767. ;--NOT USED!!--
  768. ;--NOT USED!!-- mov [esi],ah ;DrawPixel(X, Y+SCREEN_WIDTH_IN_BYTES,
  769. ;--NOT USED!!-- ; BaseColor + (Weighting ^ WeightingComplementMask));
  770. ;--NOT USED!!-- sub esi, _gr_var_bwidth
  771. ;--NOT USED!!-- dec edi ;--DeltaX
  772. ;--NOT USED!!-- jnz XMajorLoop
  773. ;--NOT USED!!--
  774. ;--NOT USED!!-- DoneAA: ;we're done with this line
  775. ;--NOT USED!!-- pop edi ;restore C's register variables
  776. ;--NOT USED!!-- pop esi
  777. ;--NOT USED!!-- pop ebp ;restore caller's stack frame
  778. ;--NOT USED!!-- ret ;done
  779. _TEXT ENDS
  780. END