diff options
Diffstat (limited to 'ldmicro/draw.cpp')
-rw-r--r-- | ldmicro/draw.cpp | 1766 |
1 files changed, 883 insertions, 883 deletions
diff --git a/ldmicro/draw.cpp b/ldmicro/draw.cpp index ad70101..78232ba 100644 --- a/ldmicro/draw.cpp +++ b/ldmicro/draw.cpp @@ -69,182 +69,182 @@ BOOL ThisHighlighted; // return FALSE; // } -// //----------------------------------------------------------------------------- -// // Determine the width, in leaf element units, of a particular subcircuit. -// // The width of a leaf is 1, the width of a series circuit is the sum of -// // of the widths of its members, and the width of a parallel circuit is -// // the maximum of the widths of its members. -// //----------------------------------------------------------------------------- -// static int CountWidthOfElement(int which, void *elem, int soFar) -// { -// switch(which) { -// case ELEM_PLACEHOLDER: -// case ELEM_OPEN: -// case ELEM_SHORT: -// case ELEM_CONTACTS: -// case ELEM_TON: -// case ELEM_TOF: -// case ELEM_RTO: -// case ELEM_CTU: -// case ELEM_CTD: -// case ELEM_ONE_SHOT_RISING: -// case ELEM_ONE_SHOT_FALLING: -// case ELEM_EQU: -// case ELEM_NEQ: -// case ELEM_GRT: -// case ELEM_GEQ: -// case ELEM_LES: -// case ELEM_LEQ: -// case ELEM_UART_RECV: -// case ELEM_UART_SEND: -// return 1; - -// case ELEM_FORMATTED_STRING: -// return 2; - -// case ELEM_COMMENT: { -// if(soFar != 0) oops(); - -// ElemLeaf *l = (ElemLeaf *)elem; -// char tbuf[MAX_COMMENT_LEN]; - -// strcpy(tbuf, l->d.comment.str); -// char *b = strchr(tbuf, '\n'); - -// int len; -// if(b) { -// *b = '\0'; -// len = max(strlen(tbuf)-1, strlen(b+1)); -// } else { -// len = strlen(tbuf); -// } -// // round up, and allow space for lead-in -// len = (len + 7 + (POS_WIDTH-1)) / POS_WIDTH; -// return max(ColsAvailable, len); -// } -// case ELEM_CTC: -// case ELEM_RES: -// case ELEM_COIL: -// case ELEM_MOVE: -// case ELEM_SHIFT_REGISTER: -// case ELEM_LOOK_UP_TABLE: -// case ELEM_PIECEWISE_LINEAR: -// case ELEM_MASTER_RELAY: -// case ELEM_READ_ADC: -// case ELEM_SET_PWM: -// case ELEM_PERSIST: -// if(ColsAvailable - soFar > 1) { -// return ColsAvailable - soFar; -// } else { -// return 1; -// } - -// case ELEM_ADD: -// case ELEM_SUB: -// case ELEM_MUL: -// case ELEM_DIV: -// if(ColsAvailable - soFar > 2) { -// return ColsAvailable - soFar; -// } else { -// return 2; -// } - -// case ELEM_SERIES_SUBCKT: { -// // total of the width of the members -// int total = 0; -// int i; -// ElemSubcktSeries *s = (ElemSubcktSeries *)elem; -// for(i = 0; i < s->count; i++) { -// total += CountWidthOfElement(s->contents[i].which, -// s->contents[i].d.any, total+soFar); -// } -// return total; -// } - -// case ELEM_PARALLEL_SUBCKT: { -// // greatest of the width of the members -// int max = 0; -// int i; -// ElemSubcktParallel *p = (ElemSubcktParallel *)elem; -// for(i = 0; i < p->count; i++) { -// int w = CountWidthOfElement(p->contents[i].which, -// p->contents[i].d.any, soFar); -// if(w > max) { -// max = w; -// } -// } -// return max; -// } - -// default: -// oops(); -// } -// } - -// //----------------------------------------------------------------------------- -// // Determine the height, in leaf element units, of a particular subcircuit. -// // The height of a leaf is 1, the height of a parallel circuit is the sum of -// // of the heights of its members, and the height of a series circuit is the -// // maximum of the heights of its members. (This is the dual of the width -// // case.) -// //----------------------------------------------------------------------------- -// int CountHeightOfElement(int which, void *elem) -// { -// switch(which) { -// CASE_LEAF -// return 1; - -// case ELEM_PARALLEL_SUBCKT: { -// // total of the height of the members -// int total = 0; -// int i; -// ElemSubcktParallel *s = (ElemSubcktParallel *)elem; -// for(i = 0; i < s->count; i++) { -// total += CountHeightOfElement(s->contents[i].which, -// s->contents[i].d.any); -// } -// return total; -// } - -// case ELEM_SERIES_SUBCKT: { -// // greatest of the height of the members -// int max = 0; -// int i; -// ElemSubcktSeries *s = (ElemSubcktSeries *)elem; -// for(i = 0; i < s->count; i++) { -// int w = CountHeightOfElement(s->contents[i].which, -// s->contents[i].d.any); -// if(w > max) { -// max = w; -// } -// } -// return max; -// } +//----------------------------------------------------------------------------- +// Determine the width, in leaf element units, of a particular subcircuit. +// The width of a leaf is 1, the width of a series circuit is the sum of +// of the widths of its members, and the width of a parallel circuit is +// the maximum of the widths of its members. +//----------------------------------------------------------------------------- +static int CountWidthOfElement(int which, void *elem, int soFar) +{ + switch(which) { + case ELEM_PLACEHOLDER: + case ELEM_OPEN: + case ELEM_SHORT: + case ELEM_CONTACTS: + case ELEM_TON: + case ELEM_TOF: + case ELEM_RTO: + case ELEM_CTU: + case ELEM_CTD: + case ELEM_ONE_SHOT_RISING: + case ELEM_ONE_SHOT_FALLING: + case ELEM_EQU: + case ELEM_NEQ: + case ELEM_GRT: + case ELEM_GEQ: + case ELEM_LES: + case ELEM_LEQ: + case ELEM_UART_RECV: + case ELEM_UART_SEND: + return 1; + + case ELEM_FORMATTED_STRING: + return 2; + + case ELEM_COMMENT: { + if(soFar != 0) oops(); + + ElemLeaf *l = (ElemLeaf *)elem; + char tbuf[MAX_COMMENT_LEN]; + + strcpy(tbuf, l->d.comment.str); + char *b = strchr(tbuf, '\n'); + + int len; + if(b) { + *b = '\0'; + len = max(strlen(tbuf)-1, strlen(b+1)); + } else { + len = strlen(tbuf); + } + // round up, and allow space for lead-in + len = (len + 7 + (POS_WIDTH-1)) / POS_WIDTH; + return max(ColsAvailable, len); + } + case ELEM_CTC: + case ELEM_RES: + case ELEM_COIL: + case ELEM_MOVE: + case ELEM_SHIFT_REGISTER: + case ELEM_LOOK_UP_TABLE: + case ELEM_PIECEWISE_LINEAR: + case ELEM_MASTER_RELAY: + case ELEM_READ_ADC: + case ELEM_SET_PWM: + case ELEM_PERSIST: + if(ColsAvailable - soFar > 1) { + return ColsAvailable - soFar; + } else { + return 1; + } + + case ELEM_ADD: + case ELEM_SUB: + case ELEM_MUL: + case ELEM_DIV: + if(ColsAvailable - soFar > 2) { + return ColsAvailable - soFar; + } else { + return 2; + } + + case ELEM_SERIES_SUBCKT: { + // total of the width of the members + int total = 0; + int i; + ElemSubcktSeries *s = (ElemSubcktSeries *)elem; + for(i = 0; i < s->count; i++) { + total += CountWidthOfElement(s->contents[i].which, + s->contents[i].d.any, total+soFar); + } + return total; + } + + case ELEM_PARALLEL_SUBCKT: { + // greatest of the width of the members + int max = 0; + int i; + ElemSubcktParallel *p = (ElemSubcktParallel *)elem; + for(i = 0; i < p->count; i++) { + int w = CountWidthOfElement(p->contents[i].which, + p->contents[i].d.any, soFar); + if(w > max) { + max = w; + } + } + return max; + } + + default: + oops(); + } +} -// default: -// oops(); -// } -// } +//----------------------------------------------------------------------------- +// Determine the height, in leaf element units, of a particular subcircuit. +// The height of a leaf is 1, the height of a parallel circuit is the sum of +// of the heights of its members, and the height of a series circuit is the +// maximum of the heights of its members. (This is the dual of the width +// case.) +//----------------------------------------------------------------------------- +int CountHeightOfElement(int which, void *elem) +{ + switch(which) { + CASE_LEAF + return 1; + + case ELEM_PARALLEL_SUBCKT: { + // total of the height of the members + int total = 0; + int i; + ElemSubcktParallel *s = (ElemSubcktParallel *)elem; + for(i = 0; i < s->count; i++) { + total += CountHeightOfElement(s->contents[i].which, + s->contents[i].d.any); + } + return total; + } + + case ELEM_SERIES_SUBCKT: { + // greatest of the height of the members + int max = 0; + int i; + ElemSubcktSeries *s = (ElemSubcktSeries *)elem; + for(i = 0; i < s->count; i++) { + int w = CountHeightOfElement(s->contents[i].which, + s->contents[i].d.any); + if(w > max) { + max = w; + } + } + return max; + } + + default: + oops(); + } +} -// //----------------------------------------------------------------------------- -// // Determine the width, in leaf element units, of the widest row of the PLC -// // program (i.e. loop over all the rungs and find the widest). -// //----------------------------------------------------------------------------- -// int ProgCountWidestRow(void) -// { -// int i; -// int max = 0; -// int colsTemp = ColsAvailable; -// ColsAvailable = 0; -// for(i = 0; i < Prog.numRungs; i++) { -// int w = CountWidthOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i], 0); -// if(w > max) { -// max = w; -// } -// } -// ColsAvailable = colsTemp; -// return max; -// } +//----------------------------------------------------------------------------- +// Determine the width, in leaf element units, of the widest row of the PLC +// program (i.e. loop over all the rungs and find the widest). +//----------------------------------------------------------------------------- +int ProgCountWidestRow(void) +{ + int i; + int max = 0; + int colsTemp = ColsAvailable; + ColsAvailable = 0; + for(i = 0; i < Prog.numRungs; i++) { + int w = CountWidthOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i], 0); + if(w > max) { + max = w; + } + } + ColsAvailable = colsTemp; + return max; +} // //----------------------------------------------------------------------------- // // Draw a vertical wire one leaf element unit high up from (cx, cy), where cx @@ -355,716 +355,716 @@ BOOL ThisHighlighted; // } // } -// //----------------------------------------------------------------------------- -// // 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 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 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; -// //----------------------------------------------------------------------------- -// // 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)); -// // memcpy(s1+strlen(leaf->d.cmp.op1)+2, s, strlen(s)); -// // memcpy(s2+2, leaf->d.cmp.op2, strlen(leaf->d.cmp.op2)); -// // } else { -// // strcpy(s1, ""); -// // strcpy(s2, TOO_LONG); -// // } - -// // CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); -// // CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); - -// // *cx += POS_WIDTH; -// // break; -// // } -// // case ELEM_OPEN: -// // CenterWithWires(*cx, *cy, "+ +", poweredBefore, poweredAfter); -// // *cx += POS_WIDTH; -// // break; - -// // case ELEM_SHORT: -// // CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter); -// // *cx += POS_WIDTH; -// // break; - -// // case ELEM_ONE_SHOT_RISING: -// // case ELEM_ONE_SHOT_FALLING: { -// // char *s1, *s2; -// // if(which == ELEM_ONE_SHOT_RISING) { -// // s1 = " _ "; -// // s2 = "[\x01OSR\x02_/ ]"; -// // } else if(which == ELEM_ONE_SHOT_FALLING) { -// // s1 = " _ "; -// // s2 = "[\x01OSF\x02 \\_]"; -// // } else oops(); - -// // CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); -// // CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); - -// // *cx += POS_WIDTH; -// // break; -// // } -// // case ELEM_CTU: -// // case ELEM_CTD: { -// // char *s; -// // if(which == ELEM_CTU) -// // s = "\x01""CTU\x02"; -// // else if(which == ELEM_CTD) -// // s = "\x01""CTD\x02"; -// // else oops(); - -// // char buf[256]; -// // ElemCounter *c = &leaf->d.counter; -// // sprintf(buf, "[%s >=%d]", s, c->max); - -// // CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); -// // CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); - -// // *cx += POS_WIDTH; -// // break; -// // } -// // case ELEM_RTO: -// // case ELEM_TON: -// // case ELEM_TOF: { -// // char *s; -// // if(which == ELEM_TON) -// // s = "\x01TON\x02"; -// // else if(which == ELEM_TOF) -// // s = "\x01TOF\x02"; -// // else if(which == ELEM_RTO) -// // s = "\x01RTO\x02"; -// // else oops(); - -// // char buf[256]; -// // ElemTimer *t = &leaf->d.timer; -// // if(t->delay >= 1000*1000) { -// // sprintf(buf, "[%s %.3f s]", s, t->delay/1000000.0); -// // } else if(t->delay >= 100*1000) { -// // sprintf(buf, "[%s %.1f ms]", s, t->delay/1000.0); -// // } else { -// // sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0); -// // } - -// // CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE); -// // CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); - -// // *cx += POS_WIDTH; -// // break; -// // } -// // case ELEM_FORMATTED_STRING: { -// // // Careful, string could be longer than fits in our space. -// // char str[POS_WIDTH*2]; -// // memset(str, 0, sizeof(str)); -// // char *srcStr = leaf->d.fmtdStr.string; -// // memcpy(str, srcStr, min(strlen(srcStr), POS_WIDTH*2 - 7)); - -// // char bot[100]; -// // sprintf(bot, "{\"%s\"}", str); - -// // int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var); -// // PoweredText(poweredAfter); -// // NameText(); -// // DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, -// // leaf->d.fmtdStr.var); -// // BodyText(); - -// // CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter, -// // 2*POS_WIDTH); -// // *cx += 2*POS_WIDTH; -// // break; -// // } -// // case ELEM_UART_RECV: -// // case ELEM_UART_SEND: -// // CenterWithWires(*cx, *cy, -// // (which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}", -// // poweredBefore, poweredAfter); -// // CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE); -// // *cx += POS_WIDTH; -// // break; - -// // default: -// // poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore); -// // break; -// // } - -// // // And now we can enter the element into the display matrix so that the -// // // UI routines know what element is at position (gx, gy) when the user -// // // clicks there, and so that we know where to put the cursor if this -// // // element is selected. - -// // // Don't use original cx0, as an end of line element might be further -// // // along than that. -// // cx0 = *cx - POS_WIDTH; - -// // int gx = cx0/POS_WIDTH; -// // int gy = cy0/POS_HEIGHT; -// // if(CheckBoundsUndoIfFails(gx, gy)) return FALSE; -// // DM_BOUNDS(gx, gy); - -// // DisplayMatrix[gx][gy] = leaf; -// // DisplayMatrixWhich[gx][gy] = which; - -// // int xadj = 0; -// // switch(which) { -// // case ELEM_ADD: -// // case ELEM_SUB: -// // case ELEM_MUL: -// // case ELEM_DIV: -// // case ELEM_FORMATTED_STRING: -// // DM_BOUNDS(gx-1, gy); -// // DisplayMatrix[gx-1][gy] = leaf; -// // DisplayMatrixWhich[gx-1][gy] = which; -// // xadj = POS_WIDTH*FONT_WIDTH; -// // break; -// // } - -// // if(which == ELEM_COMMENT) { -// // int i; -// // for(i = 0; i < ColsAvailable; i++) { -// // DisplayMatrix[i][gy] = leaf; -// // DisplayMatrixWhich[i][gy] = ELEM_COMMENT; -// // } -// // xadj = (ColsAvailable-1)*POS_WIDTH*FONT_WIDTH; -// // } - -// // int x0 = X_PADDING + cx0*FONT_WIDTH; -// // int y0 = Y_PADDING + cy0*FONT_HEIGHT; - -// // if(leaf->selectedState != SELECTED_NONE && leaf == Selected) { -// // SelectionActive = TRUE; -// // } -// // switch(leaf->selectedState) { -// // case SELECTED_LEFT: -// // Cursor.left = x0 + FONT_WIDTH - 4 - xadj; -// // Cursor.top = y0 - FONT_HEIGHT/2; -// // Cursor.width = 2; -// // Cursor.height = POS_HEIGHT*FONT_HEIGHT; -// // break; - -// // case SELECTED_RIGHT: -// // Cursor.left = x0 + (POS_WIDTH-1)*FONT_WIDTH - 5; -// // Cursor.top = y0 - FONT_HEIGHT/2; -// // Cursor.width = 2; -// // Cursor.height = POS_HEIGHT*FONT_HEIGHT; -// // break; - -// // case SELECTED_ABOVE: -// // Cursor.left = x0 + FONT_WIDTH/2 - xadj; -// // Cursor.top = y0 - 2; -// // Cursor.width = (POS_WIDTH-2)*FONT_WIDTH + xadj; -// // Cursor.height = 2; -// // break; - -// // case SELECTED_BELOW: -// // Cursor.left = x0 + FONT_WIDTH/2 - xadj; -// // Cursor.top = y0 + (POS_HEIGHT-1)*FONT_HEIGHT + -// // FONT_HEIGHT/2 - 2; -// // Cursor.width = (POS_WIDTH-2)*(FONT_WIDTH) + xadj; -// // Cursor.height = 2; -// // break; - -// // default: -// // break; -// // } - -// // return poweredAfter; -// // } +// BOOL poweredAfter = leaf->poweredAfter; -// //----------------------------------------------------------------------------- -// // Draw a particular subcircuit with its top left corner at *cx and *cy (in -// // characters). If it is a leaf element then just print it and return; else -// // loop over the elements of the subcircuit and call ourselves recursively. -// // At the end updates *cx and *cy. -// // -// // In simulation mode, returns TRUE the circuit is energized after the given -// // element, else FALSE. This is needed to colour all the wires correctly, -// // since the colouring indicates whether a wire is energized. -// //----------------------------------------------------------------------------- -// // BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) -// // { -// // BOOL poweredAfter; - -// // int cx0 = *cx, cy0 = *cy; -// // ElemLeaf *leaf = (ElemLeaf *)elem; - -// // SetBkColor(Hdc, InSimulationMode ? HighlightColours.simBg : -// // HighlightColours.bg); -// // NormText(); - -// // if(elem == Selected && !InSimulationMode) { -// // EmphText(); -// // ThisHighlighted = TRUE; -// // } else { -// // ThisHighlighted = FALSE; -// // } - -// // switch(which) { -// // case ELEM_SERIES_SUBCKT: { -// // int i; -// // ElemSubcktSeries *s = (ElemSubcktSeries *)elem; -// // poweredAfter = poweredBefore; -// // for(i = 0; i < s->count; i++) { -// // poweredAfter = DrawElement(s->contents[i].which, -// // s->contents[i].d.any, cx, cy, poweredAfter); -// // } -// // break; -// // } -// // case ELEM_PARALLEL_SUBCKT: { -// // int i; -// // ElemSubcktParallel *p = (ElemSubcktParallel *)elem; -// // int widthMax = CountWidthOfElement(which, elem, (*cx)/POS_WIDTH); -// // int heightMax = CountHeightOfElement(which, elem); - -// // poweredAfter = FALSE; - -// // int lowestPowered = -1; -// // int downBy = 0; -// // for(i = 0; i < p->count; i++) { -// // BOOL poweredThis; - -// // poweredThis = DrawElement(p->contents[i].which, -// // p->contents[i].d.any, cx, cy, poweredBefore); - -// // if(InSimulationMode) { -// // if(poweredThis) poweredAfter = TRUE; -// // PoweredText(poweredThis); -// // } - -// // while((*cx - cx0) < widthMax*POS_WIDTH) { -// // int gx = *cx/POS_WIDTH; -// // int gy = *cy/POS_HEIGHT; - -// // if(CheckBoundsUndoIfFails(gx, gy)) return FALSE; - -// // DM_BOUNDS(gx, gy); -// // DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX; -// // DisplayMatrixWhich[gx][gy] = ELEM_PADDING; - -// // char buf[256]; -// // int j; -// // for(j = 0; j < POS_WIDTH; j++) { -// // buf[j] = '-'; -// // } -// // buf[j] = '\0'; -// // DrawChars(*cx, *cy + (POS_HEIGHT/2), buf); -// // *cx += POS_WIDTH; -// // } - -// // *cx = cx0; -// // int justDrewHeight = CountHeightOfElement(p->contents[i].which, -// // p->contents[i].d.any); -// // *cy += POS_HEIGHT*justDrewHeight; - -// // downBy += justDrewHeight; -// // if(poweredThis) { -// // lowestPowered = downBy - 1; -// // } -// // } -// // *cx = cx0 + POS_WIDTH*widthMax; -// // *cy = cy0; - -// // int j; -// // BOOL needWire; - -// // if(*cx/POS_WIDTH != ColsAvailable) { -// // needWire = FALSE; -// // for(j = heightMax - 1; j >= 1; j--) { -// // if(j <= lowestPowered) PoweredText(poweredAfter); -// // if(DisplayMatrix[*cx/POS_WIDTH - 1][*cy/POS_HEIGHT + j]) { -// // needWire = TRUE; -// // } -// // if(needWire) VerticalWire(*cx - 1, *cy + j*POS_HEIGHT); -// // } -// // // stupid special case -// // if(lowestPowered == 0 && InSimulationMode) { -// // EmphText(); -// // DrawChars(*cx - 1, *cy + (POS_HEIGHT/2), "+"); -// // } -// // } - -// // PoweredText(poweredBefore); -// // needWire = FALSE; -// // for(j = heightMax - 1; j >= 1; j--) { -// // if(DisplayMatrix[cx0/POS_WIDTH][*cy/POS_HEIGHT + j]) { -// // needWire = TRUE; -// // } -// // if(needWire) VerticalWire(cx0 - 1, *cy + j*POS_HEIGHT); -// // } - -// // break; -// // } -// // default: -// // poweredAfter = DrawLeaf(which, leaf, cx, cy, poweredBefore); -// // break; -// // } - - -// // NormText(); -// // return poweredAfter; -// // } +// int thisWidth; +// switch(which) { +// case ELEM_ADD: +// case ELEM_SUB: +// case ELEM_MUL: +// case ELEM_DIV: +// thisWidth = 2; +// break; -// //----------------------------------------------------------------------------- -// // Draw the rung that signals the end of the program. Kind of useless but -// // do it anyways, for convention. -// //----------------------------------------------------------------------------- -// // void DrawEndRung(int cx, int cy) -// // { -// // int i; -// // char *str = "[END]"; -// // int lead = (POS_WIDTH - strlen(str))/2; -// // ThisHighlighted = TRUE; -// // for(i = 0; i < lead; i++) { -// // DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); -// // } -// // DrawChars(cx + i, cy + (POS_HEIGHT/2), str); -// // i += strlen(str); -// // for(; i < ColsAvailable*POS_WIDTH; i++) { -// // DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); -// // } -// // } +// 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)); +// memcpy(s1+strlen(leaf->d.cmp.op1)+2, s, strlen(s)); +// memcpy(s2+2, leaf->d.cmp.op2, strlen(leaf->d.cmp.op2)); +// } else { +// strcpy(s1, ""); +// strcpy(s2, TOO_LONG); +// } + +// CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); +// CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); + +// *cx += POS_WIDTH; +// break; +// } +// case ELEM_OPEN: +// CenterWithWires(*cx, *cy, "+ +", poweredBefore, poweredAfter); +// *cx += POS_WIDTH; +// break; + +// case ELEM_SHORT: +// CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter); +// *cx += POS_WIDTH; +// break; + +// case ELEM_ONE_SHOT_RISING: +// case ELEM_ONE_SHOT_FALLING: { +// char *s1, *s2; +// if(which == ELEM_ONE_SHOT_RISING) { +// s1 = " _ "; +// s2 = "[\x01OSR\x02_/ ]"; +// } else if(which == ELEM_ONE_SHOT_FALLING) { +// s1 = " _ "; +// s2 = "[\x01OSF\x02 \\_]"; +// } else oops(); + +// CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); +// CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); + +// *cx += POS_WIDTH; +// break; +// } +// case ELEM_CTU: +// case ELEM_CTD: { +// char *s; +// if(which == ELEM_CTU) +// s = "\x01""CTU\x02"; +// else if(which == ELEM_CTD) +// s = "\x01""CTD\x02"; +// else oops(); + +// char buf[256]; +// ElemCounter *c = &leaf->d.counter; +// sprintf(buf, "[%s >=%d]", s, c->max); + +// CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); +// CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + +// *cx += POS_WIDTH; +// break; +// } +// case ELEM_RTO: +// case ELEM_TON: +// case ELEM_TOF: { +// char *s; +// if(which == ELEM_TON) +// s = "\x01TON\x02"; +// else if(which == ELEM_TOF) +// s = "\x01TOF\x02"; +// else if(which == ELEM_RTO) +// s = "\x01RTO\x02"; +// else oops(); + +// char buf[256]; +// ElemTimer *t = &leaf->d.timer; +// if(t->delay >= 1000*1000) { +// sprintf(buf, "[%s %.3f s]", s, t->delay/1000000.0); +// } else if(t->delay >= 100*1000) { +// sprintf(buf, "[%s %.1f ms]", s, t->delay/1000.0); +// } else { +// sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0); +// } + +// CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE); +// CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + +// *cx += POS_WIDTH; +// break; +// } +// case ELEM_FORMATTED_STRING: { +// // Careful, string could be longer than fits in our space. +// char str[POS_WIDTH*2]; +// memset(str, 0, sizeof(str)); +// char *srcStr = leaf->d.fmtdStr.string; +// memcpy(str, srcStr, min(strlen(srcStr), POS_WIDTH*2 - 7)); + +// char bot[100]; +// sprintf(bot, "{\"%s\"}", str); + +// int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var); +// PoweredText(poweredAfter); +// NameText(); +// DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, +// leaf->d.fmtdStr.var); +// BodyText(); + +// CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter, +// 2*POS_WIDTH); +// *cx += 2*POS_WIDTH; +// break; +// } +// case ELEM_UART_RECV: +// case ELEM_UART_SEND: +// CenterWithWires(*cx, *cy, +// (which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}", +// poweredBefore, poweredAfter); +// CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE); +// *cx += POS_WIDTH; +// break; + +// default: +// poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore); +// break; +// } + +// // And now we can enter the element into the display matrix so that the +// // UI routines know what element is at position (gx, gy) when the user +// // clicks there, and so that we know where to put the cursor if this +// // element is selected. + +// // Don't use original cx0, as an end of line element might be further +// // along than that. +// cx0 = *cx - POS_WIDTH; + +// int gx = cx0/POS_WIDTH; +// int gy = cy0/POS_HEIGHT; +// if(CheckBoundsUndoIfFails(gx, gy)) return FALSE; +// DM_BOUNDS(gx, gy); + +// DisplayMatrix[gx][gy] = leaf; +// DisplayMatrixWhich[gx][gy] = which; + +// int xadj = 0; +// switch(which) { +// case ELEM_ADD: +// case ELEM_SUB: +// case ELEM_MUL: +// case ELEM_DIV: +// case ELEM_FORMATTED_STRING: +// DM_BOUNDS(gx-1, gy); +// DisplayMatrix[gx-1][gy] = leaf; +// DisplayMatrixWhich[gx-1][gy] = which; +// xadj = POS_WIDTH*FONT_WIDTH; +// break; +// } + +// if(which == ELEM_COMMENT) { +// int i; +// for(i = 0; i < ColsAvailable; i++) { +// DisplayMatrix[i][gy] = leaf; +// DisplayMatrixWhich[i][gy] = ELEM_COMMENT; +// } +// xadj = (ColsAvailable-1)*POS_WIDTH*FONT_WIDTH; +// } + +// int x0 = X_PADDING + cx0*FONT_WIDTH; +// int y0 = Y_PADDING + cy0*FONT_HEIGHT; + +// if(leaf->selectedState != SELECTED_NONE && leaf == Selected) { +// SelectionActive = TRUE; +// } +// switch(leaf->selectedState) { +// case SELECTED_LEFT: +// Cursor.left = x0 + FONT_WIDTH - 4 - xadj; +// Cursor.top = y0 - FONT_HEIGHT/2; +// Cursor.width = 2; +// Cursor.height = POS_HEIGHT*FONT_HEIGHT; +// break; + +// case SELECTED_RIGHT: +// Cursor.left = x0 + (POS_WIDTH-1)*FONT_WIDTH - 5; +// Cursor.top = y0 - FONT_HEIGHT/2; +// Cursor.width = 2; +// Cursor.height = POS_HEIGHT*FONT_HEIGHT; +// break; + +// case SELECTED_ABOVE: +// Cursor.left = x0 + FONT_WIDTH/2 - xadj; +// Cursor.top = y0 - 2; +// Cursor.width = (POS_WIDTH-2)*FONT_WIDTH + xadj; +// Cursor.height = 2; +// break; + +// case SELECTED_BELOW: +// Cursor.left = x0 + FONT_WIDTH/2 - xadj; +// Cursor.top = y0 + (POS_HEIGHT-1)*FONT_HEIGHT + +// FONT_HEIGHT/2 - 2; +// Cursor.width = (POS_WIDTH-2)*(FONT_WIDTH) + xadj; +// Cursor.height = 2; +// break; + +// default: +// break; +// } + +// return poweredAfter; +// } + +//----------------------------------------------------------------------------- +// Draw a particular subcircuit with its top left corner at *cx and *cy (in +// characters). If it is a leaf element then just print it and return; else +// loop over the elements of the subcircuit and call ourselves recursively. +// At the end updates *cx and *cy. +// +// In simulation mode, returns TRUE the circuit is energized after the given +// element, else FALSE. This is needed to colour all the wires correctly, +// since the colouring indicates whether a wire is energized. +//----------------------------------------------------------------------------- +BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) +{ +// BOOL poweredAfter; + +// int cx0 = *cx, cy0 = *cy; +// ElemLeaf *leaf = (ElemLeaf *)elem; + +// SetBkColor(Hdc, InSimulationMode ? HighlightColours.simBg : +// HighlightColours.bg); +// NormText(); + +// if(elem == Selected && !InSimulationMode) { +// EmphText(); +// ThisHighlighted = TRUE; +// } else { +// ThisHighlighted = FALSE; +// } + +// switch(which) { +// case ELEM_SERIES_SUBCKT: { +// int i; +// ElemSubcktSeries *s = (ElemSubcktSeries *)elem; +// poweredAfter = poweredBefore; +// for(i = 0; i < s->count; i++) { +// poweredAfter = DrawElement(s->contents[i].which, +// s->contents[i].d.any, cx, cy, poweredAfter); +// } +// break; +// } +// case ELEM_PARALLEL_SUBCKT: { +// int i; +// ElemSubcktParallel *p = (ElemSubcktParallel *)elem; +// int widthMax = CountWidthOfElement(which, elem, (*cx)/POS_WIDTH); +// int heightMax = CountHeightOfElement(which, elem); + +// poweredAfter = FALSE; + +// int lowestPowered = -1; +// int downBy = 0; +// for(i = 0; i < p->count; i++) { +// BOOL poweredThis; + +// poweredThis = DrawElement(p->contents[i].which, +// p->contents[i].d.any, cx, cy, poweredBefore); + +// if(InSimulationMode) { +// if(poweredThis) poweredAfter = TRUE; +// PoweredText(poweredThis); +// } + +// while((*cx - cx0) < widthMax*POS_WIDTH) { +// int gx = *cx/POS_WIDTH; +// int gy = *cy/POS_HEIGHT; + +// if(CheckBoundsUndoIfFails(gx, gy)) return FALSE; + +// DM_BOUNDS(gx, gy); +// DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX; +// DisplayMatrixWhich[gx][gy] = ELEM_PADDING; + +// char buf[256]; +// int j; +// for(j = 0; j < POS_WIDTH; j++) { +// buf[j] = '-'; +// } +// buf[j] = '\0'; +// DrawChars(*cx, *cy + (POS_HEIGHT/2), buf); +// *cx += POS_WIDTH; +// } + +// *cx = cx0; +// int justDrewHeight = CountHeightOfElement(p->contents[i].which, +// p->contents[i].d.any); +// *cy += POS_HEIGHT*justDrewHeight; + +// downBy += justDrewHeight; +// if(poweredThis) { +// lowestPowered = downBy - 1; +// } +// } +// *cx = cx0 + POS_WIDTH*widthMax; +// *cy = cy0; + +// int j; +// BOOL needWire; + +// if(*cx/POS_WIDTH != ColsAvailable) { +// needWire = FALSE; +// for(j = heightMax - 1; j >= 1; j--) { +// if(j <= lowestPowered) PoweredText(poweredAfter); +// if(DisplayMatrix[*cx/POS_WIDTH - 1][*cy/POS_HEIGHT + j]) { +// needWire = TRUE; +// } +// if(needWire) VerticalWire(*cx - 1, *cy + j*POS_HEIGHT); +// } +// // stupid special case +// if(lowestPowered == 0 && InSimulationMode) { +// EmphText(); +// DrawChars(*cx - 1, *cy + (POS_HEIGHT/2), "+"); +// } +// } + +// PoweredText(poweredBefore); +// needWire = FALSE; +// for(j = heightMax - 1; j >= 1; j--) { +// if(DisplayMatrix[cx0/POS_WIDTH][*cy/POS_HEIGHT + j]) { +// needWire = TRUE; +// } +// if(needWire) VerticalWire(cx0 - 1, *cy + j*POS_HEIGHT); +// } + +// break; +// } +// default: +// poweredAfter = DrawLeaf(which, leaf, cx, cy, poweredBefore); +// break; +// } + + +// NormText(); +// return poweredAfter; +} + +//----------------------------------------------------------------------------- +// Draw the rung that signals the end of the program. Kind of useless but +// do it anyways, for convention. +//----------------------------------------------------------------------------- +void DrawEndRung(int cx, int cy) +{ +// int i; +// char *str = "[END]"; +// int lead = (POS_WIDTH - strlen(str))/2; +// ThisHighlighted = TRUE; +// for(i = 0; i < lead; i++) { +// DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); +// } +// DrawChars(cx + i, cy + (POS_HEIGHT/2), str); +// i += strlen(str); +// for(; i < ColsAvailable*POS_WIDTH; i++) { +// DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); +// } +} |