2 // nibblewidget.cpp: Track waveform nibble display widget
4 // Part of the WOZ Maker project
6 // (C) 2018 Underground Software
9 #include "nibblewidget.h"
14 NibbleWidget::NibbleWidget(QWidget * parent/*= 0*/): QWidget(parent)
16 // Is this even needed?
17 setGeometry(QRect(0, 0, 20, 20));
21 NibbleWidget::~NibbleWidget(void)
26 void NibbleWidget::Update(void)
31 setMinimumWidth(52 * fWidth);
32 // setMaximumWidth(52 * fWidth);
33 setMinimumHeight(((Global::nibbleCount + 51) / 52) * fHeight);
34 setMaximumHeight(((Global::nibbleCount + 51) / 52) * fHeight);
39 void NibbleWidget::DecodeWaveform(void)
42 if (Global::streamNum >= Global::numStreams)
45 uint8_t * data = Global::bitStream;
46 uint32_t dataSize = Uint32LE(Global::stream[Global::streamNum]->dataLength);
47 uint8_t * sdata = Global::stream[Global::streamNum]->data;
48 uint32_t & bits = Global::bitStreamLength;
54 for(uint32_t i=1; i<dataSize; i++)
56 uint32_t timeToNext = sdata[i];
60 while (sdata[i++] == 0xFF)
61 timeToNext += sdata[i];
66 if ((timeToNext >= 24) && (timeToNext <= 49))
70 else if ((timeToNext >= 50) && (timeToNext <= 80))
75 else if ((timeToNext >= 81) && (timeToNext <= 112))
81 else if ((timeToNext >= 113) && (timeToNext <= 137))
90 // Handle zeros here...
91 while (timeToNext > 32)
104 void NibbleWidget::DecodeBitstream(void)
106 uint8_t zeroBits3[6] = { 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07 };
107 uint8_t * data = Global::bitStream;
113 uint32_t dataSize = Global::bitStreamLength;
116 Global::nibbleCount = 0;
117 memset(nibble, 0, sizeof(uint16_t) * 10000);
119 while (pos < dataSize)
121 uint8_t bit = data[pos];
126 nibble[Global::nibbleCount]++;
129 // Check to see if there are illegal bit patterns in the
131 for(uint8_t i=0; i<6; i++)
133 if ((byte & zeroBits3[i]) == 0)
135 nibble[Global::nibbleCount] |= 0x0080;
140 nibble[Global::nibbleCount++] |= byte << 8;
145 byte = (byte << 1) | (bit ? 1 : 0);
152 void NibbleWidget::paintEvent(QPaintEvent * /*event*/)
154 QPainter painter(this);
155 painter.setRenderHint(QPainter::Antialiasing);
157 // QFont font("Monospace"); // ugly
158 // QFont font("DejaVu Sans Mono"); // ugly
160 font.setPixelSize(14.5);
161 font.setWeight(QFont::Black);
162 font.setHintingPreference(QFont::PreferFullHinting);
163 font.setStyleHint(QFont::Monospace);
164 painter.setFont(font);
166 for(uint32_t y=0; y<(Global::nibbleCount+51)/52; y++)
168 for(uint32_t x=0; x<52; x++)
170 if (((y * 52) + x) >= Global::nibbleCount)
173 QRectF r(x * fWidth, y * fHeight, fWidth, fHeight);
174 uint8_t trailingZeroes = nibble[(y * 52) + x] & 0x7F;
175 uint8_t badBitPattern = nibble[(y * 52) + x] & 0x80;
178 painter.fillRect(r, QColor(0xBF, 0xE3, 0xEF, 0xFF));
180 painter.fillRect(r, Qt::white);
183 painter.setPen(Qt::red);
185 painter.drawText(r.translated(0.0, 2.0), Qt::AlignCenter, QString("%1").arg((ushort)(nibble[(y * 52) + x] >> 8), 2, 16, QChar('0')).toUpper());
186 painter.setPen(Qt::black);
188 if (trailingZeroes == 1)
190 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f), r.y() + 5.0f), 2.0f, 2.0f);
192 else if (trailingZeroes == 2)
194 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f) - 4.0f, r.y() + 5.0f), 2.0f, 2.0f);
195 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f) + 4.0f, r.y() + 5.0f), 2.0f, 2.0f);
197 else if (trailingZeroes >= 3)
199 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f), r.y() + 5.0f), 2.0f, 2.0f);
200 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f) - 6.0f, r.y() + 5.0f), 2.0f, 2.0f);
201 painter.drawEllipse(QPointF(r.x() + ((float)fWidth / 2.0f) + 6.0f, r.y() + 5.0f), 2.0f, 2.0f);
208 void NibbleWidget::mousePressEvent(QMouseEvent * event)
210 if (event->button() == Qt::LeftButton)
217 void NibbleWidget::mouseMoveEvent(QMouseEvent * event)
219 if (event->buttons() & Qt::LeftButton)
226 void NibbleWidget::mouseReleaseEvent(QMouseEvent * event)
228 if (event->button() == Qt::LeftButton)
235 void NibbleWidget::mouseDoubleClickEvent(QMouseEvent * event)
237 if (event->button() == Qt::LeftButton)
244 void NibbleWidget::keyPressEvent(QKeyEvent * event)
246 int key = event->key();
248 if (key == Qt::Key_Up)
251 else if (key == Qt::Key_Down)
254 else if (key == Qt::Key_Left)
257 else if (key == Qt::Key_Right)
263 // Only update if a key we recognize has been pressed!
268 void NibbleWidget::keyReleaseEvent(QKeyEvent * /*event*/)
273 void NibbleWidget::resizeEvent(QResizeEvent * /*event*/)