home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / gl_plot / part06 < prev    next >
Text File  |  1989-03-23  |  43KB  |  1,433 lines

  1. Subject:  v18i064:  GL Graphics Library for AT-clone Unix, Part06/07
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: umix!m-net!dtlewis!lewis
  7. Posting-number: Volume 18, Issue 64
  8. Archive-name: gl_plot/part06
  9.  
  10. # To recover, type "sh archive"
  11. echo restoring config.h
  12. sed 's/^X//' > config.h <<XxX--EOF--XxX
  13. X/*    @(#) config.h 5.1 89/02/20    */
  14. X/*
  15. X *    Copyright (c) David T. Lewis 1987, 1988
  16. X *    All rights reserved.
  17. X *
  18. X *    Permission is granted to use this for any personal noncommercial use.
  19. X *    You may not distribute source or executable code for profit, nor
  20. X *    may you distribute it with a commercial product without the written
  21. X *    consent of the author.  Please send modifications to the author for
  22. X *    inclusion in updates to the program.  Thanks.
  23. X */
  24. X
  25. X/* User modifiable parameters for GL graphics library.            */
  26. X/* ===> BEGIN USER MODIFIABLE PARAMETERS <===                */
  27. X
  28. X/* Select one of the following to specify your target system (Xenix    */
  29. X/* cross compile to MS_DOS should select MS_DOS).            */
  30. X
  31. X#define SVAT 1
  32. X#define XENIX_286 0
  33. X#define MS_DOS 0
  34. X#define UNIX_386 0    /* (not yet supported) */
  35. X#define XENIX_386 0    /* (not yet supported) */
  36. X
  37. X/* If you defined MS_DOS 1, then specify your compiler here.        */
  38. X
  39. X#if MS_DOS
  40. X#define XEN2DOS 1    /* Compile on Xenix 286 for DOS target system    */
  41. X#define USOFT 0        /* Microsoft C under DOS            */
  42. X#define TCC 0        /* Borland Turbo-C                */
  43. X#define MIX_C 0        /* The old CP/M derived MIX-C compiler        */
  44. X#endif /* MS_DOS */
  45. X
  46. X/* The following should be defined if you do NOT have a numeric        */
  47. X/* coprocessor.  It will cause some trig functions to be done with    */
  48. X/* integer math (see trig.c).                        */
  49. X
  50. X#define NOFLOAT 1
  51. X
  52. X/* The following should be defined if you want the gl library to handle    */
  53. X/* interrupt signals.  This will clear the screen and return to text    */
  54. X/* mode when the interrupt key (or ^C, for MS-DOS) is pressed.  If you    */
  55. X/* need to do your own signal routine (to close files, for example),    */
  56. X/* you may prefer not to have this defined.                */
  57. X
  58. X#define DO_CLEANUP 1
  59. X
  60. X/* VIDEO stuff:                                */
  61. X
  62. X/* Define the name of the program or shell script which will be used    */
  63. X/* to switch video modes (UNIX only).  This will be made from either    */
  64. X/* the mode.c program, or the mode.sh shell script, or some equivalent    */
  65. X/* program that works with your system and video adapter.        */
  66. X
  67. X#define MODEPROG "mode"
  68. X/* Another possible choice:                        */
  69. X/* #define MODEPROG "/usr/local/bin/mode"                */
  70. X
  71. X/* Define the name of the environment variable that you wish to use to     */
  72. X/* indicate your default graphics mode.  If we call g_init(ENV_MODE),    */
  73. X/* then we will use this environment variable to set the graphics mode.    */
  74. X
  75. X#define GL_ENV_MODE "GLMODE"
  76. X
  77. X/* If the environment variable is not set, then fall back to         */
  78. X/* DEFAULT_MODE as a last resort.  Mode 4 is CGA color mode, a safe    */
  79. X/* choice for most systems.                        */
  80. X
  81. X#define DEFAULT_MODE 4
  82. X
  83. X/* PRINTER stuff:                            */
  84. X
  85. X/* Define name of the environment variable that you wish to set to     */
  86. X/* indicate your default print device.                    */
  87. X
  88. X#define GL_PLOT_DEV "PLOTDEV"
  89. X
  90. X/* For MS-DOS, define your printer device name (and ignore the rest    */
  91. X/* of the printer stuff that follows).  Note: Microsoft compilers will    */
  92. X/* send output to "stdprn" regardless of how you define this; other     */
  93. X/* compilers will use the device you define below.  See code in     */
  94. X/* g_finish.c if you need to change this.                */
  95. X
  96. X#define DOSPRINTER "PRN:"
  97. X
  98. X/* Define the standard print spooler program for your system (UNIX).    */
  99. X
  100. X#define PRINTPROG "/usr/bin/lp"
  101. X#define LP_DEV_FLAG "-d"
  102. X
  103. X/* Define the device to use if GL_PLOT_DEV is not set.            */
  104. X/* Note:  Use "lp" only if you plan to manually put the printer        */
  105. X/* driver in transparency mode (see lpset(1M)).                */
  106. X/* On Microport, your printer devices might look something like the    */
  107. X/* following, where /dev/lp is the standard printer driver, and        */
  108. X/* /dev/lpt is the transparency mode printer driver.  See the "Readme"    */
  109. X/* file for more information.                        */
  110. X/*                                     */
  111. X/* \$ ls -li /dev/lp*                            */
  112. X/*   82 crw-rw-rw-   2 root     sys        7,  0 Oct  9 18:03 /dev/lp    */
  113. X/*   82 crw-rw-rw-   2 root     sys        7,  0 Oct  9 18:03 /dev/lp0    */
  114. X/*   83 crw-rw-rw-   1 root     sys        7,  1 Feb 11  1988 /dev/lp1    */
  115. X/*  295 crw-rw-rw-   2 root     sys        7,128 Oct  9 18:08 /dev/lpt    */
  116. X/*  295 crw-rw-rw-   2 root     sys        7,128 Oct  9 18:08 /dev/lpt0    */
  117. X/*  291 crw-rw-rw-   1 root     sys        7,129 May 22 18:42 /dev/lpt1    */
  118. X
  119. X#define PRINTDEV "lpt"
  120. X
  121. X/* You may need to tweak the following in order to get round circles.    */
  122. X
  123. X#define HERC_ASPECT_RATIO 0.7
  124. X#define CGA_ASPECT_RATIO 0.85
  125. X#define EGA_ASPECT_RATIO 0.6
  126. X#define IBM_PR_ASPECT_RATIO 0.7
  127. X#define LJ_PR_ASPECT_RATIO 0.81
  128. X
  129. X/* For Xenix System V 286, you must indicate the video adapter you    */
  130. X/* are using.  Microport users can ignore this (they must, however,     */
  131. X/* create a shared memory key with shmcreate(1).  MS-DOS users may    */
  132. X/* also ignore this.                            */
  133. X
  134. X#define GL_CGA 0
  135. X#define GL_EGA 1
  136. X#define GL_HERC 0
  137. X#define GL_PGA 0    /* (not implemented)                */
  138. X#define GL_VGA 0    /* (easy to do, but not implemented)        */
  139. X
  140. X/* The following definitions specify the shared memory key identifiers    */
  141. X/* which are used by Microport System V/AT.  You are free to use any    */
  142. X/* identifiers you want to map to video memory with shmcreate(1).    */
  143. X/* The following are the recommended values.  If you use these, the    */
  144. X/* key values will be the same as the physical memory addresses.    */
  145. X/* Change these definitions only if you are using different shared    */
  146. X/* memory keys for your system.  Xenix users may ignore this.        */
  147. X
  148. X#define MCA_KEY 0xB0000L
  149. X#define CGA_KEY 0xB8000L
  150. X#define HERC_P0KEY 0xB0000L
  151. X#define HERC_P1KEY 0xB8000L
  152. X#define EGA_KEY 0xA0000L
  153. X
  154. X/* ===> END USER MODIFIABLE PARAMETERS <===                */
  155. X
  156. X/* The following definitions specify the physical memory locations of    */
  157. X/* video memory, for use with MS-DOS.                    */
  158. X
  159. X#define DOS_MCA 0xB0000000L
  160. X#define DOS_CGA 0xB8000000L
  161. X#define DOS_H_P0 0xB0000000L
  162. X#define DOS_H_P1 0xB8000000L
  163. X#define DOS_EGA 0xA0000000L
  164. X
  165. X/* Some specific system dependent characteristics.            */
  166. X
  167. X#if MIX_C
  168. X#define HAS_SIG 0    /* System does not have ^C interrupt handling    */
  169. X#else
  170. X#if USOFT
  171. X#define HAS_SIG 0    /* System does not have ^C interrupt handling    */
  172. X#else
  173. X#if XEN2DOS
  174. X#define HAS_SIG 0    /* System does not have ^C interrupt handling    */
  175. X#else
  176. X#define HAS_SIG 1    /* System has ^C interrupt handling        */
  177. X#endif /* XEN2DOS */
  178. X#endif /* USOFT */
  179. X#endif /* MIX_C */
  180. X
  181. X#if MIX_C
  182. X#define HAS_ENV 0    /* System does not have getenv() call        */
  183. X#else
  184. X#define HAS_ENV 1    /* System has getenv() call            */
  185. X#endif /* MIX_C */
  186. X
  187. X#if MS_DOS
  188. X#define HAS_PIPES 0    /* System does not have popen() call        */
  189. X#else
  190. X#define HAS_PIPES 1    /* System has popen() call            */
  191. X#endif /* MS_DOS */
  192. X
  193. X#if USOFT
  194. X#define HAS_SLEEP 0    /* System does not have sleep() call        */
  195. X#else
  196. X#if XEN2DOS
  197. X#define HAS_SLEEP 0    /* System does not have sleep() call        */
  198. X#else
  199. X#if MIX_C
  200. X#define HAS_SLEEP 0    /* System does not have sleep() call        */
  201. X#else
  202. X#define HAS_SLEEP 1    /* System has sleep() call            */
  203. X#endif /* MIX_C */
  204. X#endif /* XEN2DOS */
  205. X#endif /* USOFT */
  206. X
  207. X#if MIX_C
  208. X#define HAS_FMOD 0    /* System does not have fmod() call        */
  209. X#else
  210. X#define HAS_FMOD 1    /* System has fmod() call            */
  211. X#endif /* MIX_C */
  212. X
  213. X#if MIX_C
  214. X#define HAS_ATAN2 0    /* System does not have atan2() call        */
  215. X#else
  216. X#define HAS_ATAN2 1    /* System has atan2() call            */
  217. X#endif /* MIX_C */
  218. X
  219. X/* Some MS-DOS compilers have "stdprn" predefined for stream output to    */
  220. X/* the printer.                                */
  221. X
  222. X#if USOFT
  223. X#define HAS_STDPRN 1
  224. X#else
  225. X#if XEN2DOS
  226. X#define HAS_STDPRN 1
  227. X#else
  228. X#if TCC
  229. X#define HAS_STDPRN 1
  230. X#else /* "stdprn" is not predefined    */
  231. X#define HAS_STDPRN 0
  232. X#endif /* TCC */
  233. X#endif /* XEN2DOS */
  234. X#endif /* USOFT */
  235. X
  236. X/* The following should be defined for 286 versions, in which an    */
  237. X/* integer is 16 bits.  Other machines must do extra work to check    */
  238. X/* for out of range on the normalized 2-D screen space (0 through    */
  239. X/* 32767).                                */
  240. X
  241. X#if MS_DOS
  242. X#else
  243. X#if XENIX_286
  244. X#else
  245. X#if SVAT
  246. X#define INT16 1
  247. X#else    /* Not a 16 bit integer machine    */
  248. X#define INT16 0
  249. X#endif /* SVAT */
  250. X#endif /* XENIX_286 */
  251. X#endif /* MS_DOS */
  252. X
  253. X/* Parameter to signal call is system dependent.  Define a macro to     */
  254. X/* handle the difference between pointer to void and pointer to int.    */
  255. X
  256. X#if TCC
  257. X#define SIG_TYPE void
  258. X#else
  259. X#define SIG_TYPE int
  260. X#endif /* TCC */
  261. X
  262. X/* Some compilers can use a macro for the calculation for transform     */
  263. X/* from normalized 2-D to screen coordinates.  If yours can't, then    */
  264. X/* define N_TO_P_MACRO as 0.                        */
  265. X/* (All the compilers I've tried are working now with the macro.  Leave    */
  266. X/* this here just in case...)                        */
  267. X
  268. X#define N_TO_P_MACRO 1
  269. X
  270. X/* Compiler specific stuff for MS-DOS.                    */
  271. X
  272. X/* For MS-DOS, use the DO_BIOS macro to point to the library routine    */
  273. X/* that invokes a BIOS call.  Int is the interrupt number, and reg     */
  274. X/* is a pointer to a structure representing machine registers.        */
  275. X/* Define REGISTERS as the name of the data structure for machine    */
  276. X/* registers (probably declared in <stdlib.h>).                */
  277. X/* The remaining macros (AL, AH ...) specify individual registers    */
  278. X/* within the REGISTERS data structure, as they would be referenced    */
  279. X/* in a    REGISTERS structure (e.g. "inreg.AH").                */
  280. X
  281. X#if MIX_C
  282. X#define DO_BIOS(int,inreg,outreg) bios(int,inreg) 
  283. X#define REGISTERS REGS
  284. X#define AL byte.al
  285. X#define AH byte.ah
  286. X#define BL byte.bl
  287. X#define BH byte.bh
  288. X#define CL byte.cl
  289. X#define CH byte.ch
  290. X#define DL byte.dl
  291. X#define DH byte.dh
  292. X#endif /* MIX_C */
  293. X
  294. X#if USOFT
  295. X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
  296. X#define REGISTERS union REGS
  297. X#define AL h.al
  298. X#define AH h.ah
  299. X#define BL h.bl
  300. X#define BH h.bh
  301. X#define CL h.cl
  302. X#define CH h.ch
  303. X#define DL h.dl
  304. X#define DH h.dh
  305. X#endif /* USOFT */
  306. X
  307. X#if XEN2DOS
  308. X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
  309. X#define REGISTERS union REGS
  310. X#define AL h.al
  311. X#define AH h.ah
  312. X#define BL h.bl
  313. X#define BH h.bh
  314. X#define CL h.cl
  315. X#define CH h.ch
  316. X#define DL h.dl
  317. X#define DH h.dh
  318. X#endif /* XEN2DOS */
  319. X
  320. X#if TCC
  321. X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
  322. X#define REGISTERS union REGS
  323. X#define AL h.al
  324. X#define AH h.ah
  325. X#define BL h.bl
  326. X#define BH h.bh
  327. X#define CL h.cl
  328. X#define CH h.ch
  329. X#define DL h.dl
  330. X#define DH h.dh
  331. X#endif /* TCC */
  332. X
  333. XxX--EOF--XxX
  334. echo restoring g_fntctl.c
  335. sed 's/^X//' > g_fntctl.c <<XxX--EOF--XxX
  336. X#ifndef lint
  337. Xstatic char sccsid[] = "@(#) g_fntctl.c 5.1 89/02/20";
  338. X#endif
  339. X
  340. X/*
  341. X *    Copyright (c) David T. Lewis 1988
  342. X *    All rights reserved.
  343. X *
  344. X *    Permission is granted to use this for any personal noncommercial use.
  345. X *    You may not distribute source or executable code for profit, nor
  346. X *    may you distribute it with a commercial product without the written
  347. X *    consent of the author.  Please send modifications to the author for
  348. X *    inclusion in updates to the program.  Thanks.
  349. X */
  350. X
  351. X/* Control size, aspect ratio, spacing, angle and slant of stroke font.    */
  352. X/* Size, aspect ratio and spacing control height, relative width and    */
  353. X/* relative spacing of characters, with 1.0 selecting default values.    */
  354. X/* Changing size will change the width and spacing appropriately.    */
  355. X/* Changing width will change the spacing.                */
  356. X/* Angle is the angle of a text string in radians, with positive    */
  357. X/* values rotating the text clockwise.  Slant is the character slant    */
  358. X/* in radians (typically a number on the order of 0.2), with positive    */
  359. X/* values slanting the text to the "right," as in italics.        */
  360. X
  361. X#include "config.h"
  362. X#include "bitmaps.h"
  363. X#include "graphics.h"
  364. X
  365. Xextern struct GL_graphics graphics;
  366. X
  367. Xint g_fontctl(size, aspect_ratio, spacing, angle, slant)
  368. Xfloat size, aspect_ratio, spacing, angle, slant;
  369. X
  370. X{
  371. X    graphics.strokefont.xtic
  372. X        = (int)(size * aspect_ratio * spacing *
  373. X        (float)graphics.default_strokefont.xtic);
  374. X    graphics.strokefont.ytic
  375. X        = (int)(size * (float)graphics.default_strokefont.ytic);
  376. X    graphics.strokefont.xsize
  377. X        = (int)(size * aspect_ratio * 
  378. X        (float)graphics.default_strokefont.xsize);
  379. X    graphics.strokefont.ysize
  380. X        = (int)(size * (float)graphics.default_strokefont.ysize);
  381. X    graphics.strokefont.angle = angle;
  382. X    graphics.strokefont.slant = slant;
  383. X
  384. X    if (angle == 0.0) graphics.strokefont.angle_flag = FALSE;
  385. X    else graphics.strokefont.angle_flag = TRUE;
  386. X
  387. X    if (slant == 0.0) graphics.strokefont.slant_flag = FALSE;
  388. X    else graphics.strokefont.slant_flag = TRUE;
  389. X
  390. X    return(0);
  391. X}
  392. X
  393. XxX--EOF--XxX
  394. echo restoring gf_types.h
  395. sed 's/^X//' > gf_types.h <<XxX--EOF--XxX
  396. X/****** Warning! Do not alter this file without updating gl.h! *******/
  397. X
  398. X/*    @(#) gf_types.h 5.1 89/02/20    */
  399. X/*
  400. X *    Copyright (c) David T. Lewis 1988
  401. X *    All rights reserved.
  402. X *
  403. X *    Permission is granted to use this for any personal noncommercial use.
  404. X *    You may not distribute source or executable code for profit, nor
  405. X *    may you distribute it with a commercial product without the written
  406. X *    consent of the author.  Please send modifications to the author for
  407. X *    inclusion in updates to the program.  Thanks.
  408. X */
  409. X
  410. X/*    Definition(s) required for more than one include file.
  411. X */
  412. X
  413. X/* Define pixel setting modes.             */
  414. X
  415. X#define CLEAR 0
  416. X#define AND 1
  417. X#define OR 2
  418. X#define XOR 3
  419. X
  420. X/* Define colors.                 */
  421. X
  422. X#define BLACK        0
  423. X#define BLUE         1
  424. X#define GREEN        2
  425. X#define CYAN         3
  426. X#define RED          4
  427. X#define MAGENTA      5
  428. X#define BROWN        6
  429. X#define WHITE        7
  430. X#define GREY         8
  431. X#define LT_BLUE      9
  432. X#define LT_GREEN    10
  433. X#define LT_CYAN     11
  434. X#define LT_RED      12
  435. X#define LT_MAGENTA  13
  436. X#define YELLOW      14
  437. X#define LT_WHITE    15
  438. X
  439. X/* Define line styles (not yet implemented).    */
  440. X
  441. X#define SOLID 0xffffffffL    /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  */
  442. X#define DOTTED 0x66666666L    /* XX..XX..XX..XX..XX..XX..XX..XX..  */
  443. X#define DASHED 0xffe0ffe0L    /* XXXXXXXXXXX.....XXXXXXXXXXX.....  */
  444. X#define SHORTDASHED 0xf8f8f8f8L    /* XXXXX...XXXXX...XXXXX...XXXXX...  */
  445. X#define LONGDASHED 0xffffff00L    /* XXXXXXXXXXXXXXXXXXXXXXXX........  */
  446. X#define DOTDASHED 0xfc30fc30L    /* XXXXXX....XX....XXXXXX....XX....  */
  447. X
  448. X/* Define line weights (not yet implemented).    */
  449. X
  450. X#define LIGHT 1
  451. X#define MEDIUM 2
  452. X#define HEAVY 4
  453. X
  454. X
  455. XxX--EOF--XxX
  456. echo restoring gl.h
  457. sed 's/^X//' > gl.h <<XxX--EOF--XxX
  458. X/*    @(#) gl.h 5.1 89/02/20    */
  459. X/*
  460. X *    Copyright (c) David T. Lewis 1988
  461. X *    All rights reserved.
  462. X *
  463. X *    Permission is granted to use this for any personal noncommercial use.
  464. X *    You may not distribute source or executable code for profit, nor
  465. X *    may you distribute it with a commercial product without the written
  466. X *    consent of the author.  Please send modifications to the author for
  467. X *    inclusion in updates to the program.  Thanks.
  468. X */
  469. X
  470. X/*    This file defines the interface to the graphics library, and should
  471. X *    be included in user programs.
  472. X */
  473. X
  474. X/* Definition of programming interface to gl library.    */
  475. X
  476. Xextern int g_clear();
  477. Xextern int g_init();
  478. Xextern int g_finish();
  479. Xextern int g_pix_mode();
  480. Xextern int g_pix_color();
  481. Xextern int g_fontctl();
  482. Xextern long g_style();
  483. Xextern int g_weight();
  484. Xextern int p_wr_pix();
  485. Xextern int c_cellchar();
  486. Xextern int c_cellstr();
  487. Xextern int c_cursor();
  488. Xextern int n_movepen();
  489. Xextern int n_box();
  490. Xextern int n_line();
  491. Xextern int n_draw();
  492. Xextern int n_grafchar();
  493. Xextern int n_grafstr();
  494. Xextern int n_arc();
  495. Xextern int n_ellipse();
  496. Xextern int n_point();
  497. X
  498. X/* Everything that follows should be identical to gf_types.h and modes.h. */
  499. X
  500. X/*    @(#) gf_types.h 1.4 88/12/26    */
  501. X
  502. X/* Define pixel setting modes.             */
  503. X
  504. X#define CLEAR 0
  505. X#define AND 1
  506. X#define OR 2
  507. X#define XOR 3
  508. X
  509. X/* Define colors.                 */
  510. X
  511. X#define BLACK        0
  512. X#define BLUE         1
  513. X#define GREEN        2
  514. X#define CYAN         3
  515. X#define RED          4
  516. X#define MAGENTA      5
  517. X#define BROWN        6
  518. X#define WHITE        7
  519. X#define GREY         8
  520. X#define LT_BLUE      9
  521. X#define LT_GREEN    10
  522. X#define LT_CYAN     11
  523. X#define LT_RED      12
  524. X#define LT_MAGENTA  13
  525. X#define YELLOW      14
  526. X#define LT_WHITE    15
  527. X
  528. X/* Define line styles.    */
  529. X
  530. X#define SOLID 0xffffffffL    /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  */
  531. X#define DOTTED 0x66666666L    /* XX..XX..XX..XX..XX..XX..XX..XX..  */
  532. X#define DASHED 0xffe0ffe0L    /* XXXXXXXXXXX.....XXXXXXXXXXX.....  */
  533. X#define SHORTDASHED 0xf8f8f8f8L    /* XXXXX...XXXXX...XXXXX...XXXXX...  */
  534. X#define LONGDASHED 0xffffff00L    /* XXXXXXXXXXXXXXXXXXXXXXXX........  */
  535. X#define DOTDASHED 0xfc30fc30L    /* XXXXXX....XX....XXXXXX....XX....  */
  536. X
  537. X/* Define line weights (not yet implemented).    */
  538. X
  539. X#define LIGHT 1
  540. X#define MEDIUM 2
  541. X#define HEAVY 4
  542. X
  543. X/*    @(#) modes.h 1.4 89/01/10    */
  544. X
  545. X/*
  546. X *    Mode definitions.  These will be used by init(), and by the mode
  547. X *    program or shell script.  As much as possible, the numeric mode
  548. X *    values should correspond to those used by the uPort screen driver
  549. X *    and by DOS.  The values given for hercules and for printers are
  550. X *    arbitrary, but should not conflict with other "standard" assignments.
  551. X */
  552. X
  553. X/* ENV_MODE means take the mode setting from an environment variable. */
  554. X#define ENV_MODE 0
  555. X
  556. X/* CGA text modes */
  557. X#define MONO_TEXT 0x02
  558. X#define COLOR_TEXT 0x03
  559. X
  560. X/* CGA modes (for CGA or EGA) */
  561. X#define CGA_COLOR_MODE 0x04
  562. X#define CGA_HI_RES_MODE 0x06
  563. X
  564. X/* Monochrome text mode */
  565. X#define MDA_TEXT 0x07
  566. X
  567. X/* Hercules mono graphics, page 0 and page 1 */
  568. X/* Note:  Modes 8 and 9 were used by the IBM PC Junior.  I trust that     */
  569. X/* they will not be found on your machine.                */
  570. X#define HERC_P0_MODE 0x08
  571. X#define HERC_P1_MODE 0x09
  572. X
  573. X/* EGA 640 x 350 color mode */
  574. X#define EGA_COLOR_MODE 0x010
  575. X
  576. X/* Anything beyond MAXVIDEO is not a video board.  Printers and other    */
  577. X/* hardcopy would fall in this category.                */
  578. X
  579. X#define MAXVIDEO 0x0FF
  580. X
  581. X/* Non-video modes follow.                        */
  582. X
  583. X#define IBM_PRINTER 0x100
  584. X
  585. X
  586. XxX--EOF--XxX
  587. echo restoring modes.h
  588. sed 's/^X//' > modes.h <<XxX--EOF--XxX
  589. X/****** Warning! Do not alter this file without updating gl.h! *******/
  590. X
  591. X/*    @(#) modes.h 5.1 89/02/20    */
  592. X/*
  593. X *    Copyright (c) David T. Lewis 1987, 1988
  594. X *    All rights reserved.
  595. X *
  596. X *    Permission is granted to use this for any personal noncommercial use.
  597. X *    You may not distribute source or executable code for profit, nor
  598. X *    may you distribute it with a commercial product without the written
  599. X *    consent of the author.  Please send modifications to the author for
  600. X *    inclusion in updates to the program.  Thanks.
  601. X */
  602. X
  603. X/*
  604. X *    Mode definitions.  These will be used by init(), and by the mode
  605. X *    program or shell script.  As much as possible, the numeric mode
  606. X *    values should correspond to those used by the uPort screen driver
  607. X *    and by DOS.  The values given for hercules and for printers are
  608. X *    arbitrary, but should not conflict with other "standard" assignments.
  609. X */
  610. X
  611. X/* ENV_MODE means take the mode setting from an environment variable. */
  612. X#define ENV_MODE 0
  613. X
  614. X/* CGA text modes */
  615. X#define MONO_TEXT 0x02
  616. X#define COLOR_TEXT 0x03
  617. X
  618. X/* CGA modes (for CGA or EGA) */
  619. X#define CGA_COLOR_MODE 0x04
  620. X#define CGA_HI_RES_MODE 0x06
  621. X
  622. X/* Monochrome text mode */
  623. X#define MDA_TEXT 0x07
  624. X
  625. X/* Hercules mono graphics, page 0 and page 1 */
  626. X/* Note:  Modes 8 and 9 were used by the IBM PC Junior.  I trust that     */
  627. X/* they will not be found on your machine.                */
  628. X#define HERC_P0_MODE 0x08
  629. X#define HERC_P1_MODE 0x09
  630. X
  631. X/* EGA 640 x 350 color mode */
  632. X#define EGA_COLOR_MODE 0x010
  633. X
  634. X/* Anything beyond MAXVIDEO is not a video board.  Printers and other    */
  635. X/* hardcopy would fall in this category.                */
  636. X
  637. X#define MAXVIDEO 0x0FF
  638. X
  639. X/* Non-video modes follow.                        */
  640. X
  641. X#define IBM_PRINTER 0x100
  642. X#define LJ_PRINTER 0x101
  643. X
  644. X
  645. XxX--EOF--XxX
  646. echo restoring n_curves.c
  647. sed 's/^X//' > n_curves.c <<XxX--EOF--XxX
  648. X#ifndef lint
  649. Xstatic char sccsid[] = "@(#) n_curves.c 5.1 89/02/20";
  650. X#endif
  651. X
  652. X/*
  653. X *    Copyright (c) David T. Lewis 1988
  654. X *    All rights reserved.
  655. X *
  656. X *    Permission is granted to use this for any personal noncommercial use.
  657. X *    You may not distribute source or executable code for profit, nor
  658. X *    may you distribute it with a commercial product without the written
  659. X *    consent of the author.  Please send modifications to the author for
  660. X *    inclusion in updates to the program.  Thanks.
  661. X */
  662. X
  663. X/*    Sat Aug  6 20:38:14 EDT 1988
  664. X**
  665. X** n_arc():
  666. X**
  667. X** Routine to draw an arc as a partial ellipse.  This routine uses
  668. X** parts of the ellipse() routine to generate the curve.
  669. X** The arc is drawn around an ellipse located at (x,y) with axes a and b.
  670. X** The arc begins at the angle angle1 and traverses counterclockwise to
  671. X** angle2.  "Counterclockwise" is in the sense of the normalized coordinate
  672. X** system, with an inverted Y axis, so the arcs are actually drawn clockwise
  673. X** on the display screen.
  674. X** The values of angle1 and angle2 are given in radians, with 0 being to the
  675. X** right of the center of the ellipse.
  676. X**
  677. X** n_ellipse():
  678. X**
  679. X** Routine to draw an ellipse in normalized 2-d coordinates.  Uses a line
  680. X** segment approximation to the ellipse.  The trig is done with hard coded
  681. X** tables of cos and sin values for speed.  The number of vertices on the
  682. X** ellipse varies according to the size of the ellipse.  The eliminates
  683. X** unnecessary calculations of endpoints for small images.
  684. X** Another method for ellipe drawing would be to do a modified Bresenham
  685. X** type algorithm, but this would be less adaptable for drawing partial arcs.
  686. X**
  687. X** NOTE:  This is an ellipse routine, and not a circle, because the PC display
  688. X** adapters do not generally have square pixels.  A circle routine should be
  689. X** done at a higher level, and should take the screen aspect ration into
  690. X** account (see graphics->aspect_ratio in the graphics.h file).
  691. X**
  692. X** The basic idea is:
  693. X**
  694. X**    Equation of an ellipse:
  695. X**
  696. X**    x^2 / a^2 + y^2 / b^2 = 1
  697. X**
  698. X**    Therefore the X and Y values are:
  699. X**
  700. X**        X = a * cos(theta)
  701. X**        Y = b * sin(theta)
  702. X**
  703. X**        For some angle theta.
  704. X**
  705. X**    By stepping through values of theta, we can generate a list of 
  706. X**    line segment endpoints on the ellipse.  Then call n_movepen() and
  707. X**    n_draw() to display the ellipse.
  708. X**
  709. X**    Note:  The macros PTS_PER_QUADRANT and TRIG_SCALE are defined 
  710. X**    in graphics.h.
  711. X*/
  712. X
  713. X#include "config.h"
  714. X#if MIX_C
  715. X#else
  716. X#include <math.h>
  717. X#endif /* MIX_C */
  718. X#include "bitmaps.h"
  719. X#include "graphics.h"
  720. X
  721. X#ifndef M_PI
  722. X#define M_PI    3.1415926536 
  723. X#endif /* M_PI */
  724. X#ifndef M_PI_2
  725. X#define M_PI_2    1.5707963268 
  726. X#endif /* M_PI_2 */
  727. X
  728. X#define XINDEX 0        /* For specifying array indices.    */
  729. X#define YINDEX 1
  730. X
  731. X/* The following two arrays are tables of values for cos and sin    */
  732. X/* for one quadrant of a circle, divided into PTS_PER_QUADRANT slices.    */
  733. X/* They are found in source file trig.c.                */
  734. X
  735. Xextern long cos_table[PTS_PER_QUADRANT];
  736. Xextern long sin_table[PTS_PER_QUADRANT];
  737. Xextern long longsin(), longcos();
  738. Xextern int n_movepen(), n_draw();
  739. X
  740. Xstatic void make_endpoints(x,y,a,b,endpoints,step)
  741. Xint x,y,a,b,step;
  742. Xint endpoints[4][PTS_PER_QUADRANT][2];
  743. X{
  744. X    int idx;        /* Loop index.            */
  745. X    int value;        /* Temporary storage of values    */
  746. X
  747. X    /* Set the values for points on the ellipse.  While we're    */
  748. X    /* at it, scale the values back down using TRIG_SCALE, and do    */
  749. X    /* the x and y translation to the center point of the ellipse.    */
  750. X    /* Calculations are done with long ints to preserve precision,    */
  751. X    /* then cast back to short ints in the endpoints array.        */
  752. X    /* Use the value of step to skip unnecessary points (for small    */
  753. X    /* ellipes and arcs).                        */
  754. X
  755. X    for(idx=step-1; idx<PTS_PER_QUADRANT; idx+= step)  {
  756. X        value = (cos_table[idx] * (long)a) / TRIG_SCALE;
  757. X        endpoints[0][idx][XINDEX] = value + x;
  758. X        value = -value;
  759. X        endpoints[2][idx][XINDEX] = value + x;
  760. X        value = (sin_table[idx] * (long)a) / TRIG_SCALE;
  761. X        endpoints[3][idx][XINDEX] = value + x;
  762. X        value = -value;
  763. X        endpoints[1][idx][XINDEX] = value + x;
  764. X        value = (cos_table[idx] * (long)b) / TRIG_SCALE;
  765. X        endpoints[1][idx][YINDEX] = value + y;
  766. X        value = -value;
  767. X        endpoints[3][idx][YINDEX] = value + y;
  768. X        value = (sin_table[idx] * (long)b) / TRIG_SCALE;
  769. X        endpoints[0][idx][YINDEX] = value + y;
  770. X        value = -value;
  771. X        endpoints[2][idx][YINDEX] = value + y;
  772. X    }
  773. X    return;
  774. X}
  775. X
  776. Xstatic int make_step(a,b)
  777. Xint a,b;
  778. X{
  779. X    int size;
  780. X    size = a + b;    /* an indication of the "size" of the ellipse.    */
  781. X    if (size <= 0) return(1);    /* Check for integer overflow.    */
  782. X    else if (size < 2000) return(16);
  783. X    else if (size < 8000) return(8);
  784. X    else if (size < 16000) return(4);
  785. X    else if (size < 32000) return(2);
  786. X    else return(1);
  787. X}
  788. X
  789. Xint n_arc(x,y,a,b,angle1,angle2)
  790. Xint x,y,a,b;
  791. Xfloat angle1,angle2;
  792. X{
  793. X    int endpoints[4][PTS_PER_QUADRANT][2];
  794. X    int x_1,y_1,x_2,y_2;    /* The start and end points of the arc.    */
  795. X    int quadrant;        /* Quadrant of first point.        */
  796. X    int endquadrant;    /* Quadrant of second point.        */
  797. X    int index;        /* First index into endpoints array.    */
  798. X    int endindex;        /* Last index into endpoints array.    */
  799. X    int istat = 0;        /* Function call return status.        */
  800. X    int step;    /* Amount by which to step through array.    */
  801. X
  802. X    /* Size of a circle, in radians.                */
  803. X    float cir_size = M_PI * 2;
  804. X
  805. X    /* Don't feed huge numbers to the trig functions.        */
  806. X    if (fabs(angle1) > cir_size)
  807. X        angle1 = fmod((double)angle1,(double)cir_size);
  808. X    if (fabs(angle2) > cir_size)
  809. X        angle2 = fmod((double)angle2,(double)cir_size);
  810. X
  811. X    /* Make the angles positive.                    */
  812. X    while (angle1 < 0) angle1 += cir_size;
  813. X    while (angle2 < 0) angle2 += cir_size;
  814. X
  815. X    /* Calculate a value for step, so we can use fewer endpoints    */
  816. X    /* for small arcs.                        */
  817. X    step = make_step(a,b);
  818. X
  819. X#ifdef DEBUG
  820. X    printf("step is %d\n",step);
  821. X#endif /* DEBUG */
  822. X
  823. X    /* Calculate the end points.    */
  824. X
  825. X#if NOFLOAT
  826. X    x_1 = x + (int)((longcos(angle1) * a) / TRIG_SCALE); 
  827. X    y_1 = y + (int)((longsin(angle1) * b) / TRIG_SCALE);
  828. X    x_2 = x + (int)((longcos(angle2) * a) / TRIG_SCALE);
  829. X    y_2 = y + (int)((longsin(angle2) * b) / TRIG_SCALE);
  830. X#else
  831. X    x_1 = x + (int)(a * cos((double)angle1));
  832. X    y_1 = y + (int)(b * sin((double)angle1));
  833. X    x_2 = x + (int)(a * cos((double)angle2));
  834. X    y_2 = y + (int)(b * sin((double)angle2));
  835. X#endif /* NOFLOAT */
  836. X
  837. X    /* Generate the array of arc endpoints. */
  838. X    make_endpoints(x,y,a,b,endpoints,step);
  839. X
  840. X    /* Deduce the first and last element of interest in the     */
  841. X    /* endpoint array.    */
  842. X
  843. X    /* First calculate the initial index value.    */
  844. X    index = (int)(angle1 / M_PI_2 * (float)PTS_PER_QUADRANT);
  845. X    /* Now figure the quadrant.    */
  846. X    quadrant = (index / PTS_PER_QUADRANT) % 4;
  847. X    /* Wrap around so we point at the array.    */
  848. X    index = (index % PTS_PER_QUADRANT);
  849. X    index = index + step - (index % step) - 1;
  850. X
  851. X#ifdef DEBUG
  852. X    printf("In n_arc(), index is %d\n",index);
  853. X#endif /* DEBUG */
  854. X
  855. X    /* Calculate the final index value.    */
  856. X    endindex = (int)(angle2 / M_PI_2 * (float)PTS_PER_QUADRANT);
  857. X    /* Now figure the quadrant.    */
  858. X    endquadrant = (endindex / PTS_PER_QUADRANT) % 4;
  859. X    /* Wrap around so we point at the array.    */
  860. X    endindex = (endindex % PTS_PER_QUADRANT);
  861. X    endindex = endindex + step - (endindex % step) - 1;
  862. X
  863. X#ifdef DEBUG
  864. X    printf("In n_arc(), endindex is %d\n",endindex);
  865. X#endif /* DEBUG */
  866. X
  867. X    /* Move pen to start point. */
  868. X
  869. X#ifdef DEBUG
  870. X    printf("Move pen to %d %d\n",x_1,y_1);
  871. X#endif /* DEBUG */
  872. X
  873. X    if(n_movepen(x_1,y_1)) istat = 1;
  874. X
  875. X    /* Start drawing, beginning with the first point of interest.     */
  876. X    /* Wrap around the array if needed.                */
  877. X
  878. X    while ((index != endindex) || (quadrant != endquadrant))  {
  879. X
  880. X#ifdef DEBUG
  881. X    printf("Draw to %d %d -- quadrant %d index %d\n", 
  882. X        endpoints[quadrant][index][XINDEX], 
  883. X        endpoints[quadrant][index][YINDEX],quadrant,index);
  884. X#endif /* DEBUG */
  885. X
  886. X        if(n_draw(endpoints[quadrant][index][XINDEX], 
  887. X            endpoints[quadrant][index][YINDEX]))  {
  888. X            istat = 1;
  889. X            /* This is just for cleaner error recovery: */
  890. X            n_movepen(endpoints[quadrant][index][XINDEX], 
  891. X                endpoints[quadrant][index][YINDEX]); 
  892. X        }
  893. X        /* Increment the indices.    */
  894. X        if ((index+=step) >= PTS_PER_QUADRANT)  {
  895. X            index = step - 1;
  896. X            if ((++quadrant) >= 4)  {
  897. X                quadrant = 0;
  898. X            }
  899. X        }
  900. X    };
  901. X
  902. X    /* Finish at last point of interest.    */
  903. X
  904. X#ifdef DEBUG
  905. X    printf("Finish by drawing to %d %d\n",x_2,y_2);
  906. X#endif /* DEBUG */
  907. X
  908. X    if(n_draw(x_2,y_2))  {
  909. X        istat = 1;
  910. X        /* This is just for cleaner error recovery: */
  911. X        n_movepen(x_2,y_2);
  912. X    } 
  913. X    return(istat);
  914. X}
  915. X
  916. Xint n_ellipse(x,y,a,b)
  917. Xint x,y,a,b;
  918. X{
  919. X    /* The endpoints array will hold line segment (x,y) end points.    */
  920. X    /* There are four quadrants, each with PTS_PER_QUADRANT points,    */
  921. X    /* with two values (X and Y) each.                */
  922. X    int endpoints[4][PTS_PER_QUADRANT][2];
  923. X    int pointindex, quadrant;    /* Loop index.            */
  924. X    int istat = 0;            /* Function call return status.    */
  925. X    int step;    /* Amount by which to step through array.    */
  926. X
  927. X    /* Calculate a value for step, so we can use fewer endpoints    */
  928. X    /* for small ellipses.                        */
  929. X    step = make_step(a,b);
  930. X
  931. X    /* Build the array of endpoints.                */
  932. X    make_endpoints(x,y,a,b,endpoints,step);
  933. X
  934. X    /* Display the result, drawing all four quadrants.        */
  935. X
  936. X    /* Start the pen at the location of the last endpoint.  This    */
  937. X    /* is the point we want to end up on.                */
  938. X    if(n_movepen(endpoints[3][PTS_PER_QUADRANT-1][XINDEX],
  939. X        endpoints[3][PTS_PER_QUADRANT-1][YINDEX]))
  940. X        istat = 1;
  941. X
  942. X    for (quadrant=0; quadrant<=3; quadrant++)  {
  943. X
  944. X        for (pointindex = step -1; pointindex < PTS_PER_QUADRANT; 
  945. X            pointindex += step)  {
  946. X            if(n_draw(endpoints[quadrant][pointindex][XINDEX],
  947. X                endpoints[quadrant][pointindex][YINDEX]))  {
  948. X                istat = 1;
  949. X                /* This is just for cleaner error recovery: */
  950. X                n_movepen(endpoints[quadrant][pointindex]
  951. X                        [XINDEX],
  952. X                    endpoints[quadrant][pointindex]
  953. X                        [YINDEX]);
  954. X            }
  955. X        }
  956. X    }
  957. X    return(istat);
  958. X}
  959. X
  960. XxX--EOF--XxX
  961. echo restoring plot.c
  962. sed 's/^X//' > plot.c <<XxX--EOF--XxX
  963. X#ifndef lint
  964. Xstatic char sccsid[] = "@(#) plot.c 5.1 89/02/20";
  965. X#endif
  966. X
  967. X/*
  968. X *    Copyright (c) David T. Lewis 1988
  969. X *    All rights reserved.
  970. X *
  971. X *    Permission is granted to use this for any personal noncommercial use.
  972. X *    You may not distribute source or executable code for profit, nor
  973. X *    may you distribute it with a commercial product without the written
  974. X *    consent of the author.  Please send modifications to the author for
  975. X *    inclusion in updates to the program.  Thanks.
  976. X */
  977. X
  978. X#include "config.h"
  979. X#include "gf_types.h"
  980. X#include <stdio.h>
  981. X#if MIX_C
  982. X#else
  983. X#include <math.h>
  984. X#endif /* MIX_C */
  985. X#include "modes.h"
  986. X#include "bitmaps.h"
  987. X#include "graphics.h"
  988. X
  989. X/* The following declarations copied from gl.h.    */
  990. Xextern int g_clear();
  991. Xextern int g_init();
  992. Xextern int g_finish();
  993. Xextern long g_style();
  994. Xextern int c_cellstr();
  995. Xextern int n_movepen();
  996. Xextern int n_line();
  997. Xextern int n_draw();
  998. Xextern int n_arc();
  999. Xextern int n_ellipse();
  1000. Xextern int n_point();
  1001. X
  1002. Xextern struct GL_graphics graphics;
  1003. X
  1004. X/* These routines emulate the BSD plot(3) library.
  1005. X *
  1006. X * The arc() routine may vary slightly from the BSD version,
  1007. X * in that it calculates start and end angles with trig
  1008. X * functions, rather than with simple integer approximations
  1009. X * used in the BSD routine.
  1010. X *
  1011. X * plot:    openpl,    erase, label, line, circle, arc, move, cont,
  1012. X * point, linemod, space, closepl - graphics interface
  1013. X *
  1014. X * Coordinate transformations, using X0, X1, Y0, Y1 set in space(): 
  1015. X * X:
  1016. X *     x' = x * (NRM_X_RANGE)/(X1-X0) - (X0*NRM_X_RANGE)/(X1-X0)
  1017. X *     x' = (X0*NRM_X_RANGE + x*NRM_X_RANGE) / (X1-X0)
  1018. X * 
  1019. X *     xconst = X0*NRM_X_RANGE;
  1020. X *     xdiv = X1-X0;
  1021. X *     x' = (xconst+x*NRM_X_RANGE)/xdiv;
  1022. X * 
  1023. X * Y:
  1024. X *     y' = y * (-NRM_Y_RANGE)/(Y1-Y0) + (Y1*NRM_Y_RANGE)/(Y1-Y0)
  1025. X *     y' = (Y1*NRM_Y_RANGE - y*NRM_Y_RANGE) / (Y1-Y0)
  1026. X * 
  1027. X *     yconst = Y1*NRM_Y_RANGE;
  1028. X *     ydiv = Y1-Y0;
  1029. X *     y' = (yconst-y*NRM_Y_RANGE)/ydiv;
  1030. X */
  1031. X
  1032. X/* X_TO_NORM(x) and Y_TO_NORM(y) are used to translate from the plot()    */
  1033. X/* coordinate system, as defined by scale(), to the normalized 2-D    */
  1034. X/* coordinate system of the screen.                    */
  1035. X
  1036. X#define X_TO_NORM(x) ((int)((xconst+x*NRM_X_RANGE)/xdiv))
  1037. X#define Y_TO_NORM(y) ((int)((yconst-y*NRM_Y_RANGE)/ydiv))
  1038. X
  1039. X/* X_SCALE_NORM() and Y_SCALE_NORM() are used for scaling magnitudes.    */
  1040. X
  1041. X#define X_SCALE_NORM(x) (((x)*(NRM_X_RANGE))/(xdiv))
  1042. X#define Y_SCALE_NORM(y) (((y)*(NRM_Y_RANGE))/(ydiv))
  1043. X
  1044. Xstatic long xconst,xdiv,yconst,ydiv;    /* Used in space() transforms.    */
  1045. X
  1046. Xint openpl()
  1047. X{
  1048. X    /* Try to get the mode from the environment.        */
  1049. X    /* If no environment variable, use a default.        */
  1050. X    if((g_init(ENV_MODE)) == 0) return(0);
  1051. X    else {
  1052. X        /* Put warning message to standard error, then    */
  1053. X        /* continue.                    */
  1054. X        fprintf(stderr,"Use environment variable %s to control mode.\n",
  1055. X            GL_ENV_MODE);
  1056. X        fprintf(stderr,"Continuing with default mode %d\n",
  1057. X            DEFAULT_MODE);
  1058. X        sleep(2);
  1059. X        return(g_init(DEFAULT_MODE));
  1060. X    }
  1061. X}
  1062. X
  1063. Xint erase()
  1064. X{
  1065. X    return(g_clear());
  1066. X}
  1067. X
  1068. Xint label(s)
  1069. Xchar s[];
  1070. X{
  1071. X    return(c_cellstr(s));
  1072. X}
  1073. X
  1074. Xint line(x_1, y_1, x_2, y_2)
  1075. Xint x_1,y_1,x_2,y_2;
  1076. X{
  1077. X    return(n_line(
  1078. X        X_TO_NORM(x_1),Y_TO_NORM(y_1),X_TO_NORM(x_2),Y_TO_NORM(y_2)));
  1079. X}
  1080. X
  1081. Xint circle(x, y, r)
  1082. X{
  1083. X    int x_axis=X_SCALE_NORM(r);
  1084. X    int y_axis=Y_SCALE_NORM(r);
  1085. X    return(n_ellipse(X_TO_NORM(x), Y_TO_NORM(y), x_axis, y_axis));
  1086. X}
  1087. X
  1088. Xint arc(x, y, x_0, y_0, x_1, y_1)
  1089. X{
  1090. X    int x_axis, y_axis;        /* Major and minor axes.    */
  1091. X    float angle1, angle2;        /* Start and end angles.    */
  1092. X    int radius;    /* Radius, as calculated from sqrt(x**2+y**2).    */
  1093. X    long dx_0 = x_0 - x;
  1094. X    long dy_0 = y_0 - y;
  1095. X    long dx_1 = x_1 - x;
  1096. X    long dy_1 = y_1 - y;
  1097. X
  1098. X    /* We will draw a section of elliptical arc with major and     */
  1099. X    /* minor axes such that it appears as a circle on the screen.    */
  1100. X    /* We know the center of the arc (x and y), and the ratio of    */
  1101. X    /* the major and minor axes (b/a equals graphics.aspect_ratio).    */
  1102. X    /* Given the start and end points of the arc, we need to solve    */
  1103. X    /* for the first and second angle, and then for major and minor    */
  1104. X    /* axes.                            */
  1105. X    /* These values can be used to call the n_arc() routine.    */
  1106. X
  1107. X    /* WARNING:  The value of angle2 is calculated directly as the    */
  1108. X    /* angle of the vector from (x,y) to (x_1,y_1).  The original    */
  1109. X    /* versions of plot(3) from the BSD code apparently use        */
  1110. X    /* a simplistic approximation to this, which may lead to    */
  1111. X    /* different screen displays for arcs drawn with the BSD    */
  1112. X    /* code.  The basic idea for the user, however, should be to    */
  1113. X    /* specify x_1 and y_1 such that they fall very close to the    */
  1114. X    /* intended angle.                        */
  1115. X
  1116. X    angle1 = (float)(-atan2((double)dy_0,(double)dx_0));
  1117. X    angle2 = (float)(-atan2((double)dy_1,(double)dx_1));
  1118. X
  1119. X    radius = ((int)(sqrt(fabs((double)(dx_0*dx_0+dy_0*dy_0)))));
  1120. X    x_axis = X_SCALE_NORM(radius);
  1121. X    y_axis = Y_SCALE_NORM(radius);
  1122. X
  1123. X    return(n_arc(X_TO_NORM(x),Y_TO_NORM(y),x_axis,y_axis,angle2,angle1));
  1124. X}
  1125. X
  1126. Xint move(x, y)
  1127. Xint x,y;
  1128. X{
  1129. X    return(n_movepen(X_TO_NORM(x),Y_TO_NORM(y)));
  1130. X}
  1131. X
  1132. Xint cont(x, y)
  1133. Xint x,y;
  1134. X{
  1135. X    return(n_draw(X_TO_NORM(x),Y_TO_NORM(y)));
  1136. X}
  1137. X
  1138. Xint point(x, y)
  1139. Xint x, y;
  1140. X{
  1141. X    return(n_point(X_TO_NORM(x),Y_TO_NORM(y)));
  1142. X}
  1143. X
  1144. Xint linemod(s)
  1145. Xchar s[];
  1146. X{
  1147. X    if (strncmp(s, "dotted", 6) == 0)  {
  1148. X        g_style(DOTTED);
  1149. X    }
  1150. X    else if (strncmp(s, "dotdashed", 9) == 0)  {
  1151. X        g_style(DOTDASHED);
  1152. X    }
  1153. X    else if (strncmp(s, "longdashed", 10) == 0)  {
  1154. X        g_style(LONGDASHED);
  1155. X    }
  1156. X    else if (strncmp(s, "shortdashed", 11) == 0)  {
  1157. X        g_style(SHORTDASHED);
  1158. X    }
  1159. X    else if (strncmp(s, "solid", 5) == 0)  {
  1160. X        g_style(SOLID);
  1161. X    }
  1162. X    else  {
  1163. X        g_style(SOLID);
  1164. X    }
  1165. X    return(0);
  1166. X}
  1167. X
  1168. Xint space(x_0, y_0, x_1, y_1)
  1169. X{
  1170. X    /* Set constants for coordinate transformations.        */
  1171. X    /* Adjust x axis for aspect ratio so that output is square.    */
  1172. X
  1173. X     xconst = (long)(x_0) * NRM_X_RANGE; 
  1174. X     xdiv = (long)((float)(x_1-x_0) / graphics.aspect_ratio);
  1175. X     yconst = y_1*NRM_Y_RANGE;
  1176. X     ydiv = y_1-y_0;
  1177. X}
  1178. X
  1179. Xint closepl()
  1180. X{
  1181. X    return(g_finish());
  1182. X}
  1183. X
  1184. XxX--EOF--XxX
  1185. echo restoring trig.c
  1186. sed 's/^X//' > trig.c <<XxX--EOF--XxX
  1187. X#ifndef lint
  1188. Xstatic char sccsid[] = "@(#) trig.c 5.1 89/02/20";
  1189. X#endif
  1190. X
  1191. X/*
  1192. X *    Copyright (c) David T. Lewis 1988
  1193. X *    All rights reserved.
  1194. X *
  1195. X *    Permission is granted to use this for any personal noncommercial use.
  1196. X *    You may not distribute source or executable code for profit, nor
  1197. X *    may you distribute it with a commercial product without the written
  1198. X *    consent of the author.  Please send modifications to the author for
  1199. X *    inclusion in updates to the program.  Thanks.
  1200. X */
  1201. X
  1202. X/* Integer approximations to simple trig functions.  Results are scaled    */
  1203. X/* by a factor of TRIG_SCALE.                        */
  1204. X
  1205. X/* The macro TRIG_SCALE is defined in graphics.h so that other routines    */
  1206. X/* can use it.  F_TRIG_SCALE is the same value, but in floating point    */
  1207. X/* format.  The defines should look like this:                */
  1208. X/*                                    */
  1209. X/*    #define TRIG_SCALE 32768                    */
  1210. X/*    #define F_TRIG_SCALE 32768.0                    */
  1211. X/*                                    */
  1212. X/* The macro PTS_PER_QUADRANT defines the size of the sin_table and    */
  1213. X/* cos_table arrays.  It is defined in graphics.h and should look    */
  1214. X/* like this:                                */
  1215. X/*                                    */
  1216. X/*    #define PTS_PER_QUADRANT 64                    */
  1217. X/*                                    */
  1218. X
  1219. X#include "config.h"
  1220. X#if MIX_C
  1221. X#else
  1222. X#include <math.h>
  1223. X#endif /* MIX_C */
  1224. X#include "bitmaps.h"
  1225. X#include "graphics.h"
  1226. X
  1227. X#define L_PI 102944L        /* Value of pi times TRIG_SCALE.    */
  1228. X#define L_PI_2 51472L        /* Value of pi/2 times TRIG_SCALE.    */
  1229. X#define L_PI_4 25736L        /* Value of pi/4 times TRIG_SCALE.    */
  1230. X
  1231. X#define CIRCLE_SIZE 205887L    /* Value of pi * 2 * TRIG_SCALE.    */
  1232. X
  1233. X#define TABLESLICE 804L        /* (L_PI_2 / PTS_PER_QUADRANT)        */
  1234. X
  1235. X#define XINDEX 0        /* For specifying array indices.    */
  1236. X#define YINDEX 1
  1237. X
  1238. X/* The following two arrays are tables of values for cos and sin    */
  1239. X/* for one quadrant of a circle, divided into PTS_PER_QUADRANT slices.    */
  1240. X
  1241. Xlong cos_table[PTS_PER_QUADRANT] = {
  1242. X    32758L, 32729L, 32679L, 32610L, 32522L, 32413L, 32286L, 32138L, 
  1243. X    31972L, 31786L, 31581L, 31357L, 31114L, 30853L, 30572L, 30274L, 
  1244. X    29957L, 29622L, 29269L, 28899L, 28511L, 28106L, 27684L, 27246L, 
  1245. X    26791L, 26320L, 25833L, 25330L, 24812L, 24279L, 23732L, 23170L, 
  1246. X    22595L, 22006L, 21403L, 20788L, 20160L, 19520L, 18868L, 18205L, 
  1247. X    17531L, 16846L, 16151L, 15447L, 14733L, 14010L, 13279L, 12540L, 
  1248. X    11793L, 11039L, 10279L, 9512L, 8740L, 7962L, 7180L, 6393L, 
  1249. X    5602L, 4808L, 4011L, 3212L, 2411L, 1608L, 804L, 0L
  1250. X};
  1251. X
  1252. Xlong sin_table[PTS_PER_QUADRANT] = {
  1253. X    804L, 1608L, 2411L, 3212L, 4011L, 4808L, 5602L, 6393L, 
  1254. X    7180L, 7962L, 8740L, 9512L, 10279L, 11039L, 11793L, 12540L, 
  1255. X    13279L, 14010L, 14733L, 15447L, 16151L, 16846L, 17531L, 18205L, 
  1256. X    18868L, 19520L, 20160L, 20788L, 21403L, 22006L, 22595L, 23170L, 
  1257. X    23732L, 24279L, 24812L, 25330L, 25833L, 26320L, 26791L, 27246L, 
  1258. X    27684L, 28106L, 28511L, 28899L, 29269L, 29622L, 29957L, 30274L, 
  1259. X    30572L, 30853L, 31114L, 31357L, 31581L, 31786L, 31972L, 32138L, 
  1260. X    32286L, 32413L, 32522L, 32610L, 32679L, 32729L, 32758L, 32768L
  1261. X};
  1262. X
  1263. X/* Estimate sin by interpolation.  Return long integer value.        */
  1264. X
  1265. Xlong longsin(theta)
  1266. Xfloat theta;
  1267. X{
  1268. X    long longtheta;
  1269. X    int quadrant;
  1270. X    long value1, value2;
  1271. X    long value;
  1272. X    long intpart;
  1273. X    long fractionpart;
  1274. X
  1275. X    /* We have a floating point value for theta.  Put theta     */
  1276. X    /* into a long integer for the rest of the processing.        */
  1277. X    /* Keep everything scaled by a factor of TRIG_SCALE.        */
  1278. X
  1279. X    longtheta = (long)(theta * F_TRIG_SCALE);
  1280. X
  1281. X    /* Make angle positive.                        */
  1282. X
  1283. X    while (longtheta < 0) longtheta += CIRCLE_SIZE;
  1284. X
  1285. X    /* Figure quadrant while making it less than PI/2.        */
  1286. X
  1287. X    quadrant = 1;
  1288. X
  1289. X    while (longtheta > L_PI_2)  {
  1290. X        longtheta -= L_PI_2;
  1291. X        quadrant++;
  1292. X        if (quadrant > 4) quadrant = 1;
  1293. X    }
  1294. X
  1295. X    /* If Quadrant 2 or 4 we need to use the reverse of the        */
  1296. X    /* interpolation table.                        */
  1297. X
  1298. X    if (quadrant == 2 || quadrant == 4) longtheta = L_PI_2 - longtheta;
  1299. X
  1300. X    /* Express angle in terms of number of table increments.    */
  1301. X
  1302. X    intpart = longtheta / TABLESLICE;
  1303. X
  1304. X    fractionpart = longtheta % TABLESLICE;
  1305. X
  1306. X    /* This looks like a kludge, but it isn't.  When TABLESLICE is    */
  1307. X    /* set to TABLESLICE, we have the smallest error in the result.    */
  1308. X    /* This just rounds back down when we overshoot the table.    */
  1309. X
  1310. X    if (intpart >= PTS_PER_QUADRANT)  {
  1311. X        intpart = PTS_PER_QUADRANT - 1;
  1312. X        fractionpart = TABLESLICE;
  1313. X    }
  1314. X
  1315. X    /* Interpolate.                            */
  1316. X
  1317. X    if (intpart <= 0)  {
  1318. X        value1 = 0;
  1319. X        value2 = sin_table[0];
  1320. X    }
  1321. X    else  {
  1322. X        value2 = sin_table[(int)(intpart--)];
  1323. X        value1 = sin_table[(int)intpart];
  1324. X    }
  1325. X
  1326. X    value = value1 + (fractionpart * (value2 - value1)) / TABLESLICE;
  1327. X
  1328. X    /* If Quadrant 3 or 4 the result should be negative.        */
  1329. X
  1330. X    if (quadrant == 3 || quadrant == 4) return(-value);
  1331. X    else return(value);
  1332. X}
  1333. X
  1334. X
  1335. X/* Estimate cos by interpolation.  Return long integer value.        */
  1336. X
  1337. Xlong longcos(theta)
  1338. Xfloat theta;
  1339. X{
  1340. X    long longtheta;
  1341. X    int quadrant;
  1342. X    long value1, value2;
  1343. X    long value;
  1344. X    long intpart;
  1345. X    long fractionpart;
  1346. X
  1347. X    /* We have a floating point value for theta.  Put theta     */
  1348. X    /* into a long integer for the rest of the processing.        */
  1349. X    /* Keep everything scaled by a factor of TRIG_SCALE.        */
  1350. X
  1351. X    longtheta = (long)(theta * F_TRIG_SCALE);
  1352. X
  1353. X    /* Make angle positive.                        */
  1354. X
  1355. X    while (longtheta < 0) longtheta += CIRCLE_SIZE;
  1356. X
  1357. X    /* Figure quadrant while making it less than PI/2.        */
  1358. X
  1359. X    quadrant = 1;
  1360. X
  1361. X    while (longtheta > L_PI_2)  {
  1362. X        longtheta -= L_PI_2;
  1363. X        quadrant++;
  1364. X        if (quadrant > 4) quadrant = 1;
  1365. X    }
  1366. X
  1367. X    /* If Quadrant 2 or 4 we need to use the reverse of the        */
  1368. X    /* interpolation table.                        */
  1369. X
  1370. X    if (quadrant == 2 || quadrant == 4) longtheta = L_PI_2 - longtheta;
  1371. X
  1372. X    /* Express angle in terms of number of table increments.    */
  1373. X
  1374. X    intpart = longtheta / TABLESLICE;
  1375. X
  1376. X    fractionpart = longtheta % TABLESLICE;
  1377. X
  1378. X    /* This looks like a kludge, but it isn't.  When TABLESLICE is    */
  1379. X    /* set to TABLESLICE, we have the smallest error in the result.    */
  1380. X    /* This just rounds back down when we overshoot the table.    */
  1381. X
  1382. X    if (intpart >= PTS_PER_QUADRANT)  {
  1383. X        intpart = PTS_PER_QUADRANT - 1;
  1384. X        fractionpart = TABLESLICE;
  1385. X    }
  1386. X
  1387. X    /* Interpolate.                            */
  1388. X
  1389. X    if (intpart <= 0)  {
  1390. X        value1 = 32768L;
  1391. X        value2 = cos_table[0];
  1392. X    }
  1393. X    else  {
  1394. X        value2 = cos_table[(int)(intpart--)];
  1395. X        value1 = cos_table[(int)intpart];
  1396. X    }
  1397. X
  1398. X    value = value1 + (fractionpart * (value2 - value1)) / TABLESLICE;
  1399. X
  1400. X    /* If Quadrant 2 or 3 the result should be negative.        */
  1401. X
  1402. X    if (quadrant == 2 || quadrant == 3) return(-value);
  1403. X    else return(value);
  1404. X}
  1405. X
  1406. X/* Test program:
  1407. Xmain()  {
  1408. X    float theta;
  1409. X
  1410. Xfloat sinval;
  1411. Xfloat lsinval;
  1412. Xfloat cosval;
  1413. Xfloat lcosval;
  1414. X
  1415. X    for (theta = -8.3; theta < 100.0; theta += 0.1)  {
  1416. X
  1417. X        sinval = sin((double)theta);
  1418. X        lsinval = longsin(theta) / F_TRIG_SCALE;
  1419. X        cosval = cos((double)theta);
  1420. X        lcosval = longcos(theta) / F_TRIG_SCALE;
  1421. X
  1422. X        printf("SIN: angle %g    %lg    %g    err %g\n",theta,sinval,
  1423. X        lsinval,sinval-lsinval);
  1424. X        printf("COS: angle %g    %lg    %g    err %g\n",theta,cosval,
  1425. X        lcosval,cosval-lcosval);
  1426. X    }
  1427. X}
  1428. X*/
  1429. X
  1430. XxX--EOF--XxX
  1431.  
  1432.  
  1433.