📄 graph1.c
字号:
/****************************************************************
* File : graph.c
* Function : This file contains graphics routines used by the BCM93180
* controller program. These routine use the BGI routines
* from Borland C.
* Authors : P.J. Michalewicz, I.A. Ikizyan
* History : 04/02/96 - PJM - Initial Coding
* : 08/30/96 - IAI - New Ownership of Coding
* : 06/12/97 - DGM - Added hooks for REVA/REVB auto detect
* Notes :
****************************************************************/
/* include files */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
#include <alloc.h>
#include <string.h>
#include <dos.h>
#include <graphics.h>
#include "qam3118.h"
#include "host_api.h"
#include "fft.h"
/* compiler constants */
#define FKEY_MENU_HEIGHT 80
#define LINE_BORDER 20
#define STAT_BORDER 20
#define FKEY_BORDER 8
#define CONST_FILE_SIZE 4096
#define MAX_ACQBUF 256
#define CONST_BORDER 25
#define QPSK 0
#define QAM16 1
#define QAM64 2
#define QAM256 3
#define COUNT_SATS 1
#define COUNT_ERRS 2
#define PLOT_UNARY 1
#define PLOT_SPECTRUM 0x10
#define BUFSIZE 512
#define LOOPBUFSIZE 64
#define CONST_REFRESH 4*BUFSIZE
/* for dithering display in zoom mode */
#define CONST_DITHER (random(2) - 1)
#define QAM_SYMMODE (0x3 & (stat0 >> 8))
/* misc compiler constants */
#define STATUS_XPOS 50
#define STATUS_YPOS 5
#define LP_TEST(p1,p2,p3) if (p1 < p2) p1 = p2; if (p1 > p3) p1 = p3
/* indicates when BER measurement is not valid */
#define UNDEFINED_BER -1.0
/***************************************************************
* This structure is used to display status information to the
* screen. It is used by plot_status().
**************************************************************/
typedef struct plot_status_t {
char *name;
char *val;
char *unit;
} plot_status_t;
typedef struct script_info_t {
char filename[64]; /* file containing script */
int status; /* 1 if loaded, 0 otherwise */
int size; /* size in bytes of image */
uint addr; /* HC11 address where loaded */
} script_info_t;
/* global variables */
extern qamstatus_t qam_status;
float snr_data[64],snr_buf[16];
/* function prototypes */
/**************************************************************
* line_plot - This routine scales and draws a line plot to the
* screen in the specified region. The arguments are as follows:
* 'window' defines the screen coordinates (x1,y1, x2,y2)
* 'buf' is the data to plot ... must be float.
* 'bufsize' is size of buf array
* 'scale' if > 0.0, autoscaling will be disabled.
* 'mode' defines plot mode (LOG or LINEAR, UNIPOLAR or BIPOLAR)
* 'title' 2D string array
* title[0] = plot title
* title[1] = x axis label
* title[2] = y axis label
* title[3] = misc info
**************************************************************/
void line_plot(int *window,float buf[],int bufsize,float scale,int mode,char *title[])
{
int i, c , x, y, start, stop, zero_crossing;
int minx, miny, maxx, maxy,tick;
float xscale, yscale, maxbufy, minbufy,delta;
int done=0;
char txt_maxy[80],txt_miny[80];
/* clear the window */
setfillstyle(SOLID_FILL,0);
bar(1+window[0],1+window[1],window[2]-1,window[3]-1);
minx = 2*LINE_BORDER + window[0];
miny = LINE_BORDER + window[1];
maxx = - LINE_BORDER + window[2];
maxy = - LINE_BORDER + window[3];
/* set start and stop indices */
bufsize = min(maxx-minx,bufsize);
start = 0;
stop = bufsize;
while (!done) {
/* get range of buffer for scaling */
xscale = (float) (maxx-minx) / (stop - start);
if (mode & PLOT_SPECTRUM) {
yscale = (float) (maxy-miny) / 30.0;
zero_crossing = (float) (maxy) - 10.0*yscale;
}
else {
if (scale > 0.0) {
if (mode & PLOT_UNARY) {
yscale = (float) (maxy-miny) / scale;
zero_crossing = maxy;
} else {
yscale = (float) (maxy-miny) / (2.0*scale);
zero_crossing = (maxy + miny) / 2;
}
}
else {
maxbufy = -65535.0;
minbufy = 65535.0;
for (i=0; i < bufsize; i++) {
maxbufy = max(maxbufy, buf[i]);
minbufy = min(minbufy, buf[i]);
}
if (minbufy > 0) minbufy = 0.0;
if (maxbufy < 0) maxbufy = 0.0;
delta = maxbufy - minbufy;
if (delta < 1.0e-6 && delta > -1.0e-06)
yscale = 0.0;
else {
yscale = (float) (maxy-miny) / delta;
}
zero_crossing = (int)(miny + maxbufy*yscale);
}
}
/* draw the grid lines */
setcolor(RED);
setlinestyle(USERBIT_LINE,0xf0f0,NORM_WIDTH);
tick = (maxy-miny) / 10;
for (i=0; i<=10; i++) {
y = zero_crossing - i * tick;
if (y < miny) break;
line(minx,y,maxx,y);
}
for (i=0; i<=10; i++) {
y = zero_crossing + i * tick;
if (y > maxy) break;
line(minx,y,maxx,y);
}
/* draw x and y axis */
setcolor(WHITE);
setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
line(minx,zero_crossing,maxx,zero_crossing);
line(minx,miny,minx,maxy);
/* if a spectrum plot, draw center freq */
if (mode & PLOT_SPECTRUM)
line((maxx + minx) / 2,miny,(maxx + minx) / 2,maxy);
/* graph the data points */
setcolor(YELLOW);
x = (int) (minx);
if (scale > 0.0)
y = (int) (zero_crossing - yscale * buf[start]);
else
y = (int) (miny + yscale * (maxbufy - buf[start]));
LP_TEST(y,miny,maxy);
moveto(x,y);
for (i=start+1; i<stop; i++) {
x = (int) (minx + (i-start) * xscale);
if (scale > 0.0)
y = (int) (zero_crossing - yscale * buf[i]);
else
y = (int) (miny + yscale * (maxbufy - buf[i]));
LP_TEST(y,miny,maxy);
lineto(x,y);
}
/* print title, etc. */
setcolor(WHITE);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,CENTER_TEXT);
outtextxy((maxx+minx)/2, miny- LINE_BORDER/2,title[0]);
settextstyle(SMALL_FONT,HORIZ_DIR,4);
if (title[1] != (char *) 0) outtextxy((maxx+minx)/2,maxy+10,title[1]);
if (title[2] != (char *) 0) outtextxy(minx-10,miny-10,title[2]);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
/* print the grid magnitudes */
settextstyle(SMALL_FONT,HORIZ_DIR,2);
settextjustify(RIGHT_TEXT,CENTER_TEXT);
/* Plot POSITIVE y-axis values */
for (i=0; i<=10; i++) {
y = zero_crossing - i * tick;
if (y < miny) break;
if (yscale > 1.0e-6) {
sprintf(txt_maxy,"%5.2f",i * (float)(maxy-miny) / (10.0*yscale));
outtextxy(minx-2,y,txt_maxy);
}
}
/* Plot NEGATIVE y-axis values (if necessary) */
if ( ((mode & PLOT_UNARY )== 0) || (mode & PLOT_SPECTRUM) ) {
for (i=1; i<10; i++) {
y = zero_crossing + i * tick;
if (y > maxy) break;
if (yscale > 1.0e-6) {
sprintf(txt_maxy,"%5.2f",-i * (float)(maxy-miny) / (10.0*yscale));
outtextxy(minx-2,y,txt_maxy);
}
}
}
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
done = 1;
}
}
/**************************************************************
* status_plot - This routine prints status information to the
* specified window. Status information is of the type plot_status_t.
* Each item in this structure contains the item 'name',
* the 'u' and the 'unit'
**************************************************************/
void status_plot(int *window, char *title, plot_status_t status[], int nitems)
{
int i,n;
int minx, miny, maxx, maxy;
int x1,x2,y1,y2;
int maxname=-1,maxmsg=-1,char_size=8;
char buf[80],fmt_string[32];
/* clear the window */
setfillstyle(SOLID_FILL,0);
bar(1+window[0],1+window[1],window[2]-1,window[3]-1);
/* determine plot range */
minx = window[0];
miny = window[1];
maxx = window[2];
/* determine the maximum string length */
for (i=0; i<nitems; i++) {
if ((n=strlen(status[i].name)) > maxname) maxname = n;
}
sprintf(fmt_string,"%%%ds %%s %%s",maxname+2);
/* print the title */
setcolor(WHITE);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,CENTER_TEXT);
outtextxy(minx + (maxx-minx)/2,miny-STAT_BORDER/2,title);
/* determine extent of message area and draw background */
for (i=0; i<nitems; i++) {
sprintf(buf,fmt_string,status[i].name,status[i].val,status[i].unit);
if ((n=strlen(buf)) > maxmsg) maxmsg = n;
}
x1 = minx;
y1 = miny;
x2 = x1 + char_size * (1+maxmsg);
y2 = y1 + 2 * char_size * nitems;
setfillstyle(SOLID_FILL,BLUE);
bar(x1,y1,x2,y2);
/* print the stats */
setcolor(WHITE);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(LEFT_TEXT,CENTER_TEXT);
x1 = minx + char_size;
y1 = miny + char_size;
for (i=0; i<nitems; i++) {
sprintf(buf,fmt_string,status[i].name,status[i].val,status[i].unit);
outtextxy(x1,2*i*char_size+y1,buf);
}
}
/**************************************************************
* fkey_menu - this routine prints buttons to the defines screen
* area that represent function keys.
* Returns function key pressed
**************************************************************/
int fkey_menu(int noquerry,int *window, char *msg[])
{
int xsiz,ysiz,fxsiz,fysiz;
int x1,x2,y1,y2;
int i,c,nkeys=10;
char fmsg[32];
/* determine scaling */
xsiz = window[2] - window[0];
ysiz = window[3] - window[1];
fxsiz = (xsiz - 6*FKEY_BORDER) / 5;
fysiz = (ysiz - 3*FKEY_BORDER) / 2;
/* draw the buttons */
setcolor(WHITE);
settextstyle(SMALL_FONT,HORIZ_DIR,4);
settextjustify(CENTER_TEXT,CENTER_TEXT);
setfillstyle(SOLID_FILL,0);
bar(window[0],window[1],window[2],window[3]);
for (i=0; i<nkeys; i++) {
/* draw buttons */
x1 = window[0] + FKEY_BORDER * (1 + (i % 5)) + fxsiz * (i % 5);
x2 = x1 + fxsiz;
y1 = window[1] + FKEY_BORDER * (1 + (i / 5)) + fysiz * (i / 5);
y2 = y1 + fysiz;
setfillstyle(SOLID_FILL,GREEN);
bar(x1,y1,x2,y2);
setfillstyle(SOLID_FILL,BLUE);
bar(x1+2,y1+2,x2+2,y2+2);
rectangle(x1+2,y1+2,x2+2,y2+2);
/* draw text */
x1 += fxsiz / 2;
y1 += 0.33 * fysiz;
sprintf(fmsg,"F%d",1+i);
outtextxy(x1,y1,fmsg);
y1 += 0.33 * fysiz;
outtextxy(x1,y1,msg[i]);
}
/* get input */
if (!noquerry) {
if ((c = getch()) == 0) {
c = getch();
return c - 0x3a;
}
}
return 0;
}
#define DIALOG_BUTTON_HEIGHT 30
/**************************************************************
* dialog_box - this routine is used to notify the user of some
* event that required input. x1,y1 defines the upper left corner
* of the dialog box. msg defines the message to be printed. It
* must be null-terminated. prompt defines the hot-key prompts.
* Up to 10 hotkeys may be printed. This routine returns the
* hot-key pressed.
**************************************************************/
int dialog_box(int x1, int y1, char *msg[], char *prompt[])
{
int i,x,y,c,x2,y2,x3,y3,x4,y4,fxsiz;
int window[4];
int n,maxlength,nmessage,nkeys;
char fmsg[32];
unsigned size;
void far *imagebuf;
/* determine the size of the message area */
for (nmessage=maxlength=0; msg[nmessage] != (char *)0; nmessage++) {
n = strlen(msg[nmessage]);
if (n > maxlength) maxlength = n;
}
x2 = x1 + 10 * maxlength;
y2 = y1 + 10 * (4 + nmessage) + DIALOG_BUTTON_HEIGHT;
/* save the bitmap for the window */
size = imagesize(x1,y1,x2,y2);
imagebuf = farmalloc(size);
getimage(x1,y1,x2,y2,imagebuf);
/* draw the background */
setfillstyle(SOLID_FILL,BLUE);
bar(x1,y1,x2,y2);
setfillstyle(SOLID_FILL,RED);
bar(x1+5,y1+5,x2-5,y2-5);
/* print the message */
x = (x1 + x2) / 2;
y = y1 + 20;
setcolor(WHITE);
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,CENTER_TEXT);
for (i=0; i < nmessage; i++) {
outtextxy(x,y,msg[i]);
y+=10;
}
/* count the number of keys */
for (nkeys=0; prompt[nkeys] != (char *)0; nkeys++) ;
if (nkeys) fxsiz = (x2-x1-5*nkeys - 5) / (nkeys);
/* draw the buttons */
setcolor(WHITE);
settextstyle(SMALL_FONT,HORIZ_DIR,4);
settextjustify(CENTER_TEXT,CENTER_TEXT);
setfillstyle(SOLID_FILL,0);
for (i=0; i<nkeys; i++) {
/* draw buttons */
x3 = x1 + fxsiz * i + 5*i + 5;
x4 = x3 + fxsiz;
y3 = y2 - DIALOG_BUTTON_HEIGHT - 10;
y4 = y2 - 10;
setfillstyle(SOLID_FILL,GREEN);
bar(x3,y3,x4,y4);
setfillstyle(SOLID_FILL,BLUE);
bar(x3+2,y3+2,x4+2,y4+2);
rectangle(x3+2,y3+2,x4+2,y4+2);
/* draw text */
x3 += fxsiz / 2;
y3 += 0.33 * DIALOG_BUTTON_HEIGHT;
sprintf(fmsg,"F%d",1+i);
outtextxy(x3,y3,fmsg);
y3 += 0.33 * DIALOG_BUTTON_HEIGHT;
outtextxy(x3,y3,prompt[i]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -