📄 draw.cpp
字号:
// Draw a string, centred in the space of a single position, with en dashes on
// the left and right coloured according to the powered state. Draws on the
// middle line.
//-----------------------------------------------------------------------------
static void CenterWithWires(int cx, int cy, char *str, BOOL before, BOOL after)
{
CenterWithWiresWidth(cx, cy, str, before, after, POS_WIDTH);
}
//-----------------------------------------------------------------------------
// Draw an end of line element (coil, RES, MOV, etc.). Special things about
// an end of line element: we must right-justify it.
//-----------------------------------------------------------------------------
static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy,
BOOL poweredBefore)
{
int cx0 = *cx, cy0 = *cy;
BOOL poweredAfter = leaf->poweredAfter;
int thisWidth;
switch(which) {
case ELEM_ADD:
case ELEM_SUB:
case ELEM_MUL:
case ELEM_DIV:
thisWidth = 2;
break;
default:
thisWidth = 1;
break;
}
NormText();
PoweredText(poweredBefore);
while(*cx < (ColsAvailable-thisWidth)*POS_WIDTH) {
int gx = *cx/POS_WIDTH;
int gy = *cy/POS_HEIGHT;
if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;
if(gx >= DISPLAY_MATRIX_X_SIZE) oops();
DM_BOUNDS(gx, gy);
DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX;
DisplayMatrixWhich[gx][gy] = ELEM_PADDING;
int i;
for(i = 0; i < POS_WIDTH; i++) {
DrawChars(*cx + i, *cy + (POS_HEIGHT/2), "-");
}
*cx += POS_WIDTH;
cx0 += POS_WIDTH;
}
if(leaf == Selected && !InSimulationMode) {
EmphText();
ThisHighlighted = TRUE;
} else {
ThisHighlighted = FALSE;
}
switch(which) {
case ELEM_CTC: {
char buf[256];
ElemCounter *c = &leaf->d.counter;
sprintf(buf, "{\x01""CTC\x02 0:%d}", c->max);
CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);
break;
}
case ELEM_RES: {
ElemReset *r = &leaf->d.reset;
CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, "{RES}", poweredBefore, poweredAfter);
break;
}
case ELEM_READ_ADC: {
ElemReadAdc *r = &leaf->d.readAdc;
CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, "{READ ADC}", poweredBefore,
poweredAfter);
break;
}
case ELEM_SET_PWM: {
ElemSetPwm *s = &leaf->d.setPwm;
CenterWithSpaces(*cx, *cy, s->name, poweredAfter, TRUE);
char l[50];
if(s->targetFreq >= 100000) {
sprintf(l, "{PWM %d kHz}", (s->targetFreq+500)/1000);
} else if(s->targetFreq >= 10000) {
sprintf(l, "{PWM %.1f kHz}", s->targetFreq/1000.0);
} else if(s->targetFreq >= 1000) {
sprintf(l, "{PWM %.2f kHz}", s->targetFreq/1000.0);
} else {
sprintf(l, "{PWM %d Hz}", s->targetFreq);
}
CenterWithWires(*cx, *cy, l, poweredBefore,
poweredAfter);
break;
}
case ELEM_PERSIST:
CenterWithSpaces(*cx, *cy, leaf->d.persist.var, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, "{PERSIST}", poweredBefore, poweredAfter);
break;
case ELEM_MOVE: {
char top[256];
char bot[256];
ElemMove *m = &leaf->d.move;
if((strlen(m->dest) > (POS_WIDTH - 9)) ||
(strlen(m->src) > (POS_WIDTH - 9)))
{
CenterWithWires(*cx, *cy, TOO_LONG, poweredBefore,
poweredAfter);
break;
}
strcpy(top, "{ }");
memcpy(top+1, m->dest, strlen(m->dest));
top[strlen(m->dest) + 3] = ':';
top[strlen(m->dest) + 4] = '=';
strcpy(bot, "{ \x01MOV\x02}");
memcpy(bot+2, m->src, strlen(m->src));
CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE);
CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
break;
}
case ELEM_MASTER_RELAY:
CenterWithWires(*cx, *cy, "{MASTER RLY}", poweredBefore,
poweredAfter);
break;
case ELEM_SHIFT_REGISTER: {
char bot[MAX_NAME_LEN+20];
memset(bot, ' ', sizeof(bot));
bot[0] = '{';
sprintf(bot+2, "%s0..%d", leaf->d.shiftRegister.name,
leaf->d.shiftRegister.stages-1);
bot[strlen(bot)] = ' ';
bot[13] = '}';
bot[14] = '\0';
CenterWithSpaces(*cx, *cy, "{\x01SHIFT REG\x02 }",
poweredAfter, FALSE);
CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
break;
}
case ELEM_PIECEWISE_LINEAR:
case ELEM_LOOK_UP_TABLE: {
char top[MAX_NAME_LEN+20], bot[MAX_NAME_LEN+20];
char *dest, *index, *str;
if(which == ELEM_PIECEWISE_LINEAR) {
dest = leaf->d.piecewiseLinear.dest;
index = leaf->d.piecewiseLinear.index;
str = "PWL";
} else {
dest = leaf->d.lookUpTable.dest;
index = leaf->d.lookUpTable.index;
str = "LUT";
}
memset(top, ' ', sizeof(top));
top[0] = '{';
sprintf(top+2, "%s :=", dest);
top[strlen(top)] = ' ';
top[13] = '}';
top[14] = '\0';
CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE);
memset(bot, ' ', sizeof(bot));
bot[0] = '{';
sprintf(bot+2, " %s[%s]", str, index);
bot[strlen(bot)] = ' ';
bot[13] = '}';
bot[14] = '\0';
CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter);
break;
}
case ELEM_COIL: {
char buf[4];
ElemCoil *c = &leaf->d.coil;
buf[0] = '(';
if(c->negated) {
buf[1] = '/';
} else if(c->setOnly) {
buf[1] = 'S';
} else if(c->resetOnly) {
buf[1] = 'R';
} else {
buf[1] = ' ';
}
buf[2] = ')';
buf[3] = '\0';
CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);
break;
}
case ELEM_DIV:
case ELEM_MUL:
case ELEM_SUB:
case ELEM_ADD: {
char top[POS_WIDTH*2-3+2];
char bot[POS_WIDTH*2-3];
memset(top, ' ', sizeof(top)-1);
top[0] = '{';
memset(bot, ' ', sizeof(bot)-1);
bot[0] = '{';
int lt = 1;
if(which == ELEM_ADD) {
memcpy(top+lt, "\x01""ADD\x02", 5);
} else if(which == ELEM_SUB) {
memcpy(top+lt, "\x01SUB\x02", 5);
} else if(which == ELEM_MUL) {
memcpy(top+lt, "\x01MUL\x02", 5);
} else if(which == ELEM_DIV) {
memcpy(top+lt, "\x01""DIV\x02", 5);
} else oops();
lt += 7;
memcpy(top+lt, leaf->d.math.dest, strlen(leaf->d.math.dest));
lt += strlen(leaf->d.math.dest) + 2;
top[lt++] = ':';
top[lt++] = '=';
int lb = 2;
memcpy(bot+lb, leaf->d.math.op1, strlen(leaf->d.math.op1));
lb += strlen(leaf->d.math.op1) + 1;
if(which == ELEM_ADD) {
bot[lb++] = '+';
} else if(which == ELEM_SUB) {
bot[lb++] = '-';
} else if(which == ELEM_MUL) {
bot[lb++] = '*';
} else if(which == ELEM_DIV) {
bot[lb++] = '/';
} else oops();
lb++;
memcpy(bot+lb, leaf->d.math.op2, strlen(leaf->d.math.op2));
lb += strlen(leaf->d.math.op2);
int l = max(lb, lt - 2);
top[l+2] = '}'; top[l+3] = '\0';
bot[l] = '}'; bot[l+1] = '\0';
int extra = 2*POS_WIDTH - FormattedStrlen(top);
PoweredText(poweredAfter);
DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, top);
CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter,
2*POS_WIDTH);
*cx += POS_WIDTH;
break;
}
default:
oops();
break;
}
*cx += POS_WIDTH;
return poweredAfter;
}
//-----------------------------------------------------------------------------
// Draw a leaf element. Special things about a leaf: no need to recurse
// further, and we must put it into the display matrix.
//-----------------------------------------------------------------------------
static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy,
BOOL poweredBefore)
{
int cx0 = *cx, cy0 = *cy;
BOOL poweredAfter = leaf->poweredAfter;
switch(which) {
case ELEM_COMMENT: {
char tbuf[MAX_COMMENT_LEN];
char tlbuf[MAX_COMMENT_LEN+8];
strcpy(tbuf, leaf->d.comment.str);
char *b = strchr(tbuf, '\n');
if(b) {
if(b[-1] == '\r') b[-1] = '\0';
*b = '\0';
sprintf(tlbuf, "\x03 ; %s\x02", tbuf);
DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf);
sprintf(tlbuf, "\x03 ; %s\x02", b+1);
DrawChars(*cx, *cy + (POS_HEIGHT/2), tlbuf);
} else {
sprintf(tlbuf, "\x03 ; %s\x02", tbuf);
DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf);
}
*cx += ColsAvailable*POS_WIDTH;
break;
}
case ELEM_PLACEHOLDER: {
NormText();
CenterWithWiresWidth(*cx, *cy, "--", FALSE, FALSE, 2);
*cx += POS_WIDTH;
break;
}
case ELEM_CONTACTS: {
char buf[4];
ElemContacts *c = &leaf->d.contacts;
buf[0] = ']';
buf[1] = c->negated ? '/' : ' ';
buf[2] = '[';
buf[3] = '\0';
CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);
*cx += POS_WIDTH;
break;
}
{
char *s;
case ELEM_EQU:
s = "=="; goto cmp;
case ELEM_NEQ:
s = "/="; goto cmp;
case ELEM_GRT:
s = ">"; goto cmp;
case ELEM_GEQ:
s = ">="; goto cmp;
case ELEM_LES:
s = "<"; goto cmp;
case ELEM_LEQ:
s = "<="; goto cmp;
cmp:
char s1[POS_WIDTH+10], s2[POS_WIDTH+10];
int l1, l2, lmax;
l1 = 2 + 1 + strlen(s) + strlen(leaf->d.cmp.op1);
l2 = 2 + 1 + strlen(leaf->d.cmp.op2);
lmax = max(l1, l2);
if(lmax < POS_WIDTH) {
memset(s1, ' ', sizeof(s1));
s1[0] = '[';
s1[lmax-1] = ']';
s1[lmax] = '\0';
strcpy(s2, s1);
memcpy(s1+1, leaf->d.cmp.op1, strlen(leaf->d.cmp.op1));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -