LINEAR.ASM 33 KB

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