home *** CD-ROM | disk | FTP | other *** search
- /*
- * esm.c
- *
- * This program plots simulated ESM (Electronic Support Measures)
- * reports on IBM EGA/VGA Graphic Adaptors.
- *
- * Public Domain (p) July 1990, S. R. Sampson
- */
-
- /* Includes */
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <math.h>
- #include <conio.h>
- #include <alloc.h>
- #include <dos.h>
- #include <graphics.h>
- #include <mouse.h>
-
- /* Defines */
-
- typedef unsigned char uchar;
- typedef unsigned int uint;
-
- #define PI (3.141593F)
- #define RADIAN (180.0F / PI) /* One radian */
- #define TWOPI (2.0F * PI) /* Two Pi alias 360 Degrees */
- #define TWO (2.0F / RADIAN) /* 2 Degrees in radians */
- #define TEN (10.0F / RADIAN) /* 10 degrees in radians */
- #define ASPECT (0.775F) /* Screen aspect ratio */
-
- #define F1 315 /* Hook track with mouse cursor */
- #define F2 316 /* Erase track info */
- #define F7 321 /* Toggle mouse cursor off/on */
- #define F10 324 /* Return to OS */
-
- /* not used yet */
-
- #define ESC 27
- #define HOMEKEY 327
- #define ENDKEY 335
- #define UPKEY 328
- #define DOWNKEY 336
- #define PGUPKEY 329
- #define PGDNKEY 337
- #define LEFTKEY 331
- #define RIGHTKEY 333
- #define INSKEY 338
- #define DELKEY 339
- #define CTRLLEFTKEY 371
- #define CTRLRIGHTKEY 372
- #define F3 317
- #define F4 318
- #define F5 319
- #define F6 320
- #define F8 322
- #define F9 323
-
- /*
- * A Target Detect
- */
-
- typedef struct {
- uchar amp;
- uchar bearing;
- uchar range;
- uchar leader;
- uint speed;
- char line1[9];
- char line2[9];
- } TRACK;
-
- #define EraseTrack(x, y) PlotTrack(x, y)
-
- /* Globals */
-
- M_POS *Mptr;
- void *Image; /* track symbol */
- int GraphDriver = DETECT; /* graphics device driver */
- int GraphMode; /* graphics mode value */
- int MaxX, MaxY; /* maximum resolution of screen */
- int CenterX, CenterY; /* center of screen */
- int Sw1, Sw2, Sw4, Sw5; /* Five Bit Sliding window */
- uchar CanTgtFile[256]; /* Detections each pass */
- float Aspect; /* Screen aspect ratio */
-
- TRACK FwdTgts1[256]; /* First pass detects */
- TRACK FwdTgts2[256]; /* Second pass detects */
- TRACK *ThisPass = &FwdTgts1[0];
- TRACK *LastPass = &FwdTgts2[0];
-
- int Pos1 = 72; /* Moving test target window */
- int Pos2 = 73;
- int Pos3 = 74;
- int Pos4 = 75;
- int Pos5 = 76;
-
- /*
- * This is a square mouse cursor with a pointer dot in the center
- */
-
- uint Cursor[] = {
- 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xF00F, 0xF7EF, 0xF7EF, 0xF66F,
- 0xF7EF, 0xF7EF, 0xF00F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF0, 0x0810, 0x0810, 0x0990,
- 0x0810, 0x0810, 0x0FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
-
- /*
- * This program was designed to work with EGA Graphics.
- * VGA is supported only in an EGA compatible mode.
- * EGA = 0.775 Aspect Ratio
- *
- * 8-Bit Sine Degree Table for n = 0 to 255
- *
- * Sine[n] = sin(x) * 127, x = x + (360 / 256)
- */
-
- char Sine[] = {
- 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45,
- 48, 51, 54, 57, 59, 62, 65, 67, 70, 73, 75, 78, 80, 82, 85, 87,
- 89, 91, 94, 96, 98, 100, 102, 103, 105, 107, 108, 110, 112, 113,
- 114, 116, 117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 125,
- 126, 126, 126, 126, 126, 127, 126, 126, 126, 126, 126, 125, 125,
- 124, 123, 123, 122, 121, 120, 119, 118, 117, 116, 114, 113, 112,
- 110, 108, 107, 105, 103, 102, 100, 98, 96, 94, 91, 89, 87, 85,
- 82, 80, 78, 75, 73, 70, 67, 65, 62, 59, 57, 54, 51, 48, 45, 42,
- 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0, -3, -6, -9,
- -12, -15, -18, -21, -24, -27, -30, -33, -36, -39, -42, -45, -48,
- -51, -54, -57, -59, -62, -65, -67, -70, -73, -75, -78, -80, -82,
- -85, -87, -89, -91, -94, -96, -98, -100, -102, -103, -105, -107,
- -108, -110, -112, -113, -114, -116, -117, -118, -119, -120, -121,
- -122, -123, -123, -124, -125, -125, -126, -126, -126, -126, -126,
- -127, -126, -126, -126, -126, -126, -125, -125, -124, -123, -123,
- -122, -121, -120, -119, -118, -117, -116, -114, -113, -112, -110,
- -108, -107, -105, -103, -102, -100, -98, -96, -94, -91, -89, -87,
- -85, -82, -80, -78, -75, -73, -70, -67, -65, -62, -59, -57, -54,
- -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21, -18, -15,
- -12, -9, -6, -3
- };
-
- /*
- * 8-Bit Cosine Degree Table for n = 0 to 255
- *
- * Cosine[n] = cos(x) * Aspect * 127, x = x + (360 / 256)
- */
-
- char Cosine[] = {
- 98, 98, 98, 98, 97, 97, 97, 96, 96, 96, 95, 94, 94, 93, 92, 91,
- 90, 89, 88, 87, 86, 85, 84, 83, 81, 80, 79, 77, 76, 74, 72, 71,
- 69, 67, 66, 64, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 39,
- 37, 35, 33, 30, 28, 26, 23, 21, 19, 16, 14, 12, 9, 7, 4, 2,
- 0, -2, -4, -7, -9, -12, -14, -16, -19, -21, -23, -26, -28, -30,
- -33, -35, -37, -39, -42, -44, -46, -48, -50, -52, -54, -56, -58,
- -60, -62, -64, -66, -67, -69, -71, -72, -74, -76, -77, -79, -80,
- -81, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94,
- -94, -95, -96, -96, -96, -97, -97, -97, -98, -98, -98, -98, -98,
- -98, -98, -97, -97, -97, -96, -96, -96, -95, -94, -94, -93, -92,
- -91, -90, -89, -88, -87, -86, -85, -84, -83, -81, -80, -79, -77,
- -76, -74, -72, -71, -69, -67, -66, -64, -62, -60, -58, -56, -54,
- -52, -50, -48, -46, -44, -42, -39, -37, -35, -33, -30, -28, -26,
- -23, -21, -19, -16, -14, -12, -9, -7, -4, -2, 0, 2, 4, 7, 9, 12,
- 14, 16, 19, 21, 23, 26, 28, 30, 33, 35, 37, 39, 42, 44, 46, 48,
- 50, 52, 54, 56, 58, 60, 62, 64, 66, 67, 69, 71, 72, 74, 76, 77,
- 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94,
- 95, 96, 96, 96, 97, 97, 97, 98, 98, 98
- };
-
- /* Function Prototypes */
-
- void InitGraphics(void), GetCommand(void), GenTarget(void);
- void ScanForTgt(void), convert(int, int, int *, int *), quit(void);
- void PlotTrack(int, int), LoadCandidate(void);
- int getkey(void);
-
- /* Main Program */
-
- void main()
- {
- int i;
-
- delay(10); /* need to prime delay to work properly */
-
- for (i = 0; i < 256; i++)
- FwdTgts1[i].amp = FwdTgts2[i].amp = 0;
-
- if ((i = m_init()) == 0) {
- fprintf(stderr, "Fatal - Mouse driver not installed\n");
- exit(1);
- }
-
- if (i == 2) {
- fprintf(stderr, "Fatal - You need DOS 2.0 or greater\n");
- exit(1);
- }
-
- InitGraphics();
- m_graph_cursor(7, 7, (void far *)Cursor);
- m_display(ON);
-
- for (;;) {
- LoadCandidate();
- ScanForTgt();
- GenTarget();
-
- if (kbhit())
- GetCommand();
- }
- }
-
- /* Functions */
-
- /*
- * Get the keyboard command entered
- */
-
- void GetCommand()
- {
- int x, y;
- static char str1[16], str2[16];
-
- switch (getkey()) { /* find out which key was pressed */
- case F1:
- Mptr = m_status();
- outtextxy(550, 20, itoa(Mptr->curx, str1, 10));
- outtextxy(600, 20, itoa(Mptr->cury, str2, 10));
- break;
- case F2:
- setcolor(EGA_BLUE);
- outtextxy(550, 20, str1);
- outtextxy(600, 20, str2);
- setcolor(EGA_LIGHTGRAY);
- break;
- case F7:
- Mptr = m_status();
- if (Mptr->display == ON)
- m_display(OFF);
- else
- m_display(ON);
- break;
- case F10:
- quit();
- }
- }
-
- int getkey()
- {
- int lo, hi, key;
-
- key = bioskey(0);
- lo = key & 0x00FF;
- hi = (key & 0xFF00) >> 8;
-
- return ((lo == 0) ? hi + 256 : lo);
- }
-
- /*
- * Free all data buffers and return to DOS
- */
-
- void quit()
- {
- free(Image);
- closegraph();
- m_display(OFF);
-
- sound(500);
- delay(125);
- nosound();
-
- exit(0);
- }
-
- /*
- * Input test data into the candidate target array
- */
-
- void LoadCandidate()
- {
- int i;
-
- for (i = 0; i < 256; ++i)
- CanTgtFile[i] = 0;
-
- Pos1 = ++Pos1 & 0xFF;
- Pos2 = ++Pos2 & 0xFF;
- Pos3 = ++Pos3 & 0xFF;
- Pos4 = ++Pos4 & 0xFF;
- Pos5 = ++Pos5 & 0xFF;
-
- CanTgtFile[Pos3] = 128; /* Moving Test Target */
- CanTgtFile[Pos1] = 63;
- CanTgtFile[Pos2] = 32;
- CanTgtFile[Pos4] = 32;
- CanTgtFile[Pos5] = 63;
-
- CanTgtFile[200] = 3; /* NW Test Target */
- CanTgtFile[201] = 5;
- CanTgtFile[202] = 9;
- CanTgtFile[203] = 5;
- CanTgtFile[204] = 3;
-
- CanTgtFile[148] = 32; /* SW Test Target */
- CanTgtFile[149] = 50;
- CanTgtFile[150] = 84;
- CanTgtFile[151] = 50;
- CanTgtFile[152] = 32;
-
- CanTgtFile[254] = 32; /* N Test Target */
- CanTgtFile[255] = 50;
- CanTgtFile[000] = 192;
- CanTgtFile[001] = 50;
- CanTgtFile[002] = 32;
- }
-
- /*
- * Run the Sliding Window (sw) through the data
- * and produce peak detects
- */
-
- void ScanForTgt()
- {
- int i, sw3;
-
- Sw1 = 254, /* Sliding window */
- Sw2 = 255,
- Sw4 = 001,
- Sw5 = 002;
-
- for (i = 0; i < 256; ++i) {
-
- /* threshold is twice the average of surrounding signal */
-
- sw3 = CanTgtFile[Sw1];
- sw3 += CanTgtFile[Sw2];
- sw3 += CanTgtFile[Sw4];
- sw3 += CanTgtFile[Sw5];
- sw3 >>= 2; /* divide by 4 (truncate) */
- sw3 <<= 1; /* multiply by 2 */
- sw3 &= 0xFF; /* normalize to range 0 - 255 */
-
- if (CanTgtFile[i] > sw3)
- ThisPass[i].amp = (CanTgtFile[i] * CenterY) >> 8;
- else
- ThisPass[i].amp = 0;
-
- Sw1 = ++Sw1 & 0xFF;
- Sw2 = ++Sw2 & 0xFF;
- Sw4 = ++Sw4 & 0xFF;
- Sw5 = ++Sw5 & 0xFF;
- }
- }
-
- void GenTarget()
- {
- int t1, t2, i, x, y;
- TRACK *tmp;
-
- for (i = 0; i < 256; ++i) {
- t1 = LastPass[i].amp;
- t2 = ThisPass[i].amp;
-
- if (t2) {
-
- /*
- * We have an amplitude on this pass
- */
-
- if (t2 == t1) {
-
- /*
- * Amplitude was already plotted
- */
-
- continue;
- } else if (t1) {
-
- /*
- * Different amplitude was plotted
- * on last pass, so erase old amplitude
- */
-
- convert(i, CenterY-t1, &x, &y);
- EraseTrack(x, y);
-
- /*
- * And plot new amplitude
- */
-
- convert(i, CenterY-t2, &x, &y);
- PlotTrack(x, y);
- } else {
-
- /*
- * No amplitudes plotted on last pass
- */
-
- convert(i, CenterY-t2, &x, &y);
- PlotTrack(x, y);
- }
- }
- else if (t1) {
-
- /*
- * No amplitude on this pass but one on last
- */
-
- convert(i, CenterY-t1, &x, &y);
- EraseTrack(x, y);
- }
- }
-
- /*
- * Swap the data pointers
- */
-
- tmp = ThisPass;
- ThisPass = LastPass;
- LastPass = tmp;
- }
-
- /*
- * This is real slow and ugly yet.
- */
-
- void PlotTrack(int x, int y)
- {
- Mptr = m_status();
-
- if (Mptr->display == ON) {
- m_display(OFF);
- putimage(x-4, y-4, Image, XOR_PUT);
- m_display(ON);
- } else
- putimage(x-4, y-4, Image, XOR_PUT);
- }
-
- /*
- * Initialize the graphics system
- */
-
- void InitGraphics()
- {
- uint size;
- float bearing, t;
- int x, y;
-
- registerbgidriver(EGAVGA_driver);
- initgraph(&GraphDriver, &GraphMode, "");
-
- if (GraphMode == EGAHI)
- ;
- else if (GraphMode == VGAHI) {
- GraphMode = VGAMED;
- setgraphmode(VGAMED);
- } else {
- fprintf(stderr, "Fatal - Program requires EGA or VGA.\n");
- exit(1);
- }
-
- /* Fill in global constants */
-
- MaxX = getmaxx(); /* size of screen (future) */
- MaxY = getmaxy();
- CenterX = (MaxX / 2) - 100; /* PPI center (moved left) */
- CenterY = MaxY / 2;
- Aspect = ASPECT;
-
- /*
- * Create Target Symbol
- */
-
- setcolor(EGA_GREEN);
- circle(23, 14, 3);
- setfillstyle(SOLID_FILL, EGA_GREEN);
- floodfill(23, 14, EGA_GREEN);
-
- setcolor(EGA_LIGHTGREEN);
- rectangle(22, 13, 24, 15);
-
- size = imagesize(19, 11, 28, 27);
- Image = malloc(size);
-
- getimage(19, 11, 28, 27, Image);
- putimage(19, 11, Image, XOR_PUT);
-
- /*
- * Draw the border and scope
- */
-
- cleardevice(); /* Clear graphics screen */
- setcolor(EGA_GREEN);
-
- setactivepage(1);
- outtextxy(175, 175, "Please Wait While Configuring");
- setvisualpage(1);
- setactivepage(0);
-
- setcolor(EGA_LIGHTGRAY);
- circle(CenterX, CenterY, CenterY); /* inner ring */
- circle(CenterX, CenterY, CenterY + 10); /* outer ring */
-
- /*
- * Ten Degree Full size ticks
- */
-
- t = (float)(CenterY + 10);
- for (bearing = 0.0F; bearing < TWOPI; bearing += TEN) {
- moveto(CenterX, CenterY);
- x = CenterX + (int)(t * sin(bearing));
- y = CenterY - (int)(t * cos(bearing) * Aspect);
- lineto(x, y);
- }
-
- /*
- * Two Degree Half size ticks
- */
-
- t = (float)(CenterY + 5);
- for (bearing = 0.0F; bearing < TWOPI; bearing += TWO) {
- moveto(CenterX, CenterY);
- x = CenterX + (int)(t * sin(bearing));
- y = CenterY - (int)(t * cos(bearing) * Aspect);
- lineto(x, y);
- }
-
- /*
- * This routine erases all bearing lines except
- * those between the two circles.
- */
-
- setcolor(WHITE);
- circle(CenterX, CenterY, CenterY); /* inner ring */
-
- setfillstyle(SOLID_FILL, BLACK);
- floodfill(CenterX, CenterY, WHITE);
- setcolor(EGA_LIGHTGRAY);
- circle(CenterX, CenterY, CenterY); /* inner ring */
- outtextxy(CenterX, CenterY, "+");
-
- /*
- * Make a fancy escutcheon
- */
-
- rectangle(0, 0, MaxX, MaxY);
- line(440, 0, 440, 349);
-
- setfillstyle(INTERLEAVE_FILL, EGA_BLUE);
- floodfill(10, 10, EGA_LIGHTGRAY);
-
- setfillstyle(SOLID_FILL, EGA_BLUE);
- floodfill(450, 10, EGA_LIGHTGRAY);
-
- setvisualpage(0);
- }
-
- void convert(int bearing, int amp, int *x, int *y)
- {
- /*
- * Convert polar to rectangular
- */
-
- *x = CenterX + ((amp * Sine[bearing]) >> 7);
- *y = CenterY - ((amp * Cosine[bearing]) >> 7);
- }
-
- /*EOF*/