#include "Convac.h"
/*================*
* Digital-Editor *
*================*/
// Horizontale Position des Bits ermitteln
// 7 Pixel pro Zeichen (7*32 + 4*1 + 3*4 = 240)
static byte bitPosition(byte bit) {
return bit*7+(bit>>2)+(bit>>3)*3;
}
// Fokusrechteck für Bit setzen / wegnehmen
static void xorFocus() {
byte x=bitPosition(C.focusb);
xorFocusRect(x,40,x+6,50);
}
static void bitTitle() {
const char*s=(const char*)pgm_read_word(Nlist+C.seite);
centerTitle(strend1(s,C.focusb),2);
}
// Bitrichtung oben rechts ausgeben
static void bitDir() {
prepareField(188,0,239,10); // 52×11 Pixel
byte dir=shrb(DIGITAL::getDir(byte(C.seite<<2)|byte(C.focusb>>3)),C.focusb);
d.print(dir&1?F("Ausgang"):F("Eingang"));
}
static void menuDirClock() {
paintMenuItem(5*40,zoom?F("Uhr"):F("Richtung"));
}
void dlgDigital() {
vorn:
d.clear();
d.print(C.seite?F("Ausgänge "):F("Eingänge"));
if (C.seite) d.print('0'+C.seite); // "1" oder "2"
byte maxbit=C.seite?28:31;
if (C.focusb>maxbit) C.focusb=maxbit;
bitTitle();
// d.clrClip();
paintMenu(F("\x1F\0\x1E\0\x1C\0\x1D\0Alles 0"),0x1F);
byte curbit=0;
for (byte j=0;; j++) {
byte x=j*61;
d.gotoXY(x+1,25); // eine Klammer mit Lücke in der Mitte zeichnen
d.lineTo(x+1,21);
d.lineTo(x+3,19);
d.lineTo(x+22,19);
d.gotoXY(x+33,19);
d.lineTo(x+52,19);
d.lineTo(x+54,21);
d.lineTo(x+54,25);
d.gotoXY(x+26,14);
d.print('0'|j);
d.gotoXY(x+1,25);
for (byte i=0; i<8; i++) {
if (i==4) d.X+=1; // Lücke zwischen Nibbles
d.print('0'|i); // unten 0..7 (Bits)
d.X+=2;
if (++curbit>maxbit) goto raus1;
}
idle(); // im Bildaufbau byteweise idlen
}
raus1:
d.drawLine(0,38,239,38); // waagerechte Linie
byte change=0xFF; // Zuerst alle Bits ausgeben
byte last[4]; // Bit-Merker
startFocusCounter();
xorFocus(); // Zuallererst Fokusrechteck darstellen
zoomchanged:
if (zoom) bitDir(); else onZoomClear();
menuDirClock();
d.clrClip();
// Hauptschleife guckt nach veränderten Bits und aktualisiert (nur) diese
for(;;) {
if (ticCheck(50)) {
xorFocus(); // 2 Hz Blinken realisieren
xorFocusVis();
}
curbit=0;
for (byte j=0;; j++) { // Veränderungen detektieren und anzeigen
byte b=DIGITAL::getIo(C.seite<<2|j);
byte c=change|(b^last[j]); // Änderungen als 1-Bits
last[j]=b; // Letzter Wert
for (byte m=1;m;m<<=1) {
if (c&m) {
d.flags=b&m?d.R2_NOTCOPYPEN:d.R2_COPYPEN; // ohne COLOR, ohne COOKED
d.X=bitPosition(curbit);
d.drawLine(d.X,50,d.X,40); // Ziffer links und rechts rändern
d.X++;
d.print(b&m?'1':'0');
d.drawLine(d.X,50,d.X,40);
if (curbit==::C.focusb && focusVis) xorFocus();
}
if (++curbit>maxbit) goto keyin;
}
idle(); // byteweise idlen
}
keyin:
change=0;
switch (byte action=getkey(5)) { // Tasten auswerten
case 0: continue;
case '\r': return;
case 0xF1: // Bit -
case 0xF2: { // Bit +
if (focusVis) xorFocus();
C.focusb=updown(C.focusb,action,maxbit);
startFocusCounter();
xorFocus();
bitTitle();
idle(); // bitTitle() könnte länger dauern
if (zoom) bitDir();
d.clrClip();
}continue;
case 0xF3: // Seite -
case 0xF4: { // Seite +
C.seite=updown(C.seite,action-2,2);
}goto vorn;
case 0xF5: { // Alles Null
for (byte i=0; i<4; i++) DIGITAL::setIo(C.seite<<2|i,0);
}continue;
case 0xF6: {
xorZoom(); // schaltet hier zwischen Uhr und Bitrichtungsanzeige um
}goto zoomchanged;
case '0': // Ausgang abschalten; Eingangsinvertierung beenden
case '1': // Ausgang zuschalten; Eingangsinvertierung starten
case '\n': { // Ausgang umschalten; Eingangsinvertierung kippen
byte a=C.seite<<2|C.focusb>>3;
byte b=DIGITAL::ios[a];
byte m=shlb(1,C.focusb);
switch (action) {
case '0': b&=~m; break; // Bit löschen
case '1': b|=m; break; // Bit setzen
default: b^=m; break; // Bit kippen
}
DIGITAL::setIo(a,b);
}continue;
default: beep(80,20); goto keyin; // Tasten '2'..'9'
}
}
}
Detected encoding: UTF-8 | 0
|