GRAPHI.LST 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. Listing:
  2. 1 (* Release 3.10 *)
  3. 2 (*-------------------------------------------------------------------------*
  4. 3 * *
  5. 4 * GRAPHI.MOD - OS/2 graphics functions requiring IOPL *
  6. 5 * *
  7. 6 * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
  8. 7 * All Rights Reserved *
  9. 8 * *
  10. 9 *--------------------------------------------------------------------------*)
  11. 10
  12. 11 (*# call(o_a_copy=>off) *)
  13. 12 (*# module(implementation=>off) *)
  14. 13 (*%F _fdata *)
  15. 14 (*# data(seg_name => null) *)
  16. 15 (*%E *)
  17. 16 (*# check(stack=>off,
  18. 17 index=>off,
  19. 18 range=>off,
  20. 19 overflow=>off,
  21. 20 nil_ptr=>off) *)
  22. 21
  23. 22 IMPLEMENTATION MODULE GraphI;
  24. 23
  25. 24 (*# call(near_call=>off,
  26. 25 seg_name=>GRAPH_IOPL,
  27. 26 iopl=>on) *)
  28. 27
  29. 28 IMPORT Graph, Dos;
  30. 29
  31. 30 CONST
  32. 31 CGAWidth = 320 ;
  33. 32 CGADepth = 200 ;
  34. 33 CGANumColor = 4 ;
  35. 34 EGAWidth = 640 ;
  36. 35 EGADepth = 350 ;
  37. 36 VGAWidth = 640 ;
  38. 37 VGADepth = 350 ;
  39. 38 EGANumColor = 16 ;
  40. 39 VGA256Width = 320 ;
  41. 40 VGA256Depth = 200 ;
  42. 41 VGANumColor = 16 ;
  43. 42
  44. 43 CONST
  45. 44 HercWidth = 720 ;
  46. 45 HercDepth = 348 ;
  47. 46 HercNumColor = 2 ;
  48. 47 ATTWidth = 640 ;
  49. 48 ATTDepth = 400 ;
  50. 49 ATTNumColor = 2 ;
  51. 50
  52. 51
  53. 52 PROCEDURE SaveScreen;
  54. 53 VAR
  55. 54 BitMap : CARDINAL;
  56. 55 bp : CGABuffPtr;
  57. ***** ^ undeclared identifier
  58. 56 BEGIN
  59. 57 IF IsCGA THEN
  60. ***** ^ undeclared identifier
  61. 58 bp := FarADR(CBuffer);
  62. ***** ^ not supported yet
  63. ***** ^ undeclared identifier
  64. ***** ^ undeclared identifier
  65. 59 GRCopy(bp, [VideoSel:0 CGABuffPtr], 4000H);
  66. ***** ^ undeclared identifier
  67. ***** ^ not supported yet
  68. ***** ^ undeclared identifier
  69. ***** ^ not supported yet
  70. ***** ^ not supported yet
  71. 60 ELSE
  72. 61 FOR BitMap := 0 TO MaxBitMap DO
  73. ***** ^ undeclared identifier
  74. 62 Out(3CEH,4);
  75. ***** ^ undeclared identifier
  76. ***** ^ not supported yet
  77. 63 Out(3CFH,SHORTCARD(BitMap));
  78. ***** ^ undeclared identifier
  79. ***** ^ not supported yet
  80. 64 GRCopy(Buffer[BitMap], [VideoSel:0 BMP], BitMapSize);
  81. ***** ^ undeclared identifier
  82. ***** ^ undeclared identifier
  83. ***** ^ not supported yet
  84. ***** ^ undeclared identifier
  85. ***** ^ not supported yet
  86. ***** ^ undeclared identifier
  87. 65 END;
  88. 66 END;
  89. 67 END SaveScreen;
  90. ***** ^ not supported yet
  91. 68
  92. 69
  93. 70 PROCEDURE RestoreScreen();
  94. 71 VAR
  95. 72 BitMap : CARDINAL;
  96. 73 BEGIN
  97. 74 IF IsCGA THEN
  98. ***** ^ undeclared identifier
  99. 75 GRCopy([VideoSel:0 CGABuffPtr], FarADR(CBuffer), 4000H);
  100. ***** ^ undeclared identifier
  101. ***** ^ undeclared identifier
  102. ***** ^ not supported yet
  103. ***** ^ undeclared identifier
  104. ***** ^ undeclared identifier
  105. ***** ^ not supported yet
  106. 76 ELSE
  107. 77 FOR BitMap := 0 TO MaxBitMap DO
  108. ***** ^ undeclared identifier
  109. 78 Out( 3C4H,2);Out( 3C5H,SHORTCARD(1<<BitMap));
  110. ***** ^ undeclared identifier
  111. ***** ^ not supported yet
  112. ***** ^ undeclared identifier
  113. ***** ^ not supported yet
  114. 79 GRCopy([VideoSel:0 BMP], Buffer[BitMap], BitMapSize);
  115. ***** ^ undeclared identifier
  116. ***** ^ undeclared identifier
  117. ***** ^ not supported yet
  118. ***** ^ undeclared identifier
  119. ***** ^ not supported yet
  120. ***** ^ undeclared identifier
  121. 80 END;
  122. 81 END ;
  123. 82 END RestoreScreen;
  124. ***** ^ not supported yet
  125. 83
  126. 84
  127. 85 PROCEDURE EGAPlot( x,y,c : CARDINAL); (* Also VGA *)
  128. 86 VAR
  129. 87 (*# save, data(volatile=>on) *)
  130. 88 t:BS;
  131. ***** ^ undeclared identifier
  132. 89 (*# restore *)
  133. 90 p,b,s,i,bi:CARDINAL;
  134. 91 BEGIN
  135. 92 IF (x < EGAWidth) AND (y < Graph.Depth) THEN
  136. ***** ^ not supported yet
  137. ***** ^ not supported yet
  138. 93 bi := (7-(x MOD 8));
  139. 94 p := y*80+(x DIV 8);
  140. 95 IF Virtual THEN
  141. ***** ^ undeclared identifier
  142. 96 FOR i := 0 TO 3 DO
  143. 97 IF i IN BS(c) THEN
  144. ***** ^ undeclared identifier
  145. ***** ^ not supported yet
  146. 98 INCL(BS(Buffer[i]^[p]),bi)
  147. ***** ^ undeclared identifier
  148. ***** ^ undeclared identifier
  149. ***** ^ undeclared identifier
  150. ***** ^ not supported yet
  151. ***** ^ not supported yet
  152. ***** ^ not supported yet
  153. 99 ELSE
  154. 100 EXCL(BS(Buffer[i]^[p]),bi);
  155. ***** ^ undeclared identifier
  156. ***** ^ undeclared identifier
  157. ***** ^ undeclared identifier
  158. ***** ^ not supported yet
  159. ***** ^ not supported yet
  160. ***** ^ not supported yet
  161. 101 END;
  162. 102 END;
  163. 103 ELSE
  164. 104 b := 1 << bi;
  165. 105
  166. 106 Out( 3CEH,8);Out( 3CFH,SHORTCARD(b));
  167. ***** ^ undeclared identifier
  168. ***** ^ not supported yet
  169. ***** ^ undeclared identifier
  170. ***** ^ not supported yet
  171. 107 Out( 3C4H,2);Out( 3C5H,0FH);
  172. ***** ^ undeclared identifier
  173. ***** ^ not supported yet
  174. ***** ^ undeclared identifier
  175. ***** ^ not supported yet
  176. 108 s := VideoSel;
  177. ***** ^ undeclared identifier
  178. 109 t := [s:p BP]^;
  179. ***** ^ not supported yet
  180. ***** ^ not supported yet
  181. ***** ^ not supported yet
  182. 110 [s:p BP]^ := BS{};
  183. 111 Out( 3C4H,2);Out( 3C5H,SHORTCARD(c));
  184. 112 [s:p BP]^ := BS{0..7};
  185. 113 Out( 3CEH,8);Out( 3CFH,0FFH);
  186. 114 Out( 3C4H,2);Out( 3C5H,0FH);
  187. 115
  188. 116 END;
  189. 117 END;
  190. 118 END EGAPlot;
  191. 119
  192. 120 PROCEDURE EGAPoint(x,y:CARDINAL) : CARDINAL; (* Also VGA *)
  193. 121 VAR
  194. 122 t:BS;
  195. 123 p,b,s,i:CARDINAL;
  196. 124 c:CARDINAL;
  197. 125 BEGIN
  198. 126 c := 0;
  199. 127 IF (x < EGAWidth) AND (y < Graph.Depth) THEN
  200. 128 b := 1 << (7-(x MOD 8));
  201. 129 p := y*80+(x DIV 8 );
  202. 130
  203. 131 IF Virtual THEN
  204. 132 FOR i := 3 TO 0 BY -1 DO
  205. 133 t := BS(Buffer[i]^[p])*BS(b);
  206. 134 c := c * 2 + CARDINAL( SHORTCARD(t) );
  207. 135 END;
  208. 136 ELSE
  209. 137 s := VideoSel;
  210. 138
  211. 139 Out( 3CEH, 4 ); (* read map sel *)
  212. 140
  213. 141 Out( 3CFH, 3 );
  214. 142 t := [s:p BP]^;
  215. 143 t := t * BS(b);
  216. 144 c := CARDINAL( SHORTCARD(t) );
  217. 145
  218. 146 Out( 3CFH, 2 );
  219. 147 t := [s:p BP]^;
  220. 148 t := t * BS(b);
  221. 149 c := c * 2 + CARDINAL( SHORTCARD(t) );
  222. 150
  223. 151 Out( 3CFH, 1 );
  224. 152 t := [s:p BP]^;
  225. 153 t := t * BS(b);
  226. 154 c := c * 2 + CARDINAL( SHORTCARD(t) );
  227. 155
  228. 156 Out( 3CFH, 0 );
  229. 157 t := [s:p BP]^;
  230. 158 t := t * BS(b);
  231. 159 c := c * 2 + CARDINAL( SHORTCARD(t) );
  232. 160
  233. 161 END;
  234. 162 c := c >> ( 7 - ( x MOD 8 ) );
  235. 163 END;
  236. 164 RETURN c;
  237. 165 END EGAPoint;
  238. 166
  239. 167 PROCEDURE EGAHLine ( x,y,x2 : CARDINAL; c:CARDINAL ); (* Also VGA *)
  240. 168 VAR c1,c2,i : CARDINAL;
  241. 169 BEGIN
  242. 170 IF y >= Graph.Depth THEN RETURN END;
  243. 171 IF INTEGER(x) >= INTEGER(EGAWidth) THEN RETURN END;
  244. 172 IF INTEGER(x) < 0 THEN x := 0; END;
  245. 173 IF x2 >= EGAWidth THEN x2 := EGAWidth-1 END;
  246. 174 WHILE (x MOD 8 # 0) AND (x <= x2) DO
  247. 175 EGAPlot( x , y , c ); INC( x );
  248. 176 END;
  249. 177 WHILE (x2 MOD 8 # 7) AND (x <= x2) DO
  250. 178 EGAPlot( x2 , y , c ); DEC( x2 );
  251. 179 END;
  252. 180 IF INTEGER(x) > INTEGER(x2) THEN RETURN; END;
  253. 181 y := y*80;
  254. 182 x := x DIV 8;
  255. 183 x2 := x2 DIV 8;
  256. 184 IF Virtual THEN
  257. 185 INC(y,x);
  258. 186 WHILE x <= x2 DO
  259. 187 FOR i := 0 TO 3 DO
  260. 188 IF i IN BS(c) THEN
  261. 189 Buffer[i]^[y] := BS{0..7};
  262. 190 ELSE
  263. 191 Buffer[i]^[y] := BS{};
  264. 192 END;
  265. 193 END;
  266. 194 INC( x );
  267. 195 INC( y );
  268. 196 END;
  269. 197 ELSE
  270. 198 Out( 3CEH,8);Out( 3CFH,0FFH);
  271. 199 Out( 3C4H,2);Out( 3C5H,0FH);
  272. 200 Out( 3CEH,5);Out( 3CFH,2);
  273. 201 WHILE x <= x2 DO
  274. 202 [VideoSel:y+x BP]^ := BS(c);
  275. 203 INC( x );
  276. 204 END;
  277. 205 END ;
  278. 206 Out( 3CEH,5);Out( 3CFH,0);
  279. 207 END EGAHLine;
  280. 208
  281. 209 (* -- CGA routines -- *)
  282. 210
  283. 211 PROCEDURE SaveCGAScreen;
  284. 212 BEGIN
  285. 213 GRCopy([VideoSel:0 CGABuffPtr], FarADR(CBuffer), 4000H);
  286. 214 END SaveCGAScreen;
  287. 215
  288. 216
  289. 217 PROCEDURE RestoreCGAScreen();
  290. 218 VAR
  291. 219 bp : CGABuffPtr;
  292. 220 BEGIN
  293. 221 bp := FarADR(CBuffer);
  294. 222 GRCopy(bp, [VideoSel:0 CGABuffPtr], 4000H);
  295. 223 END RestoreCGAScreen;
  296. 224
  297. 225
  298. 226 PROCEDURE CGAPlot(x,y:CARDINAL;c:CARDINAL);
  299. 227 VAR
  300. 228 off : CARDINAL;
  301. 229 seg : CARDINAL;
  302. 230 tmp : CARDINAL;
  303. 231 BEGIN
  304. 232 IF (x >= CGAWidth) OR (y >= CGADepth) THEN RETURN END;
  305. 233 off := x >> 2;
  306. 234 IF ODD(y) THEN INC( off, 2000H - 40 ) END;
  307. 235 INC( y, y << 2 );
  308. 236 INC( off, y << 3 );
  309. 237 x := 3 - CARDINAL( BITSET(x) * BITSET(3) );
  310. 238 x := x << 1;
  311. 239 seg := VideoSel;
  312. 240 [seg:off BP]^ := ( [seg:off BP]^ - BS(3<<x) ) + BS(c<<x);
  313. 241 END CGAPlot;
  314. 242
  315. 243 PROCEDURE CGAPoint(x,y:CARDINAL) : CARDINAL;
  316. 244 VAR
  317. 245 off : CARDINAL;
  318. 246 seg : CARDINAL;
  319. 247 tmp : CARDINAL;
  320. 248 BEGIN
  321. 249 IF (x >= CGAWidth) OR (y >= CGADepth) THEN RETURN MAX(CARDINAL) END;
  322. 250 off := x >> 2;
  323. 251 IF ODD(y) THEN INC( off, 2000H - 40 ) END;
  324. 252 INC( y, y << 2 );
  325. 253 INC( off, y << 3 );
  326. 254 x := 3 - CARDINAL( BITSET(x) * BITSET(3) );
  327. 255 x := x << 1;
  328. 256 seg := VideoSel;
  329. 257 RETURN CARDINAL( [seg:off BP]^ * BS(3<<x) ) >> x;
  330. 258 END CGAPoint;
  331. 259
  332. 260 PROCEDURE CGAHLine ( x,y,x2 : CARDINAL; c:CARDINAL );
  333. 261 VAR
  334. 262 off : CARDINAL;
  335. 263 seg : CARDINAL;
  336. 264 tmp : CARDINAL;
  337. 265 n,i : CARDINAL;
  338. 266 w : BS;
  339. 267 mask : BS;
  340. 268 fillc: SHORTCARD;
  341. 269 BEGIN
  342. 270 IF y > CGADepth-1 THEN RETURN END;
  343. 271 IF INTEGER(x) >= INTEGER(CGAWidth) THEN RETURN END;
  344. 272 IF INTEGER(x) < 0 THEN x := 0; END;
  345. 273 IF x2 >= CGAWidth THEN x2 := CGAWidth-1 END;
  346. 274
  347. 275 n := ( x2 - x ) + 1;
  348. 276 off := x >> 2;
  349. 277 IF ODD(y) THEN
  350. 278 INC( off, 2000H - 40 );
  351. 279 c := ( c >> 2 + c << 2 ) MOD 16;
  352. 280 END;
  353. 281 c := c + c * 16;
  354. 282 INC( y, y << 2 );
  355. 283 INC( off, y << 3 );
  356. 284 x := 3 - CARDINAL( BITSET(x) * BITSET(3) );
  357. 285 x := x << 1;
  358. 286 seg := VideoSel;
  359. 287
  360. 288 w := [seg:off BP]^;
  361. 289 REPEAT
  362. 290 mask := BS(3 << x);
  363. 291 w := ( w - mask ) + BS(c)*mask;
  364. 292 DEC(n);
  365. 293 DEC(x,2);
  366. 294 UNTIL (n=0) OR (x=CARDINAL(-2));
  367. 295 [seg:off BP]^ := w;
  368. 296
  369. 297 INC(off);
  370. 298 FOR i := 1 TO (n>>2) DO
  371. 299 [seg:off BP]^ := BS(c);
  372. 300 INC(off);
  373. 301 END;
  374. 302 n := n MOD 4;
  375. 303 x := 6;
  376. 304 w := [seg:off BP]^;
  377. 305 WHILE n <> 0 DO
  378. 306 mask := BS(3 << x);
  379. 307 w := ( w - mask ) + BS(c)*mask;
  380. 308 DEC(n);
  381. 309 DEC(x,2);
  382. 310 END;
  383. 311 [seg:off BP]^ := w;
  384. 312 END CGAHLine;
  385. 313
  386. 314 PROCEDURE Plot( x,y,c : CARDINAL); (* CGA/EGA/VGA *)
  387. 315 BEGIN
  388. 316 IF IsCGA THEN
  389. 317 CGAPlot(x,y,c);
  390. 318 ELSE
  391. 319 EGAPlot(x,y,c);
  392. 320 END;
  393. 321 END Plot;
  394. 322
  395. 323
  396. 324 PROCEDURE HLine ( x,y,x2 : CARDINAL; c:CARDINAL ); (* CGA/EGA/VGA *)
  397. 325 BEGIN
  398. 326 IF IsCGA THEN
  399. 327 CGAHLine(x,y,x2,c);
  400. 328 ELSE
  401. 329 EGAHLine(x,y,x2,c);
  402. 330 END;
  403. 331 END HLine;
  404. 332
  405. 333
  406. 334 PROCEDURE Line(x1,y1,x2,y2: CARDINAL; c: CARDINAL);
  407. 335 VAR
  408. 336 dx,dy,e,tmp : INTEGER;
  409. 337 BEGIN
  410. 338 IF x1 > x2 THEN (* ensure that x2 >= x1 *)
  411. 339 tmp := x1; x1 := x2; x2 := tmp;
  412. 340 tmp := y1; y1 := y2; y2 := tmp;
  413. 341 END;
  414. 342
  415. 343 dx := x2-x1;
  416. 344 e := 0;
  417. 345 IF y1 <= y2 THEN (* case where y increases *)
  418. 346 dy := (y2-y1);
  419. 347 IF dx >= dy THEN
  420. 348 LOOP
  421. 349 Plot( x1,y1,c );
  422. 350 IF x1 = x2 THEN EXIT END;
  423. 351 INC(x1);
  424. 352 INC(e,dy);
  425. 353 INC(e,dy);
  426. 354 IF e > dx THEN
  427. 355 DEC(e,dx);
  428. 356 DEC(e,dx);
  429. 357 INC(y1);
  430. 358 END;
  431. 359 END;
  432. 360 ELSE
  433. 361 LOOP
  434. 362 Plot( x1,y1,c );
  435. 363 IF y1 = y2 THEN EXIT END;
  436. 364 INC(y1);
  437. 365 INC(e,dx);
  438. 366 INC(e,dx);
  439. 367 IF e > dy THEN
  440. 368 DEC(e,dy);
  441. 369 DEC(e,dy);
  442. 370 INC(x1);
  443. 371 END;
  444. 372 END;
  445. 373 END;
  446. 374 ELSE
  447. 375 (* case where y decreases *)
  448. 376 dy := (y1-y2);
  449. 377 IF dx >= dy THEN
  450. 378 LOOP
  451. 379 Plot( x1,y1,c );
  452. 380 IF x1 = x2 THEN EXIT END;
  453. 381 INC(x1);
  454. 382 INC(e,dy);
  455. 383 INC(e,dy);
  456. 384 IF e > dx THEN
  457. 385 DEC(e,dx);
  458. 386 DEC(e,dx);
  459. 387 DEC(y1);
  460. 388 END;
  461. 389 END;
  462. 390 ELSE
  463. 391 LOOP
  464. 392 Plot( x1,y1,c );
  465. 393 IF y1 = y2 THEN EXIT END;
  466. 394 DEC(y1);
  467. 395 INC(e,dx);
  468. 396 INC(e,dx);
  469. 397 IF e > dy THEN
  470. 398 DEC(e,dy);
  471. 399 DEC(e,dy);
  472. 400 INC(x1);
  473. 401 END;
  474. 402 END;
  475. 403 END;
  476. 404 END;
  477. 405 END Line;
  478. 406
  479. 407
  480. 408 CONST
  481. 409 dx = 2;
  482. 410 dy = 2;
  483. 411
  484. 412 PROCEDURE Disc(x0,y0,r: CARDINAL; c: CARDINAL);
  485. 413 VAR
  486. 414 e : INTEGER;
  487. 415 x,y : CARDINAL;
  488. 416 BEGIN
  489. 417 x := r; y := 0; e := 0;
  490. 418 WHILE INTEGER(y) <= INTEGER(x) DO
  491. 419 HLine(x0-x,y0+y,x0+x,c);
  492. 420 HLine(x0-x,y0-y,x0+x,c);
  493. 421 INC(y);
  494. 422 INC(e,y*dy-1);
  495. 423 IF e > INTEGER(x) THEN
  496. 424 DEC(x);
  497. 425 DEC(e,x*dx+1);
  498. 426 HLine(x0-y,y0+x,x0+y,c);
  499. 427 HLine(x0-y,y0-x,x0+y,c);
  500. 428 END;
  501. 429 END;
  502. 430 END Disc;
  503. 431
  504. 432 PROCEDURE Circle(x0,y0,r: CARDINAL; c: CARDINAL);
  505. 433 VAR
  506. 434 e : INTEGER;
  507. 435 x,y : CARDINAL;
  508. 436 BEGIN
  509. 437 x := r; y := 0; e := 0;
  510. 438 WHILE INTEGER(y) <= INTEGER(x) DO
  511. 439 Plot(x0+x,y0+y,c);
  512. 440 Plot(x0-x,y0+y,c);
  513. 441 Plot(x0+x,y0-y,c);
  514. 442 Plot(x0-x,y0-y,c);
  515. 443 Plot(x0+y,y0+x,c);
  516. 444 Plot(x0-y,y0+x,c);
  517. 445 Plot(x0+y,y0-x,c);
  518. 446 Plot(x0-y,y0-x,c);
  519. 447 INC(y);
  520. 448 INC(e,y*dy-1);
  521. 449 IF e > INTEGER(x) THEN
  522. 450 DEC(x);
  523. 451 DEC(e,x*dx+1);
  524. 452 END;
  525. 453 END;
  526. 454 END Circle;
  527. 455
  528. 456 PROCEDURE Ellipse ( x0,y0 : CARDINAL ; (* center *)
  529. 457 a0,b0 : CARDINAL ; (* semi-axes *)
  530. 458 c : CARDINAL ; (* color *)
  531. 459 fill : BOOLEAN ) ; (* wether filled *)
  532. 460 VAR
  533. 461 x,y : CARDINAL ;
  534. 462 a,b : LONGINT ;
  535. 463 asq,asq2,bsq,bsq2 : LONGINT ;
  536. 464 d,dx,dy : LONGINT ;
  537. 465 BEGIN
  538. 466 x := 0 ;
  539. 467 y := b0 ;
  540. 468 a := LONGINT(a0) ;
  541. 469 b := LONGINT(b0) ;
  542. 470 asq := a*a ;
  543. 471 asq2 := asq*2 ;
  544. 472 bsq := b*b ;
  545. 473 bsq2 := bsq*2 ;
  546. 474 d := bsq-(asq*b)+(asq DIV 4) ;
  547. 475 dx := 0 ;
  548. 476 dy := asq2*b ;
  549. 477 WHILE dx<dy DO
  550. 478 IF fill THEN
  551. 479 HLine(x0-x,y0+y,x0+x,c);
  552. 480 HLine(x0-x,y0-y,x0+x,c);
  553. 481 ELSE
  554. 482 Plot(x0+x,y0+y,c) ;
  555. 483 Plot(x0-x,y0+y,c) ;
  556. 484 Plot(x0+x,y0-y,c) ;
  557. 485 Plot(x0-x,y0-y,c) ;
  558. 486 END ;
  559. 487 IF d>0 THEN
  560. 488 DEC(y) ;
  561. 489 DEC(dy,asq2) ;
  562. 490 DEC(d,dy) ;
  563. 491 END ;
  564. 492 INC(x) ;
  565. 493 INC(dx,bsq2) ;
  566. 494 INC(d,bsq+dx) ;
  567. 495 END ;
  568. 496 INC(d,(3*(asq-bsq)DIV 2-(dx+dy))DIV 2) ;
  569. 497 WHILE INTEGER(y)>=0 DO
  570. 498 IF fill THEN
  571. 499 HLine(x0-x,y0+y,x0+x,c);
  572. 500 HLine(x0-x,y0-y,x0+x,c);
  573. 501 ELSE
  574. 502 Plot(x0+x,y0+y,c) ;
  575. 503 Plot(x0-x,y0+y,c) ;
  576. 504 Plot(x0+x,y0-y,c) ;
  577. 505 Plot(x0-x,y0-y,c) ;
  578. 506 END ;
  579. 507 IF d<0 THEN
  580. 508 INC(x) ;
  581. 509 INC(dx,bsq2) ;
  582. 510 INC(d,dx) ;
  583. 511 END ;
  584. 512 DEC(y) ;
  585. 513 DEC(dy,asq2) ;
  586. 514 INC(d,asq-dy) ;
  587. 515 END ;
  588. 516 END Ellipse ;
  589. 517
  590. 518
  591. 519 PROCEDURE Polygon(n: CARDINAL; px,py: ARRAY OF CARDINAL; c: CARDINAL);
  592. 520 CONST
  593. 521 MaxPts = 20;
  594. 522 VAR
  595. 523 y,miny,maxy,x0,y0,x1,y1,temp,i,edge,next_edge,active : INTEGER;
  596. 524 xord : ARRAY [0..MaxPts] OF INTEGER;
  597. 525 x : ARRAY [0..MaxPts] OF CARDINAL;
  598. 526 e : ARRAY [0..MaxPts] OF INTEGER;
  599. 527
  600. 528 (*# save *)
  601. 529 (*# call(reg_saved=>(ax,bx,cx,ds,si,di,st1,st2)) *)
  602. 530 PROCEDURE quicksort(l,r: INTEGER);
  603. 531 VAR
  604. 532 i,j,temp : INTEGER;
  605. 533 key : CARDINAL;
  606. 534 BEGIN
  607. 535 WHILE ( l < r ) DO
  608. 536 i := l; j := r; key := x[xord[j]];
  609. 537 REPEAT
  610. 538 WHILE ( i < j ) AND ( x[xord[i]] <= key ) DO i := i + 1 END;
  611. 539 WHILE ( i < j ) AND ( key <= x[xord[j]] ) DO j := j - 1 END;
  612. 540 IF i < j THEN
  613. 541 temp := xord[i]; xord[i] := xord[j]; xord[j] := temp;
  614. 542 END;
  615. 543 UNTIL ( i >= j );
  616. 544 temp := xord[i]; xord[i] := xord[r]; xord[r] := temp;
  617. 545 IF (i-l < r-i) THEN
  618. 546 quicksort( l, i-1 ); l := i+1;
  619. 547 ELSE
  620. 548 quicksort( i+1, r ); r := i-1;
  621. 549 END;
  622. 550 END;
  623. 551 END quicksort;
  624. 552 (*# restore *)
  625. 553
  626. 554 BEGIN
  627. 555 IF n > MaxPts THEN n := MaxPts END;
  628. 556
  629. 557 (* find extremal y points *)
  630. 558 miny := py[0]; maxy := miny;
  631. 559 FOR i := 0 TO n-1 DO
  632. 560 IF INTEGER(py[i]) < miny THEN miny := py[i]; END;
  633. 561 IF INTEGER(py[i]) > maxy THEN maxy := py[i]; END;
  634. 562 END;
  635. 563
  636. 564 FOR y := miny TO maxy DO
  637. 565 active := -1;
  638. 566 FOR edge := 0 TO n-1 DO
  639. 567 IF edge = INTEGER(n-1) THEN next_edge := 0 ELSE next_edge := edge + 1; END;
  640. 568 x0 := px[edge]; y0 := py[edge];
  641. 569 x1 := px[next_edge]; y1 := py[next_edge];
  642. 570 IF y0 > y1 THEN temp := x0; x0 := x1; x1 := temp;
  643. 571 temp := y0; y0 := y1; y1 := temp END;
  644. 572 IF y = y0 THEN e[edge] := 0; x[edge] := x0
  645. 573 ELSIF ( y0 <= y ) AND ( y <= y1 ) THEN
  646. 574 IF x1 >= x0 THEN (* x increases with y *)
  647. 575 INC( e[edge], 2*(x1-x0) );
  648. 576 WHILE e[edge] > INTEGER(y1-y0) DO
  649. 577 DEC( e[edge], 2*(y1-y0) ); INC(x[edge]);
  650. 578 END;
  651. 579 ELSE (* x decreases with y *)
  652. 580 INC( e[edge], 2*(x0-x1) );
  653. 581 WHILE e[edge] > INTEGER(y1-y0) DO
  654. 582 DEC( e[edge], 2*(y1-y0) ); DEC(x[edge]);
  655. 583 END;
  656. 584 END;
  657. 585 active := active + 1;
  658. 586 xord[active] := edge;
  659. 587 END;
  660. 588 END;
  661. 589 quicksort(0,active);
  662. 590 i := 0;
  663. 591 WHILE i < active DO
  664. 592 HLine( x[xord[i]], y, x[xord[i+1]], c );
  665. 593 i := i + 2;
  666. 594 END;
  667. 595 END; (* for y := .. *)
  668. 596 END Polygon;
  669. 597
  670. 598 BEGIN
  671. 599 Dos.PortAccess(0, 0, 3C4H, 3C5H);
  672. 600 Dos.PortAccess(0, 0, 3CEH, 3CFH);
  673. 601 END GraphI.
  674. 71 errors